blob: 398817f6f74bc2b737ff11989b44daedbc9c0456 [file] [log] [blame]
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -08001/* -*- 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 <alexander.afanasyev@ucla.edu>
8 */
9
10#ifndef NDN_BUFFER_HPP
11#define NDN_BUFFER_HPP
12
Alexander Afanasyev19508852014-01-29 01:01:51 -080013#include "../common.hpp"
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -080014
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -080015namespace ndn {
16
17class Buffer;
18typedef ptr_lib::shared_ptr<const Buffer> ConstBufferPtr;
19typedef ptr_lib::shared_ptr<Buffer> BufferPtr;
20
21/**
22 * @brief Class representing a general-use automatically managed/resized buffer
23 *
24 * In most respect, Buffer class is equivalent to std::vector<uint8_t> and is in fact
25 * uses it as a base class. In addition to that, it provides buf() and buf<T>() helper
26 * method for easier access to the underlying data (buf<T>() casts pointer to the requested class)
27 */
28class Buffer : public std::vector<uint8_t>
29{
30public:
31 /**
32 * @brief Creates an empty buffer
33 */
34 Buffer ()
35 {
36 }
37
38 /**
Wentao Shang77949212014-02-01 23:42:24 -080039 * @brief Creates a buffer with pre-allocated size
40 * @param size size of the buffer to be allocated
41 */
42 Buffer (size_t size)
43 : std::vector<uint8_t> (size, 0)
44 {
45 }
46
47 /**
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -080048 * @brief Create a buffer by copying the supplied data from a const buffer
49 * @param buf const pointer to buffer
50 * @param length length of the buffer to copy
51 */
52 Buffer (const void *buf, size_t length)
53 : std::vector<uint8_t> (reinterpret_cast<const uint8_t*> (buf), reinterpret_cast<const uint8_t*> (buf) + length)
54 {
55 }
56
57 /**
58 * @brief Create a buffer by copying the supplied data using iterator interface
59 *
60 * Note that the supplied iterators must be compatible with std::vector<uint8_t> interface
61 *
62 * @param first iterator to a first element to copy
63 * @param last iterator to an element immediately following the last element to copy
64 */
65 template <class InputIterator>
66 Buffer (InputIterator first, InputIterator last)
67 : std::vector<uint8_t> (first, last)
68 {
69 }
70
71 /**
72 * @brief Get pointer to the first byte of the buffer
73 */
74 inline uint8_t*
75 get ()
76 {
77 return &front ();
78 }
79
80 /**
81 * @brief Get pointer to the first byte of the buffer (alternative version)
82 */
83 inline uint8_t*
84 buf ()
85 {
86 return &front ();
87 }
88
89 /**
90 * @brief Get pointer to the first byte of the buffer and cast
91 * it (reinterpret_cast) to the requested type T
92 */
93 template<class T>
94 inline T*
95 get ()
96 {
97 return reinterpret_cast<T *>(&front ());
98 }
99
100 /**
101 * @brief Get pointer to the first byte of the buffer (alternative version)
102 */
103 inline const uint8_t*
104 buf () const
105 {
106 return &front ();
107 }
108
109 /**
110 * @brief Get const pointer to the first byte of the buffer
111 */
112 inline const uint8_t*
113 get () const
114 {
115 return &front ();
116 }
117
118 /**
119 * @brief Get const pointer to the first byte of the buffer and cast
120 * it (reinterpret_cast) to the requested type T
121 */
122 template<class T>
123 inline const T*
124 get () const
125 {
126 return reinterpret_cast<const T *>(&front ());
127 }
128};
129
130/// @cond include_hidden
131namespace iostreams
132{
133
134class buffer_append_device {
135public:
136 typedef char char_type;
137 typedef boost::iostreams::sink_tag category;
138
139 buffer_append_device (Buffer& container)
140 : m_container (container)
141 {
142 }
143
144 std::streamsize
145 write(const char_type* s, std::streamsize n)
146 {
147 std::copy (s, s+n, std::back_inserter(m_container));
148 return n;
149 }
150
151protected:
152 Buffer& m_container;
153};
154
155} // iostreams
156/// @endcond
157
158/**
159 * Class implementing interface similar to ostringstream, but to construct ndn::Buffer
160 *
161 * The benefit of using stream interface is that it provides automatic buffering of written data
162 * and eliminates (or reduces) overhead of resizing the underlying buffer when writing small pieces of data.
163 *
164 * Usage example:
165 * @code
166 * OBufferStream obuf;
167 * obuf.put(0);
168 * obuf.write(another_buffer, another_buffer_size);
169 * ptr_lib::shared_ptr<Buffer> buf = obuf.get();
170 * @endcode
171 */
172struct OBufferStream : public boost::iostreams::stream<iostreams::buffer_append_device>
173{
174 /**
175 * Default constructor
176 */
177 OBufferStream ()
178 : m_buffer (ptr_lib::make_shared<Buffer> ())
179 , m_device (*m_buffer)
180 {
181 open (m_device);
182 }
183
184 /**
185 * Flush written data to the stream and return shared pointer to the underlying buffer
186 */
187 ptr_lib::shared_ptr<Buffer>
188 buf ()
189 {
190 flush ();
191 return m_buffer;
192 }
193
194private:
195 BufferPtr m_buffer;
196 iostreams::buffer_append_device m_device;
197};
198
199
200} // ndn
201
202#endif // NDN_BUFFER_HPP