format string fixes
[asdcplib.git] / src / h__Reader.cpp
index 95c510c6e93b8f1ea586b06380cde67c78811b26..268f3086624f74e038484cd68bfdaea2cb2bccef 100755 (executable)
@@ -1,5 +1,5 @@
 /*
-Copyright (c) 2004-2005, John Hurst
+Copyright (c) 2004-2006, John Hurst
 All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
@@ -56,10 +56,19 @@ ASDCP::h__Reader::Close()
 
 //
 Result_t
-ASDCP::h__Reader::InitInfo(WriterInfo& Info)
+ASDCP::h__Reader::InitInfo()
 {
   InterchangeObject* Object;
 
+  m_Info.LabelSetType = LS_MXF_UNKNOWN;
+  UL OPAtomUL(Dict::ul(MDD_OPAtom));
+  UL Interop_OPAtomUL(Dict::ul(MDD_MXFInterop_OPAtom));
+
+  if ( m_HeaderPart.OperationalPattern == Interop_OPAtomUL )
+    m_Info.LabelSetType = LS_MXF_INTEROP;
+  else if ( m_HeaderPart.OperationalPattern == OPAtomUL )
+    m_Info.LabelSetType = LS_MXF_SMPTE;
+
   // Identification
   Result_t result = m_HeaderPart.GetMDObjectByType(OBJ_TYPE_ARGS(Identification), &Object);
 
@@ -73,7 +82,7 @@ ASDCP::h__Reader::InitInfo(WriterInfo& Info)
   if( ASDCP_SUCCESS(result) )
     {
       SourcePackage* SP = (SourcePackage*)Object;
-      memcpy(Info.AssetUUID, SP->PackageUID.Value() + 16, UUIDlen);
+      memcpy(m_Info.AssetUUID, SP->PackageUID.Value() + 16, UUIDlen);
     }
 
   // optional CryptographicContext
@@ -99,32 +108,18 @@ ASDCP::h__Reader::OpenMXFRead(const char* filename)
   if ( ASDCP_SUCCESS(result) )
     result = m_HeaderPart.InitFromFile(m_File);
 
-  // OP-Atom states that there will be either two or three partitions,
-  // one closed header and one closed footer with an optional body
-  ui32_t test_s = m_HeaderPart.m_RIP.PairArray.size();
-
-  if ( test_s < 2 || test_s > 3 )
-    {
-      DefaultLogSink().Error("RIP count is not 2 or 3: %lu\n", test_s);
-      return RESULT_FORMAT;
-    }
-
-  // it really OP-Atom?
-  //  MDObject* OpPattern = GetMDObjectByType("OperationalPattern");
-  // TODO: check the label
-
   // if this is a three partition file, go to the body
   // partition and read off the partition pack
-  if ( test_s == 3 )
+  if ( m_HeaderPart.m_RIP.PairArray.size() == 3 )
     {
-      DefaultLogSink().Error("RIP count is 3: must write code...\n");
-      return RESULT_FORMAT;
+      Array<RIP::Pair>::iterator r_i = m_HeaderPart.m_RIP.PairArray.begin();
+      r_i++;
+      m_File.Seek((*r_i).ByteOffset);
+
+      result = m_BodyPart.InitFromFile(m_File);
     }
-  // TODO: check the partition pack to make sure it is
-  //       really a body with a single essence container
 
   m_EssenceStart = m_File.Tell();
-
   return RESULT_OK;
 }
 
@@ -150,6 +145,36 @@ ASDCP::h__Reader::InitMXFIndex()
   return result;
 }
 
+//
+class KLReader : public ASDCP::KLVPacket
+{
+  ASDCP_NO_COPY_CONSTRUCT(KLReader);
+  byte_t m_KeyBuf[32];
+
+public:
+  KLReader() {}
+  ~KLReader() {}
+
+  inline const byte_t* Key() { return m_KeyBuf; }
+  inline const ui64_t  Length() { return m_ValueLength; }
+  inline const ui64_t  KLLength() { return m_KLLength; }
+
+  Result_t ReadKLFromFile(Kumu::FileReader& Reader)
+  {
+    ui32_t read_count;
+    ui32_t header_length = SMPTE_UL_LENGTH + MXF_BER_LENGTH;
+    Result_t result = Reader.Read(m_KeyBuf, header_length, &read_count);
+
+    if ( read_count != header_length )
+      return RESULT_READFAIL;
+  
+    if ( ASDCP_SUCCESS(result) )
+      result = InitFromBuffer(m_KeyBuf, header_length);
+
+    return result;
+  }
+};
+
 
 // standard method of reading a plaintext or encrypted frame
 Result_t
@@ -167,8 +192,8 @@ ASDCP::h__Reader::ReadEKLVPacket(ui32_t FrameNum, ASDCP::FrameBuffer& FrameBuf,
 
   // get frame position and go read the frame's key and length
   Result_t result = RESULT_OK;
-  ASDCP::KLVReader Reader;
-  ASDCP::fpos_t FilePosition = m_EssenceStart + TmpEntry.StreamOffset;
+  KLReader Reader;
+  Kumu::fpos_t FilePosition = m_EssenceStart + TmpEntry.StreamOffset;
 
   if ( FilePosition != m_LastPosition )
     {
@@ -183,12 +208,11 @@ ASDCP::h__Reader::ReadEKLVPacket(ui32_t FrameNum, ASDCP::FrameBuffer& FrameBuf,
     return result;
 
   UL Key(Reader.Key());
-  UL InteropRef(CryptEssenceUL_Data);
-  UL SMPTERef(CryptEssenceUL_Data);
   ui64_t PacketLength = Reader.Length();
   m_LastPosition = m_LastPosition + Reader.KLLength() + PacketLength;
 
-  if ( Key == InteropRef || Key == SMPTERef )
+  if ( memcmp(Key.Value(), Dict::ul(MDD_CryptEssence), Key.Size() - 1) == 0  // ignore the stream numbers
+       || memcmp(Key.Value(), Dict::ul(MDD_MXFInterop_CryptEssence), Key.Size() - 1) == 0 )
     {
       if ( ! m_Info.EncryptedEssence )
        {
@@ -216,7 +240,7 @@ ASDCP::h__Reader::ReadEKLVPacket(ui32_t FrameNum, ASDCP::FrameBuffer& FrameBuf,
       byte_t* ess_p = m_CtFrameBuf.Data();
 
       // read context ID length
-      if ( ! read_test_BER(&ess_p, UUIDlen) )
+      if ( ! Kumu::read_test_BER(&ess_p, UUIDlen) )
        return RESULT_FORMAT;
 
       // test the context ID
@@ -228,24 +252,34 @@ ASDCP::h__Reader::ReadEKLVPacket(ui32_t FrameNum, ASDCP::FrameBuffer& FrameBuf,
       ess_p += UUIDlen;
 
       // read PlaintextOffset length
-      if ( ! read_test_BER(&ess_p, sizeof(ui64_t)) )
+      if ( ! Kumu::read_test_BER(&ess_p, sizeof(ui64_t)) )
        return RESULT_FORMAT;
 
-      ui32_t PlaintextOffset = (ui32_t)ASDCP_i64_BE(cp2i<ui64_t>(ess_p));
+      ui32_t PlaintextOffset = (ui32_t)KM_i64_BE(Kumu::cp2i<ui64_t>(ess_p));
       ess_p += sizeof(ui64_t);
 
       // read essence UL length
-      if ( ! read_test_BER(&ess_p, klv_key_size) )
+      if ( ! Kumu::read_test_BER(&ess_p, SMPTE_UL_LENGTH) )
        return RESULT_FORMAT;
 
-      // TODO: test essence UL
-      ess_p += klv_key_size;
+      // test essence UL
+      if ( memcmp(ess_p, EssenceUL, SMPTE_UL_LENGTH - 1) != 0 ) // ignore the stream number
+       {
+         char strbuf[IntBufferLen];
+         const MDDEntry* Entry = Dict::FindUL(Key.Value());
+         if ( Entry == 0 )
+           DefaultLogSink().Warn("Unexpected Essence UL found: %s.\n", Key.EncodeString(strbuf, IntBufferLen));
+         else
+           DefaultLogSink().Warn("Unexpected Essence UL found: %s.\n", Entry->name);
+         return RESULT_FORMAT;
+       }
+      ess_p += SMPTE_UL_LENGTH;
 
       // read SourceLength length
-      if ( ! read_test_BER(&ess_p, sizeof(ui64_t)) )
+      if ( ! Kumu::read_test_BER(&ess_p, sizeof(ui64_t)) )
        return RESULT_FORMAT;
 
-      ui32_t SourceLength = (ui32_t)ASDCP_i64_BE(cp2i<ui64_t>(ess_p));
+      ui32_t SourceLength = (ui32_t)KM_i64_BE(Kumu::cp2i<ui64_t>(ess_p));
       ess_p += sizeof(ui64_t);
       assert(SourceLength);
          
@@ -258,7 +292,7 @@ ASDCP::h__Reader::ReadEKLVPacket(ui32_t FrameNum, ASDCP::FrameBuffer& FrameBuf,
       ui32_t esv_length = calc_esv_length(SourceLength, PlaintextOffset);
 
       // read ESV length
-      if ( ! read_test_BER(&ess_p, esv_length) )
+      if ( ! Kumu::read_test_BER(&ess_p, esv_length) )
        {
          DefaultLogSink().Error("read_test_BER did not return %lu\n", esv_length);
          return RESULT_FORMAT;
@@ -303,7 +337,7 @@ ASDCP::h__Reader::ReadEKLVPacket(ui32_t FrameNum, ASDCP::FrameBuffer& FrameBuf,
          FrameBuf.PlaintextOffset(PlaintextOffset);
        }
     }
-  else if ( Key == EssenceUL )
+  else if ( memcmp(Key.Value(), EssenceUL, Key.Size() - 1) == 0 ) // ignore the stream number
     { // read plaintext frame
        if ( FrameBuf.Capacity() < PacketLength )
        {
@@ -336,7 +370,12 @@ ASDCP::h__Reader::ReadEKLVPacket(ui32_t FrameNum, ASDCP::FrameBuffer& FrameBuf,
     }
   else
     {
-      DefaultLogSink().Error("Unexpected UL found.\n");
+      char strbuf[IntBufferLen];
+      const MDDEntry* Entry = Dict::FindUL(Key.Value());
+      if ( Entry == 0 )
+        DefaultLogSink().Warn("Unexpected Essence UL found: %s.\n", Key.EncodeString(strbuf, IntBufferLen));
+      else
+        DefaultLogSink().Warn("Unexpected Essence UL found: %s.\n", Entry->name);
       return RESULT_FORMAT;
     }