Commit for release to 1.5.29.
[asdcplib.git] / src / h__Reader.cpp
index 2179ca68459675a5ef6bc1ce233c9e3e0fb49ce8..6d74b9d9e7a042e3a8bcca1652481e8002dea3ba 100755 (executable)
@@ -1,5 +1,5 @@
 /*
-Copyright (c) 2004-2006, John Hurst
+Copyright (c) 2004-2009, John Hurst
 All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
@@ -36,7 +36,8 @@ using namespace ASDCP;
 using namespace ASDCP::MXF;
 
 //
-ASDCP::h__Reader::h__Reader() : m_EssenceStart(0)
+ASDCP::h__Reader::h__Reader(const Dictionary& d) :
+  m_HeaderPart(m_Dict), m_BodyPart(m_Dict), m_FooterPart(m_Dict), m_Dict(&d), m_EssenceStart(0)
 {
 }
 
@@ -58,11 +59,12 @@ ASDCP::h__Reader::Close()
 Result_t
 ASDCP::h__Reader::InitInfo()
 {
+  assert(m_Dict);
   InterchangeObject* Object;
 
   m_Info.LabelSetType = LS_MXF_UNKNOWN;
-  UL OPAtomUL(Dict::ul(MDD_OPAtom));
-  UL Interop_OPAtomUL(Dict::ul(MDD_MXFInterop_OPAtom));
+  UL OPAtomUL(SMPTE_390_OPAtom_Entry().ul);
+  UL Interop_OPAtomUL(MXFInterop_OPAtom_Entry().ul);
 
   if ( m_HeaderPart.OperationalPattern == Interop_OPAtomUL )
     m_Info.LabelSetType = LS_MXF_INTEROP;
@@ -91,7 +93,7 @@ ASDCP::h__Reader::InitInfo()
       Result_t cr_result = m_HeaderPart.GetMDObjectByType(OBJ_TYPE_ARGS(CryptographicContext), &Object);
 
       if( ASDCP_SUCCESS(cr_result) )
-       MD_to_CryptoInfo((CryptographicContext*)Object, m_Info);
+       MD_to_CryptoInfo((CryptographicContext*)Object, m_Info, *m_Dict);
     }
 
   return result;
@@ -112,7 +114,7 @@ ASDCP::h__Reader::OpenMXFRead(const char* filename)
     {
       // if this is a three partition file, go to the body
       // partition and read the partition pack
-      if ( m_HeaderPart.m_RIP.PairArray.size() == 3 )
+      if ( m_HeaderPart.m_RIP.PairArray.size() > 2 )
        {
          Array<RIP::Pair>::iterator r_i = m_HeaderPart.m_RIP.PairArray.begin();
          r_i++;
@@ -150,40 +152,29 @@ ASDCP::h__Reader::InitMXFIndex()
 }
 
 //
-class KLReader : public ASDCP::KLVPacket
+Result_t
+ASDCP::KLReader::ReadKLFromFile(Kumu::FileReader& Reader)
 {
-  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);
+  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) )
+    {
+      if ( read_count != header_length )
+       result = RESULT_READFAIL;
   
-    if ( ASDCP_SUCCESS(result) )
-      result = InitFromBuffer(m_KeyBuf, header_length);
-
-    return result;
-  }
-};
+      else
+       result = InitFromBuffer(m_KeyBuf, header_length);
+    }
 
+  return result;
+}
 
 // standard method of reading a plaintext or encrypted frame
 Result_t
-ASDCP::h__Reader::ReadEKLVPacket(ui32_t FrameNum, ASDCP::FrameBuffer& FrameBuf,
-                                const byte_t* EssenceUL, AESDecContext* Ctx, HMACContext* HMAC)
+ASDCP::h__Reader::ReadEKLVFrame(ui32_t FrameNum, ASDCP::FrameBuffer& FrameBuf,
+                               const byte_t* EssenceUL, AESDecContext* Ctx, HMACContext* HMAC)
 {
   // look up frame index node
   IndexTableSegment::IndexEntry TmpEntry;
@@ -195,9 +186,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;
-  KLReader Reader;
   Kumu::fpos_t FilePosition = m_EssenceStart + TmpEntry.StreamOffset;
+  Result_t result = RESULT_OK;
 
   if ( FilePosition != m_LastPosition )
     {
@@ -205,8 +195,19 @@ ASDCP::h__Reader::ReadEKLVPacket(ui32_t FrameNum, ASDCP::FrameBuffer& FrameBuf,
       result = m_File.Seek(FilePosition);
     }
 
-  if ( ASDCP_SUCCESS(result) )
-    result = Reader.ReadKLFromFile(m_File);
+  if( ASDCP_SUCCESS(result) )
+    result = ReadEKLVPacket(FrameNum, FrameNum + 1, FrameBuf, EssenceUL, Ctx, HMAC);
+
+  return result;
+}
+
+
+Result_t
+ASDCP::h__Reader::ReadEKLVPacket(ui32_t FrameNum, ui32_t SequenceNum, ASDCP::FrameBuffer& FrameBuf,
+                                const byte_t* EssenceUL, AESDecContext* Ctx, HMACContext* HMAC)
+{
+  KLReader Reader;
+  Result_t result = Reader.ReadKLFromFile(m_File);
 
   if ( ASDCP_FAILURE(result) )
     return result;
@@ -214,9 +215,9 @@ ASDCP::h__Reader::ReadEKLVPacket(ui32_t FrameNum, ASDCP::FrameBuffer& FrameBuf,
   UL Key(Reader.Key());
   ui64_t PacketLength = Reader.Length();
   m_LastPosition = m_LastPosition + Reader.KLLength() + PacketLength;
+  assert(m_Dict);
 
-  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 ( memcmp(Key.Value(), m_Dict->ul(MDD_CryptEssence), Key.Size() - 1) == 0 )  // ignore the stream numbers
     {
       if ( ! m_Info.EncryptedEssence )
        {
@@ -225,9 +226,11 @@ ASDCP::h__Reader::ReadEKLVPacket(ui32_t FrameNum, ASDCP::FrameBuffer& FrameBuf,
        }
 
       // read encrypted triplet value into internal buffer
-      m_CtFrameBuf.Capacity(PacketLength);
+      assert(PacketLength <= 0xFFFFFFFFL);
+      m_CtFrameBuf.Capacity((ui32_t) PacketLength);
       ui32_t read_count;
-      result = m_File.Read(m_CtFrameBuf.Data(), PacketLength, &read_count);
+      result = m_File.Read(m_CtFrameBuf.Data(), (ui32_t) PacketLength,
+                          &read_count);
 
       if ( ASDCP_FAILURE(result) )
        return result;
@@ -238,7 +241,7 @@ ASDCP::h__Reader::ReadEKLVPacket(ui32_t FrameNum, ASDCP::FrameBuffer& FrameBuf,
           return RESULT_FORMAT;
         }
 
-      m_CtFrameBuf.Size(PacketLength);
+      m_CtFrameBuf.Size((ui32_t) PacketLength);
 
       // should be const but mxflib::ReadBER is not
       byte_t* ess_p = m_CtFrameBuf.Data();
@@ -270,7 +273,7 @@ ASDCP::h__Reader::ReadEKLVPacket(ui32_t FrameNum, ASDCP::FrameBuffer& FrameBuf,
       if ( memcmp(ess_p, EssenceUL, SMPTE_UL_LENGTH - 1) != 0 ) // ignore the stream number
        {
          char strbuf[IntBufferLen];
-         const MDDEntry* Entry = Dict::FindUL(Key.Value());
+         const MDDEntry* Entry = m_Dict->FindUL(Key.Value());
          if ( Entry == 0 )
            DefaultLogSink().Warn("Unexpected Essence UL found: %s.\n", Key.EncodeString(strbuf, IntBufferLen));
          else
@@ -327,7 +330,7 @@ ASDCP::h__Reader::ReadEKLVPacket(ui32_t FrameNum, ASDCP::FrameBuffer& FrameBuf,
          if ( ASDCP_SUCCESS(result) && m_Info.UsesHMAC && HMAC )
            {
              IntegrityPack IntPack;
-             result = IntPack.TestValues(TmpWrapper, m_Info.AssetUUID, FrameNum + 1, HMAC);
+             result = IntPack.TestValues(TmpWrapper, m_Info.AssetUUID, SequenceNum, HMAC);
            }
        }
       else // return ciphertext to caller
@@ -358,7 +361,8 @@ ASDCP::h__Reader::ReadEKLVPacket(ui32_t FrameNum, ASDCP::FrameBuffer& FrameBuf,
 
       // read the data into the supplied buffer
       ui32_t read_count;
-      result = m_File.Read(FrameBuf.Data(), PacketLength, &read_count);
+      assert(PacketLength <= 0xFFFFFFFFL);
+      result = m_File.Read(FrameBuf.Data(), (ui32_t) PacketLength, &read_count);
          
       if ( ASDCP_FAILURE(result) )
        return result;
@@ -380,7 +384,7 @@ ASDCP::h__Reader::ReadEKLVPacket(ui32_t FrameNum, ASDCP::FrameBuffer& FrameBuf,
   else
     {
       char strbuf[IntBufferLen];
-      const MDDEntry* Entry = Dict::FindUL(Key.Value());
+      const MDDEntry* Entry = m_Dict->FindUL(Key.Value());
       if ( Entry == 0 )
         DefaultLogSink().Warn("Unexpected Essence UL found: %s.\n", Key.EncodeString(strbuf, IntBufferLen));
       else