1 /* 2 3 Copyright (c) 2002-2008, Yauheni Akhotnikau 4 Copyright (c) 2008-2016, The SObjectizer Project 5 All rights reserved. 6 7 Redistribution and use in source and binary forms, with or without 8 modification, are permitted provided that the following conditions are met: 9 10 - Redistributions of source code must retain the above copyright notice, this 11 list of conditions and the following disclaimer. 12 13 - Redistributions in binary form must reproduce the above copyright notice, this 14 list of conditions and the following disclaimer in the documentation and/or 15 other materials provided with the distribution. 16 17 - The name of the author may not be used to endorse or promote products derived 18 from this software without specific prior written permission. 19 20 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 21 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 22 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 23 EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 24 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 25 OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 28 IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 29 OF SUCH DAMAGE. 30 31 */ 32 33 /*! 34 \file 35 \brief mem_buf class. 36 */ 37 38 #if !defined( OESS_2_IO_MEM_BUF_HPP ) 39 #define OESS_2_IO_MEM_BUF_HPP 40 41 #include <oess_2/io/h/declspec.hpp> 42 43 #include <oess_2/io/h/binbuffer.hpp> 44 45 #include <vector> 46 #include <algorithm> 47 48 namespace oess_2 { 49 50 namespace io { 51 52 #if defined( _MSC_VER ) 53 #pragma warning(push) 54 #pragma warning(disable: 4251) 55 #pragma warning(disable: 4275) 56 #endif 57 58 // 59 // mem_buf_t 60 // 61 62 //! Binary input/output stream with growing memory buffer. 63 /*! 64 * \note 65 * Copy operation copies the current position in source buffer too: 66 \code 67 oess_2::io::mem_buf_t buf1( 1024 ); 68 oess_2::io::mem_buf_t buf2( 2048 ); 69 70 buf1.set_size( 256 ); 71 buf1.set_pos( 26 ); 72 73 buf2.set_size( 512 ); 74 buf2.set_pos( 384 ); 75 76 buf2 = buf1; 77 // 26 == buf2.pos() 78 \endcode 79 */ 80 class OESS_2_IO_TYPE mem_buf_t : 81 public ibinbuffer_t, 82 public obinbuffer_t 83 { 84 public : 85 //! Default constructor. 86 /*! 87 * Initial capacity is e_initial_capacity. 88 */ 89 mem_buf_t(); 90 //! Initializing constructor. 91 mem_buf_t( 92 //! Initial capacity of the buffer. 93 size_t capacity ); 94 mem_buf_t( 95 const mem_buf_t & o ); 96 virtual ~mem_buf_t(); 97 98 mem_buf_t & 99 operator=( 100 const mem_buf_t & o ); 101 102 enum { 103 e_initial_capacity = 64 104 }; 105 106 //! The current capacity. 107 virtual size_t 108 capacity() const override; 109 110 //! Recreate buffer. 111 /*! 112 * A new buffer is always allocated. 113 * 114 * If \a save_contents is true then the current buffer value 115 * is copied into the new buffer. 116 * 117 * Value of 'size' will be min(new_capacity, old_size). 118 * 119 * The current position become 0. 120 */ 121 void 122 change_capacity( 123 //! A new capacity of buffer. 124 size_t new_capacity, 125 //! Should the current content be saved? 126 bool save_contents = true ); 127 128 //! The current size of the buffer. 129 /*! 130 * Returns amount of data written into the buffer. 131 */ 132 virtual size_t 133 size() const override; 134 135 //! Change the amount of data in the buffer. 136 /*! 137 * The current position become 0. 138 * 139 * The size is changed only of new_size <= capacity(). 140 */ 141 void 142 change_size( 143 //! New data size. 144 size_t new_size ); 145 146 //! The current position in the buffer. 147 virtual size_t 148 pos() const override; 149 150 //! Change the current position. 151 /*! 152 * The current position is changed only if pos <= size(). 153 */ 154 void 155 set_pos( size_t pos ); 156 157 /*! 158 * \return true if pos() == size(). 159 */ 160 virtual bool 161 eof() const override; 162 163 //! A pointer to the beginning of the buffer. 164 const oess_2::char_t * 165 ptr() const; 166 167 //! A pointer to the current position in the buffer. 168 const oess_2::char_t * 169 current_ptr() const; 170 171 //! Copy a part of buffer content into another buffer. 172 /*! 173 * \a count bytes from position \a from_pos are copied into 174 * position \a to_pos of buffer \a to. 175 * 176 * The current position in \a to buffer is not changed. 177 * 178 * \note 179 * The presence of data is not checked. 180 */ 181 void 182 subbuf( 183 //! Source position in this buffer. 184 size_t from_pos, 185 //! A buffer-receiver. 186 mem_buf_t & to, 187 //! Target position in buffer-receiver. 188 size_t to_pos, 189 //! Count of bytes to be copied. 190 size_t count ) const; 191 192 //! Copy a part of buffer content into the specified memory location. 193 /*! 194 * \a count bytes from position \a from_pos are copied into \a to. 195 * 196 * \note 197 * The presence of data is not checked. 198 */ 199 void 200 subbuf( 201 //! Source position in this buffer. 202 size_t from_pos, 203 //! Memory area to which data will be copied. 204 void * to, 205 //! Count of bytes to be copied. 206 size_t count ) const; 207 208 //! Insertion of data. 209 /*! 210 * Insertion of \a count bytes from buffer \a from starting from 211 * position \a from_pos into position \a to_pos. 212 * The current content at position \a to_pos is moved to 213 * position (to_pos+count). 214 * 215 * The current position become 0. 216 * 217 * \note 218 * The presence of data in \a from is not checked. 219 * 220 * \note 221 * Behavior if to_pos > size() is not defined. 222 */ 223 void 224 insert( 225 //! Postion for data insertion. 226 size_t to_pos, 227 //! A source for data to be inserted. 228 const mem_buf_t & from, 229 //! A position in source buffer. 230 size_t from_pos, 231 //! Count of data to be copied. 232 size_t count ); 233 234 //! Insertion of data. 235 /*! 236 * Insertion of \a count bytes from memory area \a from into position 237 * \a to_pos. The current content at position \a to_pos is moved to 238 * position (to_pos+count). 239 * 240 * The current position become 0. 241 * 242 * \note 243 * The presence of data in \a from is not checked. 244 * 245 * \note 246 * Behavior if to_pos > size() is not defined. 247 */ 248 void 249 insert( 250 size_t to_pos, 251 const void * from, 252 size_t count ); 253 254 //! Erase part of data from buffer. 255 /*! 256 * \a count bytes from position \a from_offs are erased. 257 * 258 * \note 259 * Behavior if from_offs > size() or 260 * (from_offs + count > size()) is not defined. 261 */ 262 void 263 erase( 264 size_t from_offs, 265 size_t count ); 266 267 void 268 swap( 269 mem_buf_t & o ); 270 271 protected : 272 virtual const oess_2::char_t * 273 in_reserve( 274 size_t item_count, 275 size_t item_size, 276 size_t & item_available ) override; 277 278 virtual void 279 in_shift( 280 size_t item_count, 281 size_t item_size ) override; 282 283 virtual oess_2::char_t * 284 out_reserve( 285 size_t item_count, 286 size_t item_size, 287 size_t & item_available ) override; 288 289 virtual void 290 out_shift( 291 size_t item_count, 292 size_t item_size ) override; 293 294 private : 295 std::vector<oess_2::char_t> m_buf; 296 297 size_t m_size; 298 size_t m_pos; 299 }; 300 301 #if defined( _MSC_VER ) 302 #pragma warning(pop) 303 #endif 304 305 } /* namespace io */ 306 307 } /* namespace oess_2 */ 308 309 #endif 310