Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion format.sh
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ src/elements/audio_track_format_id.cpp
src/elements/audio_block_format_id.cpp
src/elements/audio_block_format_hoa.cpp
src/document.cpp
src/private/xml_parser.cpp
include/adm/elements/audio_block_format_hoa.hpp
include/adm/elements/audio_pack_format.hpp
include/adm/elements/audio_channel_format.hpp
Expand Down
2 changes: 0 additions & 2 deletions include/adm/private/rapidxml_formatter.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@ namespace adm {

class XmlNode;

void formatAudioProgramme(
XmlNode &node, const std::shared_ptr<const AudioProgramme> programme);
void formatLabel(XmlNode &node, const Label &label);
void formatAudioComplementaryObjectGroupLabel(
XmlNode &node, const AudioComplementaryObjectGroupLabel &label);
Expand Down
52 changes: 29 additions & 23 deletions include/adm/private/xml_parser.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,10 @@ namespace adm {
AudioProgrammeReferenceScreen parseAudioProgrammeReferenceScreen(
NodePtr node);
Label parseLabel(NodePtr node);
AudioBlockFormatObjects parseAudioBlockFormatObjects(NodePtr node);
Gain parseGain(NodePtr node);
ChannelLock parseChannelLock(NodePtr node);
ObjectDivergence parseObjectDivergence(NodePtr node);
JumpPosition parseJumpPosition(NodePtr node);
AudioBlockFormatDirectSpeakers parseAudioBlockFormatDirectSpeakers(
NodePtr node);
SphericalSpeakerPosition parseSphericalSpeakerPosition(
const std::vector<std::pair<NodePtr, SphericalCoordinateValue>>&
sphericalCoordinates);
Expand All @@ -61,36 +58,45 @@ namespace adm {
SpeakerPosition parseSpeakerPosition(std::vector<NodePtr> node);
SpeakerLabel parseSpeakerLabel(NodePtr node);
HeadphoneVirtualise parseHeadphoneVirtualise(NodePtr node);
AudioBlockFormatHoa parseAudioBlockFormatHoa(NodePtr node);
AudioBlockFormatBinaural parseAudioBlockFormatBinaural(NodePtr node);

NodePtr findAudioFormatExtendedNodeEbuCore(NodePtr root);
NodePtr findAudioFormatExtendedNodeFullRecursive(NodePtr root);
class XmlParser {
public:
explicit XmlParser(
const std::string& filename,
ParserOptions options = ParserOptions::none,
std::shared_ptr<Document> destDocument = Document::create());
explicit XmlParser(
std::istream& stream, ParserOptions options = ParserOptions::none,
std::shared_ptr<Document> destDocument = Document::create());
explicit XmlParser(std::shared_ptr<Document> destDocument,
ParserOptions options = ParserOptions::none);

std::shared_ptr<Document> parse();
void parseFile(const std::string& filename);
void parseStream(std::istream& stream);
void parseString(const std::string& xmlString);
void parseXmlFile(rapidxml::file<>& xmlFile);
void parseXml(const rapidxml::xml_document<>& xmlDocument);

bool hasUnresolvedReferences();

private:
std::shared_ptr<AudioProgramme> parseAudioProgramme(NodePtr node);
std::shared_ptr<AudioContent> parseAudioContent(NodePtr node);
std::shared_ptr<AudioObject> parseAudioObject(NodePtr node);
std::shared_ptr<AudioTrackFormat> parseAudioTrackFormat(NodePtr node);
std::shared_ptr<AudioStreamFormat> parseAudioStreamFormat(NodePtr node);
std::shared_ptr<AudioPackFormat> parseAudioPackFormat(NodePtr node);
std::shared_ptr<AudioTrackUid> parseAudioTrackUid(NodePtr node);
std::shared_ptr<AudioChannelFormat> parseAudioChannelFormat(NodePtr node);
protected:
virtual std::shared_ptr<AudioProgramme> parseAudioProgramme(NodePtr node);
virtual std::shared_ptr<AudioContent> parseAudioContent(NodePtr node);
virtual std::shared_ptr<AudioObject> parseAudioObject(NodePtr node);
virtual std::shared_ptr<AudioTrackFormat> parseAudioTrackFormat(
NodePtr node);
virtual std::shared_ptr<AudioStreamFormat> parseAudioStreamFormat(
NodePtr node);
virtual std::shared_ptr<AudioPackFormat> parseAudioPackFormat(
NodePtr node);
virtual std::shared_ptr<AudioTrackUid> parseAudioTrackUid(NodePtr node);
virtual std::shared_ptr<AudioChannelFormat> parseAudioChannelFormat(
NodePtr node);

rapidxml::file<> xmlFile_;
virtual AudioBlockFormatObjects parseAudioBlockFormatObjects(
NodePtr node);
virtual AudioBlockFormatDirectSpeakers
parseAudioBlockFormatDirectSpeakers(NodePtr node);
virtual AudioBlockFormatHoa parseAudioBlockFormatHoa(NodePtr node);
virtual AudioBlockFormatBinaural parseAudioBlockFormatBinaural(
NodePtr node);

private:
ParserOptions options_;
std::shared_ptr<Document> document_;

Expand Down
7 changes: 4 additions & 3 deletions include/adm/private/xml_parser_helper.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ namespace adm {
* @returns NodePtr to first element or a nullptr if no element could
* not be found.
*/
NodePtr findElement(NodePtr node, const std::string& name) {
inline NodePtr findElement(NodePtr node, const std::string& name) {
for (NodePtr elementNode = node->first_node(); elementNode;
elementNode = elementNode->next_sibling()) {
if (std::string(elementNode->name()) == name) {
Expand All @@ -79,7 +79,8 @@ namespace adm {
* @returns a vector of NodePtr or an empty vector if no element could
* not be found.
*/
std::vector<NodePtr> findElements(NodePtr node, const std::string& name) {
inline std::vector<NodePtr> findElements(NodePtr node,
const std::string& name) {
std::vector<NodePtr> elements;
for (NodePtr elementNode = node->first_node(); elementNode;
elementNode = elementNode->next_sibling()) {
Expand Down Expand Up @@ -342,7 +343,7 @@ namespace adm {
}
}

FormatDescriptor checkFormat(
inline FormatDescriptor checkFormat(
boost::optional<FormatDescriptor> formatLabel,
boost::optional<FormatDescriptor> formatDefinition) {
if (formatLabel != boost::none && formatDefinition != boost::none) {
Expand Down
9 changes: 9 additions & 0 deletions include/adm/private/xml_writer.hpp
Original file line number Diff line number Diff line change
@@ -1,17 +1,26 @@
#pragma once
#include "adm/write.hpp"
#include <memory>

namespace adm {
class Document;
class AudioProgramme;

namespace xml {

class XmlNode;

class XmlWriter {
public:
explicit XmlWriter(WriterOptions options = WriterOptions::none);

std::ostream& write(std::shared_ptr<const Document> document,
std::ostream& stream);

protected:
virtual void formatAudioProgramme(
XmlNode& node, const std::shared_ptr<const AudioProgramme> programme);

private:
WriterOptions options_;
};
Expand Down
9 changes: 7 additions & 2 deletions src/common_definitions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -158,9 +158,14 @@ namespace adm {
std::shared_ptr<Document> getCommonDefinitions() {
std::stringstream commonDefinitions;
getEmbeddedFile("common_definitions.xml", commonDefinitions);
xml::XmlParser parser(commonDefinitions,

std::shared_ptr<Document> destDocument = Document::create();

xml::XmlParser parser(destDocument,
xml::ParserOptions::recursive_node_search);
return parser.parse();
parser.parseStream(commonDefinitions);

return destDocument;
}

void addCommonDefinitionsTo(std::shared_ptr<Document> document) {
Expand Down
18 changes: 12 additions & 6 deletions src/parse.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,21 @@ namespace adm {

std::shared_ptr<Document> parseXml(const std::string& filename,
xml::ParserOptions options) {
auto commonDefinitions = getCommonDefinitions();
xml::XmlParser parser(filename, options, commonDefinitions);
return parser.parse();
std::shared_ptr<Document> doc = getCommonDefinitions();

xml::XmlParser parser(doc, options);
parser.parseFile(filename);

return doc;
}

std::shared_ptr<Document> parseXml(std::istream& stream,
xml::ParserOptions options) {
auto commonDefinitions = getCommonDefinitions();
xml::XmlParser parser(stream, options, commonDefinitions);
return parser.parse();
std::shared_ptr<Document> doc = getCommonDefinitions();

xml::XmlParser parser(doc, options);
parser.parseStream(stream);

return doc;
}
} // namespace adm
15 changes: 0 additions & 15 deletions src/private/rapidxml_formatter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,21 +46,6 @@ namespace adm {

} // namespace detail

void formatAudioProgramme(
XmlNode &node, const std::shared_ptr<const AudioProgramme> programme) {
// clang-format off
node.addAttribute<AudioProgrammeId>(programme, "audioProgrammeID");
node.addOptionalAttribute<AudioProgrammeName>(programme, "audioProgrammeName");
node.addOptionalAttribute<AudioProgrammeLanguage>(programme, "audioProgrammeLanguage");
node.addOptionalAttribute<Start>(programme, "start");
node.addOptionalAttribute<End>(programme, "end");
node.addOptionalAttribute<MaxDuckingDepth>(programme, "maxDuckingDepth");
node.addReferences<AudioContent, AudioContentId>(programme, "audioContentIDRef");
node.addVectorElements<LoudnessMetadatas>(programme, "loudnessMetadata", &formatLoudnessMetadata);
node.addVectorElements<Labels>(programme, "audioProgrammeLabel", &formatLabel);
// clang-format on
}

void formatLoudnessMetadata(XmlNode &node,
const LoudnessMetadata loudnessMetadata) {
node.addOptionalAttribute<LoudnessMethod>(&loudnessMetadata,
Expand Down
59 changes: 40 additions & 19 deletions src/private/xml_parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,20 +17,37 @@ namespace adm {
return static_cast<bool>(options & flag);
}

XmlParser::XmlParser(const std::string& filename, ParserOptions options,
std::shared_ptr<Document> destDocument)
: xmlFile_(filename.c_str()),
options_(options),
document_(destDocument) {}
XmlParser::XmlParser(std::shared_ptr<Document> destDocument,
ParserOptions options)
: options_(options), document_(std::move(destDocument)) {}

XmlParser::XmlParser(std::istream& stream, ParserOptions options,
std::shared_ptr<Document> destDocument)
: xmlFile_(stream), options_(options), document_(destDocument) {}
void XmlParser::parseFile(const std::string& filename) {
rapidxml::file<> xmlFile(filename.c_str());
parseXmlFile(xmlFile);
}

void XmlParser::parseStream(std::istream& stream) {
rapidxml::file<> xmlFile(stream);
parseXmlFile(xmlFile);
}

void XmlParser::parseString(const std::string& xmlString) {
// null-terminated copy to be modified by rapidxml (so can't use c_str)
std::vector<char> vec(xmlString.begin(), xmlString.end());
vec.push_back('\0');

std::shared_ptr<Document> XmlParser::parse() {
rapidxml::xml_document<> xmlDocument;
xmlDocument.parse<0>(xmlFile_.data());
xmlDocument.parse<0>(vec.data());
parseXml(xmlDocument);
}

void XmlParser::parseXmlFile(rapidxml::file<>& xmlFile) {
rapidxml::xml_document<> xmlDocument;
xmlDocument.parse<0>(xmlFile.data());
parseXml(xmlDocument);
}

void XmlParser::parseXml(const rapidxml::xml_document<>& xmlDocument) {
if (!xmlDocument.first_node())
throw error::XmlParsingError("xml document is empty");

Expand Down Expand Up @@ -80,7 +97,6 @@ namespace adm {
} else {
throw error::XmlParsingError("audioFormatExtended node not found");
}
return document_;
} // namespace xml

/**
Expand Down Expand Up @@ -430,8 +446,8 @@ namespace adm {
return audioTrackUid;
}

AudioBlockFormatDirectSpeakers parseAudioBlockFormatDirectSpeakers(
NodePtr node) {
AudioBlockFormatDirectSpeakers
XmlParser::parseAudioBlockFormatDirectSpeakers(NodePtr node) {
AudioBlockFormatDirectSpeakers audioBlockFormat;
// clang-format off
setOptionalAttribute<AudioBlockFormatId>(node, "audioBlockFormatID", audioBlockFormat, &parseAudioBlockFormatId);
Expand Down Expand Up @@ -600,7 +616,8 @@ namespace adm {
return headphoneVirtualise;
}

AudioBlockFormatObjects parseAudioBlockFormatObjects(NodePtr node) {
AudioBlockFormatObjects XmlParser::parseAudioBlockFormatObjects(
NodePtr node) {
AudioBlockFormatObjects audioBlockFormat{SphericalPosition()};
// clang-format off
setOptionalAttribute<AudioBlockFormatId>(node, "audioBlockFormatID", audioBlockFormat, &parseAudioBlockFormatId);
Expand Down Expand Up @@ -826,7 +843,8 @@ namespace adm {
return ContentKind(
parseAttribute<MixedContentKind>(node, "mixedContentKind"));
} else {
throw error::XmlParsingError("unknown dialogue id", getDocumentLine(node));
throw error::XmlParsingError("unknown dialogue id",
getDocumentLine(node));
}
}

Expand All @@ -835,7 +853,7 @@ namespace adm {
return AudioProgrammeReferenceScreen();
}

AudioBlockFormatHoa parseAudioBlockFormatHoa(NodePtr node) {
AudioBlockFormatHoa XmlParser::parseAudioBlockFormatHoa(NodePtr node) {
AudioBlockFormatHoa audioBlockFormat{Order(), Degree()};
// clang-format off
setOptionalAttribute<AudioBlockFormatId>(node, "audioBlockFormatID", audioBlockFormat, &parseAudioBlockFormatId);
Expand All @@ -855,11 +873,14 @@ namespace adm {
return audioBlockFormat;
}

AudioBlockFormatBinaural parseAudioBlockFormatBinaural(NodePtr node) {
AudioBlockFormatBinaural XmlParser::parseAudioBlockFormatBinaural(
NodePtr node) {
AudioBlockFormatBinaural audioBlockFormat;

setOptionalAttribute<Rtime>(node, "rtime", audioBlockFormat, &parseTimecode);
setOptionalAttribute<Duration>(node, "duration", audioBlockFormat, &parseTimecode);
setOptionalAttribute<Rtime>(node, "rtime", audioBlockFormat,
&parseTimecode);
setOptionalAttribute<Duration>(node, "duration", audioBlockFormat,
&parseTimecode);
setOptionalElement<Gain>(node, "gain", audioBlockFormat, &parseGain);
setOptionalElement<Importance>(node, "importance", audioBlockFormat);

Expand Down
22 changes: 21 additions & 1 deletion src/private/xml_writer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,13 @@ namespace adm {
} else {
root = xmlDocument.addEbuStructure();
}

root.addBaseElements<AudioProgramme, AudioProgrammeId>(
document, "audioProgramme", [this](XmlNode& node, auto programme) {
formatAudioProgramme(node, programme);
});

// clang-format off
root.addBaseElements<AudioProgramme, AudioProgrammeId>(document, "audioProgramme", &formatAudioProgramme);
root.addBaseElements<AudioContent, AudioContentId>(document, "audioContent", &formatAudioContent);
root.addBaseElements<AudioObject, AudioObjectId>(document, "audioObject", &formatAudioObject);
root.addBaseElements<AudioPackFormat, AudioPackFormatId>(document, "audioPackFormat", &formatAudioPackFormat);
Expand All @@ -50,5 +55,20 @@ namespace adm {
return stream << xmlDocument;
}

void XmlWriter::formatAudioProgramme(
XmlNode& node, const std::shared_ptr<const AudioProgramme> programme) {
// clang-format off
node.addAttribute<AudioProgrammeId>(programme, "audioProgrammeID");
node.addOptionalAttribute<AudioProgrammeName>(programme, "audioProgrammeName");
node.addOptionalAttribute<AudioProgrammeLanguage>(programme, "audioProgrammeLanguage");
node.addOptionalAttribute<Start>(programme, "start");
node.addOptionalAttribute<End>(programme, "end");
node.addOptionalAttribute<MaxDuckingDepth>(programme, "maxDuckingDepth");
node.addReferences<AudioContent, AudioContentId>(programme, "audioContentIDRef");
node.addVectorElements<LoudnessMetadatas>(programme, "loudnessMetadata", &formatLoudnessMetadata);
node.addVectorElements<Labels>(programme, "audioProgrammeLabel", &formatLabel);
// clang-format on
}

} // namespace xml
} // namespace adm
5 changes: 5 additions & 0 deletions tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -94,3 +94,8 @@ add_adm_test("xml_writer_audio_content_tests")
add_adm_test("xml_writer_objects_creation_tests")
add_adm_test("xml_writer_label_tests")
add_adm_test("xml_writer_tests")

# tests which use non-exported symbols
if ((NOT BUILD_SHARED_LIBS) OR (NOT ADM_HIDE_INTERNAL_SYMBOLS))
add_adm_test("xml_parser_override_tests")
endif ()
Loading