github.com/insionng/yougam@v0.0.0-20170714101924-2bc18d833463/libraries/pingcap/tidb/util/codec/number.go (about)

     1  // Copyright 2015 PingCAP, Inc.
     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  // See the License for the specific language governing permissions and
    12  // limitations under the License.
    13  
    14  package codec
    15  
    16  import (
    17  	"encoding/binary"
    18  
    19  	"github.com/insionng/yougam/libraries/juju/errors"
    20  )
    21  
    22  const signMask uint64 = 0x8000000000000000
    23  
    24  func encodeIntToCmpUint(v int64) uint64 {
    25  	return uint64(v) ^ signMask
    26  }
    27  
    28  func decodeCmpUintToInt(u uint64) int64 {
    29  	return int64(u ^ signMask)
    30  }
    31  
    32  // EncodeInt appends the encoded value to slice b and returns the appended slice.
    33  // EncodeInt guarantees that the encoded value is in ascending order for comparison.
    34  func EncodeInt(b []byte, v int64) []byte {
    35  	var data [8]byte
    36  	u := encodeIntToCmpUint(v)
    37  	binary.BigEndian.PutUint64(data[:], u)
    38  	return append(b, data[:]...)
    39  }
    40  
    41  // EncodeIntDesc appends the encoded value to slice b and returns the appended slice.
    42  // EncodeIntDesc guarantees that the encoded value is in descending order for comparison.
    43  func EncodeIntDesc(b []byte, v int64) []byte {
    44  	var data [8]byte
    45  	u := encodeIntToCmpUint(v)
    46  	binary.BigEndian.PutUint64(data[:], ^u)
    47  	return append(b, data[:]...)
    48  }
    49  
    50  // DecodeInt decodes value encoded by EncodeInt before.
    51  // It returns the leftover un-decoded slice, decoded value if no error.
    52  func DecodeInt(b []byte) ([]byte, int64, error) {
    53  	if len(b) < 8 {
    54  		return nil, 0, errors.New("insufficient bytes to decode value")
    55  	}
    56  
    57  	u := binary.BigEndian.Uint64(b[:8])
    58  	v := decodeCmpUintToInt(u)
    59  	b = b[8:]
    60  	return b, v, nil
    61  }
    62  
    63  // DecodeIntDesc decodes value encoded by EncodeInt before.
    64  // It returns the leftover un-decoded slice, decoded value if no error.
    65  func DecodeIntDesc(b []byte) ([]byte, int64, error) {
    66  	if len(b) < 8 {
    67  		return nil, 0, errors.New("insufficient bytes to decode value")
    68  	}
    69  
    70  	u := binary.BigEndian.Uint64(b[:8])
    71  	v := decodeCmpUintToInt(^u)
    72  	b = b[8:]
    73  	return b, v, nil
    74  }
    75  
    76  // EncodeUint appends the encoded value to slice b and returns the appended slice.
    77  // EncodeUint guarantees that the encoded value is in ascending order for comparison.
    78  func EncodeUint(b []byte, v uint64) []byte {
    79  	var data [8]byte
    80  	binary.BigEndian.PutUint64(data[:], v)
    81  	return append(b, data[:]...)
    82  }
    83  
    84  // EncodeUintDesc appends the encoded value to slice b and returns the appended slice.
    85  // EncodeUintDesc guarantees that the encoded value is in descending order for comparison.
    86  func EncodeUintDesc(b []byte, v uint64) []byte {
    87  	var data [8]byte
    88  	binary.BigEndian.PutUint64(data[:], ^v)
    89  	return append(b, data[:]...)
    90  }
    91  
    92  // DecodeUint decodes value encoded by EncodeUint before.
    93  // It returns the leftover un-decoded slice, decoded value if no error.
    94  func DecodeUint(b []byte) ([]byte, uint64, error) {
    95  	if len(b) < 8 {
    96  		return nil, 0, errors.New("insufficient bytes to decode value")
    97  	}
    98  
    99  	v := binary.BigEndian.Uint64(b[:8])
   100  	b = b[8:]
   101  	return b, v, nil
   102  }
   103  
   104  // DecodeUintDesc decodes value encoded by EncodeInt before.
   105  // It returns the leftover un-decoded slice, decoded value if no error.
   106  func DecodeUintDesc(b []byte) ([]byte, uint64, error) {
   107  	if len(b) < 8 {
   108  		return nil, 0, errors.New("insufficient bytes to decode value")
   109  	}
   110  
   111  	data := b[:8]
   112  	v := binary.BigEndian.Uint64(data)
   113  	b = b[8:]
   114  	return b, ^v, nil
   115  }
   116  
   117  // EncodeVarint appends the encoded value to slice b and returns the appended slice.
   118  // Note that the encoded result is not memcomparable.
   119  func EncodeVarint(b []byte, v int64) []byte {
   120  	var data [binary.MaxVarintLen64]byte
   121  	n := binary.PutVarint(data[:], v)
   122  	return append(b, data[:n]...)
   123  }
   124  
   125  // DecodeVarint decodes value encoded by EncodeVarint before.
   126  // It returns the leftover un-decoded slice, decoded value if no error.
   127  func DecodeVarint(b []byte) ([]byte, int64, error) {
   128  	v, n := binary.Varint(b)
   129  	if n > 0 {
   130  		return b[n:], v, nil
   131  	}
   132  	if n < 0 {
   133  		return nil, 0, errors.New("value larger than 64 bits")
   134  	}
   135  	return nil, 0, errors.New("insufficient bytes to decode value")
   136  }
   137  
   138  // EncodeUvarint appends the encoded value to slice b and returns the appended slice.
   139  // Note that the encoded result is not memcomparable.
   140  func EncodeUvarint(b []byte, v uint64) []byte {
   141  	var data [binary.MaxVarintLen64]byte
   142  	n := binary.PutUvarint(data[:], v)
   143  	return append(b, data[:n]...)
   144  }
   145  
   146  // DecodeUvarint decodes value encoded by EncodeUvarint before.
   147  // It returns the leftover un-decoded slice, decoded value if no error.
   148  func DecodeUvarint(b []byte) ([]byte, uint64, error) {
   149  	v, n := binary.Uvarint(b)
   150  	if n > 0 {
   151  		return b[n:], v, nil
   152  	}
   153  	if n < 0 {
   154  		return nil, 0, errors.New("value larger than 64 bits")
   155  	}
   156  	return nil, 0, errors.New("insufficient bytes to decode value")
   157  }