encode.go (4419B)
1 // Copyright 2017 Google Inc. All rights reserved. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package s2 16 17 import ( 18 "encoding/binary" 19 "io" 20 "math" 21 ) 22 23 const ( 24 // encodingVersion is the current version of the encoding 25 // format that is compatible with C++ and other S2 libraries. 26 encodingVersion = int8(1) 27 28 // encodingCompressedVersion is the current version of the 29 // compressed format. 30 encodingCompressedVersion = int8(4) 31 ) 32 33 // encoder handles the specifics of encoding for S2 types. 34 type encoder struct { 35 w io.Writer // the real writer passed to Encode 36 err error 37 } 38 39 func (e *encoder) writeUvarint(x uint64) { 40 if e.err != nil { 41 return 42 } 43 var buf [binary.MaxVarintLen64]byte 44 n := binary.PutUvarint(buf[:], x) 45 _, e.err = e.w.Write(buf[:n]) 46 } 47 48 func (e *encoder) writeBool(x bool) { 49 if e.err != nil { 50 return 51 } 52 var val int8 53 if x { 54 val = 1 55 } 56 e.err = binary.Write(e.w, binary.LittleEndian, val) 57 } 58 59 func (e *encoder) writeInt8(x int8) { 60 if e.err != nil { 61 return 62 } 63 e.err = binary.Write(e.w, binary.LittleEndian, x) 64 } 65 66 func (e *encoder) writeInt16(x int16) { 67 if e.err != nil { 68 return 69 } 70 e.err = binary.Write(e.w, binary.LittleEndian, x) 71 } 72 73 func (e *encoder) writeInt32(x int32) { 74 if e.err != nil { 75 return 76 } 77 e.err = binary.Write(e.w, binary.LittleEndian, x) 78 } 79 80 func (e *encoder) writeInt64(x int64) { 81 if e.err != nil { 82 return 83 } 84 e.err = binary.Write(e.w, binary.LittleEndian, x) 85 } 86 87 func (e *encoder) writeUint8(x uint8) { 88 if e.err != nil { 89 return 90 } 91 _, e.err = e.w.Write([]byte{x}) 92 } 93 94 func (e *encoder) writeUint32(x uint32) { 95 if e.err != nil { 96 return 97 } 98 e.err = binary.Write(e.w, binary.LittleEndian, x) 99 } 100 101 func (e *encoder) writeUint64(x uint64) { 102 if e.err != nil { 103 return 104 } 105 e.err = binary.Write(e.w, binary.LittleEndian, x) 106 } 107 108 func (e *encoder) writeFloat32(x float32) { 109 if e.err != nil { 110 return 111 } 112 e.err = binary.Write(e.w, binary.LittleEndian, x) 113 } 114 115 func (e *encoder) writeFloat64(x float64) { 116 if e.err != nil { 117 return 118 } 119 e.err = binary.Write(e.w, binary.LittleEndian, x) 120 } 121 122 type byteReader interface { 123 io.Reader 124 io.ByteReader 125 } 126 127 // byteReaderAdapter embellishes an io.Reader with a ReadByte method, 128 // so that it implements the io.ByteReader interface. 129 type byteReaderAdapter struct { 130 io.Reader 131 } 132 133 func (b byteReaderAdapter) ReadByte() (byte, error) { 134 buf := []byte{0} 135 _, err := io.ReadFull(b, buf) 136 return buf[0], err 137 } 138 139 func asByteReader(r io.Reader) byteReader { 140 if br, ok := r.(byteReader); ok { 141 return br 142 } 143 return byteReaderAdapter{r} 144 } 145 146 type decoder struct { 147 r byteReader // the real reader passed to Decode 148 err error 149 buf []byte 150 } 151 152 // Get a buffer of size 8, to avoid allocating over and over. 153 func (d *decoder) buffer() []byte { 154 if d.buf == nil { 155 d.buf = make([]byte, 8) 156 } 157 return d.buf 158 } 159 160 func (d *decoder) readBool() (x bool) { 161 if d.err != nil { 162 return 163 } 164 var val int8 165 d.err = binary.Read(d.r, binary.LittleEndian, &val) 166 return val == 1 167 } 168 169 func (d *decoder) readInt8() (x int8) { 170 if d.err != nil { 171 return 172 } 173 d.err = binary.Read(d.r, binary.LittleEndian, &x) 174 return 175 } 176 177 func (d *decoder) readInt64() (x int64) { 178 if d.err != nil { 179 return 180 } 181 d.err = binary.Read(d.r, binary.LittleEndian, &x) 182 return 183 } 184 185 func (d *decoder) readUint8() (x uint8) { 186 if d.err != nil { 187 return 188 } 189 x, d.err = d.r.ReadByte() 190 return 191 } 192 193 func (d *decoder) readUint32() (x uint32) { 194 if d.err != nil { 195 return 196 } 197 d.err = binary.Read(d.r, binary.LittleEndian, &x) 198 return 199 } 200 201 func (d *decoder) readUint64() (x uint64) { 202 if d.err != nil { 203 return 204 } 205 d.err = binary.Read(d.r, binary.LittleEndian, &x) 206 return 207 } 208 209 func (d *decoder) readFloat64() float64 { 210 if d.err != nil { 211 return 0 212 } 213 buf := d.buffer() 214 _, d.err = io.ReadFull(d.r, buf) 215 return math.Float64frombits(binary.LittleEndian.Uint64(buf)) 216 } 217 218 func (d *decoder) readUvarint() (x uint64) { 219 if d.err != nil { 220 return 221 } 222 x, d.err = binary.ReadUvarint(d.r) 223 return 224 }