metadata reformed...
[asdcplib.git] / MemIO.h
1 /*
2 Copyright (c) 2005, 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    MemIO.h
28     \version $Id$
29     \brief   Interface for reading and writing typed objects to a byte-oriented buffer
30 */
31
32 #ifndef _MEMIO_H_
33 #define _MEMIO_H_
34
35 #include <AS_DCP_system.h>
36 #include <hex_utils.h>
37
38 namespace ASDCP
39 {
40   //
41   class MemIOWriter
42     {
43       ASDCP_NO_COPY_CONSTRUCT(MemIOWriter);
44       MemIOWriter();
45       
46     protected:
47       byte_t* m_p;
48       ui32_t  m_capacity;
49       ui32_t  m_size;
50
51     public:
52       MemIOWriter(byte_t* p, ui32_t c) :
53         m_p(p), m_capacity(c), m_size(0) {
54         assert(m_p);
55       }
56
57       ~MemIOWriter() {}
58
59       inline byte_t* Data() { return m_p; }
60       inline byte_t* CurrentData() { return m_p + m_size; }
61       inline ui32_t Size() { return m_size; }
62       inline ui32_t Remainder() { return m_capacity - m_size; }
63
64       inline Result_t AddOffset(ui32_t offset) {
65         if ( ( m_size + offset ) > m_capacity )
66           return RESULT_FAIL;
67
68         m_size += offset;
69         return RESULT_OK;
70
71       }
72
73       inline Result_t WriteRaw(const byte_t* p, ui32_t buf_len) {
74         if ( ( m_size + buf_len ) > m_capacity )
75           return RESULT_FAIL;
76
77         memcpy(m_p + m_size, p, buf_len);
78         m_size += buf_len;
79         return RESULT_OK;
80       }
81
82       inline Result_t WriteBER(ui64_t i, ui32_t ber_len) {
83         if ( ( m_size + ber_len ) > m_capacity )
84           return RESULT_FAIL;
85
86         if ( ! write_BER(m_p + m_size, i, ber_len) )
87           return RESULT_FAIL;
88
89         m_size += ber_len;
90         return RESULT_OK;
91       }
92
93       inline Result_t WriteUi8(ui8_t i) {
94         if ( ( m_size + 1 ) > m_capacity )
95           return RESULT_FAIL;
96
97         *(m_p + m_size) = i;
98         m_size++;
99         return RESULT_OK;
100       }
101
102       inline Result_t WriteUi16BE(ui16_t i) {
103         if ( ( m_size + sizeof(ui16_t) ) > m_capacity )
104           return RESULT_FAIL;
105         
106         i2p<ui16_t>(ASDCP_i16_BE(i), m_p + m_size);
107         m_size += sizeof(ui16_t);
108         return RESULT_OK;
109       }
110
111       inline Result_t WriteUi32BE(ui32_t i) {
112         if ( ( m_size + sizeof(ui32_t) ) > m_capacity )
113           return RESULT_FAIL;
114         
115         i2p<ui32_t>(ASDCP_i32_BE(i), m_p + m_size);
116         m_size += sizeof(ui32_t);
117         return RESULT_OK;
118       }
119
120       inline Result_t WriteUi64BE(ui64_t i) {
121         if ( ( m_size + sizeof(ui64_t) ) > m_capacity )
122           return RESULT_FAIL;
123         
124         i2p<ui64_t>(ASDCP_i64_BE(i), m_p + m_size);
125         m_size += sizeof(ui64_t);
126         return RESULT_OK;
127       }
128     };
129
130   //
131   class MemIOReader
132     {
133       ASDCP_NO_COPY_CONSTRUCT(MemIOReader);
134       MemIOReader();
135       
136     protected:
137       const byte_t* m_p;
138       ui32_t  m_capacity;
139       ui32_t  m_size; // this is sort of a misnomer, when we are reading it measures offset
140
141     public:
142       MemIOReader(const byte_t* p, ui32_t c) :
143         m_p(p), m_capacity(c), m_size(0) {
144         assert(m_p);
145       }
146
147       ~MemIOReader() {}
148
149       inline const byte_t* Data() { return m_p; }
150       inline const byte_t* CurrentData() { return m_p + m_size; }
151       inline ui32_t Offset() { return m_size; }
152       inline ui32_t Remainder() { return m_capacity - m_size; }
153
154       inline Result_t SkipOffset(ui32_t offset) {
155         if ( ( m_size + offset ) > m_capacity )
156           return RESULT_FAIL;
157
158         m_size += offset;
159         return RESULT_OK;
160       }
161
162       inline Result_t ReadRaw(byte_t* p, ui32_t buf_len) {
163         if ( ( m_size + buf_len ) > m_capacity )
164           return RESULT_FAIL;
165
166         memcpy(p, m_p + m_size, buf_len);
167         m_size += buf_len;
168         return RESULT_OK;
169       }
170
171       Result_t ReadBER(ui64_t* i, ui32_t* ber_len) {
172         ASDCP_TEST_NULL(i);
173         ASDCP_TEST_NULL(ber_len);
174
175         if ( ( *ber_len = BER_length(m_p + m_size) ) == 0 )
176           return RESULT_FAIL;
177
178         if ( ( m_size + *ber_len ) > m_capacity )
179           return RESULT_FAIL;
180
181         if ( ! read_BER(m_p + m_size, i) )
182           return RESULT_FAIL;
183
184         m_size += *ber_len;
185         return RESULT_OK;
186       }
187
188       inline Result_t ReadUi8(ui8_t* i) {
189         ASDCP_TEST_NULL(i);
190         if ( ( m_size + 1 ) > m_capacity )
191           return RESULT_FAIL;
192
193         *i = *(m_p + m_size);
194         m_size++;
195         return RESULT_OK;
196       }
197
198       inline Result_t ReadUi16BE(ui16_t* i) {
199         ASDCP_TEST_NULL(i);
200         if ( ( m_size + sizeof(ui16_t) ) > m_capacity )
201           return RESULT_FAIL;
202
203         *i = ASDCP_i16_BE(cp2i<ui16_t>(m_p + m_size));
204         m_size += sizeof(ui16_t);
205         return RESULT_OK;
206       }
207
208       inline Result_t ReadUi32BE(ui32_t* i) {
209         ASDCP_TEST_NULL(i);
210         if ( ( m_size + sizeof(ui32_t) ) > m_capacity )
211           return RESULT_FAIL;
212
213         *i = ASDCP_i32_BE(cp2i<ui32_t>(m_p + m_size));
214         m_size += sizeof(ui32_t);
215         return RESULT_OK;
216       }
217
218       inline Result_t ReadUi64BE(ui64_t* i) {
219         ASDCP_TEST_NULL(i);
220         if ( ( m_size + sizeof(ui64_t) ) > m_capacity )
221           return RESULT_FAIL;
222
223         *i = ASDCP_i64_BE(cp2i<ui64_t>(m_p + m_size));
224         m_size += sizeof(ui64_t);
225         return RESULT_OK;
226       }
227     };
228
229
230 } // namespace ASDCP
231
232 #endif // _MEMIO_H_
233
234 //
235 // end MemIO.h
236 //