Strict C++ compliance.
[asdcplib.git] / src / KM_memio.h
1 /*
2 Copyright (c) 2006-2008, 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 byte_t* CurrentData() { return m_p + m_size; }
65       inline ui32_t  Length() { return m_size; }
66       inline ui32_t  Remainder() { return m_capacity - m_size; }
67
68       inline bool AddOffset(ui32_t offset) {
69         if ( ( m_size + offset ) > m_capacity )
70           return false;
71
72         m_size += offset;
73         return true;
74
75       }
76
77       inline bool WriteRaw(const byte_t* p, ui32_t buf_len) {
78         if ( ( m_size + buf_len ) > m_capacity )
79           return false;
80
81         memcpy(m_p + m_size, p, buf_len);
82         m_size += buf_len;
83         return true;
84       }
85
86       bool WriteBER(ui64_t i, ui32_t ber_len);
87
88       inline bool WriteUi8(ui8_t i) {
89         if ( ( m_size + 1 ) > m_capacity )
90           return false;
91
92         *(m_p + m_size) = i;
93         m_size++;
94         return true;
95       }
96
97       inline bool WriteUi16BE(ui16_t i) {
98         if ( ( m_size + sizeof(ui16_t) ) > m_capacity )
99           return false;
100         
101         i2p<ui16_t>(KM_i16_BE(i), m_p + m_size);
102         m_size += sizeof(ui16_t);
103         return true;
104       }
105
106       inline bool WriteUi32BE(ui32_t i) {
107         if ( ( m_size + sizeof(ui32_t) ) > m_capacity )
108           return false;
109         
110         i2p<ui32_t>(KM_i32_BE(i), m_p + m_size);
111         m_size += sizeof(ui32_t);
112         return true;
113       }
114
115       inline bool WriteUi64BE(ui64_t i) {
116         if ( ( m_size + sizeof(ui64_t) ) > m_capacity )
117           return false;
118         
119         i2p<ui64_t>(KM_i64_BE(i), m_p + m_size);
120         m_size += sizeof(ui64_t);
121         return true;
122       }
123     };
124
125   //
126   class MemIOReader
127     {
128       KM_NO_COPY_CONSTRUCT(MemIOReader);
129       MemIOReader();
130       
131     protected:
132       const byte_t* m_p;
133       ui32_t  m_capacity;
134       ui32_t  m_size; // this is sort of a misnomer, when we are reading it measures offset
135
136     public:
137       MemIOReader(const byte_t* p, ui32_t c) :
138         m_p(p), m_capacity(c), m_size(0) {
139         assert(m_p); assert(m_capacity);
140       }
141
142       MemIOReader(const ByteString* Buf);
143       ~MemIOReader() {}
144
145       inline void          Reset() { m_size = 0; }
146       inline const byte_t* Data() { return m_p; }
147       inline const byte_t* CurrentData() { return m_p + m_size; }
148       inline ui32_t        Offset() { return m_size; }
149       inline ui32_t        Remainder() { return m_capacity - m_size; }
150
151       inline bool SkipOffset(ui32_t offset) {
152         if ( ( m_size + offset ) > m_capacity )
153           return false;
154
155         m_size += offset;
156         return true;
157       }
158
159       inline bool ReadRaw(byte_t* p, ui32_t buf_len) {
160         if ( ( m_size + buf_len ) > m_capacity )
161           return false;
162
163         memcpy(p, m_p + m_size, buf_len);
164         m_size += buf_len;
165         return true;
166       }
167
168       bool ReadBER(ui64_t* i, ui32_t* ber_len);
169
170       inline bool ReadUi8(ui8_t* i) {
171         assert(i);
172         if ( ( m_size + 1 ) > m_capacity )
173           return false;
174
175         *i = *(m_p + m_size);
176         m_size++;
177         return true;
178       }
179
180       inline bool ReadUi16BE(ui16_t* i) {
181         assert(i);
182         if ( ( m_size + sizeof(ui16_t) ) > m_capacity )
183           return false;
184
185         *i = KM_i16_BE(cp2i<ui16_t>(m_p + m_size));
186         m_size += sizeof(ui16_t);
187         return true;
188       }
189
190       inline bool ReadUi32BE(ui32_t* i) {
191         assert(i);
192         if ( ( m_size + sizeof(ui32_t) ) > m_capacity )
193           return false;
194
195         *i = KM_i32_BE(cp2i<ui32_t>(m_p + m_size));
196         m_size += sizeof(ui32_t);
197         return true;
198       }
199
200       inline bool ReadUi64BE(ui64_t* i) {
201         assert(i);
202         if ( ( m_size + sizeof(ui64_t) ) > m_capacity )
203           return false;
204
205         *i = KM_i64_BE(cp2i<ui64_t>(m_p + m_size));
206         m_size += sizeof(ui64_t);
207         return true;
208       }
209     };
210
211   //
212   inline bool
213     UnarchiveString(MemIOReader& Reader, std::string& str)
214     {
215       ui32_t str_length;
216       if ( ! Reader.ReadUi32BE(&str_length) ) return false;
217       str.assign((const char*)Reader.CurrentData(), str_length);
218       if ( ! Reader.SkipOffset(str_length) ) return false;
219       return true;
220     }
221
222   //
223   inline bool
224     ArchiveString(MemIOWriter& Writer, const std::string& str)
225     {
226       if ( ! Writer.WriteUi32BE(str.length()) ) return false;
227       if ( ! Writer.WriteRaw((const byte_t*)str.c_str(), str.length()) ) return false;
228       return true;
229     }
230
231 } // namespace Kumu
232
233 #endif // _KM_MEMIO_H_
234
235 //
236 // end KM_memio.h
237 //