Throw exceptions with badly-formed XML when reading a DCP; preserve detail in DCPRead...
[libdcp.git] / src / smpte_subtitle_asset.cc
index 3b30a0c71a5be7edd1dff883c3cbfe48cb5f1976..c85afc2e268cd2ba8588b6b406047f095b67a053 100644 (file)
@@ -66,6 +66,7 @@ SMPTESubtitleAsset::SMPTESubtitleAsset ()
        : _intrinsic_duration (0)
        , _edit_rate (24, 1)
        , _time_code_rate (24)
+       , _xml_id (make_uuid ())
 {
 
 }
@@ -99,7 +100,7 @@ SMPTESubtitleAsset::SMPTESubtitleAsset (boost::filesystem::path file)
                        xml.reset (new cxml::Document ("SubtitleReel"));
                        xml->read_file (file);
                        parse_xml (xml);
-                       _id = remove_urn_uuid (xml->string_child ("Id"));
+                       _id = _xml_id = remove_urn_uuid (xml->string_child ("Id"));
                } catch (cxml::Error& e) {
                        boost::throw_exception (
                                DCPReadError (
@@ -116,6 +117,7 @@ SMPTESubtitleAsset::SMPTESubtitleAsset (boost::filesystem::path file)
 void
 SMPTESubtitleAsset::parse_xml (shared_ptr<cxml::Document> xml)
 {
+       _xml_id = remove_urn_uuid(xml->string_child("Id"));
        _load_font_nodes = type_children<dcp::SMPTELoadFontNode> (xml, "LoadFont");
 
        _content_title_text = xml->string_child ("ContentTitleText");
@@ -198,11 +200,17 @@ SMPTESubtitleAsset::read_mxf_descriptor (shared_ptr<ASDCP::TimedText::MXFReader>
 void
 SMPTESubtitleAsset::set_key (Key key)
 {
+       /* See if we already have a key; if we do, and we have a file, we'll already
+          have read that file.
+       */
+       bool const had_key = static_cast<bool> (_key);
+
        MXF::set_key (key);
 
-       if (!_key_id || !_file) {
-               /* Either we don't have any data to read, or it wasn't
-                  encrypted, so we don't need to do anything else.
+       if (!_key_id || !_file || had_key) {
+               /* Either we don't have any data to read, it wasn't
+                  encrypted, or we've already read it, so we don't
+                  need to do anything else.
                */
                return;
        }
@@ -252,7 +260,7 @@ SMPTESubtitleAsset::xml_as_string () const
        root->set_namespace_declaration ("http://www.smpte-ra.org/schemas/428-7/2010/DCST", "dcst");
        root->set_namespace_declaration ("http://www.w3.org/2001/XMLSchema", "xs");
 
-       root->add_child("Id", "dcst")->add_child_text ("urn:uuid:" + _id);
+       root->add_child("Id", "dcst")->add_child_text ("urn:uuid:" + _xml_id);
        root->add_child("ContentTitleText", "dcst")->add_child_text (_content_title_text);
        if (_annotation_text) {
                root->add_child("AnnotationText", "dcst")->add_child_text (_annotation_text.get ());
@@ -278,7 +286,7 @@ SMPTESubtitleAsset::xml_as_string () const
 
        subtitles_as_xml (root->add_child ("SubtitleList", "dcst"), _time_code_rate, SMPTE);
 
-       return doc.write_to_string_formatted ("UTF-8");
+       return doc.write_to_string ("UTF-8");
 }
 
 /** Write this content to a MXF file */