package codec import "io" // Encodable is any type that can write itself to an encoder. type Encodable interface { // Encode sends data to encoder. It returns the amount of bytes written, // and an error if the write stopped early. Encode(encoder *Encoder) (n int, err error) } // Encoder wraps an [io.Writer] and encodes data to it. type Encoder struct { io.Writer } // WriteByte encodes a single byte to the output writer. func (this *Encoder) WriteByte(value byte) (n int, err error) { return this.WriteByte(uint8(value)) } // WriteInt8 encodes an 8-bit signed integer to the output writer. func (this *Encoder) WriteInt8(value int8) (n int, err error) { return this.WriteUint8(uint8(value)) } // WriteUint8 encodes an 8-bit unsigned integer to the output writer. func (this *Encoder) WriteUint8(value uint8) (n int, err error) { return this.Write([]byte { byte(value) }) } // WriteInt16 encodes an 16-bit signed integer to the output writer. func (this *Encoder) WriteInt16(value int16) (n int, err error) { return this.WriteUint16(uint16(value)) } // WriteUint16 encodes an 16-bit unsigned integer to the output writer. func (this *Encoder) WriteUint16(value uint16) (n int, err error) { return this.Write([]byte { byte(value >> 8), byte(value), }) } // WriteInt32 encodes an 32-bit signed integer to the output writer. func (this *Encoder) WriteInt32(value int32) (n int, err error) { return this.WriteUint32(uint32(value)) } // WriteUint32 encodes an 32-bit unsigned integer to the output writer. func (this *Encoder) WriteUint32(value uint32) (n int, err error) { return this.Write([]byte { byte(value >> 24), byte(value >> 16), byte(value >> 8), byte(value), }) } // WriteInt64 encodes an 64-bit signed integer to the output writer. func (this *Encoder) WriteInt64(value int64) (n int, err error) { return this.WriteUint64(uint64(value)) } // WriteUint64 encodes an 64-bit unsigned integer to the output writer. func (this *Encoder) WriteUint64(value uint64) (n int, err error) { return this.Write([]byte { byte(value >> 56), byte(value >> 48), byte(value >> 40), byte(value >> 32), byte(value >> 24), byte(value >> 16), byte(value >> 8), byte(value), }) } // EncodeGBEU encodes a growing unsigned integer of up to 64 bits to the output // writer. func (this *Encoder) EncodeGBEU(value uint64) (n int, err error) { // increase if go somehow gets support for over 64 bit integers. we // could also make an expanding int type in goutil to use here, or maybe // there is one in the stdlib. keep this int64 version as well though // because its ergonomic. buffer := [16]byte { } window := (GBEUSize(value) - 1) * 7 index := 0 for window >= 0 { chunk := uint8(value >> window) & 0x7F if window > 0 { chunk |= 0x80 } buffer[index] = chunk index += 1 window -= 7 } return this.Write(buffer[:]) }