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