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