LEFT | RIGHT |
1 // Copyright 2011 The Go Authors. All rights reserved. | 1 // Copyright 2011 The Go Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style | 2 // Use of this source code is governed by a BSD-style |
3 // license that can be found in the LICENSE file. | 3 // license that can be found in the LICENSE file. |
4 | 4 |
5 package binary | 5 package binary |
6 | 6 |
| 7 // This file implements "varint" encoding of 64-bit integers. |
| 8 // The encoding is: |
| 9 // - unsigned integers are serialized 7 bits at a time, starting with the |
| 10 // least significant bits |
| 11 // - the most significant bit (msb) in each output byte indicates if there |
| 12 // is a continuation byte (msb = 1) |
| 13 // - signed integers are mapped to unsigned integers using "zig-zag" |
| 14 // encoding: Positive values x are written as 2*x + 0, negative values |
| 15 // are written as 2*(^x) + 1; that is, negative numbers are complemented |
| 16 // and whether to complement is encoded in bit 0. |
| 17 // |
| 18 // Design note: |
| 19 // At most 10 bytes are needed for 64-bit values. The encoding could |
| 20 // be more dense: a full 64-bit value needs an extra byte just to hold bit 63. |
| 21 // Instead, the msb of the previous byte could be used to hold bit 63 since we |
| 22 // know there can't be more than 64 bits. This is a trivial improvement and |
| 23 // would reduce the maximum encoding length to 9 bytes. However, it breaks the |
| 24 // invariant that the msb is always the "continuation bit" and thus makes the |
| 25 // format incompatible with a varint encoding for larger numbers (say 128-bit). |
| 26 |
7 import ( | 27 import ( |
8 "io" | 28 "io" |
9 "os" | 29 "os" |
10 ) | 30 ) |
11 | 31 |
12 // PutUint encodes a uint64 into buf and returns the number of bytes written. | 32 // MaxVarintLenN is the maximum length of a varint-encoded N-bit integer. |
13 // If the buffer is to small, the result is 0. | 33 const ( |
14 func PutUint(buf []byte, x uint64) int { | 34 » MaxVarintLen16 = 3 |
15 » for i := range buf { | 35 » MaxVarintLen32 = 5 |
16 » » if x < 128 { | 36 » MaxVarintLen64 = 10 |
| 37 ) |
| 38 |
| 39 // PutUvarint encodes a uint64 into buf and returns the number of bytes written. |
| 40 // If the buffer is too small, the result is the negated number of bytes require
d |
| 41 // (that is, -PutUvarint(nil, x) is the number of bytes required to encode x). |
| 42 func PutUvarint(buf []byte, x uint64) int { |
| 43 » var i int |
| 44 » for i = range buf { |
| 45 » » if x < 0x80 { |
17 buf[i] = byte(x) | 46 buf[i] = byte(x) |
18 return i + 1 | 47 return i + 1 |
19 } | 48 } |
20 » » buf[i] = byte(x) | 128 | 49 » » buf[i] = byte(x) | 0x80 |
21 x >>= 7 | 50 x >>= 7 |
22 } | 51 } |
23 » return 0 // error: buffer too small | 52 » // buffer too small; compute number of bytes required |
| 53 » for x >= 0x4000 { |
| 54 » » x >>= 2 * 7 |
| 55 » » i += 2 |
| 56 » } |
| 57 » if x >= 0x80 { |
| 58 » » i++ |
| 59 » } |
| 60 » return -(i + 1) |
24 } | 61 } |
25 | 62 |
26 // Uint decodes a uint64 from buf and returns that value and the | 63 // Uvarint decodes a uint64 from buf and returns that value and the |
27 // number of bytes read. If the buffer is too small, the value is | 64 // number of bytes read (> 0). If an error occurred, the value is 0 |
28 // undefined and the number of bytes is 0. At most 11 bytes are read. | 65 // and the number of bytes n is <= 0 meaning: |
29 func Uint(buf []byte) (uint64, int) { | 66 // |
| 67 //» n == 0: buf too small |
| 68 //» n < 0: value larger than 64 bits (overflow) |
| 69 // and -n is the number of bytes read |
| 70 // |
| 71 func Uvarint(buf []byte) (uint64, int) { |
30 var x uint64 | 72 var x uint64 |
31 var s uint | 73 var s uint |
32 for i, b := range buf { | 74 for i, b := range buf { |
33 » » if b < 128 || i >= 10 { | 75 » » if b < 0x80 { |
| 76 » » » if i > 9 || i == 9 && b > 1 { |
| 77 » » » » return 0, -(i + 1) // overflow |
| 78 » » » } |
34 return x | uint64(b)<<s, i + 1 | 79 return x | uint64(b)<<s, i + 1 |
35 } | 80 } |
36 » » x |= uint64(b&127) << s | 81 » » x |= uint64(b&0x7f) << s |
37 s += 7 | 82 s += 7 |
38 } | 83 } |
39 » return x, 0 | 84 » return 0, 0 |
40 } | 85 } |
41 | 86 |
42 // PutInt encodes an int64 into buf and returns the number of bytes written. | 87 // PutVarint encodes an int64 into buf and returns the number of bytes written. |
43 // If the buffer is to small, the result is 0. | 88 // If the buffer is too small, the result is the negated number of bytes require
d |
44 func PutInt(buf []byte, x int64) int { | 89 // (that is, -PutVarint(nil, x) is the number of bytes required to encode x). |
| 90 func PutVarint(buf []byte, x int64) int { |
45 ux := uint64(x) << 1 | 91 ux := uint64(x) << 1 |
46 if x < 0 { | 92 if x < 0 { |
47 ux = ^ux | 93 ux = ^ux |
48 } | 94 } |
49 » return PutUint(buf, ux) | 95 » return PutUvarint(buf, ux) |
50 } | 96 } |
51 | 97 |
52 // Int decodes an int64 from buf and returns that value and the | 98 // Varint decodes an int64 from buf and returns that value and the |
53 // number of bytes read. If the buffer is too small, the value is | 99 // number of bytes read (> 0). If an error occurred, the value is 0 |
54 // undefined and the number of bytes is 0. At most 11 bytes are read. | 100 // and the number of bytes n is <= 0 with the following meaning: |
55 func Int(buf []byte) (int64, int) { | 101 // |
56 » ux, n := Uint(buf) // ok to continue in presence of error | 102 //» n == 0: buf too small |
| 103 //» n < 0: value larger than 64 bits (overflow) |
| 104 // and -n is the number of bytes read |
| 105 // |
| 106 func Varint(buf []byte) (int64, int) { |
| 107 » ux, n := Uvarint(buf) // ok to continue in presence of error |
57 x := int64(ux >> 1) | 108 x := int64(ux >> 1) |
58 if ux&1 != 0 { | 109 if ux&1 != 0 { |
59 x = ^x | 110 x = ^x |
60 } | 111 } |
61 return x, n | 112 return x, n |
62 } | 113 } |
63 | 114 |
64 // WriteUint writes a uint64 to w. | 115 // WriteUvarint encodes x and writes the result to w. |
65 func WriteUint(w io.Writer, x uint64) os.Error { | 116 func WriteUvarint(w io.Writer, x uint64) os.Error { |
66 » var buf [10]byte | 117 » var buf [MaxVarintLen64]byte |
67 » n := PutUint(buf[:], x) // won't fail | 118 » n := PutUvarint(buf[:], x) // won't fail |
68 _, err := w.Write(buf[0:n]) | 119 _, err := w.Write(buf[0:n]) |
69 return err | 120 return err |
70 } | 121 } |
71 | 122 |
72 var overflow = os.NewError("overflow: not a 64bit integer") | 123 var overflow = os.NewError("binary: varint overflows a 64-bit integer") |
73 | 124 |
74 // ReadUint reads a uint64 from r. | 125 // ReadUvarint reads an encoded unsigned integer from r and returns it as a uint
64. |
75 func ReadUint(r io.ByteReader) (uint64, os.Error) { | 126 func ReadUvarint(r io.ByteReader) (uint64, os.Error) { |
76 var x uint64 | 127 var x uint64 |
77 var s uint | 128 var s uint |
78 » for i := 0; i < 10; i++ { | 129 » for i := 0; ; i++ { |
79 b, err := r.ReadByte() | 130 b, err := r.ReadByte() |
80 » » if b < 128 || err != nil { | 131 » » if err != nil { |
81 » » » return x | uint64(b)<<s, err | 132 » » » return x, err |
82 } | 133 } |
83 » » x |= uint64(b&127) << s | 134 » » if b < 0x80 { |
| 135 » » » if i > 9 || i == 9 && b > 1 { |
| 136 » » » » return x, overflow |
| 137 » » » } |
| 138 » » » return x | uint64(b)<<s, nil |
| 139 » » } |
| 140 » » x |= uint64(b&0x7f) << s |
84 s += 7 | 141 s += 7 |
85 } | 142 } |
86 » return x, overflow | 143 » panic("unreachable") |
87 } | 144 } |
88 | 145 |
89 // WriteInt writes a uint64 to w. | 146 // WriteVarint encodes x and writes the result to w. |
90 func WriteInt(w io.Writer, x int64) os.Error { | 147 func WriteVarint(w io.Writer, x int64) os.Error { |
91 ux := uint64(x) << 1 | 148 ux := uint64(x) << 1 |
92 if x < 0 { | 149 if x < 0 { |
93 ux = ^ux | 150 ux = ^ux |
94 } | 151 } |
95 » return WriteUint(w, ux) | 152 » return WriteUvarint(w, ux) |
96 } | 153 } |
97 | 154 |
98 // ReadInt reads a uint64 from r. | 155 // ReadVarint reads an encoded unsigned integer from r and returns it as a uint6
4. |
99 func ReadInt(r io.ByteReader) (int64, os.Error) { | 156 func ReadVarint(r io.ByteReader) (int64, os.Error) { |
100 » ux, err := ReadUint(r) // ok to continue in presence of error | 157 » ux, err := ReadUvarint(r) // ok to continue in presence of error |
101 x := int64(ux >> 1) | 158 x := int64(ux >> 1) |
102 if ux&1 != 0 { | 159 if ux&1 != 0 { |
103 x = ^x | 160 x = ^x |
104 } | 161 } |
105 return x, err | 162 return x, err |
106 } | 163 } |
LEFT | RIGHT |