OLD | NEW |
(Empty) | |
| 1 // Copyright 2011 The Go Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style |
| 3 // license that can be found in the LICENSE file. |
| 4 |
| 5 package binary |
| 6 |
| 7 import ( |
| 8 "io" |
| 9 "os" |
| 10 ) |
| 11 |
| 12 // PutUint encodes a uint64 into buf and returns the number of bytes written. |
| 13 // If the buffer is to small, the result is 0. |
| 14 func PutUint(buf []byte, x uint64) int { |
| 15 for i := range buf { |
| 16 if x < 128 { |
| 17 buf[i] = byte(x) |
| 18 return i + 1 |
| 19 } |
| 20 buf[i] = byte(x) | 128 |
| 21 x >>= 7 |
| 22 } |
| 23 return 0 // error: buffer too small |
| 24 } |
| 25 |
| 26 // Uint 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 |
| 28 // undefined and the number of bytes is 0. At most 11 bytes are read. |
| 29 func Uint(buf []byte) (uint64, int) { |
| 30 var x uint64 |
| 31 var s uint |
| 32 for i, b := range buf { |
| 33 if b < 128 || i >= 10 { |
| 34 return x | uint64(b)<<s, i + 1 |
| 35 } |
| 36 x |= uint64(b&127) << s |
| 37 s += 7 |
| 38 } |
| 39 return x, 0 |
| 40 } |
| 41 |
| 42 // PutInt encodes an int64 into buf and returns the number of bytes written. |
| 43 // If the buffer is to small, the result is 0. |
| 44 func PutInt(buf []byte, x int64) int { |
| 45 ux := uint64(x) << 1 |
| 46 if x < 0 { |
| 47 ux = ^ux |
| 48 } |
| 49 return PutUint(buf, ux) |
| 50 } |
| 51 |
| 52 // Int 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 |
| 54 // undefined and the number of bytes is 0. At most 11 bytes are read. |
| 55 func Int(buf []byte) (int64, int) { |
| 56 ux, n := Uint(buf) // ok to continue in presence of error |
| 57 x := int64(ux >> 1) |
| 58 if ux&1 != 0 { |
| 59 x = ^x |
| 60 } |
| 61 return x, n |
| 62 } |
| 63 |
| 64 // WriteUint writes a uint64 to w. |
| 65 func WriteUint(w io.Writer, x uint64) os.Error { |
| 66 var buf [10]byte |
| 67 n := PutUint(buf[:], x) // won't fail |
| 68 _, err := w.Write(buf[0:n]) |
| 69 return err |
| 70 } |
| 71 |
| 72 var overflow = os.NewError("overflow: not a 64bit integer") |
| 73 |
| 74 // ReadUint reads a uint64 from r. |
| 75 func ReadUint(r io.ByteReader) (uint64, os.Error) { |
| 76 var x uint64 |
| 77 var s uint |
| 78 for i := 0; i < 10; i++ { |
| 79 b, err := r.ReadByte() |
| 80 if b < 128 || err != nil { |
| 81 return x | uint64(b)<<s, err |
| 82 } |
| 83 x |= uint64(b&127) << s |
| 84 s += 7 |
| 85 } |
| 86 return x, overflow |
| 87 } |
| 88 |
| 89 // WriteInt writes a uint64 to w. |
| 90 func WriteInt(w io.Writer, x int64) os.Error { |
| 91 ux := uint64(x) << 1 |
| 92 if x < 0 { |
| 93 ux = ^ux |
| 94 } |
| 95 return WriteUint(w, ux) |
| 96 } |
| 97 |
| 98 // ReadInt reads a uint64 from r. |
| 99 func ReadInt(r io.ByteReader) (int64, os.Error) { |
| 100 ux, err := ReadUint(r) // ok to continue in presence of error |
| 101 x := int64(ux >> 1) |
| 102 if ux&1 != 0 { |
| 103 x = ^x |
| 104 } |
| 105 return x, err |
| 106 } |
OLD | NEW |