working multi-dict
[asdcplib.git] / src / Dict.cpp
1 /*
2 Copyright (c) 2006-2009, 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    Dict.cpp
28   \version $Id$
29   \brief   MXF dictionary
30 */
31
32
33 #include "KM_mutex.h"
34 #include "KM_log.h"
35 #include "KLV.h"
36 #include "MDD.cpp"
37
38 //------------------------------------------------------------------------------------------
39
40 // The composite dict is the union of the SMPTE and Interop dicts
41 //
42 static ASDCP::Dictionary s_CompositeDict;
43 static Kumu::Mutex s_CompositeDictLock;
44 static bool s_CompositeDictInit = false;
45
46 //
47 const ASDCP::Dictionary&
48 ASDCP::DefaultCompositeDict()
49 {
50   if ( ! s_CompositeDictInit )
51     {
52       Kumu::AutoMutex AL(s_CompositeDictLock);
53
54       if ( ! s_CompositeDictInit )
55         {
56           s_CompositeDict.Init();
57           s_CompositeDictInit = true;
58         }
59     }
60
61   return s_CompositeDict;
62 }
63
64 //
65 //
66 static ASDCP::Dictionary s_InteropDict;
67 static Kumu::Mutex s_InteropDictLock;
68 static bool s_InteropDictInit = false;
69
70 //
71 const ASDCP::Dictionary&
72 ASDCP::DefaultInteropDict()
73 {
74   if ( ! s_InteropDictInit )
75     {
76       Kumu::AutoMutex AL(s_InteropDictLock);
77
78       if ( ! s_InteropDictInit )
79         {
80           s_InteropDict.Init();
81
82           s_InteropDict.AddEntry(s_InteropDict.Type(MDD_MXFInterop_OPAtom), MDD_OPAtom);
83           s_InteropDict.AddEntry(s_InteropDict.Type(MDD_MXFInterop_CryptEssence), MDD_CryptEssence);
84           s_InteropDict.AddEntry(s_InteropDict.Type(MDD_MXFInterop_GenericDescriptor_SubDescriptors),
85                                      MDD_GenericDescriptor_SubDescriptors);
86           s_InteropDict.DeleteEntry(MDD_TimedTextWrapping);
87           s_InteropDict.DeleteEntry(MDD_TimedTextEssence);
88           s_InteropDict.DeleteEntry(MDD_TimedTextDescriptor);
89           s_InteropDict.DeleteEntry(MDD_TimedTextDescriptor_ResourceID);
90           s_InteropDict.DeleteEntry(MDD_TimedTextDescriptor_UCSEncoding);
91           s_InteropDict.DeleteEntry(MDD_TimedTextDescriptor_NamespaceURI);
92           s_InteropDict.DeleteEntry(MDD_TimedTextResourceSubDescriptor);
93           s_InteropDict.DeleteEntry(MDD_TimedTextResourceSubDescriptor_AncillaryResourceID);
94           s_InteropDict.DeleteEntry(MDD_TimedTextResourceSubDescriptor_MIMEMediaType);
95           s_InteropDict.DeleteEntry(MDD_TimedTextResourceSubDescriptor_EssenceStreamID);
96           s_InteropDict.DeleteEntry(MDD_GenericStreamPartition);
97           s_InteropDict.DeleteEntry(MDD_StereoscopicPictureSubDescriptor);
98           s_InteropDict.DeleteEntry(MDD_GenericStream_DataElement);
99
100           s_InteropDictInit = true;
101         }
102     }
103
104   return s_InteropDict;
105 }
106
107 //
108 //
109 static ASDCP::Dictionary s_SMPTEDict;
110 static Kumu::Mutex s_SMPTEDictLock;
111 static bool s_SMPTEDictInit = false;
112
113 //
114 const ASDCP::Dictionary&
115 ASDCP::DefaultSMPTEDict()
116 {
117   if ( ! s_SMPTEDictInit )
118     {
119       Kumu::AutoMutex AL(s_SMPTEDictLock);
120
121       if ( ! s_SMPTEDictInit )
122         {
123           s_SMPTEDict.Init();
124
125           s_SMPTEDict.DeleteEntry(MDD_MXFInterop_OPAtom);
126           s_SMPTEDict.DeleteEntry(MDD_MXFInterop_CryptEssence);
127           s_SMPTEDict.DeleteEntry(MDD_MXFInterop_GenericDescriptor_SubDescriptors);
128
129           s_SMPTEDictInit = true;
130         }
131     }
132
133   return s_SMPTEDict;
134 }
135
136
137 //------------------------------------------------------------------------------------------
138 //
139
140 ASDCP::Dictionary::Dictionary() {}
141 ASDCP::Dictionary::~Dictionary() {}
142
143 //
144 void
145 ASDCP::Dictionary::Init()
146 {
147   m_md_lookup.clear();
148   memset(m_MDD_Table, 0, sizeof(m_MDD_Table));
149
150   for ( ui32_t x = 0; x < ASDCP::MDD_Table_size; x++ )
151     AddEntry(s_MDD_Table[x], x);
152 }
153
154 //
155 bool
156 ASDCP::Dictionary::AddEntry(const MDDEntry& Entry, ui32_t index)
157 {
158   bool result = true;
159   // is this index already there?
160   std::map<ui32_t, ASDCP::UL>::iterator rii = m_md_rev_lookup.find(index);
161
162   if ( rii != m_md_rev_lookup.end() )
163     {
164       DeleteEntry(index);
165       result = false;
166     }
167
168   m_md_lookup.insert(std::map<UL, ui32_t>::value_type(UL(Entry.ul), index));
169   m_md_rev_lookup.insert(std::map<ui32_t, UL>::value_type(index, UL(Entry.ul)));
170   m_MDD_Table[index] = Entry;
171
172   return result;
173 }
174
175 //
176 bool
177 ASDCP::Dictionary::DeleteEntry(ui32_t index)
178 {
179   // is this index already there?
180   std::map<ui32_t, ASDCP::UL>::iterator rii = m_md_rev_lookup.find(index);
181
182   if ( rii != m_md_rev_lookup.end() )
183     {
184       std::map<ASDCP::UL, ui32_t>::iterator ii = m_md_lookup.find(rii->second);
185       assert(ii != m_md_lookup.end());
186
187       char buf[64];
188       Kumu::DefaultLogSink().Warn("Deleting %s: %s\n", ii->first.EncodeString(buf, 64), m_MDD_Table[index].name);
189       return true;
190     }
191
192   return false;
193 }
194
195 //
196 const ASDCP::MDDEntry&
197 ASDCP::Dictionary::Type(MDD_t type_id) const
198 {
199   return m_MDD_Table[type_id];
200 }
201
202 //
203 const ASDCP::MDDEntry*
204 ASDCP::Dictionary::FindUL(const byte_t* ul_buf) const
205 {
206   std::map<UL, ui32_t>::const_iterator i = m_md_lookup.find(UL(ul_buf));
207   
208   if ( i == m_md_lookup.end() )
209     {
210       byte_t tmp_ul[SMPTE_UL_LENGTH];
211       memcpy(tmp_ul, ul_buf, SMPTE_UL_LENGTH);
212       tmp_ul[SMPTE_UL_LENGTH-1] = 0;
213
214       i = m_md_lookup.find(UL(tmp_ul));
215
216       if ( i == m_md_lookup.end() )
217         return 0;
218     }
219
220   return &m_MDD_Table[(*i).second];
221 }
222
223 //
224 void
225 ASDCP::Dictionary::Dump(FILE* stream) const
226 {
227   if ( stream == 0 )
228     stream = stderr;
229
230   MDD_t di = (MDD_t)0;
231   char     str_buf[64];
232
233   while ( di < MDD_Max )
234     {
235       MDDEntry TmpType = m_MDD_Table[di];
236       UL TmpUL(TmpType.ul);
237       fprintf(stream, "%s: %s\n", TmpUL.EncodeString(str_buf, 64), TmpType.name);
238       di = (MDD_t)(di + 1);
239     }
240 }
241
242 //
243 // end Dict.cpp
244 //