Loading...
Searching...
No Matches
binary_stream.cpp
1/*---------------------------------------------------------------------------*\
2 *
3 * bitpit
4 *
5 * Copyright (C) 2015-2021 OPTIMAD engineering Srl
6 *
7 * -------------------------------------------------------------------------
8 * License
9 * This file is part of bitpit.
10 *
11 * bitpit is free software: you can redistribute it and/or modify it
12 * under the terms of the GNU Lesser General Public License v3 (LGPL)
13 * as published by the Free Software Foundation.
14 *
15 * bitpit is distributed in the hope that it will be useful, but WITHOUT
16 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
17 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
18 * License for more details.
19 *
20 * You should have received a copy of the GNU Lesser General Public License
21 * along with bitpit. If not, see <http://www.gnu.org/licenses/>.
22 *
23\*---------------------------------------------------------------------------*/
24
25#include <cassert>
26#include <limits>
27#include <cmath>
28#include <cstring>
29
30#include "binary_stream.hpp"
31
32namespace bitpit {
33
40template<>
41bitpit::IBinaryStream& operator>>(bitpit::IBinaryStream &stream, std::string &data)
42{
43 std::size_t size;
44 stream.read(reinterpret_cast<char *>(&size), sizeof(size));
45
46 if (size > 0) {
47 std::vector<char> buffer(size);
48 stream.read(buffer.data(), size);
49 data.assign(buffer.data(), size);
50 } else {
51 data = "";
52 }
53
54 return stream;
55}
56
63template<>
64bitpit::OBinaryStream& operator<<(bitpit::OBinaryStream &stream, const std::string &data)
65{
66 std::size_t size = data.size();
67 stream.write(reinterpret_cast<const char *>(&size), sizeof(size));
68
69 if (size > 0) {
70 stream.write(data.c_str(), size);
71 }
72
73 return stream;
74}
75
89 : m_size(0), m_pos(0), m_chunkSize(1)
90{
91}
92
101 : m_pos(0)
102{
103 setSize(size);
104}
105
115BinaryStream::BinaryStream(const char *buffer, std::size_t capacity)
116{
117 open(buffer, capacity);
118}
119
128BinaryStream::BinaryStream(const std::vector<char> &buffer)
129{
130 open(buffer.data(), buffer.size());
131}
132
140void BinaryStream::open(const char *buffer, std::size_t size)
141{
142 open(size);
143
144 m_buffer.assign(buffer, buffer + size);
145}
146
152void BinaryStream::open(std::size_t size)
153{
154 m_pos = 0;
155
156 setSize(size);
157}
158
164std::streampos BinaryStream::tellg() const
165{
166 return m_pos;
167}
168
175bool BinaryStream::seekg(std::size_t pos)
176{
177 if (pos >= getSize()) {
178 return false;
179 }
180
181 m_pos = pos;
182
183 return true;
184}
185
192{
193 return m_buffer.data();
194}
195
201const char * BinaryStream::data() const
202{
203 return m_buffer.data();
204}
205
212{
213 return (m_pos >= getSize());
214}
215
223bool BinaryStream::seekg(std::streamoff offset, std::ios_base::seekdir way)
224{
225 if ((way == std::ios_base::beg) && (offset < (long) getSize())) {
226 m_pos = offset;
227 } else if ((way == std::ios_base::cur) && (m_pos + offset < getSize())) {
228 m_pos += offset;
229 } else if ((way == std::ios_base::end) && ((long) getSize() - offset >= 0)) {
230 m_pos = getSize() - offset;
231 } else {
232 return false;
233 }
234
235 return true;
236}
237
243std::size_t BinaryStream::getSize() const
244{
245 return m_size;
246}
247
253void BinaryStream::setSize(std::size_t size)
254{
255 setCapacity(size);
256
257 m_size = size;
258}
259
272void BinaryStream::setCapacity(std::size_t capacity)
273{
274 m_chunkSize = 1;
275 std::size_t nChunks = capacity;
276 while (nChunks > (std::size_t) std::numeric_limits<int>::max()) {
277 m_chunkSize = 2 * m_chunkSize;
278 nChunks = (1 + ((capacity - 1) / m_chunkSize));
279 }
280
281 m_buffer.resize(nChunks * m_chunkSize);
282}
283
295{
296 return m_chunkSize;
297}
298
313{
314 return (getCapacity() / m_chunkSize);
315}
316
332std::size_t BinaryStream::getCapacity() const
333{
334 return m_buffer.size();
335}
336
353
362 : BinaryStream(size)
363{
364}
365
375IBinaryStream::IBinaryStream(const char *buffer, std::size_t size)
376 : BinaryStream(buffer, size)
377{
378}
379
388IBinaryStream::IBinaryStream(const std::vector<char> &buffer)
389 : BinaryStream(buffer)
390{
391}
392
398void IBinaryStream::open(std::size_t size)
399{
400 BinaryStream::open(size);
401}
402
410void IBinaryStream::open(const char *buffer, std::size_t size)
411{
412 BinaryStream::open(buffer, size);
413}
414
422void IBinaryStream::read(char *data, std::size_t size)
423{
424 if ((m_pos + size) > getSize()) {
425 throw std::runtime_error("Bad memory access!");
426 }
427
428 std::memcpy(data, m_buffer.data() + m_pos, size);
429 m_pos += size;
430}
431
445 : BinaryStream(), m_expandable(true)
446{
447}
448
459 : BinaryStream(size), m_expandable(size == 0)
460{
461}
462
472void OBinaryStream::open(std::size_t size)
473{
474 // Set the stream expandable to allow changing its size
475 m_expandable = true;
476
477 // Open a stream with the desidered size
478 BinaryStream::open(size);
479
480 // Set the definitive expandable flag
481 m_expandable = (size == 0);
482}
483
491void OBinaryStream::setSize(std::size_t size)
492{
493 if (!m_expandable) {
494 throw std::runtime_error("Stream is not expandable.");
495 }
496
498}
499
505{
506 bool expandableFlag = m_expandable;
507
508 // Set the stream expandable to allow changing its size
509 m_expandable = true;
510
511 // Update the size of the stream
512 setSize(tellg());
513
514 // Set the expandable flag back to its initial value
515 m_expandable = expandableFlag;
516}
517
525void OBinaryStream::write(const char *data, std::size_t size)
526{
527 if (getSize() - m_pos < size) {
528 // If the stream is not expandable, the request for a new size
529 // will throw an exception.
530 std::size_t bufferSize = getSize() + size;
531 setSize(bufferSize);
532 }
533
534 std::memcpy(m_buffer.data() + m_pos, data, size);
535 m_pos += size;
536}
537
538}
Base class for defining input and output binary streams.
std::streampos tellg() const
std::size_t getCapacity() const
void open(const char *buffer, std::size_t capacity)
bool seekg(std::size_t pos)
void setCapacity(std::size_t capacity)
virtual void setSize(std::size_t size)
std::size_t getSize() const
Output binary stream.
void read(char *data, std::size_t size)
void open(const char *buffer, std::size_t size)
Output binary stream.
void write(const char *data, std::size_t size)
void open(std::size_t size)
void setSize(std::size_t size) override
Logger & operator<<(Logger &logger, LoggerManipulator< T > &&m)
Definition logger.hpp:367
--- layout: doxygen_footer ---