/*************************************************************************** copyright : (C) 2002 - 2008 by Scott Wheeler email : wheeler@kde.org ***************************************************************************/ /*************************************************************************** * This library is free software; you can redistribute it and/or modify * * it under the terms of the GNU Lesser General Public License version * * 2.1 as published by the Free Software Foundation. * * * * This library is distributed in the hope that it will be useful, but * * WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * * Lesser General Public License for more details. * * * * You should have received a copy of the GNU Lesser General Public * * License along with this library; if not, write to the Free Software * * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * * 02110-1301 USA * * * * Alternatively, this file is available under the Mozilla Public * * License Version 1.1. You may obtain a copy of the License at * * http://www.mozilla.org/MPL/ * ***************************************************************************/ #ifndef TAGLIB_OGGPAGE_H #define TAGLIB_OGGPAGE_H #include "taglib_export.h" #include "tbytevectorlist.h" namespace TagLib { namespace Ogg { class File; class PageHeader; //! An implementation of Ogg pages /*! * This is an implementation of the pages that make up an Ogg stream. * This handles parsing pages and breaking them down into packets and handles * the details of packets spanning multiple pages and pages that contain * multiple packets. * * In most Xiph.org formats the comments are found in the first few packets, * this however is a reasonably complete implementation of Ogg pages that * could potentially be useful for non-meta data purposes. */ class TAGLIB_EXPORT Page { public: /*! * Read an Ogg page from the \a file at the position \a pageOffset. */ Page(File *file, long pageOffset); virtual ~Page(); /*! * Returns the page's position within the file (in bytes). */ long fileOffset() const; /*! * Returns a pointer to the header for this page. This pointer will become * invalid when the page is deleted. */ const PageHeader *header() const; /*! * Returns the index of the page within the Ogg stream. This helps make it * possible to determine if pages have been lost. * * \see setPageSequenceNumber() */ int pageSequenceNumber() const; /*! * Sets the page's position in the stream to \a sequenceNumber. * * \see pageSequenceNumber() */ void setPageSequenceNumber(int sequenceNumber); /*! * Returns a copy of the page with \a sequenceNumber set as sequence number. * * \see header() * \see PageHeader::setPageSequenceNumber() * * \deprecated Always returns null. */ TAGLIB_DEPRECATED Page *getCopyWithNewPageSequenceNumber(int sequenceNumber); /*! * Returns the index of the first packet wholly or partially contained in * this page. * * \see setFirstPacketIndex() */ int firstPacketIndex() const; /*! * Sets the index of the first packet in the page. * * \see firstPacketIndex() */ void setFirstPacketIndex(int index); /*! * When checking to see if a page contains a given packet this set of flags * represents the possible values for that packets status in the page. * * \see containsPacket() */ enum ContainsPacketFlags { //! No part of the packet is contained in the page DoesNotContainPacket = 0x0000, //! The packet is wholly contained in the page CompletePacket = 0x0001, //! The page starts with the given packet BeginsWithPacket = 0x0002, //! The page ends with the given packet EndsWithPacket = 0x0004 }; /*! * Checks to see if the specified \a packet is contained in the current * page. * * \see ContainsPacketFlags */ ContainsPacketFlags containsPacket(int index) const; /*! * Returns the number of packets (whole or partial) in this page. */ unsigned int packetCount() const; /*! * Returns a list of the packets in this page. * * \note Either or both the first and last packets may be only partial. * \see PageHeader::firstPacketContinued() */ ByteVectorList packets() const; /*! * Returns the size of the page in bytes. */ int size() const; ByteVector render() const; /*! * Defines a strategy for pagination, or grouping pages into Ogg packets, * for use with pagination methods. * * \note Yes, I'm aware that this is not a canonical "Strategy Pattern", * the term was simply convenient. */ enum PaginationStrategy { /*! * Attempt to put the specified set of packets into a single Ogg packet. * If the sum of the packet data is greater than will fit into a single * Ogg page -- 65280 bytes -- this will fall back to repagination using * the recommended page sizes. */ SinglePagePerGroup, /*! * Split the packet or group of packets into pages that conform to the * sizes recommended in the Ogg standard. */ Repaginate }; /*! * Pack \a packets into Ogg pages using the \a strategy for pagination. * The page number indicator inside of the rendered packets will start * with \a firstPage and be incremented for each page rendered. * \a containsLastPacket should be set to true if \a packets contains the * last page in the stream and will set the appropriate flag in the last * rendered Ogg page's header. \a streamSerialNumber should be set to * the serial number for this stream. * * \note The "absolute granule position" is currently always zeroed using * this method as this suffices for the comment headers. * * \warning The pages returned by this method must be deleted by the user. * You can use List::setAutoDelete(true) to set these pages to be * automatically deleted when this list passes out of scope. * * \see PaginationStrategy * \see List::setAutoDelete() */ static List paginate(const ByteVectorList &packets, PaginationStrategy strategy, unsigned int streamSerialNumber, int firstPage, bool firstPacketContinued = false, bool lastPacketCompleted = true, bool containsLastPacket = false); protected: /*! * Creates an Ogg packet based on the data in \a packets. The page number * for each page will be set to \a pageNumber. */ Page(const ByteVectorList &packets, unsigned int streamSerialNumber, int pageNumber, bool firstPacketContinued = false, bool lastPacketCompleted = true, bool containsLastPacket = false); private: Page(const Page &); Page &operator=(const Page &); class PagePrivate; PagePrivate *d; }; } } #endif