this method will try to resize GrowingBuffer to accommodate_size elements (in reality it preallocates a 'few' more ) if the new size is 0, then internal buffer object is deleted, freeing all memory Warning: when buffer is growing, only it's part that contains any valid data is copied (i.e. from start, to write_off ) returns -2 if there were problems allocating new block of memory for the intern
| 176 | returns 0 if everything went ok |
| 177 | */ |
| 178 | int GrowingBuffer::resize(uint32_t accommodate_size) |
| 179 | { |
| 180 | uint32_t new_size = accommodate_size ? 2*accommodate_size+1 : 0; |
| 181 | if(accommodate_size>m_max_size) |
| 182 | return -1; |
| 183 | if(accommodate_size<m_size) |
| 184 | return 0; |
| 185 | assert(accommodate_size<0x100000); |
| 186 | new_size = std::min<uint32_t>(new_size,m_max_size); |
| 187 | // fix read/write indexers ( it'll happen only if new size is less then current size) |
| 188 | if(m_read_off>new_size) |
| 189 | m_read_off = new_size; |
| 190 | if(m_write_off>new_size) |
| 191 | m_write_off = new_size; |
| 192 | |
| 193 | if(0==new_size) // requested freeing of internal buffer |
| 194 | { |
| 195 | delete [] m_buf; |
| 196 | m_buf = nullptr; // this allows us to catch calls through Unchecked methods quickly |
| 197 | m_size= new_size; |
| 198 | return 0; |
| 199 | } |
| 200 | if(new_size>m_size) |
| 201 | { |
| 202 | uint8_t *tmp = new uint8_t[new_size+m_safe_area]; |
| 203 | if(nullptr==tmp) |
| 204 | return -2; |
| 205 | assert(m_write_off<=m_size); // just to be sure |
| 206 | if(m_write_off>1) |
| 207 | memcpy(tmp,m_buf,m_size); // copying old contents, up to actual m_write_off |
| 208 | memset(&tmp[m_size],0,new_size+m_safe_area-m_size); |
| 209 | delete [] m_buf; |
| 210 | m_buf = tmp; |
| 211 | m_size = new_size; |
| 212 | } |
| 213 | return 0; |
| 214 | } |
| 215 | |
| 216 | //! @} |
no outgoing calls