summaryrefslogtreecommitdiff
path: root/src/pkg/gob/encode.go
diff options
context:
space:
mode:
authorRob Pike <r@golang.org>2009-07-28 17:20:19 -0700
committerRob Pike <r@golang.org>2009-07-28 17:20:19 -0700
commit2371820a800563d0a7a5a96e34f9e158bc81eb24 (patch)
treee28e2153d863e5f8d66e6f67ff3d6ea183686f79 /src/pkg/gob/encode.go
parentcc74f077abe6bb64b8200834dc009a426555d17c (diff)
downloadgolang-2371820a800563d0a7a5a96e34f9e158bc81eb24.tar.gz
change the encoding of uints to simplify overflow checking and to make them
easier and faster to read. they are now either a one-byte value or a n-byte value preceded by a byte holding -n. R=rsc DELTA=150 (45 added, 7 deleted, 98 changed) OCL=32381 CL=32387
Diffstat (limited to 'src/pkg/gob/encode.go')
-rw-r--r--src/pkg/gob/encode.go30
1 files changed, 19 insertions, 11 deletions
diff --git a/src/pkg/gob/encode.go b/src/pkg/gob/encode.go
index 0589f3863..be3599770 100644
--- a/src/pkg/gob/encode.go
+++ b/src/pkg/gob/encode.go
@@ -15,6 +15,8 @@ import (
"unsafe";
)
+const uint64Size = unsafe.Sizeof(uint64(0))
+
// The global execution state of an instance of the encoder.
// Field numbers are delta encoded and always increase. The field
// number is initialized to -1 so 0 comes out as delta(1). A delta of
@@ -23,27 +25,33 @@ type encoderState struct {
b *bytes.Buffer;
err os.Error; // error encountered during encoding;
fieldnum int; // the last field number written.
- buf [16]byte; // buffer used by the encoder; here to avoid allocation.
+ buf [1+uint64Size]byte; // buffer used by the encoder; here to avoid allocation.
}
-// Integers encode as a variant of Google's protocol buffer varint (varvarint?).
-// The variant is that the continuation bytes have a zero top bit instead of a one.
-// That way there's only one bit to clear and the value is a little easier to see if
-// you're the unfortunate sort of person who must read the hex to debug.
+// Unsigned integers have a two-state encoding. If the number is less
+// than 128 (0 through 0x7F), its value is written directly.
+// Otherwise the value is written in big-endian byte order preceded
+// by the byte length, negated.
// encodeUint writes an encoded unsigned integer to state.b. Sets state.err.
// If state.err is already non-nil, it does nothing.
func encodeUint(state *encoderState, x uint64) {
- var n int;
if state.err != nil {
return
}
- for n = 0; x > 0x7F; n++ {
- state.buf[n] = uint8(x & 0x7F);
- x >>= 7;
+ if x <= 0x7F {
+ state.err = state.b.WriteByte(uint8(x));
+ return;
+ }
+ var n, m int;
+ m = uint64Size;
+ for n = 1; x > 0; n++ {
+ state.buf[m] = uint8(x & 0xFF);
+ x >>= 8;
+ m--;
}
- state.buf[n] = 0x80 | uint8(x);
- n, state.err = state.b.Write(state.buf[0:n+1]);
+ state.buf[m] = uint8(-(n-1));
+ n, state.err = state.b.Write(state.buf[m:uint64Size+1]);
}
// encodeInt writes an encoded signed integer to state.w.