--- /dev/null
+#!/bin/bash
+
+export LD_LIBRARY_PATH=build/src
+if [ "$1" == "--debug" ]; then
+ gdb --args build/tools/dcpdiff "$@"
+elif [ "$1" == "--valgrind" ]; then
+ valgrind --tool="memcheck" --leak-check=full --show-reachable=yes build/tools/dcpdiff "$@"
+else
+ build/tools/dcpdiff "$@"
+fi
--- /dev/null
+#include "asset_map.h"
+
+using namespace std;
+using namespace libdcp;
+
+AssetMap::AssetMap (string file)
+ : XMLFile (file)
+{
+ id = string_node ("Id");
+ creator = string_node ("Creator");
+ volume_count = int_node ("VolumeCount");
+ issue_date = string_node ("IssueDate");
+ issuer = string_node ("Issuer");
+ asset_list = sub_node<AssetList> ("AssetMapAssetList");
+}
+
+AssetMapAssetList::AssetMapAssetList (xmlpp::Node const * node)
+ : XMLNode (node)
+{
+ assets = sub_nodes<AssetMapAsset> ("Asset");
+}
+
+AssetMapAsset::AssetMapAsset (xmlpp::Node const * node)
+ : XMLNode (node)
+{
+ id = string_node ("Id");
+ packing_list = optional_string_node ("PackingList");
+ chunk_list = sub_node<ChunkList> ("ChunkList");
+}
+
+ChunkList::ChunkList (xmlpp::Node const * node)
+ : XMLNode (node)
+{
+ chunks = sub_nodes<Chunk> ("Chunk");
+}
+
+Chunk::Chunk (xmlpp::Node const * node)
+ : XMLNode (node)
+{
+ path = string_node ("Path");
+ volume_index = int_node ("VolumeIndex");
+ offset = int_node ("Offset");
+ length = int_node ("Length");
+}
+
--- /dev/null
+#include <boost/shared_ptr.hpp>
+#include "xml.h"
+
+namespace libdcp {
+
+class AssetMapAsset : public XMLNode
+{
+public:
+ AssetMapAsset ();
+ AssetMapAsset (xmlpp::Node const * node);
+
+ std::string id;
+ std::string packing_list;
+ boost::shared_ptr<ChunkList>
+};
+
+class AssetMapAssetList : public XMLNode
+{
+public:
+ AssetMapAssetList ();
+ AssetMapAssetList (xmlpp::Node const * node);
+
+ std::list<boost::shared_ptr<AssetMapAsset> > assets;
+};
+
+class AssetMap : public XMLFile
+{
+public:
+ AssetMap (std::string file);
+
+ std::string id;
+ std::string creator;
+ int volume_count;
+ std::string issue_date;
+ std::string issuer;
+ boost::shared_ptr<AssetMapAssetList> asset_list;
+};
#include "cpl.h"
+using namespace std;
+using namespace libdcp;
+
CPL::CPL (string file)
+ : XMLFile (file, "CompositionPlaylist")
+{
+ id = string_node ("Id");
+ annotation_text = string_node ("AnnotationText");
+ issue_date = string_node ("IssueDate");
+ creator = string_node ("Creator");
+ content_title_text = string_node ("ContentTitleText");
+ content_kind = kind_node ("ContentKind");
+ content_version = sub_node<ContentVersion> ("ContentVersion");
+ ignore_node ("RatingList");
+ reel_list = sub_node<ReelList> ("ReelList");
+
+ done ();
+}
+
+ContentVersion::ContentVersion (xmlpp::Node const * node)
+ : XMLNode (node)
+{
+ id = string_node ("Id");
+ label_text = string_node ("LabelText");
+ done ();
+}
+
+ReelList::ReelList (xmlpp::Node const * node)
+ : XMLNode (node)
+{
+ reels = sub_nodes<Reel> ("Reel");
+ done ();
+}
+
+Reel::Reel (xmlpp::Node const * node)
+ : XMLNode (node)
+{
+ id = string_node ("Id");
+ asset_list = sub_node<CPLAssetList> ("AssetList");
+
+ done ();
+}
+
+CPLAssetList::CPLAssetList (xmlpp::Node const * node)
+ : XMLNode (node)
+{
+ main_picture = sub_node<MainPicture> ("MainPicture");
+ main_sound = optional_sub_node<MainSound> ("MainSound");
+
+ done ();
+}
+
+MainPicture::MainPicture (xmlpp::Node const * node)
+ : XMLNode (node)
+{
+ id = string_node ("Id");
+ annotation_text = string_node ("AnnotationText");
+ edit_rate = fraction_node ("EditRate");
+ intrinsic_duration = int_node ("IntrinsicDuration");
+ entry_point = int_node ("EntryPoint");
+ duration = int_node ("Duration");
+ frame_rate = fraction_node ("FrameRate");
+ screen_aspect_ratio = fraction_node ("ScreenAspectRatio");
+
+ done ();
+}
+
+MainSound::MainSound (xmlpp::Node const * node)
+ : XMLNode (node)
{
- 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");
+ id = string_node ("Id");
+ annotation_text = string_node ("AnnotationText");
+ edit_rate = fraction_node ("EditRate");
+ intrinsic_duration = int_node ("IntrinsicDuration");
+ entry_point = int_node ("EntryPoint");
+ duration = int_node ("Duration");
+
+ done ();
}
+#include <boost/shared_ptr.hpp>
#include "xml.h"
-class CPL : public XML
+namespace libdcp {
+
+class MainPicture : public XMLNode
+{
+public:
+ MainPicture () {}
+ MainPicture (xmlpp::Node const * node);
+
+ std::string id;
+ std::string annotation_text;
+ Fraction edit_rate;
+ int intrinsic_duration;
+ int entry_point;
+ int duration;
+ Fraction frame_rate;
+ Fraction screen_aspect_ratio;
+};
+
+class MainSound : public XMLNode
+{
+public:
+ MainSound () {}
+ MainSound (xmlpp::Node const * node);
+
+ std::string id;
+ std::string annotation_text;
+ Fraction edit_rate;
+ int intrinsic_duration;
+ int entry_point;
+ int duration;
+};
+
+class CPLAssetList : public XMLNode
+{
+public:
+ CPLAssetList () {}
+ CPLAssetList (xmlpp::Node const * node);
+
+ boost::shared_ptr<MainPicture> main_picture;
+ boost::shared_ptr<MainSound> main_sound;
+};
+
+class Reel : public XMLNode
+{
+public:
+ Reel () {}
+ Reel (xmlpp::Node const * node);
+
+ std::string id;
+ boost::shared_ptr<CPLAssetList> asset_list;
+};
+
+class ReelList : public XMLNode
+{
+public:
+ ReelList () {}
+ ReelList (xmlpp::Node const * node);
+
+ std::list<boost::shared_ptr<Reel> > reels;
+};
+
+class ContentVersion : public XMLNode
+{
+public:
+ ContentVersion () {}
+ ContentVersion (xmlpp::Node const * node);
+
+ std::string id;
+ std::string label_text;
+};
+
+class CPL : public XMLFile
{
public:
CPL (std::string file);
+ std::string id;
+ std::string annotation_text;
+ std::string issue_date;
+ std::string creator;
+ std::string content_title_text;
+ std::string content_kind;
+ boost::shared_ptr<ContentVersion> content_version;
+ boost::shared_ptr<ReelList> reel_list;
};
+
+}
+
#include "picture_asset.h"
#include "util.h"
#include "metadata.h"
+#include "exceptions.h"
+#include "cpl.h"
+#include "pkl.h"
using namespace std;
using namespace boost;
using namespace libdcp;
-DCP::DCP (string directory, string name, ContentType content_type, int fps, int length)
+DCP::DCP (string directory, string name, ContentKind content_kind, int fps, int length)
: _directory (directory)
, _name (name)
- , _content_type (content_type)
+ , _content_kind (content_kind)
, _fps (fps)
, _length (length)
{
<< " <IssueDate>" << Metadata::instance()->issue_date << "</IssueDate>\n"
<< " <Creator>" << Metadata::instance()->creator << "</Creator>\n"
<< " <ContentTitleText>" << _name << "</ContentTitleText>\n"
- << " <ContentKind>" << content_type_string (_content_type) << "</ContentKind>\n"
+ << " <ContentKind>" << content_kind_to_string (_content_kind) << "</ContentKind>\n"
<< " <ContentVersion>\n"
<< " <Id>urn:uri:" << cpl_uuid << "_" << Metadata::instance()->issue_date << "</Id>\n"
<< " <LabelText>" << cpl_uuid << "_" << Metadata::instance()->issue_date << "</LabelText>\n"
DCP::DCP (string directory)
: _directory (directory)
{
- string cpl;
- string pkl;
- string asset_map;
+ string cpl_file;
+ string pkl_file;
+ string asset_map_file;
for (filesystem::directory_iterator i = filesystem::directory_iterator(directory); i != filesystem::directory_iterator(); ++i) {
- string const t = i->path()->string ();
+ string const t = i->path().string ();
if (ends_with (t, "_cpl.xml")) {
- if (cpl.empty ()) {
- cpl = t;
+ if (cpl_file.empty ()) {
+ cpl_file = t;
} else {
throw DCPReadError ("duplicate CPLs found");
}
} else if (ends_with (t, "_pkl.xml")) {
- if (pkl.empty ()) {
- pkl = t;
+ if (pkl_file.empty ()) {
+ pkl_file = t;
} else {
throw DCPReadError ("duplicate PKLs found");
}
} else if (ends_with (t, "ASSETMAP.xml")) {
- if (asset_map.empty ()) {
- asset_map = t;
+ if (asset_map_file.empty ()) {
+ asset_map_file = t;
} else {
throw DCPReadError ("duplicate AssetMaps found");
}
}
}
- load_cpl (cpl);
- load_pkl (pkl);
- load_asset_map (asset_map);
+ CPL cpl (cpl_file);
+ PKL pkl (pkl_file);
}
-void
-DCP::load_cpl (string file)
-{
- xmlpp::DOMParser parser;
- parser.parser_file (file);
- if (!parser) {
- throw DCPReadError ("could not create parser for CPL");
- }
-
- 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");
-
- }
-}
/** Construct a DCP.
* @param directory Directory to write files to.
* @param name Name.
- * @param content_type Content type.
+ * @param content_kind Content kind.
* @param fps Frames per second.
* @param length Length in frames.
*/
- DCP (std::string directory, std::string name, ContentType content_type, int fps, int length);
+ DCP (std::string directory, std::string name, ContentKind content_kind, int fps, int length);
DCP (std::string directory);
std::string _directory;
/** the name of the DCP */
std::string _name;
- /** the content type of the DCP */
- ContentType _content_type;
+ /** the content kind of the DCP */
+ ContentKind _content_kind;
/** frames per second */
int _fps;
/** length in frames */
*/
+#ifndef LIBDCP_EXCEPTIONS_H
+#define LIBDCP_EXCEPTIONS_H
+
/** @file src/exceptions.h
* @brief Exceptions thrown by libdcp.
*/
std::string _message;
};
+/** @brief A DCP read exception */
+class DCPReadError : public std::exception
+{
+public:
+ DCPReadError (std::string const & message) : _message (message) {}
+ ~DCPReadError () throw () {}
+
+ /** @return error message */
+ char const * what () const throw () {
+ return _message.c_str ();
+ }
+
+private:
+ /** error message */
+ std::string _message;
+};
+
+/** @brief An XML error */
+class XMLError : public std::exception
+{
+public:
+ XMLError (std::string const & message) : _message (message) {}
+ ~XMLError () throw () {}
+
+ /** @return error message */
+ char const * what () const throw () {
+ return _message.c_str ();
+ }
+
+private:
+ /** error message */
+ std::string _message;
+};
+
}
+
+#endif
--- /dev/null
+#include "pkl.h"
+
+using namespace std;
+using namespace libdcp;
+
+PKL::PKL (string file)
+ : XMLFile (file, "PackingList")
+{
+ id = string_node ("Id");
+ annotation_text = string_node ("AnnotationText");
+ issue_date = string_node ("IssueDate");
+ issuer = string_node ("Issuer");
+ creator = string_node ("Creator");
+ asset_list = sub_node<PKLAssetList> ("AssetList");
+}
+
+PKLAssetList::PKLAssetList (xmlpp::Node const * node)
+ : XMLNode (node)
+{
+ assets = sub_nodes<PKLAsset> ("Asset");
+}
+
+PKLAsset::PKLAsset (xmlpp::Node const * node)
+ : XMLNode (node)
+{
+ id = string_node ("Id");
+ annotation_text = optional_string_node ("AnnotationText");
+ hash = string_node ("Hash");
+ size = int_node ("Size");
+ type = string_node ("Type");
+}
+
--- /dev/null
+#include <boost/shared_ptr.hpp>
+#include "xml.h"
+
+namespace libdcp {
+
+class PKLAsset : public XMLNode
+{
+public:
+ PKLAsset () {}
+ PKLAsset (xmlpp::Node const * node);
+
+ std::string id;
+ std::string annotation_text;
+ std::string hash;
+ int size;
+ std::string type;
+};
+
+class PKLAssetList : public XMLNode
+{
+public:
+ PKLAssetList ();
+ PKLAssetList (xmlpp::Node const * node);
+
+ std::list<boost::shared_ptr<PKLAsset> > assets;
+};
+
+class PKL : public XMLFile
+{
+public:
+ PKL (std::string file);
+
+ std::string id;
+ std::string annotation_text;
+ std::string issue_date;
+ std::string issuer;
+ std::string creator;
+ boost::shared_ptr<PKLAssetList> asset_list;
+};
+
+}
--- /dev/null
+#include <vector>
+#include <boost/lexical_cast.hpp>
+#include <boost/algorithm/string.hpp>
+#include "types.h"
+#include "exceptions.h"
+
+using namespace std;
+using namespace libdcp;
+using namespace boost;
+
+Fraction::Fraction (string s)
+{
+ vector<string> b;
+ split (b, s, is_any_of (" "));
+ if (b.size() != 2) {
+ throw XMLError ("malformed fraction " + s + " in XML node");
+ }
+ numerator = lexical_cast<int> (b[0]);
+ denominator = lexical_cast<int> (b[1]);
+}
RS = 5 ///< right surround
};
-enum ContentType
+enum ContentKind
{
FEATURE,
SHORT,
ADVERTISEMENT
};
+class Fraction
+{
+public:
+ Fraction () : numerator (0), denominator (0) {}
+ Fraction (std::string s);
+ Fraction (int n, int d) : numerator (n), denominator (d) {}
+
+ int numerator;
+ int denominator;
+};
+
}
#endif
#include "AS_DCP.h"
#include "util.h"
#include "exceptions.h"
+#include "types.h"
using namespace std;
using namespace boost;
}
string
-libdcp::content_type_to_string (ContentType type)
+libdcp::content_kind_to_string (ContentKind kind)
{
- switch (type) {
+ switch (kind) {
case FEATURE:
return "feature";
case SHORT:
assert (false);
}
+
+libdcp::ContentKind
+libdcp::content_kind_from_string (string type)
+{
+ if (type == "feature") {
+ return FEATURE;
+ } else if (type == "short") {
+ return SHORT;
+ } else if (type == "trailer") {
+ return TRAILER;
+ } else if (type == "test") {
+ return TEST;
+ } else if (type == "transitional") {
+ return TRANSITIONAL;
+ } else if (type == "rating") {
+ return RATING;
+ } else if (type == "teaser") {
+ return TEASER;
+ } else if (type == "policy") {
+ return POLICY;
+ } else if (type == "psa") {
+ return PUBLIC_SERVICE_ANNOUNCEMENT;
+ } else if (type == "advertisement") {
+ return ADVERTISEMENT;
+ }
+
+ assert (false);
+}
bool
libdcp::ends_with (string big, string little)
#include <string>
#include <sigc++/sigc++.h>
+#include "types.h"
namespace libdcp {
*/
extern std::string make_digest (std::string filename, sigc::signal1<void, float>* progress);
-extern std::string content_type_to_string (ContentType type);
+extern std::string content_kind_to_string (ContentKind kind);
+extern ContentKind content_kind_from_string (std::string kind);
extern bool ends_with (std::string big, std::string little);
}
obj.name = 'libdcp'
obj.target = 'dcp'
obj.export_includes = ['.']
- obj.uselib = 'BOOST_FILESYSTEM OPENSSL SIGC++'
+ obj.uselib = 'BOOST_FILESYSTEM OPENSSL SIGC++ LIBXML++'
obj.use = 'libkumu-libdcp libasdcp-libdcp'
obj.source = """
- dcp.cc
+ cpl.cc
+ dcp.cc
asset.cc
sound_asset.cc
picture_asset.cc
+ pkl.cc
util.cc
metadata.cc
version.cc
test_mode.cc
+ types.cc
+ xml.cc
"""
headers = """
+#include <sstream>
+#include <iostream>
+#include <boost/lexical_cast.hpp>
+#include <libxml++/libxml++.h>
#include "xml.h"
+#include "exceptions.h"
+#include "util.h"
-XMLFile::XMLFile (string file, string root_id)
+using namespace std;
+using namespace boost;
+using namespace libdcp;
+
+XMLNode::XMLNode ()
+ : _node (0)
{
- xmlpp::DomParser parser;
- parser.parse_file (file);
- if (!parser) {
- throw XMLError ("could not parse XML");
+
+}
+
+XMLNode::XMLNode (xmlpp::Node const * node)
+ : _node (node)
+{
+
+}
+
+xmlpp::Node *
+XMLNode::xml_node (string name)
+{
+ list<xmlpp::Node*> n = xml_nodes (name);
+ if (n.size() > 1) {
+ throw XMLError ("duplicate XML tag " + name);
+ } else if (n.empty ()) {
+ throw XMLError ("missing XML tag " + name);
}
+
+ return n.front ();
+}
- _root = parser.get_document()->get_root_node ();
- if (_root->get_name() != root_id) {
- throw XMLError ("unrecognised root node");
+list<xmlpp::Node*>
+XMLNode::xml_nodes (string name)
+{
+ /* XXX: using find / get_path should work here, but I can't follow
+ how get_path works.
+ */
+
+ xmlpp::Node::NodeList c = _node->get_children ();
+
+ list<xmlpp::Node*> n;
+ for (xmlpp::Node::NodeList::iterator i = c.begin (); i != c.end(); ++i) {
+ if ((*i)->get_name() == name) {
+ n.push_back (*i);
+ }
+ }
+
+ _taken.push_back (name);
+ return n;
+}
+
+string
+XMLNode::string_node (string name)
+{
+ xmlpp::Node* node = xml_node (name);
+
+ xmlpp::Node::NodeList c = node->get_children ();
+ if (c.size() != 1) {
+ throw XMLError ("unexpected content in XML node");
}
+
+ xmlpp::ContentNode const * v = dynamic_cast<xmlpp::ContentNode const *> (c.front());
+ if (!v) {
+ throw XMLError ("missing content in XML node");
+ }
+
+ return v->get_content ();
}
string
-XMLFile::string_tag (string id)
+XMLNode::optional_string_node (string name)
+{
+ list<xmlpp::Node*> nodes = xml_nodes (name);
+ if (nodes.size() > 2) {
+ throw XMLError ("duplicate XML tag " + name);
+ }
+
+ if (nodes.empty ()) {
+ return "";
+ }
+
+ return string_node (name);
+}
+
+ContentKind
+XMLNode::kind_node (string name)
+{
+ return content_kind_from_string (string_node (name));
+}
+
+Fraction
+XMLNode::fraction_node (string name)
+{
+ return Fraction (string_node (name));
+}
+
+int
+XMLNode::int_node (string name)
+{
+ return lexical_cast<int> (string_node (name));
+}
+
+void
+XMLNode::ignore_node (string name)
+{
+ _taken.push_back (name);
+}
+
+void
+XMLNode::done ()
+{
+ xmlpp::Node::NodeList c = _node->get_children ();
+ for (xmlpp::Node::NodeList::iterator i = c.begin(); i != c.end(); ++i) {
+ if (dynamic_cast<xmlpp::Element *> (*i) && find (_taken.begin(), _taken.end(), (*i)->get_name()) == _taken.end ()) {
+ throw XMLError ("unexpected XML node " + (*i)->get_name());
+ }
+ }
+}
+
+XMLFile::XMLFile (string file, string root_name)
{
- 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");
+ _parser = new xmlpp::DomParser;
+ _parser->parse_file (file);
+ if (!_parser) {
+ throw XMLError ("could not parse XML");
+ }
+
+ _node = _parser->get_document()->get_root_node ();
+ if (_node->get_name() != root_name) {
+ throw XMLError ("unrecognised root node");
}
- xml::Node::NodeList c = n.front()->get_children ();
- if (c.empty()
-
+ cout << this << " root node is " << _node->get_name() << "\n";
+}
- return n.front()->get_name ();
+XMLFile::~XMLFile ()
+{
+ delete _parser;
}
+#ifndef LIBDCP_XML_H
+#define LIBDCP_XML_H
-class XMLFile
+#include <string>
+#include <list>
+#include <glibmm.h>
+#include <boost/shared_ptr.hpp>
+#include "types.h"
+#include "exceptions.h"
+
+namespace xmlpp {
+ class Node;
+ class DomParser;
+}
+
+namespace libdcp {
+
+class XMLNode
{
public:
- XMLFile (std::string file);
+ XMLNode ();
+ XMLNode (xmlpp::Node const * node);
+
+protected:
+ std::string string_node (std::string);
+ std::string optional_string_node (std::string);
+ ContentKind kind_node (std::string);
+ Fraction fraction_node (std::string);
+ int int_node (std::string);
+ void ignore_node (std::string);
+ void done ();
+
+ template <class T>
+ boost::shared_ptr<T> sub_node (std::string name) {
+ return boost::shared_ptr<T> (new T (xml_node (name)));
+ }
+
+ template <class T>
+ boost::shared_ptr<T> optional_sub_node (std::string name) {
+ std::list<xmlpp::Node*> n = xml_nodes (name);
+ if (n.size() > 1) {
+ throw XMLError ("duplicate XML tag");
+ } else if (n.empty ()) {
+ return boost::shared_ptr<T> ();
+ }
+
+ return boost::shared_ptr<T> (new T (n.front ()));
+ }
+
+ template <class T>
+ std::list<boost::shared_ptr<T> > sub_nodes (std::string name) {
+ std::list<xmlpp::Node*> n = xml_nodes (name);
+ std::list<boost::shared_ptr<T> > r;
+ for (typename std::list<xmlpp::Node*>::iterator i = n.begin(); i != n.end(); ++i) {
+ r.push_back (boost::shared_ptr<T> (new T (*i)));
+ }
+ return r;
+ }
+
+ xmlpp::Node const * _node;
+
+private:
+ xmlpp::Node* xml_node (std::string);
+ std::list<xmlpp::Node*> xml_nodes (std::string);
+ std::list<Glib::ustring> _taken;
};
+
+class XMLFile : public XMLNode
+{
+public:
+ XMLFile (std::string file, std::string root_name);
+ virtual ~XMLFile ();
+
+private:
+ xmlpp::DomParser* _parser;
+};
+
+}
+
+#endif
t->issue_date = "2012-07-17T04:45:18+00:00";
filesystem::remove_all ("build/test/foo");
filesystem::create_directories ("build/test/foo");
- libdcp::DCP d ("build/test/foo", "A Test DCP", libdcp::DCP::FEATURE, 24, 24);
+ libdcp::DCP d ("build/test/foo", "A Test DCP", libdcp::FEATURE, 24, 24);
d.add_picture_asset (sigc::ptr_fun (&j2c), 32, 32);
d.add_sound_asset (sigc::ptr_fun (&wav), 2);
BOOST_AUTO_TEST_CASE (error_test)
{
- libdcp::DCP d ("build/test/bar", "A Test DCP", libdcp::DCP::TEST, 24, 24);
+ libdcp::DCP d ("build/test/bar", "A Test DCP", libdcp::TEST, 24, 24);
vector<string> p;
p.push_back ("frobozz");
BOOST_CHECK_THROW (d.add_picture_asset (p, 32, 32), libdcp::FileError);
--- /dev/null
+#include "dcp.h"
+
+using namespace libdcp;
+
+int
+main (int argc, char* argv[])
+{
+ DCP dcp ("/home/carl/src/dvdomatic-test/reference/dolby_aurora.vob/dolby_aurora.vob");
+ return 0;
+}
--- /dev/null
+def build(bld):
+ obj = bld(features = 'cxx cxxprogram')
+ obj.use = ['libdcp']
+ obj.source = 'dcpdiff.cc'
+ obj.target = 'dcpdiff'
def options(opt):
opt.load('compiler_cxx')
opt.add_option('--target-windows', action='store_true', default = False, help = 'set up to do a cross-compile to Windows')
+ opt.add_option('--enable-debug', action='store_true', default = False, help = 'build with debugging information and without optimisation')
def configure(conf):
conf.load('compiler_cxx')
conf.check_cfg(package = 'openssl', args = '--cflags --libs', uselib_store = 'OPENSSL', mandatory = True)
conf.check_cfg(package = 'sigc++-2.0', args = '--cflags --libs', uselib_store = 'SIGC++', mandatory = True)
+ conf.check_cfg(package = 'libxml++-2.6', args = '--cflags --libs', uselib_store = 'LIBXML++', mandatory = True)
if conf.options.target_windows:
boost_lib_suffix = '-mt'
else:
boost_lib_suffix = ''
-
+
+ if conf.options.enable_debug:
+ conf.env.append_value('CXXFLAGS', '-g')
+ else:
+ conf.env.append_value('CXXFLAGS', '-O3')
+
conf.check_cxx(fragment = """
#include <boost/filesystem.hpp>\n
int main() { boost::filesystem::copy_file ("a", "b"); }\n
install_path = '${LIBDIR}/pkgconfig')
bld.recurse('src')
+ bld.recurse('tools')
bld.recurse('test')
bld.recurse('asdcplib')