const, baby
[asdcplib.git] / src / KM_memio.h
1 /*
2 Copyright (c) 2006-2009, John Hurst
3 All rights reserved.
4
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions
7 are met:
8 1. Redistributions of source code must retain the above copyright
9    notice, this list of conditions and the following disclaimer.
10 2. Redistributions in binary form must reproduce the above copyright
11    notice, this list of conditions and the following disclaimer in the
12    documentation and/or other materials provided with the distribution.
13 3. The name of the author may not be used to endorse or promote products
14    derived from this software without specific prior written permission.
15
16 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27   /*! \file  KM_memio.h
28     \version $Id$
29     \brief   abstraction for byte-oriented conversion of integers and objects
30   */
31
32 #ifndef _KM_MEMIO_H_
33 #define _KM_MEMIO_H_
34
35 #include <KM_platform.h>
36 #include <string>
37 #include <cstring>
38
39 namespace Kumu
40 {
41   class ByteString;
42
43   //
44   class MemIOWriter
45     {
46       KM_NO_COPY_CONSTRUCT(MemIOWriter);
47       MemIOWriter();
48       
49     protected:
50       byte_t* m_p;
51       ui32_t  m_capacity;
52       ui32_t  m_size;
53
54     public:
55       MemIOWriter(byte_t* p, ui32_t c) : m_p(p), m_capacity(c), m_size(0) {
56         assert(m_p); assert(m_capacity);
57       }
58
59       MemIOWriter(ByteString* Buf);
60       ~MemIOWriter() {}
61
62       inline void    Reset() { m_size = 0; }
63       inline byte_t* Data() { return m_p; }
64       inline const byte_t* RoData() const { return m_p; }
65       inline byte_t* CurrentData() { return m_p + m_size; }
66       inline ui32_t  Length() const { return m_size; }
67       inline ui32_t  Remainder() const { return m_capacity - m_size; }
68
69       inline bool AddOffset(ui32_t offset) {
70         if ( ( m_size + offset ) > m_capacity )
71           return false;
72
73         m_size += offset;
74         return true;
75
76       }
77
78       inline bool WriteRaw(const byte_t* p, ui32_t buf_len) {
79         if ( ( m_size + buf_len ) > m_capacity )
80           return false;
81
82         memcpy(m_p + m_size, p, buf_len);
83         m_size += buf_len;
84         return true;
85       }
86
87       bool WriteBER(ui64_t i, ui32_t ber_len);
88
89       inline bool WriteUi8(ui8_t i) {
90         if ( ( m_size + 1 ) > m_capacity )
91           return false;
92
93         *(m_p + m_size) = i;
94         m_size++;
95         return true;
96       }
97
98       inline bool WriteUi16BE(ui16_t i) {
99         if ( ( m_size + sizeof(ui16_t) ) > m_capacity )
100           return false;
101         
102         i2p<ui16_t>(KM_i16_BE(i), m_p + m_size);
103         m_size += sizeof(ui16_t);
104         return true;
105       }
106
107       inline bool WriteUi32BE(ui32_t i) {
108         if ( ( m_size + sizeof(ui32_t) ) > m_capacity )
109           return false;
110         
111         i2p<ui32_t>(KM_i32_BE(i), m_p + m_size);
112         m_size += sizeof(ui32_t);
113         return true;
114       }
115
116       inline bool WriteUi64BE(ui64_t i) {
117         if ( ( m_size + sizeof(ui64_t) ) > m_capacity )
118           return false;
119         
120         i2p<ui64_t>(KM_i64_BE(i), m_p + m_size);
121         m_size += sizeof(ui64_t);
122         return true;
123       }
124     };
125
126   //
127   class MemIOReader
128     {
129       KM_NO_COPY_CONSTRUCT(MemIOReader);
130       MemIOReader();
131       
132     protected:
133       const byte_t* m_p;
134       ui32_t  m_capacity;
135       ui32_t  m_size; // this is sort of a misnomer, when we are reading it measures offset
136
137     public:
138       MemIOReader(const byte_t* p, ui32_t c) :
139         m_p(p), m_capacity(c), m_size(0) {
140         assert(m_p); assert(m_capacity);
141       }
142
143       MemIOReader(const ByteString* Buf);
144       ~MemIOReader() {}
145
146       inline void          Reset() { m_size = 0; }
147       inline const byte_t* Data() const { return m_p; }
148       inline const byte_t* CurrentData() const { return m_p + m_size; }
149       inline ui32_t        Offset() const { return m_size; }
150       inline ui32_t        Remainder() const { return m_capacity - m_size; }
151
152       inline bool SkipOffset(ui32_t offset) {
153         if ( ( m_size + offset ) > m_capacity )
154           return false;
155
156         m_size += offset;
157         return true;
158       }
159
160       inline bool ReadRaw(byte_t* p, ui32_t buf_len) {
161         if ( ( m_size + buf_len ) > m_capacity )
162           return false;
163
164         memcpy(p, m_p + m_size, buf_len);
165         m_size += buf_len;
166         return true;
167       }
168
169       bool ReadBER(ui64_t* i, ui32_t* ber_len);
170
171       inline bool ReadUi8(ui8_t* i) {
172         assert(i);
173         if ( ( m_size + 1 ) > m_capacity )
174           return false;
175
176         *i = *(m_p + m_size);
177         m_size++;
178         return true;
179       }
180
181       inline bool ReadUi16BE(ui16_t* i) {
182         assert(i);
183         if ( ( m_size + sizeof(ui16_t) ) > m_capacity )
184           return false;
185
186         *i = KM_i16_BE(cp2i<ui16_t>(m_p + m_size));
187         m_size += sizeof(ui16_t);
188         return true;
189       }
190
191       inline bool ReadUi32BE(ui32_t* i) {
192         assert(i);
193         if ( ( m_size + sizeof(ui32_t) ) > m_capacity )
194           return false;
195
196         *i = KM_i32_BE(cp2i<ui32_t>(m_p + m_size));
197         m_size += sizeof(ui32_t);
198         return true;
199       }
200
201       inline bool ReadUi64BE(ui64_t* i) {
202         assert(i);
203         if ( ( m_size + sizeof(ui64_t) ) > m_capacity )
204           return false;
205
206         *i = KM_i64_BE(cp2i<ui64_t>(m_p + m_size));
207         m_size += sizeof(ui64_t);
208         return true;
209       }
210     };
211
212   //
213   inline bool
214     UnarchiveString(MemIOReader& Reader, std::string& str)
215     {
216       ui32_t str_length;
217       if ( ! Reader.ReadUi32BE(&str_length) ) return false;
218       str.assign((const char*)Reader.CurrentData(), str_length);
219       if ( ! Reader.SkipOffset(str_length) ) return false;
220       return true;
221     }
222
223   //
224   inline bool
225     ArchiveString(MemIOWriter& Writer, const std::string& str)
226     {
227       if ( ! Writer.WriteUi32BE(str.length()) ) return false;
228       if ( ! Writer.WriteRaw((const byte_t*)str.c_str(), str.length()) ) return false;
229       return true;
230     }
231
232 } // namespace Kumu
233
234 #endif // _KM_MEMIO_H_
235
236 //
237 // end KM_memio.h
238 //