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