Bump patch version post tag.
[asdcplib.git] / src / Index.cpp
index 9d1791ad68944074b23baacc753a78b531ea5e6d..6406e0f353a1cad4ac65300f04d245f57114cd2e 100755 (executable)
@@ -1,15 +1,46 @@
-//
-// Index.cpp
-//
+/*
+Copyright (c) 2005-2012, John Hurst
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+3. The name of the author may not be used to endorse or promote products
+   derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/*! \file    Index.cpp
+    \version $Id$
+    \brief   MXF index segment objects
+*/
 
-#include "MDD.h"
 #include "MXF.h"
+const ui32_t kl_length = ASDCP::SMPTE_UL_LENGTH + ASDCP::MXF_BER_LENGTH;
+
 
 //
-ASDCP::MXF::IndexTableSegment::IndexTableSegment() :
+ASDCP::MXF::IndexTableSegment::IndexTableSegment(const Dictionary*& d) :
+  InterchangeObject(d), m_Dict(d), RtFileOffset(0), RtEntryOffset(0),
   IndexStartPosition(0), IndexDuration(0), EditUnitByteCount(0),
-  IndexSID(0), BodySID(0), SliceCount(0), PosTableCount(0)
+  IndexSID(129), BodySID(1), SliceCount(0), PosTableCount(0)
 {
+  assert(m_Dict);
+  m_UL = m_Dict->ul(MDD_IndexTableSegment);
 }
 
 //
@@ -18,41 +49,70 @@ ASDCP::MXF::IndexTableSegment::~IndexTableSegment()
 }
 
 //
-ASDCP::Result_t
-ASDCP::MXF::IndexTableSegment::InitFromBuffer(const byte_t* p, ui32_t l)
+void
+ASDCP::MXF::IndexTableSegment::Copy(const IndexTableSegment& rhs)
 {
-  ASDCP_TEST_NULL(p);
+  InterchangeObject::Copy(rhs);
+  IndexEditRate = rhs.IndexEditRate;
+  IndexStartPosition = rhs.IndexStartPosition;
+  IndexDuration = rhs.IndexDuration;
+  EditUnitByteCount = rhs.EditUnitByteCount;
+  IndexSID = rhs.IndexSID;
+  BodySID = rhs.BodySID;
+  SliceCount = rhs.SliceCount;
+  PosTableCount = rhs.PosTableCount;
+  DeltaEntryArray = rhs.DeltaEntryArray;
+  IndexEntryArray = rhs.IndexEntryArray;
+}
 
-  Result_t result = KLVPacket::InitFromBuffer(p, l, s_MDD_Table[MDDindex_IndexTableSegment].ul);
+//
+ASDCP::Result_t
+ASDCP::MXF::IndexTableSegment::InitFromTLVSet(TLVReader& TLVSet)
+{
+  Result_t result = InterchangeObject::InitFromTLVSet(TLVSet);
+  if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadObject(OBJ_READ_ARGS(IndexTableSegmentBase, IndexEditRate));
+  if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadUi64(OBJ_READ_ARGS(IndexTableSegmentBase, IndexStartPosition));
+  if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadUi64(OBJ_READ_ARGS(IndexTableSegmentBase, IndexDuration));
+  if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadUi32(OBJ_READ_ARGS(IndexTableSegmentBase, EditUnitByteCount));
+  if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadUi32(OBJ_READ_ARGS(IndexTableSegmentBase, IndexSID));
+  if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadUi32(OBJ_READ_ARGS(EssenceContainerData, BodySID));
+  if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadUi8(OBJ_READ_ARGS(IndexTableSegmentBase, SliceCount));
+  if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadUi8(OBJ_READ_ARGS(IndexTableSegmentBase, PosTableCount));
+  if ( ASDCP_SUCCESS(result) ) result = TLVSet.ReadObject(OBJ_READ_ARGS(IndexTableSegment, DeltaEntryArray));
 
   if ( ASDCP_SUCCESS(result) )
     {
-      TLVReader MemRDR(m_ValueStart, m_ValueLength, m_Lookup);
-
-      result = MemRDR.ReadObject(OBJ_READ_ARGS(InterchangeObject, InstanceUID));
-      if ( ASDCP_SUCCESS(result) ) result = MemRDR.ReadObject(OBJ_READ_ARGS(IndexTableSegmentBase, IndexEditRate));
-      if ( ASDCP_SUCCESS(result) ) result = MemRDR.ReadUi64(OBJ_READ_ARGS(IndexTableSegmentBase, IndexStartPosition));
-      if ( ASDCP_SUCCESS(result) ) result = MemRDR.ReadUi64(OBJ_READ_ARGS(IndexTableSegmentBase, IndexDuration));
-      if ( ASDCP_SUCCESS(result) ) result = MemRDR.ReadUi32(OBJ_READ_ARGS(IndexTableSegmentBase, EditUnitByteCount));
-      if ( ASDCP_SUCCESS(result) ) result = MemRDR.ReadUi32(OBJ_READ_ARGS(IndexTableSegmentBase, IndexSID));
-      if ( ASDCP_SUCCESS(result) ) result = MemRDR.ReadUi32(OBJ_READ_ARGS(IndexTableSegmentBase, BodySID));
-      if ( ASDCP_SUCCESS(result) ) result = MemRDR.ReadUi8(OBJ_READ_ARGS(IndexTableSegmentBase, SliceCount));
-      if ( ASDCP_SUCCESS(result) ) result = MemRDR.ReadUi8(OBJ_READ_ARGS(IndexTableSegmentBase, PosTableCount));
-      if ( ASDCP_SUCCESS(result) ) result = MemRDR.ReadObject(OBJ_READ_ARGS(IndexTableSegment, DeltaEntryArray));
-      if ( ASDCP_SUCCESS(result) ) result = MemRDR.ReadObject(OBJ_READ_ARGS(IndexTableSegment, IndexEntryArray));
-    }
+      bool rc = TLVSet.FindTL(m_Dict->Type(MDD_IndexTableSegment_IndexEntryArray));
 
-  if ( ASDCP_SUCCESS(result) )
-    {
-      Batch<IndexEntry>::iterator i;
-      ui32_t offset = 0;
-      for ( i = IndexEntryArray.begin(); i != IndexEntryArray.end(); i++ )
+      if ( rc )
        {
-         if ( (*i).Flags == 0x40 )
-           offset = 0;
-
-         (*i).KeyFrameOffset = offset++;
+         ui32_t item_count, item_size;
+         ui32_t const decoder_item_size = IndexEntryArray.ItemSize();
+
+         if ( TLVSet.ReadUi32BE(&item_count) )
+           {
+             if ( TLVSet.ReadUi32BE(&item_size) )
+               {
+                 for ( ui32_t i = 0; i < item_count && rc; ++i )
+                   {
+                     IndexEntry tmp_item;
+                     rc = tmp_item.Unarchive(&TLVSet);
+
+                     if ( rc )
+                       {
+                         IndexEntryArray.push_back(tmp_item);
+
+                         if ( decoder_item_size < item_size )
+                           {
+                             TLVSet.SkipOffset(item_size - decoder_item_size);
+                           }
+                       }
+                   }
+               }
+           }
        }
+
+      result = rc ? RESULT_OK : RESULT_FALSE;
     }
 
   return result;
@@ -60,31 +120,34 @@ ASDCP::MXF::IndexTableSegment::InitFromBuffer(const byte_t* p, ui32_t l)
 
 //
 ASDCP::Result_t
-ASDCP::MXF::IndexTableSegment::WriteToBuffer(ASDCP::FrameBuffer& Buffer)
+ASDCP::MXF::IndexTableSegment::WriteToTLVSet(TLVWriter& TLVSet)
 {
-  return WriteKLToBuffer(Buffer, s_MDD_Table[MDDindex_IndexTableSegment].ul, 0);
-#if 0
-  Result_t result = KLVPacket::InitFromBuffer(p, l, s_MDD_Table[MDDindex_IndexTableSegment].ul);
+  Result_t result = InterchangeObject::WriteToTLVSet(TLVSet);
+  if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteObject(OBJ_WRITE_ARGS(IndexTableSegmentBase, IndexEditRate));
+  if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteUi64(OBJ_WRITE_ARGS(IndexTableSegmentBase, IndexStartPosition));
+  if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteUi64(OBJ_WRITE_ARGS(IndexTableSegmentBase, IndexDuration));
+  if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteUi32(OBJ_WRITE_ARGS(IndexTableSegmentBase, EditUnitByteCount));
+  if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteUi32(OBJ_WRITE_ARGS(IndexTableSegmentBase, IndexSID));
+  if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteUi32(OBJ_WRITE_ARGS(EssenceContainerData, BodySID));
+  if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteUi8(OBJ_WRITE_ARGS(IndexTableSegmentBase, SliceCount));
+  if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteUi8(OBJ_WRITE_ARGS(IndexTableSegmentBase, PosTableCount));
+  if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteObject(OBJ_WRITE_ARGS(IndexTableSegment, DeltaEntryArray));
+  if ( ASDCP_SUCCESS(result) ) result = TLVSet.WriteObject(OBJ_WRITE_ARGS(IndexTableSegment, IndexEntryArray));
+  return result;
+}
 
-  if ( ASDCP_SUCCESS(result) )
-    {
-      TLVWriter MemRDR(m_ValueStart, m_ValueLength, m_Lookup);
-
-      result = MemRDR.ReadObject(OBJ_READ_ARGS(InterchangeObject, InstanceUID));
-      if ( ASDCP_SUCCESS(result) ) result = MemRDR.ReadObject(OBJ_READ_ARGS(IndexTableSegmentBase, IndexEditRate));
-      if ( ASDCP_SUCCESS(result) ) result = MemRDR.ReadUi64(OBJ_READ_ARGS(IndexTableSegmentBase, IndexStartPosition));
-      if ( ASDCP_SUCCESS(result) ) result = MemRDR.ReadUi64(OBJ_READ_ARGS(IndexTableSegmentBase, IndexDuration));
-      if ( ASDCP_SUCCESS(result) ) result = MemRDR.ReadUi32(OBJ_READ_ARGS(IndexTableSegmentBase, EditUnitByteCount));
-      if ( ASDCP_SUCCESS(result) ) result = MemRDR.ReadUi32(OBJ_READ_ARGS(IndexTableSegmentBase, IndexSID));
-      if ( ASDCP_SUCCESS(result) ) result = MemRDR.ReadUi32(OBJ_READ_ARGS(IndexTableSegmentBase, BodySID));
-      if ( ASDCP_SUCCESS(result) ) result = MemRDR.ReadUi8(OBJ_READ_ARGS(IndexTableSegmentBase, SliceCount));
-      if ( ASDCP_SUCCESS(result) ) result = MemRDR.ReadUi8(OBJ_READ_ARGS(IndexTableSegmentBase, PosTableCount));
-      if ( ASDCP_SUCCESS(result) ) result = MemRDR.ReadObject(OBJ_READ_ARGS(IndexTableSegment, DeltaEntryArray));
-      if ( ASDCP_SUCCESS(result) ) result = MemRDR.ReadObject(OBJ_READ_ARGS(IndexTableSegment, IndexEntryArray));
-    }
+//
+ASDCP::Result_t
+ASDCP::MXF::IndexTableSegment::InitFromBuffer(const byte_t* p, ui32_t l)
+{
+  return InterchangeObject::InitFromBuffer(p, l);
+}
 
-  return result;
-#endif
+//
+ASDCP::Result_t
+ASDCP::MXF::IndexTableSegment::WriteToBuffer(ASDCP::FrameBuffer& Buffer)
+{
+  return InterchangeObject::WriteToBuffer(Buffer);
 }
 
 //
@@ -96,51 +159,67 @@ ASDCP::MXF::IndexTableSegment::Dump(FILE* stream)
   if ( stream == 0 )
     stream = stderr;
 
-  KLVPacket::Dump(stream, false);
-  fprintf(stream, "  InstanceUID        = %s\n",  InstanceUID.ToString(identbuf));
-  fprintf(stream, "  IndexEditRate      = %s\n",  IndexEditRate.ToString(identbuf));
+  InterchangeObject::Dump(stream);
+  fprintf(stream, "  IndexEditRate      = %s\n",  IndexEditRate.EncodeString(identbuf, IdentBufferLen));
   fprintf(stream, "  IndexStartPosition = %s\n",  i64sz(IndexStartPosition, identbuf));
   fprintf(stream, "  IndexDuration      = %s\n",  i64sz(IndexDuration, identbuf));
-  fprintf(stream, "  EditUnitByteCount  = %lu\n", EditUnitByteCount);
-  fprintf(stream, "  IndexSID           = %lu\n", IndexSID);
-  fprintf(stream, "  BodySID            = %lu\n", BodySID);
-  fprintf(stream, "  SliceCount         = %hu\n", SliceCount);
-  fprintf(stream, "  PosTableCount      = %hu\n", PosTableCount);
+  fprintf(stream, "  EditUnitByteCount  = %u\n",  EditUnitByteCount);
+  fprintf(stream, "  IndexSID           = %u\n",  IndexSID);
+  fprintf(stream, "  BodySID            = %u\n",  BodySID);
+  fprintf(stream, "  SliceCount         = %hhu\n", SliceCount);
+  fprintf(stream, "  PosTableCount      = %hhu\n", PosTableCount);
 
   fprintf(stream, "  DeltaEntryArray:\n");  DeltaEntryArray.Dump(stream);
-  fprintf(stream, "  IndexEntryArray:\n");  IndexEntryArray.Dump(stream);
 
-  fputs("==========================================================================\n", stream);
+  if ( IndexEntryArray.empty() )
+    {
+      fprintf(stream, "  IndexEntryArray: NO ENTRIES\n");
+    }
+  else if ( IndexEntryArray.size() < 1000 )
+    {
+      fprintf(stream, "  IndexEntryArray:\n");
+      IndexEntryArray.Dump(stream);
+    }
+  else
+    {
+      fprintf(stream, "  IndexEntryArray: %zu entries\n", IndexEntryArray.size());
+    }
 }
 
+//------------------------------------------------------------------------------------------
+//
+
 //
 const char*
-ASDCP::MXF::IndexTableSegment::DeltaEntry::ToString(char* str_buf) const
+ASDCP::MXF::IndexTableSegment::DeltaEntry::EncodeString(char* str_buf, ui32_t buf_len) const
 {
-  sprintf(str_buf, "%3i %-3hu %-3lu", PosTableIndex, Slice, ElementData);
+  snprintf(str_buf, buf_len, "%3d %-3hhu %-3u", PosTableIndex, Slice, ElementData);
   return str_buf;
 }
 
 //
-ASDCP::Result_t
-ASDCP::MXF::IndexTableSegment::DeltaEntry::ReadFrom(ASDCP::MemIOReader& Reader)
+bool
+ASDCP::MXF::IndexTableSegment::DeltaEntry::Unarchive(Kumu::MemIOReader* Reader)
 {
-  Result_t result = Reader.ReadUi8((ui8_t*)&PosTableIndex);
-  if ( ASDCP_SUCCESS(result) ) result = Reader.ReadUi8(&Slice);
-  if ( ASDCP_SUCCESS(result) ) result = Reader.ReadUi32BE(&ElementData);
-  return result;
+  if ( ! Reader->ReadUi8((ui8_t*)&PosTableIndex) ) return false;
+  if ( ! Reader->ReadUi8(&Slice) ) return false;
+  if ( ! Reader->ReadUi32BE(&ElementData) ) return false;
+  return true;
 }
 
 //
-ASDCP::Result_t
-ASDCP::MXF::IndexTableSegment::DeltaEntry::WriteTo(ASDCP::MemIOWriter& Writer)
+bool
+ASDCP::MXF::IndexTableSegment::DeltaEntry::Archive(Kumu::MemIOWriter* Writer) const
 {
-  Result_t result = Writer.WriteUi8((ui8_t)PosTableIndex);
-  if ( ASDCP_SUCCESS(result) ) result = Writer.WriteUi8(Slice);
-  if ( ASDCP_SUCCESS(result) ) result = Writer.WriteUi32BE(ElementData);
-  return result;
+  if ( ! Writer->WriteUi8((ui8_t)PosTableIndex) ) return false;
+  if ( ! Writer->WriteUi8(Slice) ) return false;
+  if ( ! Writer->WriteUi32BE(ElementData) ) return false;
+  return true;
 }
 
+//------------------------------------------------------------------------------------------
+//
+
 // Flags:
 // Bit 7: Random Access
 // Bit 6: Sequence Header
@@ -155,45 +234,45 @@ ASDCP::MXF::IndexTableSegment::DeltaEntry::WriteTo(ASDCP::MemIOWriter& Writer)
 
 //
 const char*
-ASDCP::MXF::IndexTableSegment::IndexEntry::ToString(char* str_buf) const
+ASDCP::MXF::IndexTableSegment::IndexEntry::EncodeString(char* str_buf, ui32_t buf_len) const
 {
   char intbuf[IntBufferLen];
   char txt_flags[6];
-  txt_flags[5] = 0;
 
   txt_flags[0] = ( (Flags & 0x80) != 0 ) ? 'r' : ' ';
   txt_flags[1] = ( (Flags & 0x40) != 0 ) ? 's' : ' ';
   txt_flags[2] = ( (Flags & 0x20) != 0 ) ? 'f' : ' ';
   txt_flags[3] = ( (Flags & 0x10) != 0 ) ? 'b' : ' ';
   txt_flags[4] = ( (Flags & 0x0f) == 3 ) ? 'B' : ( (Flags & 0x0f) == 2 ) ? 'P' : 'I';
+  txt_flags[5] = 0;
 
-  sprintf(str_buf, "%3i %-3hu %s %s",
-         TemporalOffset, KeyFrameOffset, txt_flags,
-         i64sz(StreamOffset, intbuf));
+  snprintf(str_buf, buf_len, "%3i %-3hhu %s %s",
+          TemporalOffset, KeyFrameOffset, txt_flags,
+          i64sz(StreamOffset, intbuf));
 
   return str_buf;
 }
 
 //
-ASDCP::Result_t
-ASDCP::MXF::IndexTableSegment::IndexEntry::ReadFrom(ASDCP::MemIOReader& Reader)
+bool
+ASDCP::MXF::IndexTableSegment::IndexEntry::Unarchive(Kumu::MemIOReader* Reader)
 {
-  Result_t result = Reader.ReadUi8((ui8_t*)&TemporalOffset);
-  if ( ASDCP_SUCCESS(result) ) result = Reader.ReadUi8((ui8_t*)&KeyFrameOffset);
-  if ( ASDCP_SUCCESS(result) ) result = Reader.ReadUi8(&Flags);
-  if ( ASDCP_SUCCESS(result) ) result = Reader.ReadUi64BE(&StreamOffset);
-  return result;
+  if ( ! Reader->ReadUi8((ui8_t*)&TemporalOffset) ) return false;
+  if ( ! Reader->ReadUi8((ui8_t*)&KeyFrameOffset) ) return false;
+  if ( ! Reader->ReadUi8(&Flags) ) return false;
+  if ( ! Reader->ReadUi64BE(&StreamOffset) ) return false;
+  return true;
 }
 
 //
-ASDCP::Result_t
-ASDCP::MXF::IndexTableSegment::IndexEntry::WriteTo(ASDCP::MemIOWriter& Writer)
+bool
+ASDCP::MXF::IndexTableSegment::IndexEntry::Archive(Kumu::MemIOWriter* Writer) const
 {
-  Result_t result = Writer.WriteUi8((ui8_t)TemporalOffset);
-  if ( ASDCP_SUCCESS(result) ) result = Writer.WriteUi8((ui8_t)KeyFrameOffset);
-  if ( ASDCP_SUCCESS(result) ) result = Writer.WriteUi8(Flags);
-  if ( ASDCP_SUCCESS(result) ) result = Writer.WriteUi64BE(StreamOffset);
-  return result;
+  if ( ! Writer->WriteUi8((ui8_t)TemporalOffset) ) return false;
+  if ( ! Writer->WriteUi8((ui8_t)KeyFrameOffset) ) return false;
+  if ( ! Writer->WriteUi8(Flags) ) return false;
+  if ( ! Writer->WriteUi64BE(StreamOffset) ) return false;
+  return true;
 }