Big nasty commit to add code generation for encoding
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
21
codec/measure_test.go
Normal 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)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user