summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorCarl Hetherington <cth@carlh.net>2013-01-01 23:17:07 +0000
committerCarl Hetherington <cth@carlh.net>2013-01-01 23:17:07 +0000
commitaef58f7a1caf6a67c2c0b12ba3a6bc632d890f4e (patch)
treede09dea793415454c0e656b5cfd27a027abc8f57 /src
parent039ea029c811b7f74f02befad10d2106ad645e74 (diff)
Use libxml++ to write CPLs.
Diffstat (limited to 'src')
-rw-r--r--src/asset.h10
-rw-r--r--src/dcp.cc130
-rw-r--r--src/picture_asset.cc25
-rw-r--r--src/picture_asset.h6
-rw-r--r--src/reel.cc17
-rw-r--r--src/reel.h6
-rw-r--r--src/sound_asset.cc18
-rw-r--r--src/sound_asset.h6
-rw-r--r--src/subtitle_asset.cc14
-rw-r--r--src/subtitle_asset.h6
10 files changed, 129 insertions, 109 deletions
diff --git a/src/asset.h b/src/asset.h
index cc6fbcb7..4a52e819 100644
--- a/src/asset.h
+++ b/src/asset.h
@@ -33,6 +33,10 @@ namespace ASDCP {
class WriterInfo;
}
+namespace xmlpp {
+ class Element;
+}
+
namespace libdcp
{
@@ -51,10 +55,10 @@ public:
virtual ~Asset() {}
- /** Write details of the asset to a CPL stream.
- * @param s Stream.
+ /** Write details of the asset to a CPL AssetList node.
+ * @param p Parent node.
*/
- virtual void write_to_cpl (std::ostream& s) const = 0;
+ virtual void write_to_cpl (xmlpp::Element* p) const = 0;
/** Write details of the asset to a PKL stream.
* @param s Stream.
diff --git a/src/dcp.cc b/src/dcp.cc
index 647ff7f6..bd3cc80b 100644
--- a/src/dcp.cc
+++ b/src/dcp.cc
@@ -293,7 +293,7 @@ DCP::assets () const
a.merge (t);
}
- a.sort ();
+ a.sort (AssetComparator ());
a.unique ();
return a;
}
@@ -431,77 +431,81 @@ CPL::write_xml (bool encrypted, CertificateChain const & certificates) const
stringstream s;
s << _uuid << "_cpl.xml";
p /= s.str();
- ofstream os (p.string().c_str());
-
- os << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
- << "<CompositionPlaylist xmlns=\"http://www.smpte-ra.org/schemas/429-7/2006/CPL\">\n"
- << " <Id>urn:uuid:" << _uuid << "</Id>\n"
- << " <AnnotationText>" << _name << "</AnnotationText>\n"
- << " <IssueDate>" << Metadata::instance()->issue_date << "</IssueDate>\n"
- << " <Creator>" << Metadata::instance()->creator << "</Creator>\n"
- << " <ContentTitleText>" << _name << "</ContentTitleText>\n"
- << " <ContentKind>" << content_kind_to_string (_content_kind) << "</ContentKind>\n"
- << " <ContentVersion>\n"
- << " <Id>urn:uri:" << _uuid << "_" << Metadata::instance()->issue_date << "</Id>\n"
- << " <LabelText>" << _uuid << "_" << Metadata::instance()->issue_date << "</LabelText>\n"
- << " </ContentVersion>\n"
- << " <RatingList/>\n"
- << " <ReelList>\n";
-
- for (list<shared_ptr<const Reel> >::const_iterator i = _reels.begin(); i != _reels.end(); ++i) {
- (*i)->write_to_cpl (os);
+
+ xmlpp::Document doc;
+ xmlpp::Element* cpl = doc.create_root_node("CompositionPlaylist", "http://www.smpte-ra.org/schemas/429-7/2006/CPL");
+
+ cpl->add_child("Id")->add_child_text ("urn:uuid:" + _uuid);
+ cpl->add_child("AnnotationText")->add_child_text (_name);
+ cpl->add_child("IssueDate")->add_child_text (Metadata::instance()->issue_date);
+ cpl->add_child("Creator")->add_child_text (Metadata::instance()->creator);
+ cpl->add_child("ContentTitleText")->add_child_text (_name);
+ cpl->add_child("ContentKind")->add_child_text (content_kind_to_string (_content_kind));
+
+ {
+ xmlpp::Element* cv = cpl->add_child ("ContentVersion");
+ cv->add_child("Id")->add_child_text ("urn:uri:" + _uuid + "_" + Metadata::instance()->issue_date);
+ cv->add_child("LabelText")->add_child_text (_uuid + "_" + Metadata::instance()->issue_date);
}
- os << " </AssetList>\n"
- << " </Reel>\n"
- << " </ReelList>\n";
+ cpl->add_child("RatingList");
+
+ xmlpp::Element* reel_list = cpl->add_child("ReelList");
+ for (list<shared_ptr<const Reel> >::const_iterator i = _reels.begin(); i != _reels.end(); ++i) {
+ (*i)->write_to_cpl (reel_list);
+ }
if (encrypted) {
- os << " <Signer>\n"
- << " <dsig:X509Data>\n"
- << " <dsig:X509IssuerSerial>\n"
- << " <dsig:X509IssuerName>" << Certificate::name_for_xml (certificates.leaf()->issuer()) << "</dsig:IssuerName>\n"
- << " <dsig:X509SerialNumber>" << certificates.leaf()->serial() << "</dsig:X509SerialNumber>\n"
- << " <dsig:X509IssuerSerial>\n"
- << " <dsig:X509SubjectName>" << Certificate::name_for_xml (certificates.leaf()->subject()) << "</dsig:X509SubjectName>\n"
- << " </dsig:X509Data>\n"
- << " </Signer>\n"
- << " <dsig:Signature>\n"
- << " <dsig:SignedInfo>\n"
- << " <dsig:CanonicalizationMethod Algorithm=\"http://www.w3.org/TR/2001/REC-xml-c14n-20010315\"/>\n"
- << " <dsig:SignatureMethod Algorithm=\"http://www.w3.org/2001/04/xmldsig-more#rsa-sha256\"/>\n"
- << " <dsig:Reference URI=\"\">\n"
- << " <dsig:Transforms>\n"
- << " <dsig:Transform Algorithm=\"http://www.w3.org/2000/09/xmldsig#enveloped-signature\"/>\n"
- << " </dsig:Transforms>\n"
- << " <dsig:DigestMethod Algorithm=\"http://www.w3.org/2000/09/xmldsig#sha1\"/>\n"
- /* this is done by xmlsec1 in cinemaslides */
- << " <dsig:DigestValue>" << "XXX" << "</dsig:DigestValue>\n"
- << " </dsig:Reference>\n"
- << " </dsig:SignedInfo>\n"
- /* this is done by xmlsec1 in cinemaslides */
- << " <dsig:SignatureValue>" << "XXX" << "</dsig:SignatureValue>\n";
-
- os << " <dsig:KeyInfo>\n";
-
+ xmlpp::Element* signer = cpl->add_child("Signer");
+ {
+ xmlpp::Element* data = signer->add_child("X509Data", "dsig");
+ {
+ xmlpp::Element* serial = data->add_child("X509IssuerSerial", "dsig");
+ serial->add_child("X509IssuerName", "dsig")->add_child_text (
+ Certificate::name_for_xml (certificates.leaf()->issuer())
+ );
+ serial->add_child("X509SerialNumber", "dsig")->add_child_text (
+ certificates.leaf()->serial()
+ );
+ }
+ data->add_child("X509SubjectName", "dsig")->add_child_text (
+ Certificate::name_for_xml (certificates.leaf()->subject())
+ );
+ }
+
+ xmlpp::Element* signature = cpl->add_child("Signature", "dsig");
+ {
+ xmlpp::Element* signed_info = signature->add_child ("SignedInfo", "dsig");
+ signed_info->add_child("CanonicalizationMethod", "dsig")->set_attribute ("Algorithm", "http://www.w3.org/TR/2001/REC-xml-c14n-20010315");
+ signed_info->add_child("SignatureMethod", "dsig")->set_attribute("Algorithm", "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256");
+ {
+ xmlpp::Element* reference = signature->add_child("Reference", "dsig");
+ reference->set_attribute ("URI", "");
+ {
+ xmlpp::Element* transforms = reference->add_child("Transforms", "dsig");
+ transforms->add_child("Transform", "dsig")->set_attribute (
+ "Algorithm", "http://www.w3.org/2000/09/xmldsig#enveloped-signature"
+ );
+ }
+ reference->add_child("DigestMethod", "dsig")->set_attribute("Algorithm", "http://www.w3.org/2000/09/xmldsig#sha1");
+ }
+ }
+
list<shared_ptr<Certificate> > c = certificates.leaf_to_root ();
for (list<shared_ptr<Certificate> >::iterator i = c.begin(); i != c.end(); ++i) {
- os << " <dsig:X509Data>\n"
- << " <dsig:X509IssuerSerial>\n"
- << " <dsig:X509IssuerName>" << Certificate::name_for_xml ((*i)->issuer()) << "</dsig:IssuerName>\n"
- << " <dsig:X509SerialNumber>" << (*i)->serial() << "</dsig:X509SerialNumber>\n"
- << " </dsig:X509IssuerSerial>\n"
- << " <dsig:X509Certificate>" << "XXX" << "</dsig:X509Certificate>\n"
- << " </dsig:X509Data>\n";
+ xmlpp::Element* data = signature->add_child("X509Data", "dsig");
+ {
+ xmlpp::Element* serial = data->add_child("X509IssuerSerial", "data");
+ serial->add_child("X509IssuerName", "dsig")->add_child_text(
+ Certificate::name_for_xml ((*i)->issuer())
+ );
+ serial->add_child("X509SerialNumber", "dsig")->add_child_text((*i)->serial());
+ serial->add_child("X509Certificate", "dsig")->add_child_text("XXX");
+ }
}
-
- os << " </dsig:KeyInfo>\n";
- os << " </dsig:Signature>\n";
}
-
- os << "</CompositionPlaylist>\n";
- os.close ();
+ doc.write_to_file_formatted (p.string(), "UTF-8");
_digest = make_digest (p.string (), 0);
_length = boost::filesystem::file_size (p.string ());
diff --git a/src/picture_asset.cc b/src/picture_asset.cc
index f2c489e7..e7cb8757 100644
--- a/src/picture_asset.cc
+++ b/src/picture_asset.cc
@@ -29,6 +29,7 @@
#include <boost/filesystem.hpp>
#include <boost/lexical_cast.hpp>
#include <openjpeg.h>
+#include <libxml++/nodes/element.h>
#include "AS_DCP.h"
#include "KM_fileio.h"
#include "picture_asset.h"
@@ -41,6 +42,7 @@ using std::ostream;
using std::list;
using std::vector;
using std::max;
+using std::stringstream;
using boost::shared_ptr;
using boost::dynamic_pointer_cast;
using boost::lexical_cast;
@@ -55,18 +57,19 @@ PictureAsset::PictureAsset (string directory, string mxf_name, boost::signals2::
}
void
-PictureAsset::write_to_cpl (ostream& s) const
+PictureAsset::write_to_cpl (xmlpp::Element* parent) const
{
- s << " <MainPicture>\n"
- << " <Id>urn:uuid:" << _uuid << "</Id>\n"
- << " <AnnotationText>" << _file_name << "</AnnotationText>\n"
- << " <EditRate>" << _fps << " 1</EditRate>\n"
- << " <IntrinsicDuration>" << _length << "</IntrinsicDuration>\n"
- << " <EntryPoint>0</EntryPoint>\n"
- << " <Duration>" << _length << "</Duration>\n"
- << " <FrameRate>" << _fps << " 1</FrameRate>\n"
- << " <ScreenAspectRatio>" << _width << " " << _height << "</ScreenAspectRatio>\n"
- << " </MainPicture>\n";
+ xmlpp::Element* main_picture = parent->add_child("MainPicture");
+ main_picture->add_child("Id")->add_child_text("urn:uuid:" + _uuid);
+ main_picture->add_child("AnnotationText")->add_child_text(_file_name);
+ main_picture->add_child("EditRate")->add_child_text(boost::lexical_cast<string> (_fps) + " 1");
+ main_picture->add_child("IntrinsicDuration")->add_child_text(boost::lexical_cast<string> (_length));
+ main_picture->add_child("EntryPoint")->add_child_text("0");
+ main_picture->add_child("Duration")->add_child_text(boost::lexical_cast<string> (_length));
+ main_picture->add_child("FrameRate")->add_child_text(boost::lexical_cast<string> (_fps) + " 1");
+ stringstream sar;
+ sar << _width << " " << _height;
+ main_picture->add_child("ScreenAspectRatio")->add_child_text(sar.str());
}
bool
diff --git a/src/picture_asset.h b/src/picture_asset.h
index 53c62223..15764dab 100644
--- a/src/picture_asset.h
+++ b/src/picture_asset.h
@@ -38,10 +38,10 @@ public:
std::string directory, std::string mxf_name, boost::signals2::signal<void (float)>* progress, int fps, int entry_point, int length, bool encrypted
);
- /** Write details of this asset to a CPL stream.
- * @param s Stream.
+ /** Write details of the asset to a CPL AssetList node.
+ * @param p Parent node.
*/
- void write_to_cpl (std::ostream& s) const;
+ void write_to_cpl (xmlpp::Element* p) const;
bool equals (boost::shared_ptr<const Asset> other, EqualityOptions opt, std::list<std::string>& notes) const;
diff --git a/src/reel.cc b/src/reel.cc
index 52a4f0fb..d8703dd0 100644
--- a/src/reel.cc
+++ b/src/reel.cc
@@ -17,6 +17,7 @@
*/
+#include <libxml++/nodes/element.h>
#include "reel.h"
#include "util.h"
#include "picture_asset.h"
@@ -27,22 +28,22 @@ using namespace std;
using namespace libdcp;
void
-Reel::write_to_cpl (ostream& s) const
+Reel::write_to_cpl (xmlpp::Node* parent) const
{
- s << " <Reel>\n"
- << " <Id>urn:uuid:" << make_uuid() << "</Id>\n"
- << " <AssetList>\n";
-
+ xmlpp::Element* reel = parent->add_child("Reel");
+ reel->add_child("Id")->add_child_text("urn:uuid:" + make_uuid());
+ xmlpp::Element* asset_list = reel->add_child("AssetList");
+
if (_main_picture) {
- _main_picture->write_to_cpl (s);
+ _main_picture->write_to_cpl (asset_list);
}
if (_main_sound) {
- _main_sound->write_to_cpl (s);
+ _main_sound->write_to_cpl (asset_list);
}
if (_main_subtitle) {
- _main_subtitle->write_to_cpl (s);
+ _main_subtitle->write_to_cpl (asset_list);
}
}
diff --git a/src/reel.h b/src/reel.h
index 08a438dd..52b3951a 100644
--- a/src/reel.h
+++ b/src/reel.h
@@ -21,6 +21,10 @@
#include <boost/shared_ptr.hpp>
#include "types.h"
+namespace xmlpp {
+ class Node;
+}
+
namespace libdcp {
class PictureAsset;
@@ -52,7 +56,7 @@ public:
return _main_subtitle;
}
- void write_to_cpl (std::ostream & s) const;
+ void write_to_cpl (xmlpp::Node *) const;
bool equals (boost::shared_ptr<const Reel> other, EqualityOptions opt, std::list<std::string>& notes) const;
diff --git a/src/sound_asset.cc b/src/sound_asset.cc
index 5e52da8e..6ab7f031 100644
--- a/src/sound_asset.cc
+++ b/src/sound_asset.cc
@@ -25,6 +25,7 @@
#include <stdexcept>
#include <boost/filesystem.hpp>
#include <boost/lexical_cast.hpp>
+#include <libxml++/nodes/element.h>
#include "KM_fileio.h"
#include "AS_DCP.h"
#include "sound_asset.h"
@@ -191,16 +192,15 @@ SoundAsset::construct (boost::function<string (Channel)> get_path)
}
void
-SoundAsset::write_to_cpl (ostream& s) const
+SoundAsset::write_to_cpl (xmlpp::Element* parent) const
{
- s << " <MainSound>\n"
- << " <Id>urn:uuid:" << _uuid << "</Id>\n"
- << " <AnnotationText>" << _file_name << "</AnnotationText>\n"
- << " <EditRate>" << _fps << " 1</EditRate>\n"
- << " <IntrinsicDuration>" << _length << "</IntrinsicDuration>\n"
- << " <EntryPoint>0</EntryPoint>\n"
- << " <Duration>" << _length << "</Duration>\n"
- << " </MainSound>\n";
+ xmlpp::Element* main_sound = parent->add_child("MainSound");
+ main_sound->add_child("Id")->add_child_text("urn:uuid:" + _uuid);
+ main_sound->add_child("AnnotationText")->add_child_text(_file_name);
+ main_sound->add_child("EditRate")->add_child_text(boost::lexical_cast<string> (_fps) + " 1");
+ main_sound->add_child("IntrinsicDuration")->add_child_text(boost::lexical_cast<string> (_length));
+ main_sound->add_child("EntryPoint")->add_child_text("0");
+ main_sound->add_child("Duration")->add_child_text(boost::lexical_cast<string> (_length));
}
bool
diff --git a/src/sound_asset.h b/src/sound_asset.h
index 4633b9a7..0a6c8f4e 100644
--- a/src/sound_asset.h
+++ b/src/sound_asset.h
@@ -86,10 +86,10 @@ public:
int length
);
- /** Write details of this asset to a CPL stream.
- * @param s Stream.
+ /** Write details of the asset to a CPL AssetList node.
+ * @param p Parent node.
*/
- void write_to_cpl (std::ostream& s) const;
+ void write_to_cpl (xmlpp::Element* p) const;
bool equals (boost::shared_ptr<const Asset> other, EqualityOptions opt, std::list<std::string>& notes) const;
diff --git a/src/subtitle_asset.cc b/src/subtitle_asset.cc
index c7051eae..998abc07 100644
--- a/src/subtitle_asset.cc
+++ b/src/subtitle_asset.cc
@@ -20,6 +20,7 @@
#include <fstream>
#include <boost/lexical_cast.hpp>
#include <boost/algorithm/string.hpp>
+#include <libxml++/nodes/element.h>
#include "subtitle_asset.h"
#include "util.h"
@@ -375,15 +376,14 @@ SubtitleAsset::add (shared_ptr<Subtitle> s)
}
void
-SubtitleAsset::write_to_cpl (ostream& s) const
+SubtitleAsset::write_to_cpl (xmlpp::Element* parent) const
{
/* XXX: should EditRate, Duration and IntrinsicDuration be in here? */
-
- s << " <MainSubtitle>\n"
- << " <Id>urn:uuid:" << _uuid << "</Id>\n"
- << " <AnnotationText>" << _file_name << "</AnnotationText>\n"
- << " <EntryPoint>0</EntryPoint>\n"
- << " </MainSubtitle>\n";
+
+ xmlpp::Element* main_subtitle = parent->add_child("MainSubtitle");
+ main_subtitle->add_child("Id")->add_child_text("urn:uuid:" + _uuid);
+ main_subtitle->add_child("AnnotationText")->add_child_text(_file_name);
+ main_subtitle->add_child("EntryPoint")->add_child_text("0");
}
struct SubtitleSorter {
diff --git a/src/subtitle_asset.h b/src/subtitle_asset.h
index 71ae42fc..f4a57151 100644
--- a/src/subtitle_asset.h
+++ b/src/subtitle_asset.h
@@ -183,7 +183,11 @@ public:
SubtitleAsset (std::string directory, std::string xml_file);
SubtitleAsset (std::string directory, std::string movie_title, std::string language);
- void write_to_cpl (std::ostream&) const;
+ /** Write details of the asset to a CPL AssetList node.
+ * @param p Parent node.
+ */
+ void write_to_cpl (xmlpp::Element* p) const;
+
virtual bool equals (boost::shared_ptr<const Asset>, EqualityOptions, std::list<std::string>& notes) const {
/* XXX */
notes.push_back ("subtitle assets not compared yet");