libxspf  1.2.0
XspfReader.h
Go to the documentation of this file.
00001 /*
00002  * libxspf - XSPF playlist handling library
00003  *
00004  * Copyright (C) 2006-2008, Sebastian Pipping / Xiph.Org Foundation
00005  * All rights reserved.
00006  *
00007  * Redistribution  and use in source and binary forms, with or without
00008  * modification,  are permitted provided that the following conditions
00009  * are met:
00010  *
00011  *     * Redistributions   of  source  code  must  retain  the   above
00012  *       copyright  notice, this list of conditions and the  following
00013  *       disclaimer.
00014  *
00015  *     * Redistributions  in  binary  form must  reproduce  the  above
00016  *       copyright  notice, this list of conditions and the  following
00017  *       disclaimer   in  the  documentation  and/or  other  materials
00018  *       provided with the distribution.
00019  *
00020  *     * Neither  the name of the Xiph.Org Foundation nor the names of
00021  *       its  contributors may be used to endorse or promote  products
00022  *       derived  from  this software without specific  prior  written
00023  *       permission.
00024  *
00025  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00026  * "AS  IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT  NOT
00027  * LIMITED  TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND  FITNESS
00028  * FOR  A  PARTICULAR  PURPOSE ARE DISCLAIMED. IN NO EVENT  SHALL  THE
00029  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00030  * INCIDENTAL,    SPECIAL,   EXEMPLARY,   OR   CONSEQUENTIAL   DAMAGES
00031  * (INCLUDING,  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
00032  * SERVICES;  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00033  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
00034  * STRICT  LIABILITY,  OR  TORT (INCLUDING  NEGLIGENCE  OR  OTHERWISE)
00035  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
00036  * OF THE POSSIBILITY OF SUCH DAMAGE.
00037  *
00038  * Sebastian Pipping, sping@xiph.org
00039  */
00040 
00046 #ifndef XSPF_READER_H
00047 #define XSPF_READER_H
00048 
00049 
00050 #include "XspfDefines.h"
00051 #include <string>
00052 
00053 
00054 namespace Xspf {
00055 
00056 
00058 
00059 // Messages with ONE "%s" in it
00060 #define XSPF_READER_TEXT_ONE_ATTRIBUTE_FORBIDDEN                      _PT("Attribute '%s' not allowed.")
00061 #define XSPF_READER_TEXT_ONE_EXPAT_ERROR                              _PT("Expat error '%s'")
00062 #define XSPF_READER_TEXT_ONE_ELEMENT_FORBIDDEN                        _PT("Element '%s' not allowed.")
00063 #define XSPF_READER_TEXT_ONE_ELEMENT_FORBIDDEN_VERSION_ZERO           _PT("Element '%s' not allowed in XSPF-0.")
00064 #define XSPF_READER_TEXT_ONE_FILE_READING_ERROR                       _PT("File '%s' could not be read.")
00065 #define XSPF_READER_TEXT_ONE_WRONG_ROOT_NAME                          _PT("Root element must be '") XSPF_NS_HOME XSPF_NS_SEP_STRING _PT("playlist', not '%s'.")
00066 #define XSPF_READER_TEXT_ONE_WRONG_VERSION                            _PT("Version must be '0' or '1', not '%s'.")
00067 
00068 // Messages with ZERO "%s" in it
00069 #define XSPF_READER_TEXT_ZERO_ATTRIBUTE_MISSING(name)                 _PT("Attribute '") name _PT("' missing.")
00070 #define XSPF_READER_TEXT_ZERO_ELEMENT_MISSING(ns, name)               _PT("Element '") ns XSPF_NS_SEP_STRING name _PT("' missing.")
00071 #define XSPF_READER_TEXT_ZERO_ELEMENT_MISSING_VERSION_ZERO(ns, name)  _PT("Element '") ns XSPF_NS_SEP_STRING name _PT("' missing. This is not allowed in XSPF-0.")
00072 #define XSPF_READER_TEXT_ZERO_FILENAME_NULL                           _PT("Filename must not be NULL.")
00073 #define XSPF_READER_TEXT_ZERO_TOO_MANY_ELEMENTS(ns, name)             _PT("Only one '") ns XSPF_NS_SEP_STRING name _PT("' allowed.")
00074 #define XSPF_READER_TEXT_ZERO_WRONG_ATTRIBUTE_TYPE(attr, type)        _PT("Attribute '") attr _PT("' is not a valid ") type _PT(".")
00075 #define XSPF_READER_TEXT_ZERO_WRONG_CONTENT_TYPE(ns, elem, type)      _PT("Content of '") ns XSPF_NS_SEP_STRING elem _PT("' is not a valid ") type _PT(".")
00076 #define XSPF_READER_TEXT_ZERO_TEXT_FORBIDDEN(ns, elem)                _PT("Content of '") ns XSPF_NS_SEP_STRING elem _PT("' must be whitespace or child elements, not text.")
00077 #define XSPF_READER_TEXT_ZERO_KEY_WITHOUT_VERSION(name)               _PT("Attribute '") name _PT("' does not carry version information.")
00078 #define XSPF_READER_TEXT_ZERO_KEY_WITH_REL_URI(name)                  _PT("Attribute '") name _PT("' does not contain an absolute URI.")
00079 
00081 
00082 
00086 enum XspfReaderReturnCode {
00087         XSPF_READER_SUCCESS, 
00088 
00089         XSPF_READER_ERROR_NO_INPUT, 
00090         XSPF_READER_ERROR_ELEMENT_TOOMANY, 
00091         XSPF_READER_ERROR_ELEMENT_FORBIDDEN, 
00092         XSPF_READER_ERROR_ELEMENT_MISSING, 
00093         XSPF_READER_ERROR_ATTRIBUTE_INVALID, 
00094         XSPF_READER_ERROR_ATTRIBUTE_MISSING, 
00095         XSPF_READER_ERROR_ATTRIBUTE_FORBIDDEN, 
00096         XSPF_READER_ERROR_CONTENT_INVALID, 
00097         XSPF_READER_ERROR_BASE_URI_USELESS, 
00098 
00099         XSPF_READER_WARNING_KEY_WITHOUT_VERSION, 
00100         XSPF_READER_WARNING_KEY_WITH_REL_URI, 
00101 
00102         XSPF_READER_ERROR_MALICIOUS_SPACE, 
00103         XSPF_READER_ERROR_MALICIOUS_LOOKUP_SUM, 
00104         XSPF_READER_ERROR_MALICIOUS_LOOKUP_DEPTH, //< An entity's lookup depth is too high
00105 
00106         // Insert new codes HERE!
00107 
00108         // This one must come last!
00109         XSPF_READER_ERROR_EXPAT = 0x1000 
00110 };
00111 
00112 
00113 /*
00114 playlist                                                                        1
00115         title                                                   ?
00116         creator                                                 ?
00117         annotation                                              ?
00118         info                                                    ?
00119         location                                                ?
00120         identifier                                              ?
00121         image                                                   ?
00122         date                                                    ?
00123         license                                                 ?
00124         attribution                                             ?
00125                 location                                                *
00126                 identifier                                              *
00127         link                                                            *
00128         meta                                                            *
00129         extension                                                       *
00130                 ...                                                             *
00131         trackList                                                               1
00132                 track                                                   +|*
00133                         location                                        *
00134                         identifier                                      *
00135                         title                                   ?
00136                         creator                                 ?
00137                         annotation                              ?
00138                         info                                    ?
00139                         image                                   ?
00140                         album                                   ?
00141                         trackNum (uint > 0)             ?
00142                         duration (uint)                 ?
00143                         link                                            *
00144                         meta                                            *
00145                         extension                                       *
00146 */
00147 
00151 enum XspfTag {
00152         // Stack returns 0 if empty
00153         TAG_UNKNOWN, 
00154 
00155         TAG_PLAYLIST, 
00156         TAG_PLAYLIST_TITLE,  
00157         TAG_PLAYLIST_CREATOR, 
00158         TAG_PLAYLIST_ANNOTATION, 
00159         TAG_PLAYLIST_INFO, 
00160         TAG_PLAYLIST_LOCATION, 
00161         TAG_PLAYLIST_IDENTIFIER, 
00162         TAG_PLAYLIST_IMAGE, 
00163         TAG_PLAYLIST_DATE, 
00164         TAG_PLAYLIST_LICENSE, 
00165         TAG_PLAYLIST_ATTRIBUTION, 
00166         TAG_PLAYLIST_ATTRIBUTION_LOCATION, 
00167         TAG_PLAYLIST_ATTRIBUTION_IDENTIFIER, 
00168         TAG_PLAYLIST_LINK, 
00169         TAG_PLAYLIST_META, 
00170         TAG_PLAYLIST_EXTENSION, 
00171         TAG_PLAYLIST_TRACKLIST, 
00172         TAG_PLAYLIST_TRACKLIST_TRACK, 
00173         TAG_PLAYLIST_TRACKLIST_TRACK_LOCATION, 
00174         TAG_PLAYLIST_TRACKLIST_TRACK_IDENTIFIER, 
00175         TAG_PLAYLIST_TRACKLIST_TRACK_TITLE, 
00176         TAG_PLAYLIST_TRACKLIST_TRACK_CREATOR, 
00177         TAG_PLAYLIST_TRACKLIST_TRACK_ANNOTATION, 
00178         TAG_PLAYLIST_TRACKLIST_TRACK_INFO, 
00179         TAG_PLAYLIST_TRACKLIST_TRACK_IMAGE, 
00180         TAG_PLAYLIST_TRACKLIST_TRACK_ALBUM, 
00181         TAG_PLAYLIST_TRACKLIST_TRACK_TRACKNUM, 
00182         TAG_PLAYLIST_TRACKLIST_TRACK_DURATION, 
00183         TAG_PLAYLIST_TRACKLIST_TRACK_LINK, 
00184         TAG_PLAYLIST_TRACKLIST_TRACK_META, 
00185         TAG_PLAYLIST_TRACKLIST_TRACK_EXTENSION, 
00186 
00187         // Insert XSPF-2 codes HERE!
00188 
00189         // This one must come last!
00190         TAG_USER = 0x1000 
00191 };
00192 
00193 
00194 class XspfProps;
00195 class XspfDateTime;
00196 class XspfTrack;
00197 class XspfReaderCallback;
00198 template <class T> class XspfStack;
00199 class XspfChunkCallback;
00200 
00201 class XspfExtensionReaderFactory;
00202 class XspfExtensionReader;
00203 class XspfReaderPrivate;
00204 
00205 
00209 class XspfReader {
00210 
00211 private:
00213         XspfReaderPrivate * const d; 
00214 
00215 
00216 public:
00222         XspfReader(XspfExtensionReaderFactory * handlerFactory = NULL);
00223 
00229         XspfReader(XspfReader const & source);
00230 
00236         XspfReader & operator=(XspfReader const & source);
00237 
00241         ~XspfReader();
00242 
00254         int parseFile(XML_Char const * filename, XspfReaderCallback * callback,
00255                         XML_Char const * baseUri);
00256 
00269         int parseMemory(char const * memory, int numBytes, XspfReaderCallback * callback,
00270                         XML_Char const * baseUri);
00271 
00283         int parseChunks(XspfChunkCallback * inputCallback,
00284                         XspfReaderCallback * dataCallback, XML_Char const * baseUri);
00285 
00294         void limitLengthPerEntityValue(bool enabled);
00295 
00304         void limitLookupSumPerEntityValue(bool enabled);
00305 
00314         void limitLookupDepthPerEntityValue(bool enabled);
00315 
00327         void enableMaliciousXmlDetection(bool enabled);
00328 
00337         void setMaxLengthPerEntityValue(int maxLength);
00338 
00347         void setMaxLookupSumPerEntityValue(int maxLookupSum);
00348 
00357         void setMaxLookupDepthPerEntityValue(int maxLookupDepth);
00358 
00359 private:
00363         void makeReusable();
00364 
00372         bool handleError(int code, XML_Char const * text);
00373 
00382         bool handleError(int code, XML_Char const * format, XML_Char const * param);
00383 
00390         void handleFatalError(int code, XML_Char const * text);
00391 
00399         void handleFatalError(int code, XML_Char const * format, XML_Char const * param);
00400 
00408         bool handleWarning(int code, XML_Char const * text);
00409 
00414         void setExpatError();
00415 
00419         void stop();
00420 
00427         void handleStart(XML_Char const * fullName, XML_Char const ** atts);
00428 
00436         bool handleStartOne(XML_Char const * fullName, XML_Char const ** atts);
00437 
00445         bool handleStartTwo(XML_Char const * fullName, XML_Char const ** atts);
00446 
00454         bool handleStartThree(XML_Char const * fullName, XML_Char const ** atts);
00455 
00463         bool handleStartFour(XML_Char const * fullName, XML_Char const ** atts);
00464 
00471         void handleCharacters(XML_Char const * s, int len);
00472 
00479         void handleEntityDeclaration(XML_Char const * entityName,
00480                         XML_Char const * value);
00481 
00487         void handleEnd(XML_Char const * fullName);
00488 
00495         bool handleEndOne(XML_Char const * fullName);
00496 
00503         bool handleEndTwo(XML_Char const * fullName);
00504 
00511         bool handleEndThree(XML_Char const * fullName);
00512 
00519         bool handleEndFour(XML_Char const * fullName);
00520 
00528         bool handlePlaylistAttribs(XML_Char const ** atts);
00529 
00538         bool handleMetaLinkAttribs(XML_Char const ** atts, XML_Char const * & rel);
00539 
00548         bool handleExtensionAttribs(XML_Char const ** atts,
00549                         XML_Char const * & application);
00550 
00557         bool handleNoAttribsExceptXmlBase(XML_Char const ** atts);
00558 
00562         void clearError();
00563 
00571         static void masterStart(void * userData, XML_Char const * fullName, XML_Char const ** atts);
00572 
00579         static void masterEnd(void * userData, XML_Char const * fullName);
00580 
00588         static void masterCharacters(void * userData, XML_Char const * s, int len);
00589 
00603         static void masterEntityDeclaration(void * userData, XML_Char const * entityName,
00604                         int is_parameter_entity, XML_Char const * value, int value_length,
00605                         XML_Char const * base, XML_Char const * systemId, XML_Char const * publicId,
00606                         XML_Char const * notationName);
00607 
00615         bool onBeforeParse(XspfReaderCallback * callback,
00616                         XML_Char const * baseUri);
00617 
00621         void onAfterParse();
00622 
00623 public:
00630         static bool isXmlBase(XML_Char const * attributeKey);
00631 
00632 private:
00639         bool handleXmlBaseAttribute(XML_Char const * xmlBase);
00640 
00648         XML_Char * makeAbsoluteUri(XML_Char const * sourceUri) const;
00649 
00655         XspfStack<unsigned int> & getElementStack() const;
00656 
00662         XspfStack<std::basic_string<XML_Char> > & getBaseUriStack() const;
00663 
00670         void skipFromHere();
00671 
00682         bool checkAndSkipNamespace(XML_Char const * fullName,
00683                         XML_Char const * & localName);
00684 
00689         void notifySuccess() const;
00690 
00691         friend class XspfExtensionReader;
00692 
00693 };
00694 
00695 
00696 } // namespace Xspf
00697 
00698 #endif // XSPF_READER_H
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines