Hacks.
authorCarl Hetherington <cth@carlh.net>
Mon, 30 Jul 2012 21:03:25 +0000 (22:03 +0100)
committerCarl Hetherington <cth@carlh.net>
Mon, 30 Jul 2012 21:03:25 +0000 (22:03 +0100)
src/cpl.cc [new file with mode: 0644]
src/cpl.h [new file with mode: 0644]
src/dcp.cc
src/dcp.h
src/types.h
src/util.cc
src/util.h
src/xml.cc [new file with mode: 0644]
src/xml.h [new file with mode: 0644]

diff --git a/src/cpl.cc b/src/cpl.cc
new file mode 100644 (file)
index 0000000..1eba666
--- /dev/null
@@ -0,0 +1,16 @@
+#include "cpl.h"
+
+CPL::CPL (string file)
+{
+       file_is (file);
+
+       _id = string_tag ("Id");
+       _annotation_text = string_tag ("AnnotationText");
+       _issue_date = string_tag ("IssueDate");
+       _creator = string_tag ("Creator");
+       _content_title_text = string_tag ("ContentTitleText");
+       _content_kind = kind_tag ("ContentKind");
+       _content_version = sub (new ContentVersion, "ContentVersion");
+       ignore ("RatingList");
+       _reel_list = sub (new ReelList, "ReelList");
+}
diff --git a/src/cpl.h b/src/cpl.h
new file mode 100644 (file)
index 0000000..6ec55e6
--- /dev/null
+++ b/src/cpl.h
@@ -0,0 +1,8 @@
+#include "xml.h"
+
+class CPL : public XML
+{
+public:
+       CPL (std::string file);
+
+};
index 27ae9636da7ee3a4cff317acc929f1a29518fa51..8c74ea8e593e3ba2f4e1597249622a6e6e65f249 100644 (file)
@@ -239,32 +239,152 @@ DCP::write_assetmap (string cpl_uuid, int cpl_length, string pkl_uuid, int pkl_l
           << "</AssetMap>\n";
 }
 
-string
-DCP::content_type_string (ContentType type)
+
+DCP::DCP (string directory)
+       : _directory (directory)
+{
+       string cpl;
+       string pkl;
+       string asset_map;
+
+       for (filesystem::directory_iterator i = filesystem::directory_iterator(directory); i != filesystem::directory_iterator(); ++i) {
+               string const t = i->path()->string ();
+               if (ends_with (t, "_cpl.xml")) {
+                       if (cpl.empty ()) {
+                               cpl = t;
+                       } else {
+                               throw DCPReadError ("duplicate CPLs found");
+                       }
+               } else if (ends_with (t, "_pkl.xml")) {
+                       if (pkl.empty ()) {
+                               pkl = t;
+                       } else {
+                               throw DCPReadError ("duplicate PKLs found");
+                       }
+               } else if (ends_with (t, "ASSETMAP.xml")) {
+                       if (asset_map.empty ()) {
+                               asset_map = t;
+                       } else {
+                               throw DCPReadError ("duplicate AssetMaps found");
+                       }
+               }
+       }
+
+       load_cpl (cpl);
+       load_pkl (pkl);
+       load_asset_map (asset_map);
+}
+
+void
+DCP::load_cpl (string file)
 {
-       switch (type) {
-       case FEATURE:
-               return "feature";
-       case SHORT:
-               return "short";
-       case TRAILER:
-               return "trailer";
-       case TEST:
-               return "test";
-       case TRANSITIONAL:
-               return "transitional";
-       case RATING:
-               return "rating";
-       case TEASER:
-               return "teaser";
-       case POLICY:
-               return "policy";
-       case PUBLIC_SERVICE_ANNOUNCEMENT:
-               return "psa";
-       case ADVERTISEMENT:
-               return "advertisement";
+       xmlpp::DOMParser parser;
+       parser.parser_file (file);
+       if (!parser) {
+               throw DCPReadError ("could not create parser for CPL");
        }
 
-       assert (false);
+       xmlpp::Element* root = parser.get_document()->get_root_node ();
+       dcp_read_assert (root->get_name() == "CompositionPlaylist", "unrecognised CPL format");
+
+       xmlpp::Node::NodeList children = root->get_children ();
+       for (xmlpp::Node::NodeList::iterator i = children.begin(); i != children.end(); ++i) {
+               bool taken = false;
+               xml_maybe (*i, taken, _cpl_id, "Id");
+               xml_maybe (*i, taken, _annotation_text, "AnnotationText");
+               xml_maybe (*i, taken, _issue_date, "IssueDate");
+               xml_maybe (*i, taken, _creator, "Creator");
+               xml_maybe (*i, taken, _content_title_text, "ContentTitleText");
+               xml_maybe (*i, taken, _content_kind, "ContentKind");
+
+               if ((*i)->get_name() == "ContentVersion") {
+                       taken = true;
+                       load_cpl_content_version (*i);
+               }
+
+               if ((*i)->get_name() == "RatingList") {
+                       taken = true;
+               }
+
+               if ((*i)->get_name() == "ReelList") {
+                       taken = true;
+                       load_cpl_reel_list (*i);
+               }
+
+               xml_assert_taken (*i, taken);
+       }
 }
+
+void
+DCP::load_cpl_content_version (xmlpp::Node const * node)
+{
+       xmlpp::Node::NodeList children = node->get_children ();
+       for (xmlpp::Node::NodeList::iterator i = children.begin(); i != children.end(); ++i) {
+               bool taken = false;
+               xml_maybe (*i, taken, _content_version_id, "Id");
+               xml_maybe (*i, taken, _content_version_label_text, "LabelText");
+               xml_assert_taken (*i, taken);
+       }
+}
+
+void
+DCP::load_cpl_reel_list (xmlpp::Node const * node)
+{
+       xmlpp::Node::NodeList children = node->get_children ();
+       bool had_reel = false;
+       for (xmlpp::Node::NodeList::iterator i = children.begin(); i != children.end(); ++i) {
+               bool taken = false;
+               if ((*i)->get_name() == "Reel") {
+                       if (!had_reel) {
+                               load_cpl_reel (*i);
+                               had_reel = true;
+                       } else {
+                               throw DCPReadError ("multiple reels not supported");
+                       }
+               }
+               xml_assert_taken (*i, taken);
+       }
+}
+
+void
+DCP::load_cpl_reel (xmlpp::Node const * node)
+{
+       xmlpp::Node::NodeList children = node->get_children ();
+       for (xmlpp::Node::NodeList::iterator i = children.begin(); i != children.end(); ++i) {
+               bool taken = false;
+               xml_taken (*i, taken, _reel_id, "Id");
+               if ((*i)->name() == "AssetList") {
+                       taken = true;
+                       load_cpl_asset_list (*i);
+               }
+               xml_assert_taken (*i, taken);
+       }
+}
+
+void
+DCP::load_cpl_asset_list (xmlpp::Node const * node)
+{
+       xmlpp::Node::NodeList children = node->get_children ();
+       for (xmlpp::Node::NodeList::iterator i = children.begin(); i != children.end(); ++i) {
+               bool taken = false;
+               if ((*i)->name() == "MainPicture") {
+                       taken = true;
+                       load_cpl_main_picture (*i);
+               } else if ((*i)->name() == "MainSound") {
+                       taken = true;
+                       load_cpl_main_sound (*i);
+               }
+               xml_assert_taken (*i, taken);
+       }
+}
+
+void
+DCP::load_cpl_main_picture (xmlpp::Node const * node)
+{
+       xmlpp::Node::NodeList children = node->get_children ();
+       for (xmlpp::Node::NodeList::iterator i = children.begin(); i != children.end(); ++i) {
+               bool taken = false;
+               xml_maybe (*i, taken, _video_id, "Id");
                
+       }
+}
index 828a6e751a2cb3f2b777fcdec1086cd1ff0356ab..9407c9c79320bee3c42c8210de0bec83d27b0928 100644 (file)
--- a/src/dcp.h
+++ b/src/dcp.h
 #include <sigc++/sigc++.h>
 #include "types.h"
 
+namespace xmlpp {
+       class Node;
+}
+
 /** @brief Namespace for everything in libdcp */
 namespace libdcp
 {
@@ -43,20 +47,6 @@ class Asset;
 class DCP
 {
 public:
-       enum ContentType
-       {
-               FEATURE,
-               SHORT,
-               TRAILER,
-               TEST,
-               TRANSITIONAL,
-               RATING,
-               TEASER,
-               POLICY,
-               PUBLIC_SERVICE_ANNOUNCEMENT,
-               ADVERTISEMENT
-       };
-
        /** Construct a DCP.
         *  @param directory Directory to write files to.
         *  @param name Name.
@@ -66,6 +56,8 @@ public:
         */
        DCP (std::string directory, std::string name, ContentType content_type, int fps, int length);
 
+       DCP (std::string directory);
+
        /** Add a sound asset.
         *  @param files Pathnames of WAV files to use in the order Left, Right,
         *  Centre, Lfe (sub), Left surround, Right surround; not all files need
@@ -130,11 +122,6 @@ private:
         */
        void write_assetmap (std::string cpl_uuid, int cpl_length, std::string pkl_uuid, int pkl_length) const;
 
-       /** @param type A content type.
-        *  @return A string representation suitable for use in a CPL.
-        */
-       static std::string content_type_string (ContentType type);
-
        /** the directory that we are writing to */
        std::string _directory;
        /** the name of the DCP */
index e2b916706014a97136b2af967ba4a56f17acc612..63f52f3e7e8e127f14dbd77f3bdd1ef9fd362859 100644 (file)
@@ -37,6 +37,20 @@ enum Channel {
        RS = 5       ///< right surround
 };
 
+enum ContentType
+{
+       FEATURE,
+       SHORT,
+       TRAILER,
+       TEST,
+       TRANSITIONAL,
+       RATING,
+       TEASER,
+       POLICY,
+       PUBLIC_SERVICE_ANNOUNCEMENT,
+       ADVERTISEMENT
+};
+
 }
 
 #endif
index 849b7d24b614d267293ae9c6dd027cad712cba71..9b650fa459fcb3f3c704e815867afb9a5968656d 100644 (file)
@@ -86,3 +86,42 @@ libdcp::make_digest (string filename, sigc::signal1<void, float>* progress)
        char digest[64];
        return Kumu::base64encode (byte_buffer, 20, digest, 64);
 }
+
+string
+libdcp::content_type_to_string (ContentType type)
+{
+       switch (type) {
+       case FEATURE:
+               return "feature";
+       case SHORT:
+               return "short";
+       case TRAILER:
+               return "trailer";
+       case TEST:
+               return "test";
+       case TRANSITIONAL:
+               return "transitional";
+       case RATING:
+               return "rating";
+       case TEASER:
+               return "teaser";
+       case POLICY:
+               return "policy";
+       case PUBLIC_SERVICE_ANNOUNCEMENT:
+               return "psa";
+       case ADVERTISEMENT:
+               return "advertisement";
+       }
+
+       assert (false);
+}
+               
+bool
+libdcp::ends_with (string big, string little)
+{
+       if (little.size() > big.size()) {
+               return false;
+       }
+
+       return big.compare (big.length() - little.length(), little.length(), little) == 0;
+}
index b6c945a5a812933f6598c2811985b83e965f81b7..f4c7d2866845bc54af31549d18ce5c2f54af3377 100644 (file)
@@ -39,4 +39,7 @@ extern std::string make_uuid ();
  */
 extern std::string make_digest (std::string filename, sigc::signal1<void, float>* progress);
 
+extern std::string content_type_to_string (ContentType type);
+extern bool ends_with (std::string big, std::string little);
+       
 }
diff --git a/src/xml.cc b/src/xml.cc
new file mode 100644 (file)
index 0000000..3863bdf
--- /dev/null
@@ -0,0 +1,34 @@
+#include "xml.h"
+
+XMLFile::XMLFile (string file, string root_id)
+{
+       xmlpp::DomParser parser;
+       parser.parse_file (file);
+       if (!parser) {
+               throw XMLError ("could not parse XML");
+       }
+
+       _root = parser.get_document()->get_root_node ();
+       if (_root->get_name() != root_id) {
+               throw XMLError ("unrecognised root node");
+       }
+}
+
+string
+XMLFile::string_tag (string id)
+{
+       stringstream x;
+       x << _root->get_name() << "/" << id;
+       xmlpp::NodeSet n = _root->find (x.str ());
+       if (n.empty ()) {
+               throw XMLError ("missing XML tag");
+       } else if (n.size() > 1) {
+               throw XMLError ("duplicate XML tag");
+       }
+
+       xml::Node::NodeList c = n.front()->get_children ();
+       if (c.empty() 
+           
+
+       return n.front()->get_name ();
+}
diff --git a/src/xml.h b/src/xml.h
new file mode 100644 (file)
index 0000000..5cfa494
--- /dev/null
+++ b/src/xml.h
@@ -0,0 +1,6 @@
+
+class XMLFile
+{
+public:
+       XMLFile (std::string file);
+};