OpenSDN source code
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
src/contrail-common/base/proto.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
3  */
4 
5 #include "base/proto.h"
6 
7 #include <boost/bind.hpp>
8 
9 using namespace std;
10 
11 namespace detail {
12  bool debug_ = false;
13 }
14 
16  StackFrame() : offset(0), lensize(0), size(-1), total_size(-1) {
17  }
18  int offset; // offset of the data pointer at present
19  int lensize; //size of the length of the current element being parsed
20  size_t size;
21  size_t total_size;
22  std::unique_ptr<ParseObject> data;
23 };
24 
26  : offset_(0) {
27 }
28 
29 struct deleter {
30  template <typename T>
31  void operator()(T *ptr) {
32  delete ptr;
33  }
34 };
35 
37  for_each(stack_.begin(), stack_.end(), deleter());
38  stack_.clear();
39 }
40 
42  if (stack_.empty()) {
43  return NULL;
44  }
45  StackFrame *current = stack_.back();
46  return current->data.release();
47 }
48 
50  StackFrame *frame = new StackFrame();
51  frame->data.reset(data);
52  stack_.push_back(frame);
53 }
54 
56  if (stack_.size() <= 1) {
57  return NULL;
58  }
59  StackFrame *frame = stack_.back();
60  ParseObject *obj = frame->data.release();
61  stack_.pop_back();
62  delete frame;
63  return obj;
64 }
65 
67  if (!stack_.empty()) {
68  StackFrame *frame = stack_.back();
69  frame->data.release();
70  }
71 }
73  if (!stack_.empty() && obj) {
74  StackFrame *frame = stack_.back();
75  frame->data.reset(obj);
76  } else {
77  delete obj;
78  }
79 }
80 
82  if (stack_.empty()) {
83  return NULL;
84  }
85  StackFrame *current = stack_.back();
86  return current->data.get();
87 }
88 
89 void ParseContext::advance(int delta) {
90  if (!stack_.empty()) {
91  stack_.back()->offset += delta;
92  }
93  offset_ += delta;
94 }
95 
96 void ParseContext::set_lensize(int length) {
97  if (!stack_.empty()) {
98  StackFrame *current = stack_.back();
99  current->lensize = length;
100  }
101 }
102 
104  if (stack_.empty()) {
105  return -1;
106  }
107  StackFrame *current = stack_.back();
108  return current->lensize;
109 }
110 
111 void ParseContext::set_size(size_t length) {
112  if (!stack_.empty()) {
113  StackFrame *current = stack_.back();
114  current->size = length;
115  }
116 }
117 
118 size_t ParseContext::size() const {
119  if (stack_.empty()) {
120  return -1;
121  }
122  StackFrame *current = stack_.back();
123  return current->size;
124 }
125 
127  if (!stack_.empty()) {
128  StackFrame *current = stack_.back();
129  current->total_size = current->size;
130  }
131 }
132 
133 size_t ParseContext::total_size() const {
134  if (stack_.empty()) {
135  return -1;
136  }
137  StackFrame *current = stack_.back();
138  return current->total_size >= 0 ? current->total_size : current->size;
139 }
140 
141 void ParseContext::SetError(int error, int subcode, std::string type,
142  const uint8_t *data, int data_size) {
144  // Error already set. Ignore this one.
145  return;
146  }
147  error_context_.error_code = error;
148  error_context_.error_subcode = subcode;
151  error_context_.data_size = data_size;
152 }
153 
155  typedef boost::function<void(EncodeContext *)> CallbackFn;
156  typedef std::vector<CallbackFn>::iterator CallbackIterator;
158  }
159  int offset;
160  std::vector<CallbackFn> callbacks;
161 };
162 
164 }
165 
167 }
168 
170  StackFrame *frame = new StackFrame();
171  stack_.push_back(frame);
172 }
173 
174 void EncodeContext::Pop(bool callback) {
175  StackFrame *frame = &stack_.back();
176  if (callback) {
177  for (StackFrame::CallbackIterator iter =
178  frame->callbacks.begin(); iter != frame->callbacks.end(); ++iter) {
179  StackFrame::CallbackFn cb = *iter;
180  (cb)(this);
181  }
182  }
183 
184  int p_offset = frame->offset;
185  stack_.pop_back(); // deletes frame
186  if (!stack_.empty()) {
187  StackFrame *top = &(stack_.back());
188  top->offset += p_offset;
189  }
190 }
191 
192 void EncodeContext::advance(int delta) {
193  if (stack_.empty()) {
194  return;
195  }
196  StackFrame *frame = &stack_.back();
197  frame->offset += delta;
198 }
199 
201  const StackFrame *frame = &stack_.back();
202  return frame->offset;
203 };
204 
206  int element_size) {
207  StackFrame *top = &(stack_.back());
208  top->callbacks.push_back(
209  boost::bind(cb, _1, data, top->offset, element_size));
210 }
211 
212 void EncodeOffsets::SaveOffset(std::string key, int offset) {
213  std::pair<std::map<std::string, int>::iterator, bool > result =
214  offsets_.insert(make_pair(key, offset));
215  if (!result.second) {
216  PROTO_DEBUG("Offset for " << key << " already set");
217  }
218 }
219 
220 void EncodeContext::SaveOffset(std::string key) {
221  int length = 0;
222  for (boost::ptr_vector<StackFrame>::iterator it = stack_.begin();
223  it != stack_.end(); ++it) {
224  length += it->offset;
225  }
226  PROTO_DEBUG("Saving Offset for " << key << " at " << length);
227  offsets_.SaveOffset(key, length);
228 }
229 
230 int EncodeOffsets::FindOffset(const char *key) {
231  std::map<std::string, int>::iterator it = offsets_.find(std::string(key));
232  if (it == offsets_.end())
233  return -1;
234  return it->second;
235 }
#define PROTO_DEBUG(args...)
Definition: proto_impl.h:13
void set_lensize(int lensize)
void SwapData(ParseObject *obj)
void SetError(int error, int subcode, std::string type, const uint8_t *data, int data_size)
std::string type_name
Definition: parse_object.h:88
boost::function< void(EncodeContext *)> CallbackFn
uint8_t type
Definition: load_balance.h:109
ParseErrorContext error_context_
std::vector< StackFrame * > stack_
bool debug_
std::unique_ptr< ParseObject > data
const uint8_t * data
Definition: parse_object.h:89
void AddCallback(CallbackType cb, uint8_t *data, int arg)
void SaveOffset(std::string, int)
boost::function< void(EncodeContext *, uint8_t *, int, int)> CallbackType
void set_size(size_t length)
boost::ptr_vector< StackFrame > stack_
void Push(ParseObject *data)
std::map< std::string, int > offsets_
Definition: parse_object.h:99
std::vector< CallbackFn >::iterator CallbackIterator