Big nasty commit to add code generation for encoding

This commit is contained in:
2025-06-20 15:05:58 -04:00
parent a1f297e5b5
commit ce503c4689
9 changed files with 786 additions and 35 deletions

View File

@@ -81,7 +81,7 @@ func (this *Decoder) ReadUint64() (value uint64, n int, err error) {
n, err = this.ReadFull(buffer[:])
return uint64(buffer[0]) << 56 |
uint64(buffer[1]) << 48 |
uint64(buffer[2]) << 48 |
uint64(buffer[2]) << 40 |
uint64(buffer[3]) << 32 |
uint64(buffer[4]) << 24 |
uint64(buffer[5]) << 16 |
@@ -89,14 +89,33 @@ func (this *Decoder) ReadUint64() (value uint64, n int, err error) {
uint64(buffer[7]), n, err
}
// ReadIntN decodes an N-byte signed integer from the input reader.
func (this *Decoder) ReadIntN(bytes int) (value int64, n int, err error) {
uncasted, n, err := this.ReadUintN(bytes)
return int64(uncasted), n, err
}
// ReadUintN decodes an N-byte unsigned integer from the input reader.
func (this *Decoder) ReadUintN(bytes int) (value uint64, n int, err error) {
// TODO: don't make multiple read calls (without allocating)
buffer := [1]byte { }
for bytesLeft := bytes; bytesLeft > 0; bytesLeft -- {
nn, err := this.ReadFull(buffer[:])
n += nn; if err != nil { return 0, n, err }
value |= uint64(buffer[0]) << ((bytesLeft - 1) * 8)
}
// *read* integers too big, but don't return them.
if bytes > 8 { value = 0 }
return value, n, nil
}
// ReadGBEU decodes a growing unsigned integer of up to 64 bits from the input
// reader.
func (this *Decoder) ReadGBEU() (value uint64, n int, err error) {
var fullValue uint64
for {
chunk, nn, err := this.ReadByte()
if err != nil { return 0, n, err }
n += nn
n += nn; if err != nil { return 0, n, err }
fullValue *= 0x80
fullValue += uint64(chunk & 0x7F)

View File

@@ -76,13 +76,31 @@ func (this *Encoder) WriteUint64(value uint64) (n int, err error) {
})
}
// 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) {
// 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

View File

@@ -9,3 +9,14 @@ func GBEUSize(value uint64) int {
if value == 0 { return length }
}
}
// IntBytes returns the number of bytes required to hold a given unsigned
// integer.
func IntBytes(value uint64) int {
bytes := 0
for value > 0 || bytes == 0 {
value >>= 8;
bytes ++
}
return bytes
}

21
codec/measure_test.go Normal file
View File

@@ -0,0 +1,21 @@
package codec
import "testing"
func TestIntBytes(test *testing.T) {
if correct, got := 1, IntBytes(0); correct != got {
test.Fatal("wrong:", got)
}
if correct, got := 1, IntBytes(1); correct != got {
test.Fatal("wrong:", got)
}
if correct, got := 1, IntBytes(16); correct != got {
test.Fatal("wrong:", got)
}
if correct, got := 1, IntBytes(255); correct != got {
test.Fatal("wrong:", got)
}
if correct, got := 2, IntBytes(256); correct != got {
test.Fatal("wrong:", got)
}
}