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  }