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_FILE_H 27 #define TAGLIB_FILE_H 28 29 #include "taglib_export.h" 30 #include "taglib.h" 31 #include "tag.h" 32 #include "tbytevector.h" 33 #include "tiostream.h" 34 35 namespace TagLib { 36 37 class String; 38 class Tag; 39 class AudioProperties; 40 class PropertyMap; 41 42 //! A file class with some useful methods for tag manipulation 43 44 /*! 45 * This class is a basic file class with some methods that are particularly 46 * useful for tag editors. It has methods to take advantage of 47 * ByteVector and a binary search method for finding patterns in a file. 48 */ 49 50 class TAGLIB_EXPORT File 51 { 52 public: 53 /*! 54 * Position in the file used for seeking. 55 */ 56 enum Position { 57 //! Seek from the beginning of the file. 58 Beginning, 59 //! Seek from the current position in the file. 60 Current, 61 //! Seek from the end of the file. 62 End 63 }; 64 65 /*! 66 * Destroys this File instance. 67 */ 68 virtual ~File(); 69 70 /*! 71 * Returns the file name in the local file system encoding. 72 */ 73 FileName name() const; 74 75 /*! 76 * Returns a pointer to this file's tag. This should be reimplemented in 77 * the concrete subclasses. 78 */ 79 virtual Tag *tag() const = 0; 80 81 /*! 82 * Exports the tags of the file as dictionary mapping (human readable) tag 83 * names (uppercase Strings) to StringLists of tag values. Calls the according 84 * specialization in the File subclasses. 85 * For each metadata object of the file that could not be parsed into the PropertyMap 86 * format, the returned map's unsupportedData() list will contain one entry identifying 87 * that object (e.g. the frame type for ID3v2 tags). Use removeUnsupportedProperties() 88 * to remove (a subset of) them. 89 * For files that contain more than one tag (e.g. an MP3 with both an ID3v1 and an ID3v2 90 * tag) only the most "modern" one will be exported (ID3v2 in this case). 91 * BIC: Will be made virtual in future releases. 92 */ 93 PropertyMap properties() const; 94 95 /*! 96 * Removes unsupported properties, or a subset of them, from the file's metadata. 97 * The parameter \a properties must contain only entries from 98 * properties().unsupportedData(). 99 * BIC: Will be mad virtual in future releases. 100 */ 101 void removeUnsupportedProperties(const StringList& properties); 102 103 /*! 104 * Sets the tags of this File to those specified in \a properties. Calls the 105 * according specialization method in the subclasses of File to do the translation 106 * into the format-specific details. 107 * If some value(s) could not be written imported to the specific metadata format, 108 * the returned PropertyMap will contain those value(s). Otherwise it will be empty, 109 * indicating that no problems occurred. 110 * With file types that support several tag formats (for instance, MP3 files can have 111 * ID3v1, ID3v2, and APEv2 tags), this function will create the most appropriate one 112 * (ID3v2 for MP3 files). Older formats will be updated as well, if they exist, but won't 113 * be taken into account for the return value of this function. 114 * See the documentation of the subclass implementations for detailed descriptions. 115 * BIC: will become pure virtual in the future 116 */ 117 PropertyMap setProperties(const PropertyMap &properties); 118 119 /*! 120 * Returns a pointer to this file's audio properties. This should be 121 * reimplemented in the concrete subclasses. If no audio properties were 122 * read then this will return a null pointer. 123 */ 124 virtual AudioProperties *audioProperties() const = 0; 125 126 /*! 127 * Save the file and its associated tags. This should be reimplemented in 128 * the concrete subclasses. Returns true if the save succeeds. 129 * 130 * \warning On UNIX multiple processes are able to write to the same file at 131 * the same time. This can result in serious file corruption. If you are 132 * developing a program that makes use of TagLib from multiple processes you 133 * must insure that you are only doing writes to a particular file from one 134 * of them. 135 */ 136 virtual bool save() = 0; 137 138 /*! 139 * Reads a block of size \a length at the current get pointer. 140 */ 141 ByteVector readBlock(unsigned long length); 142 143 /*! 144 * Attempts to write the block \a data at the current get pointer. If the 145 * file is currently only opened read only -- i.e. readOnly() returns true -- 146 * this attempts to reopen the file in read/write mode. 147 * 148 * \note This should be used instead of using the streaming output operator 149 * for a ByteVector. And even this function is significantly slower than 150 * doing output with a char[]. 151 */ 152 void writeBlock(const ByteVector &data); 153 154 /*! 155 * Returns the offset in the file that \a pattern occurs at or -1 if it can 156 * not be found. If \a before is set, the search will only continue until the 157 * pattern \a before is found. This is useful for tagging purposes to search 158 * for a tag before the sync frame. 159 * 160 * Searching starts at \a fromOffset, which defaults to the beginning of the 161 * file. 162 * 163 * \note This has the practical limitation that \a pattern can not be longer 164 * than the buffer size used by readBlock(). Currently this is 1024 bytes. 165 */ 166 long find(const ByteVector &pattern, 167 long fromOffset = 0, 168 const ByteVector &before = ByteVector()); 169 170 /*! 171 * Returns the offset in the file that \a pattern occurs at or -1 if it can 172 * not be found. If \a before is set, the search will only continue until the 173 * pattern \a before is found. This is useful for tagging purposes to search 174 * for a tag before the sync frame. 175 * 176 * Searching starts at \a fromOffset and proceeds from the that point to the 177 * beginning of the file and defaults to the end of the file. 178 * 179 * \note This has the practical limitation that \a pattern can not be longer 180 * than the buffer size used by readBlock(). Currently this is 1024 bytes. 181 */ 182 long rfind(const ByteVector &pattern, 183 long fromOffset = 0, 184 const ByteVector &before = ByteVector()); 185 186 /*! 187 * Insert \a data at position \a start in the file overwriting \a replace 188 * bytes of the original content. 189 * 190 * \note This method is slow since it requires rewriting all of the file 191 * after the insertion point. 192 */ 193 void insert(const ByteVector &data, unsigned long start = 0, unsigned long replace = 0); 194 195 /*! 196 * Removes a block of the file starting a \a start and continuing for 197 * \a length bytes. 198 * 199 * \note This method is slow since it involves rewriting all of the file 200 * after the removed portion. 201 */ 202 void removeBlock(unsigned long start = 0, unsigned long length = 0); 203 204 /*! 205 * Returns true if the file is read only (or if the file can not be opened). 206 */ 207 bool readOnly() const; 208 209 /*! 210 * Since the file can currently only be opened as an argument to the 211 * constructor (sort-of by design), this returns if that open succeeded. 212 */ 213 bool isOpen() const; 214 215 /*! 216 * Returns true if the file is open and readable. 217 */ 218 bool isValid() const; 219 220 /*! 221 * Move the I/O pointer to \a offset in the file from position \a p. This 222 * defaults to seeking from the beginning of the file. 223 * 224 * \see Position 225 */ 226 void seek(long offset, Position p = Beginning); 227 228 /*! 229 * Reset the end-of-file and error flags on the file. 230 */ 231 void clear(); 232 233 /*! 234 * Returns the current offset within the file. 235 */ 236 long tell() const; 237 238 /*! 239 * Returns the length of the file. 240 */ 241 long length(); 242 243 /*! 244 * Returns true if \a file can be opened for reading. If the file does not 245 * exist, this will return false. 246 * 247 * \deprecated 248 */ 249 static bool isReadable(const char *file); 250 251 /*! 252 * Returns true if \a file can be opened for writing. 253 * 254 * \deprecated 255 */ 256 static bool isWritable(const char *name); 257 258 protected: 259 /*! 260 * Construct a File object and opens the \a file. \a file should be a 261 * be a C-string in the local file system encoding. 262 * 263 * \note Constructor is protected since this class should only be 264 * instantiated through subclasses. 265 */ 266 File(FileName file); 267 268 /*! 269 * Construct a File object and use the \a stream instance. 270 * 271 * \note TagLib will *not* take ownership of the stream, the caller is 272 * responsible for deleting it after the File object. 273 * 274 * \note Constructor is protected since this class should only be 275 * instantiated through subclasses. 276 */ 277 File(IOStream *stream); 278 279 /*! 280 * Marks the file as valid or invalid. 281 * 282 * \see isValid() 283 */ 284 void setValid(bool valid); 285 286 /*! 287 * Truncates the file to a \a length. 288 */ 289 void truncate(long length); 290 291 /*! 292 * Returns the buffer size that is used for internal buffering. 293 */ 294 static unsigned int bufferSize(); 295 296 private: 297 File(const File &); 298 File &operator=(const File &); 299 300 class FilePrivate; 301 FilePrivate *d; 302 }; 303 304 } 305 306 #endif 307