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_ 105