2
// Copyright 2000 - 2003 Google Inc.
5
// This holds the encoding/decoding routines that used to live in netutil
7
#ifndef UTIL_CODING_CODER_H__
8
#define UTIL_CODING_CODER_H__
16
#include "util/coding/varint.h"
17
#include "base/logging.h"
18
#include "base/port.h"
19
#include "util/endian/endian.h"
21
/* Class for encoding data into a memory buffer */
24
// Creates an empty Encoder with no room that is enlarged
25
// (if necessary) when "Encoder::Ensure(N)" is called.
29
// Initialize encoder to encode into "buf"
30
explicit Encoder(void* buf, int maxn);
31
void reset(void* buf, int maxn);
34
// Encoding routines. Note that these do not check bounds
35
void put8(unsigned char v);
39
void putword(uword_t v);
40
void putn(const void* mem, int n);
42
// put no more than n bytes, stopping when c is put
43
void putcn(const void* mem, int c, int n);
45
void puts(const void* mem); // put a c-string including \0
46
void puts_without_null(const char* mem); // put a c-string without \0
47
void putfloat(float f);
48
void putdouble(double d);
50
// Support for variable length encoding with 7 bits per byte
51
// (these are just simple wrappers around the Varint module)
52
static const int kVarintMax32; // = Varint::kMax32;
53
static const int kVarintMax64; // = Varint::kMax64;
55
void put_varint32(uint32 v);
56
void put_varint64(uint64 v);
57
static int varint32_length(uint32 v); // Length of var encoding of "v"
58
static int varint64_length(uint64 v); // Length of var encoding of "v"
62
// For new code use put_varint32(ZigZagEncode(signed_value));
63
// ZigZag coding is defined in utils/coding/transforms.h
64
void put_varsigned32(int32 v);
66
// Return number of bytes encoded so far
69
// Return number of bytes of space remaining in buffer
72
// REQUIRES: Encoder was created with the 0-argument constructor interface.
74
// This interface ensures that at least "N" more bytes are available
75
// in the underlying buffer by resizing the buffer (if necessary).
77
// Note that no bounds checking is done on any of the put routines,
78
// so it is the client's responsibility to call Ensure() at
79
// appropriate intervals to ensure that enough space is available
80
// for the data being added.
83
// Returns true if Ensure is allowed to be called on "this"
84
bool ensure_allowed() const { return underlying_buffer_ != NULL; }
86
// Return ptr to start of encoded data. This pointer remains valid
87
// until reset or Ensure is called.
88
const char* base() const { return (const char*)orig_; }
90
// Advances the write pointer by "N" bytes.
91
void skip(int N) { buf_ += N; }
93
// REQUIRES: length() >= N
94
// Removes the last N bytes out of the encoded buffer
95
void RemoveLast(int N);
97
// REQUIRES: length() >= N
98
// Removes the last length()-N bytes to make the encoded buffer have length N
102
void EnsureSlowPath(int N);
104
unsigned char* orig_;
106
unsigned char* limit_;
108
// If constructed with the zero-argument constructor, we're allowed
109
// to use Ensure; otherwise we're not. If Ensure is allowed,
110
// underlying_buffer_ is non-NULL; otherwise it is set to NULL.
111
unsigned char* underlying_buffer_;
113
static unsigned char kEmptyBuffer;
115
DISALLOW_EVIL_CONSTRUCTORS(Encoder);
118
/* Class for decoding data from a memory buffer */
121
// Empty constructor to create uninitialized decoder
124
// NOTE: for efficiency reasons, this is not virtual. so don't add
125
// any members that really need to be destructed, and be careful about
129
// Initialize decoder to decode from "buf"
130
explicit Decoder(const void* buf, int maxn);
131
void reset(const void* buf, int maxn);
133
// Decoding routines. Note that these do not check bounds
134
unsigned char get8();
141
void getn(void* mem, int n);
142
void getcn(void* mem, int c, int n); // get no more than n bytes,
143
// stopping after c is got
144
void gets(void* mem, int n); // get a c-string no more than
145
// n bytes. always appends '\0'
147
unsigned char const* ptr(); // Return ptr to current position in buffer
149
// "get_varint" actually checks bounds
150
bool get_varint32(uint32* v);
151
bool get_varint64(uint64* v);
156
// get_varint32(&unsigned_temp);
157
// signed_value = ZigZagDecode(unsigned_temp);
158
// ZigZag coding is defined in utils/coding/transforms.h
159
bool get_varsigned32(int32* v);
162
// Return number of bytes decoded so far
165
// Return number of available bytes to read
168
friend class IndexBlockDecoder;
169
const unsigned char* orig_;
170
const unsigned char* buf_;
171
const unsigned char* limit_;
173
DECLARE_POD(Decoder); // so then we might as well be a POD
175
/***** Implementation details. Clients should ignore them. *****/
177
inline Encoder::Encoder(void* b, int maxn) {
178
orig_ = buf_ = reinterpret_cast<unsigned char*>(b);
179
limit_ = orig_ + maxn;
180
underlying_buffer_ = NULL;
183
inline void Encoder::reset(void* b, int maxn) {
184
orig_ = buf_ = reinterpret_cast<unsigned char*>(b);
185
limit_ = orig_ + maxn;
186
// Can't use the underlying buffer anymore
187
if (underlying_buffer_ != &kEmptyBuffer) {
188
delete[] underlying_buffer_;
190
underlying_buffer_ = NULL;
193
inline void Encoder::clear() {
197
inline void Encoder::Ensure(int N) {
198
DCHECK(ensure_allowed());
204
inline int Encoder::length() const {
205
return (buf_ - orig_);
208
inline int Encoder::avail() const {
209
return (limit_ - buf_);
212
inline void Encoder::putn(const void* src, int n) {
213
memcpy(buf_, src, n);
217
inline void Encoder::putcn(const void* src, int c, int n) {
218
unsigned char *old = buf_;
219
buf_ = static_cast<unsigned char *>(memccpy(buf_, src, c, n));
224
inline void Encoder::puts(const void* src) {
225
putcn(src, '\0', limit_ - buf_);
228
inline void Encoder::puts_without_null(const char* mem) {
229
while (*mem != '\0' && buf_ < limit_) {
234
inline void Encoder::put_varint32(uint32 v) {
235
buf_ = reinterpret_cast<unsigned char*>
236
(Varint::Encode32(reinterpret_cast<char*>(buf_), v));
239
inline void Encoder::put_varint64(uint64 v) {
240
buf_ = reinterpret_cast<unsigned char*>
241
(Varint::Encode64(reinterpret_cast<char*>(buf_), v));
246
// For new code use put_varint32(ZigZagEncode(signed_value));
247
// ZigZag coding is defined in utils/coding/transforms.h
248
inline void Encoder::put_varsigned32(int32 n) {
249
// Encode sign in low-bit
250
int sign = (n < 0) ? 1 : 0;
251
uint32 mag = (n < 0) ? -n : n;
252
put_varint32((mag << 1) | sign);
255
inline Decoder::Decoder(const void* b, int maxn) {
256
orig_ = buf_ = reinterpret_cast<const unsigned char*>(b);
257
limit_ = orig_ + maxn;
260
inline void Decoder::reset(const void* b, int maxn) {
261
orig_ = buf_ = reinterpret_cast<const unsigned char*>(b);
262
limit_ = orig_ + maxn;
265
inline int Decoder::pos() const {
266
return (buf_ - orig_);
269
inline int Decoder::avail() const {
270
return (limit_ - buf_);
273
inline void Decoder::getn(void* dst, int n) {
274
memcpy(dst, buf_, n);
278
inline void Decoder::getcn(void* dst, int c, int n) {
280
ptr = memccpy(dst, buf_, c, n);
284
buf_ = buf_ + (reinterpret_cast<unsigned char *>(ptr) -
285
reinterpret_cast<unsigned char *>(dst));
288
inline void Decoder::gets(void* dst, int n) {
289
int len = min<int>((n - 1), (limit_ - buf_));
290
(reinterpret_cast<char *>(dst))[len] = '\0';
291
getcn(dst, '\0', len);
294
inline void Decoder::skip(int n) {
298
inline unsigned char const* Decoder::ptr() {
306
// get_varint32(&unsigned_temp);
307
// signed_value = ZigZagDecode(unsigned_temp);
308
// ZigZag coding is defined in utils/coding/transforms.h
309
inline bool Decoder::get_varsigned32(int32* v) {
311
if (get_varint32(&coding)) {
312
int sign = coding & 1;
313
int32 mag = coding >> 1;
315
// Special handling for encoding of kint32min
316
*v = (mag == 0) ? kint32min : -mag;
326
inline void Encoder::put8(unsigned char v) {
327
DCHECK_GE((size_t)avail(), sizeof(v));
332
inline void Encoder::put16(uint16 v) {
333
DCHECK_GE((size_t)avail(), sizeof(v));
334
LittleEndian::Store16(buf_, v);
338
inline void Encoder::put32(uint32 v) {
339
DCHECK_GE((size_t)avail(), sizeof(v));
340
LittleEndian::Store32(buf_, v);
344
inline void Encoder::put64(uint64 v) {
345
DCHECK_GE((size_t)avail(), sizeof(v));
346
LittleEndian::Store64(buf_, v);
350
inline void Encoder::putword(uword_t v) {
352
LittleEndian::Store64(buf_, v);
354
LittleEndian::Store32(buf_, v);
359
inline void Encoder::putfloat(float f) {
361
typedef char VerifySizesAreEqual[sizeof(f) == sizeof(v) ? 1 : -1];
362
memcpy(&v, &f, sizeof(f));
366
inline void Encoder::putdouble(double d) {
368
typedef char VerifySizesAreEqual[sizeof(d) == sizeof(v) ? 1 : -1];
369
memcpy(&v, &d, sizeof(d));
373
inline unsigned char Decoder::get8() {
374
const unsigned char v = *buf_;
379
inline uint16 Decoder::get16() {
380
const uint16 v = LittleEndian::Load16(buf_);
385
inline uint32 Decoder::get32() {
386
const uint32 v = LittleEndian::Load32(buf_);
391
inline uint64 Decoder::get64() {
392
const uint64 v = LittleEndian::Load64(buf_);
397
inline uword_t Decoder::getword() {
399
const uword_t v = LittleEndian::Load64(buf_);
401
const uword_t v = LittleEndian::Load32(buf_);
408
inline float Decoder::getfloat() {
411
typedef char VerifySizesAreEqual[sizeof(f) == sizeof(v) ? 1 : -1];
412
memcpy(&f, &v, sizeof(f));
416
inline double Decoder::getdouble() {
419
typedef char VerifySizesAreEqual[sizeof(d) == sizeof(v) ? 1 : -1];
420
memcpy(&d, &v, sizeof(d));
424
#endif // UTIL_CODING_CODER_H__