Merge codec and tape packages
This commit is contained in:
120
tape/encode.go
Normal file
120
tape/encode.go
Normal file
@@ -0,0 +1,120 @@
|
||||
package tape
|
||||
|
||||
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),
|
||||
})
|
||||
}
|
||||
|
||||
// WriteIntN encodes an N-byte signed integer to the output writer.
|
||||
func (this *Encoder) WriteIntN(value int64, bytes int) (n int, err error) {
|
||||
return this.WriteUintN(uint64(value), bytes)
|
||||
}
|
||||
|
||||
// for below functions, increase buffers 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 the int64 versions as well though
|
||||
// because its ergonomic.
|
||||
|
||||
// WriteUintN encodes an N-byte unsigned integer to the output writer.
|
||||
func (this *Encoder) WriteUintN(value uint64, bytes int) (n int, err error) {
|
||||
// TODO: don't make multiple write calls (without allocating)
|
||||
buffer := [1]byte { }
|
||||
for bytesLeft := bytes; bytesLeft > 0; bytesLeft -- {
|
||||
buffer[0] = byte(buffer[0]) >> ((bytesLeft - 1) * 8)
|
||||
nn, err := this.Write(buffer[:])
|
||||
n += nn; if err != nil { return n, err }
|
||||
}
|
||||
return n, nil
|
||||
}
|
||||
|
||||
// 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) {
|
||||
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[:])
|
||||
}
|
||||
Reference in New Issue
Block a user