Update copyright dates.
[asdcplib.git] / src / MXFTypes.h
1 /*
2 Copyright (c) 2005-2009, 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) Dict::Type(MDD_##s##_##l), &l
45 #define OBJ_WRITE_ARGS(s,l) Dict::Type(MDD_##s##_##l), &l
46 #define OBJ_TYPE_ARGS(t) 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 UTF16String : public std::string, public Kumu::IArchive
293         {
294         public:
295           UTF16String() {}
296           ~UTF16String() {}
297
298           const UTF16String& operator=(const char*);
299           const UTF16String& 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 Rational : public ASDCP::Rational, public Kumu::IArchive
310         {
311         public:
312           Rational() {}
313           ~Rational() {}
314
315           Rational(const Rational& rhs) : ASDCP::Rational(), IArchive() {
316             Numerator = rhs.Numerator;
317             Denominator = rhs.Denominator;
318           }
319
320           const Rational& operator=(const Rational& rhs) {
321             Numerator = rhs.Numerator;
322             Denominator = rhs.Denominator;
323             return *this;
324           }
325
326           Rational(const ASDCP::Rational& rhs) {
327             Numerator = rhs.Numerator;
328             Denominator = rhs.Denominator;
329           }
330
331           const Rational& operator=(const ASDCP::Rational& rhs) {
332             Numerator = rhs.Numerator;
333             Denominator = rhs.Denominator;
334             return *this;
335           }
336
337           //
338           inline const char* EncodeString(char* str_buf, ui32_t buf_len) const {
339             snprintf(str_buf, buf_len, "%d/%d", Numerator, Denominator);
340             return str_buf;
341           }
342
343           inline virtual bool Unarchive(Kumu::MemIOReader* Reader) {
344             if ( ! Reader->ReadUi32BE((ui32_t*)&Numerator) ) return false;
345             if ( ! Reader->ReadUi32BE((ui32_t*)&Denominator) ) return false;
346             return true;
347           }
348
349           inline virtual bool HasValue() const { return true; }
350           inline virtual ui32_t ArchiveLength() const { return sizeof(ui32_t)*2; }
351
352           inline virtual bool Archive(Kumu::MemIOWriter* Writer) const {
353             if ( ! Writer->WriteUi32BE((ui32_t)Numerator) ) return false;
354             if ( ! Writer->WriteUi32BE((ui32_t)Denominator) ) return false;
355             return true;
356           }
357         };
358
359       //
360       class VersionType : public Kumu::IArchive
361         {
362           ASDCP_NO_COPY_CONSTRUCT(VersionType);
363
364         public:
365           enum Release_t { RL_UNKNOWN, RL_RELEASE, RL_DEVELOPMENT, RL_PATCHED, RL_BETA, RL_PRIVATE };
366           ui16_t Major;
367           ui16_t Minor;
368           ui16_t Patch;
369           ui16_t Build;
370           Release_t Release;
371
372           VersionType() : Major(0), Minor(0), Patch(0), Build(0), Release(RL_UNKNOWN) {}
373           ~VersionType() {}
374           void Dump(FILE* = 0);
375
376           const char* EncodeString(char* str_buf, ui32_t buf_len) const {
377             snprintf(str_buf, buf_len, "%hu.%hu.%hu.%hur%hu", Major, Minor, Patch, Build, Release);
378             return str_buf;
379           }
380
381           virtual bool Unarchive(Kumu::MemIOReader* Reader) {
382             if ( ! Reader->ReadUi16BE(&Major) ) return false;
383             if ( ! Reader->ReadUi16BE(&Minor) ) return false;
384             if ( ! Reader->ReadUi16BE(&Patch) ) return false;
385             if ( ! Reader->ReadUi16BE(&Build) ) return false;
386             ui16_t tmp_release;
387             if ( ! Reader->ReadUi16BE(&tmp_release) ) return false;
388             Release = (Release_t)tmp_release;
389             return true;
390           }
391
392           inline virtual bool HasValue() const { return true; }
393           inline virtual ui32_t ArchiveLength() const { return sizeof(ui16_t)*5; }
394
395           virtual bool Archive(Kumu::MemIOWriter* Writer) const {
396             if ( ! Writer->WriteUi16BE(Major) ) return false;
397             if ( ! Writer->WriteUi16BE(Minor) ) return false;
398             if ( ! Writer->WriteUi16BE(Patch) ) return false;
399             if ( ! Writer->WriteUi16BE(Build) ) return false;
400             if ( ! Writer->WriteUi16BE((ui16_t)(Release & 0x0000ffffL)) ) return false;
401             return true;
402           }
403         };
404
405       //
406       class Raw : public Kumu::ByteString
407         {
408           ASDCP_NO_COPY_CONSTRUCT(Raw);
409
410         public:
411           Raw();
412           ~Raw();
413
414           //
415           virtual bool Unarchive(Kumu::MemIOReader* Reader);
416           virtual bool Archive(Kumu::MemIOWriter* Writer) const;
417           const char* EncodeString(char* str_buf, ui32_t buf_len) const;
418         };
419
420     } // namespace MXF
421 } // namespace ASDCP
422
423
424 #endif //_MXFTYPES_H_
425
426 //
427 // end MXFTypes.h
428 //