2 Copyright (c) 2005-2006, John Hurst
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions
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.
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.
27 /*! \file MXFTypes.cpp
34 //------------------------------------------------------------------------------------------
39 ASDCP::MXF::UTF16String::ReadFrom(ASDCP::MemIOReader& Reader)
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);
46 assert(IdentBufferLen >= m_length);
49 for ( i = 0; i < m_length; i++ )
50 m_buffer[i] = p[(i*2)+1];
54 Reader.SkipOffset(m_length*2);
60 ASDCP::MXF::UTF16String::WriteTo(ASDCP::MemIOWriter& Writer)
62 byte_t* p = Writer.Data() + Writer.Size();
64 m_length = strlen(m_buffer);
65 memset(p, 0, m_length*2);
67 for ( i = 0; i < m_length; i++ )
68 p[(i*2)+1] = m_buffer[i];
72 Writer.AddOffset(m_length*2);
77 //------------------------------------------------------------------------------------------
80 ASDCP::MXF::TLVReader::TLVReader(const byte_t* p, ui32_t c, IPrimerLookup* PrimerLookup) :
81 MemIOReader(p, c), m_Lookup(PrimerLookup)
83 Result_t result = RESULT_OK;
85 while ( Remainder() > 0 && ASDCP_SUCCESS(result) )
90 result = MemIOReader::ReadUi8(&Tag.a);
92 if ( ASDCP_SUCCESS(result) )
93 result = MemIOReader::ReadUi8(&Tag.b);
95 if ( ASDCP_SUCCESS(result) )
96 result = MemIOReader::ReadUi16BE(&pkt_len);
98 if ( ASDCP_SUCCESS(result) )
100 m_ElementMap.insert(TagMap::value_type(Tag, ItemInfo(m_size, pkt_len)));
101 result = SkipOffset(pkt_len);
104 if ( ASDCP_FAILURE(result) )
106 DefaultLogSink().Error("Malformed Set\n");
107 m_ElementMap.clear();
115 ASDCP::MXF::TLVReader::FindTL(const MDDEntry& Entry)
119 fprintf(stderr, "No Lookup service\n");
125 if ( m_Lookup->TagForKey(Entry.ul, TmpTag) != RESULT_OK )
127 if ( Entry.tag.a == 0 )
129 DefaultLogSink().Info("No such UL in this TL list: %s (%02x %02x)\n",
130 Entry.name, Entry.tag.a, Entry.tag.b);
137 TagMap::iterator e_i = m_ElementMap.find(TmpTag);
139 if ( e_i != m_ElementMap.end() )
141 m_size = (*e_i).second.first;
142 m_capacity = m_size + (*e_i).second.second;
146 DefaultLogSink().Info("Not Found (%02x %02x): %s\n", TmpTag.a, TmpTag.b, Entry.name);
152 ASDCP::MXF::TLVReader::ReadObject(const MDDEntry& Entry, IArchive* Object)
154 ASDCP_TEST_NULL(Object);
157 return Object->ReadFrom(*this);
164 ASDCP::MXF::TLVReader::ReadUi8(const MDDEntry& Entry, ui8_t* value)
166 ASDCP_TEST_NULL(value);
169 return MemIOReader::ReadUi8(value);
176 ASDCP::MXF::TLVReader::ReadUi16(const MDDEntry& Entry, ui16_t* value)
178 ASDCP_TEST_NULL(value);
181 return MemIOReader::ReadUi16BE(value);
188 ASDCP::MXF::TLVReader::ReadUi32(const MDDEntry& Entry, ui32_t* value)
190 ASDCP_TEST_NULL(value);
193 return MemIOReader::ReadUi32BE(value);
200 ASDCP::MXF::TLVReader::ReadUi64(const MDDEntry& Entry, ui64_t* value)
202 ASDCP_TEST_NULL(value);
205 return MemIOReader::ReadUi64BE(value);
210 //------------------------------------------------------------------------------------------
213 ASDCP::MXF::TLVWriter::TLVWriter(byte_t* p, ui32_t c, IPrimerLookup* PrimerLookup) :
214 MemIOWriter(p, c), m_Lookup(PrimerLookup)
221 ASDCP::MXF::TLVWriter::WriteTag(const MDDEntry& Entry)
227 DefaultLogSink().Error("No Primer object available\n");
231 if ( m_Lookup->InsertTag(Entry.ul, TmpTag) != RESULT_OK )
233 DefaultLogSink().Error("No tag for entry %s\n", Entry.name);
237 Result_t result = MemIOWriter::WriteUi8(TmpTag.a);
238 if ( ASDCP_SUCCESS(result) ) MemIOWriter::WriteUi8(TmpTag.b);
245 ASDCP::MXF::TLVWriter::WriteObject(const MDDEntry& Entry, IArchive* Object)
247 ASDCP_TEST_NULL(Object);
248 Result_t result = WriteTag(Entry);
250 // write a temp length
251 byte_t* l_p = CurrentData();
253 if ( ASDCP_SUCCESS(result) )
254 MemIOWriter::WriteUi16BE(0);
256 if ( ASDCP_SUCCESS(result) )
258 ui32_t before = Size();
259 result = Object->WriteTo(*this);
261 if ( ASDCP_SUCCESS(result) )
262 i2p<ui16_t>(ASDCP_i16_BE( Size() - before), l_p);
270 ASDCP::MXF::TLVWriter::WriteUi8(const MDDEntry& Entry, ui8_t* value)
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);
281 ASDCP::MXF::TLVWriter::WriteUi16(const MDDEntry& Entry, ui16_t* value)
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);
292 ASDCP::MXF::TLVWriter::WriteUi32(const MDDEntry& Entry, ui32_t* value)
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);
303 ASDCP::MXF::TLVWriter::WriteUi64(const MDDEntry& Entry, ui64_t* value)
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);