5 #ifndef ctrlplane_proto_h
6 #define ctrlplane_proto_h
8 #define BOOST_MPL_CFG_NO_PREPROCESSED_HEADERS
9 #define BOOST_MPL_LIMIT_MAP_SIZE 30
16 #include <boost/ptr_container/ptr_vector.hpp>
17 #include <boost/function.hpp>
18 #include <boost/type_traits/is_same.hpp>
19 #include <boost/type_traits/is_base_of.hpp>
20 #include <boost/mpl/equal_to.hpp>
21 #include <boost/mpl/for_each.hpp>
22 #include <boost/mpl/greater.hpp>
23 #include <boost/mpl/list.hpp>
24 #include <boost/mpl/map.hpp>
25 #include <boost/mpl/or.hpp>
26 #include <boost/mpl/vector.hpp>
27 #include <boost/mpl/string.hpp>
33 namespace mpl = boost::mpl;
80 void Pop(
bool callback);
90 boost::ptr_vector<StackFrame>
stack_;
94 template <
class C,
typename T, T C::* Member>
97 static void set(C *obj, T value) {
100 static T
get(
const C *obj) {
105 template <
class C, std::
string C::* Member>
107 static void set(C*obj,
const uint8_t *data,
size_t elem_size) {
108 obj->*Member = std::string((
const char *) data, elem_size);
110 static int size(
const C *obj) {
111 return (obj->*Member).size();
113 static std::string::const_iterator
begin(
const C *obj) {
114 return (obj->*Member).begin();
116 static std::string::const_iterator
end(
const C *obj) {
117 return (obj->*Member).end();
121 template <
class C,
typename T, std::vector<T> C::* Member>
123 static void set(C*obj,
const uint8_t *data,
size_t elem_size) {
124 obj->*Member = std::vector<T>();
125 size_t size =
sizeof(T);
126 for (
size_t i = 0; i < elem_size; i +=
size) {
129 (obj->*Member).push_back(value);
132 static int size(
const C *obj) {
133 return (obj->*Member).size() *
sizeof(T);
135 static typename std::vector<T>::const_iterator
begin(
const C *obj) {
136 return (obj->*Member).begin();
138 static typename std::vector<T>::const_iterator
end(
const C *obj) {
139 return (obj->*Member).end();
144 template <
typename T>
148 template <
typename T>
153 template <
typename Obj,
typename Col, Col Obj::* Member>
157 typedef typename CollectionType::const_iterator
iterator;
159 (obj->*Member).push_back(element);
162 return (obj->*Member).begin();
165 return (obj->*Member).end();
183 static bool Verifier(
const void * obj,
const uint8_t *data,
size_t size,
211 template<
class Derived>
216 template <
typename T>
217 static void Writer(T *msg, uint8_t *data,
size_t size) {
218 typedef typename Derived::Setter setter_t;
219 typedef typename mpl::if_<
221 mpl::int_<Derived::kSize>, mpl::int_<-1> >,
226 writer(data, Derived::kSize, msg);
229 template <
typename T>
232 typedef typename mpl::if_<
234 mpl::int_<Derived::kSize>, mpl::int_<0> >,
242 context->
SetError(Derived::kErrorCode, Derived::kErrorSubcode,
244 Derived::kSize > 0 ? Derived::kSize : context->
size());
247 if (!Derived::Verifier(obj, data, size, context)) {
249 context->
SetError(Derived::kErrorCode, Derived::kErrorSubcode,
251 Derived::kSize > 0 ? Derived::kSize : context->
size());
255 typedef typename Derived::ContextInit ctx_init_t;
256 ctx_init_t initializer;
260 int res = slen(context, data, Derived::kSize, size, obj);
263 context->
SetError(Derived::kErrorCode, Derived::kErrorSubcode,
268 typedef typename mpl::if_<boost::is_same<typename Derived::SizeSetter, void>,
270 mpl::equal_to<mpl::int_<Derived::kSize>, mpl::int_<-1> >,
273 mpl::greater<mpl::int_<Derived::kSize>, mpl::int_<0> >,
282 res = setter(data, size, context, obj);
284 context->
SetError(Derived::kErrorCode, Derived::kErrorSubcode,
286 Derived::kSize > 0 ? Derived::kSize : context->
size());
291 template <
typename T>
295 mpl::if_<boost::is_same<typename Derived::SizeSetter, void>,
296 typename mpl::if_<mpl::equal_to<mpl::int_<Derived::kSize>, mpl::int_<-1> >,
299 typename Derived::SizeSetter
302 int element_size = size_value_t::get(msg);
304 context->
advance(element_size);
307 assert(element_size >= 0);
308 if (size < (
size_t) element_size) {
315 boost::is_same<typename Derived::Setter, void>,
321 cbadd(context, data, element_size);
325 Derived::Writer(msg, data, size);
327 context->
advance(element_size);
333 int offset,
int element_size) {
334 int length = context->
length() - offset - element_size;
339 template <
typename Setter,
typename T>
342 Setter::set(obj, value);
346 template <
typename T>
351 template <
class Derived>
354 template <
typename T>
357 int advance = Derived::kSize;
360 if (size < (
size_t) advance) {
361 context->
SetError(Derived::kErrorCode, Derived::kErrorSubcode,
372 typedef typename mpl::if_<
373 boost::is_same<typename Derived::Setter, void>,
378 choice_setter_t setter;
381 int result =
ParseChoice(data, size, value, context, obj);
385 context->
SetError(Derived::kErrorCode, Derived::kErrorSubcode,
386 TYPE_NAME(Derived), data - advance, advance);
394 template <
typename T>
397 typedef typename Derived::Choice choice_t;
400 mpl::for_each<choice_t>(encoder);
405 template <
typename T>
412 template <
typename U>
415 if (U::first::value != -1 && U::first::value !=
value) {
431 template <
typename T>
432 static int ParseChoice(
const uint8_t *data,
size_t size,
int value,
436 mpl::for_each<typename Derived::Choice>(match);
440 template <
typename T>
447 template <
typename U,
typename CtxType>
451 if (Derived::kSize) {
453 if (
size < Derived::kSize)
return -1;
455 data += Derived::kSize;
456 size -= Derived::kSize;
462 result += Derived::kSize;
467 template <
typename U,
typename CtxType>
471 int value = Derived::Setter::get(
msg);
472 if (value == opt || opt == -1) {
478 template <
typename U>
482 typename U::ContextMatch matcher;
483 if (matcher.match(
msg)) {
489 template <
typename U>
493 if (
typeid(*
msg) ==
typeid(
typename U::ContextType)) {
494 typedef typename U::ContextType ctx_t;
495 const ctx_t *ctx =
static_cast<const ctx_t *
>(
msg);
497 typedef typename mpl::if_<
498 boost::is_same<typename Derived::Setter, void>,
513 template <
typename U>
524 typedef typename mpl::if_<
525 boost::is_same<typename U::second::ContextType, T>,
528 boost::is_same<typename U::second::ContextType, void>,
531 boost::is_base_of<T, typename U::second::ContextType>,
541 }
else if (result > 0) {
556 template <
class Derived>
559 template <
typename T>
567 template <
typename U>
600 template <
typename T>
603 int min = Derived::kMinOccurs;
604 if (min == 0 && size == 0) {
607 if (!Derived::Verifier(obj, data, size, context)) {
609 context->
SetError(Derived::kErrorCode, Derived::kErrorSubcode,
611 Derived::kSize > 0 ? Derived::kSize : context->
size());
614 int lensize = Derived::kSize;
617 if (size < (
size_t) lensize) {
618 PROTO_DEBUG(
"Error: size = " << size <<
" lensize = " << lensize);
619 context->
SetError(Derived::kErrorCode, Derived::kErrorSubcode,
627 if ((
size_t) length > size) {
628 PROTO_DEBUG(
"Error: length = " << length <<
" size = " << size);
629 context->
SetError(Derived::kErrorCode, Derived::kErrorSubcode,
636 int result = lensize;
637 int max = Derived::kMaxOccurs;
638 for (
int i = 0; (max == -1 || i < max) && (length > 0); i++) {
640 typedef typename Derived::ContextStorer ctx_access_t;
643 typedef typename mpl::if_<boost::is_same<typename Derived::ContextSwap, void>,
648 typedef typename mpl::if_<boost::is_same<child_obj_t, void>,
649 T, child_obj_t>
::type ctx_t;
650 ctx_t *child_obj = pushfn(context, obj);
653 mpl::for_each<typename Derived::Sequence>(parser);
658 if (sublen < (
int)(context->
size() + context->
lensize())) {
660 <<
" < " << context->
size() <<
"+" << context->
lensize());
661 context->
SetError(Derived::kErrorCode, Derived::kErrorSubcode,
670 typedef typename mpl::if_<boost::is_same<typename Derived::ContextSwap, void>,
680 template <
typename T>
687 mpl::for_each<sequence_t>(encoder);
692 template <
typename T>
697 typedef typename Derived::ContextStorer ctx_access_t;
704 child_obj_t *child_obj = iter.
Next();
708 data, size, &subres);
709 mpl::for_each<sequence_t>(encoder);
719 context->
Pop(data != NULL);
725 template <
typename T>
730 if (Derived::kSize > 0) {
734 data += Derived::kSize;
735 size -= Derived::kSize;
737 context->
advance(Derived::kSize);
739 typedef typename mpl::if_<
741 mpl::equal_to<mpl::int_<Derived::kMaxOccurs>,
743 mpl::greater<mpl::int_<Derived::kMaxOccurs>,
749 int result = encoder(context, msg, data, size);
751 result += Derived::kSize;
752 context->
Pop(data != NULL);
758 template <
typename T>
765 template <
typename U>
791 int offset,
int arg) {
792 int length = context->
length() - Derived::kSize;
boost::function< void(EncodeContext *, uint8_t *, int, int)> CallbackType
void SaveOffset(std::string)
void AddCallback(CallbackType cb, uint8_t *data, int arg)
EncodeOffsets & encode_offsets()
boost::ptr_vector< StackFrame > stack_
const ParseErrorContext & error_context()
void set_lensize(int lensize)
void set_size(size_t length)
void SetError(int error, int subcode, std::string type, const uint8_t *data, int data_size)
size_t total_size() const
void Push(ParseObject *data)
ParseErrorContext error_context_
void SwapData(ParseObject *obj)
std::vector< StackFrame * > stack_
static int Encode(EncodeContext *context, const T *msg, uint8_t *data, size_t size)
static int ParseChoice(const uint8_t *data, size_t size, int value, ParseContext *context, T *obj)
static int Parse(const uint8_t *data, size_t size, ParseContext *context, T *obj)
static int Encode(EncodeContext *context, const T *msg, uint8_t *data, size_t size)
static void Writer(T *msg, uint8_t *data, size_t size)
static int Parse(const uint8_t *data, size_t size, ParseContext *context, T *obj)
static void SequenceLengthWriteLen(EncodeContext *context, uint8_t *data, int offset, int element_size)
static void SequenceLengthWriteLen(EncodeContext *context, uint8_t *data, int offset, int arg)
static int Encode(EncodeContext *context, const T *msg, uint8_t *data, size_t size)
static int Parse(const uint8_t *data, size_t size, ParseContext *context, T *obj)
static const int kMinOccurs
static const int kMaxOccurs
static void put_value(uint8_t *data, int size, uint64_t value)
static uint64_t get_value(const uint8_t *data, int size)
#define PROTO_DEBUG(args...)
static std::string::const_iterator begin(const C *obj)
static int size(const C *obj)
static std::string::const_iterator end(const C *obj)
static void set(C *obj, const uint8_t *data, size_t elem_size)
static void set(C *obj, T value)
static T get(const C *obj)
void operator()(T *obj, int value)
void operator()(T *obj, int &value)
CollectionType::const_iterator iterator
static iterator begin(const Obj *obj)
ValueType< typename Col::value_type >::type ValueType
static iterator end(const Obj *obj)
static void insert(Obj *obj, ValueType *element)
static const int kErrorSubcode
static bool Verifier(const void *obj, const uint8_t *data, size_t size, ParseContext *context)
static const int kErrorCode
int operator()(int opt, EncodeContext *context, const T *msg, uint8_t *data, int size)
int operator()(int opt, EncodeContext *context, T *msg, uint8_t *data, int size)
int operator()(int opt, EncodeContext *context, const T *msg, uint8_t *data, int size)
int operator()(int opt, EncodeContext *context, const CtxType *msg, uint8_t *data, int size)
int operator()(int opt, EncodeContext *context, const CtxType *msg, uint8_t *data, int size)
ChoiceEncoder(EncodeContext *context, const T *msg, uint8_t *data, int size, int *resultp)
ChoiceMatcher(const uint8_t *data, size_t size, int value, ParseContext *context, T *obj, int *resultp)
Derived::Sequence sequence_t
int operator()(EncodeContext *context, const T *msg, uint8_t *data, size_t size)
void operator()(U element)
SequenceEncoder(EncodeContext *context, const T *msg, uint8_t *data, size_t size, int *resultp)
SequenceParser(const uint8_t *data, size_t size, ParseContext *context, T *obj, int *resultp)
Derived::Sequence sequence_t
int operator()(EncodeContext *context, const T *msg, uint8_t *data, size_t size)
static void set(C *obj, const uint8_t *data, size_t elem_size)
static std::vector< T >::const_iterator end(const C *obj)
static int size(const C *obj)
static std::vector< T >::const_iterator begin(const C *obj)
ContextAccessor::ValueType ValueType
bool HasNext(Obj *obj) const