/*
-Copyright (c) 2005-2006, John Hurst
+Copyright (c) 2005-2016, John Hurst
All rights reserved.
Redistribution and use in source and binary forms, with or without
\brief MXF objects
*/
+#include <KM_prng.h>
+#include <KM_tai.h>
#include "MXFTypes.h"
+#include <KM_log.h>
+
+using Kumu::DefaultLogSink;
//------------------------------------------------------------------------------------------
//
//
-ASDCP::Result_t
-ASDCP::MXF::UTF16String::ReadFrom(ASDCP::MemIOReader& Reader)
-{
- const byte_t* p = Reader.Data() + Reader.Offset();
- /// cheating - for all use cases, we know the previous two bytes are the length
- m_length = ASDCP_i16_BE(cp2i<ui16_t>(p-2));
- assert(m_length % 2 == 0);
- m_length /= 2;
- assert(IdentBufferLen >= m_length);
- ui32_t i = 0;
+bool
+ASDCP::UL::operator==(const UL& rhs) const
+{
+ if ( m_Value[0] == rhs.m_Value[0] &&
+ m_Value[1] == rhs.m_Value[1] &&
+ m_Value[2] == rhs.m_Value[2] &&
+ m_Value[3] == rhs.m_Value[3] &&
+ m_Value[4] == rhs.m_Value[4] &&
+ m_Value[5] == rhs.m_Value[5] &&
+ m_Value[6] == rhs.m_Value[6] &&
+ // m_Value[7] == rhs.m_Value[7] && // version is ignored when performing lookups
+ m_Value[8] == rhs.m_Value[8] &&
+ m_Value[9] == rhs.m_Value[9] &&
+ m_Value[10] == rhs.m_Value[10] &&
+ m_Value[11] == rhs.m_Value[11] &&
+ m_Value[12] == rhs.m_Value[12] &&
+ m_Value[13] == rhs.m_Value[13] &&
+ m_Value[14] == rhs.m_Value[14] &&
+ m_Value[15] == rhs.m_Value[15]
+ )
+ return true;
- for ( i = 0; i < m_length; i++ )
- m_buffer[i] = p[(i*2)+1];
+ return false;
+}
- m_buffer[i] = 0;
+//
+bool
+ASDCP::UL::MatchIgnoreStream(const UL& rhs) const
+{
+ if ( m_Value[0] == rhs.m_Value[0] &&
+ m_Value[1] == rhs.m_Value[1] &&
+ m_Value[2] == rhs.m_Value[2] &&
+ m_Value[3] == rhs.m_Value[3] &&
+ m_Value[4] == rhs.m_Value[4] &&
+ m_Value[5] == rhs.m_Value[5] &&
+ m_Value[6] == rhs.m_Value[6] &&
+ // m_Value[7] == rhs.m_Value[7] && // version is ignored when performing lookups
+ m_Value[8] == rhs.m_Value[8] &&
+ m_Value[9] == rhs.m_Value[9] &&
+ m_Value[10] == rhs.m_Value[10] &&
+ m_Value[11] == rhs.m_Value[11] &&
+ m_Value[12] == rhs.m_Value[12] &&
+ m_Value[13] == rhs.m_Value[13] &&
+ m_Value[14] == rhs.m_Value[14]
+ // m_Value[15] == rhs.m_Value[15] // ignore stream number
+ )
+ return true;
- Reader.SkipOffset(m_length*2);
- return RESULT_OK;
+ return false;
}
//
-ASDCP::Result_t
-ASDCP::MXF::UTF16String::WriteTo(ASDCP::MemIOWriter& Writer)
+bool
+ASDCP::UL::MatchExact(const UL& rhs) const
{
- byte_t* p = Writer.Data() + Writer.Size();
- ui32_t i = 0;
- m_length = strlen(m_buffer);
- memset(p, 0, m_length*2);
+ if ( m_Value[0] == rhs.m_Value[0] &&
+ m_Value[1] == rhs.m_Value[1] &&
+ m_Value[2] == rhs.m_Value[2] &&
+ m_Value[3] == rhs.m_Value[3] &&
+ m_Value[4] == rhs.m_Value[4] &&
+ m_Value[5] == rhs.m_Value[5] &&
+ m_Value[6] == rhs.m_Value[6] &&
+ m_Value[7] == rhs.m_Value[7] &&
+ m_Value[8] == rhs.m_Value[8] &&
+ m_Value[9] == rhs.m_Value[9] &&
+ m_Value[10] == rhs.m_Value[10] &&
+ m_Value[11] == rhs.m_Value[11] &&
+ m_Value[12] == rhs.m_Value[12] &&
+ m_Value[13] == rhs.m_Value[13] &&
+ m_Value[14] == rhs.m_Value[14] &&
+ m_Value[15] == rhs.m_Value[15]
+ )
+ return true;
- for ( i = 0; i < m_length; i++ )
- p[(i*2)+1] = m_buffer[i];
+ return false;
+}
- m_buffer[i] = 0;
+const char*
+ASDCP::UL::EncodeString(char* str_buf, ui32_t buf_len) const
+{
+ if ( buf_len > 38 ) // room for dotted notation?
+ {
+ snprintf(str_buf, buf_len,
+ "%02x%02x%02x%02x.%02x%02x%02x%02x.%02x%02x%02x%02x.%02x%02x%02x%02x",
+ m_Value[0], m_Value[1], m_Value[2], m_Value[3],
+ m_Value[4], m_Value[5], m_Value[6], m_Value[7],
+ m_Value[8], m_Value[9], m_Value[10], m_Value[11],
+ m_Value[12], m_Value[13], m_Value[14], m_Value[15]
+ );
+
+ return str_buf;
+ }
+ else if ( buf_len > 32 ) // room for compact?
+ {
+ snprintf(str_buf, buf_len,
+ "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
+ m_Value[0], m_Value[1], m_Value[2], m_Value[3],
+ m_Value[4], m_Value[5], m_Value[6], m_Value[7],
+ m_Value[8], m_Value[9], m_Value[10], m_Value[11],
+ m_Value[12], m_Value[13], m_Value[14], m_Value[15]
+ );
+
+ return str_buf;
+ }
- Writer.AddOffset(m_length*2);
- return RESULT_OK;
+ return 0;
+}
+
+//
+void
+ASDCP::UMID::MakeUMID(int Type)
+{
+ UUID AssetID;
+ Kumu::GenRandomValue(AssetID);
+ MakeUMID(Type, AssetID);
+}
+
+//
+void
+ASDCP::UMID::MakeUMID(int Type, const UUID& AssetID)
+{
+ // Set the non-varying base of the UMID
+ static const byte_t UMIDBase[10] = { 0x06, 0x0a, 0x2b, 0x34, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 };
+ memcpy(m_Value, UMIDBase, 10);
+ m_Value[10] = Type; // Material Type
+ m_Value[12] = 0x13; // length
+
+ // preserved for compatibility with mfxlib
+ if( Type > 4 ) m_Value[7] = 5;
+ m_Value[11] = 0x20; // UUID/UL method, number gen undefined
+
+ // Instance Number
+ m_Value[13] = m_Value[14] = m_Value[15] = 0;
+
+ memcpy(&m_Value[16], AssetID.Value(), AssetID.Size());
+ m_HasValue = true;
}
+// Write the UMID value to the given buffer in the form
+// [00000000.0000.0000.00000000],00,00,00,00,00000000.0000.0000.00000000.00000000]
+// or
+// [00000000.0000.0000.00000000],00,00,00,00,00000000-0000-0000-0000-000000000000]
+// returns 0 if the buffer is smaller than DateTimeLen
+const char*
+ASDCP::UMID::EncodeString(char* str_buf, ui32_t buf_len) const
+{
+ assert(str_buf);
+
+ snprintf(str_buf, buf_len, "[%02x%02x%02x%02x.%02x%02x%02x%02x.%02x%02x%02x%02x],%02x,%02x,%02x,%02x,",
+ m_Value[0], m_Value[1], m_Value[2], m_Value[3],
+ m_Value[4], m_Value[5], m_Value[6], m_Value[7],
+ m_Value[8], m_Value[9], m_Value[10], m_Value[11],
+ m_Value[12], m_Value[13], m_Value[14], m_Value[15]
+ );
+
+ ui32_t offset = strlen(str_buf);
+
+ if ( ( m_Value[8] & 0x80 ) == 0 )
+ {
+ // half-swapped UL, use [bbaa9988.ddcc.ffee.00010203.04050607]
+ snprintf(str_buf + offset, buf_len - offset,
+ "[%02x%02x%02x%02x.%02x%02x%02x%02x.%02x%02x%02x%02x.%02x%02x%02x%02x]",
+ m_Value[24], m_Value[25], m_Value[26], m_Value[27],
+ m_Value[28], m_Value[29], m_Value[30], m_Value[31],
+ m_Value[16], m_Value[17], m_Value[18], m_Value[19],
+ m_Value[20], m_Value[21], m_Value[22], m_Value[23]
+ );
+ }
+ else
+ {
+ // UUID, use {00112233-4455-6677-8899-aabbccddeeff}
+ snprintf(str_buf + offset, buf_len - offset,
+ "{%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
+ m_Value[16], m_Value[17], m_Value[18], m_Value[19],
+ m_Value[20], m_Value[21], m_Value[22], m_Value[23],
+ m_Value[24], m_Value[25], m_Value[26], m_Value[27],
+ m_Value[28], m_Value[29], m_Value[30], m_Value[31]
+ );
+ }
+
+ return str_buf;
+}
+
//------------------------------------------------------------------------------------------
//
-ASDCP::MXF::TLVReader::TLVReader(const byte_t* p, ui32_t c, IPrimerLookup* PrimerLookup) :
- MemIOReader(p, c), m_Lookup(PrimerLookup)
+//
+ASDCP::MXF::UTF16String::UTF16String(const char* sz)
{
- Result_t result = RESULT_OK;
+ if ( sz != 0 && *sz != 0 )
+ {
+ this->assign(sz);
+ }
+}
- while ( Remainder() > 0 && ASDCP_SUCCESS(result) )
+ASDCP::MXF::UTF16String::UTF16String(const std::string& str)
+{
+ this->assign(str);
+}
+
+//
+const ASDCP::MXF::UTF16String&
+ASDCP::MXF::UTF16String::operator=(const char* sz)
+{
+ if ( sz == 0 || *sz == 0 )
+ erase();
+
+ else
+ this->assign(sz);
+
+ return *this;
+}
+
+//
+const ASDCP::MXF::UTF16String&
+ASDCP::MXF::UTF16String::operator=(const std::string& str)
+{
+ this->assign(str);
+ return *this;
+}
+
+//
+const char*
+ASDCP::MXF::UTF16String::EncodeString(char* str_buf, ui32_t buf_len) const
+{
+ ui32_t write_len = Kumu::xmin(buf_len - 1, (ui32_t)size());
+ strncpy(str_buf, c_str(), write_len);
+ str_buf[write_len] = 0;
+ return str_buf;
+}
+
+//
+bool
+ASDCP::MXF::UTF16String::Unarchive(Kumu::MemIOReader* Reader)
+{
+ erase();
+ const ui16_t* p = (ui16_t*)Reader->CurrentData();
+ ui32_t length = Reader->Remainder() / 2;
+ char mb_buf[MB_LEN_MAX];
+
+ mbstate_t ps;
+ memset(&ps, 0, sizeof(mbstate_t));
+
+ for ( ui32_t i = 0; i < length; i++ )
{
- TagValue Tag;
- ui16_t pkt_len = 0;
+ int count = wcrtomb(mb_buf, KM_i16_BE(p[i]), &ps);
- result = MemIOReader::ReadUi8(&Tag.a);
+ if ( count == -1 )
+ {
+ DefaultLogSink().Error("Unable to decode wide character 0x%04hx\n", p[i]);
+ return false;
+ }
- if ( ASDCP_SUCCESS(result) )
- result = MemIOReader::ReadUi8(&Tag.b);
+ assert(count <= MB_LEN_MAX);
+ mb_buf[count] = 0;
+ this->append(mb_buf);
+ }
- if ( ASDCP_SUCCESS(result) )
- result = MemIOReader::ReadUi16BE(&pkt_len);
+ Reader->SkipOffset(length*2);
+ return true;
+}
- if ( ASDCP_SUCCESS(result) )
+//
+bool
+ASDCP::MXF::UTF16String::Archive(Kumu::MemIOWriter* Writer) const
+{
+ if ( size() > IdentBufferLen )
+ {
+ DefaultLogSink().Error("String length exceeds maximum %u bytes\n", IdentBufferLen);
+ return false;
+ }
+
+ const char* mbp = c_str();
+ wchar_t wcp;
+ ui32_t remainder = size();
+ ui32_t length = size();
+ ui32_t i = 0;
+
+ mbstate_t ps;
+ memset(&ps, 0, sizeof(mbstate_t));
+
+ while ( i < length )
+ {
+ int count = mbrtowc(&wcp, mbp+i, remainder, &ps);
+
+ if ( count == -1 )
{
- m_ElementMap.insert(TagMap::value_type(Tag, ItemInfo(m_size, pkt_len)));
- result = SkipOffset(pkt_len);
+ DefaultLogSink().Error("Error decoding multi-byte sequence starting at offset %u\n", i);
+ return false;
}
-
- if ( ASDCP_FAILURE(result) )
+ else if ( count == 0 )
{
- DefaultLogSink().Error("Malformed Set\n");
- m_ElementMap.clear();
break;
}
+
+ bool result = Writer->WriteUi16BE((ui16_t)wcp);
+
+ if ( result == false )
+ {
+ DefaultLogSink().Error("No more space in memory IO writer\n");
+ return false;
+ }
+
+ i += count;
+ remainder -= count;
+ }
+
+ return true;
+}
+
+//------------------------------------------------------------------------------------------
+//
+
+//
+ASDCP::MXF::ISO8String::ISO8String(const char* sz)
+{
+ if ( sz != 0 && *sz != 0 )
+ {
+ this->assign(sz);
+ }
+}
+
+ASDCP::MXF::ISO8String::ISO8String(const std::string& str)
+{
+ this->assign(str);
+}
+
+
+//
+const ASDCP::MXF::ISO8String&
+ASDCP::MXF::ISO8String::operator=(const char* sz)
+{
+ if ( sz == 0 || *sz == 0 )
+ erase();
+
+ else
+ this->assign(sz);
+
+ return *this;
+}
+
+//
+const ASDCP::MXF::ISO8String&
+ASDCP::MXF::ISO8String::operator=(const std::string& str)
+{
+ this->assign(str);
+ return *this;
+}
+
+//
+const char*
+ASDCP::MXF::ISO8String::EncodeString(char* str_buf, ui32_t buf_len) const
+{
+ ui32_t write_len = Kumu::xmin(buf_len - 1, (ui32_t)size());
+ strncpy(str_buf, c_str(), write_len);
+ str_buf[write_len] = 0;
+ return str_buf;
+}
+
+//
+bool
+ASDCP::MXF::ISO8String::Unarchive(Kumu::MemIOReader* Reader)
+{
+ assign((char*)Reader->CurrentData(), Reader->Remainder());
+ return true;
+}
+
+//
+bool
+ASDCP::MXF::ISO8String::Archive(Kumu::MemIOWriter* Writer) const
+{
+ if ( size() > IdentBufferLen )
+ {
+ DefaultLogSink().Error("String length exceeds maximum %u bytes\n", IdentBufferLen);
+ return false;
+ }
+
+ return Writer->WriteRaw((const byte_t*)c_str(), size());
+}
+
+//------------------------------------------------------------------------------------------
+//
+
+ASDCP::MXF::TLVReader::TLVReader(const byte_t* p, ui32_t c, IPrimerLookup* PrimerLookup) :
+ MemIOReader(p, c), m_Lookup(PrimerLookup)
+{
+ Result_t result = RESULT_OK;
+
+ while ( Remainder() > 0 && ASDCP_SUCCESS(result) )
+ {
+ TagValue Tag;
+ ui16_t pkt_len = 0;
+
+ if ( MemIOReader::ReadUi8(&Tag.a) )
+ if ( MemIOReader::ReadUi8(&Tag.b) )
+ if ( MemIOReader::ReadUi16BE(&pkt_len) )
+ {
+ m_ElementMap.insert(TagMap::value_type(Tag, ItemInfo(m_size, pkt_len)));
+ if ( SkipOffset(pkt_len) )
+ continue;;
+ }
+
+ DefaultLogSink().Error("Malformed Set\n");
+ m_ElementMap.clear();
+ result = RESULT_KLV_CODING(__LINE__, __FILE__);
}
}
{
if ( m_Lookup == 0 )
{
- fprintf(stderr, "No Lookup service\n");
+ DefaultLogSink().Error("No Lookup service\n");
return false;
}
{
if ( Entry.tag.a == 0 )
{
- DefaultLogSink().Info("No such UL in this TL list: %s (%02x %02x)\n",
- Entry.name, Entry.tag.a, Entry.tag.b);
+ // DefaultLogSink().Debug("No such UL in this TL list: %s (%02x %02x)\n",
+ // Entry.name, Entry.tag.a, Entry.tag.b);
return false;
}
return true;
}
- DefaultLogSink().Info("Not Found (%02x %02x): %s\n", TmpTag.a, TmpTag.b, Entry.name);
+ // DefaultLogSink().Debug("Not Found (%02x %02x): %s\n", TmpTag.a, TmpTag.b, Entry.name);
return false;
}
//
ASDCP::Result_t
-ASDCP::MXF::TLVReader::ReadObject(const MDDEntry& Entry, IArchive* Object)
+ASDCP::MXF::TLVReader::ReadObject(const MDDEntry& Entry, Kumu::IArchive* Object)
{
ASDCP_TEST_NULL(Object);
if ( FindTL(Entry) )
- return Object->ReadFrom(*this);
+ {
+ if ( m_size < m_capacity ) // don't try to unarchive an empty item
+ {
+ // TODO: carry on if uachive fails
+ return Object->Unarchive(this) ? RESULT_OK : RESULT_FALSE(__LINE__, __FILE__);
+ }
+ }
return RESULT_FALSE;
}
ASDCP_TEST_NULL(value);
if ( FindTL(Entry) )
- return MemIOReader::ReadUi8(value);
+ return MemIOReader::ReadUi8(value) ? RESULT_OK : RESULT_FALSE(__LINE__, __FILE__);
return RESULT_FALSE;
}
ASDCP_TEST_NULL(value);
if ( FindTL(Entry) )
- return MemIOReader::ReadUi16BE(value);
+ return MemIOReader::ReadUi16BE(value) ? RESULT_OK : RESULT_FALSE(__LINE__, __FILE__);
return RESULT_FALSE;
}
ASDCP_TEST_NULL(value);
if ( FindTL(Entry) )
- return MemIOReader::ReadUi32BE(value);
+ return MemIOReader::ReadUi32BE(value) ? RESULT_OK : RESULT_FALSE(__LINE__, __FILE__);
return RESULT_FALSE;
}
ASDCP_TEST_NULL(value);
if ( FindTL(Entry) )
- return MemIOReader::ReadUi64BE(value);
+ return MemIOReader::ReadUi64BE(value) ? RESULT_OK : RESULT_FALSE(__LINE__, __FILE__);
return RESULT_FALSE;
}
ASDCP::Result_t
ASDCP::MXF::TLVWriter::WriteTag(const MDDEntry& Entry)
{
- TagValue TmpTag;
-
if ( m_Lookup == 0 )
{
- DefaultLogSink().Error("No Primer object available\n");
+ DefaultLogSink().Error("No Primer object available.\n");
return RESULT_FAIL;
}
- if ( m_Lookup->InsertTag(Entry.ul, TmpTag) != RESULT_OK )
+ TagValue TmpTag;
+
+ if ( m_Lookup->InsertTag(Entry, TmpTag) != RESULT_OK )
{
DefaultLogSink().Error("No tag for entry %s\n", Entry.name);
return RESULT_FAIL;
}
- Result_t result = MemIOWriter::WriteUi8(TmpTag.a);
- if ( ASDCP_SUCCESS(result) ) MemIOWriter::WriteUi8(TmpTag.b);
-
- return result;
+ if ( ! MemIOWriter::WriteUi8(TmpTag.a) ) return RESULT_KLV_CODING(__LINE__, __FILE__);
+ if ( ! MemIOWriter::WriteUi8(TmpTag.b) ) return RESULT_KLV_CODING(__LINE__, __FILE__);
+ return RESULT_OK;
}
//
ASDCP::Result_t
-ASDCP::MXF::TLVWriter::WriteObject(const MDDEntry& Entry, IArchive* Object)
+ASDCP::MXF::TLVWriter::WriteObject(const MDDEntry& Entry, Kumu::IArchive* Object)
{
ASDCP_TEST_NULL(Object);
- Result_t result = WriteTag(Entry);
- // write a temp length
- byte_t* l_p = CurrentData();
+ if ( Entry.optional && ! Object->HasValue() )
+ return RESULT_OK;
- if ( ASDCP_SUCCESS(result) )
- MemIOWriter::WriteUi16BE(0);
+ Result_t result = WriteTag(Entry);
if ( ASDCP_SUCCESS(result) )
{
- ui32_t before = Size();
- result = Object->WriteTo(*this);
+ // write a temp length
+ byte_t* l_p = CurrentData();
+
+ if ( ! MemIOWriter::WriteUi16BE(0) ) return RESULT_KLV_CODING(__LINE__, __FILE__);
- if ( ASDCP_SUCCESS(result) )
- i2p<ui16_t>(ASDCP_i16_BE( Size() - before), l_p);
+ ui32_t before = Length();
+ if ( ! Object->Archive(this) ) return RESULT_KLV_CODING(__LINE__, __FILE__);
+ if ( (Length() - before) > 0xffffL ) return RESULT_KLV_CODING(__LINE__, __FILE__);
+ Kumu::i2p<ui16_t>(KM_i16_BE(Length() - before), l_p);
}
return result;
{
ASDCP_TEST_NULL(value);
Result_t result = WriteTag(Entry);
- if ( ASDCP_SUCCESS(result) ) MemIOWriter::WriteUi16BE(sizeof(ui8_t));
- if ( ASDCP_SUCCESS(result) ) MemIOWriter::WriteUi8(*value);
+
+ if ( ASDCP_SUCCESS(result) )
+ {
+ if ( ! MemIOWriter::WriteUi16BE(sizeof(ui8_t)) ) return RESULT_KLV_CODING(__LINE__, __FILE__);
+ if ( ! MemIOWriter::WriteUi8(*value) ) return RESULT_KLV_CODING(__LINE__, __FILE__);
+ }
+
return result;
}
{
ASDCP_TEST_NULL(value);
Result_t result = WriteTag(Entry);
- if ( ASDCP_SUCCESS(result) ) MemIOWriter::WriteUi16BE(sizeof(ui16_t));
- if ( ASDCP_SUCCESS(result) ) MemIOWriter::WriteUi8(*value);
+
+ if ( KM_SUCCESS(result) )
+ {
+ if ( ! MemIOWriter::WriteUi16BE(sizeof(ui16_t)) ) return RESULT_KLV_CODING(__LINE__, __FILE__);
+ if ( ! MemIOWriter::WriteUi16BE(*value) ) return RESULT_KLV_CODING(__LINE__, __FILE__);
+ }
+
return result;
}
{
ASDCP_TEST_NULL(value);
Result_t result = WriteTag(Entry);
- if ( ASDCP_SUCCESS(result) ) MemIOWriter::WriteUi16BE(sizeof(ui32_t));
- if ( ASDCP_SUCCESS(result) ) MemIOWriter::WriteUi8(*value);
+
+ if ( KM_SUCCESS(result) )
+ {
+ if ( ! MemIOWriter::WriteUi16BE(sizeof(ui32_t)) ) return RESULT_KLV_CODING(__LINE__, __FILE__);
+ if ( ! MemIOWriter::WriteUi32BE(*value) ) return RESULT_KLV_CODING(__LINE__, __FILE__);
+ }
+
return result;
}
{
ASDCP_TEST_NULL(value);
Result_t result = WriteTag(Entry);
- if ( ASDCP_SUCCESS(result) ) MemIOWriter::WriteUi16BE(sizeof(ui64_t));
- if ( ASDCP_SUCCESS(result) ) MemIOWriter::WriteUi8(*value);
+
+ if ( KM_SUCCESS(result) )
+ {
+ if ( ! MemIOWriter::WriteUi16BE(sizeof(ui64_t)) ) return RESULT_KLV_CODING(__LINE__, __FILE__);
+ if ( ! MemIOWriter::WriteUi64BE(*value) ) return RESULT_KLV_CODING(__LINE__, __FILE__);
+ }
+
return result;
}
+
+//----------------------------------------------------------------------------------------------------
+//
+
+
+ASDCP::MXF::RGBALayout::RGBALayout()
+{
+ memset(m_value, 0, RGBAValueLength);
+}
+
+ASDCP::MXF::RGBALayout::RGBALayout(const byte_t* value)
+{
+ memcpy(m_value, value, RGBAValueLength);
+}
+
+ASDCP::MXF::RGBALayout::~RGBALayout()
+{
+}
+
+static char
+get_char_for_code(byte_t c)
+{
+ for ( int i = 0; ASDCP::MXF::RGBALayoutTable[i].code != 0; ++i )
+ {
+ if ( ASDCP::MXF::RGBALayoutTable[i].code == c )
+ {
+ return ASDCP::MXF::RGBALayoutTable[i].symbol;
+ }
+ }
+
+ return '_';
+}
+
+//
+const char*
+ASDCP::MXF::RGBALayout::EncodeString(char* buf, ui32_t buf_len) const
+{
+ std::string tmp_str;
+ char tmp_buf[64];
+
+ for ( int i = 0; i < RGBAValueLength && m_value[i] != 0; i += 2 )
+ {
+ snprintf(tmp_buf, 64, "%c(%d)", get_char_for_code(m_value[i]), m_value[i+1]);
+
+ if ( ! tmp_str.empty() )
+ {
+ tmp_str += " ";
+ }
+
+ tmp_str += tmp_buf;
+ }
+
+ assert(tmp_str.size() < buf_len);
+ strncpy(buf, tmp_str.c_str(), tmp_str.size());
+ return buf;
+}
+
+
+//----------------------------------------------------------------------------------------------------
+//
+
+ASDCP::MXF::Raw::Raw()
+{
+ Capacity(256);
+}
+
+ASDCP::MXF::Raw::~Raw()
+{
+}
+
+//
+bool
+ASDCP::MXF::Raw::Unarchive(Kumu::MemIOReader* Reader)
+{
+ ui32_t payload_size = Reader->Remainder();
+ if ( payload_size == 0 ) return false;
+ if ( KM_FAILURE(Capacity(payload_size)) ) return false;
+
+ memcpy(Data(), Reader->CurrentData(), payload_size);
+ Length(payload_size);
+ return true;
+}
+
+//
+bool
+ASDCP::MXF::Raw::Archive(Kumu::MemIOWriter* Writer) const
+{
+ return Writer->WriteRaw(RoData(), Length());
+}
+
+//
+const char*
+ASDCP::MXF::Raw::EncodeString(char* str_buf, ui32_t buf_len) const
+{
+ *str_buf = 0;
+ Kumu::bin2hex(RoData(), Length(), str_buf, buf_len);
+ return str_buf;
+}
+
//
-// end
+// end MXFTypes.cpp
//