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