From aef58f7a1caf6a67c2c0b12ba3a6bc632d890f4e Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Tue, 1 Jan 2013 23:17:07 +0000 Subject: Use libxml++ to write CPLs. --- src/asset.h | 10 ++-- src/dcp.cc | 130 ++++++++++++++++++++++++++------------------------ src/picture_asset.cc | 25 +++++----- src/picture_asset.h | 6 +-- src/reel.cc | 17 +++---- src/reel.h | 6 ++- src/sound_asset.cc | 18 +++---- src/sound_asset.h | 6 +-- src/subtitle_asset.cc | 14 +++--- src/subtitle_asset.h | 6 ++- 10 files changed, 129 insertions(+), 109 deletions(-) (limited to 'src') 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 << "\n" - << "\n" - << " urn:uuid:" << _uuid << "\n" - << " " << _name << "\n" - << " " << Metadata::instance()->issue_date << "\n" - << " " << Metadata::instance()->creator << "\n" - << " " << _name << "\n" - << " " << content_kind_to_string (_content_kind) << "\n" - << " \n" - << " urn:uri:" << _uuid << "_" << Metadata::instance()->issue_date << "\n" - << " " << _uuid << "_" << Metadata::instance()->issue_date << "\n" - << " \n" - << " \n" - << " \n"; - - for (list >::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 << " \n" - << " \n" - << " \n"; + cpl->add_child("RatingList"); + + xmlpp::Element* reel_list = cpl->add_child("ReelList"); + for (list >::const_iterator i = _reels.begin(); i != _reels.end(); ++i) { + (*i)->write_to_cpl (reel_list); + } if (encrypted) { - os << " \n" - << " \n" - << " \n" - << " " << Certificate::name_for_xml (certificates.leaf()->issuer()) << "\n" - << " " << certificates.leaf()->serial() << "\n" - << " \n" - << " " << Certificate::name_for_xml (certificates.leaf()->subject()) << "\n" - << " \n" - << " \n" - << " \n" - << " \n" - << " \n" - << " \n" - << " \n" - << " \n" - << " \n" - << " \n" - << " \n" - /* this is done by xmlsec1 in cinemaslides */ - << " " << "XXX" << "\n" - << " \n" - << " \n" - /* this is done by xmlsec1 in cinemaslides */ - << " " << "XXX" << "\n"; - - os << " \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 > c = certificates.leaf_to_root (); for (list >::iterator i = c.begin(); i != c.end(); ++i) { - os << " \n" - << " \n" - << " " << Certificate::name_for_xml ((*i)->issuer()) << "\n" - << " " << (*i)->serial() << "\n" - << " \n" - << " " << "XXX" << "\n" - << " \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 << " \n"; - os << " \n"; } - - os << "\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 #include #include +#include #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 << " \n" - << " urn:uuid:" << _uuid << "\n" - << " " << _file_name << "\n" - << " " << _fps << " 1\n" - << " " << _length << "\n" - << " 0\n" - << " " << _length << "\n" - << " " << _fps << " 1\n" - << " " << _width << " " << _height << "\n" - << " \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 (_fps) + " 1"); + main_picture->add_child("IntrinsicDuration")->add_child_text(boost::lexical_cast (_length)); + main_picture->add_child("EntryPoint")->add_child_text("0"); + main_picture->add_child("Duration")->add_child_text(boost::lexical_cast (_length)); + main_picture->add_child("FrameRate")->add_child_text(boost::lexical_cast (_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* 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 other, EqualityOptions opt, std::list& 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 #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 << " \n" - << " urn:uuid:" << make_uuid() << "\n" - << " \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 #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 other, EqualityOptions opt, std::list& 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 #include #include +#include #include "KM_fileio.h" #include "AS_DCP.h" #include "sound_asset.h" @@ -191,16 +192,15 @@ SoundAsset::construct (boost::function get_path) } void -SoundAsset::write_to_cpl (ostream& s) const +SoundAsset::write_to_cpl (xmlpp::Element* parent) const { - s << " \n" - << " urn:uuid:" << _uuid << "\n" - << " " << _file_name << "\n" - << " " << _fps << " 1\n" - << " " << _length << "\n" - << " 0\n" - << " " << _length << "\n" - << " \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 (_fps) + " 1"); + main_sound->add_child("IntrinsicDuration")->add_child_text(boost::lexical_cast (_length)); + main_sound->add_child("EntryPoint")->add_child_text("0"); + main_sound->add_child("Duration")->add_child_text(boost::lexical_cast (_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 other, EqualityOptions opt, std::list& 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 #include #include +#include #include "subtitle_asset.h" #include "util.h" @@ -375,15 +376,14 @@ SubtitleAsset::add (shared_ptr 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 << " \n" - << " urn:uuid:" << _uuid << "\n" - << " " << _file_name << "\n" - << " 0\n" - << " \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, EqualityOptions, std::list& notes) const { /* XXX */ notes.push_back ("subtitle assets not compared yet"); -- cgit v1.2.3