Line data Source code
1 : /*
2 : * Copyright (c) 2009-2015: G-CSC, Goethe University Frankfurt
3 : * Author: Sebastian Reiter
4 : *
5 : * This file is part of UG4.
6 : *
7 : * UG4 is free software: you can redistribute it and/or modify it under the
8 : * terms of the GNU Lesser General Public License version 3 (as published by the
9 : * Free Software Foundation) with the following additional attribution
10 : * requirements (according to LGPL/GPL v3 §7):
11 : *
12 : * (1) The following notice must be displayed in the Appropriate Legal Notices
13 : * of covered and combined works: "Based on UG4 (www.ug4.org/license)".
14 : *
15 : * (2) The following notice must be displayed at a prominent place in the
16 : * terminal output of covered works: "Based on UG4 (www.ug4.org/license)".
17 : *
18 : * (3) The following bibliography is recommended for citation and must be
19 : * preserved in all covered files:
20 : * "Reiter, S., Vogel, A., Heppner, I., Rupp, M., and Wittum, G. A massively
21 : * parallel geometric multigrid solver on hierarchically distributed grids.
22 : * Computing and visualization in science 16, 4 (2013), 151-164"
23 : * "Vogel, A., Reiter, S., Rupp, M., Nägel, A., and Wittum, G. UG4 -- a novel
24 : * flexible software system for simulating pde based models on high performance
25 : * computers. Computing and visualization in science 16, 4 (2013), 165-179"
26 : *
27 : * This program is distributed in the hope that it will be useful,
28 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
29 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30 : * GNU Lesser General Public License for more details.
31 : */
32 :
33 : #ifndef __H__UTIL__BINARY_STREAM__
34 : #define __H__UTIL__BINARY_STREAM__
35 :
36 : #include <iostream>
37 : #include <vector>
38 : #include "vector_util.h"
39 :
40 : namespace ug
41 : {
42 :
43 : /// \addtogroup ugbase_common_io
44 : /// \{
45 :
46 : ////////////////////////////////////////////////////////////////////////
47 : /// A special version of a std::streambuf, writes data directly into a buffer that is accessible at any time.
48 : /** This buffer stores the data directly in a growing array.
49 : * You may receive a pointer to that array using get_buffer().
50 : * The size of the buffer is returned by get_buffer_size().
51 : *
52 : * Note that the pointer returned from get_buffer may be invalidated
53 : * after new insertions into the buffer.
54 : * Using resize() you may reserve a buffer-section. Input- and output-positions
55 : * won't be affected by a resize.
56 : */
57 : class BinaryStreamBuffer : public std::streambuf
58 : {
59 : public:
60 : BinaryStreamBuffer();
61 :
62 : /// clears the data and resets the read and write positions.
63 : void clear();
64 :
65 : /// Similar to resize, however, doesn't alter the read-area.
66 : void reserve(size_t newSize);
67 :
68 : /// resizes the data-buffer but does not alter read and write positions.
69 : /** A resize extends the readable area.*/
70 : void resize(size_t newSize);
71 :
72 : /// set read- and write-positions to the start of the buffer.
73 : void reset();
74 :
75 : /// returns a pointer to the front of the buffer or NULL if the buffer is empty.
76 : inline char_type* buffer() {return reinterpret_cast<char_type*>(GetDataPtr(m_dataBuf));}
77 :
78 : inline const char_type* buffer() const {return reinterpret_cast<const char_type*>(GetDataPtr(m_dataBuf));}
79 :
80 : /// returns the size of the buffer in bytes.
81 : size_t size() const;
82 :
83 : /// advances the write-pointer by jumpSize bytes
84 : void write_jump(size_t jumpSize);
85 :
86 : /// advances the read-pointer by jumpSize bytes
87 : void read_jump(size_t jumpSize);
88 :
89 : /// returns the read-position
90 : size_t get_read_pos() const;
91 :
92 : // implementation of virtual std::streambuf methods.
93 : virtual int_type overflow(int_type c = traits_type::eof());
94 :
95 : virtual int_type underflow();
96 :
97 : protected:
98 : /// returns pointer to the first entry behind the buffer.
99 0 : inline char_type* end() {return buffer() + m_dataBuf.size();}
100 : inline const char_type* end() const {return buffer() + m_dataBuf.size();}
101 :
102 : protected:
103 : std::vector<unsigned char> m_dataBuf;
104 : };
105 :
106 : ////////////////////////////////////////////////////////////////////////
107 : /// a specialzation of std::iostream, that uses a \sa BinaryStreamBuffer as buffer.
108 : class BinaryStream : public std::iostream
109 : {
110 : public:
111 : BinaryStream() : std::iostream(&m_streamBuf) {}
112 : BinaryStream(size_t newSize) : std::iostream(&m_streamBuf) {resize(newSize);}
113 :
114 : inline void clear() //< clears the data and resets the read and write positions.
115 : {m_streamBuf.clear();}
116 :
117 : inline void resize(size_t newSize) //< resizes the data-buffer but does not alter read and write positions.
118 : {m_streamBuf.resize(newSize);}
119 :
120 : inline void reset() //< set read- and write-positions to the start of the buffer.
121 : {m_streamBuf.reset();}
122 :
123 : inline void* buffer() //< returns a pointer to the front of the buffer.
124 : {return m_streamBuf.buffer();}
125 :
126 : inline size_t size() const//< returns the size of the buffer in bytes.
127 : {return m_streamBuf.size();}
128 :
129 : inline void write_jump(size_t jumpSize) //< advances the write-pointer by jumpSize bytes
130 : {m_streamBuf.write_jump(jumpSize);}
131 :
132 : inline void read_jump(size_t jumpSize) //< advances the read-pointer by jumpSize bytes
133 : {m_streamBuf.read_jump(jumpSize);}
134 :
135 : inline size_t read_pos() const
136 : {return m_streamBuf.get_read_pos();}
137 :
138 : /// returns true if there is more data left to read.
139 : /** \todo this method should be removed. The normal stream-methdos should be used
140 : * instead (eof,...). However - those do not seem to work properly in the moment.
141 : */
142 : inline bool can_read_more()
143 : {return m_streamBuf.get_read_pos() < size();}
144 : protected:
145 : BinaryStreamBuffer m_streamBuf;
146 : };
147 :
148 : // end group ugbase_common_io
149 : /// \}
150 :
151 : }// end of namespace
152 :
153 : #endif
|