pre as-02
[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           virtual ~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                   this->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           virtual ~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                   this->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 ISO8String : public std::string, public Kumu::IArchive
241         {
242         public:
243           ISO8String() {}
244           ~ISO8String() {}
245
246           const ISO8String& operator=(const char*);
247           const ISO8String& operator=(const std::string&);
248
249           const char* EncodeString(char* str_buf, ui32_t buf_len) const;
250           inline virtual bool HasValue() const { return ! empty(); }
251           inline virtual ui32_t ArchiveLength() const { return sizeof(ui32_t) + size(); }
252           virtual bool Unarchive(Kumu::MemIOReader* Reader);
253           virtual bool Archive(Kumu::MemIOWriter* Writer) const;
254         };
255
256       //
257     class UTF16String : public std::string, public Kumu::IArchive
258         {
259         public:
260           UTF16String() {}
261           ~UTF16String() {}
262
263           const UTF16String& operator=(const char*);
264           const UTF16String& operator=(const std::string&);
265
266           const char* EncodeString(char* str_buf, ui32_t buf_len) const;
267           inline virtual bool HasValue() const { return ! empty(); }
268           inline virtual ui32_t ArchiveLength() const { return sizeof(ui32_t) + size(); }
269           virtual bool Unarchive(Kumu::MemIOReader* Reader);
270           virtual bool Archive(Kumu::MemIOWriter* Writer) const;
271         };
272
273       //
274       class Rational : public ASDCP::Rational, public Kumu::IArchive
275         {
276         public:
277           Rational() {}
278           ~Rational() {}
279
280           Rational(const Rational& rhs) : ASDCP::Rational(), IArchive() {
281             Numerator = rhs.Numerator;
282             Denominator = rhs.Denominator;
283           }
284
285           const Rational& operator=(const Rational& rhs) {
286             Numerator = rhs.Numerator;
287             Denominator = rhs.Denominator;
288             return *this;
289           }
290
291           Rational(const ASDCP::Rational& rhs) {
292             Numerator = rhs.Numerator;
293             Denominator = rhs.Denominator;
294           }
295
296           const Rational& operator=(const ASDCP::Rational& rhs) {
297             Numerator = rhs.Numerator;
298             Denominator = rhs.Denominator;
299             return *this;
300           }
301
302           //
303           inline const char* EncodeString(char* str_buf, ui32_t buf_len) const {
304             snprintf(str_buf, buf_len, "%d/%d", Numerator, Denominator);
305             return str_buf;
306           }
307
308           inline virtual bool Unarchive(Kumu::MemIOReader* Reader) {
309             if ( ! Reader->ReadUi32BE((ui32_t*)&Numerator) ) return false;
310             if ( ! Reader->ReadUi32BE((ui32_t*)&Denominator) ) return false;
311             return true;
312           }
313
314           inline virtual bool HasValue() const { return true; }
315           inline virtual ui32_t ArchiveLength() const { return sizeof(ui32_t)*2; }
316
317           inline virtual bool Archive(Kumu::MemIOWriter* Writer) const {
318             if ( ! Writer->WriteUi32BE((ui32_t)Numerator) ) return false;
319             if ( ! Writer->WriteUi32BE((ui32_t)Denominator) ) return false;
320             return true;
321           }
322         };
323
324       //
325       class VersionType : public Kumu::IArchive
326         {
327         public:
328           enum Release_t { RL_UNKNOWN, RL_RELEASE, RL_DEVELOPMENT, RL_PATCHED, RL_BETA, RL_PRIVATE };
329           ui16_t Major;
330           ui16_t Minor;
331           ui16_t Patch;
332           ui16_t Build;
333           Release_t Release;
334
335           VersionType() : Major(0), Minor(0), Patch(0), Build(0), Release(RL_UNKNOWN) {}
336           VersionType(const VersionType& rhs) { Copy(rhs); }
337           virtual ~VersionType() {}
338
339           const VersionType& operator=(const VersionType& rhs) { Copy(rhs); return *this; }
340           void Copy(const VersionType& rhs) {
341             Major = rhs.Major;
342             Minor = rhs.Minor;
343             Patch = rhs.Patch;
344             Build = rhs.Build;
345             Release = rhs.Release;
346           }
347
348           void Dump(FILE* = 0);
349
350           const char* EncodeString(char* str_buf, ui32_t buf_len) const {
351             snprintf(str_buf, buf_len, "%hu.%hu.%hu.%hur%hu", Major, Minor, Patch, Build, Release);
352             return str_buf;
353           }
354
355           virtual bool Unarchive(Kumu::MemIOReader* Reader) {
356             if ( ! Reader->ReadUi16BE(&Major) ) return false;
357             if ( ! Reader->ReadUi16BE(&Minor) ) return false;
358             if ( ! Reader->ReadUi16BE(&Patch) ) return false;
359             if ( ! Reader->ReadUi16BE(&Build) ) return false;
360             ui16_t tmp_release;
361             if ( ! Reader->ReadUi16BE(&tmp_release) ) return false;
362             Release = (Release_t)tmp_release;
363             return true;
364           }
365
366           inline virtual bool HasValue() const { return true; }
367           inline virtual ui32_t ArchiveLength() const { return sizeof(ui16_t)*5; }
368
369           virtual bool Archive(Kumu::MemIOWriter* Writer) const {
370             if ( ! Writer->WriteUi16BE(Major) ) return false;
371             if ( ! Writer->WriteUi16BE(Minor) ) return false;
372             if ( ! Writer->WriteUi16BE(Patch) ) return false;
373             if ( ! Writer->WriteUi16BE(Build) ) return false;
374             if ( ! Writer->WriteUi16BE((ui16_t)(Release & 0x0000ffffL)) ) return false;
375             return true;
376           }
377         };
378
379       //
380       class Raw : public Kumu::ByteString
381         {
382         public:
383           Raw();
384           Raw(const Raw& rhs) { Copy(rhs); }
385           virtual ~Raw();
386
387           const Raw& operator=(const Raw& rhs) { Copy(rhs); return *this; }
388           void Copy(const Raw& rhs) {
389             if ( KM_SUCCESS(Capacity(rhs.Length())) )
390               {
391                 Set(rhs);
392               }
393           }
394
395           //
396           virtual bool Unarchive(Kumu::MemIOReader* Reader);
397           virtual bool Archive(Kumu::MemIOWriter* Writer) const;
398           const char* EncodeString(char* str_buf, ui32_t buf_len) const;
399         };
400
401     } // namespace MXF
402 } // namespace ASDCP
403
404
405 #endif //_MXFTYPES_H_
406
407 //
408 // end MXFTypes.h
409 //