2a8949e44f1dda51ca4875f0c1ac99b3d32d2c9e
[asdcplib.git] / src / MXFTypes.cpp
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.cpp
28     \version $Id$
29     \brief   MXF objects
30 */
31
32 #include "MXFTypes.h"
33
34 //------------------------------------------------------------------------------------------
35 //
36
37 //
38 ASDCP::Result_t
39 ASDCP::MXF::UTF16String::ReadFrom(ASDCP::MemIOReader& Reader)
40 {
41   const byte_t* p = Reader.Data() + Reader.Offset();
42   /// cheating - for all use cases, we know the previous two bytes are the length
43   m_length = ASDCP_i16_BE(cp2i<ui16_t>(p-2));
44   assert(m_length % 2 == 0);
45   m_length /= 2;
46   assert(IdentBufferLen >= m_length);
47   ui32_t i = 0;
48
49   for ( i = 0; i < m_length; i++ )
50     m_buffer[i] = p[(i*2)+1];
51
52   m_buffer[i] = 0;
53
54   Reader.SkipOffset(m_length*2);
55   return RESULT_OK;
56 }
57
58 //
59 ASDCP::Result_t
60 ASDCP::MXF::UTF16String::WriteTo(ASDCP::MemIOWriter& Writer)
61 {
62   byte_t* p = Writer.Data() + Writer.Size();
63   ui32_t i = 0;
64   m_length = strlen(m_buffer);
65   memset(p, 0, m_length*2);
66
67   for ( i = 0; i < m_length; i++ )
68     p[(i*2)+1] = m_buffer[i];
69
70   m_buffer[i] = 0;
71
72   Writer.AddOffset(m_length*2);
73   return RESULT_OK;
74 }
75
76
77 //------------------------------------------------------------------------------------------
78 //
79
80 ASDCP::MXF::TLVReader::TLVReader(const byte_t* p, ui32_t c, IPrimerLookup* PrimerLookup) :
81   MemIOReader(p, c), m_Lookup(PrimerLookup)
82 {
83   Result_t result = RESULT_OK;
84
85   while ( Remainder() > 0 && ASDCP_SUCCESS(result) )
86     {
87       TagValue Tag;
88       ui16_t pkt_len = 0;
89
90       result = MemIOReader::ReadUi8(&Tag.a);
91
92       if ( ASDCP_SUCCESS(result) )
93         result = MemIOReader::ReadUi8(&Tag.b);
94
95       if ( ASDCP_SUCCESS(result) )
96         result = MemIOReader::ReadUi16BE(&pkt_len);
97
98       if ( ASDCP_SUCCESS(result) )
99         {
100           m_ElementMap.insert(TagMap::value_type(Tag, ItemInfo(m_size, pkt_len)));
101           result = SkipOffset(pkt_len);
102         }
103       
104       if ( ASDCP_FAILURE(result) )
105         {
106           DefaultLogSink().Error("Malformed Set\n");
107           m_ElementMap.clear();
108           break;
109         }
110     }
111 }
112
113 //
114 bool
115 ASDCP::MXF::TLVReader::FindTL(const MDDEntry& Entry)
116 {
117   if ( m_Lookup == 0 )
118     {
119       fprintf(stderr, "No Lookup service\n");
120       return false;
121     }
122   
123   TagValue TmpTag;
124
125   if ( m_Lookup->TagForKey(Entry.ul, TmpTag) != RESULT_OK )
126     {
127       if ( Entry.tag.a == 0 )
128         {
129           DefaultLogSink().Info("No such UL in this TL list: %s (%02x %02x)\n",
130                                 Entry.name, Entry.tag.a, Entry.tag.b);
131           return false;
132         }
133
134       TmpTag = Entry.tag;
135     }
136
137   TagMap::iterator e_i = m_ElementMap.find(TmpTag);
138
139   if ( e_i != m_ElementMap.end() )
140     {
141       m_size = (*e_i).second.first;
142       m_capacity = m_size + (*e_i).second.second;
143       return true;
144     }
145
146   DefaultLogSink().Info("Not Found (%02x %02x): %s\n", TmpTag.a, TmpTag.b, Entry.name);
147   return false;
148 }
149
150 //
151 ASDCP::Result_t
152 ASDCP::MXF::TLVReader::ReadObject(const MDDEntry& Entry, IArchive* Object)
153 {
154   ASDCP_TEST_NULL(Object);
155
156   if ( FindTL(Entry) )
157     return Object->ReadFrom(*this);
158
159   return RESULT_FALSE;
160 }
161
162 //
163 ASDCP::Result_t
164 ASDCP::MXF::TLVReader::ReadUi8(const MDDEntry& Entry, ui8_t* value)
165 {
166   ASDCP_TEST_NULL(value);
167
168   if ( FindTL(Entry) )
169     return MemIOReader::ReadUi8(value);
170
171   return RESULT_FALSE;
172 }
173
174 //
175 ASDCP::Result_t
176 ASDCP::MXF::TLVReader::ReadUi16(const MDDEntry& Entry, ui16_t* value)
177 {
178   ASDCP_TEST_NULL(value);
179
180   if ( FindTL(Entry) )
181     return MemIOReader::ReadUi16BE(value);
182
183   return RESULT_FALSE;
184 }
185
186 //
187 ASDCP::Result_t
188 ASDCP::MXF::TLVReader::ReadUi32(const MDDEntry& Entry, ui32_t* value)
189 {
190   ASDCP_TEST_NULL(value);
191
192   if ( FindTL(Entry) )
193     return MemIOReader::ReadUi32BE(value);
194
195   return RESULT_FALSE;
196 }
197
198 //
199 ASDCP::Result_t
200 ASDCP::MXF::TLVReader::ReadUi64(const MDDEntry& Entry, ui64_t* value)
201 {
202   ASDCP_TEST_NULL(value);
203
204   if ( FindTL(Entry) )
205     return MemIOReader::ReadUi64BE(value);
206
207   return RESULT_FALSE;
208 }
209
210 //------------------------------------------------------------------------------------------
211 //
212
213 ASDCP::MXF::TLVWriter::TLVWriter(byte_t* p, ui32_t c, IPrimerLookup* PrimerLookup) :
214   MemIOWriter(p, c), m_Lookup(PrimerLookup)
215 {
216   assert(c > 3);
217 }
218
219 //
220 ASDCP::Result_t
221 ASDCP::MXF::TLVWriter::WriteTag(const MDDEntry& Entry)
222 {
223   TagValue TmpTag;
224
225   if ( m_Lookup == 0 )
226     {
227       DefaultLogSink().Error("No Primer object available\n");
228       return RESULT_FAIL;
229     }
230
231   if ( m_Lookup->InsertTag(Entry.ul, TmpTag) != RESULT_OK )
232     {
233       DefaultLogSink().Error("No tag for entry %s\n", Entry.name);
234       return RESULT_FAIL;
235     }
236
237   Result_t result = MemIOWriter::WriteUi8(TmpTag.a);
238   if ( ASDCP_SUCCESS(result) ) MemIOWriter::WriteUi8(TmpTag.b);
239
240   return result;
241 }
242
243 //
244 ASDCP::Result_t
245 ASDCP::MXF::TLVWriter::WriteObject(const MDDEntry& Entry, IArchive* Object)
246 {
247   ASDCP_TEST_NULL(Object);
248   Result_t result = WriteTag(Entry);
249
250   // write a temp length
251   byte_t* l_p = CurrentData();
252
253   if ( ASDCP_SUCCESS(result) )
254     MemIOWriter::WriteUi16BE(0);
255
256   if ( ASDCP_SUCCESS(result) )
257     {
258       ui32_t before = Size();
259       result = Object->WriteTo(*this);
260
261       if ( ASDCP_SUCCESS(result) ) 
262         i2p<ui16_t>(ASDCP_i16_BE( Size() - before), l_p);
263     }
264
265   return result;
266 }
267
268 //
269 ASDCP::Result_t
270 ASDCP::MXF::TLVWriter::WriteUi8(const MDDEntry& Entry, ui8_t* value)
271 {
272   ASDCP_TEST_NULL(value);
273   Result_t result = WriteTag(Entry);
274   if ( ASDCP_SUCCESS(result) ) MemIOWriter::WriteUi16BE(sizeof(ui8_t));
275   if ( ASDCP_SUCCESS(result) ) MemIOWriter::WriteUi8(*value);
276   return result;
277 }
278
279 //
280 ASDCP::Result_t
281 ASDCP::MXF::TLVWriter::WriteUi16(const MDDEntry& Entry, ui16_t* value)
282 {
283   ASDCP_TEST_NULL(value);
284   Result_t result = WriteTag(Entry);
285   if ( ASDCP_SUCCESS(result) ) MemIOWriter::WriteUi16BE(sizeof(ui16_t));
286   if ( ASDCP_SUCCESS(result) ) MemIOWriter::WriteUi8(*value);
287   return result;
288 }
289
290 //
291 ASDCP::Result_t
292 ASDCP::MXF::TLVWriter::WriteUi32(const MDDEntry& Entry, ui32_t* value)
293 {
294   ASDCP_TEST_NULL(value);
295   Result_t result = WriteTag(Entry);
296   if ( ASDCP_SUCCESS(result) ) MemIOWriter::WriteUi16BE(sizeof(ui32_t));
297   if ( ASDCP_SUCCESS(result) ) MemIOWriter::WriteUi8(*value);
298   return result;
299 }
300
301 //
302 ASDCP::Result_t
303 ASDCP::MXF::TLVWriter::WriteUi64(const MDDEntry& Entry, ui64_t* value)
304 {
305   ASDCP_TEST_NULL(value);
306   Result_t result = WriteTag(Entry);
307   if ( ASDCP_SUCCESS(result) ) MemIOWriter::WriteUi16BE(sizeof(ui64_t));
308   if ( ASDCP_SUCCESS(result) ) MemIOWriter::WriteUi8(*value);
309   return result;
310 }
311
312 //
313 // end 
314 //