115 lines
2.4 KiB
Go
115 lines
2.4 KiB
Go
|
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))
|
||
|
}
|