optional properties, take 1
[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() {}
247
248           const ISO8String& operator=(const char*);
249           const ISO8String& operator=(const std::string&);
250
251           const char* EncodeString(char* str_buf, ui32_t buf_len) const;
252           inline virtual bool HasValue() const { return ! empty(); }
253           inline virtual ui32_t ArchiveLength() const { return sizeof(ui32_t) + size(); }
254           virtual bool Unarchive(Kumu::MemIOReader* Reader);
255           virtual bool Archive(Kumu::MemIOWriter* Writer) const;
256         };
257
258       //
259     class UTF16String : public std::string, public Kumu::IArchive
260         {
261         public:
262           UTF16String() {}
263           ~UTF16String() {}
264
265           const UTF16String& operator=(const char*);
266           const UTF16String& operator=(const std::string&);
267
268           const char* EncodeString(char* str_buf, ui32_t buf_len) const;
269           inline virtual bool HasValue() const { return ! empty(); }
270           inline virtual ui32_t ArchiveLength() const { return sizeof(ui32_t) + size(); }
271           virtual bool Unarchive(Kumu::MemIOReader* Reader);
272           virtual bool Archive(Kumu::MemIOWriter* Writer) const;
273         };
274
275       //
276       class Rational : public ASDCP::Rational, public Kumu::IArchive
277         {
278         public:
279           Rational() {}
280           ~Rational() {}
281
282           Rational(const Rational& rhs) : ASDCP::Rational(), IArchive() {
283             Numerator = rhs.Numerator;
284             Denominator = rhs.Denominator;
285           }
286
287           const Rational& operator=(const Rational& rhs) {
288             Numerator = rhs.Numerator;
289             Denominator = rhs.Denominator;
290             return *this;
291           }
292
293           Rational(const ASDCP::Rational& rhs) {
294             Numerator = rhs.Numerator;
295             Denominator = rhs.Denominator;
296           }
297
298           const Rational& operator=(const ASDCP::Rational& rhs) {
299             Numerator = rhs.Numerator;
300             Denominator = rhs.Denominator;
301             return *this;
302           }
303
304           //
305           inline const char* EncodeString(char* str_buf, ui32_t buf_len) const {
306             snprintf(str_buf, buf_len, "%d/%d", Numerator, Denominator);
307             return str_buf;
308           }
309
310           inline virtual bool Unarchive(Kumu::MemIOReader* Reader) {
311             if ( ! Reader->ReadUi32BE((ui32_t*)&Numerator) ) return false;
312             if ( ! Reader->ReadUi32BE((ui32_t*)&Denominator) ) return false;
313             return true;
314           }
315
316           inline virtual bool HasValue() const { return true; }
317           inline virtual ui32_t ArchiveLength() const { return sizeof(ui32_t)*2; }
318
319           inline virtual bool Archive(Kumu::MemIOWriter* Writer) const {
320             if ( ! Writer->WriteUi32BE((ui32_t)Numerator) ) return false;
321             if ( ! Writer->WriteUi32BE((ui32_t)Denominator) ) return false;
322             return true;
323           }
324         };
325
326       //
327       class VersionType : public Kumu::IArchive
328         {
329         public:
330           enum Release_t { RL_UNKNOWN, RL_RELEASE, RL_DEVELOPMENT, RL_PATCHED, RL_BETA, RL_PRIVATE, RL_MAX };
331           ui16_t Major;
332           ui16_t Minor;
333           ui16_t Patch;
334           ui16_t Build;
335           Release_t Release;
336
337           VersionType() : Major(0), Minor(0), Patch(0), Build(0), Release(RL_UNKNOWN) {}
338           VersionType(const VersionType& rhs) { Copy(rhs); }
339           virtual ~VersionType() {}
340
341           const VersionType& operator=(const VersionType& rhs) { Copy(rhs); return *this; }
342           void Copy(const VersionType& rhs) {
343             Major = rhs.Major;
344             Minor = rhs.Minor;
345             Patch = rhs.Patch;
346             Build = rhs.Build;
347             Release = rhs.Release;
348           }
349
350           void Dump(FILE* = 0);
351
352           const char* EncodeString(char* str_buf, ui32_t buf_len) const {
353             snprintf(str_buf, buf_len, "%hu.%hu.%hu.%hur%hu", Major, Minor, Patch, Build, Release);
354             return str_buf;
355           }
356
357           virtual bool Unarchive(Kumu::MemIOReader* Reader) {
358             if ( ! Reader->ReadUi16BE(&Major) ) return false;
359             if ( ! Reader->ReadUi16BE(&Minor) ) return false;
360             if ( ! Reader->ReadUi16BE(&Patch) ) return false;
361             if ( ! Reader->ReadUi16BE(&Build) ) return false;
362             ui16_t tmp_release;
363             if ( ! Reader->ReadUi16BE(&tmp_release) ) return false;
364             Release = (Release_t)tmp_release;
365             return true;
366           }
367
368           inline virtual bool HasValue() const { return true; }
369           inline virtual ui32_t ArchiveLength() const { return sizeof(ui16_t)*5; }
370
371           virtual bool Archive(Kumu::MemIOWriter* Writer) const {
372             if ( ! Writer->WriteUi16BE(Major) ) return false;
373             if ( ! Writer->WriteUi16BE(Minor) ) return false;
374             if ( ! Writer->WriteUi16BE(Patch) ) return false;
375             if ( ! Writer->WriteUi16BE(Build) ) return false;
376             if ( ! Writer->WriteUi16BE((ui16_t)(Release & 0x0000ffffL)) ) return false;
377             return true;
378           }
379         };
380
381       //
382       class Raw : public Kumu::ByteString
383         {
384         public:
385           Raw();
386           Raw(const Raw& rhs) { Copy(rhs); }
387           virtual ~Raw();
388
389           const Raw& operator=(const Raw& rhs) { Copy(rhs); return *this; }
390           void Copy(const Raw& rhs) {
391             if ( KM_SUCCESS(Capacity(rhs.Length())) )
392               {
393                 Set(rhs);
394               }
395           }
396
397           //
398           virtual bool Unarchive(Kumu::MemIOReader* Reader);
399           virtual bool Archive(Kumu::MemIOWriter* Writer) const;
400           const char* EncodeString(char* str_buf, ui32_t buf_len) const;
401         };
402
403     } // namespace MXF
404 } // namespace ASDCP
405
406
407 #endif //_MXFTYPES_H_
408
409 //
410 // end MXFTypes.h
411 //