1 //
2 // Copyright 2000 - 2003 Google Inc.
3 //
4 //
5 
6 #include "base/logging.h"
7 #include "util/coding/coder.h"
8 
9 // An initialization value used when we are allowed to
10 unsigned char Encoder::kEmptyBuffer = 0;
11 const int Encoder::kVarintMax32 = Varint::kMax32;
12 const int Encoder::kVarintMax64 = Varint::kMax64;
13 
Encoder()14 Encoder::Encoder()
15   : orig_(NULL),
16     buf_(NULL),
17     limit_(NULL),
18     underlying_buffer_(&kEmptyBuffer) {
19 }
20 
~Encoder()21 Encoder::~Encoder() {
22   if (underlying_buffer_ != &kEmptyBuffer) {
23     delete[] underlying_buffer_;
24   }
25 }
26 
varint32_length(uint32 v)27 int Encoder::varint32_length(uint32 v) {
28   return Varint::Length32(v);
29 }
30 
varint64_length(uint64 v)31 int Encoder::varint64_length(uint64 v) {
32   return Varint::Length64(v);
33 }
34 
EnsureSlowPath(int N)35 void Encoder::EnsureSlowPath(int N) {
36   CHECK(ensure_allowed());
37   assert(avail() < N);
38   assert(length() == 0 || orig_ == underlying_buffer_);
39 
40   // Double buffer size, but make sure we always have at least N extra bytes
41   int current_len = length();
42   int new_capacity = max(current_len + N, 2 * current_len);
43 
44   unsigned char* new_buffer = new unsigned char[new_capacity];
45   memcpy(new_buffer, underlying_buffer_, current_len);
46   if (underlying_buffer_ != &kEmptyBuffer) {
47     delete[] underlying_buffer_;
48   }
49   underlying_buffer_ = new_buffer;
50 
51   orig_ = new_buffer;
52   limit_ = new_buffer + new_capacity;
53   buf_ = orig_ + current_len;
54   CHECK(avail() >= N);
55 }
56 
RemoveLast(int N)57 void Encoder::RemoveLast(int N) {
58   CHECK(length() >= N);
59   buf_ -= N;
60 }
61 
Resize(int N)62 void Encoder::Resize(int N) {
63   CHECK(length() >= N);
64   buf_ = orig_ + N;
65   assert(length() == N);
66 }
67 
68 // Special optimized version: does not use Varint
get_varint32(uint32 * v)69 bool Decoder::get_varint32(uint32* v) {
70   const char* r = Varint::Parse32WithLimit(
71                                    reinterpret_cast<const char*>(buf_),
72                                    reinterpret_cast<const char*>(limit_), v);
73   if (r == NULL) { return false; }
74   buf_ = reinterpret_cast<const unsigned char*>(r);
75   return true;
76 }
77 
78 // Special optimized version: does not use Varint
get_varint64(uint64 * v)79 bool Decoder::get_varint64(uint64* v) {
80   uint64 result = 0;
81 
82   if (buf_ + Varint::kMax64 <= limit_) {
83     const char* r = Varint::Parse64(reinterpret_cast<const char*>(buf_), v);
84     if (r == NULL) {
85       return false;
86     } else {
87       buf_ = reinterpret_cast<const unsigned char*>(r);
88       return true;
89     }
90   } else {
91     int shift = 0;        // How much to shift next set of bits
92     unsigned char byte;
93     do {
94       if ((shift >= 64) || (buf_ >= limit_)) {
95         // Out of range
96         return false;
97       }
98 
99       // Get 7 bits from next byte
100       byte = *(buf_++);
101       result |= static_cast<uint64>(byte & 127) << shift;
102       shift += 7;
103     } while ((byte & 128) != 0);
104     *v = result;
105     return true;
106   }
107 }
108