gtsocial-umbx

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

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 }