1 /*************************************************************************** 2 copyright : (C) 2002 - 2008 by Scott Wheeler 3 email : wheeler@kde.org 4 ***************************************************************************/ 5 6 /*************************************************************************** 7 * This library is free software; you can redistribute it and/or modify * 8 * it under the terms of the GNU Lesser General Public License version * 9 * 2.1 as published by the Free Software Foundation. * 10 * * 11 * This library is distributed in the hope that it will be useful, but * 12 * WITHOUT ANY WARRANTY; without even the implied warranty of * 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * 14 * Lesser General Public License for more details. * 15 * * 16 * You should have received a copy of the GNU Lesser General Public * 17 * License along with this library; if not, write to the Free Software * 18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 19 * 02110-1301 USA * 20 * * 21 * Alternatively, this file is available under the Mozilla Public * 22 * License Version 1.1. You may obtain a copy of the License at * 23 * http://www.mozilla.org/MPL/ * 24 ***************************************************************************/ 25 26 #ifndef TAGLIB_OGGPAGE_H 27 #define TAGLIB_OGGPAGE_H 28 29 #include "taglib_export.h" 30 #include "tbytevectorlist.h" 31 32 namespace TagLib { 33 34 namespace Ogg { 35 36 class File; 37 class PageHeader; 38 39 //! An implementation of Ogg pages 40 41 /*! 42 * This is an implementation of the pages that make up an Ogg stream. 43 * This handles parsing pages and breaking them down into packets and handles 44 * the details of packets spanning multiple pages and pages that contain 45 * multiple packets. 46 * 47 * In most Xiph.org formats the comments are found in the first few packets, 48 * this however is a reasonably complete implementation of Ogg pages that 49 * could potentially be useful for non-meta data purposes. 50 */ 51 52 class TAGLIB_EXPORT Page 53 { 54 public: 55 /*! 56 * Read an Ogg page from the \a file at the position \a pageOffset. 57 */ 58 Page(File *file, long pageOffset); 59 60 virtual ~Page(); 61 62 /*! 63 * Returns the page's position within the file (in bytes). 64 */ 65 long fileOffset() const; 66 67 /*! 68 * Returns a pointer to the header for this page. This pointer will become 69 * invalid when the page is deleted. 70 */ 71 const PageHeader *header() const; 72 73 /*! 74 * Returns the index of the page within the Ogg stream. This helps make it 75 * possible to determine if pages have been lost. 76 * 77 * \see setPageSequenceNumber() 78 */ 79 int pageSequenceNumber() const; 80 81 /*! 82 * Sets the page's position in the stream to \a sequenceNumber. 83 * 84 * \see pageSequenceNumber() 85 */ 86 void setPageSequenceNumber(int sequenceNumber); 87 88 /*! 89 * Returns a copy of the page with \a sequenceNumber set as sequence number. 90 * 91 * \see header() 92 * \see PageHeader::setPageSequenceNumber() 93 * 94 * \deprecated Always returns null. 95 */ 96 Page* getCopyWithNewPageSequenceNumber(int sequenceNumber); 97 98 /*! 99 * Returns the index of the first packet wholly or partially contained in 100 * this page. 101 * 102 * \see setFirstPacketIndex() 103 */ 104 int firstPacketIndex() const; 105 106 /*! 107 * Sets the index of the first packet in the page. 108 * 109 * \see firstPacketIndex() 110 */ 111 void setFirstPacketIndex(int index); 112 113 /*! 114 * When checking to see if a page contains a given packet this set of flags 115 * represents the possible values for that packets status in the page. 116 * 117 * \see containsPacket() 118 */ 119 enum ContainsPacketFlags { 120 //! No part of the packet is contained in the page 121 DoesNotContainPacket = 0x0000, 122 //! The packet is wholly contained in the page 123 CompletePacket = 0x0001, 124 //! The page starts with the given packet 125 BeginsWithPacket = 0x0002, 126 //! The page ends with the given packet 127 EndsWithPacket = 0x0004 128 }; 129 130 /*! 131 * Checks to see if the specified \a packet is contained in the current 132 * page. 133 * 134 * \see ContainsPacketFlags 135 */ 136 ContainsPacketFlags containsPacket(int index) const; 137 138 /*! 139 * Returns the number of packets (whole or partial) in this page. 140 */ 141 unsigned int packetCount() const; 142 143 /*! 144 * Returns a list of the packets in this page. 145 * 146 * \note Either or both the first and last packets may be only partial. 147 * \see PageHeader::firstPacketContinued() 148 */ 149 ByteVectorList packets() const; 150 151 /*! 152 * Returns the size of the page in bytes. 153 */ 154 int size() const; 155 156 ByteVector render() const; 157 158 /*! 159 * Defines a strategy for pagination, or grouping pages into Ogg packets, 160 * for use with pagination methods. 161 * 162 * \note Yes, I'm aware that this is not a canonical "Strategy Pattern", 163 * the term was simply convenient. 164 */ 165 enum PaginationStrategy { 166 /*! 167 * Attempt to put the specified set of packets into a single Ogg packet. 168 * If the sum of the packet data is greater than will fit into a single 169 * Ogg page -- 65280 bytes -- this will fall back to repagination using 170 * the recommended page sizes. 171 */ 172 SinglePagePerGroup, 173 /*! 174 * Split the packet or group of packets into pages that conform to the 175 * sizes recommended in the Ogg standard. 176 */ 177 Repaginate 178 }; 179 180 /*! 181 * Pack \a packets into Ogg pages using the \a strategy for pagination. 182 * The page number indicator inside of the rendered packets will start 183 * with \a firstPage and be incremented for each page rendered. 184 * \a containsLastPacket should be set to true if \a packets contains the 185 * last page in the stream and will set the appropriate flag in the last 186 * rendered Ogg page's header. \a streamSerialNumber should be set to 187 * the serial number for this stream. 188 * 189 * \note The "absolute granule position" is currently always zeroed using 190 * this method as this suffices for the comment headers. 191 * 192 * \warning The pages returned by this method must be deleted by the user. 193 * You can use List<T>::setAutoDelete(true) to set these pages to be 194 * automatically deleted when this list passes out of scope. 195 * 196 * \see PaginationStrategy 197 * \see List::setAutoDelete() 198 */ 199 static List<Page *> paginate(const ByteVectorList &packets, 200 PaginationStrategy strategy, 201 unsigned int streamSerialNumber, 202 int firstPage, 203 bool firstPacketContinued = false, 204 bool lastPacketCompleted = true, 205 bool containsLastPacket = false); 206 207 protected: 208 /*! 209 * Creates an Ogg packet based on the data in \a packets. The page number 210 * for each page will be set to \a pageNumber. 211 */ 212 Page(const ByteVectorList &packets, 213 unsigned int streamSerialNumber, 214 int pageNumber, 215 bool firstPacketContinued = false, 216 bool lastPacketCompleted = true, 217 bool containsLastPacket = false); 218 219 private: 220 Page(const Page &); 221 Page &operator=(const Page &); 222 223 class PagePrivate; 224 PagePrivate *d; 225 }; 226 } 227 } 228 #endif 229