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