bug fixes
[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) 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           //
129           virtual bool Archive(Kumu::MemIOWriter* Writer) const {
130             if ( ! Writer->WriteUi32BE(this->size()) ) return false;
131             byte_t* p = Writer->CurrentData();
132
133             if ( ! Writer->WriteUi32BE(0) ) return false;
134             if ( this->empty() ) return true;
135             
136             typename std::vector<T>::const_iterator l_i = this->begin();
137             assert(l_i != this->end());
138
139             ui32_t ItemSize = Writer->Remainder();
140             if ( ! (*l_i).Archive(Writer) ) return false;
141             ItemSize -= Writer->Remainder();
142             Kumu::i2p<ui32_t>(KM_i32_BE(ItemSize), p);
143             l_i++;
144
145             bool result = true;
146             for ( ; l_i != this->end() && result; l_i++ )
147               result = (*l_i).Archive(Writer);
148
149             return result;
150           }
151
152           //
153           void Dump(FILE* stream = 0, ui32_t depth = 0)
154             {
155               char identbuf[IdentBufferLen];
156
157               if ( stream == 0 )
158                 stream = stderr;
159
160               typename std::vector<T>::iterator i = this->begin();
161               for ( ; i != this->end(); i++ )
162                 fprintf(stream, "  %s\n", (*i).EncodeString(identbuf, IdentBufferLen));
163             }
164         };
165
166       //
167       template <class T>
168         class Array : public std::list<T>, public Kumu::IArchive
169         {
170         public:
171           Array() {}
172           ~Array() {}
173
174           //
175           virtual bool Unarchive(Kumu::MemIOReader* Reader)
176             {
177               bool result = true;
178
179               while ( Reader->Remainder() > 0 && result )
180                 {
181                   T Tmp;
182                   result = Tmp.Unarchive(Reader);
183                   push_back(Tmp);
184                 }
185
186               return result;
187             }
188
189           inline virtual bool HasValue() const { return ! this->empty(); }
190
191           //
192           virtual bool Archive(Kumu::MemIOWriter* Writer) const {
193             bool result = true;
194             typename std::list<T>::const_iterator l_i = this->begin();
195
196             for ( ; l_i != this->end() && result; l_i++ )
197               result = (*l_i).Archive(Writer);
198
199             return result;
200           }
201
202           //
203           void Dump(FILE* stream = 0, ui32_t depth = 0)
204             {
205               char identbuf[IdentBufferLen];
206
207               if ( stream == 0 )
208                 stream = stderr;
209
210               typename std::list<T>::iterator i = this->begin();
211               for ( ; i != this->end(); i++ )
212                 fprintf(stream, "  %s\n", (*i).EncodeString(identbuf, IdentBufferLen));
213             }
214         };
215
216       //
217       class Timestamp : public Kumu::IArchive
218         {
219         public:
220           ui16_t Year;
221           ui8_t  Month;
222           ui8_t  Day;
223           ui8_t  Hour;
224           ui8_t  Minute;
225           ui8_t  Second;
226           ui8_t  Tick;
227
228           Timestamp();
229           Timestamp(const Timestamp& rhs);
230           Timestamp(const char* datestr);
231           virtual ~Timestamp();
232
233           const Timestamp& operator=(const Timestamp& rhs);
234           bool operator<(const Timestamp& rhs) const;
235           bool operator==(const Timestamp& rhs) const;
236           bool operator!=(const Timestamp& rhs) const;
237
238           // decode and set value from string formatted by EncodeAsString
239           Result_t    SetFromString(const char* datestr);
240           
241           // add the given number of days or hours to the timestamp value. Values less than zero
242           // will cause the value to decrease
243           void AddDays(i32_t);
244           void AddHours(i32_t);
245
246           // Write the timestamp value to the given buffer in the form 2004-05-01 13:20:00.000
247           // returns 0 if the buffer is smaller than DateTimeLen
248           const char* EncodeString(char* str_buf, ui32_t buf_len) const;
249
250           //
251           inline virtual bool Unarchive(Kumu::MemIOReader* Reader) {
252             if ( ! Reader->ReadUi16BE(&Year) ) return false;
253             if ( ! Reader->ReadRaw(&Month, 6) ) return false;
254             return true;
255           }
256
257           inline virtual bool HasValue() const { return true; }
258
259           //
260           inline virtual bool Archive(Kumu::MemIOWriter* Writer) const {
261             if ( ! Writer->WriteUi16BE(Year) ) return false;
262             if ( ! Writer->WriteRaw(&Month, 6) ) return false;
263             return true;
264           }
265         };
266
267       //
268       class UTF16String : public Kumu::IArchive
269         {
270           ui16_t m_length;
271           char   m_buffer[IdentBufferLen];
272           ASDCP_NO_COPY_CONSTRUCT(UTF16String);
273           
274         public:
275           UTF16String() : m_length(0) { *m_buffer = 0; }
276           ~UTF16String() {}
277
278           const UTF16String& operator=(const char*);
279
280           //
281           const char* EncodeString(char* str_buf, ui32_t buf_len) const {
282             strncpy(str_buf, m_buffer, Kumu::xmin(buf_len, ((ui32_t)m_length+1)));
283             str_buf[buf_len-1] = 0;
284             return str_buf;
285           }
286
287           virtual bool Unarchive(Kumu::MemIOReader* Reader);
288           inline virtual bool HasValue() const { return m_length > 0; }
289           virtual bool Archive(Kumu::MemIOWriter* Writer) const;
290         };
291
292       //
293       class Rational : public ASDCP::Rational, public Kumu::IArchive
294         {
295         public:
296           Rational() {}
297           ~Rational() {}
298
299           Rational(const Rational& rhs) {
300             Numerator = rhs.Numerator;
301             Denominator = rhs.Denominator;
302           }
303
304           const Rational& operator=(const Rational& rhs) {
305             Numerator = rhs.Numerator;
306             Denominator = rhs.Denominator;
307             return *this;
308           }
309
310           Rational(const ASDCP::Rational& rhs) {
311             Numerator = rhs.Numerator;
312             Denominator = rhs.Denominator;
313           }
314
315           const Rational& operator=(const ASDCP::Rational& rhs) {
316             Numerator = rhs.Numerator;
317             Denominator = rhs.Denominator;
318             return *this;
319           }
320
321           //
322           inline const char* EncodeString(char* str_buf, ui32_t buf_len) const {
323             snprintf(str_buf, buf_len, "%d/%d", Numerator, Denominator);
324             return str_buf;
325           }
326
327           inline virtual bool Unarchive(Kumu::MemIOReader* Reader) {
328             if ( ! Reader->ReadUi32BE((ui32_t*)&Numerator) ) return false;
329             if ( ! Reader->ReadUi32BE((ui32_t*)&Denominator) ) return false;
330             return true;
331           }
332
333           inline virtual bool HasValue() const { return true; }
334
335           inline virtual bool Archive(Kumu::MemIOWriter* Writer) const {
336             if ( ! Writer->WriteUi32BE((ui32_t)Numerator) ) return false;
337             if ( ! Writer->WriteUi32BE((ui32_t)Denominator) ) return false;
338             return true;
339           }
340         };
341
342       //
343       class VersionType : public Kumu::IArchive
344         {
345           ASDCP_NO_COPY_CONSTRUCT(VersionType);
346
347         public:
348           enum Release_t { RL_UNKNOWN, RL_RELEASE, RL_DEVELOPMENT, RL_PATCHED, RL_BETA, RL_PRIVATE };
349           ui16_t Major;
350           ui16_t Minor;
351           ui16_t Patch;
352           ui16_t Build;
353           ui16_t Release;
354
355           VersionType() : Major(0), Minor(0), Patch(0), Build(0), Release(RL_UNKNOWN) {}
356           ~VersionType() {}
357           void Dump(FILE* = 0);
358
359           const char* EncodeString(char* str_buf, ui32_t buf_len) const {
360             snprintf(str_buf, buf_len, "%hu.%hu.%hu.%hur%hu", Major, Minor, Patch, Build, Release);
361             return str_buf;
362           }
363
364           virtual bool Unarchive(Kumu::MemIOReader* Reader) {
365             if ( ! Reader->ReadUi16BE(&Major) ) return false;
366             if ( ! Reader->ReadUi16BE(&Minor) ) return false;
367             if ( ! Reader->ReadUi16BE(&Patch) ) return false;
368             if ( ! Reader->ReadUi16BE(&Build) ) return false;
369             ui16_t tmp_release;
370             if ( ! Reader->ReadUi16BE(&tmp_release) ) return false;
371             Release = (Release_t)tmp_release;
372             return true;
373           }
374
375           inline virtual bool HasValue() const { return true; }
376
377           virtual bool Archive(Kumu::MemIOWriter* Writer) const {
378             if ( ! Writer->WriteUi16BE(Major) ) return false;
379             if ( ! Writer->WriteUi16BE(Minor) ) return false;
380             if ( ! Writer->WriteUi16BE(Patch) ) return false;
381             if ( ! Writer->WriteUi16BE(Build) ) return false;
382             if ( ! Writer->WriteUi16BE((ui16_t)(Release & 0x0000ffffL)) ) return false;
383             return true;
384           }
385         };
386
387       //
388       class Raw : public Kumu::ByteString
389         {
390           ASDCP_NO_COPY_CONSTRUCT(Raw);
391
392         public:
393           Raw();
394           ~Raw();
395
396           //
397           virtual bool Unarchive(Kumu::MemIOReader* Reader);
398           virtual bool Archive(Kumu::MemIOWriter* Writer) const;
399           const char* EncodeString(char* str_buf, ui32_t buf_len) const;
400         };
401
402     } // namespace MXF
403 } // namespace ASDCP
404
405
406 #endif //_MXFTYPES_H_
407
408 //
409 // end MXFTypes.h
410 //