bugfix in indexing
[asdcplib.git] / src / MXFTypes.h
1 /*
2 Copyright (c) 2005-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    MXFTypes.h
28     \version $Id$
29     \brief   MXF objects
30 */
31
32 #ifndef _MXFTYPES_H_
33 #define _MXFTYPES_H_
34
35 #include "KLV.h"
36 #include <list>
37 #include <vector>
38 #include <map>
39 #include <wchar.h>
40
41 // used with TLVReader::Read*
42 //
43 // these are used below to manufacture arguments
44 #define OBJ_READ_ARGS(s,l) s_MDD_Table[MDDindex_##s##_##l], &l
45 #define OBJ_READ_ARGS_R(s,l,r) s_MDD_Table[MDDindex_##s##_##l], &r
46
47 #define OBJ_WRITE_ARGS(s,l) s_MDD_Table[MDDindex_##s##_##l], &l
48
49 #define OBJ_TYPE_ARGS(t) s_MDD_Table[MDDindex_##t].ul
50
51
52 namespace ASDCP
53 {
54   namespace MXF
55     {
56       typedef std::pair<ui32_t, ui32_t> ItemInfo;
57       typedef std::map<TagValue, ItemInfo> TagMap;
58
59       //      
60       class TLVReader : public ASDCP::MemIOReader
61         {
62
63           TagMap         m_ElementMap;
64           IPrimerLookup* m_Lookup;
65
66           TLVReader();
67           ASDCP_NO_COPY_CONSTRUCT(TLVReader);
68           bool FindTL(const MDDEntry&);
69
70         public:
71           TLVReader(const byte_t* p, ui32_t c, IPrimerLookup* = 0);
72           Result_t ReadObject(const MDDEntry&, IArchive*);
73           Result_t ReadUi8(const MDDEntry&, ui8_t*);
74           Result_t ReadUi16(const MDDEntry&, ui16_t*);
75           Result_t ReadUi32(const MDDEntry&, ui32_t*);
76           Result_t ReadUi64(const MDDEntry&, ui64_t*);
77         };
78
79       //      
80       class TLVWriter : public ASDCP::MemIOWriter
81         {
82
83           TagMap         m_ElementMap;
84           IPrimerLookup* m_Lookup;
85
86           TLVWriter();
87           ASDCP_NO_COPY_CONSTRUCT(TLVWriter);
88           Result_t WriteTag(const MDDEntry&);
89
90         public:
91           TLVWriter(byte_t* p, ui32_t c, IPrimerLookup* = 0);
92           Result_t WriteObject(const MDDEntry&, IArchive*);
93           Result_t WriteUi8(const MDDEntry&, ui8_t*);
94           Result_t WriteUi16(const MDDEntry&, ui16_t*);
95           Result_t WriteUi32(const MDDEntry&, ui32_t*);
96           Result_t WriteUi64(const MDDEntry&, ui64_t*);
97         };
98
99       //
100       template <class T>
101         class Batch : public std::vector<T>, public IArchive
102         {
103         public:
104           ui32_t ItemCount;
105           ui32_t ItemSize;
106
107           Batch() : ItemCount(0), ItemSize(0) { ItemSize = sizeof(T); }
108           ~Batch() {}
109
110           //
111           Result_t ReadFrom(ASDCP::MemIOReader& Reader) {
112             Result_t result = Reader.ReadUi32BE(&ItemCount);
113
114             if ( ASDCP_SUCCESS(result) )
115               result = Reader.ReadUi32BE(&ItemSize);
116
117             if ( ( ItemCount > 65536 ) || ( ItemSize > 1024 ) )
118               return RESULT_FAIL;
119
120             for ( ui32_t i = 0; i < ItemCount && ASDCP_SUCCESS(result); i++ )
121               {
122                 T Tmp;
123                 result = Tmp.ReadFrom(Reader);
124
125                 if ( ASDCP_SUCCESS(result) )
126                   push_back(Tmp);
127               }
128
129             return result;
130           }
131
132           //
133           Result_t WriteTo(ASDCP::MemIOWriter& Writer) {
134             Result_t result = Writer.WriteUi32BE(size());
135
136             if ( ASDCP_SUCCESS(result) )
137               result = Writer.WriteUi32BE(ItemSize);
138
139             typename std::vector<T>::iterator l_i = begin();
140             for ( ; l_i != end() && ASDCP_SUCCESS(result); l_i++ )
141               result = (*l_i).WriteTo(Writer);
142
143             return result;
144           }
145
146           //
147           void Dump(FILE* stream = 0, ui32_t depth = 0)
148             {
149               char identbuf[IdentBufferLen];
150
151               if ( stream == 0 )
152                 stream = stderr;
153
154               typename std::vector<T>::iterator i = this->begin();
155               for ( ; i != this->end(); i++ )
156                 fprintf(stream, "  %s\n", (*i).ToString(identbuf));
157             }
158         };
159
160       //
161       template <class T>
162         class Array : public std::list<T>, public IArchive
163         {
164         public:
165           Array() {}
166           ~Array() {}
167
168           //
169           Result_t ReadFrom(ASDCP::MemIOReader& Reader)
170             {
171               while ( Reader.Remainder() > 0 )
172                 {
173                   T Tmp;
174                   Tmp.ReadFrom(Reader);
175                   push_back(Tmp);
176                 }
177
178               return RESULT_OK;
179             }
180
181           //
182           Result_t WriteTo(ASDCP::MemIOWriter& Writer) {
183             Result_t result = RESULT_OK;
184             typename std::list<T>::iterator l_i = begin();
185
186             for ( ; l_i != end() && ASDCP_SUCCESS(result); l_i++ )
187               result = (*l_i).WriteTo(Writer);
188
189             return result;
190           }
191
192           //
193           void Dump(FILE* stream = 0, ui32_t depth = 0)
194             {
195               char identbuf[IdentBufferLen];
196
197               if ( stream == 0 )
198                 stream = stderr;
199
200               typename std::list<T>::iterator i = this->begin();
201               for ( ; i != this->end(); i++ )
202                 fprintf(stream, "  %s\n", (*i).ToString(identbuf));
203             }
204         };
205
206       //
207       class Timestamp : public IArchive
208         {
209         public:
210           ui16_t Year;
211           ui8_t  Month;
212           ui8_t  Day;
213           ui8_t  Hour;
214           ui8_t  Minute;
215           ui8_t  Second;
216           ui8_t  mSec_4;
217
218           Timestamp() :
219             Year(0), Month(0),  Day(0),
220             Hour(0), Minute(0), Second(0), mSec_4(0) {}
221
222           //
223           inline const char* ToString(char* str_buf) const {
224             snprintf(str_buf, IdentBufferLen,
225                      "%04hu-%02hu-%02hu %02hu:%02hu:%02hu.%03hu",
226                      Year, Month, Day, Hour, Minute, Second, mSec_4);
227             return str_buf;
228           }
229
230           //
231           inline Result_t ReadFrom(ASDCP::MemIOReader& Reader) {
232             Result_t result = Reader.ReadUi16BE(&Year);
233
234             if ( ASDCP_SUCCESS(result) )
235               result = Reader.ReadRaw(&Month, 6);
236
237             return result;
238           }
239
240           //
241           inline Result_t WriteTo(ASDCP::MemIOWriter& Writer) {
242             Result_t result = Writer.WriteUi16BE(Year);
243
244             if ( ASDCP_SUCCESS(result) )
245               result = Writer.WriteRaw(&Month, 6);
246
247             return result;
248           }
249         };
250
251       //
252       class UTF16String : public IArchive
253         {
254           ui16_t m_length;
255           char   m_buffer[IdentBufferLen];
256           
257         public:
258           UTF16String() : m_length(0) { *m_buffer = 0; }
259           ~UTF16String() {}
260
261           //
262           const char* ToString(char* str_buf) const {
263             strncpy(str_buf, m_buffer, m_length+1);
264             return str_buf;
265           }
266
267           Result_t ReadFrom(ASDCP::MemIOReader& Reader);
268           Result_t WriteTo(ASDCP::MemIOWriter& Writer);
269         };
270
271       //
272       class Rational : public ASDCP::Rational, public IArchive
273         {
274         public:
275           Rational() {}
276           ~Rational() {}
277
278           //
279           const char* ToString(char* str_buf) const {
280             snprintf(str_buf, IdentBufferLen, "%lu/%lu", Numerator, Denominator);
281             return str_buf;
282           }
283
284           Result_t ReadFrom(ASDCP::MemIOReader& Reader) {
285             Result_t result = Reader.ReadUi32BE((ui32_t*)&Numerator);
286
287             if ( ASDCP_SUCCESS(result) )
288               result = Reader.ReadUi32BE((ui32_t*)&Denominator);
289             
290             return result;
291           }
292
293           Result_t WriteTo(ASDCP::MemIOWriter& Writer) {
294             Result_t result = Writer.WriteUi32BE((ui32_t)Numerator);
295
296             if ( ASDCP_SUCCESS(result) )
297               result = Writer.WriteUi32BE((ui32_t)Denominator);
298             
299             return result;
300           }
301         };
302
303     } // namespace MXF
304 } // namespace ASDCP
305
306
307 #endif //_MXFTYPES_H_
308
309 //
310 // end MXFTypes.h
311 //