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