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 19namespace leveldb { 20 21// Standard Put... routines append to a string 22extern void PutFixed32(std::string* dst, uint32_t value); 23extern void PutFixed64(std::string* dst, uint64_t value); 24extern void PutVarint32(std::string* dst, uint32_t value); 25extern void PutVarint64(std::string* dst, uint64_t value); 26extern 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. 30extern bool GetVarint32(Slice* input, uint32_t* value); 31extern bool GetVarint64(Slice* input, uint64_t* value); 32extern 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] 38extern const char* GetVarint32Ptr(const char* p,const char* limit, uint32_t* v); 39extern 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" 42extern 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 46extern void EncodeFixed32(char* dst, uint32_t value); 47extern 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 52extern char* EncodeVarint32(char* dst, uint32_t value); 53extern 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 58inline 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 72inline 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 86extern const char* GetVarint32PtrFallback(const char* p, 87 const char* limit, 88 uint32_t* value); 89inline 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