Subversion Repositories SmartDukaan

Rev

Rev 30 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
30 ashish 1
/*
2
 * Licensed to the Apache Software Foundation (ASF) under one
3
 * or more contributor license agreements. See the NOTICE file
4
 * distributed with this work for additional information
5
 * regarding copyright ownership. The ASF licenses this file
6
 * to you under the Apache License, Version 2.0 (the
7
 * "License"); you may not use this file except in compliance
8
 * with the License. You may obtain a copy of the License at
9
 *
10
 *   http://www.apache.org/licenses/LICENSE-2.0
11
 *
12
 * Unless required by applicable law or agreed to in writing,
13
 * software distributed under the License is distributed on an
14
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15
 * KIND, either express or implied. See the License for the
16
 * specific language governing permissions and limitations
17
 * under the License.
18
 */
19
 
20
#ifndef _THRIFT_PROTOCOL_TCOMPACTPROTOCOL_H_
21
#define _THRIFT_PROTOCOL_TCOMPACTPROTOCOL_H_ 1
22
 
23
#include "TProtocol.h"
24
 
25
#include <stack>
26
#include <boost/shared_ptr.hpp>
27
 
28
namespace apache { namespace thrift { namespace protocol {
29
 
30
/**
31
 * C++ Implementation of the Compact Protocol as described in THRIFT-110
32
 */
33
class TCompactProtocol : public TProtocol {
34
 
35
 protected:
36
  static const int8_t  PROTOCOL_ID = 0x82;
37
  static const int8_t  VERSION_N = 1;
38
  static const int8_t  VERSION_MASK = 0x1f; // 0001 1111
39
  static const int8_t  TYPE_MASK = 0xE0; // 1110 0000
40
  static const int32_t TYPE_SHIFT_AMOUNT = 5;
41
 
42
  /**
43
   * (Writing) If we encounter a boolean field begin, save the TField here
44
   * so it can have the value incorporated.
45
   */
46
  struct {
47
    const char* name;
48
    TType fieldType;
49
    int16_t fieldId;
50
  } booleanField_;
51
 
52
  /**
53
   * (Reading) If we read a field header, and it's a boolean field, save
54
   * the boolean value here so that readBool can use it.
55
   */
56
  struct {
57
    bool hasBoolValue;
58
    bool boolValue;
59
  } boolValue_;
60
 
61
  /**
62
   * Used to keep track of the last field for the current and previous structs,
63
   * so we can do the delta stuff.
64
   */
65
 
66
  std::stack<int16_t> lastField_;
67
  int16_t lastFieldId_;
68
 
69
  enum Types {
70
    CT_STOP           = 0x00,
71
    CT_BOOLEAN_TRUE   = 0x01,
72
    CT_BOOLEAN_FALSE  = 0x02,
73
    CT_BYTE           = 0x03,
74
    CT_I16            = 0x04,
75
    CT_I32            = 0x05,
76
    CT_I64            = 0x06,
77
    CT_DOUBLE         = 0x07,
78
    CT_BINARY         = 0x08,
79
    CT_LIST           = 0x09,
80
    CT_SET            = 0x0A,
81
    CT_MAP            = 0x0B,
82
    CT_STRUCT         = 0x0C,
83
  };
84
 
85
  static const int8_t TTypeToCType[16];
86
 
87
 public:
88
  TCompactProtocol(boost::shared_ptr<TTransport> trans) :
89
    TProtocol(trans),
90
    lastFieldId_(0),
91
    string_limit_(0),
92
    string_buf_(NULL),
93
    string_buf_size_(0),
94
    container_limit_(0) {
95
    booleanField_.name = NULL;
96
    boolValue_.hasBoolValue = false;
97
  }
98
 
99
  TCompactProtocol(boost::shared_ptr<TTransport> trans,
100
                   int32_t string_limit,
101
                   int32_t container_limit) :
102
    TProtocol(trans),
103
    lastFieldId_(0),
104
    string_limit_(string_limit),
105
    string_buf_(NULL),
106
    string_buf_size_(0),
107
    container_limit_(container_limit) {
108
    booleanField_.name = NULL;
109
    boolValue_.hasBoolValue = false;
110
  }
111
 
112
 
113
 
114
  /**
115
   * Writing functions
116
   */
117
 
118
  virtual uint32_t writeMessageBegin(const std::string& name,
119
                                     const TMessageType messageType,
120
                                     const int32_t seqid);
121
 
122
  uint32_t writeStructBegin(const char* name);
123
 
124
  uint32_t writeStructEnd();
125
 
126
  uint32_t writeFieldBegin(const char* name,
127
                           const TType fieldType,
128
                           const int16_t fieldId);
129
 
130
  uint32_t writeFieldStop();
131
 
132
  uint32_t writeListBegin(const TType elemType,
133
                          const uint32_t size);
134
 
135
  uint32_t writeSetBegin(const TType elemType,
136
                         const uint32_t size);
137
 
138
  virtual uint32_t writeMapBegin(const TType keyType,
139
                                 const TType valType,
140
                                 const uint32_t size);
141
 
142
  uint32_t writeBool(const bool value);
143
 
144
  uint32_t writeByte(const int8_t byte);
145
 
146
  uint32_t writeI16(const int16_t i16);
147
 
148
  uint32_t writeI32(const int32_t i32);
149
 
150
  uint32_t writeI64(const int64_t i64);
151
 
152
  uint32_t writeDouble(const double dub);
153
 
154
  uint32_t writeString(const std::string& str);
155
 
156
  uint32_t writeBinary(const std::string& str);
157
 
158
  /**
159
  * These methods are called by structs, but don't actually have any wired
160
  * output or purpose
161
  */
162
  virtual uint32_t writeMessageEnd() { return 0; }
163
  uint32_t writeMapEnd() { return 0; }
164
  uint32_t writeListEnd() { return 0; }
165
  uint32_t writeSetEnd() { return 0; }
166
  uint32_t writeFieldEnd() { return 0; }
167
 
168
 protected:
169
  int32_t writeFieldBeginInternal(const char* name,
170
                                  const TType fieldType,
171
                                  const int16_t fieldId,
172
                                  int8_t typeOverride);
173
  uint32_t writeCollectionBegin(int8_t elemType, int32_t size);
174
  uint32_t writeVarint32(uint32_t n);
175
  uint32_t writeVarint64(uint64_t n);
176
  uint64_t i64ToZigzag(const int64_t l);
177
  uint32_t i32ToZigzag(const int32_t n);
178
  inline int8_t getCompactType(int8_t ttype);
179
 
180
 public:
181
  uint32_t readMessageBegin(std::string& name,
182
                            TMessageType& messageType,
183
                            int32_t& seqid);
184
 
185
  uint32_t readStructBegin(std::string& name);
186
 
187
  uint32_t readStructEnd();
188
 
189
  uint32_t readFieldBegin(std::string& name,
190
                          TType& fieldType,
191
                          int16_t& fieldId);
192
 
193
  uint32_t readMapBegin(TType& keyType,
194
                        TType& valType,
195
                        uint32_t& size);
196
 
197
  uint32_t readListBegin(TType& elemType,
198
                         uint32_t& size);
199
 
200
  uint32_t readSetBegin(TType& elemType,
201
                        uint32_t& size);
202
 
203
  uint32_t readBool(bool& value);
204
 
205
  uint32_t readByte(int8_t& byte);
206
 
207
  uint32_t readI16(int16_t& i16);
208
 
209
  uint32_t readI32(int32_t& i32);
210
 
211
  uint32_t readI64(int64_t& i64);
212
 
213
  uint32_t readDouble(double& dub);
214
 
215
  uint32_t readString(std::string& str);
216
 
217
  uint32_t readBinary(std::string& str);
218
 
219
  /*
220
   *These methods are here for the struct to call, but don't have any wire
221
   * encoding.
222
   */
223
  uint32_t readMessageEnd() { return 0; }
224
  uint32_t readFieldEnd() { return 0; }
225
  uint32_t readMapEnd() { return 0; }
226
  uint32_t readListEnd() { return 0; }
227
  uint32_t readSetEnd() { return 0; }
228
 
229
 protected:
230
  uint32_t readVarint32(int32_t& i32);
231
  uint32_t readVarint64(int64_t& i64);
232
  int32_t zigzagToI32(uint32_t n);
233
  int64_t zigzagToI64(uint64_t n);
234
  TType getTType(int8_t type);
235
 
236
  // Buffer for reading strings, save for the lifetime of the protocol to
237
  // avoid memory churn allocating memory on every string read
238
  int32_t string_limit_;
239
  uint8_t* string_buf_;
240
  int32_t string_buf_size_;
241
  int32_t container_limit_;
242
};
243
 
244
/**
245
 * Constructs compact protocol handlers
246
 */
247
class TCompactProtocolFactory : public TProtocolFactory {
248
 public:
249
  TCompactProtocolFactory() :
250
    string_limit_(0),
251
    container_limit_(0) {}
252
 
253
  TCompactProtocolFactory(int32_t string_limit, int32_t container_limit) :
254
    string_limit_(string_limit),
255
    container_limit_(container_limit) {}
256
 
257
  virtual ~TCompactProtocolFactory() {}
258
 
259
  void setStringSizeLimit(int32_t string_limit) {
260
    string_limit_ = string_limit;
261
  }
262
 
263
  void setContainerSizeLimit(int32_t container_limit) {
264
    container_limit_ = container_limit;
265
  }
266
 
267
  boost::shared_ptr<TProtocol> getProtocol(boost::shared_ptr<TTransport> trans) {
268
    return boost::shared_ptr<TProtocol>(new TCompactProtocol(trans, string_limit_, container_limit_));
269
  }
270
 
271
 private:
272
  int32_t string_limit_;
273
  int32_t container_limit_;
274
 
275
};
276
 
277
}}} // apache::thrift::protocol
278
 
279
#endif