~evarlast/ubuntu/utopic/mongodb/upstart-workaround-debian-bug-718702

« back to all changes in this revision

Viewing changes to src/third_party/s2/util/coding/coder.h

  • Committer: Package Import Robot
  • Author(s): James Page, James Page, Robie Basak
  • Date: 2013-05-29 17:44:42 UTC
  • mfrom: (44.1.7 sid)
  • Revision ID: package-import@ubuntu.com-20130529174442-z0a4qmoww4y0t458
Tags: 1:2.4.3-1ubuntu1
[ James Page ]
* Merge from Debian unstable, remaining changes:
  - Enable SSL support:
    + d/control: Add libssl-dev to BD's.
    + d/rules: Enabled --ssl option.
    + d/mongodb.conf: Add example SSL configuration options.
  - d/mongodb-server.mongodb.upstart: Add upstart configuration.
  - d/rules: Don't strip binaries during scons build for Ubuntu.
  - d/control: Add armhf to target archs.
  - d/p/SConscript.client.patch: fixup install of client libraries.
  - d/p/0010-install-libs-to-usr-lib-not-usr-lib64-Closes-588557.patch:
    Install libraries to lib not lib64.
* Dropped changes:
  - d/p/arm-support.patch: Included in Debian.
  - d/p/double-alignment.patch: Included in Debian.
  - d/rules,control: Debian also builds with avaliable system libraries
    now.
* Fix FTBFS due to gcc and boost upgrades in saucy:
  - d/p/0008-ignore-unused-local-typedefs.patch: Add -Wno-unused-typedefs
    to unbreak building with g++-4.8.
  - d/p/0009-boost-1.53.patch: Fixup signed/unsigned casting issue.

[ Robie Basak ]
* d/p/0011-Use-a-signed-char-to-store-BSONType-enumerations.patch: Fixup
  build failure on ARM due to missing signed'ness of char cast.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
//
 
2
// Copyright 2000 - 2003 Google Inc.
 
3
//
 
4
//
 
5
// This holds the encoding/decoding routines that used to live in netutil
 
6
 
 
7
#ifndef UTIL_CODING_CODER_H__
 
8
#define UTIL_CODING_CODER_H__
 
9
 
 
10
#include <algorithm>
 
11
using std::min;
 
12
using std::max;
 
13
using std::swap;
 
14
using std::reverse;
 
15
        // for min
 
16
#include "util/coding/varint.h"
 
17
#include "base/logging.h"
 
18
#include "base/port.h"
 
19
#include "util/endian/endian.h"
 
20
 
 
21
/* Class for encoding data into a memory buffer */
 
22
class Encoder {
 
23
 public:
 
24
  // Creates an empty Encoder with no room that is enlarged
 
25
  // (if necessary) when "Encoder::Ensure(N)" is called.
 
26
  Encoder();
 
27
  ~Encoder();
 
28
 
 
29
  // Initialize encoder to encode into "buf"
 
30
  explicit Encoder(void* buf, int maxn);
 
31
  void reset(void* buf, int maxn);
 
32
  void clear();
 
33
 
 
34
  // Encoding routines.  Note that these do not check bounds
 
35
  void put8(unsigned char v);
 
36
  void put16(uint16 v);
 
37
  void put32(uint32 v);
 
38
  void put64(uint64 v);
 
39
  void putword(uword_t v);
 
40
  void putn(const void* mem, int n);
 
41
 
 
42
  // put no more than n bytes, stopping when c is put
 
43
  void putcn(const void* mem, int c, int n);
 
44
 
 
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);
 
49
 
 
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;
 
54
 
 
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"
 
59
 
 
60
  // DEPRECATED
 
61
  //
 
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);
 
65
 
 
66
  // Return number of bytes encoded so far
 
67
  int length() const;
 
68
 
 
69
  // Return number of bytes of space remaining in buffer
 
70
  int avail() const;
 
71
 
 
72
  // REQUIRES: Encoder was created with the 0-argument constructor interface.
 
73
  //
 
74
  // This interface ensures that at least "N" more bytes are available
 
75
  // in the underlying buffer by resizing the buffer (if necessary).
 
76
  //
 
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.
 
81
  void Ensure(int N);
 
82
 
 
83
  // Returns true if Ensure is allowed to be called on "this"
 
84
  bool ensure_allowed() const { return underlying_buffer_ != NULL; }
 
85
 
 
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_; }
 
89
 
 
90
  // Advances the write pointer by "N" bytes.
 
91
  void skip(int N) { buf_ += N; }
 
92
 
 
93
  // REQUIRES: length() >= N
 
94
  // Removes the last N bytes out of the encoded buffer
 
95
  void RemoveLast(int N);
 
96
 
 
97
  // REQUIRES: length() >= N
 
98
  // Removes the last length()-N bytes to make the encoded buffer have length N
 
99
  void Resize(int N);
 
100
 
 
101
 private:
 
102
  void EnsureSlowPath(int N);
 
103
 
 
104
  unsigned char* orig_;
 
105
  unsigned char* buf_;
 
106
  unsigned char* limit_;
 
107
 
 
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_;
 
112
 
 
113
  static unsigned char kEmptyBuffer;
 
114
 
 
115
  DISALLOW_EVIL_CONSTRUCTORS(Encoder);
 
116
};
 
117
 
 
118
/* Class for decoding data from a memory buffer */
 
119
class Decoder {
 
120
 public:
 
121
  // Empty constructor to create uninitialized decoder
 
122
  inline Decoder() { }
 
123
 
 
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
 
126
  // inheritance.
 
127
  ~Decoder() { }
 
128
 
 
129
  // Initialize decoder to decode from "buf"
 
130
  explicit Decoder(const void* buf, int maxn);
 
131
  void reset(const void* buf, int maxn);
 
132
 
 
133
  // Decoding routines.  Note that these do not check bounds
 
134
  unsigned char  get8();
 
135
  uint16 get16();
 
136
  uint32 get32();
 
137
  uint64 get64();
 
138
  uword_t getword();
 
139
  float  getfloat();
 
140
  double getdouble();
 
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'
 
146
  void   skip(int n);
 
147
  unsigned char const* ptr();       // Return ptr to current position in buffer
 
148
 
 
149
  // "get_varint" actually checks bounds
 
150
  bool get_varint32(uint32* v);
 
151
  bool get_varint64(uint64* v);
 
152
 
 
153
  // DEPRECATED
 
154
  //
 
155
  // For new code use
 
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);
 
160
 
 
161
  int pos() const;
 
162
  // Return number of bytes decoded so far
 
163
 
 
164
  int avail() const;
 
165
  // Return number of available bytes to read
 
166
 
 
167
 private:
 
168
  friend class IndexBlockDecoder;
 
169
  const unsigned char* orig_;
 
170
  const unsigned char* buf_;
 
171
  const unsigned char* limit_;
 
172
};
 
173
DECLARE_POD(Decoder);  // so then we might as well be a POD
 
174
 
 
175
/***** Implementation details.  Clients should ignore them. *****/
 
176
 
 
177
inline Encoder::Encoder(void* b, int maxn) {
 
178
  orig_ = buf_ = reinterpret_cast<unsigned char*>(b);
 
179
  limit_ = orig_ + maxn;
 
180
  underlying_buffer_ = NULL;
 
181
}
 
182
 
 
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_;
 
189
  }
 
190
  underlying_buffer_ = NULL;
 
191
}
 
192
 
 
193
inline void Encoder::clear() {
 
194
  buf_ = orig_;
 
195
}
 
196
 
 
197
inline void Encoder::Ensure(int N) {
 
198
  DCHECK(ensure_allowed());
 
199
  if (avail() < N) {
 
200
    EnsureSlowPath(N);
 
201
  }
 
202
}
 
203
 
 
204
inline int Encoder::length() const {
 
205
  return (buf_ - orig_);
 
206
}
 
207
 
 
208
inline int Encoder::avail() const {
 
209
  return (limit_ - buf_);
 
210
}
 
211
 
 
212
inline void Encoder::putn(const void* src, int n) {
 
213
  memcpy(buf_, src, n);
 
214
  buf_ += n;
 
215
}
 
216
 
 
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));
 
220
  if (buf_ == NULL)
 
221
    buf_ = old + n;
 
222
}
 
223
 
 
224
inline void Encoder::puts(const void* src) {
 
225
  putcn(src, '\0', limit_ - buf_);
 
226
}
 
227
 
 
228
inline void Encoder::puts_without_null(const char* mem) {
 
229
  while (*mem != '\0' && buf_ < limit_) {
 
230
    *buf_++ = *mem++;
 
231
  }
 
232
}
 
233
 
 
234
inline void Encoder::put_varint32(uint32 v) {
 
235
  buf_ = reinterpret_cast<unsigned char*>
 
236
         (Varint::Encode32(reinterpret_cast<char*>(buf_), v));
 
237
}
 
238
 
 
239
inline void Encoder::put_varint64(uint64 v) {
 
240
  buf_ = reinterpret_cast<unsigned char*>
 
241
         (Varint::Encode64(reinterpret_cast<char*>(buf_), v));
 
242
}
 
243
 
 
244
// DEPRECATED
 
245
//
 
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);
 
253
}
 
254
 
 
255
inline Decoder::Decoder(const void* b, int maxn) {
 
256
  orig_ = buf_ = reinterpret_cast<const unsigned char*>(b);
 
257
  limit_ = orig_ + maxn;
 
258
}
 
259
 
 
260
inline void Decoder::reset(const void* b, int maxn) {
 
261
  orig_ = buf_ = reinterpret_cast<const unsigned char*>(b);
 
262
  limit_ = orig_ + maxn;
 
263
}
 
264
 
 
265
inline int Decoder::pos() const {
 
266
  return (buf_ - orig_);
 
267
}
 
268
 
 
269
inline int Decoder::avail() const {
 
270
  return (limit_ - buf_);
 
271
}
 
272
 
 
273
inline void Decoder::getn(void* dst, int n) {
 
274
  memcpy(dst, buf_, n);
 
275
  buf_ += n;
 
276
}
 
277
 
 
278
inline void Decoder::getcn(void* dst, int c, int n) {
 
279
  void *ptr;
 
280
  ptr = memccpy(dst, buf_, c, n);
 
281
  if (ptr == NULL)
 
282
    buf_ = buf_ + n;
 
283
  else
 
284
    buf_ = buf_ + (reinterpret_cast<unsigned char *>(ptr) -
 
285
                   reinterpret_cast<unsigned char *>(dst));
 
286
}
 
287
 
 
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);
 
292
}
 
293
 
 
294
inline void Decoder::skip(int n) {
 
295
  buf_ += n;
 
296
}
 
297
 
 
298
inline unsigned char const* Decoder::ptr() {
 
299
  return buf_;
 
300
}
 
301
 
 
302
 
 
303
// DEPRECATED
 
304
//
 
305
// For new code use
 
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) {
 
310
  uint32 coding;
 
311
  if (get_varint32(&coding)) {
 
312
    int sign = coding & 1;
 
313
    int32 mag = coding >> 1;
 
314
    if (sign) {
 
315
      // Special handling for encoding of kint32min
 
316
      *v = (mag == 0) ? kint32min : -mag;
 
317
    } else {
 
318
      *v = mag;
 
319
    }
 
320
    return true;
 
321
  } else {
 
322
    return false;
 
323
  }
 
324
}
 
325
 
 
326
inline void Encoder::put8(unsigned char v) {
 
327
  DCHECK_GE((size_t)avail(), sizeof(v));
 
328
  *buf_ = v;
 
329
  buf_ += sizeof(v);
 
330
}
 
331
 
 
332
inline void Encoder::put16(uint16 v) {
 
333
  DCHECK_GE((size_t)avail(), sizeof(v));
 
334
  LittleEndian::Store16(buf_, v);
 
335
  buf_ += sizeof(v);
 
336
}
 
337
 
 
338
inline void Encoder::put32(uint32 v) {
 
339
  DCHECK_GE((size_t)avail(), sizeof(v));
 
340
  LittleEndian::Store32(buf_, v);
 
341
  buf_ += sizeof(v);
 
342
}
 
343
 
 
344
inline void Encoder::put64(uint64 v) {
 
345
  DCHECK_GE((size_t)avail(), sizeof(v));
 
346
  LittleEndian::Store64(buf_, v);
 
347
  buf_ += sizeof(v);
 
348
}
 
349
 
 
350
inline void Encoder::putword(uword_t v) {
 
351
#ifdef _LP64
 
352
  LittleEndian::Store64(buf_, v);
 
353
#else
 
354
  LittleEndian::Store32(buf_, v);
 
355
#endif /* _LP64 */
 
356
  buf_ += sizeof(v);
 
357
}
 
358
 
 
359
inline void Encoder::putfloat(float f) {
 
360
  uint32 v;
 
361
  typedef char VerifySizesAreEqual[sizeof(f) == sizeof(v) ? 1 : -1];
 
362
  memcpy(&v, &f, sizeof(f));
 
363
  put32(v);
 
364
}
 
365
 
 
366
inline void Encoder::putdouble(double d) {
 
367
  uint64 v;
 
368
  typedef char VerifySizesAreEqual[sizeof(d) == sizeof(v) ? 1 : -1];
 
369
  memcpy(&v, &d, sizeof(d));
 
370
  put64(v);
 
371
}
 
372
 
 
373
inline unsigned char Decoder::get8() {
 
374
  const unsigned char v = *buf_;
 
375
  buf_ += sizeof(v);
 
376
  return v;
 
377
}
 
378
 
 
379
inline uint16 Decoder::get16() {
 
380
  const uint16 v = LittleEndian::Load16(buf_);
 
381
  buf_ += sizeof(v);
 
382
  return v;
 
383
}
 
384
 
 
385
inline uint32 Decoder::get32() {
 
386
  const uint32 v = LittleEndian::Load32(buf_);
 
387
  buf_ += sizeof(v);
 
388
  return v;
 
389
}
 
390
 
 
391
inline uint64 Decoder::get64() {
 
392
  const uint64 v = LittleEndian::Load64(buf_);
 
393
  buf_ += sizeof(v);
 
394
  return v;
 
395
}
 
396
 
 
397
inline uword_t Decoder::getword() {
 
398
#ifdef _LP64
 
399
  const uword_t v = LittleEndian::Load64(buf_);
 
400
#else
 
401
  const uword_t v = LittleEndian::Load32(buf_);
 
402
#endif /* _LP64 */
 
403
  buf_ += sizeof(v);
 
404
  return v;
 
405
}
 
406
 
 
407
 
 
408
inline float Decoder::getfloat() {
 
409
  uint32 v = get32();
 
410
  float f;
 
411
  typedef char VerifySizesAreEqual[sizeof(f) == sizeof(v) ? 1 : -1];
 
412
  memcpy(&f, &v, sizeof(f));
 
413
  return f;
 
414
}
 
415
 
 
416
inline double Decoder::getdouble() {
 
417
  uint64 v = get64();
 
418
  double d;
 
419
  typedef char VerifySizesAreEqual[sizeof(d) == sizeof(v) ? 1 : -1];
 
420
  memcpy(&d, &v, sizeof(d));
 
421
  return d;
 
422
}
 
423
 
 
424
#endif  // UTIL_CODING_CODER_H__