blob: d4b14c0cce474b2b1a1cc35b74ac782439ff5228 [file] [log] [blame]
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -08001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
Alexander Afanasyevdfa52c42014-04-24 21:10:11 -07002/**
3 * Copyright (c) 2013-2014, Regents of the University of California.
4 * All rights reserved.
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -08005 *
Alexander Afanasyevdfa52c42014-04-24 21:10:11 -07006 * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
7 * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -08008 *
Alexander Afanasyevdfa52c42014-04-24 21:10:11 -07009 * This file licensed under New BSD License. See COPYING for detailed information about
10 * ndn-cxx library copyright, permissions, and redistribution restrictions.
11 *
12 * @author Alexander Afanasyev <http://lasr.cs.ucla.edu/afanasyev/index.html>
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -080013 */
14
15#ifndef NDN_BUFFER_HPP
16#define NDN_BUFFER_HPP
17
Alexander Afanasyev19508852014-01-29 01:01:51 -080018#include "../common.hpp"
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -080019
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -080020namespace ndn {
21
22class Buffer;
Alexander Afanasyevb67090a2014-04-29 22:31:01 -070023typedef shared_ptr<const Buffer> ConstBufferPtr;
24typedef shared_ptr<Buffer> BufferPtr;
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -080025
26/**
27 * @brief Class representing a general-use automatically managed/resized buffer
28 *
29 * In most respect, Buffer class is equivalent to std::vector<uint8_t> and is in fact
30 * uses it as a base class. In addition to that, it provides buf() and buf<T>() helper
31 * method for easier access to the underlying data (buf<T>() casts pointer to the requested class)
32 */
33class Buffer : public std::vector<uint8_t>
34{
35public:
36 /**
37 * @brief Creates an empty buffer
38 */
Alexander Afanasyeva465e972014-03-22 17:21:49 -070039 Buffer()
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -080040 {
41 }
42
43 /**
Wentao Shang77949212014-02-01 23:42:24 -080044 * @brief Creates a buffer with pre-allocated size
45 * @param size size of the buffer to be allocated
46 */
Alexander Afanasyeva465e972014-03-22 17:21:49 -070047 explicit
48 Buffer(size_t size)
49 : std::vector<uint8_t>(size, 0)
Wentao Shang77949212014-02-01 23:42:24 -080050 {
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 */
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070058 Buffer(const void* buf, size_t length)
Alexander Afanasyeva465e972014-03-22 17:21:49 -070059 : std::vector<uint8_t>(reinterpret_cast<const uint8_t*>(buf),
60 reinterpret_cast<const uint8_t*>(buf) + length)
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -080061 {
62 }
63
64 /**
65 * @brief Create a buffer by copying the supplied data using iterator interface
66 *
67 * Note that the supplied iterators must be compatible with std::vector<uint8_t> interface
68 *
69 * @param first iterator to a first element to copy
70 * @param last iterator to an element immediately following the last element to copy
71 */
72 template <class InputIterator>
Alexander Afanasyeva465e972014-03-22 17:21:49 -070073 Buffer(InputIterator first, InputIterator last)
74 : std::vector<uint8_t>(first, last)
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -080075 {
76 }
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -070077
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -080078 /**
79 * @brief Get pointer to the first byte of the buffer
80 */
Alexander Afanasyeva465e972014-03-22 17:21:49 -070081 uint8_t*
82 get()
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -080083 {
Alexander Afanasyeva465e972014-03-22 17:21:49 -070084 return &front();
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -080085 }
86
87 /**
88 * @brief Get pointer to the first byte of the buffer (alternative version)
89 */
Alexander Afanasyeva465e972014-03-22 17:21:49 -070090 uint8_t*
91 buf()
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -080092 {
Alexander Afanasyeva465e972014-03-22 17:21:49 -070093 return &front();
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -080094 }
95
96 /**
97 * @brief Get pointer to the first byte of the buffer and cast
98 * it (reinterpret_cast) to the requested type T
99 */
100 template<class T>
Alexander Afanasyeva465e972014-03-22 17:21:49 -0700101 T*
102 get()
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800103 {
Alexander Afanasyeva465e972014-03-22 17:21:49 -0700104 return reinterpret_cast<T*>(&front());
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800105 }
106
107 /**
108 * @brief Get pointer to the first byte of the buffer (alternative version)
109 */
Alexander Afanasyeva465e972014-03-22 17:21:49 -0700110 const uint8_t*
111 buf() const
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800112 {
Alexander Afanasyeva465e972014-03-22 17:21:49 -0700113 return &front();
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800114 }
115
116 /**
117 * @brief Get const pointer to the first byte of the buffer
118 */
Alexander Afanasyeva465e972014-03-22 17:21:49 -0700119 const uint8_t*
120 get() const
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800121 {
Alexander Afanasyeva465e972014-03-22 17:21:49 -0700122 return &front();
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800123 }
124
125 /**
126 * @brief Get const pointer to the first byte of the buffer and cast
127 * it (reinterpret_cast) to the requested type T
128 */
129 template<class T>
Alexander Afanasyeva465e972014-03-22 17:21:49 -0700130 const T*
131 get() const
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800132 {
Alexander Afanasyeva465e972014-03-22 17:21:49 -0700133 return reinterpret_cast<const T*>(&front());
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700134 }
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800135};
136
137/// @cond include_hidden
138namespace iostreams
139{
140
Alexander Afanasyeva465e972014-03-22 17:21:49 -0700141class buffer_append_device
142{
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800143public:
Alexander Afanasyeva465e972014-03-22 17:21:49 -0700144 typedef char char_type;
145 typedef boost::iostreams::sink_tag category;
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700146
Alexander Afanasyeva465e972014-03-22 17:21:49 -0700147 buffer_append_device(Buffer& container)
148 : m_container(container)
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800149 {
150 }
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700151
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800152 std::streamsize
153 write(const char_type* s, std::streamsize n)
154 {
Alexander Afanasyeva465e972014-03-22 17:21:49 -0700155 std::copy(s, s+n, std::back_inserter(m_container));
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800156 return n;
157 }
Alexander Afanasyevfdbfc6d2014-04-14 15:12:11 -0700158
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800159protected:
160 Buffer& m_container;
161};
162
163} // iostreams
164/// @endcond
165
166/**
167 * Class implementing interface similar to ostringstream, but to construct ndn::Buffer
168 *
Alexander Afanasyeva465e972014-03-22 17:21:49 -0700169 * The benefit of using stream interface is that it provides automatic buffering of
170 * written data and eliminates (or reduces) overhead of resizing the underlying buffer
171 * when writing small pieces of data.
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800172 *
173 * Usage example:
174 * @code
175 * OBufferStream obuf;
176 * obuf.put(0);
177 * obuf.write(another_buffer, another_buffer_size);
Alexander Afanasyevf73f0632014-05-12 18:02:37 -0700178 * shared_ptr<Buffer> buf = obuf.get();
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800179 * @endcode
180 */
181struct OBufferStream : public boost::iostreams::stream<iostreams::buffer_append_device>
182{
183 /**
184 * Default constructor
185 */
Alexander Afanasyeva465e972014-03-22 17:21:49 -0700186 OBufferStream()
Alexander Afanasyevf73f0632014-05-12 18:02:37 -0700187 : m_buffer(make_shared<Buffer>())
Alexander Afanasyeva465e972014-03-22 17:21:49 -0700188 , m_device(*m_buffer)
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800189 {
Alexander Afanasyeva465e972014-03-22 17:21:49 -0700190 open(m_device);
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800191 }
192
193 /**
194 * Flush written data to the stream and return shared pointer to the underlying buffer
195 */
Alexander Afanasyevf73f0632014-05-12 18:02:37 -0700196 shared_ptr<Buffer>
Alexander Afanasyeva465e972014-03-22 17:21:49 -0700197 buf()
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800198 {
Alexander Afanasyeva465e972014-03-22 17:21:49 -0700199 flush();
Alexander Afanasyev13bb51a2014-01-02 19:13:26 -0800200 return m_buffer;
201 }
202
203private:
204 BufferPtr m_buffer;
205 iostreams::buffer_append_device m_device;
206};
207
208
209} // ndn
210
211#endif // NDN_BUFFER_HPP