github.com/cellofellow/gopkg@v0.0.0-20140722061823-eec0544a62ad/database/leveldb/include/util/coding.h (about)

     1  // Copyright (c) 2011 The LevelDB Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style license that can be
     3  // found in the LICENSE file. See the AUTHORS file for names of contributors.
     4  //
     5  // Endian-neutral encoding:
     6  // * Fixed-length numbers are encoded with least-significant byte first
     7  // * In addition we support variable length "varint" encoding
     8  // * Strings are encoded prefixed by their length in varint format
     9  
    10  #ifndef STORAGE_LEVELDB_UTIL_CODING_H_
    11  #define STORAGE_LEVELDB_UTIL_CODING_H_
    12  
    13  #include <stdint.h>
    14  #include <string.h>
    15  #include <string>
    16  #include "leveldb/slice.h"
    17  #include "port/port.h"
    18  
    19  namespace leveldb {
    20  
    21  // Standard Put... routines append to a string
    22  extern void PutFixed32(std::string* dst, uint32_t value);
    23  extern void PutFixed64(std::string* dst, uint64_t value);
    24  extern void PutVarint32(std::string* dst, uint32_t value);
    25  extern void PutVarint64(std::string* dst, uint64_t value);
    26  extern void PutLengthPrefixedSlice(std::string* dst, const Slice& value);
    27  
    28  // Standard Get... routines parse a value from the beginning of a Slice
    29  // and advance the slice past the parsed value.
    30  extern bool GetVarint32(Slice* input, uint32_t* value);
    31  extern bool GetVarint64(Slice* input, uint64_t* value);
    32  extern bool GetLengthPrefixedSlice(Slice* input, Slice* result);
    33  
    34  // Pointer-based variants of GetVarint...  These either store a value
    35  // in *v and return a pointer just past the parsed value, or return
    36  // NULL on error.  These routines only look at bytes in the range
    37  // [p..limit-1]
    38  extern const char* GetVarint32Ptr(const char* p,const char* limit, uint32_t* v);
    39  extern const char* GetVarint64Ptr(const char* p,const char* limit, uint64_t* v);
    40  
    41  // Returns the length of the varint32 or varint64 encoding of "v"
    42  extern int VarintLength(uint64_t v);
    43  
    44  // Lower-level versions of Put... that write directly into a character buffer
    45  // REQUIRES: dst has enough space for the value being written
    46  extern void EncodeFixed32(char* dst, uint32_t value);
    47  extern void EncodeFixed64(char* dst, uint64_t value);
    48  
    49  // Lower-level versions of Put... that write directly into a character buffer
    50  // and return a pointer just past the last byte written.
    51  // REQUIRES: dst has enough space for the value being written
    52  extern char* EncodeVarint32(char* dst, uint32_t value);
    53  extern char* EncodeVarint64(char* dst, uint64_t value);
    54  
    55  // Lower-level versions of Get... that read directly from a character buffer
    56  // without any bounds checking.
    57  
    58  inline uint32_t DecodeFixed32(const char* ptr) {
    59    if (port::kLittleEndian) {
    60      // Load the raw bytes
    61      uint32_t result;
    62      memcpy(&result, ptr, sizeof(result));  // gcc optimizes this to a plain load
    63      return result;
    64    } else {
    65      return ((static_cast<uint32_t>(static_cast<unsigned char>(ptr[0])))
    66          | (static_cast<uint32_t>(static_cast<unsigned char>(ptr[1])) << 8)
    67          | (static_cast<uint32_t>(static_cast<unsigned char>(ptr[2])) << 16)
    68          | (static_cast<uint32_t>(static_cast<unsigned char>(ptr[3])) << 24));
    69    }
    70  }
    71  
    72  inline uint64_t DecodeFixed64(const char* ptr) {
    73    if (port::kLittleEndian) {
    74      // Load the raw bytes
    75      uint64_t result;
    76      memcpy(&result, ptr, sizeof(result));  // gcc optimizes this to a plain load
    77      return result;
    78    } else {
    79      uint64_t lo = DecodeFixed32(ptr);
    80      uint64_t hi = DecodeFixed32(ptr + 4);
    81      return (hi << 32) | lo;
    82    }
    83  }
    84  
    85  // Internal routine for use by fallback path of GetVarint32Ptr
    86  extern const char* GetVarint32PtrFallback(const char* p,
    87                                            const char* limit,
    88                                            uint32_t* value);
    89  inline const char* GetVarint32Ptr(const char* p,
    90                                    const char* limit,
    91                                    uint32_t* value) {
    92    if (p < limit) {
    93      uint32_t result = *(reinterpret_cast<const unsigned char*>(p));
    94      if ((result & 128) == 0) {
    95        *value = result;
    96        return p + 1;
    97      }
    98    }
    99    return GetVarint32PtrFallback(p, limit, value);
   100  }
   101  
   102  }  // namespace leveldb
   103  
   104  #endif  // STORAGE_LEVELDB_UTIL_CODING_H_