Bitwise MXF comparison.
[libdcp.git] / src / asset.cc
index 0ad7b5b18290209dfd7f5be63e6cf450e9842d92..86bd54c56d700e21446d3c3a016f24011f8a440a 100644 (file)
@@ -22,6 +22,7 @@
  */
 
 #include <iostream>
+#include <fstream>
 #include <boost/filesystem.hpp>
 #include "AS_DCP.h"
 #include "KM_util.h"
@@ -33,8 +34,9 @@ using namespace std;
 using namespace boost;
 using namespace libdcp;
 
-Asset::Asset (string mxf_path, sigc::signal1<void, float>* progress, int fps, int length)
-       : _mxf_path (mxf_path)
+Asset::Asset (string directory, string mxf_name, sigc::signal1<void, float>* progress, int fps, int length)
+       : _directory (directory)
+       , _mxf_name (mxf_name)
        , _progress (progress)
        , _fps (fps)
        , _length (length)
@@ -48,9 +50,9 @@ Asset::write_to_pkl (ostream& s) const
 {
        s << "    <Asset>\n"
          << "      <Id>urn:uuid:" << _uuid << "</Id>\n"
-         << "      <AnnotationText>" << filesystem::path(_mxf_path).filename().string() << "</AnnotationText>\n"
+         << "      <AnnotationText>" << _mxf_name << "</AnnotationText>\n"
          << "      <Hash>" << _digest << "</Hash>\n"
-         << "      <Size>" << filesystem::file_size(_mxf_path) << "</Size>\n"
+         << "      <Size>" << filesystem::file_size(mxf_path()) << "</Size>\n"
          << "      <Type>application/mxf</Type>\n"
          << "    </Asset>\n";
 }
@@ -62,10 +64,10 @@ Asset::write_to_assetmap (ostream& s) const
          << "      <Id>urn:uuid:" << _uuid << "</Id>\n"
          << "      <ChunkList>\n"
          << "        <Chunk>\n"
-         << "          <Path>" << filesystem::path(_mxf_path).filename().string() << "</Path>\n"
+         << "          <Path>" << _mxf_name << "</Path>\n"
          << "          <VolumeIndex>1</VolumeIndex>\n"
          << "          <Offset>0</Offset>\n"
-         << "          <Length>" << filesystem::file_size(_mxf_path) << "</Length>\n"
+         << "          <Length>" << filesystem::file_size(mxf_path()) << "</Length>\n"
          << "        </Chunk>\n"
          << "      </ChunkList>\n"
          << "    </Asset>\n";
@@ -83,3 +85,54 @@ Asset::fill_writer_info (ASDCP::WriterInfo* writer_info) const
        Kumu::hex2bin (_uuid.c_str(), writer_info->AssetUUID, Kumu::UUID_Length, &c);
        assert (c == Kumu::UUID_Length);
 }
+
+filesystem::path
+Asset::mxf_path () const
+{
+       filesystem::path p;
+       p /= _directory;
+       p /= _mxf_name;
+       return p;
+}
+
+list<string>
+Asset::equals (Asset const & other, EqualityFlags flags) const
+{
+       list<string> notes;
+       
+       switch (flags) {
+       case LIBDCP_METADATA:
+               break;
+       case MXF_BITWISE:
+               if (filesystem::file_size (mxf_path()) != filesystem::file_size (other.mxf_path())) {
+                       notes.push_back (mxf_path().string() + " and " + other.mxf_path().string() + " sizes differ");
+                       return notes;
+               }
+               
+               ifstream a (mxf_path().c_str(), ios::binary);
+               ifstream b (other.mxf_path().c_str(), ios::binary);
+
+               int buffer_size = 65536;
+               char abuffer[buffer_size];
+               char bbuffer[buffer_size];
+
+               int n = filesystem::file_size (mxf_path ());
+
+               while (n) {
+                       int const t = min (n, buffer_size);
+                       a.read (abuffer, t);
+                       b.read (bbuffer, t);
+
+                       for (int i = 0; i < t; ++i) {
+                               if (abuffer[i] != bbuffer[i]) {
+                                       notes.push_back (mxf_path().string() + " and " + other.mxf_path().string() + " content differs");
+                                       return notes;
+                               }
+                       }
+
+                       n -= t;
+               }
+       }
+
+       return notes;
+}