Modify to test email notice.
[asdcplib.git] / src / KLV.h
1 /*
2 Copyright (c) 2005-2018, 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    KLV.h
28   \version $Id$
29   \brief   KLV objects
30 */
31
32 #ifndef _KLV_H_
33 #define _KLV_H_
34
35 #include <KM_fileio.h>
36 #include <KM_memio.h>
37 #include "AS_DCP.h"
38 #include "MDD.h"
39 #include <map>
40
41
42 namespace ASDCP
43 {
44   const ui32_t MXF_BER_LENGTH = 4;
45   const ui32_t MXF_TAG_LENGTH = 2;
46   const ui32_t SMPTE_UL_LENGTH = 16;
47   const ui32_t SMPTE_UMID_LENGTH = 32;
48   const byte_t SMPTE_UL_START[4] = { 0x06, 0x0e, 0x2b, 0x34 };
49
50 #ifndef MAX_KLV_PACKET_LENGTH
51   const ui32_t MAX_KLV_PACKET_LENGTH = 1024*1024*64;
52 #endif
53
54   const ui32_t IdentBufferLen = 128;
55   const ui32_t IntBufferLen = 64;
56
57 inline const char* i64sz(i64_t i, char* buf)
58
59   assert(buf);
60 #ifdef WIN32
61   snprintf(buf, IntBufferLen, "%I64d", i);
62 #else
63   snprintf(buf, IntBufferLen, "%lld", i);
64 #endif
65   return buf;
66 }
67
68 inline const char* ui64sz(ui64_t i, char* buf)
69
70   assert(buf);
71 #ifdef WIN32
72   snprintf(buf, IntBufferLen, "%I64u", i);
73 #else
74   snprintf(buf, IntBufferLen, "%llu", i);
75 #endif
76   return buf;
77 }
78
79   struct TagValue
80   {
81     byte_t a;
82     byte_t b;
83
84     inline bool operator<(const TagValue& rhs) const {
85       if ( a < rhs.a ) return true;
86       if ( a == rhs.a && b < rhs.b ) return true;
87       return false;
88     }
89
90     inline bool operator==(const TagValue& rhs) const {
91       if ( a != rhs.a ) return false;
92       if ( b != rhs.b ) return false;
93       return true;
94     }
95   };
96
97   using Kumu::UUID;
98
99   // Universal Label
100   class UL : public Kumu::Identifier<SMPTE_UL_LENGTH>
101     {
102     public:
103       UL() {}
104       UL(const UL& rhs) : Kumu::Identifier<SMPTE_UL_LENGTH>(rhs) {}
105       UL(const byte_t* value) : Kumu::Identifier<SMPTE_UL_LENGTH>(value) {}
106       virtual ~UL() {}
107
108       const char* EncodeString(char* str_buf, ui32_t buf_len) const;
109       bool operator==(const UL& rhs) const;
110       bool MatchIgnoreStream(const UL& rhs) const;
111       bool MatchExact(const UL& rhs) const;
112     };
113
114   // UMID
115   class UMID : public Kumu::Identifier<SMPTE_UMID_LENGTH>
116     {
117     public:
118       UMID() {}
119       UMID(const UMID& rhs) : Kumu::Identifier<SMPTE_UMID_LENGTH>(rhs) {}
120       UMID(const byte_t* value) : Kumu::Identifier<SMPTE_UMID_LENGTH>(value) {}
121       virtual ~UMID() {}
122
123       void MakeUMID(int Type);
124       void MakeUMID(int Type, const UUID& ID);
125       const char* EncodeString(char* str_buf, ui32_t buf_len) const;
126     };
127
128   const byte_t nil_UMID[SMPTE_UMID_LENGTH] = {0};
129   const UMID NilUMID(nil_UMID);
130
131   //
132   struct MDDEntry
133   {
134     byte_t        ul[SMPTE_UL_LENGTH];
135     TagValue      tag;
136     bool          optional;
137     const char*   name;
138   };
139
140   const MDDEntry& MXFInterop_OPAtom_Entry();
141   const MDDEntry& SMPTE_390_OPAtom_Entry();
142
143   //
144   class Dictionary
145     {
146       std::map<ASDCP::UL, ui32_t>   m_md_lookup;
147       std::map<std::string, ui32_t> m_md_sym_lookup;
148       std::map<ui32_t, ASDCP::UL>   m_md_rev_lookup;
149
150       ASDCP_NO_COPY_CONSTRUCT(Dictionary);
151
152     public:
153       MDDEntry m_MDD_Table[(ui32_t)ASDCP::MDD_Max];
154
155       Dictionary();
156       ~Dictionary();
157
158       void Init();
159       bool AddEntry(const MDDEntry& Entry, ui32_t index);
160       bool DeleteEntry(ui32_t index);
161
162       const MDDEntry* FindULAnyVersion(const byte_t*) const;
163       const MDDEntry* FindULExact(const byte_t*) const;
164       const MDDEntry* FindSymbol(const std::string&) const;
165       const MDDEntry& Type(MDD_t type_id) const;
166       MDDEntry& MutableType(MDD_t type_id);
167
168       inline const byte_t* ul(MDD_t type_id) const {
169         return Type(type_id).ul;
170       }
171
172       void Dump(FILE* = 0) const;
173     };
174
175
176   const Dictionary& AtmosSMPTEDict();
177   const Dictionary& DefaultSMPTEDict();
178   const Dictionary& DefaultInteropDict();
179   const Dictionary& DefaultCompositeDict();
180
181   void default_md_object_init();
182
183   //
184   class IPrimerLookup
185     {
186     public:
187       virtual ~IPrimerLookup() {}
188       virtual void     ClearTagList() = 0;
189       virtual Result_t InsertTag(const MDDEntry& Entry, ASDCP::TagValue& Tag) = 0;
190       virtual Result_t TagForKey(const ASDCP::UL& Key, ASDCP::TagValue& Tag) = 0;
191     };
192
193   //
194   class KLVPacket
195     {
196       ASDCP_NO_COPY_CONSTRUCT(KLVPacket);
197
198     protected:
199       const byte_t* m_KeyStart;
200       ui32_t        m_KLLength;
201       const byte_t* m_ValueStart;
202       ui64_t        m_ValueLength;
203       UL m_UL;
204
205     public:
206       KLVPacket() : m_KeyStart(0), m_KLLength(0), m_ValueStart(0), m_ValueLength(0) {}
207       virtual ~KLVPacket() {}
208
209       inline ui64_t  PacketLength() {
210         return m_KLLength + m_ValueLength;
211       }
212
213       inline ui64_t   ValueLength() {
214         return m_ValueLength;
215       }
216
217       inline ui32_t   KLLength() {
218         return m_KLLength;
219       }
220
221       virtual UL       GetUL();
222       virtual bool     SetUL(const UL&);
223       virtual bool     HasUL(const byte_t*);
224       virtual Result_t InitFromBuffer(const byte_t*, ui32_t);
225       virtual Result_t InitFromBuffer(const byte_t*, ui32_t, const UL& label);
226       virtual Result_t WriteKLToBuffer(ASDCP::FrameBuffer&, const UL& label, ui32_t length);
227
228       virtual Result_t WriteKLToBuffer(ASDCP::FrameBuffer& fb, ui32_t length)
229       {
230         if ( ! m_UL.HasValue() )
231           {
232             return RESULT_STATE;
233           }
234
235         return WriteKLToBuffer(fb, m_UL, length);
236       }
237
238       virtual void     Dump(FILE*, const Dictionary& Dict, bool show_value);
239     };
240
241   //
242   class KLVFilePacket : public KLVPacket
243     {
244       ASDCP_NO_COPY_CONSTRUCT(KLVFilePacket);
245
246     public:
247       ASDCP::FrameBuffer m_Buffer;
248
249       KLVFilePacket() {}
250       virtual ~KLVFilePacket() {}
251
252       virtual Result_t InitFromFile(const Kumu::FileReader&);
253       virtual Result_t InitFromFile(const Kumu::FileReader&, const UL& label);
254       virtual Result_t WriteKLToFile(Kumu::FileWriter& Writer, const UL& label, ui32_t length);
255     };
256
257 } // namespace ASDCP
258
259 #endif // _KLV_H_
260
261
262 //
263 // end KLV.h
264 //