All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
block.hpp
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
2 /*
3  * Copyright (c) 2013, Regents of the University of California
4  *
5  * BSD license, See the LICENSE file for more information
6  *
7  * Author: Alexander Afanasyev <[email protected]>
8  */
9 
10 #ifndef NDN_BLOCK_HPP
11 #define NDN_BLOCK_HPP
12 
13 #include "../common.hpp"
14 
15 #include "buffer.hpp"
16 #include "tlv.hpp"
17 
18 namespace ndn {
19 
20 template<bool> class EncodingImpl;
22 
26 class Block
27 {
28 public:
29  typedef std::vector<Block> element_container;
30  typedef element_container::iterator element_iterator;
31  typedef element_container::const_iterator element_const_iterator;
32 
34  class Error : public Tlv::Error
35  {
36  public:
37  explicit
38  Error(const std::string& what)
39  : Tlv::Error(what)
40  {
41  }
42  };
43 
47  Block();
48 
52  explicit
53  Block(const EncodingBuffer& buffer);
54 
61  Block(const ConstBufferPtr& buffer);
62 
69  Block(const ConstBufferPtr& buffer,
70  const Buffer::const_iterator& begin, const Buffer::const_iterator& end,
71  bool verifyLength = true);
72 
77  Block(const uint8_t* buffer, size_t maxlength);
78 
79  Block(const void* buffer, size_t maxlength);
80 
81  /*
82  * @brief A helper version of a constructor to create Block from the stream.
83  */
84  explicit
85  Block(std::istream& is);
86 
92  Block(const ConstBufferPtr& wire,
93  uint32_t type,
94  const Buffer::const_iterator& begin, const Buffer::const_iterator& end,
95  const Buffer::const_iterator& valueBegin, const Buffer::const_iterator& valueEnd);
96 
100  explicit
101  Block(uint32_t type);
102 
110  Block(uint32_t type, const ConstBufferPtr& value);
111 
119  explicit
120  Block(uint32_t type, const Block& value);
121 
129  static bool
130  fromBuffer(const ConstBufferPtr& wire, size_t offset, Block& block);
131 
139  static bool
140  fromBuffer(const uint8_t* buffer, size_t maxSize, Block& block);
141 
145  bool
146  empty() const;
147 
151  bool
152  hasWire() const;
153 
157  bool
158  hasValue() const;
159 
163  void
164  reset();
165 
169  void
170  resetWire();
171 
178  void
179  parse() const;
180 
184  void
185  encode();
186 
187  uint32_t
188  type() const;
189 
193  const Block&
194  get(uint32_t type) const;
195 
197  find(uint32_t type) const;
198 
199  void
200  remove(uint32_t type);
201 
203  erase(element_iterator position);
204 
207 
208  void
209  push_back(const Block& element);
210 
211  Buffer::const_iterator
212  begin() const;
213 
214  Buffer::const_iterator
215  end() const;
216 
217  const uint8_t*
218  wire() const;
219 
220  size_t
221  size() const;
222 
223  Buffer::const_iterator
224  value_begin() const;
225 
226  Buffer::const_iterator
227  value_end() const;
228 
229  const uint8_t*
230  value() const;
231 
232  size_t
233  value_size() const;
234 
238  const element_container&
239  elements() const;
240 
242  elements_begin() const;
243 
245  elements_end() const;
246 
247  size_t
248  elements_size() const;
249 
250  Block
251  blockFromValue() const;
252 
253 public: // EqualityComparable concept
254  bool
255  operator==(const Block& other) const;
256 
257  bool
258  operator!=(const Block& other) const;
259 
260 protected:
262 
263  uint32_t m_type;
264 
265  Buffer::const_iterator m_begin;
266  Buffer::const_iterator m_end;
267  uint32_t m_size;
268 
269  Buffer::const_iterator m_value_begin;
270  Buffer::const_iterator m_value_end;
271 
273  friend class EncodingImpl<true>;
274 };
275 
279 
280 inline bool
282 {
283  return m_type == std::numeric_limits<uint32_t>::max();
284 }
285 
286 
287 inline bool
289 {
290  return m_buffer && (m_begin != m_end);
291 }
292 
293 inline bool
295 {
296  return static_cast<bool>(m_buffer);
297 }
298 
299 inline void
301 {
302  m_buffer.reset(); // reset of the shared_ptr
303  m_subBlocks.clear(); // remove all parsed subelements
304 
305  m_type = std::numeric_limits<uint32_t>::max();
306  m_begin = m_end = m_value_begin = m_value_end = Buffer::const_iterator();
307 }
308 
309 inline void
311 {
312  m_buffer.reset(); // reset of the shared_ptr
313  // keep subblocks
314 
315  // keep type
316  m_begin = m_end = m_value_begin = m_value_end = Buffer::const_iterator();
317 }
318 
319 inline uint32_t
320 Block::type() const
321 {
322  return m_type;
323 }
324 
325 inline const Block&
326 Block::get(uint32_t type) const
327 {
328  for (element_const_iterator i = m_subBlocks.begin();
329  i != m_subBlocks.end();
330  i++)
331  {
332  if (i->type() == type)
333  {
334  return *i;
335  }
336  }
337 
338  throw Error("(Block::get) Requested a non-existed type [" +
339  boost::lexical_cast<std::string>(type) + "] from Block");
340 }
341 
343 Block::find(uint32_t type) const
344 {
345  for (element_const_iterator i = m_subBlocks.begin();
346  i != m_subBlocks.end();
347  i++)
348  {
349  if (i->type() == type)
350  {
351  return i;
352  }
353  }
354  return m_subBlocks.end();
355 }
356 
357 inline void
358 Block::remove(uint32_t type)
359 {
360  resetWire();
361 
362  element_container newContainer;
363  newContainer.reserve(m_subBlocks.size());
364  for (element_iterator i = m_subBlocks.begin();
365  i != m_subBlocks.end();
366  ++i)
367  {
368  if (i->type() != type)
369  newContainer.push_back(*i);
370  }
371  m_subBlocks.swap(newContainer);
372 }
373 
376 {
377  resetWire();
378  return m_subBlocks.erase(position);
379 }
380 
383 {
384  resetWire();
385  return m_subBlocks.erase(first, last);
386 }
387 
388 
389 inline void
390 Block::push_back(const Block& element)
391 {
392  resetWire();
393  m_subBlocks.push_back(element);
394 }
395 
396 inline Buffer::const_iterator
398 {
399  if (!hasWire())
400  throw Error("Underlying wire buffer is empty");
401 
402  return m_begin;
403 }
404 
405 inline Buffer::const_iterator
406 Block::end() const
407 {
408  if (!hasWire())
409  throw Error("Underlying wire buffer is empty");
410 
411  return m_end;
412 }
413 
414 inline size_t
415 Block::size() const
416 {
417  if (hasWire() || hasValue()) {
418  return m_size;
419  }
420  else
421  throw Error("Block size cannot be determined (undefined block size)");
422 }
423 
424 inline Buffer::const_iterator
426 {
427  return m_value_begin;
428 }
429 
430 inline Buffer::const_iterator
432 {
433  return m_value_end;
434 }
435 
436 inline const uint8_t*
437 Block::wire() const
438 {
439  if (!hasWire())
440  throw Error("(Block::wire) Underlying wire buffer is empty");
441 
442  return &*m_begin;
443 }
444 
445 inline const uint8_t*
447 {
448  if (!hasValue())
449  return 0;
450 
451  return &*m_value_begin;
452 }
453 
454 inline size_t
456 {
457  if (!hasValue())
458  return 0;
459 
460  return m_value_end - m_value_begin;
461 }
462 
463 inline const Block::element_container&
465 {
466  return m_subBlocks;
467 }
468 
471 {
472  return m_subBlocks.begin();
473 }
474 
477 {
478  return m_subBlocks.end();
479 }
480 
481 inline size_t
483 {
484  return m_subBlocks.size();
485 }
486 
487 inline bool
488 Block::operator==(const Block& other) const
489 {
490  return (this->size() == other.size()) &&
491  std::equal(this->begin(), this->end(), other.begin());
492 }
493 
494 inline bool
495 Block::operator!=(const Block& other) const
496 {
497  return !this->operator==(other);
498 }
499 
500 } // ndn
501 
502 #include "block-helpers.hpp"
503 
504 #endif // NDN_BLOCK_HPP
bool empty() const
Check if the Block is empty.
Definition: block.hpp:281
bool operator!=(const Block &other) const
Definition: block.hpp:495
bool hasValue() const
Check if the Block has value block (no type and length are encoded)
Definition: block.hpp:294
Error(const std::string &what)
Definition: block.hpp:38
Buffer::const_iterator end() const
Definition: block.hpp:406
Buffer::const_iterator m_begin
Definition: block.hpp:265
element_const_iterator find(uint32_t type) const
Definition: block.hpp:343
EncodingImpl< true > EncodingBuffer
Definition: block.hpp:20
element_container::iterator element_iterator
Definition: block.hpp:30
const element_container & elements() const
Get all subelements.
Definition: block.hpp:464
Class representing wire element of the NDN packet.
Definition: block.hpp:26
Buffer::const_iterator value_begin() const
Definition: block.hpp:425
Buffer::const_iterator value_end() const
Definition: block.hpp:431
void resetWire()
Reset wire buffer but keep sub elements (if any)
Definition: block.hpp:310
uint32_t m_size
Definition: block.hpp:267
ConstBufferPtr m_buffer
Definition: block.hpp:261
element_const_iterator elements_end() const
Definition: block.hpp:476
size_t size() const
Definition: block.hpp:415
element_const_iterator elements_begin() const
Definition: block.hpp:470
ptr_lib::shared_ptr< const Buffer > ConstBufferPtr
Definition: buffer.hpp:17
Buffer::const_iterator m_value_end
Definition: block.hpp:270
Block blockFromValue() const
Definition: block.cpp:352
const Block & get(uint32_t type) const
Get the first subelement of the requested type.
Definition: block.hpp:326
element_container::const_iterator element_const_iterator
Definition: block.hpp:31
size_t elements_size() const
Definition: block.hpp:482
void remove(uint32_t type)
Definition: block.hpp:358
void reset()
Reset wire buffer of the element.
Definition: block.hpp:300
void push_back(const Block &element)
Definition: block.hpp:390
size_t value_size() const
Definition: block.hpp:455
void parse() const
Parse wire buffer into subblocks.
Definition: block.cpp:265
std::vector< Block > element_container
Definition: block.hpp:29
uint32_t type() const
Definition: block.hpp:320
void encode()
Encode subblocks into wire buffer.
Definition: block.cpp:298
const uint8_t * wire() const
Definition: block.hpp:437
element_container m_subBlocks
Definition: block.hpp:272
Buffer::const_iterator m_end
Definition: block.hpp:266
bool hasWire() const
Check if the Block has fully encoded wire.
Definition: block.hpp:288
static bool fromBuffer(const ConstBufferPtr &wire, size_t offset, Block &block)
Try to construct block from Buffer, referencing data block pointed by wire.
Definition: block.cpp:209
const uint8_t * value() const
Definition: block.hpp:446
uint32_t m_type
Definition: block.hpp:263
bool operator==(const Block &other) const
Definition: block.hpp:488
Buffer::const_iterator m_value_begin
Definition: block.hpp:269
Block()
Default constructor to create an empty Block.
Definition: block.cpp:18
element_iterator erase(element_iterator position)
Definition: block.hpp:375
Error that can be thrown from Block.
Definition: block.hpp:34
Buffer::const_iterator begin() const
Definition: block.hpp:397