github.com/insionng/yougam@v0.0.0-20170714101924-2bc18d833463/libraries/pingcap/go-hbase/iohelper/utils.go (about) 1 package iohelper 2 3 import ( 4 "bytes" 5 "encoding/binary" 6 "io" 7 8 "github.com/insionng/yougam/libraries/juju/errors" 9 ) 10 11 var ( 12 cachedItob [][]byte 13 ) 14 15 func init() { 16 cachedItob = make([][]byte, 1024) 17 for i := 0; i < len(cachedItob); i++ { 18 var b bytes.Buffer 19 writeVLong(&b, int64(i)) 20 cachedItob[i] = b.Bytes() 21 } 22 } 23 24 func itob(i int) ([]byte, error) { 25 if i >= 0 && i < len(cachedItob) { 26 return cachedItob[i], nil 27 } 28 29 var b bytes.Buffer 30 err := binary.Write(&b, binary.BigEndian, i) 31 if err != nil { 32 return nil, errors.Trace(err) 33 } 34 return b.Bytes(), nil 35 } 36 37 func decodeVIntSize(value byte) int32 { 38 if int32(value) >= -112 { 39 return int32(1) 40 } 41 42 if int32(value) < -120 { 43 return -119 - int32(value) 44 } 45 46 return -111 - int32(value) 47 } 48 49 func isNegativeVInt(value byte) bool { 50 return int32(value) < -120 || int32(value) >= -112 && int32(value) < 0 51 } 52 53 func readVLong(r io.Reader) (int64, error) { 54 var firstByte byte 55 err := binary.Read(r, binary.BigEndian, &firstByte) 56 if err != nil { 57 return 0, errors.Trace(err) 58 } 59 60 l := decodeVIntSize(firstByte) 61 if l == 1 { 62 return int64(firstByte), nil 63 } 64 65 var ( 66 i int64 67 idx int32 68 ) 69 70 for idx = 0; idx < l-1; idx++ { 71 var b byte 72 err = binary.Read(r, binary.BigEndian, &b) 73 if err != nil { 74 return 0, errors.Trace(err) 75 } 76 77 i <<= 8 78 i |= int64(b & 255) 79 } 80 81 if isNegativeVInt(firstByte) { 82 return ^i, nil 83 } 84 85 return i, nil 86 } 87 88 func writeVLong(w io.Writer, i int64) error { 89 var err error 90 if i >= -112 && i <= 127 { 91 err = binary.Write(w, binary.BigEndian, byte(i)) 92 if err != nil { 93 return errors.Trace(err) 94 } 95 } else { 96 var l int32 = -112 97 if i < 0 { 98 i = ^i 99 l = -120 100 } 101 var tmp int64 102 for tmp = i; tmp != 0; l-- { 103 tmp >>= 8 104 } 105 106 err = binary.Write(w, binary.BigEndian, byte(l)) 107 if err != nil { 108 return errors.Trace(err) 109 } 110 111 if l < -120 { 112 l = -(l + 120) 113 } else { 114 l = -(l + 112) 115 } 116 117 for idx := l; idx != 0; idx-- { 118 var mask int64 119 shiftbits := uint((idx - 1) * 8) 120 mask = int64(255) << shiftbits 121 err = binary.Write(w, binary.BigEndian, byte((i&mask)>>shiftbits)) 122 if err != nil { 123 return errors.Trace(err) 124 } 125 } 126 } 127 128 return nil 129 } 130 131 func ReadVarBytes(r ByteMultiReader) ([]byte, error) { 132 sz, err := readVLong(r) 133 if err != nil { 134 return nil, errors.Trace(err) 135 } 136 137 b := make([]byte, sz) 138 _, err = r.Read(b) 139 if err != nil { 140 return nil, errors.Trace(err) 141 } 142 143 return b, nil 144 } 145 146 func WriteVarBytes(w io.Writer, b []byte) error { 147 lenb, err := itob(len(b)) 148 if err != nil { 149 return errors.Trace(err) 150 } 151 152 _, err = w.Write(lenb) 153 if err != nil { 154 return errors.Trace(err) 155 } 156 157 _, err = w.Write(b) 158 return errors.Trace(err) 159 } 160 161 func ReadInt32(r io.Reader) (int32, error) { 162 var n int32 163 err := binary.Read(r, binary.BigEndian, &n) 164 return n, errors.Trace(err) 165 } 166 167 func ReadN(r io.Reader, n int32) ([]byte, error) { 168 b := make([]byte, n) 169 _, err := io.ReadFull(r, b) 170 return b, errors.Trace(err) 171 } 172 173 func ReadUint64(r io.Reader) (uint64, error) { 174 var n uint64 175 err := binary.Read(r, binary.BigEndian, &n) 176 return n, errors.Trace(err) 177 }