more optional stuff
[asdcplib.git] / src / MXFTypes.h
1 /*
2 Copyright (c) 2005-2012, 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) m_Dict->Type(MDD_##s##_##l), &l
45 #define OBJ_WRITE_ARGS(s,l) m_Dict->Type(MDD_##s##_##l), &l
46 #define OBJ_READ_ARGS_OPT(s,l) m_Dict->Type(MDD_##s##_##l), &l.get()
47 #define OBJ_WRITE_ARGS_OPT(s,l) m_Dict->Type(MDD_##s##_##l), &l.get()
48 #define OBJ_TYPE_ARGS(t) m_Dict->Type(MDD_##t).ul
49
50
51 namespace ASDCP
52 {
53   namespace MXF
54     {
55       typedef std::pair<ui32_t, ui32_t> ItemInfo;
56       typedef std::map<TagValue, ItemInfo> TagMap;
57
58       //      
59       class TLVReader : public Kumu::MemIOReader
60         {
61
62           TagMap         m_ElementMap;
63           IPrimerLookup* m_Lookup;
64
65           TLVReader();
66           ASDCP_NO_COPY_CONSTRUCT(TLVReader);
67           bool FindTL(const MDDEntry&);
68
69         public:
70           TLVReader(const byte_t* p, ui32_t c, IPrimerLookup* = 0);
71           Result_t ReadObject(const MDDEntry&, Kumu::IArchive*);
72           Result_t ReadUi8(const MDDEntry&, ui8_t*);
73           Result_t ReadUi16(const MDDEntry&, ui16_t*);
74           Result_t ReadUi32(const MDDEntry&, ui32_t*);
75           Result_t ReadUi64(const MDDEntry&, ui64_t*);
76         };
77
78       //      
79       class TLVWriter : public Kumu::MemIOWriter
80         {
81
82           TagMap         m_ElementMap;
83           IPrimerLookup* m_Lookup;
84
85           TLVWriter();
86           ASDCP_NO_COPY_CONSTRUCT(TLVWriter);
87           Result_t WriteTag(const MDDEntry&);
88
89         public:
90           TLVWriter(byte_t* p, ui32_t c, IPrimerLookup* = 0);
91           Result_t WriteObject(const MDDEntry&, Kumu::IArchive*);
92           Result_t WriteUi8(const MDDEntry&, ui8_t*);
93           Result_t WriteUi16(const MDDEntry&, ui16_t*);
94           Result_t WriteUi32(const MDDEntry&, ui32_t*);
95           Result_t WriteUi64(const MDDEntry&, ui64_t*);
96         };
97
98       //
99       template <class T>
100         class Batch : public std::vector<T>, public Kumu::IArchive
101         {
102         public:
103           Batch() {}
104           virtual ~Batch() {}
105
106           //
107           virtual bool Unarchive(Kumu::MemIOReader* Reader) {
108             ui32_t ItemCount, ItemSize;
109             if ( ! Reader->ReadUi32BE(&ItemCount) ) return false;
110             if ( ! Reader->ReadUi32BE(&ItemSize) ) return false;
111
112             if ( ( ItemCount > 65536 ) || ( ItemSize > 1024 ) )
113               return false;
114
115             bool result = true;
116             for ( ui32_t i = 0; i < ItemCount && result; i++ )
117               {
118                 T Tmp;
119                 result = Tmp.Unarchive(Reader);
120
121                 if ( result )
122                   this->push_back(Tmp);
123               }
124
125             return result;
126           }
127
128           inline virtual bool HasValue() const { return ! this->empty(); }
129
130           virtual ui32_t ArchiveLength() const {
131             ui32_t arch_size = sizeof(ui32_t)*2;
132
133             typename std::vector<T>::const_iterator l_i = this->begin();
134             assert(l_i != this->end());
135
136             for ( ; l_i != this->end(); l_i++ )
137               arch_size += l_i->ArchiveLength();
138             
139             return arch_size;
140           }
141
142           //
143           virtual bool Archive(Kumu::MemIOWriter* Writer) const {
144             if ( ! Writer->WriteUi32BE(this->size()) ) return false;
145             byte_t* p = Writer->CurrentData();
146
147             if ( ! Writer->WriteUi32BE(0) ) return false;
148             if ( this->empty() ) return true;
149             
150             typename std::vector<T>::const_iterator l_i = this->begin();
151             assert(l_i != this->end());
152
153             ui32_t ItemSize = Writer->Remainder();
154             if ( ! (*l_i).Archive(Writer) ) return false;
155             ItemSize -= Writer->Remainder();
156             Kumu::i2p<ui32_t>(KM_i32_BE(ItemSize), p);
157             l_i++;
158
159             bool result = true;
160             for ( ; l_i != this->end() && result; l_i++ )
161               result = (*l_i).Archive(Writer);
162
163             return result;
164           }
165
166           //
167           void Dump(FILE* stream = 0, ui32_t depth = 0)
168             {
169               char identbuf[IdentBufferLen];
170
171               if ( stream == 0 )
172                 stream = stderr;
173
174               typename std::vector<T>::iterator i = this->begin();
175               for ( ; i != this->end(); i++ )
176                 fprintf(stream, "  %s\n", (*i).EncodeString(identbuf, IdentBufferLen));
177             }
178         };
179
180       //
181       template <class T>
182         class Array : public std::list<T>, public Kumu::IArchive
183         {
184         public:
185           Array() {}
186           virtual ~Array() {}
187
188           //
189           virtual bool Unarchive(Kumu::MemIOReader* Reader)
190             {
191               bool result = true;
192
193               while ( Reader->Remainder() > 0 && result )
194                 {
195                   T Tmp;
196                   result = Tmp.Unarchive(Reader);
197                   this->push_back(Tmp);
198                 }
199
200               return result;
201             }
202
203           inline virtual bool HasValue() const { return ! this->empty(); }
204
205           virtual ui32_t ArchiveLength() const {
206             ui32_t arch_size = 0;
207
208             typename std::list<T>::const_iterator l_i = this->begin();
209
210             for ( ; l_i != this->end(); l_i++ )
211               arch_size += l_i->ArchiveLength();
212             
213             return arch_size;
214           }
215
216           //
217           virtual bool Archive(Kumu::MemIOWriter* Writer) const {
218             bool result = true;
219             typename std::list<T>::const_iterator l_i = this->begin();
220
221             for ( ; l_i != this->end() && result; l_i++ )
222               result = (*l_i).Archive(Writer);
223
224             return result;
225           }
226
227           //
228           void Dump(FILE* stream = 0, ui32_t depth = 0)
229             {
230               char identbuf[IdentBufferLen];
231
232               if ( stream == 0 )
233                 stream = stderr;
234
235               typename std::list<T>::iterator i = this->begin();
236               for ( ; i != this->end(); i++ )
237                 fprintf(stream, "  %s\n", (*i).EncodeString(identbuf, IdentBufferLen));
238             }
239         };
240
241       //
242     class ISO8String : public std::string, public Kumu::IArchive
243         {
244         public:
245           ISO8String() {}
246           ISO8String(const char*);
247           ISO8String(const std::string&);
248           ~ISO8String() {}
249
250           const ISO8String& operator=(const char*);
251           const ISO8String& operator=(const std::string&);
252
253           const char* EncodeString(char* str_buf, ui32_t buf_len) const;
254           inline virtual bool HasValue() const { return ! empty(); }
255           inline virtual ui32_t ArchiveLength() const { return sizeof(ui32_t) + size(); }
256           virtual bool Unarchive(Kumu::MemIOReader* Reader);
257           virtual bool Archive(Kumu::MemIOWriter* Writer) const;
258         };
259
260       //
261     class UTF16String : public std::string, public Kumu::IArchive
262         {
263         public:
264           UTF16String() {}
265           UTF16String(const char*);
266           UTF16String(const std::string&);
267           ~UTF16String() {}
268
269           const UTF16String& operator=(const char*);
270           const UTF16String& operator=(const std::string&);
271
272           const char* EncodeString(char* str_buf, ui32_t buf_len) const;
273           inline virtual bool HasValue() const { return ! empty(); }
274           inline virtual ui32_t ArchiveLength() const { return sizeof(ui32_t) + size(); }
275           virtual bool Unarchive(Kumu::MemIOReader* Reader);
276           virtual bool Archive(Kumu::MemIOWriter* Writer) const;
277         };
278
279       //
280       class Rational : public ASDCP::Rational, public Kumu::IArchive
281         {
282         public:
283           Rational() {}
284           ~Rational() {}
285
286           Rational(const Rational& rhs) : ASDCP::Rational(), IArchive() {
287             Numerator = rhs.Numerator;
288             Denominator = rhs.Denominator;
289           }
290
291           const Rational& operator=(const Rational& rhs) {
292             Numerator = rhs.Numerator;
293             Denominator = rhs.Denominator;
294             return *this;
295           }
296
297           Rational(const ASDCP::Rational& rhs) {
298             Numerator = rhs.Numerator;
299             Denominator = rhs.Denominator;
300           }
301
302           const Rational& operator=(const ASDCP::Rational& rhs) {
303             Numerator = rhs.Numerator;
304             Denominator = rhs.Denominator;
305             return *this;
306           }
307
308           //
309           inline const char* EncodeString(char* str_buf, ui32_t buf_len) const {
310             snprintf(str_buf, buf_len, "%d/%d", Numerator, Denominator);
311             return str_buf;
312           }
313
314           inline virtual bool Unarchive(Kumu::MemIOReader* Reader) {
315             if ( ! Reader->ReadUi32BE((ui32_t*)&Numerator) ) return false;
316             if ( ! Reader->ReadUi32BE((ui32_t*)&Denominator) ) return false;
317             return true;
318           }
319
320           inline virtual bool HasValue() const { return true; }
321           inline virtual ui32_t ArchiveLength() const { return sizeof(ui32_t)*2; }
322
323           inline virtual bool Archive(Kumu::MemIOWriter* Writer) const {
324             if ( ! Writer->WriteUi32BE((ui32_t)Numerator) ) return false;
325             if ( ! Writer->WriteUi32BE((ui32_t)Denominator) ) return false;
326             return true;
327           }
328         };
329
330       //
331       class VersionType : public Kumu::IArchive
332         {
333         public:
334           enum Release_t { RL_UNKNOWN, RL_RELEASE, RL_DEVELOPMENT, RL_PATCHED, RL_BETA, RL_PRIVATE, RL_MAX };
335           ui16_t Major;
336           ui16_t Minor;
337           ui16_t Patch;
338           ui16_t Build;
339           Release_t Release;
340
341           VersionType() : Major(0), Minor(0), Patch(0), Build(0), Release(RL_UNKNOWN) {}
342           VersionType(const VersionType& rhs) { Copy(rhs); }
343           virtual ~VersionType() {}
344
345           const VersionType& operator=(const VersionType& rhs) { Copy(rhs); return *this; }
346           void Copy(const VersionType& rhs) {
347             Major = rhs.Major;
348             Minor = rhs.Minor;
349             Patch = rhs.Patch;
350             Build = rhs.Build;
351             Release = rhs.Release;
352           }
353
354           void Dump(FILE* = 0);
355
356           const char* EncodeString(char* str_buf, ui32_t buf_len) const {
357             snprintf(str_buf, buf_len, "%hu.%hu.%hu.%hur%hu", Major, Minor, Patch, Build, Release);
358             return str_buf;
359           }
360
361           virtual bool Unarchive(Kumu::MemIOReader* Reader) {
362             if ( ! Reader->ReadUi16BE(&Major) ) return false;
363             if ( ! Reader->ReadUi16BE(&Minor) ) return false;
364             if ( ! Reader->ReadUi16BE(&Patch) ) return false;
365             if ( ! Reader->ReadUi16BE(&Build) ) return false;
366             ui16_t tmp_release;
367             if ( ! Reader->ReadUi16BE(&tmp_release) ) return false;
368             Release = (Release_t)tmp_release;
369             return true;
370           }
371
372           inline virtual bool HasValue() const { return true; }
373           inline virtual ui32_t ArchiveLength() const { return sizeof(ui16_t)*5; }
374
375           virtual bool Archive(Kumu::MemIOWriter* Writer) const {
376             if ( ! Writer->WriteUi16BE(Major) ) return false;
377             if ( ! Writer->WriteUi16BE(Minor) ) return false;
378             if ( ! Writer->WriteUi16BE(Patch) ) return false;
379             if ( ! Writer->WriteUi16BE(Build) ) return false;
380             if ( ! Writer->WriteUi16BE((ui16_t)(Release & 0x0000ffffL)) ) return false;
381             return true;
382           }
383         };
384
385       //
386       class Raw : public Kumu::ByteString
387         {
388         public:
389           Raw();
390           Raw(const Raw& rhs) { Copy(rhs); }
391           virtual ~Raw();
392
393           const Raw& operator=(const Raw& rhs) { Copy(rhs); return *this; }
394           void Copy(const Raw& rhs) {
395             if ( KM_SUCCESS(Capacity(rhs.Length())) )
396               {
397                 Set(rhs);
398               }
399           }
400
401           //
402           virtual bool Unarchive(Kumu::MemIOReader* Reader);
403           virtual bool Archive(Kumu::MemIOWriter* Writer) const;
404           const char* EncodeString(char* str_buf, ui32_t buf_len) const;
405         };
406
407     } // namespace MXF
408 } // namespace ASDCP
409
410
411 #endif //_MXFTYPES_H_
412
413 //
414 // end MXFTypes.h
415 //