/* * 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 SpiffExtensionReaderFactory.cpp * Implementation of SpiffExtensionReaderFactory. */ #include #include #include using namespace std; using namespace Spiff::Toolbox; namespace Spiff { /// @cond DOXYGEN_NON_API /** * D object for SpiffExtensionReaderFactory. */ class SpiffExtensionReaderFactoryPrivate { friend class SpiffExtensionReaderFactory; /** * Creates a new D object. */ SpiffExtensionReaderFactoryPrivate() { } /** * Destroys this D object. */ ~SpiffExtensionReaderFactoryPrivate() { } }; /// @endcond SpiffExtensionReaderFactory::SpiffExtensionReaderFactory() : d(new SpiffExtensionReaderFactoryPrivate()), playlistCatchAllReader(NULL), trackCatchAllReader(NULL) { } SpiffExtensionReaderFactory::SpiffExtensionReaderFactory( const SpiffExtensionReaderFactory & source) : d(new SpiffExtensionReaderFactoryPrivate(*(source.d))), playlistCatchAllReader((source.playlistCatchAllReader == NULL) ? NULL : source.playlistCatchAllReader->createBrother()), trackCatchAllReader((source.trackCatchAllReader == NULL) ? NULL : source.trackCatchAllReader->createBrother()) { copyMap(this->playlistExtensionReaders, source.playlistExtensionReaders); copyMap(this->trackExtensionReaders, source.trackExtensionReaders); } SpiffExtensionReaderFactory & SpiffExtensionReaderFactory::operator=(const SpiffExtensionReaderFactory & source) { if (this != &source) { *(this->d) = *(source.d); // playlistExtensionReaders freeMap(this->playlistExtensionReaders); this->playlistExtensionReaders.clear(); copyMap(this->playlistExtensionReaders, source.playlistExtensionReaders); // trackExtensionReaders freeMap(this->trackExtensionReaders); this->trackExtensionReaders.clear(); copyMap(this->trackExtensionReaders, source.trackExtensionReaders); // playlistCatchAllReader if (this->playlistCatchAllReader != NULL) { delete this->playlistCatchAllReader; } this->playlistCatchAllReader = (source.playlistCatchAllReader == NULL) ? NULL : source.playlistCatchAllReader->createBrother(); // trackCatchAllReader if (this->trackCatchAllReader != NULL) { delete this->trackCatchAllReader; } this->trackCatchAllReader = (source.trackCatchAllReader == NULL) ? NULL : source.trackCatchAllReader->createBrother(); } return *this; } SpiffExtensionReaderFactory::~SpiffExtensionReaderFactory() { freeMap(this->playlistExtensionReaders); freeMap(this->trackExtensionReaders); if (this->playlistCatchAllReader != NULL) { delete this->playlistCatchAllReader; } if (this->trackCatchAllReader != NULL) { delete this->trackCatchAllReader; } delete this->d; } /*static*/ inline void SpiffExtensionReaderFactory::freeMap( std::map & container) { // Free examples and application URIs map ::iterator iter = container.begin(); while (iter != container.end()) { delete [] iter->first; delete iter->second; iter++; } } /*static*/ inline void SpiffExtensionReaderFactory::copyMap( std::map & dest, const std::map & source) { // Copy examples and application URIs map ::const_iterator iter = source.begin(); while (iter != source.end()) { const XML_Char * const applicationUri = newAndCopy(iter->first); const SpiffExtensionReader * const clone = iter->second->createBrother(); dest.insert(pair(applicationUri, clone)); iter++; } } inline void SpiffExtensionReaderFactory::registerReader( std::map & container, const SpiffExtensionReader * & catchAll, const SpiffExtensionReader * example, const XML_Char * triggerUri) { if (example == NULL) { return; } const SpiffExtensionReader * const clone = example->createBrother(); // CatchAll reader? if (triggerUri == NULL) { // Overwrite old catcher if (catchAll != NULL) { delete catchAll; } catchAll = clone; } else { map ::iterator found = container.find(triggerUri); if (found != container.end()) { // Overwrite existing entry delete found->second; found->second = clone; } else { // Add new entry with duped URI container.insert(pair( newAndCopy(triggerUri), clone)); } } } void SpiffExtensionReaderFactory::registerPlaylistExtensionReader( const SpiffExtensionReader * example, const XML_Char * triggerUri) { registerReader(this->playlistExtensionReaders, this->playlistCatchAllReader, example, triggerUri); } void SpiffExtensionReaderFactory::registerTrackExtensionReader( const SpiffExtensionReader * example, const XML_Char * triggerUri) { registerReader(this->trackExtensionReaders, this->trackCatchAllReader, example, triggerUri); } inline void SpiffExtensionReaderFactory::unregisterReader( std::map & container, const SpiffExtensionReader * & catchAll, const XML_Char * triggerUri) { // CatchAll reader? if (triggerUri == NULL) { // Remove catcher if (catchAll != NULL) { delete catchAll; catchAll = NULL; } } else { map ::iterator found = container.find(triggerUri); if (found != container.end()) { delete found->second; container.erase(found); } } } void SpiffExtensionReaderFactory::unregisterPlaylistExtensionReader( const XML_Char * triggerUri) { unregisterReader(this->playlistExtensionReaders, this->playlistCatchAllReader, triggerUri); } void SpiffExtensionReaderFactory::unregisterTrackExtensionReader( const XML_Char * triggerUri) { unregisterReader(this->trackExtensionReaders, this->trackCatchAllReader, triggerUri); } inline SpiffExtensionReader * SpiffExtensionReaderFactory::newReader( std::map & container, const SpiffExtensionReader * catchAll, const XML_Char * applicationUri, SpiffReader * reader) { map ::const_iterator found = container.find(applicationUri); if (found != container.end()) { return found->second->createBrother(reader); } else { if (catchAll != NULL) { return catchAll->createBrother(reader); } else { return NULL; } } } SpiffExtensionReader * SpiffExtensionReaderFactory ::newPlaylistExtensionReader(const XML_Char * applicationUri, SpiffReader * reader) { return newReader(this->playlistExtensionReaders, this->playlistCatchAllReader, applicationUri, reader); } SpiffExtensionReader * SpiffExtensionReaderFactory ::newTrackExtensionReader(const XML_Char * applicationUri, SpiffReader * reader) { return newReader(this->trackExtensionReaders, this->trackCatchAllReader, applicationUri, reader); } }