/* * libSpiff - XSPF playlist handling library * * Copyright (C) 2007, Sebastian Pipping / Xiph.Org Foundation * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above * copyright notice, this list of conditions and the following * disclaimer. * * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * * Neither the name of the Xiph.Org Foundation nor the names of * its contributors may be used to endorse or promote products * derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. * * Sebastian Pipping, sping@xiph.org */ /** * @file SpiffXmlFormatter.h * Interface of SpiffXmlFormatter. */ #ifndef SPIFF_XML_FORMATTER_H #define SPIFF_XML_FORMATTER_H #include "SpiffDefines.h" #include "SpiffToolbox.h" #include #include #include #include namespace Spiff { class SpiffWriter; /// @cond DOXYGEN_NON_API /** * Holds information necessary to undo a namespace registration */ struct SpiffNamespaceRegistrationUndo { int level; ///< Level, the namespace was registered on. Root is level 0. const XML_Char * uri; ///< Namespace URI /** * Creates a new undo entry. * * @param level Nesting level, 0 for root element * @param uri Namespace URI */ SpiffNamespaceRegistrationUndo(int level, const XML_Char * uri) : level(level), uri(uri) { } }; /// @endcond class SpiffXmlFormatterPrivate; /** * Outputs XML. */ class SpiffXmlFormatter { private: /// @cond DOXYGEN_NON_API SpiffXmlFormatterPrivate * const d; ///< D pointer /// @endcond protected: bool introDone; ///< XML intro written flag std::basic_ostringstream * output; ///< Output accumulator protected: /** * Creates a new formatter. */ SpiffXmlFormatter(); /** * Copy constructor. * * @param source Source to copy from */ SpiffXmlFormatter(const SpiffXmlFormatter & source); /** * Assignment operator. * * @param source Source to copy from */ SpiffXmlFormatter & operator=(const SpiffXmlFormatter & source); /** * Destroys this formatter and deletes all memory * associated with it. */ virtual ~SpiffXmlFormatter(); private: /** * Looks up the associated prefix for namespace * nsUri. * * @param nsUri Namespace URI * @return Registered namespace prefix */ const XML_Char * getPrefix(const XML_Char * nsUri) const; /** * Looks up the associated prefix for namespace nsUri * and makes a full element name of that and localName. * * @param nsUri Namespace URI * @param localName Local element name * @return Full element name, delete on your own */ XML_Char * makeFullName(const XML_Char * nsUri, const XML_Char * localName) const; /** * Unregisteres all namespace URIs that were registered * on a higher level and are thus not needed any more. */ void cleanupNamespaceRegs(); /** * Finds an unmapped namespace prefix based on the * given suggestion and maps the namespace URI to it. * * @param uri Namespace URI * @param prefixSuggestion Suggested prefix */ bool registerNamespace(const XML_Char * uri, const XML_Char * prefixSuggestion); public: /** * Associate the formatter with an output accumulator. * * @param output Output accumulator */ void setOutput(std::basic_ostringstream & output); /** * Opens the tag localname from namespace * ns. * * @param ns Namespace URI * @param localName Local element name * @param atts NULL-terminated list of attributes (key/value pairs) * @param nsRegs NULL-terminated list of namespace registrations (uri/prefix pairs) */ void writeStart(const XML_Char * ns, const XML_Char * localName, const XML_Char ** atts, const XML_Char ** nsRegs = NULL); /** * Closes the tag localname from namespace * ns. * * @param ns Namespace URI * @param localName Local element name */ void writeEnd(const XML_Char * ns, const XML_Char * localName); /** * Opens the tag localname from the XSPF namespace. * * @param localName Local element name * @param atts NULL-terminated list of attributes (key/value pairs) * @param nsRegs NULL-terminated list of namespace registrations (uri/prefix pairs) */ void writeHomeStart(const XML_Char * localName, const XML_Char ** atts, const XML_Char ** nsRegs = NULL); /** * Closes the tag localname from the XSPF namespace. * * @param localName Local element name */ void writeHomeEnd(const XML_Char * localName); protected: /** * Opens the tag name and adds the attributes atts. * atts is not NULL and *atts is an alternating * list of attribute keys and values. Its length is uneven and the last * entry is NULL. * * @param name Name of the tag to open * @param atts Alternating list of attribute key and value */ virtual void writeStart(const XML_Char * name, const XML_Char ** atts) = 0; /** * Closes the tag name. * * @param name Name of the tag to close */ virtual void writeEnd(const XML_Char * name) = 0; public: /** * Adds element content. * * @param text Text content */ virtual void writeBody(const XML_Char * text) = 0; /** * Adds element content. * * @param number Integer content */ virtual void writeBody(int number) = 0; /** * Writes well-formed character data to the output accumulator. * * @param data Character data */ void writeCharacterData(const XML_Char * data); static const XML_Char * const namespaceKey; ///< Namespace key pointer friend class SpiffWriter; // allow access to registerNamespace }; } #endif // SPIFF_XML_FORMATTER_H