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
35namespace 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 ID3v2 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