package protocol import "io" import "fmt" // ReadInt reads a little-endian integer from a reader and returns it as result. // It will read the amount of bytes specified by bytes. func ReadInt (reader io.Reader, bytes int) (result uint, err error) { buf := [1]byte { } shift := 0 for { justRead := 0 for justRead == 0 && err == nil { justRead, err = reader.Read(buf[:]) if err != nil { break } } result += uint(buf[0]) << shift bytes -- shift += 8 if bytes == 0 { break } } return } func MaxIntOfSize (bytes int) (max uint) { for { max |= 0xFF bytes -- if bytes > 0 { max <<= 8 } else { break } } return } // ReadU8 reads an 8-bit integer. func ReadU8 (reader io.Reader) (result uint8, err error) { untypedResult, err := ReadInt(reader, 1) return uint8(untypedResult), err } // ReadU16 reads a 16-bit integer. func ReadU16 (reader io.Reader) (result uint16, err error) { untypedResult, err := ReadInt(reader, 2) return uint16(untypedResult), err } // ReadU24 reads a 24-bit integer. func ReadU24 (reader io.Reader) (result uint32, err error) { untypedResult, err := ReadInt(reader, 3) return uint32(untypedResult), err } // ReadU32 reads a 32-bit integer. func ReadU32 (reader io.Reader) (result uint32, err error) { untypedResult, err := ReadInt(reader, 4) return uint32(untypedResult), err } // WriteInt writes a little-endian integer to a writer. It will write the amount // of bytes specified by bytes. func WriteInt (writer io.Writer, bytes int, integer uint) (err error) { if integer > MaxIntOfSize(bytes) { panic(fmt.Sprintf("uint %d cannot fit in %d bytes", integer, bytes)) } buf := [1]byte { } for { buf[0] = byte(integer & 0xFF) justWrote := 0 for justWrote == 0 { justWrote, err = writer.Write(buf[:]) if err != nil { return } } bytes -- if bytes > 0 { integer >>= 8 } else { break } } return } // WriteU8 writes an 8-bit integer. func WriteU8 (writer io.Writer, integer uint8) error { return WriteInt(writer, 1, uint(integer)) } // WriteU16 writes an 16-bit integer. func WriteU16 (writer io.Writer, integer uint16) error { return WriteInt(writer, 2, uint(integer)) } // WriteU24 writes an 24-bit integer. func WriteU24 (writer io.Writer, integer uint32) error { return WriteInt(writer, 3, uint(integer)) } // WriteU32 writes an 32-bit integer. func WriteU32 (writer io.Writer, integer uint32) error { return WriteInt(writer, 4, uint(integer)) }