ReadFileIntoString() modified to return OK when the file is empty
[asdcplib.git] / src / PCMParserList.cpp
index 1fc434dd341428cb3c1e2424369ae20f9e03ba2b..c073e3f54955a9e366b41053247ce8f4251cae22 100755 (executable)
@@ -1,5 +1,5 @@
 /*
-Copyright (c) 2004-2009, John Hurst
+Copyright (c) 2004-2016, John Hurst
 All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
@@ -30,6 +30,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
 
 #include <PCMParserList.h>
+#include <KM_fileio.h>
 #include <KM_log.h>
 #include <assert.h>
 
@@ -47,10 +48,8 @@ ASDCP::ParserInstance::~ParserInstance()
 
 // PCM::CalcSampleSize(ADesc);
 Result_t
-ASDCP::ParserInstance::OpenRead(const char* filename, Rational& PictureRate)
+ASDCP::ParserInstance::OpenRead(const std::string& filename, const Rational& PictureRate)
 {
-  ASDCP_TEST_NULL_STR(filename);
-
   Result_t result = Parser.OpenRead(filename, PictureRate);
 
   if ( ASDCP_SUCCESS(result) )
@@ -73,11 +72,18 @@ ASDCP::ParserInstance::PutSample(byte_t* p)
 {
   ASDCP_TEST_NULL(p);
 
-  memcpy(p, m_p, m_SampleSize);
-  m_p += m_SampleSize;
-  return RESULT_OK;
-}
+  if ( m_p != 0 )
+    {
+      if ( m_p < ( FB.RoData() + FB.Size() ) )
+       {
+         memcpy(p, m_p, m_SampleSize);
+         m_p += m_SampleSize;
+         return RESULT_OK;
+       }
+    }
 
+  return RESULT_ENDOFFILE;
+}
 
 //
 Result_t
@@ -107,22 +113,69 @@ ASDCP::PCMParserList::~PCMParserList()
     }
 }
 
+//
+Result_t
+ASDCP::PCMParserList::OpenRead(ui32_t argc, const char** argv, const Rational& PictureRate)
+{
+  ASDCP_TEST_NULL(argv);
+  PathList_t TmpFileList;
+
+  for ( ui32_t i = 0; i < argc; ++i )
+    {
+      ASDCP_TEST_NULL(argv[i]);
+      TmpFileList.push_back(argv[i]);
+    }
+
+  return OpenRead(TmpFileList, PictureRate);
+}
 
 //
 Result_t
-ASDCP::PCMParserList::OpenRead(ui32_t argc, const char** argv, Rational& PictureRate)
+ASDCP::PCMParserList::OpenRead(const Kumu::PathList_t& argv, const Rational& PictureRate)
 {
-  ASDCP_TEST_NULL_STR(argv);
   Result_t result = RESULT_OK;
+  PathList_t::iterator fi;
+  Kumu::PathList_t file_list;
+
+  if ( argv.size() == 1 && PathIsDirectory(argv.front()) )
+    {
+      DirScanner Dir;
+      char name_buf[MaxFilePath];
+      result = Dir.Open(argv.front().c_str());
+
+      if ( KM_SUCCESS(result) )
+       result = Dir.GetNext(name_buf);
+
+      while ( KM_SUCCESS(result) )
+       {
+         if ( name_buf[0] != '.' ) // no hidden files
+           {
+             std::string tmp_path = argv.front() + "/" + name_buf;
+             file_list.push_back(tmp_path);
+           }
+
+         result = Dir.GetNext(name_buf);
+       }
+
+      if ( result == RESULT_ENDOFFILE )
+       {
+         result = RESULT_OK;
+         file_list.sort();
+       }
+    }
+  else
+    {
+      file_list = argv;
+    }
 
-  for ( ui32_t i = 0; i < argc && ASDCP_SUCCESS(result); i++ )
+  for ( fi = file_list.begin(); KM_SUCCESS(result) && fi != file_list.end(); ++fi )
     {
-      ParserInstance* I = new ParserInstance;
-      result = I->OpenRead(argv[i], PictureRate);
+      mem_ptr<ParserInstance> I = new ParserInstance;
+      result = I->OpenRead(fi->c_str(), PictureRate);
 
       if ( ASDCP_SUCCESS(result) )
        {
-         if ( i == 0 )
+         if ( fi == file_list.begin() )
            {
              m_ADesc = I->ADesc;
            }
@@ -153,15 +206,22 @@ ASDCP::PCMParserList::OpenRead(ui32_t argc, const char** argv, Rational& Picture
        result = I->FB.Capacity(PCM::CalcFrameBufferSize(m_ADesc));
 
       if ( ASDCP_SUCCESS(result) )
-       push_back(I);
+       {
+         push_back(I);
+         I.release();
+       }
     }
 
-  m_ADesc.ChannelCount = m_ChannelCount;
-  m_ADesc.AvgBps = ( m_ADesc.AvgBps  / m_ADesc.ChannelCount ) * m_ChannelCount;
+  if ( ASDCP_SUCCESS(result) )
+    {
+      m_ADesc.ChannelCount = m_ChannelCount;
+      m_ADesc.AvgBps = (ui32_t)(ceil(m_ADesc.AudioSamplingRate.Quotient()) * m_ADesc.BlockAlign);
+    }
+  else
+    {
+      clear();
+    }
 
-  if ( ASDCP_FAILURE(result) )
-    clear();
-  
   return result;
 }
 
@@ -194,21 +254,23 @@ ASDCP::PCMParserList::ReadFrame(PCM::FrameBuffer& OutFB)
   Result_t result = RESULT_OK;
 
   if ( size() == 1 )
-    return front()->Parser.ReadFrame(OutFB);
+    {
+      return front()->Parser.ReadFrame(OutFB);
+    }
 
   PCMParserList::iterator self_i;
   assert(PCM::CalcFrameBufferSize(m_ADesc) <= OutFB.Capacity());
 
   for ( self_i = begin(); self_i != end() && ASDCP_SUCCESS(result) ; self_i++ )
-    result = (*self_i)->ReadFrame();
+    {
+      result = (*self_i)->ReadFrame();
+    }
 
   if ( ASDCP_SUCCESS(result) )
     {
-      OutFB.Size(PCM::CalcFrameBufferSize(m_ADesc));
-
-      //      ui32_t sample_size = (PCM::CalcSampleSize(m_ADesc));
       byte_t* Out_p = OutFB.Data();
-      byte_t* End_p = Out_p + OutFB.Size();
+      byte_t* End_p = Out_p + OutFB.Capacity();
+      ui64_t total_sample_bytes = 0;
 
       while ( Out_p < End_p && ASDCP_SUCCESS(result) )
        {
@@ -217,17 +279,41 @@ ASDCP::PCMParserList::ReadFrame(PCM::FrameBuffer& OutFB)
          while ( self_i != end() && ASDCP_SUCCESS(result) )
            {
              result = (*self_i)->PutSample(Out_p);
-             Out_p += (*self_i)->SampleSize();
-             self_i++;
+
+             if ( ASDCP_SUCCESS(result) )
+               {
+                 Out_p += (*self_i)->SampleSize();
+                 total_sample_bytes += (*self_i)->SampleSize();
+                 self_i++;
+               }
            }
        }
 
-      assert(Out_p == End_p);
+      OutFB.Size(total_sample_bytes);
+
+      if ( result == RESULT_ENDOFFILE )
+       {
+         result = RESULT_OK;
+       }
     }
 
   return result;
 }
 
+//
+ASDCP::Result_t ASDCP::PCMParserList::Seek(ui32_t frame_number)
+{
+  Result_t result = RESULT_OK;
+  PCMParserList::iterator self_i;
+
+  for( self_i = begin(); self_i != end() && ASDCP_SUCCESS(result); self_i++ )
+    {
+      result = (*self_i)->Parser.Seek(frame_number);
+    }
+  
+  return result;
+}
+
 //
 // end PCMParserList.cpp
 //