OpenSDN source code
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
src/contrail-common/base/proto.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
3  */
4 
5 #ifndef ctrlplane_proto_h
6 #define ctrlplane_proto_h
7 
8 #include <map>
9 #include <memory>
10 
11 #include <vector>
12 
13 #include <boost/ptr_container/ptr_vector.hpp>
14 #include <boost/function.hpp>
15 #include <boost/type_traits/is_same.hpp>
16 #include <boost/type_traits/is_base_of.hpp>
17 #include <boost/mpl/equal_to.hpp>
18 #include <boost/mpl/for_each.hpp>
19 #include <boost/mpl/greater.hpp>
20 #include <boost/mpl/list.hpp>
21 #include <boost/mpl/map.hpp>
22 #include <boost/mpl/or.hpp>
23 #include <boost/mpl/vector.hpp>
24 #include <boost/mpl/string.hpp>
25 
26 #include "base/compiler.h"
27 #include "base/logging.h"
28 #include "base/parse_object.h"
29 
30 namespace mpl = boost::mpl;
31 
32 class ParseContext {
33 public:
34 
35  ParseContext();
36  ~ParseContext();
37 
39 
40  void Push(ParseObject *data);
41  ParseObject *Pop();
42 
43  void SwapData(ParseObject *obj);
44  void ReleaseData();
45 
46  ParseObject *data();
47 
48  void advance(int delta);
49  int offset() const { return offset_; }
50 
51  void set_lensize(int lensize);
52  int lensize() const;
53  void set_size(size_t length);
54  size_t size() const;
55  void set_total_size();
56  size_t total_size() const;
57 
58  void SetError(int error, int subcode, std::string type, const uint8_t *data,
59  int data_size);
61 private:
62 
64  struct StackFrame;
65  int offset_;
66  std::vector<StackFrame *> stack_;
67 };
68 
70 public:
71  typedef boost::function<void(EncodeContext *, uint8_t *, int, int)> CallbackType;
72 
73  EncodeContext();
75 
76  void Push();
77  void Pop(bool callback);
78  void AddCallback(CallbackType cb, uint8_t *data, int arg);
79 
80  void advance(int delta);
81  int length() const;
82 
83  void SaveOffset(std::string);
85 private:
86  struct StackFrame;
87  boost::ptr_vector<StackFrame> stack_;
89 };
90 
91 template <class C, typename T, T C::* Member>
92 struct Accessor {
93  typedef T C::* member_ptr_t;
94  static void set(C *obj, T value) {
95  obj->*Member = value;
96  }
97  static T get(const C *obj) {
98  return obj->*Member;
99  }
100 };
101 
102 template <class C, std::string C::* Member>
103 struct Accessor<C, std::string, Member> {
104  static void set(C*obj, const uint8_t *data, size_t elem_size) {
105  obj->*Member = std::string((const char *) data, elem_size);
106  }
107  static int size(const C *obj) {
108  return (obj->*Member).size();
109  }
110  static std::string::const_iterator begin(const C *obj) {
111  return (obj->*Member).begin();
112  }
113  static std::string::const_iterator end(const C *obj) {
114  return (obj->*Member).end();
115  }
116 };
117 
118 template <class C, typename T, std::vector<T> C::* Member>
120  static void set(C*obj, const uint8_t *data, size_t elem_size) {
121  obj->*Member = std::vector<T>();
122  size_t size = sizeof(T);
123  for (size_t i = 0; i < elem_size; i += size) {
124  T value = get_value(data, size);
125  data += size;
126  (obj->*Member).push_back(value);
127  }
128  }
129  static int size(const C *obj) {
130  return (obj->*Member).size() * sizeof(T);
131  }
132  static typename std::vector<T>::const_iterator begin(const C *obj) {
133  return (obj->*Member).begin();
134  }
135  static typename std::vector<T>::const_iterator end(const C *obj) {
136  return (obj->*Member).end();
137  }
138 };
139 
140 // Extract the underlying type for pointer types.
141 template <typename T>
142 struct ValueType {
143  typedef T type;
144 };
145 template <typename T>
146 struct ValueType<T *> {
147  typedef T type;
148 };
149 
150 template <typename Obj, typename Col, Col Obj::* Member>
153  typedef Col CollectionType;
154  typedef typename CollectionType::const_iterator iterator;
155  static void insert(Obj *obj, ValueType *element) {
156  (obj->*Member).push_back(element);
157  }
158  static iterator begin(const Obj *obj) {
159  return (obj->*Member).begin();
160  }
161  static iterator end(const Obj *obj) {
162  return (obj->*Member).end();
163  }
164 };
165 
166 // Interface
167 struct ElementBase {
168  static const int kSize = 0;
169  static const int kErrorCode = 0;
170  static const int kErrorSubcode = 0;
171  struct NullCtxInit {
172  void operator()(void *) {
173  }
174  };
175  struct NoMatch {
176  bool match(const void *) {
177  return false;
178  }
179  };
180  static bool Verifier(const void * obj, const uint8_t *data, size_t size,
181  ParseContext *context) {
182  return true;
183  }
184 
185  typedef void SaveOffset; // Save the offset in encode context
186  typedef void ContextType; // push a new context on the stack
187  typedef NullCtxInit ContextInit; // initialize the context data
189  typedef void Setter;
190  typedef void EncodingCallback;
191  typedef void ContextSwap; // swap a context with another one
192  typedef void SizeSetter; // set the size of the element
193 };
194 
195 struct ChoiceBase : public ElementBase {
196  typedef void ContextStorer; // store the context data on pop.
197 };
198 
199 class SequenceBase : public ElementBase {
200 public:
201  static const int kMinOccurs = 1;
202  static const int kMaxOccurs = 1;
203  typedef void ContextStorer; // store the context data on pop.
204 };
205 
206 #include "base/proto_impl.h"
207 
208 template<class Derived>
209 class ProtoElement : public ElementBase {
210 public:
211  typedef void SequenceLength;
212 
213  template <typename T>
214  static void Writer(T *msg, uint8_t *data, size_t size) {
215  typedef typename Derived::Setter setter_t;
216  typedef typename mpl::if_<
217  mpl::equal_to<
218  mpl::int_<Derived::kSize>, mpl::int_<-1> >,
221  >::type writer_t;
222  writer_t writer;
223  writer(data, Derived::kSize, msg);
224  }
225 
226  template <typename T>
227  static int Parse(const uint8_t *data, size_t size, ParseContext *context,
228  T *obj) {
229  typedef typename mpl::if_<
230  mpl::greater<
231  mpl::int_<Derived::kSize>, mpl::int_<0> >,
234  >::type cmp_t;
235 
236  cmp_t cmp;
237  if (!cmp(size)) {
238  PROTO_DEBUG("Error: cmp(size) failed");
239  context->SetError(Derived::kErrorCode, Derived::kErrorSubcode,
240  TYPE_NAME(Derived), data,
241  Derived::kSize > 0 ? Derived::kSize : context->size());
242  return -1;
243  }
244  if (!Derived::Verifier(obj, data, size, context)) {
245  PROTO_DEBUG(TYPE_NAME(Derived) << " Verifier failed");
246  context->SetError(Derived::kErrorCode, Derived::kErrorSubcode,
247  TYPE_NAME(Derived), data,
248  Derived::kSize > 0 ? Derived::kSize : context->size());
249  return -1;
250  }
251 
252  typedef typename Derived::ContextInit ctx_init_t;
253  ctx_init_t initializer;
254  initializer(obj);
255 
257  int res = slen(context, data, Derived::kSize, size, obj);
258  if (res < 0) {
259  PROTO_DEBUG(TYPE_NAME(Derived) << ": error: Length Setter failed");
260  context->SetError(Derived::kErrorCode, Derived::kErrorSubcode,
261  TYPE_NAME(Derived), data, context->lensize());
262  return -1;
263  }
264 
265  typedef typename mpl::if_<boost::is_same<typename Derived::SizeSetter, void>,
266  typename mpl::if_<
267  mpl::equal_to<mpl::int_<Derived::kSize>, mpl::int_<-1> >,
269  typename mpl::if_<
270  mpl::greater<mpl::int_<Derived::kSize>, mpl::int_<0> >,
273  >::type
274  >::type,
276  >::type setter_t;
277 
278  setter_t setter;
279  res = setter(data, size, context, obj);
280  if (res < 0) {
281  context->SetError(Derived::kErrorCode, Derived::kErrorSubcode,
282  TYPE_NAME(Derived), data,
283  Derived::kSize > 0 ? Derived::kSize : context->size());
284  }
285  return res;
286  }
287 
288  template <typename T>
289  static int Encode(EncodeContext *context, const T *msg, uint8_t *data,
290  size_t size) {
291  typedef typename
292  mpl::if_<boost::is_same<typename Derived::SizeSetter, void>,
293  typename mpl::if_<mpl::equal_to<mpl::int_<Derived::kSize>, mpl::int_<-1> >,
296  typename Derived::SizeSetter
297  >::type size_value_t;
298 
299  int element_size = size_value_t::get(msg);
300  if (data == NULL) {
301  context->advance(element_size);
302  return element_size;
303  }
304  assert(element_size >= 0);
305  if (size < (size_t) element_size) {
306  return -1;
307  }
308 
309  // Setter overrides SequenceLength. Do not register a sequence length
310  // callback if the element has defined a Setter.
311  typename mpl::if_<
312  boost::is_same<typename Derived::Setter, void>,
315  slen(&ProtoElement::SequenceLengthWriteLen, context, data, element_size);
316 
318  cbadd(context, data, element_size);
319 
321 
322  Derived::Writer(msg, data, size);
323 
324  context->advance(element_size);
325  return element_size;
326  }
327 
328 private:
329  static void SequenceLengthWriteLen(EncodeContext *context, uint8_t *data,
330  int offset, int element_size) {
331  int length = context->length() - offset - element_size;
332  put_value(data, element_size, length);
333  }
334 };
335 
336 template <typename Setter, typename T>
337 struct ChoiceSetter {
338  void operator()(T *obj, int &value) {
339  Setter::set(obj, value);
340  }
341 };
342 
343 template <typename T>
344 struct ChoiceSetter<void, T> {
345  void operator()(T* obj, int value) { }
346 };
347 
348 template <class Derived>
349 class ProtoChoice : public ChoiceBase {
350 public:
351  template <typename T>
352  static int Parse(const uint8_t *data, size_t size, ParseContext *context,
353  T *obj) {
354  int advance = Derived::kSize;
355  int value = -1;
356 
357  if (size < (size_t) advance) {
358  context->SetError(Derived::kErrorCode, Derived::kErrorSubcode,
359  TYPE_NAME(Derived), data, advance);
360  return -1;
361  }
362 
363  value = get_value(data, advance);
364 
365  data += advance;
366  size -= advance;
367  context->advance(advance);
368 
369  typedef typename mpl::if_<
370  boost::is_same<typename Derived::Setter, void>,
373  >::type choice_setter_t;
374 
375  choice_setter_t setter;
376  setter(obj, value);
377 
378  int result = ParseChoice(data, size, value, context, obj);
379  if (result < 0) {
380  PROTO_DEBUG(TYPE_NAME(Derived) << " ParseChoice failed");
381  if (result == -2) {
382  context->SetError(Derived::kErrorCode, Derived::kErrorSubcode,
383  TYPE_NAME(Derived), data - advance, advance);
384  }
385  return result;
386  }
387  advance += result;
388  return advance;
389  }
390 
391  template <typename T>
392  static int Encode(EncodeContext *context, const T *msg, uint8_t *data,
393  size_t size) {
394  typedef typename Derived::Choice choice_t;
395  int result = 0;
396  ChoiceEncoder<T> encoder(context, msg, data, size, &result);
397  mpl::for_each<choice_t>(encoder);
398  return result;
399  }
400 
401 private:
402  template <typename T>
403  struct ChoiceMatcher {
404  ChoiceMatcher(const uint8_t *data, size_t size, int value,
405  ParseContext *context, T *obj, int *resultp)
406  : data(data), size(size), value(value), context(context),
407  obj(obj), resultp(resultp), found(false) {
408  }
409  template <typename U>
410  void operator()(U x) {
411  if (found) return;
412  if (U::first::value != -1 && U::first::value != value) {
413  return;
414  }
415  found = true;
417  parser_t;
418  *resultp = parser_t::Parse(data, size, context, obj);
419  }
420  const uint8_t *data;
421  size_t size;
422  int value;
424  T *obj;
425  int *resultp;
426  bool found;
427  };
428  template <typename T>
429  static int ParseChoice(const uint8_t *data, size_t size, int value,
430  ParseContext *context, T *obj) {
431  int result = -2;
432  ChoiceMatcher<T> match(data, size, value, context, obj, &result);
433  mpl::for_each<typename Derived::Choice>(match);
434  return result;
435  }
436 
437  template <typename T>
438  struct ChoiceEncoder {
439  ChoiceEncoder(EncodeContext *context, const T *msg, uint8_t *data, int size,
440  int *resultp)
441  : context(context), msg(msg), data(data), size(size),
442  resultp(resultp), found(false) {
443  }
444  template <typename U, typename CtxType>
445  struct EncoderTrue {
446  int operator()(int opt, EncodeContext *context, const CtxType *msg,
447  uint8_t *data, int size) {
448  if (Derived::kSize) {
449  if (data != NULL) {
450  if (size < Derived::kSize) return -1;
451  put_value(data, Derived::kSize, opt);
452  data += Derived::kSize;
453  size -= Derived::kSize;
454  }
455  context->advance(Derived::kSize);
456  }
457  int result = U::Encode(context, msg, data, size);
458  if (result >= 0) {
459  result += Derived::kSize;
460  }
461  return result;
462  }
463  };
464  template <typename U, typename CtxType>
465  struct EncoderSetter {
466  int operator()(int opt, EncodeContext *context, const CtxType *msg,
467  uint8_t *data, int size) {
468  int value = Derived::Setter::get(msg);
469  if (value == opt || opt == -1) {
470  return EncoderTrue<U, CtxType>()(value, context, msg, data, size);
471  }
472  return 0;
473  }
474  };
475  template <typename U>
476  struct EncoderMatch {
477  int operator()(int opt, EncodeContext *context, const T *msg,
478  uint8_t *data, int size) {
479  typename U::ContextMatch matcher;
480  if (matcher.match(msg)) {
481  return EncoderTrue<U, T>()(opt, context, msg, data, size);
482  }
483  return 0;
484  }
485  };
486  template <typename U>
487  struct EncoderRunTime {
488  int operator()(int opt, EncodeContext *context, const T *msg,
489  uint8_t *data, int size) {
490  if (typeid(*msg) == typeid(typename U::ContextType)) {
491  typedef typename U::ContextType ctx_t;
492  const ctx_t *ctx = static_cast<const ctx_t *>(msg);
493 
494  typedef typename mpl::if_<
495  boost::is_same<typename Derived::Setter, void>,
498  >::type encoder;
499  return encoder()(opt, context, ctx, data, size);
500  }
501  return 0;
502  }
503  };
504  struct EncoderNil {
505  int operator()(int opt, EncodeContext *context, T *msg,
506  uint8_t *data, int size) {
507  return 0;
508  }
509  };
510  template <typename U>
511  void operator()(U x) {
512  if (*resultp < 0 || found) {
513  return;
514  }
515  // The choice element can be determined by:
516  // 1. ContextType of the descendent or
517  // 2. ContextMatch type of the descendent
518  // In the case of ContextType match, the match can be either
519  // performed at compile type (in case of exact match) or at run
520  // type using RTTI.
521  typedef typename mpl::if_<
522  boost::is_same<typename U::second::ContextType, T>,
524  typename mpl::if_<
525  boost::is_same<typename U::second::ContextType, void>,
527  typename mpl::if_<
528  boost::is_base_of<T, typename U::second::ContextType>,
530  EncoderNil
531  >::type
532  >::type
533  >::type choice_t;
534  choice_t choice;
535  int result = choice(U::first::value, context, msg, data, size);
536  if (result < 0) {
537  *resultp = result;
538  } else if (result > 0) {
539  found = true;
540  *resultp += result;
541  }
542  }
543  private:
545  const T *msg;
546  uint8_t *data;
547  int size;
548  int *resultp;
549  bool found;
550  };
551 };
552 
553 template <class Derived>
554 class ProtoSequence : public SequenceBase {
555 public:
556  template <typename T>
557  struct SequenceParser {
558  SequenceParser(const uint8_t *data, size_t size, ParseContext *context,
559  T *obj, int *resultp)
560  : data(data), size(size), context(context), obj(obj),
561  resultp(resultp) {
562  }
563 
564  template <typename U>
565  void operator()(U x) {
566  if (*resultp < 0) {
567  return;
568  }
569  typedef detail::DescendentParser<Derived, U> parser_t;
570  size_t prev_size = context->size();
571  int result = parser_t::Parse(data, size, context, obj);
572  if (result < 0) {
573  *resultp = result;
574  return;
575  }
576 
577  data += result;
578  size -= result;
579  context->advance(result);
580  *resultp += result;
581 
582  if (context->size() != prev_size) {
583  size = context->size();
585  } else {
586  context->set_size(prev_size - result);
587  }
588  }
589 
590  const uint8_t *data;
591  size_t size;
593  T *obj;
594  int *resultp;
595  };
596 
597  template <typename T>
598  static int Parse(const uint8_t *data, size_t size, ParseContext *context,
599  T *obj) {
600  int min = Derived::kMinOccurs;
601  if (min == 0 && size == 0) {
602  return 0;
603  }
604  if (!Derived::Verifier(obj, data, size, context)) {
605  PROTO_DEBUG(TYPE_NAME(Derived) << " Verifier failed");
606  context->SetError(Derived::kErrorCode, Derived::kErrorSubcode,
607  TYPE_NAME(Derived), data,
608  Derived::kSize > 0 ? Derived::kSize : context->size());
609  return -1;
610  }
611  int lensize = Derived::kSize;
612  int length = size;
613  if (lensize) {
614  if (size < (size_t) lensize) {
615  PROTO_DEBUG("Error: size = " << size << " lensize = " << lensize);
616  context->SetError(Derived::kErrorCode, Derived::kErrorSubcode,
617  TYPE_NAME(Derived), data, lensize);
618  return -1;
619  }
620  // TODO: options for length (include or exclude length field).
621  length = get_value(data, lensize);
622  assert(length >= 0);
623  size -= lensize;
624  if ((size_t) length > size) {
625  PROTO_DEBUG("Error: length = " << length << " size = " << size);
626  context->SetError(Derived::kErrorCode, Derived::kErrorSubcode,
627  TYPE_NAME(Derived), data, lensize);
628  return -1;
629  }
630  data += lensize;
631  context->advance(lensize);
632  }
633  int result = lensize;
634  int max = Derived::kMaxOccurs;
635  for (int i = 0; (max == -1 || i < max) && (length > 0); i++) {
636  int sublen = 0;
637  typedef typename Derived::ContextStorer ctx_access_t;
638  typedef typename
640  typedef typename mpl::if_<boost::is_same<typename Derived::ContextSwap, void>,
643  >::type ContextPush;
644  ContextPush pushfn;
645  typedef typename mpl::if_<boost::is_same<child_obj_t, void>,
646  T, child_obj_t>::type ctx_t;
647  ctx_t *child_obj = pushfn(context, obj);
648 
649  SequenceParser<ctx_t> parser(data, length, context, child_obj, &sublen);
650  mpl::for_each<typename Derived::Sequence>(parser);
651  if (sublen < 0) {
652  PROTO_DEBUG(TYPE_NAME(Derived) << ": error: sublen " << sublen);
653  return -1;
654  }
655  if (sublen < (int)(context->size() + context->lensize())) {
656  PROTO_DEBUG(TYPE_NAME(Derived) << ": error: sublen " << sublen
657  << " < " << context->size() << "+" << context->lensize());
658  context->SetError(Derived::kErrorCode, Derived::kErrorSubcode,
659  TYPE_NAME(Derived), data,
660  context->size()+context->lensize());
661  return -1;
662  }
663  result += sublen;
664  data += sublen;
665  length -= sublen;
666 
667  typedef typename mpl::if_<boost::is_same<typename Derived::ContextSwap, void>,
670  >::type ContextPop;
671  ContextPop popfn;
672  popfn(context, obj);
673  }
674  return result;
675  }
676 
677  template <typename T>
678  struct SingleEncoder {
679  typedef typename Derived::Sequence sequence_t;
680  int operator()(EncodeContext *context, const T *msg, uint8_t *data,
681  size_t size) {
682  int result = 0;
683  SequenceEncoder<T> encoder(context, msg, data, size, &result);
684  mpl::for_each<sequence_t>(encoder);
685  return result;
686  }
687  };
688 
689  template <typename T>
690  struct ListEncoder {
691  typedef typename Derived::Sequence sequence_t;
692  int operator()(EncodeContext *context, const T *msg, uint8_t *data,
693  size_t size) {
694  typedef typename Derived::ContextStorer ctx_access_t;
695  typedef typename
697  int result = 0;
698 
700  while (iter.HasNext(msg)) {
701  child_obj_t *child_obj = iter.Next();
702  int subres = 0;
703  context->Push();
704  SequenceEncoder<child_obj_t> encoder(context, child_obj,
705  data, size, &subres);
706  mpl::for_each<sequence_t>(encoder);
707  if (subres < 0) {
708  result = subres;
709  break;
710  }
711  result += subres;
712  if (data != NULL) {
713  data += subres;
714  size -= subres;
715  }
716  context->Pop(data != NULL);
717  }
718  return result;
719  }
720  };
721 
722  template <typename T>
723  static int Encode(EncodeContext *context, const T *msg, uint8_t *data,
724  size_t size) {
725  context->Push();
727  if (Derived::kSize > 0) {
728  // context push callback
729  if (data != NULL) {
730  context->AddCallback(&SequenceLengthWriteLen, data, Derived::kSize);
731  data += Derived::kSize;
732  size -= Derived::kSize;
733  }
734  context->advance(Derived::kSize);
735  }
736  typedef typename mpl::if_<
737  mpl::or_<
738  mpl::equal_to<mpl::int_<Derived::kMaxOccurs>,
739  mpl::int_<-1> >,
740  mpl::greater<mpl::int_<Derived::kMaxOccurs>,
741  mpl::int_<1> >
742  >,
743  ListEncoder<T>,
744  SingleEncoder<T> >::type encoder_t;
745  encoder_t encoder;
746  int result = encoder(context, msg, data, size);
747  if (result >= 0) {
748  result += Derived::kSize;
749  context->Pop(data != NULL);
750  }
751  return result;
752  }
753 
754 private:
755  template <typename T>
758  size_t size, int *resultp)
759  : context(context), msg(msg), data(data), size(size),
760  resultp(resultp) {
761  }
762  template <typename U>
763  void operator()(U element) {
764  if (*resultp < 0) {
765  return;
766  }
767  int res = U::Encode(context, msg, data, size);
768  if (res < 0) {
769  *resultp = res;
770  } else {
771  *resultp += res;
772  }
773  if (data != NULL) {
774  data += res;
775  size -= res;
776  }
777  }
778 
779  private:
781  const T *msg;
782  uint8_t *data;
783  size_t size;
784  int *resultp;
785  };
786 
787  static void SequenceLengthWriteLen(EncodeContext *context, uint8_t *data,
788  int offset, int arg) {
789  int length = context->length() - Derived::kSize;
790  put_value(data, Derived::kSize, length);
791  }
792 };
793 
794 #endif
static bool Verifier(const void *obj, const uint8_t *data, size_t size, ParseContext *context)
#define PROTO_DEBUG(args...)
Definition: proto_impl.h:13
static int size(const C *obj)
static std::string::const_iterator begin(const C *obj)
ValueType * Next()
Definition: proto_impl.h:381
int operator()(int opt, EncodeContext *context, T *msg, uint8_t *data, int size)
static void insert(Obj *obj, ValueType *element)
void set_lensize(int lensize)
static std::vector< T >::const_iterator begin(const C *obj)
void SwapData(ParseObject *obj)
static void SequenceLengthWriteLen(EncodeContext *context, uint8_t *data, int offset, int arg)
void operator()(T *obj, int &value)
bool HasNext(Obj *obj) const
Definition: proto_impl.h:388
int operator()(EncodeContext *context, const T *msg, uint8_t *data, size_t size)
SequenceParser(const uint8_t *data, size_t size, ParseContext *context, T *obj, int *resultp)
static int ParseChoice(const uint8_t *data, size_t size, int value, ParseContext *context, T *obj)
static void set(C *obj, const uint8_t *data, size_t elem_size)
static int Parse(const uint8_t *data, size_t size, ParseContext *context, T *obj)
static int Parse(const uint8_t *data, size_t size, ParseContext *context, T *obj)
void SetError(int error, int subcode, std::string type, const uint8_t *data, int data_size)
static int Encode(EncodeContext *context, const T *msg, uint8_t *data, size_t size)
static uint64_t get_value(const uint8_t *data, int size)
Definition: parse_object.h:39
static const int kErrorSubcode
ValueType< typename Col::value_type >::type ValueType
CollectionType::const_iterator iterator
uint8_t type
Definition: load_balance.h:109
EncodeOffsets & encode_offsets()
const ParseErrorContext & error_context()
static void set(C *obj, const uint8_t *data, size_t elem_size)
ParseErrorContext error_context_
int operator()(int opt, EncodeContext *context, const CtxType *msg, uint8_t *data, int size)
std::vector< StackFrame * > stack_
static int Encode(EncodeContext *context, const T *msg, uint8_t *data, size_t size)
#define TYPE_NAME(_type)
Definition: logging.h:31
void AddCallback(CallbackType cb, uint8_t *data, int arg)
int operator()(int opt, EncodeContext *context, const CtxType *msg, uint8_t *data, int size)
boost::function< void(EncodeContext *, uint8_t *, int, int)> CallbackType
static void SequenceLengthWriteLen(EncodeContext *context, uint8_t *data, int offset, int element_size)
static int Parse(const uint8_t *data, size_t size, ParseContext *context, T *obj)
static void set(C *obj, T value)
static iterator begin(const Obj *obj)
ChoiceMatcher(const uint8_t *data, size_t size, int value, ParseContext *context, T *obj, int *resultp)
void set_size(size_t length)
static std::string::const_iterator end(const C *obj)
static int Encode(EncodeContext *context, const T *msg, uint8_t *data, size_t size)
int operator()(int opt, EncodeContext *context, const T *msg, uint8_t *data, int size)
boost::ptr_vector< StackFrame > stack_
static iterator end(const Obj *obj)
int operator()(int opt, EncodeContext *context, const T *msg, uint8_t *data, int size)
static std::vector< T >::const_iterator end(const C *obj)
static void Writer(T *msg, uint8_t *data, size_t size)
SequenceEncoder(EncodeContext *context, const T *msg, uint8_t *data, size_t size, int *resultp)
void Push(ParseObject *data)
int operator()(EncodeContext *context, const T *msg, uint8_t *data, size_t size)
ContextAccessor::ValueType ValueType
Definition: proto_impl.h:365
ChoiceEncoder(EncodeContext *context, const T *msg, uint8_t *data, int size, int *resultp)
static void put_value(uint8_t *data, int size, uint64_t value)
Definition: parse_object.h:55