Audio file detection by content
This commit is contained in:
169
3rdparty/taglib/toolkit/taglib.h
vendored
Normal file
169
3rdparty/taglib/toolkit/taglib.h
vendored
Normal file
@@ -0,0 +1,169 @@
|
||||
/***************************************************************************
|
||||
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_H
|
||||
#define TAGLIB_H
|
||||
|
||||
#include "taglib_config.h"
|
||||
|
||||
#define TAGLIB_MAJOR_VERSION 1
|
||||
#define TAGLIB_MINOR_VERSION 11
|
||||
#define TAGLIB_PATCH_VERSION 1
|
||||
|
||||
#if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 1)) || defined(__clang__)
|
||||
#define TAGLIB_IGNORE_MISSING_DESTRUCTOR _Pragma("GCC diagnostic ignored \"-Wnon-virtual-dtor\"")
|
||||
#else
|
||||
#define TAGLIB_IGNORE_MISSING_DESTRUCTOR
|
||||
#endif
|
||||
|
||||
#if (defined(_MSC_VER) && _MSC_VER >= 1600)
|
||||
#define TAGLIB_CONSTRUCT_BITSET(x) static_cast<unsigned long long>(x)
|
||||
#else
|
||||
#define TAGLIB_CONSTRUCT_BITSET(x) static_cast<unsigned long>(x)
|
||||
#endif
|
||||
|
||||
#include <string>
|
||||
|
||||
//! A namespace for all TagLib related classes and functions
|
||||
|
||||
/*!
|
||||
* This namespace contains everything in TagLib. For projects working with
|
||||
* TagLib extensively it may be convenient to add a
|
||||
* \code
|
||||
* using namespace TagLib;
|
||||
* \endcode
|
||||
*/
|
||||
|
||||
namespace TagLib {
|
||||
|
||||
class String;
|
||||
|
||||
// These integer types are deprecated. Do not use them.
|
||||
|
||||
typedef wchar_t wchar; // Assumed to be sufficient to store a UTF-16 char.
|
||||
typedef unsigned char uchar;
|
||||
typedef unsigned short ushort;
|
||||
typedef unsigned int uint;
|
||||
typedef unsigned long ulong;
|
||||
typedef unsigned long long ulonglong;
|
||||
|
||||
/*!
|
||||
* Unfortunately std::wstring isn't defined on some systems, (i.e. GCC < 3)
|
||||
* so I'm providing something here that should be constant.
|
||||
*/
|
||||
typedef std::basic_string<wchar_t> wstring;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \mainpage TagLib
|
||||
*
|
||||
* \section intro Introduction
|
||||
*
|
||||
* TagLib is a library for reading and editing audio meta data, commonly know as \e tags.
|
||||
*
|
||||
* Features:
|
||||
* - A clean, high level, C++ API to handling audio meta data.
|
||||
* - Format specific APIs for advanced API users.
|
||||
* - ID3v1, ID3v2, APE, FLAC, Xiph, iTunes-style MP4 and WMA tag formats.
|
||||
* - MP3, MPC, FLAC, MP4, ASF, AIFF, WAV, TrueAudio, WavPack, Ogg FLAC, Ogg Vorbis, Speex and Opus file formats.
|
||||
* - Basic audio file properties such as length, sample rate, etc.
|
||||
* - Long term binary and source compatibility.
|
||||
* - Extensible design, notably the ability to add other formats or extend current formats as a library user.
|
||||
* - Full support for unicode and internationalized tags.
|
||||
* - Dual <a href="http://www.mozilla.org/MPL/MPL-1.1.html">MPL</a> and
|
||||
* <a href="http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html">LGPL</a> licenses.
|
||||
* - No external toolkit dependencies.
|
||||
*
|
||||
* \section why Why TagLib?
|
||||
*
|
||||
* TagLib originally was written to provide an updated and improved ID3v2 implementation in C++ for use
|
||||
* in a variety of Open Source projects. Since development began in 2002 and the 1.0 release in 2004
|
||||
* it has expanded to cover a wide variety of tag and file formats and is used in a wide variety of
|
||||
* Open Source and proprietary applications. It now supports a variety of UNIXes, including Apple's OS
|
||||
* X, as well as Microsoft Windows.
|
||||
*
|
||||
* \section commercial Usage in Commercial Applications
|
||||
*
|
||||
* TagLib's licenses \e do allow usage within propriety (\e closed) applications, however TagLib is \e not
|
||||
* public domain. Please note the requirements of the LGPL or MPL, and adhere to at least one of them.
|
||||
* In simple terms, you must at a minimum note your usage of TagLib, note the licensing terms of TagLib and
|
||||
* if you make changes to TagLib publish them. Please review the licenses above before using TagLib in your
|
||||
* software. Note that you may choose either the MPL or the LGPL, you do not have to fulfill the
|
||||
* requirements of both.
|
||||
*
|
||||
* \section installing Installing TagLib
|
||||
*
|
||||
* Please see the <a href="http://taglib.org/">TagLib website</a> for the latest
|
||||
* downloads.
|
||||
*
|
||||
* TagLib can be built using the CMake build system. TagLib installs a taglib-config and pkg-config file to
|
||||
* make it easier to integrate into various build systems. Note that TagLib's include install directory \e must
|
||||
* be included in the header include path. Simply adding <taglib/tag.h> will \e not work.
|
||||
*
|
||||
* \section start Getting Started
|
||||
*
|
||||
* TagLib provides both simple, abstract APIs which make it possible to ignore the differences between tagging
|
||||
* formats and format specific APIs which allow programmers to work with the features of specific tagging
|
||||
* schemes. There is a similar abstraction mechanism for AudioProperties.
|
||||
*
|
||||
* The best place to start is with the <b>Class Hierarchy</b> linked at the top of the page. The File and
|
||||
* AudioProperties classes and their subclasses are the core of TagLib. The FileRef class is also a convenient
|
||||
* way for using a value-based handle.
|
||||
*
|
||||
* \note When working with FileRef please consider that it has only the most basic (extension-based) file
|
||||
* type resolution. Please see its documentation on how to plug in more advanced file type resolution. (Such
|
||||
* resolution may be part of later TagLib releases by default.)
|
||||
*
|
||||
* Here's a very simple example with TagLib:
|
||||
*
|
||||
* \code
|
||||
*
|
||||
* TagLib::FileRef f("Latex Solar Beef.mp3");
|
||||
* TagLib::String artist = f.tag()->artist(); // artist == "Frank Zappa"
|
||||
*
|
||||
* f.tag()->setAlbum("Fillmore East");
|
||||
* f.save();
|
||||
*
|
||||
* TagLib::FileRef g("Free City Rhymes.ogg");
|
||||
* TagLib::String album = g.tag()->album(); // album == "NYC Ghosts & Flowers"
|
||||
*
|
||||
* g.tag()->setTrack(1);
|
||||
* g.save();
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* More examples can be found in the \e examples directory of the source distribution.
|
||||
*
|
||||
* \section Contact
|
||||
*
|
||||
* Questions about TagLib should be directed to the TagLib mailing list, not directly to the author.
|
||||
*
|
||||
* - <a href="http://taglib.org/">TagLib Homepage</a>
|
||||
* - <a href="https://mail.kde.org/mailman/listinfo/taglib-devel">TagLib Mailing List (taglib-devel@kde.org)</a>
|
||||
*
|
||||
* \author <a href="https://github.com/taglib/taglib/blob/master/AUTHORS">TagLib authors</a>.
|
||||
*/
|
||||
|
||||
#endif
|
||||
1044
3rdparty/taglib/toolkit/tbytevector.cpp
vendored
Normal file
1044
3rdparty/taglib/toolkit/tbytevector.cpp
vendored
Normal file
File diff suppressed because it is too large
Load Diff
635
3rdparty/taglib/toolkit/tbytevector.h
vendored
Normal file
635
3rdparty/taglib/toolkit/tbytevector.h
vendored
Normal file
@@ -0,0 +1,635 @@
|
||||
/***************************************************************************
|
||||
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_BYTEVECTOR_H
|
||||
#define TAGLIB_BYTEVECTOR_H
|
||||
|
||||
#include "taglib.h"
|
||||
#include "taglib_export.h"
|
||||
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
|
||||
namespace TagLib {
|
||||
|
||||
//! A byte vector
|
||||
|
||||
/*!
|
||||
* This class provides a byte vector with some methods that are useful for
|
||||
* tagging purposes. Many of the search functions are tailored to what is
|
||||
* useful for finding tag related patterns in a data array.
|
||||
*/
|
||||
|
||||
class TAGLIB_EXPORT ByteVector
|
||||
{
|
||||
public:
|
||||
#ifndef DO_NOT_DOCUMENT
|
||||
typedef std::vector<char>::iterator Iterator;
|
||||
typedef std::vector<char>::const_iterator ConstIterator;
|
||||
typedef std::vector<char>::reverse_iterator ReverseIterator;
|
||||
typedef std::vector<char>::const_reverse_iterator ConstReverseIterator;
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* Constructs an empty byte vector.
|
||||
*/
|
||||
ByteVector();
|
||||
|
||||
/*!
|
||||
* Construct a vector of size \a size with all values set to \a value by
|
||||
* default.
|
||||
*/
|
||||
ByteVector(unsigned int size, char value = 0);
|
||||
|
||||
/*!
|
||||
* Constructs a byte vector that is a copy of \a v.
|
||||
*/
|
||||
ByteVector(const ByteVector &v);
|
||||
|
||||
/*!
|
||||
* Constructs a byte vector that is a copy of \a v.
|
||||
*/
|
||||
ByteVector(const ByteVector &v, unsigned int offset, unsigned int length);
|
||||
|
||||
/*!
|
||||
* Constructs a byte vector that contains \a c.
|
||||
*/
|
||||
ByteVector(char c);
|
||||
|
||||
/*!
|
||||
* Constructs a byte vector that copies \a data for up to \a length bytes.
|
||||
*/
|
||||
ByteVector(const char *data, unsigned int length);
|
||||
|
||||
/*!
|
||||
* Constructs a byte vector that copies \a data up to the first null
|
||||
* byte. This is particularly useful for constructing byte arrays from
|
||||
* string constants.
|
||||
*
|
||||
* \warning The behavior is undefined if \a data is not null terminated.
|
||||
*/
|
||||
ByteVector(const char *data);
|
||||
|
||||
/*!
|
||||
* Destroys this ByteVector instance.
|
||||
*/
|
||||
virtual ~ByteVector();
|
||||
|
||||
/*!
|
||||
* Sets the data for the byte array using the first \a length bytes of \a data
|
||||
*/
|
||||
ByteVector &setData(const char *data, unsigned int length);
|
||||
|
||||
/*!
|
||||
* Sets the data for the byte array copies \a data up to the first null
|
||||
* byte. The behavior is undefined if \a data is not null terminated.
|
||||
*/
|
||||
ByteVector &setData(const char *data);
|
||||
|
||||
/*!
|
||||
* Returns a pointer to the internal data structure.
|
||||
*
|
||||
* \warning Care should be taken when modifying this data structure as it is
|
||||
* easy to corrupt the ByteVector when doing so. Specifically, while the
|
||||
* data may be changed, its length may not be.
|
||||
*/
|
||||
char *data();
|
||||
|
||||
/*!
|
||||
* Returns a pointer to the internal data structure which may not be modified.
|
||||
*/
|
||||
const char *data() const;
|
||||
|
||||
/*!
|
||||
* Returns a byte vector made up of the bytes starting at \a index and
|
||||
* for \a length bytes. If \a length is not specified it will return the bytes
|
||||
* from \a index to the end of the vector.
|
||||
*/
|
||||
ByteVector mid(unsigned int index, unsigned int length = 0xffffffff) const;
|
||||
|
||||
/*!
|
||||
* This essentially performs the same as operator[](), but instead of causing
|
||||
* a runtime error if the index is out of bounds, it will return a null byte.
|
||||
*/
|
||||
char at(unsigned int index) const;
|
||||
|
||||
/*!
|
||||
* Searches the ByteVector for \a pattern starting at \a offset and returns
|
||||
* the offset. Returns -1 if the pattern was not found. If \a byteAlign is
|
||||
* specified the pattern will only be matched if it starts on a byte divisible
|
||||
* by \a byteAlign (starting from \a offset).
|
||||
*/
|
||||
int find(const ByteVector &pattern, unsigned int offset = 0, int byteAlign = 1) const;
|
||||
|
||||
/*!
|
||||
* Searches the char for \a c starting at \a offset and returns
|
||||
* the offset. Returns \a -1 if the pattern was not found. If \a byteAlign is
|
||||
* specified the pattern will only be matched if it starts on a byte divisible
|
||||
* by \a byteAlign (starting from \a offset).
|
||||
*/
|
||||
int find(char c, unsigned int offset = 0, int byteAlign = 1) const;
|
||||
|
||||
/*!
|
||||
* Searches the ByteVector for \a pattern starting from either the end of the
|
||||
* vector or \a offset and returns the offset. Returns -1 if the pattern was
|
||||
* not found. If \a byteAlign is specified the pattern will only be matched
|
||||
* if it starts on a byte divisible by \a byteAlign (starting from \a offset).
|
||||
*/
|
||||
int rfind(const ByteVector &pattern, unsigned int offset = 0, int byteAlign = 1) const;
|
||||
|
||||
/*!
|
||||
* Checks to see if the vector contains the \a pattern starting at position
|
||||
* \a offset. Optionally, if you only want to search for part of the pattern
|
||||
* you can specify an offset within the pattern to start from. Also, you can
|
||||
* specify to only check for the first \a patternLength bytes of \a pattern with
|
||||
* the \a patternLength argument.
|
||||
*/
|
||||
bool containsAt(const ByteVector &pattern, unsigned int offset,
|
||||
unsigned int patternOffset = 0, unsigned int patternLength = 0xffffffff) const;
|
||||
|
||||
/*!
|
||||
* Returns true if the vector starts with \a pattern.
|
||||
*/
|
||||
bool startsWith(const ByteVector &pattern) const;
|
||||
|
||||
/*!
|
||||
* Returns true if the vector ends with \a pattern.
|
||||
*/
|
||||
bool endsWith(const ByteVector &pattern) const;
|
||||
|
||||
/*!
|
||||
* Replaces \a oldByte with \a newByte and returns a reference to the
|
||||
* ByteVector after the operation. This \e does modify the vector.
|
||||
*/
|
||||
ByteVector &replace(char oldByte, char newByte);
|
||||
|
||||
/*!
|
||||
* Replaces \a pattern with \a with and returns a reference to the ByteVector
|
||||
* after the operation. This \e does modify the vector.
|
||||
*/
|
||||
ByteVector &replace(const ByteVector &pattern, const ByteVector &with);
|
||||
|
||||
/*!
|
||||
* Checks for a partial match of \a pattern at the end of the vector. It
|
||||
* returns the offset of the partial match within the vector, or -1 if the
|
||||
* pattern is not found. This method is particularly useful when searching for
|
||||
* patterns that start in one vector and end in another. When combined with
|
||||
* startsWith() it can be used to find a pattern that overlaps two buffers.
|
||||
*
|
||||
* \note This will not match the complete pattern at the end of the string; use
|
||||
* endsWith() for that.
|
||||
*/
|
||||
int endsWithPartialMatch(const ByteVector &pattern) const;
|
||||
|
||||
/*!
|
||||
* Appends \a v to the end of the ByteVector.
|
||||
*/
|
||||
ByteVector &append(const ByteVector &v);
|
||||
|
||||
/*!
|
||||
* Appends \a c to the end of the ByteVector.
|
||||
*/
|
||||
ByteVector &append(char c);
|
||||
|
||||
/*!
|
||||
* Clears the data.
|
||||
*/
|
||||
ByteVector &clear();
|
||||
|
||||
/*!
|
||||
* Returns the size of the array.
|
||||
*/
|
||||
unsigned int size() const;
|
||||
|
||||
/*!
|
||||
* Resize the vector to \a size. If the vector is currently less than
|
||||
* \a size, pad the remaining spaces with \a padding. Returns a reference
|
||||
* to the resized vector.
|
||||
*/
|
||||
ByteVector &resize(unsigned int size, char padding = 0);
|
||||
|
||||
/*!
|
||||
* Returns an Iterator that points to the front of the vector.
|
||||
*/
|
||||
Iterator begin();
|
||||
|
||||
/*!
|
||||
* Returns a ConstIterator that points to the front of the vector.
|
||||
*/
|
||||
ConstIterator begin() const;
|
||||
|
||||
/*!
|
||||
* Returns an Iterator that points to the back of the vector.
|
||||
*/
|
||||
Iterator end();
|
||||
|
||||
/*!
|
||||
* Returns a ConstIterator that points to the back of the vector.
|
||||
*/
|
||||
ConstIterator end() const;
|
||||
|
||||
/*!
|
||||
* Returns a ReverseIterator that points to the front of the vector.
|
||||
*/
|
||||
ReverseIterator rbegin();
|
||||
|
||||
/*!
|
||||
* Returns a ConstReverseIterator that points to the front of the vector.
|
||||
*/
|
||||
ConstReverseIterator rbegin() const;
|
||||
|
||||
/*!
|
||||
* Returns a ReverseIterator that points to the back of the vector.
|
||||
*/
|
||||
ReverseIterator rend();
|
||||
|
||||
/*!
|
||||
* Returns a ConstReverseIterator that points to the back of the vector.
|
||||
*/
|
||||
ConstReverseIterator rend() const;
|
||||
|
||||
/*!
|
||||
* Returns true if the vector is null.
|
||||
*
|
||||
* \note A vector may be empty without being null. So do not use this
|
||||
* method to check if the vector is empty.
|
||||
*
|
||||
* \see isEmpty()
|
||||
*
|
||||
* \deprecated
|
||||
*/
|
||||
// BIC: remove
|
||||
bool isNull() const;
|
||||
|
||||
/*!
|
||||
* Returns true if the ByteVector is empty.
|
||||
*
|
||||
* \see size()
|
||||
* \see isNull()
|
||||
*/
|
||||
bool isEmpty() const;
|
||||
|
||||
/*!
|
||||
* Returns a CRC checksum of the byte vector's data.
|
||||
*
|
||||
* \note This uses an uncommon variant of CRC32 specializes in Ogg.
|
||||
*/
|
||||
// BIC: Remove or make generic.
|
||||
unsigned int checksum() const;
|
||||
|
||||
/*!
|
||||
* Converts the first 4 bytes of the vector to an unsigned integer.
|
||||
*
|
||||
* If \a mostSignificantByteFirst is true this will operate left to right
|
||||
* evaluating the integer. For example if \a mostSignificantByteFirst is
|
||||
* true then $00 $00 $00 $01 == 0x00000001 == 1, if false, $01 00 00 00 ==
|
||||
* 0x01000000 == 1.
|
||||
*
|
||||
* \see fromUInt()
|
||||
*/
|
||||
unsigned int toUInt(bool mostSignificantByteFirst = true) const;
|
||||
|
||||
/*!
|
||||
* Converts the 4 bytes at \a offset of the vector to an unsigned integer.
|
||||
*
|
||||
* If \a mostSignificantByteFirst is true this will operate left to right
|
||||
* evaluating the integer. For example if \a mostSignificantByteFirst is
|
||||
* true then $00 $00 $00 $01 == 0x00000001 == 1, if false, $01 00 00 00 ==
|
||||
* 0x01000000 == 1.
|
||||
*
|
||||
* \see fromUInt()
|
||||
*/
|
||||
unsigned int toUInt(unsigned int offset, bool mostSignificantByteFirst = true) const;
|
||||
|
||||
/*!
|
||||
* Converts the \a length bytes at \a offset of the vector to an unsigned
|
||||
* integer. If \a length is larger than 4, the excess is ignored.
|
||||
*
|
||||
* If \a mostSignificantByteFirst is true this will operate left to right
|
||||
* evaluating the integer. For example if \a mostSignificantByteFirst is
|
||||
* true then $00 $00 $00 $01 == 0x00000001 == 1, if false, $01 00 00 00 ==
|
||||
* 0x01000000 == 1.
|
||||
*
|
||||
* \see fromUInt()
|
||||
*/
|
||||
unsigned int toUInt(unsigned int offset, unsigned int length,
|
||||
bool mostSignificantByteFirst = true) const;
|
||||
|
||||
/*!
|
||||
* Converts the first 2 bytes of the vector to a (signed) short.
|
||||
*
|
||||
* If \a mostSignificantByteFirst is true this will operate left to right
|
||||
* evaluating the integer. For example if \a mostSignificantByteFirst is
|
||||
* true then $00 $01 == 0x0001 == 1, if false, $01 00 == 0x01000000 == 1.
|
||||
*
|
||||
* \see fromShort()
|
||||
*/
|
||||
short toShort(bool mostSignificantByteFirst = true) const;
|
||||
|
||||
/*!
|
||||
* Converts the 2 bytes at \a offset of the vector to a (signed) short.
|
||||
*
|
||||
* If \a mostSignificantByteFirst is true this will operate left to right
|
||||
* evaluating the integer. For example if \a mostSignificantByteFirst is
|
||||
* true then $00 $01 == 0x0001 == 1, if false, $01 00 == 0x01000000 == 1.
|
||||
*
|
||||
* \see fromShort()
|
||||
*/
|
||||
short toShort(unsigned int offset, bool mostSignificantByteFirst = true) const;
|
||||
|
||||
/*!
|
||||
* Converts the first 2 bytes of the vector to a unsigned short.
|
||||
*
|
||||
* If \a mostSignificantByteFirst is true this will operate left to right
|
||||
* evaluating the integer. For example if \a mostSignificantByteFirst is
|
||||
* true then $00 $01 == 0x0001 == 1, if false, $01 00 == 0x01000000 == 1.
|
||||
*
|
||||
* \see fromShort()
|
||||
*/
|
||||
unsigned short toUShort(bool mostSignificantByteFirst = true) const;
|
||||
|
||||
/*!
|
||||
* Converts the 2 bytes at \a offset of the vector to a unsigned short.
|
||||
*
|
||||
* If \a mostSignificantByteFirst is true this will operate left to right
|
||||
* evaluating the integer. For example if \a mostSignificantByteFirst is
|
||||
* true then $00 $01 == 0x0001 == 1, if false, $01 00 == 0x01000000 == 1.
|
||||
*
|
||||
* \see fromShort()
|
||||
*/
|
||||
unsigned short toUShort(unsigned int offset, bool mostSignificantByteFirst = true) const;
|
||||
|
||||
/*!
|
||||
* Converts the first 8 bytes of the vector to a (signed) long long.
|
||||
*
|
||||
* If \a mostSignificantByteFirst is true this will operate left to right
|
||||
* evaluating the integer. For example if \a mostSignificantByteFirst is
|
||||
* true then $00 00 00 00 00 00 00 01 == 0x0000000000000001 == 1,
|
||||
* if false, $01 00 00 00 00 00 00 00 == 0x0100000000000000 == 1.
|
||||
*
|
||||
* \see fromUInt()
|
||||
*/
|
||||
long long toLongLong(bool mostSignificantByteFirst = true) const;
|
||||
|
||||
/*!
|
||||
* Converts the 8 bytes at \a offset of the vector to a (signed) long long.
|
||||
*
|
||||
* If \a mostSignificantByteFirst is true this will operate left to right
|
||||
* evaluating the integer. For example if \a mostSignificantByteFirst is
|
||||
* true then $00 00 00 00 00 00 00 01 == 0x0000000000000001 == 1,
|
||||
* if false, $01 00 00 00 00 00 00 00 == 0x0100000000000000 == 1.
|
||||
*
|
||||
* \see fromUInt()
|
||||
*/
|
||||
long long toLongLong(unsigned int offset, bool mostSignificantByteFirst = true) const;
|
||||
|
||||
/*
|
||||
* Converts the 4 bytes at \a offset of the vector to a float as an IEEE754
|
||||
* 32-bit little-endian floating point number.
|
||||
*/
|
||||
float toFloat32LE(size_t offset) const;
|
||||
|
||||
/*
|
||||
* Converts the 4 bytes at \a offset of the vector to a float as an IEEE754
|
||||
* 32-bit big-endian floating point number.
|
||||
*/
|
||||
float toFloat32BE(size_t offset) const;
|
||||
|
||||
/*
|
||||
* Converts the 8 bytes at \a offset of the vector to a double as an IEEE754
|
||||
* 64-bit little-endian floating point number.
|
||||
*/
|
||||
double toFloat64LE(size_t offset) const;
|
||||
|
||||
/*
|
||||
* Converts the 8 bytes at \a offset of the vector to a double as an IEEE754
|
||||
* 64-bit big-endian floating point number.
|
||||
*/
|
||||
double toFloat64BE(size_t offset) const;
|
||||
|
||||
/*
|
||||
* Converts the 10 bytes at \a offset of the vector to a long double as an
|
||||
* IEEE754 80-bit little-endian floating point number.
|
||||
*
|
||||
* \note This may compromise the precision depends on the size of long double.
|
||||
*/
|
||||
long double toFloat80LE(size_t offset) const;
|
||||
|
||||
/*
|
||||
* Converts the 10 bytes at \a offset of the vector to a long double as an
|
||||
* IEEE754 80-bit big-endian floating point number.
|
||||
*
|
||||
* \note This may compromise the precision depends on the size of long double.
|
||||
*/
|
||||
long double toFloat80BE(size_t offset) const;
|
||||
|
||||
/*!
|
||||
* Creates a 4 byte ByteVector based on \a value. If
|
||||
* \a mostSignificantByteFirst is true, then this will operate left to right
|
||||
* in building the ByteVector. For example if \a mostSignificantByteFirst is
|
||||
* true then $00 00 00 01 == 0x00000001 == 1, if false, $01 00 00 00 ==
|
||||
* 0x01000000 == 1.
|
||||
*
|
||||
* \see toUInt()
|
||||
*/
|
||||
static ByteVector fromUInt(unsigned int value, bool mostSignificantByteFirst = true);
|
||||
|
||||
/*!
|
||||
* Creates a 2 byte ByteVector based on \a value. If
|
||||
* \a mostSignificantByteFirst is true, then this will operate left to right
|
||||
* in building the ByteVector. For example if \a mostSignificantByteFirst is
|
||||
* true then $00 01 == 0x0001 == 1, if false, $01 00 == 0x0100 == 1.
|
||||
*
|
||||
* \see toShort()
|
||||
*/
|
||||
static ByteVector fromShort(short value, bool mostSignificantByteFirst = true);
|
||||
|
||||
/*!
|
||||
* Creates a 8 byte ByteVector based on \a value. If
|
||||
* \a mostSignificantByteFirst is true, then this will operate left to right
|
||||
* in building the ByteVector. For example if \a mostSignificantByteFirst is
|
||||
* true then $00 00 00 01 == 0x0000000000000001 == 1, if false,
|
||||
* $01 00 00 00 00 00 00 00 == 0x0100000000000000 == 1.
|
||||
*
|
||||
* \see toLongLong()
|
||||
*/
|
||||
static ByteVector fromLongLong(long long value, bool mostSignificantByteFirst = true);
|
||||
|
||||
/*!
|
||||
* Creates a 4 byte ByteVector based on \a value as an IEEE754 32-bit
|
||||
* little-endian floating point number.
|
||||
*
|
||||
* \see fromFloat32BE()
|
||||
*/
|
||||
static ByteVector fromFloat32LE(float value);
|
||||
|
||||
/*!
|
||||
* Creates a 4 byte ByteVector based on \a value as an IEEE754 32-bit
|
||||
* big-endian floating point number.
|
||||
*
|
||||
* \see fromFloat32LE()
|
||||
*/
|
||||
static ByteVector fromFloat32BE(float value);
|
||||
|
||||
/*!
|
||||
* Creates a 8 byte ByteVector based on \a value as an IEEE754 64-bit
|
||||
* little-endian floating point number.
|
||||
*
|
||||
* \see fromFloat64BE()
|
||||
*/
|
||||
static ByteVector fromFloat64LE(double value);
|
||||
|
||||
/*!
|
||||
* Creates a 8 byte ByteVector based on \a value as an IEEE754 64-bit
|
||||
* big-endian floating point number.
|
||||
*
|
||||
* \see fromFloat64LE()
|
||||
*/
|
||||
static ByteVector fromFloat64BE(double value);
|
||||
|
||||
/*!
|
||||
* Returns a ByteVector based on the CString \a s.
|
||||
*/
|
||||
static ByteVector fromCString(const char *s, unsigned int length = 0xffffffff);
|
||||
|
||||
/*!
|
||||
* Returns a const reference to the byte at \a index.
|
||||
*/
|
||||
const char &operator[](int index) const;
|
||||
|
||||
/*!
|
||||
* Returns a reference to the byte at \a index.
|
||||
*/
|
||||
char &operator[](int index);
|
||||
|
||||
/*!
|
||||
* Returns true if this ByteVector and \a v are equal.
|
||||
*/
|
||||
bool operator==(const ByteVector &v) const;
|
||||
|
||||
/*!
|
||||
* Returns true if this ByteVector and \a v are not equal.
|
||||
*/
|
||||
bool operator!=(const ByteVector &v) const;
|
||||
|
||||
/*!
|
||||
* Returns true if this ByteVector and the null terminated C string \a s
|
||||
* contain the same data.
|
||||
*/
|
||||
bool operator==(const char *s) const;
|
||||
|
||||
/*!
|
||||
* Returns true if this ByteVector and the null terminated C string \a s
|
||||
* do not contain the same data.
|
||||
*/
|
||||
bool operator!=(const char *s) const;
|
||||
|
||||
/*!
|
||||
* Returns true if this ByteVector is less than \a v. The value of the
|
||||
* vectors is determined by evaluating the character from left to right, and
|
||||
* in the event one vector is a superset of the other, the size is used.
|
||||
*/
|
||||
bool operator<(const ByteVector &v) const;
|
||||
|
||||
/*!
|
||||
* Returns true if this ByteVector is greater than \a v.
|
||||
*/
|
||||
bool operator>(const ByteVector &v) const;
|
||||
|
||||
/*!
|
||||
* Returns a vector that is \a v appended to this vector.
|
||||
*/
|
||||
ByteVector operator+(const ByteVector &v) const;
|
||||
|
||||
/*!
|
||||
* Copies ByteVector \a v.
|
||||
*/
|
||||
ByteVector &operator=(const ByteVector &v);
|
||||
|
||||
/*!
|
||||
* Copies a byte \a c.
|
||||
*/
|
||||
ByteVector &operator=(char c);
|
||||
|
||||
/*!
|
||||
* Copies \a data up to the first null byte.
|
||||
*
|
||||
* \warning The behavior is undefined if \a data is not null terminated.
|
||||
*/
|
||||
ByteVector &operator=(const char *data);
|
||||
|
||||
/*!
|
||||
* Exchanges the content of the ByteVector by the content of \a v.
|
||||
*/
|
||||
void swap(ByteVector &v);
|
||||
|
||||
/*!
|
||||
* A static, empty ByteVector which is convenient and fast (since returning
|
||||
* an empty or "null" value does not require instantiating a new ByteVector).
|
||||
*
|
||||
* \warning Do not modify this variable. It will mess up the internal state
|
||||
* of TagLib.
|
||||
*
|
||||
* \deprecated
|
||||
*/
|
||||
// BIC: remove
|
||||
static ByteVector null;
|
||||
|
||||
/*!
|
||||
* Returns a hex-encoded copy of the byte vector.
|
||||
*/
|
||||
ByteVector toHex() const;
|
||||
|
||||
/*!
|
||||
* Returns a base64 encoded copy of the byte vector
|
||||
*/
|
||||
ByteVector toBase64() const;
|
||||
|
||||
/*!
|
||||
* Decodes the base64 encoded byte vector.
|
||||
*/
|
||||
static ByteVector fromBase64(const ByteVector &);
|
||||
|
||||
protected:
|
||||
/*
|
||||
* If this ByteVector is being shared via implicit sharing, do a deep copy
|
||||
* of the data and separate from the shared members. This should be called
|
||||
* by all non-const subclass members.
|
||||
*/
|
||||
void detach();
|
||||
|
||||
private:
|
||||
class ByteVectorPrivate;
|
||||
ByteVectorPrivate *d;
|
||||
};
|
||||
}
|
||||
|
||||
/*!
|
||||
* \relates TagLib::ByteVector
|
||||
* Streams the ByteVector \a v to the output stream \a s.
|
||||
*/
|
||||
TAGLIB_EXPORT std::ostream &operator<<(std::ostream &s, const TagLib::ByteVector &v);
|
||||
|
||||
#endif
|
||||
102
3rdparty/taglib/toolkit/tbytevectorlist.cpp
vendored
Normal file
102
3rdparty/taglib/toolkit/tbytevectorlist.cpp
vendored
Normal file
@@ -0,0 +1,102 @@
|
||||
/***************************************************************************
|
||||
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/ *
|
||||
***************************************************************************/
|
||||
|
||||
#include "tbytevectorlist.h"
|
||||
|
||||
using namespace TagLib;
|
||||
|
||||
class ByteVectorListPrivate
|
||||
{
|
||||
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// static members
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ByteVectorList ByteVectorList::split(const ByteVector &v, const ByteVector &pattern,
|
||||
int byteAlign)
|
||||
{
|
||||
return split(v, pattern, byteAlign, 0);
|
||||
}
|
||||
|
||||
ByteVectorList ByteVectorList::split(const ByteVector &v, const ByteVector &pattern,
|
||||
int byteAlign, int max)
|
||||
{
|
||||
ByteVectorList l;
|
||||
|
||||
unsigned int previousOffset = 0;
|
||||
for(int offset = v.find(pattern, 0, byteAlign);
|
||||
offset != -1 && (max == 0 || max > int(l.size()) + 1);
|
||||
offset = v.find(pattern, offset + pattern.size(), byteAlign))
|
||||
{
|
||||
if(offset - previousOffset >= 1)
|
||||
l.append(v.mid(previousOffset, offset - previousOffset));
|
||||
else
|
||||
l.append(ByteVector());
|
||||
|
||||
previousOffset = offset + pattern.size();
|
||||
}
|
||||
|
||||
if(previousOffset < v.size())
|
||||
l.append(v.mid(previousOffset, v.size() - previousOffset));
|
||||
|
||||
return l;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// public members
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ByteVectorList::ByteVectorList() : List<ByteVector>()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
ByteVectorList::ByteVectorList(const ByteVectorList &l) : List<ByteVector>(l)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
ByteVectorList::~ByteVectorList()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
ByteVector ByteVectorList::toByteVector(const ByteVector &separator) const
|
||||
{
|
||||
ByteVector v;
|
||||
|
||||
ConstIterator it = begin();
|
||||
|
||||
while(it != end()) {
|
||||
v.append(*it);
|
||||
it++;
|
||||
if(it != end())
|
||||
v.append(separator);
|
||||
}
|
||||
|
||||
return v;
|
||||
}
|
||||
91
3rdparty/taglib/toolkit/tbytevectorlist.h
vendored
Normal file
91
3rdparty/taglib/toolkit/tbytevectorlist.h
vendored
Normal file
@@ -0,0 +1,91 @@
|
||||
/***************************************************************************
|
||||
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_BYTEVECTORLIST_H
|
||||
#define TAGLIB_BYTEVECTORLIST_H
|
||||
|
||||
#include "taglib_export.h"
|
||||
#include "tbytevector.h"
|
||||
#include "tlist.h"
|
||||
|
||||
namespace TagLib {
|
||||
|
||||
//! A list of ByteVectors
|
||||
|
||||
/*!
|
||||
* A List specialization with some handy features useful for ByteVectors.
|
||||
*/
|
||||
|
||||
class TAGLIB_EXPORT ByteVectorList : public List<ByteVector>
|
||||
{
|
||||
public:
|
||||
|
||||
/*!
|
||||
* Construct an empty ByteVectorList.
|
||||
*/
|
||||
ByteVectorList();
|
||||
|
||||
/*!
|
||||
* Destroys this ByteVectorList instance.
|
||||
*/
|
||||
virtual ~ByteVectorList();
|
||||
|
||||
/*!
|
||||
* Make a shallow, implicitly shared, copy of \a l. Because this is
|
||||
* implicitly shared, this method is lightweight and suitable for
|
||||
* pass-by-value usage.
|
||||
*/
|
||||
ByteVectorList(const ByteVectorList &l);
|
||||
|
||||
/*!
|
||||
* Convert the ByteVectorList to a ByteVector separated by \a separator. By
|
||||
* default a space is used.
|
||||
*/
|
||||
ByteVector toByteVector(const ByteVector &separator = " ") const;
|
||||
|
||||
/*!
|
||||
* Splits the ByteVector \a v into several strings at \a pattern. This will
|
||||
* not include the pattern in the returned ByteVectors.
|
||||
*/
|
||||
static ByteVectorList split(const ByteVector &v, const ByteVector &pattern,
|
||||
int byteAlign = 1);
|
||||
/*!
|
||||
* Splits the ByteVector \a v into several strings at \a pattern. This will
|
||||
* not include the pattern in the returned ByteVectors. \a max is the
|
||||
* maximum number of entries that will be separated. If \a max for instance
|
||||
* is 2 then a maximum of 1 match will be found and the vector will be split
|
||||
* on that match.
|
||||
*/
|
||||
// BIC: merge with the function above
|
||||
static ByteVectorList split(const ByteVector &v, const ByteVector &pattern,
|
||||
int byteAlign, int max);
|
||||
private:
|
||||
class ByteVectorListPrivate;
|
||||
ByteVectorListPrivate *d;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
167
3rdparty/taglib/toolkit/tbytevectorstream.cpp
vendored
Normal file
167
3rdparty/taglib/toolkit/tbytevectorstream.cpp
vendored
Normal file
@@ -0,0 +1,167 @@
|
||||
/***************************************************************************
|
||||
copyright : (C) 2011 by Lukas Lalinsky
|
||||
email : lalinsky@gmail.com
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* 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/ *
|
||||
***************************************************************************/
|
||||
|
||||
#include "tbytevectorstream.h"
|
||||
#include "tstring.h"
|
||||
#include "tdebug.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
using namespace TagLib;
|
||||
|
||||
class ByteVectorStream::ByteVectorStreamPrivate
|
||||
{
|
||||
public:
|
||||
ByteVectorStreamPrivate(const ByteVector &data);
|
||||
|
||||
ByteVector data;
|
||||
long position;
|
||||
};
|
||||
|
||||
ByteVectorStream::ByteVectorStreamPrivate::ByteVectorStreamPrivate(const ByteVector &data) :
|
||||
data(data),
|
||||
position(0)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// public members
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ByteVectorStream::ByteVectorStream(const ByteVector &data) :
|
||||
d(new ByteVectorStreamPrivate(data))
|
||||
{
|
||||
}
|
||||
|
||||
ByteVectorStream::~ByteVectorStream()
|
||||
{
|
||||
delete d;
|
||||
}
|
||||
|
||||
FileName ByteVectorStream::name() const
|
||||
{
|
||||
return FileName(""); // XXX do we need a name?
|
||||
}
|
||||
|
||||
ByteVector ByteVectorStream::readBlock(unsigned long length)
|
||||
{
|
||||
if(length == 0)
|
||||
return ByteVector();
|
||||
|
||||
ByteVector v = d->data.mid(d->position, length);
|
||||
d->position += v.size();
|
||||
return v;
|
||||
}
|
||||
|
||||
void ByteVectorStream::writeBlock(const ByteVector &data)
|
||||
{
|
||||
unsigned int size = data.size();
|
||||
if(long(d->position + size) > length()) {
|
||||
truncate(d->position + size);
|
||||
}
|
||||
memcpy(d->data.data() + d->position, data.data(), size);
|
||||
d->position += size;
|
||||
}
|
||||
|
||||
void ByteVectorStream::insert(const ByteVector &data, unsigned long start, unsigned long replace)
|
||||
{
|
||||
long sizeDiff = data.size() - replace;
|
||||
if(sizeDiff < 0) {
|
||||
removeBlock(start + data.size(), -sizeDiff);
|
||||
}
|
||||
else if(sizeDiff > 0) {
|
||||
truncate(length() + sizeDiff);
|
||||
unsigned long readPosition = start + replace;
|
||||
unsigned long writePosition = start + data.size();
|
||||
memmove(d->data.data() + writePosition, d->data.data() + readPosition, length() - sizeDiff - readPosition);
|
||||
}
|
||||
seek(start);
|
||||
writeBlock(data);
|
||||
}
|
||||
|
||||
void ByteVectorStream::removeBlock(unsigned long start, unsigned long length)
|
||||
{
|
||||
unsigned long readPosition = start + length;
|
||||
unsigned long writePosition = start;
|
||||
if(readPosition < static_cast<unsigned long>(ByteVectorStream::length())) {
|
||||
unsigned long bytesToMove = ByteVectorStream::length() - readPosition;
|
||||
memmove(d->data.data() + writePosition, d->data.data() + readPosition, bytesToMove);
|
||||
writePosition += bytesToMove;
|
||||
}
|
||||
d->position = writePosition;
|
||||
truncate(writePosition);
|
||||
}
|
||||
|
||||
bool ByteVectorStream::readOnly() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ByteVectorStream::isOpen() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void ByteVectorStream::seek(long offset, Position p)
|
||||
{
|
||||
switch(p) {
|
||||
case Beginning:
|
||||
d->position = offset;
|
||||
break;
|
||||
case Current:
|
||||
d->position += offset;
|
||||
break;
|
||||
case End:
|
||||
d->position = length() + offset; // offset is expected to be negative
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void ByteVectorStream::clear()
|
||||
{
|
||||
}
|
||||
|
||||
long ByteVectorStream::tell() const
|
||||
{
|
||||
return d->position;
|
||||
}
|
||||
|
||||
long ByteVectorStream::length()
|
||||
{
|
||||
return d->data.size();
|
||||
}
|
||||
|
||||
void ByteVectorStream::truncate(long length)
|
||||
{
|
||||
d->data.resize(length);
|
||||
}
|
||||
|
||||
ByteVector *ByteVectorStream::data()
|
||||
{
|
||||
return &d->data;
|
||||
}
|
||||
145
3rdparty/taglib/toolkit/tbytevectorstream.h
vendored
Normal file
145
3rdparty/taglib/toolkit/tbytevectorstream.h
vendored
Normal file
@@ -0,0 +1,145 @@
|
||||
/***************************************************************************
|
||||
copyright : (C) 2011 by Lukas Lalinsky
|
||||
email : lalinsky@gmail.com
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* 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_BYTEVECTORSTREAM_H
|
||||
#define TAGLIB_BYTEVECTORSTREAM_H
|
||||
|
||||
#include "taglib_export.h"
|
||||
#include "taglib.h"
|
||||
#include "tbytevector.h"
|
||||
#include "tiostream.h"
|
||||
|
||||
namespace TagLib {
|
||||
|
||||
class String;
|
||||
class Tag;
|
||||
class AudioProperties;
|
||||
|
||||
//! In-memory Stream class using ByteVector for its storage.
|
||||
|
||||
class TAGLIB_EXPORT ByteVectorStream : public IOStream
|
||||
{
|
||||
public:
|
||||
/*!
|
||||
* Construct a File object and opens the \a file. \a file should be a
|
||||
* be a C-string in the local file system encoding.
|
||||
*/
|
||||
ByteVectorStream(const ByteVector &data);
|
||||
|
||||
/*!
|
||||
* Destroys this ByteVectorStream instance.
|
||||
*/
|
||||
virtual ~ByteVectorStream();
|
||||
|
||||
/*!
|
||||
* Returns the file name in the local file system encoding.
|
||||
*/
|
||||
FileName name() const;
|
||||
|
||||
/*!
|
||||
* Reads a block of size \a length at the current get pointer.
|
||||
*/
|
||||
ByteVector readBlock(unsigned long length);
|
||||
|
||||
/*!
|
||||
* Attempts to write the block \a data at the current get pointer. If the
|
||||
* file is currently only opened read only -- i.e. readOnly() returns true --
|
||||
* this attempts to reopen the file in read/write mode.
|
||||
*
|
||||
* \note This should be used instead of using the streaming output operator
|
||||
* for a ByteVector. And even this function is significantly slower than
|
||||
* doing output with a char[].
|
||||
*/
|
||||
void writeBlock(const ByteVector &data);
|
||||
|
||||
/*!
|
||||
* Insert \a data at position \a start in the file overwriting \a replace
|
||||
* bytes of the original content.
|
||||
*
|
||||
* \note This method is slow since it requires rewriting all of the file
|
||||
* after the insertion point.
|
||||
*/
|
||||
void insert(const ByteVector &data, unsigned long start = 0, unsigned long replace = 0);
|
||||
|
||||
/*!
|
||||
* Removes a block of the file starting a \a start and continuing for
|
||||
* \a length bytes.
|
||||
*
|
||||
* \note This method is slow since it involves rewriting all of the file
|
||||
* after the removed portion.
|
||||
*/
|
||||
void removeBlock(unsigned long start = 0, unsigned long length = 0);
|
||||
|
||||
/*!
|
||||
* Returns true if the file is read only (or if the file can not be opened).
|
||||
*/
|
||||
bool readOnly() const;
|
||||
|
||||
/*!
|
||||
* Since the file can currently only be opened as an argument to the
|
||||
* constructor (sort-of by design), this returns if that open succeeded.
|
||||
*/
|
||||
bool isOpen() const;
|
||||
|
||||
/*!
|
||||
* Move the I/O pointer to \a offset in the file from position \a p. This
|
||||
* defaults to seeking from the beginning of the file.
|
||||
*
|
||||
* \see Position
|
||||
*/
|
||||
void seek(long offset, Position p = Beginning);
|
||||
|
||||
/*!
|
||||
* Reset the end-of-file and error flags on the file.
|
||||
*/
|
||||
void clear();
|
||||
|
||||
/*!
|
||||
* Returns the current offset within the file.
|
||||
*/
|
||||
long tell() const;
|
||||
|
||||
/*!
|
||||
* Returns the length of the file.
|
||||
*/
|
||||
long length();
|
||||
|
||||
/*!
|
||||
* Truncates the file to a \a length.
|
||||
*/
|
||||
void truncate(long length);
|
||||
|
||||
ByteVector *data();
|
||||
|
||||
protected:
|
||||
|
||||
private:
|
||||
class ByteVectorStreamPrivate;
|
||||
ByteVectorStreamPrivate *d;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
64
3rdparty/taglib/toolkit/tdebug.cpp
vendored
Normal file
64
3rdparty/taglib/toolkit/tdebug.cpp
vendored
Normal file
@@ -0,0 +1,64 @@
|
||||
/***************************************************************************
|
||||
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/ *
|
||||
***************************************************************************/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#if !defined(NDEBUG) || defined(TRACE_IN_RELEASE)
|
||||
|
||||
#include "tdebug.h"
|
||||
#include "tstring.h"
|
||||
#include "tdebuglistener.h"
|
||||
#include "tutils.h"
|
||||
|
||||
#include <bitset>
|
||||
#include <cstdio>
|
||||
#include <cstdarg>
|
||||
|
||||
namespace TagLib
|
||||
{
|
||||
// The instance is defined in tdebuglistener.cpp.
|
||||
extern DebugListener *debugListener;
|
||||
|
||||
void debug(const String &s)
|
||||
{
|
||||
debugListener->printMessage("TagLib: " + s + "\n");
|
||||
}
|
||||
|
||||
void debugData(const ByteVector &v)
|
||||
{
|
||||
for(unsigned int i = 0; i < v.size(); ++i) {
|
||||
const std::string bits = std::bitset<8>(v[i]).to_string();
|
||||
const String msg = Utils::formatString(
|
||||
"*** [%u] - char '%c' - int %d, 0x%02x, 0b%s\n",
|
||||
i, v[i], v[i], v[i], bits.c_str());
|
||||
|
||||
debugListener->printMessage(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
70
3rdparty/taglib/toolkit/tdebug.h
vendored
Normal file
70
3rdparty/taglib/toolkit/tdebug.h
vendored
Normal file
@@ -0,0 +1,70 @@
|
||||
/***************************************************************************
|
||||
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_DEBUG_H
|
||||
#define TAGLIB_DEBUG_H
|
||||
|
||||
namespace TagLib {
|
||||
|
||||
class String;
|
||||
class ByteVector;
|
||||
|
||||
#ifndef DO_NOT_DOCUMENT
|
||||
#if !defined(NDEBUG) || defined(TRACE_IN_RELEASE)
|
||||
|
||||
/*!
|
||||
* A simple function that outputs the debug messages to the listener.
|
||||
* The default listener redirects the messages to \a stderr when NDEBUG is
|
||||
* not defined.
|
||||
*
|
||||
* \warning Do not use this outside of TagLib, it could lead to undefined
|
||||
* symbols in your build if TagLib is built with NDEBUG defined and your
|
||||
* application is not.
|
||||
*
|
||||
* \internal
|
||||
*/
|
||||
void debug(const String &s);
|
||||
|
||||
/*!
|
||||
* For debugging binary data.
|
||||
*
|
||||
* \warning Do not use this outside of TagLib, it could lead to undefined
|
||||
* symbols in your build if TagLib is built with NDEBUG defined and your
|
||||
* application is not.
|
||||
*
|
||||
* \internal
|
||||
*/
|
||||
void debugData(const ByteVector &v);
|
||||
|
||||
#else
|
||||
|
||||
#define debug(x) ((void)0)
|
||||
#define debugData(x) ((void)0)
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
85
3rdparty/taglib/toolkit/tdebuglistener.cpp
vendored
Normal file
85
3rdparty/taglib/toolkit/tdebuglistener.cpp
vendored
Normal file
@@ -0,0 +1,85 @@
|
||||
/***************************************************************************
|
||||
copyright : (C) 2013 by Tsuda Kageyu
|
||||
email : tsuda.kageyu@gmail.com
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* 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/ *
|
||||
***************************************************************************/
|
||||
|
||||
#include "tdebuglistener.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <bitset>
|
||||
|
||||
#ifdef _WIN32
|
||||
# include <windows.h>
|
||||
#endif
|
||||
|
||||
using namespace TagLib;
|
||||
|
||||
namespace
|
||||
{
|
||||
class DefaultListener : public DebugListener
|
||||
{
|
||||
public:
|
||||
virtual void printMessage(const String &msg)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
|
||||
const wstring wstr = msg.toWString();
|
||||
const int len = WideCharToMultiByte(CP_ACP, 0, wstr.c_str(), -1, NULL, 0, NULL, NULL);
|
||||
if(len != 0) {
|
||||
std::vector<char> buf(len);
|
||||
WideCharToMultiByte(CP_ACP, 0, wstr.c_str(), -1, &buf[0], len, NULL, NULL);
|
||||
|
||||
std::cerr << std::string(&buf[0]);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
std::cerr << msg;
|
||||
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
DefaultListener defaultListener;
|
||||
}
|
||||
|
||||
namespace TagLib
|
||||
{
|
||||
DebugListener *debugListener = &defaultListener;
|
||||
|
||||
DebugListener::DebugListener()
|
||||
{
|
||||
}
|
||||
|
||||
DebugListener::~DebugListener()
|
||||
{
|
||||
}
|
||||
|
||||
void setDebugListener(DebugListener *listener)
|
||||
{
|
||||
if(listener)
|
||||
debugListener = listener;
|
||||
else
|
||||
debugListener = &defaultListener;
|
||||
}
|
||||
}
|
||||
74
3rdparty/taglib/toolkit/tdebuglistener.h
vendored
Normal file
74
3rdparty/taglib/toolkit/tdebuglistener.h
vendored
Normal file
@@ -0,0 +1,74 @@
|
||||
/***************************************************************************
|
||||
copyright : (C) 2013 by Tsuda Kageyu
|
||||
email : tsuda.kageyu@gmail.com
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* 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_DEBUGLISTENER_H
|
||||
#define TAGLIB_DEBUGLISTENER_H
|
||||
|
||||
#include "taglib_export.h"
|
||||
#include "tstring.h"
|
||||
|
||||
namespace TagLib
|
||||
{
|
||||
//! An abstraction for the listener to the debug messages.
|
||||
|
||||
/*!
|
||||
* This class enables you to handle the debug messages in your preferred
|
||||
* way by subclassing this class, reimplementing printMessage() and setting
|
||||
* your reimplementation as the default with setDebugListener().
|
||||
*
|
||||
* \see setDebugListener()
|
||||
*/
|
||||
class TAGLIB_EXPORT DebugListener
|
||||
{
|
||||
public:
|
||||
DebugListener();
|
||||
virtual ~DebugListener();
|
||||
|
||||
/*!
|
||||
* When overridden in a derived class, redirects \a msg to your preferred
|
||||
* channel such as stderr, Windows debugger or so forth.
|
||||
*/
|
||||
virtual void printMessage(const String &msg) = 0;
|
||||
|
||||
private:
|
||||
// Noncopyable
|
||||
DebugListener(const DebugListener &);
|
||||
DebugListener &operator=(const DebugListener &);
|
||||
};
|
||||
|
||||
/*!
|
||||
* Sets the listener that decides how the debug messages are redirected.
|
||||
* If the parameter \a listener is null, the previous listener is released
|
||||
* and default stderr listener is restored.
|
||||
*
|
||||
* \note The caller is responsible for deleting the previous listener
|
||||
* as needed after it is released.
|
||||
*
|
||||
* \see DebugListener
|
||||
*/
|
||||
TAGLIB_EXPORT void setDebugListener(DebugListener *listener);
|
||||
}
|
||||
|
||||
#endif
|
||||
499
3rdparty/taglib/toolkit/tfile.cpp
vendored
Normal file
499
3rdparty/taglib/toolkit/tfile.cpp
vendored
Normal file
@@ -0,0 +1,499 @@
|
||||
/***************************************************************************
|
||||
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/ *
|
||||
***************************************************************************/
|
||||
|
||||
#include "tfile.h"
|
||||
#include "tfilestream.h"
|
||||
#include "tstring.h"
|
||||
#include "tdebug.h"
|
||||
#include "tpropertymap.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
# include <windows.h>
|
||||
# include <io.h>
|
||||
#else
|
||||
# include <stdio.h>
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
|
||||
#ifndef R_OK
|
||||
# define R_OK 4
|
||||
#endif
|
||||
#ifndef W_OK
|
||||
# define W_OK 2
|
||||
#endif
|
||||
|
||||
#include "asffile.h"
|
||||
#include "mpegfile.h"
|
||||
#include "vorbisfile.h"
|
||||
#include "flacfile.h"
|
||||
#include "oggflacfile.h"
|
||||
#include "mpcfile.h"
|
||||
#include "mp4file.h"
|
||||
#include "wavpackfile.h"
|
||||
#include "speexfile.h"
|
||||
#include "opusfile.h"
|
||||
#include "trueaudiofile.h"
|
||||
#include "aifffile.h"
|
||||
#include "wavfile.h"
|
||||
#include "apefile.h"
|
||||
#include "modfile.h"
|
||||
#include "s3mfile.h"
|
||||
#include "itfile.h"
|
||||
#include "xmfile.h"
|
||||
#include "mp4file.h"
|
||||
|
||||
using namespace TagLib;
|
||||
|
||||
class File::FilePrivate
|
||||
{
|
||||
public:
|
||||
FilePrivate(IOStream *stream, bool owner) :
|
||||
stream(stream),
|
||||
streamOwner(owner),
|
||||
valid(true) {}
|
||||
|
||||
~FilePrivate()
|
||||
{
|
||||
if(streamOwner)
|
||||
delete stream;
|
||||
}
|
||||
|
||||
IOStream *stream;
|
||||
bool streamOwner;
|
||||
bool valid;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// public members
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
File::File(FileName fileName) :
|
||||
d(new FilePrivate(new FileStream(fileName), true))
|
||||
{
|
||||
}
|
||||
|
||||
File::File(IOStream *stream) :
|
||||
d(new FilePrivate(stream, false))
|
||||
{
|
||||
}
|
||||
|
||||
File::~File()
|
||||
{
|
||||
delete d;
|
||||
}
|
||||
|
||||
FileName File::name() const
|
||||
{
|
||||
return d->stream->name();
|
||||
}
|
||||
|
||||
PropertyMap File::properties() const
|
||||
{
|
||||
// ugly workaround until this method is virtual
|
||||
if(dynamic_cast<const APE::File* >(this))
|
||||
return dynamic_cast<const APE::File* >(this)->properties();
|
||||
if(dynamic_cast<const FLAC::File* >(this))
|
||||
return dynamic_cast<const FLAC::File* >(this)->properties();
|
||||
if(dynamic_cast<const IT::File* >(this))
|
||||
return dynamic_cast<const IT::File* >(this)->properties();
|
||||
if(dynamic_cast<const Mod::File* >(this))
|
||||
return dynamic_cast<const Mod::File* >(this)->properties();
|
||||
if(dynamic_cast<const MPC::File* >(this))
|
||||
return dynamic_cast<const MPC::File* >(this)->properties();
|
||||
if(dynamic_cast<const MPEG::File* >(this))
|
||||
return dynamic_cast<const MPEG::File* >(this)->properties();
|
||||
if(dynamic_cast<const Ogg::FLAC::File* >(this))
|
||||
return dynamic_cast<const Ogg::FLAC::File* >(this)->properties();
|
||||
if(dynamic_cast<const Ogg::Speex::File* >(this))
|
||||
return dynamic_cast<const Ogg::Speex::File* >(this)->properties();
|
||||
if(dynamic_cast<const Ogg::Opus::File* >(this))
|
||||
return dynamic_cast<const Ogg::Opus::File* >(this)->properties();
|
||||
if(dynamic_cast<const Ogg::Vorbis::File* >(this))
|
||||
return dynamic_cast<const Ogg::Vorbis::File* >(this)->properties();
|
||||
if(dynamic_cast<const RIFF::AIFF::File* >(this))
|
||||
return dynamic_cast<const RIFF::AIFF::File* >(this)->properties();
|
||||
if(dynamic_cast<const RIFF::WAV::File* >(this))
|
||||
return dynamic_cast<const RIFF::WAV::File* >(this)->properties();
|
||||
if(dynamic_cast<const S3M::File* >(this))
|
||||
return dynamic_cast<const S3M::File* >(this)->properties();
|
||||
if(dynamic_cast<const TrueAudio::File* >(this))
|
||||
return dynamic_cast<const TrueAudio::File* >(this)->properties();
|
||||
if(dynamic_cast<const WavPack::File* >(this))
|
||||
return dynamic_cast<const WavPack::File* >(this)->properties();
|
||||
if(dynamic_cast<const XM::File* >(this))
|
||||
return dynamic_cast<const XM::File* >(this)->properties();
|
||||
if(dynamic_cast<const MP4::File* >(this))
|
||||
return dynamic_cast<const MP4::File* >(this)->properties();
|
||||
if(dynamic_cast<const ASF::File* >(this))
|
||||
return dynamic_cast<const ASF::File* >(this)->properties();
|
||||
return tag()->properties();
|
||||
}
|
||||
|
||||
void File::removeUnsupportedProperties(const StringList &properties)
|
||||
{
|
||||
// here we only consider those formats that could possibly contain
|
||||
// unsupported properties
|
||||
if(dynamic_cast<APE::File* >(this))
|
||||
dynamic_cast<APE::File* >(this)->removeUnsupportedProperties(properties);
|
||||
else if(dynamic_cast<FLAC::File* >(this))
|
||||
dynamic_cast<FLAC::File* >(this)->removeUnsupportedProperties(properties);
|
||||
else if(dynamic_cast<MPC::File* >(this))
|
||||
dynamic_cast<MPC::File* >(this)->removeUnsupportedProperties(properties);
|
||||
else if(dynamic_cast<MPEG::File* >(this))
|
||||
dynamic_cast<MPEG::File* >(this)->removeUnsupportedProperties(properties);
|
||||
else if(dynamic_cast<Ogg::Vorbis::File* >(this))
|
||||
dynamic_cast<Ogg::Vorbis::File* >(this)->removeUnsupportedProperties(properties);
|
||||
else if(dynamic_cast<RIFF::AIFF::File* >(this))
|
||||
dynamic_cast<RIFF::AIFF::File* >(this)->removeUnsupportedProperties(properties);
|
||||
else if(dynamic_cast<RIFF::WAV::File* >(this))
|
||||
dynamic_cast<RIFF::WAV::File* >(this)->removeUnsupportedProperties(properties);
|
||||
else if(dynamic_cast<TrueAudio::File* >(this))
|
||||
dynamic_cast<TrueAudio::File* >(this)->removeUnsupportedProperties(properties);
|
||||
else if(dynamic_cast<WavPack::File* >(this))
|
||||
dynamic_cast<WavPack::File* >(this)->removeUnsupportedProperties(properties);
|
||||
else if(dynamic_cast<MP4::File* >(this))
|
||||
dynamic_cast<MP4::File* >(this)->removeUnsupportedProperties(properties);
|
||||
else if(dynamic_cast<ASF::File* >(this))
|
||||
dynamic_cast<ASF::File* >(this)->removeUnsupportedProperties(properties);
|
||||
else
|
||||
tag()->removeUnsupportedProperties(properties);
|
||||
}
|
||||
|
||||
PropertyMap File::setProperties(const PropertyMap &properties)
|
||||
{
|
||||
if(dynamic_cast<APE::File* >(this))
|
||||
return dynamic_cast<APE::File* >(this)->setProperties(properties);
|
||||
else if(dynamic_cast<FLAC::File* >(this))
|
||||
return dynamic_cast<FLAC::File* >(this)->setProperties(properties);
|
||||
else if(dynamic_cast<IT::File* >(this))
|
||||
return dynamic_cast<IT::File* >(this)->setProperties(properties);
|
||||
else if(dynamic_cast<Mod::File* >(this))
|
||||
return dynamic_cast<Mod::File* >(this)->setProperties(properties);
|
||||
else if(dynamic_cast<MPC::File* >(this))
|
||||
return dynamic_cast<MPC::File* >(this)->setProperties(properties);
|
||||
else if(dynamic_cast<MPEG::File* >(this))
|
||||
return dynamic_cast<MPEG::File* >(this)->setProperties(properties);
|
||||
else if(dynamic_cast<Ogg::FLAC::File* >(this))
|
||||
return dynamic_cast<Ogg::FLAC::File* >(this)->setProperties(properties);
|
||||
else if(dynamic_cast<Ogg::Speex::File* >(this))
|
||||
return dynamic_cast<Ogg::Speex::File* >(this)->setProperties(properties);
|
||||
else if(dynamic_cast<Ogg::Opus::File* >(this))
|
||||
return dynamic_cast<Ogg::Opus::File* >(this)->setProperties(properties);
|
||||
else if(dynamic_cast<Ogg::Vorbis::File* >(this))
|
||||
return dynamic_cast<Ogg::Vorbis::File* >(this)->setProperties(properties);
|
||||
else if(dynamic_cast<RIFF::AIFF::File* >(this))
|
||||
return dynamic_cast<RIFF::AIFF::File* >(this)->setProperties(properties);
|
||||
else if(dynamic_cast<RIFF::WAV::File* >(this))
|
||||
return dynamic_cast<RIFF::WAV::File* >(this)->setProperties(properties);
|
||||
else if(dynamic_cast<S3M::File* >(this))
|
||||
return dynamic_cast<S3M::File* >(this)->setProperties(properties);
|
||||
else if(dynamic_cast<TrueAudio::File* >(this))
|
||||
return dynamic_cast<TrueAudio::File* >(this)->setProperties(properties);
|
||||
else if(dynamic_cast<WavPack::File* >(this))
|
||||
return dynamic_cast<WavPack::File* >(this)->setProperties(properties);
|
||||
else if(dynamic_cast<XM::File* >(this))
|
||||
return dynamic_cast<XM::File* >(this)->setProperties(properties);
|
||||
else if(dynamic_cast<MP4::File* >(this))
|
||||
return dynamic_cast<MP4::File* >(this)->setProperties(properties);
|
||||
else if(dynamic_cast<ASF::File* >(this))
|
||||
return dynamic_cast<ASF::File* >(this)->setProperties(properties);
|
||||
else
|
||||
return tag()->setProperties(properties);
|
||||
}
|
||||
|
||||
ByteVector File::readBlock(unsigned long length)
|
||||
{
|
||||
return d->stream->readBlock(length);
|
||||
}
|
||||
|
||||
void File::writeBlock(const ByteVector &data)
|
||||
{
|
||||
d->stream->writeBlock(data);
|
||||
}
|
||||
|
||||
long File::find(const ByteVector &pattern, long fromOffset, const ByteVector &before)
|
||||
{
|
||||
if(!d->stream || pattern.size() > bufferSize())
|
||||
return -1;
|
||||
|
||||
// The position in the file that the current buffer starts at.
|
||||
|
||||
long bufferOffset = fromOffset;
|
||||
ByteVector buffer;
|
||||
|
||||
// These variables are used to keep track of a partial match that happens at
|
||||
// the end of a buffer.
|
||||
|
||||
int previousPartialMatch = -1;
|
||||
int beforePreviousPartialMatch = -1;
|
||||
|
||||
// Save the location of the current read pointer. We will restore the
|
||||
// position using seek() before all returns.
|
||||
|
||||
long originalPosition = tell();
|
||||
|
||||
// Start the search at the offset.
|
||||
|
||||
seek(fromOffset);
|
||||
|
||||
// This loop is the crux of the find method. There are three cases that we
|
||||
// want to account for:
|
||||
//
|
||||
// (1) The previously searched buffer contained a partial match of the search
|
||||
// pattern and we want to see if the next one starts with the remainder of
|
||||
// that pattern.
|
||||
//
|
||||
// (2) The search pattern is wholly contained within the current buffer.
|
||||
//
|
||||
// (3) The current buffer ends with a partial match of the pattern. We will
|
||||
// note this for use in the next iteration, where we will check for the rest
|
||||
// of the pattern.
|
||||
//
|
||||
// All three of these are done in two steps. First we check for the pattern
|
||||
// and do things appropriately if a match (or partial match) is found. We
|
||||
// then check for "before". The order is important because it gives priority
|
||||
// to "real" matches.
|
||||
|
||||
for(buffer = readBlock(bufferSize()); buffer.size() > 0; buffer = readBlock(bufferSize())) {
|
||||
|
||||
// (1) previous partial match
|
||||
|
||||
if(previousPartialMatch >= 0 && int(bufferSize()) > previousPartialMatch) {
|
||||
const int patternOffset = (bufferSize() - previousPartialMatch);
|
||||
if(buffer.containsAt(pattern, 0, patternOffset)) {
|
||||
seek(originalPosition);
|
||||
return bufferOffset - bufferSize() + previousPartialMatch;
|
||||
}
|
||||
}
|
||||
|
||||
if(!before.isEmpty() && beforePreviousPartialMatch >= 0 && int(bufferSize()) > beforePreviousPartialMatch) {
|
||||
const int beforeOffset = (bufferSize() - beforePreviousPartialMatch);
|
||||
if(buffer.containsAt(before, 0, beforeOffset)) {
|
||||
seek(originalPosition);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
// (2) pattern contained in current buffer
|
||||
|
||||
long location = buffer.find(pattern);
|
||||
if(location >= 0) {
|
||||
seek(originalPosition);
|
||||
return bufferOffset + location;
|
||||
}
|
||||
|
||||
if(!before.isEmpty() && buffer.find(before) >= 0) {
|
||||
seek(originalPosition);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// (3) partial match
|
||||
|
||||
previousPartialMatch = buffer.endsWithPartialMatch(pattern);
|
||||
|
||||
if(!before.isEmpty())
|
||||
beforePreviousPartialMatch = buffer.endsWithPartialMatch(before);
|
||||
|
||||
bufferOffset += bufferSize();
|
||||
}
|
||||
|
||||
// Since we hit the end of the file, reset the status before continuing.
|
||||
|
||||
clear();
|
||||
|
||||
seek(originalPosition);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
long File::rfind(const ByteVector &pattern, long fromOffset, const ByteVector &before)
|
||||
{
|
||||
if(!d->stream || pattern.size() > bufferSize())
|
||||
return -1;
|
||||
|
||||
// The position in the file that the current buffer starts at.
|
||||
|
||||
ByteVector buffer;
|
||||
|
||||
// These variables are used to keep track of a partial match that happens at
|
||||
// the end of a buffer.
|
||||
|
||||
/*
|
||||
int previousPartialMatch = -1;
|
||||
int beforePreviousPartialMatch = -1;
|
||||
*/
|
||||
|
||||
// Save the location of the current read pointer. We will restore the
|
||||
// position using seek() before all returns.
|
||||
|
||||
long originalPosition = tell();
|
||||
|
||||
// Start the search at the offset.
|
||||
|
||||
if(fromOffset == 0)
|
||||
fromOffset = length();
|
||||
|
||||
long bufferLength = bufferSize();
|
||||
long bufferOffset = fromOffset + pattern.size();
|
||||
|
||||
// See the notes in find() for an explanation of this algorithm.
|
||||
|
||||
while(true) {
|
||||
|
||||
if(bufferOffset > bufferLength) {
|
||||
bufferOffset -= bufferLength;
|
||||
}
|
||||
else {
|
||||
bufferLength = bufferOffset;
|
||||
bufferOffset = 0;
|
||||
}
|
||||
seek(bufferOffset);
|
||||
|
||||
buffer = readBlock(bufferLength);
|
||||
if(buffer.isEmpty())
|
||||
break;
|
||||
|
||||
// TODO: (1) previous partial match
|
||||
|
||||
// (2) pattern contained in current buffer
|
||||
|
||||
const long location = buffer.rfind(pattern);
|
||||
if(location >= 0) {
|
||||
seek(originalPosition);
|
||||
return bufferOffset + location;
|
||||
}
|
||||
|
||||
if(!before.isEmpty() && buffer.find(before) >= 0) {
|
||||
seek(originalPosition);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// TODO: (3) partial match
|
||||
}
|
||||
|
||||
// Since we hit the end of the file, reset the status before continuing.
|
||||
|
||||
clear();
|
||||
|
||||
seek(originalPosition);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
void File::insert(const ByteVector &data, unsigned long start, unsigned long replace)
|
||||
{
|
||||
d->stream->insert(data, start, replace);
|
||||
}
|
||||
|
||||
void File::removeBlock(unsigned long start, unsigned long length)
|
||||
{
|
||||
d->stream->removeBlock(start, length);
|
||||
}
|
||||
|
||||
bool File::readOnly() const
|
||||
{
|
||||
return d->stream->readOnly();
|
||||
}
|
||||
|
||||
bool File::isOpen() const
|
||||
{
|
||||
return d->stream->isOpen();
|
||||
}
|
||||
|
||||
bool File::isValid() const
|
||||
{
|
||||
return isOpen() && d->valid;
|
||||
}
|
||||
|
||||
void File::seek(long offset, Position p)
|
||||
{
|
||||
d->stream->seek(offset, IOStream::Position(p));
|
||||
}
|
||||
|
||||
void File::truncate(long length)
|
||||
{
|
||||
d->stream->truncate(length);
|
||||
}
|
||||
|
||||
void File::clear()
|
||||
{
|
||||
d->stream->clear();
|
||||
}
|
||||
|
||||
long File::tell() const
|
||||
{
|
||||
return d->stream->tell();
|
||||
}
|
||||
|
||||
long File::length()
|
||||
{
|
||||
return d->stream->length();
|
||||
}
|
||||
|
||||
bool File::isReadable(const char *file)
|
||||
{
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1400) // VC++2005 or later
|
||||
|
||||
return _access_s(file, R_OK) == 0;
|
||||
|
||||
#else
|
||||
|
||||
return access(file, R_OK) == 0;
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
bool File::isWritable(const char *file)
|
||||
{
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1400) // VC++2005 or later
|
||||
|
||||
return _access_s(file, W_OK) == 0;
|
||||
|
||||
#else
|
||||
|
||||
return access(file, W_OK) == 0;
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// protected members
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
unsigned int File::bufferSize()
|
||||
{
|
||||
return 1024;
|
||||
}
|
||||
|
||||
void File::setValid(bool valid)
|
||||
{
|
||||
d->valid = valid;
|
||||
}
|
||||
|
||||
306
3rdparty/taglib/toolkit/tfile.h
vendored
Normal file
306
3rdparty/taglib/toolkit/tfile.h
vendored
Normal file
@@ -0,0 +1,306 @@
|
||||
/***************************************************************************
|
||||
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_FILE_H
|
||||
#define TAGLIB_FILE_H
|
||||
|
||||
#include "taglib_export.h"
|
||||
#include "taglib.h"
|
||||
#include "tag.h"
|
||||
#include "tbytevector.h"
|
||||
#include "tiostream.h"
|
||||
|
||||
namespace TagLib {
|
||||
|
||||
class String;
|
||||
class Tag;
|
||||
class AudioProperties;
|
||||
class PropertyMap;
|
||||
|
||||
//! A file class with some useful methods for tag manipulation
|
||||
|
||||
/*!
|
||||
* This class is a basic file class with some methods that are particularly
|
||||
* useful for tag editors. It has methods to take advantage of
|
||||
* ByteVector and a binary search method for finding patterns in a file.
|
||||
*/
|
||||
|
||||
class TAGLIB_EXPORT File
|
||||
{
|
||||
public:
|
||||
/*!
|
||||
* Position in the file used for seeking.
|
||||
*/
|
||||
enum Position {
|
||||
//! Seek from the beginning of the file.
|
||||
Beginning,
|
||||
//! Seek from the current position in the file.
|
||||
Current,
|
||||
//! Seek from the end of the file.
|
||||
End
|
||||
};
|
||||
|
||||
/*!
|
||||
* Destroys this File instance.
|
||||
*/
|
||||
virtual ~File();
|
||||
|
||||
/*!
|
||||
* Returns the file name in the local file system encoding.
|
||||
*/
|
||||
FileName name() const;
|
||||
|
||||
/*!
|
||||
* Returns a pointer to this file's tag. This should be reimplemented in
|
||||
* the concrete subclasses.
|
||||
*/
|
||||
virtual Tag *tag() const = 0;
|
||||
|
||||
/*!
|
||||
* Exports the tags of the file as dictionary mapping (human readable) tag
|
||||
* names (uppercase Strings) to StringLists of tag values. Calls the according
|
||||
* specialization in the File subclasses.
|
||||
* For each metadata object of the file that could not be parsed into the PropertyMap
|
||||
* format, the returned map's unsupportedData() list will contain one entry identifying
|
||||
* that object (e.g. the frame type for ID3v2 tags). Use removeUnsupportedProperties()
|
||||
* to remove (a subset of) them.
|
||||
* For files that contain more than one tag (e.g. an MP3 with both an ID3v1 and an ID3v2
|
||||
* tag) only the most "modern" one will be exported (ID3v2 in this case).
|
||||
* BIC: Will be made virtual in future releases.
|
||||
*/
|
||||
PropertyMap properties() const;
|
||||
|
||||
/*!
|
||||
* Removes unsupported properties, or a subset of them, from the file's metadata.
|
||||
* The parameter \a properties must contain only entries from
|
||||
* properties().unsupportedData().
|
||||
* BIC: Will be mad virtual in future releases.
|
||||
*/
|
||||
void removeUnsupportedProperties(const StringList& properties);
|
||||
|
||||
/*!
|
||||
* Sets the tags of this File to those specified in \a properties. Calls the
|
||||
* according specialization method in the subclasses of File to do the translation
|
||||
* into the format-specific details.
|
||||
* If some value(s) could not be written imported to the specific metadata format,
|
||||
* the returned PropertyMap will contain those value(s). Otherwise it will be empty,
|
||||
* indicating that no problems occurred.
|
||||
* With file types that support several tag formats (for instance, MP3 files can have
|
||||
* ID3v1, ID3v2, and APEv2 tags), this function will create the most appropriate one
|
||||
* (ID3v2 for MP3 files). Older formats will be updated as well, if they exist, but won't
|
||||
* be taken into account for the return value of this function.
|
||||
* See the documentation of the subclass implementations for detailed descriptions.
|
||||
* BIC: will become pure virtual in the future
|
||||
*/
|
||||
PropertyMap setProperties(const PropertyMap &properties);
|
||||
|
||||
/*!
|
||||
* Returns a pointer to this file's audio properties. This should be
|
||||
* reimplemented in the concrete subclasses. If no audio properties were
|
||||
* read then this will return a null pointer.
|
||||
*/
|
||||
virtual AudioProperties *audioProperties() const = 0;
|
||||
|
||||
/*!
|
||||
* Save the file and its associated tags. This should be reimplemented in
|
||||
* the concrete subclasses. Returns true if the save succeeds.
|
||||
*
|
||||
* \warning On UNIX multiple processes are able to write to the same file at
|
||||
* the same time. This can result in serious file corruption. If you are
|
||||
* developing a program that makes use of TagLib from multiple processes you
|
||||
* must insure that you are only doing writes to a particular file from one
|
||||
* of them.
|
||||
*/
|
||||
virtual bool save() = 0;
|
||||
|
||||
/*!
|
||||
* Reads a block of size \a length at the current get pointer.
|
||||
*/
|
||||
ByteVector readBlock(unsigned long length);
|
||||
|
||||
/*!
|
||||
* Attempts to write the block \a data at the current get pointer. If the
|
||||
* file is currently only opened read only -- i.e. readOnly() returns true --
|
||||
* this attempts to reopen the file in read/write mode.
|
||||
*
|
||||
* \note This should be used instead of using the streaming output operator
|
||||
* for a ByteVector. And even this function is significantly slower than
|
||||
* doing output with a char[].
|
||||
*/
|
||||
void writeBlock(const ByteVector &data);
|
||||
|
||||
/*!
|
||||
* Returns the offset in the file that \a pattern occurs at or -1 if it can
|
||||
* not be found. If \a before is set, the search will only continue until the
|
||||
* pattern \a before is found. This is useful for tagging purposes to search
|
||||
* for a tag before the sync frame.
|
||||
*
|
||||
* Searching starts at \a fromOffset, which defaults to the beginning of the
|
||||
* file.
|
||||
*
|
||||
* \note This has the practical limitation that \a pattern can not be longer
|
||||
* than the buffer size used by readBlock(). Currently this is 1024 bytes.
|
||||
*/
|
||||
long find(const ByteVector &pattern,
|
||||
long fromOffset = 0,
|
||||
const ByteVector &before = ByteVector());
|
||||
|
||||
/*!
|
||||
* Returns the offset in the file that \a pattern occurs at or -1 if it can
|
||||
* not be found. If \a before is set, the search will only continue until the
|
||||
* pattern \a before is found. This is useful for tagging purposes to search
|
||||
* for a tag before the sync frame.
|
||||
*
|
||||
* Searching starts at \a fromOffset and proceeds from the that point to the
|
||||
* beginning of the file and defaults to the end of the file.
|
||||
*
|
||||
* \note This has the practical limitation that \a pattern can not be longer
|
||||
* than the buffer size used by readBlock(). Currently this is 1024 bytes.
|
||||
*/
|
||||
long rfind(const ByteVector &pattern,
|
||||
long fromOffset = 0,
|
||||
const ByteVector &before = ByteVector());
|
||||
|
||||
/*!
|
||||
* Insert \a data at position \a start in the file overwriting \a replace
|
||||
* bytes of the original content.
|
||||
*
|
||||
* \note This method is slow since it requires rewriting all of the file
|
||||
* after the insertion point.
|
||||
*/
|
||||
void insert(const ByteVector &data, unsigned long start = 0, unsigned long replace = 0);
|
||||
|
||||
/*!
|
||||
* Removes a block of the file starting a \a start and continuing for
|
||||
* \a length bytes.
|
||||
*
|
||||
* \note This method is slow since it involves rewriting all of the file
|
||||
* after the removed portion.
|
||||
*/
|
||||
void removeBlock(unsigned long start = 0, unsigned long length = 0);
|
||||
|
||||
/*!
|
||||
* Returns true if the file is read only (or if the file can not be opened).
|
||||
*/
|
||||
bool readOnly() const;
|
||||
|
||||
/*!
|
||||
* Since the file can currently only be opened as an argument to the
|
||||
* constructor (sort-of by design), this returns if that open succeeded.
|
||||
*/
|
||||
bool isOpen() const;
|
||||
|
||||
/*!
|
||||
* Returns true if the file is open and readable.
|
||||
*/
|
||||
bool isValid() const;
|
||||
|
||||
/*!
|
||||
* Move the I/O pointer to \a offset in the file from position \a p. This
|
||||
* defaults to seeking from the beginning of the file.
|
||||
*
|
||||
* \see Position
|
||||
*/
|
||||
void seek(long offset, Position p = Beginning);
|
||||
|
||||
/*!
|
||||
* Reset the end-of-file and error flags on the file.
|
||||
*/
|
||||
void clear();
|
||||
|
||||
/*!
|
||||
* Returns the current offset within the file.
|
||||
*/
|
||||
long tell() const;
|
||||
|
||||
/*!
|
||||
* Returns the length of the file.
|
||||
*/
|
||||
long length();
|
||||
|
||||
/*!
|
||||
* Returns true if \a file can be opened for reading. If the file does not
|
||||
* exist, this will return false.
|
||||
*
|
||||
* \deprecated
|
||||
*/
|
||||
static bool isReadable(const char *file);
|
||||
|
||||
/*!
|
||||
* Returns true if \a file can be opened for writing.
|
||||
*
|
||||
* \deprecated
|
||||
*/
|
||||
static bool isWritable(const char *name);
|
||||
|
||||
protected:
|
||||
/*!
|
||||
* Construct a File object and opens the \a file. \a file should be a
|
||||
* be a C-string in the local file system encoding.
|
||||
*
|
||||
* \note Constructor is protected since this class should only be
|
||||
* instantiated through subclasses.
|
||||
*/
|
||||
File(FileName file);
|
||||
|
||||
/*!
|
||||
* Construct a File object and use the \a stream instance.
|
||||
*
|
||||
* \note TagLib will *not* take ownership of the stream, the caller is
|
||||
* responsible for deleting it after the File object.
|
||||
*
|
||||
* \note Constructor is protected since this class should only be
|
||||
* instantiated through subclasses.
|
||||
*/
|
||||
File(IOStream *stream);
|
||||
|
||||
/*!
|
||||
* Marks the file as valid or invalid.
|
||||
*
|
||||
* \see isValid()
|
||||
*/
|
||||
void setValid(bool valid);
|
||||
|
||||
/*!
|
||||
* Truncates the file to a \a length.
|
||||
*/
|
||||
void truncate(long length);
|
||||
|
||||
/*!
|
||||
* Returns the buffer size that is used for internal buffering.
|
||||
*/
|
||||
static unsigned int bufferSize();
|
||||
|
||||
private:
|
||||
File(const File &);
|
||||
File &operator=(const File &);
|
||||
|
||||
class FilePrivate;
|
||||
FilePrivate *d;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
483
3rdparty/taglib/toolkit/tfilestream.cpp
vendored
Normal file
483
3rdparty/taglib/toolkit/tfilestream.cpp
vendored
Normal file
@@ -0,0 +1,483 @@
|
||||
/***************************************************************************
|
||||
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/ *
|
||||
***************************************************************************/
|
||||
|
||||
#include "tfilestream.h"
|
||||
#include "tstring.h"
|
||||
#include "tdebug.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
# include <windows.h>
|
||||
#else
|
||||
# include <stdio.h>
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
|
||||
using namespace TagLib;
|
||||
|
||||
namespace
|
||||
{
|
||||
#ifdef _WIN32
|
||||
|
||||
// Uses Win32 native API instead of POSIX API to reduce the resource consumption.
|
||||
|
||||
typedef FileName FileNameHandle;
|
||||
typedef HANDLE FileHandle;
|
||||
|
||||
const FileHandle InvalidFileHandle = INVALID_HANDLE_VALUE;
|
||||
|
||||
FileHandle openFile(const FileName &path, bool readOnly)
|
||||
{
|
||||
const DWORD access = readOnly ? GENERIC_READ : (GENERIC_READ | GENERIC_WRITE);
|
||||
|
||||
#if defined (PLATFORM_WINRT)
|
||||
return CreateFile2(path.wstr().c_str(), access, FILE_SHARE_READ, OPEN_EXISTING, NULL);
|
||||
#else
|
||||
return CreateFileW(path.wstr().c_str(), access, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
void closeFile(FileHandle file)
|
||||
{
|
||||
CloseHandle(file);
|
||||
}
|
||||
|
||||
size_t readFile(FileHandle file, ByteVector &buffer)
|
||||
{
|
||||
DWORD length;
|
||||
if(ReadFile(file, buffer.data(), static_cast<DWORD>(buffer.size()), &length, NULL))
|
||||
return static_cast<size_t>(length);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t writeFile(FileHandle file, const ByteVector &buffer)
|
||||
{
|
||||
DWORD length;
|
||||
if(WriteFile(file, buffer.data(), static_cast<DWORD>(buffer.size()), &length, NULL))
|
||||
return static_cast<size_t>(length);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else // _WIN32
|
||||
|
||||
struct FileNameHandle : public std::string
|
||||
{
|
||||
FileNameHandle(FileName name) : std::string(name) {}
|
||||
operator FileName () const { return c_str(); }
|
||||
};
|
||||
|
||||
typedef FILE* FileHandle;
|
||||
|
||||
const FileHandle InvalidFileHandle = 0;
|
||||
|
||||
FileHandle openFile(const FileName &path, bool readOnly)
|
||||
{
|
||||
return fopen(path, readOnly ? "rb" : "rb+");
|
||||
}
|
||||
|
||||
void closeFile(FileHandle file)
|
||||
{
|
||||
fclose(file);
|
||||
}
|
||||
|
||||
size_t readFile(FileHandle file, ByteVector &buffer)
|
||||
{
|
||||
return fread(buffer.data(), sizeof(char), buffer.size(), file);
|
||||
}
|
||||
|
||||
size_t writeFile(FileHandle file, const ByteVector &buffer)
|
||||
{
|
||||
return fwrite(buffer.data(), sizeof(char), buffer.size(), file);
|
||||
}
|
||||
|
||||
#endif // _WIN32
|
||||
}
|
||||
|
||||
class FileStream::FileStreamPrivate
|
||||
{
|
||||
public:
|
||||
FileStreamPrivate(const FileName &fileName)
|
||||
: file(InvalidFileHandle)
|
||||
, name(fileName)
|
||||
, readOnly(true)
|
||||
{
|
||||
}
|
||||
|
||||
FileHandle file;
|
||||
FileNameHandle name;
|
||||
bool readOnly;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// public members
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
FileStream::FileStream(FileName fileName, bool openReadOnly)
|
||||
: d(new FileStreamPrivate(fileName))
|
||||
{
|
||||
// First try with read / write mode, if that fails, fall back to read only.
|
||||
|
||||
if(!openReadOnly)
|
||||
d->file = openFile(fileName, false);
|
||||
|
||||
if(d->file != InvalidFileHandle)
|
||||
d->readOnly = false;
|
||||
else
|
||||
d->file = openFile(fileName, true);
|
||||
|
||||
if(d->file == InvalidFileHandle)
|
||||
{
|
||||
# ifdef _WIN32
|
||||
debug("Could not open file " + fileName.toString());
|
||||
# else
|
||||
debug("Could not open file " + String(static_cast<const char *>(d->name)));
|
||||
# endif
|
||||
}
|
||||
}
|
||||
|
||||
FileStream::~FileStream()
|
||||
{
|
||||
if(isOpen())
|
||||
closeFile(d->file);
|
||||
|
||||
delete d;
|
||||
}
|
||||
|
||||
FileName FileStream::name() const
|
||||
{
|
||||
return d->name;
|
||||
}
|
||||
|
||||
ByteVector FileStream::readBlock(unsigned long length)
|
||||
{
|
||||
if(!isOpen()) {
|
||||
debug("FileStream::readBlock() -- invalid file.");
|
||||
return ByteVector();
|
||||
}
|
||||
|
||||
if(length == 0)
|
||||
return ByteVector();
|
||||
|
||||
const unsigned long streamLength = static_cast<unsigned long>(FileStream::length());
|
||||
if(length > bufferSize() && length > streamLength)
|
||||
length = streamLength;
|
||||
|
||||
ByteVector buffer(static_cast<unsigned int>(length));
|
||||
|
||||
const size_t count = readFile(d->file, buffer);
|
||||
buffer.resize(static_cast<unsigned int>(count));
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
void FileStream::writeBlock(const ByteVector &data)
|
||||
{
|
||||
if(!isOpen()) {
|
||||
debug("FileStream::writeBlock() -- invalid file.");
|
||||
return;
|
||||
}
|
||||
|
||||
if(readOnly()) {
|
||||
debug("FileStream::writeBlock() -- read only file.");
|
||||
return;
|
||||
}
|
||||
|
||||
writeFile(d->file, data);
|
||||
}
|
||||
|
||||
void FileStream::insert(const ByteVector &data, unsigned long start, unsigned long replace)
|
||||
{
|
||||
if(!isOpen()) {
|
||||
debug("FileStream::insert() -- invalid file.");
|
||||
return;
|
||||
}
|
||||
|
||||
if(readOnly()) {
|
||||
debug("FileStream::insert() -- read only file.");
|
||||
return;
|
||||
}
|
||||
|
||||
if(data.size() == replace) {
|
||||
seek(start);
|
||||
writeBlock(data);
|
||||
return;
|
||||
}
|
||||
else if(data.size() < replace) {
|
||||
seek(start);
|
||||
writeBlock(data);
|
||||
removeBlock(start + data.size(), replace - data.size());
|
||||
return;
|
||||
}
|
||||
|
||||
// Woohoo! Faster (about 20%) than id3lib at last. I had to get hardcore
|
||||
// and avoid TagLib's high level API for rendering just copying parts of
|
||||
// the file that don't contain tag data.
|
||||
//
|
||||
// Now I'll explain the steps in this ugliness:
|
||||
|
||||
// First, make sure that we're working with a buffer that is longer than
|
||||
// the *differnce* in the tag sizes. We want to avoid overwriting parts
|
||||
// that aren't yet in memory, so this is necessary.
|
||||
|
||||
unsigned long bufferLength = bufferSize();
|
||||
|
||||
while(data.size() - replace > bufferLength)
|
||||
bufferLength += bufferSize();
|
||||
|
||||
// Set where to start the reading and writing.
|
||||
|
||||
long readPosition = start + replace;
|
||||
long writePosition = start;
|
||||
|
||||
ByteVector buffer = data;
|
||||
ByteVector aboutToOverwrite(static_cast<unsigned int>(bufferLength));
|
||||
|
||||
while(true)
|
||||
{
|
||||
// Seek to the current read position and read the data that we're about
|
||||
// to overwrite. Appropriately increment the readPosition.
|
||||
|
||||
seek(readPosition);
|
||||
const unsigned int bytesRead = static_cast<unsigned int>(readFile(d->file, aboutToOverwrite));
|
||||
aboutToOverwrite.resize(bytesRead);
|
||||
readPosition += bufferLength;
|
||||
|
||||
// Check to see if we just read the last block. We need to call clear()
|
||||
// if we did so that the last write succeeds.
|
||||
|
||||
if(bytesRead < bufferLength)
|
||||
clear();
|
||||
|
||||
// Seek to the write position and write our buffer. Increment the
|
||||
// writePosition.
|
||||
|
||||
seek(writePosition);
|
||||
writeBlock(buffer);
|
||||
|
||||
// We hit the end of the file.
|
||||
|
||||
if(bytesRead == 0)
|
||||
break;
|
||||
|
||||
writePosition += buffer.size();
|
||||
|
||||
// Make the current buffer the data that we read in the beginning.
|
||||
|
||||
buffer = aboutToOverwrite;
|
||||
}
|
||||
}
|
||||
|
||||
void FileStream::removeBlock(unsigned long start, unsigned long length)
|
||||
{
|
||||
if(!isOpen()) {
|
||||
debug("FileStream::removeBlock() -- invalid file.");
|
||||
return;
|
||||
}
|
||||
|
||||
unsigned long bufferLength = bufferSize();
|
||||
|
||||
long readPosition = start + length;
|
||||
long writePosition = start;
|
||||
|
||||
ByteVector buffer(static_cast<unsigned int>(bufferLength));
|
||||
|
||||
for(unsigned int bytesRead = -1; bytesRead != 0;)
|
||||
{
|
||||
seek(readPosition);
|
||||
bytesRead = static_cast<unsigned int>(readFile(d->file, buffer));
|
||||
readPosition += bytesRead;
|
||||
|
||||
// Check to see if we just read the last block. We need to call clear()
|
||||
// if we did so that the last write succeeds.
|
||||
|
||||
if(bytesRead < buffer.size()) {
|
||||
clear();
|
||||
buffer.resize(bytesRead);
|
||||
}
|
||||
|
||||
seek(writePosition);
|
||||
writeFile(d->file, buffer);
|
||||
|
||||
writePosition += bytesRead;
|
||||
}
|
||||
|
||||
truncate(writePosition);
|
||||
}
|
||||
|
||||
bool FileStream::readOnly() const
|
||||
{
|
||||
return d->readOnly;
|
||||
}
|
||||
|
||||
bool FileStream::isOpen() const
|
||||
{
|
||||
return (d->file != InvalidFileHandle);
|
||||
}
|
||||
|
||||
void FileStream::seek(long offset, Position p)
|
||||
{
|
||||
if(!isOpen()) {
|
||||
debug("FileStream::seek() -- invalid file.");
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
if(p != Beginning && p != Current && p != End) {
|
||||
debug("FileStream::seek() -- Invalid Position value.");
|
||||
return;
|
||||
}
|
||||
|
||||
LARGE_INTEGER liOffset;
|
||||
liOffset.QuadPart = offset;
|
||||
|
||||
if(!SetFilePointerEx(d->file, liOffset, NULL, static_cast<DWORD>(p))) {
|
||||
debug("FileStream::seek() -- Failed to set the file pointer.");
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
int whence;
|
||||
switch(p) {
|
||||
case Beginning:
|
||||
whence = SEEK_SET;
|
||||
break;
|
||||
case Current:
|
||||
whence = SEEK_CUR;
|
||||
break;
|
||||
case End:
|
||||
whence = SEEK_END;
|
||||
break;
|
||||
default:
|
||||
debug("FileStream::seek() -- Invalid Position value.");
|
||||
return;
|
||||
}
|
||||
|
||||
fseek(d->file, offset, whence);
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
void FileStream::clear()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
|
||||
// NOP
|
||||
|
||||
#else
|
||||
|
||||
clearerr(d->file);
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
long FileStream::tell() const
|
||||
{
|
||||
#ifdef _WIN32
|
||||
|
||||
const LARGE_INTEGER zero = {};
|
||||
LARGE_INTEGER position;
|
||||
|
||||
if(SetFilePointerEx(d->file, zero, &position, FILE_CURRENT) && position.QuadPart <= LONG_MAX) {
|
||||
return static_cast<long>(position.QuadPart);
|
||||
}
|
||||
else {
|
||||
debug("FileStream::tell() -- Failed to get the file pointer.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
return ftell(d->file);
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
long FileStream::length()
|
||||
{
|
||||
if(!isOpen()) {
|
||||
debug("FileStream::length() -- invalid file.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
LARGE_INTEGER fileSize;
|
||||
|
||||
if(GetFileSizeEx(d->file, &fileSize) && fileSize.QuadPart <= LONG_MAX) {
|
||||
return static_cast<long>(fileSize.QuadPart);
|
||||
}
|
||||
else {
|
||||
debug("FileStream::length() -- Failed to get the file size.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
const long curpos = tell();
|
||||
|
||||
seek(0, End);
|
||||
const long endpos = tell();
|
||||
|
||||
seek(curpos, Beginning);
|
||||
|
||||
return endpos;
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// protected members
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void FileStream::truncate(long length)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
|
||||
const long currentPos = tell();
|
||||
|
||||
seek(length);
|
||||
|
||||
if(!SetEndOfFile(d->file)) {
|
||||
debug("FileStream::truncate() -- Failed to truncate the file.");
|
||||
}
|
||||
|
||||
seek(currentPos);
|
||||
|
||||
#else
|
||||
|
||||
const int error = ftruncate(fileno(d->file), length);
|
||||
if(error != 0) {
|
||||
debug("FileStream::truncate() -- Coundn't truncate the file.");
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
unsigned int FileStream::bufferSize()
|
||||
{
|
||||
return 1024;
|
||||
}
|
||||
154
3rdparty/taglib/toolkit/tfilestream.h
vendored
Normal file
154
3rdparty/taglib/toolkit/tfilestream.h
vendored
Normal file
@@ -0,0 +1,154 @@
|
||||
/***************************************************************************
|
||||
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_FILESTREAM_H
|
||||
#define TAGLIB_FILESTREAM_H
|
||||
|
||||
#include "taglib_export.h"
|
||||
#include "taglib.h"
|
||||
#include "tbytevector.h"
|
||||
#include "tiostream.h"
|
||||
|
||||
namespace TagLib {
|
||||
|
||||
class String;
|
||||
class Tag;
|
||||
class AudioProperties;
|
||||
|
||||
//! A file class with some useful methods for tag manipulation
|
||||
|
||||
/*!
|
||||
* This class is a basic file class with some methods that are particularly
|
||||
* useful for tag editors. It has methods to take advantage of
|
||||
* ByteVector and a binary search method for finding patterns in a file.
|
||||
*/
|
||||
|
||||
class TAGLIB_EXPORT FileStream : public IOStream
|
||||
{
|
||||
public:
|
||||
/*!
|
||||
* Construct a File object and opens the \a file. \a file should be a
|
||||
* be a C-string in the local file system encoding.
|
||||
*/
|
||||
FileStream(FileName file, bool openReadOnly = false);
|
||||
|
||||
/*!
|
||||
* Destroys this FileStream instance.
|
||||
*/
|
||||
virtual ~FileStream();
|
||||
|
||||
/*!
|
||||
* Returns the file name in the local file system encoding.
|
||||
*/
|
||||
FileName name() const;
|
||||
|
||||
/*!
|
||||
* Reads a block of size \a length at the current get pointer.
|
||||
*/
|
||||
ByteVector readBlock(unsigned long length);
|
||||
|
||||
/*!
|
||||
* Attempts to write the block \a data at the current get pointer. If the
|
||||
* file is currently only opened read only -- i.e. readOnly() returns true --
|
||||
* this attempts to reopen the file in read/write mode.
|
||||
*
|
||||
* \note This should be used instead of using the streaming output operator
|
||||
* for a ByteVector. And even this function is significantly slower than
|
||||
* doing output with a char[].
|
||||
*/
|
||||
void writeBlock(const ByteVector &data);
|
||||
|
||||
/*!
|
||||
* Insert \a data at position \a start in the file overwriting \a replace
|
||||
* bytes of the original content.
|
||||
*
|
||||
* \note This method is slow since it requires rewriting all of the file
|
||||
* after the insertion point.
|
||||
*/
|
||||
void insert(const ByteVector &data, unsigned long start = 0, unsigned long replace = 0);
|
||||
|
||||
/*!
|
||||
* Removes a block of the file starting a \a start and continuing for
|
||||
* \a length bytes.
|
||||
*
|
||||
* \note This method is slow since it involves rewriting all of the file
|
||||
* after the removed portion.
|
||||
*/
|
||||
void removeBlock(unsigned long start = 0, unsigned long length = 0);
|
||||
|
||||
/*!
|
||||
* Returns true if the file is read only (or if the file can not be opened).
|
||||
*/
|
||||
bool readOnly() const;
|
||||
|
||||
/*!
|
||||
* Since the file can currently only be opened as an argument to the
|
||||
* constructor (sort-of by design), this returns if that open succeeded.
|
||||
*/
|
||||
bool isOpen() const;
|
||||
|
||||
/*!
|
||||
* Move the I/O pointer to \a offset in the file from position \a p. This
|
||||
* defaults to seeking from the beginning of the file.
|
||||
*
|
||||
* \see Position
|
||||
*/
|
||||
void seek(long offset, Position p = Beginning);
|
||||
|
||||
/*!
|
||||
* Reset the end-of-file and error flags on the file.
|
||||
*/
|
||||
void clear();
|
||||
|
||||
/*!
|
||||
* Returns the current offset within the file.
|
||||
*/
|
||||
long tell() const;
|
||||
|
||||
/*!
|
||||
* Returns the length of the file.
|
||||
*/
|
||||
long length();
|
||||
|
||||
/*!
|
||||
* Truncates the file to a \a length.
|
||||
*/
|
||||
void truncate(long length);
|
||||
|
||||
protected:
|
||||
|
||||
/*!
|
||||
* Returns the buffer size that is used for internal buffering.
|
||||
*/
|
||||
static unsigned int bufferSize();
|
||||
|
||||
private:
|
||||
class FileStreamPrivate;
|
||||
FileStreamPrivate *d;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
114
3rdparty/taglib/toolkit/tiostream.cpp
vendored
Normal file
114
3rdparty/taglib/toolkit/tiostream.cpp
vendored
Normal file
@@ -0,0 +1,114 @@
|
||||
/***************************************************************************
|
||||
copyright : (C) 2011 by Lukas Lalinsky
|
||||
email : lalinsky@gmail.com
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* 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/ *
|
||||
***************************************************************************/
|
||||
|
||||
#ifdef _WIN32
|
||||
# include <windows.h>
|
||||
# include <tstring.h>
|
||||
#endif
|
||||
|
||||
#include "tiostream.h"
|
||||
|
||||
using namespace TagLib;
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
namespace
|
||||
{
|
||||
std::wstring ansiToUnicode(const char *str)
|
||||
{
|
||||
const int len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
|
||||
if(len == 0)
|
||||
return std::wstring();
|
||||
|
||||
std::wstring wstr(len - 1, L'\0');
|
||||
MultiByteToWideChar(CP_ACP, 0, str, -1, &wstr[0], len);
|
||||
|
||||
return wstr;
|
||||
}
|
||||
}
|
||||
|
||||
// m_name is no longer used, but kept for backward compatibility.
|
||||
|
||||
FileName::FileName(const wchar_t *name) :
|
||||
m_name(),
|
||||
m_wname(name)
|
||||
{
|
||||
}
|
||||
|
||||
FileName::FileName(const char *name) :
|
||||
m_name(),
|
||||
m_wname(ansiToUnicode(name))
|
||||
{
|
||||
}
|
||||
|
||||
FileName::FileName(const FileName &name) :
|
||||
m_name(),
|
||||
m_wname(name.m_wname)
|
||||
{
|
||||
}
|
||||
|
||||
FileName::operator const wchar_t *() const
|
||||
{
|
||||
return m_wname.c_str();
|
||||
}
|
||||
|
||||
FileName::operator const char *() const
|
||||
{
|
||||
return m_name.c_str();
|
||||
}
|
||||
|
||||
const std::wstring &FileName::wstr() const
|
||||
{
|
||||
return m_wname;
|
||||
}
|
||||
|
||||
const std::string &FileName::str() const
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
|
||||
String FileName::toString() const
|
||||
{
|
||||
return String(m_wname.c_str());
|
||||
}
|
||||
|
||||
#endif // _WIN32
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// public members
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
IOStream::IOStream()
|
||||
{
|
||||
}
|
||||
|
||||
IOStream::~IOStream()
|
||||
{
|
||||
}
|
||||
|
||||
void IOStream::clear()
|
||||
{
|
||||
}
|
||||
|
||||
170
3rdparty/taglib/toolkit/tiostream.h
vendored
Normal file
170
3rdparty/taglib/toolkit/tiostream.h
vendored
Normal file
@@ -0,0 +1,170 @@
|
||||
/***************************************************************************
|
||||
copyright : (C) 2011 by Lukas Lalinsky
|
||||
email : lalinsky@gmail.com
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* 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_IOSTREAM_H
|
||||
#define TAGLIB_IOSTREAM_H
|
||||
|
||||
#include "taglib_export.h"
|
||||
#include "taglib.h"
|
||||
#include "tbytevector.h"
|
||||
|
||||
namespace TagLib {
|
||||
|
||||
#ifdef _WIN32
|
||||
class TAGLIB_EXPORT FileName
|
||||
{
|
||||
public:
|
||||
FileName(const wchar_t *name);
|
||||
FileName(const char *name);
|
||||
|
||||
FileName(const FileName &name);
|
||||
|
||||
operator const wchar_t *() const;
|
||||
operator const char *() const;
|
||||
|
||||
const std::wstring &wstr() const;
|
||||
const std::string &str() const;
|
||||
|
||||
String toString() const;
|
||||
|
||||
private:
|
||||
const std::string m_name;
|
||||
const std::wstring m_wname;
|
||||
};
|
||||
#else
|
||||
typedef const char *FileName;
|
||||
#endif
|
||||
|
||||
//! An abstract class that provides operations on a sequence of bytes
|
||||
|
||||
class TAGLIB_EXPORT IOStream
|
||||
{
|
||||
public:
|
||||
/*!
|
||||
* Position in the file used for seeking.
|
||||
*/
|
||||
enum Position {
|
||||
//! Seek from the beginning of the file.
|
||||
Beginning,
|
||||
//! Seek from the current position in the file.
|
||||
Current,
|
||||
//! Seek from the end of the file.
|
||||
End
|
||||
};
|
||||
|
||||
IOStream();
|
||||
|
||||
/*!
|
||||
* Destroys this IOStream instance.
|
||||
*/
|
||||
virtual ~IOStream();
|
||||
|
||||
/*!
|
||||
* Returns the stream name in the local file system encoding.
|
||||
*/
|
||||
virtual FileName name() const = 0;
|
||||
|
||||
/*!
|
||||
* Reads a block of size \a length at the current get pointer.
|
||||
*/
|
||||
virtual ByteVector readBlock(unsigned long length) = 0;
|
||||
|
||||
/*!
|
||||
* Attempts to write the block \a data at the current get pointer. If the
|
||||
* file is currently only opened read only -- i.e. readOnly() returns true --
|
||||
* this attempts to reopen the file in read/write mode.
|
||||
*
|
||||
* \note This should be used instead of using the streaming output operator
|
||||
* for a ByteVector. And even this function is significantly slower than
|
||||
* doing output with a char[].
|
||||
*/
|
||||
virtual void writeBlock(const ByteVector &data) = 0;
|
||||
|
||||
/*!
|
||||
* Insert \a data at position \a start in the file overwriting \a replace
|
||||
* bytes of the original content.
|
||||
*
|
||||
* \note This method is slow since it requires rewriting all of the file
|
||||
* after the insertion point.
|
||||
*/
|
||||
virtual void insert(const ByteVector &data,
|
||||
unsigned long start = 0, unsigned long replace = 0) = 0;
|
||||
|
||||
/*!
|
||||
* Removes a block of the file starting a \a start and continuing for
|
||||
* \a length bytes.
|
||||
*
|
||||
* \note This method is slow since it involves rewriting all of the file
|
||||
* after the removed portion.
|
||||
*/
|
||||
virtual void removeBlock(unsigned long start = 0, unsigned long length = 0) = 0;
|
||||
|
||||
/*!
|
||||
* Returns true if the file is read only (or if the file can not be opened).
|
||||
*/
|
||||
virtual bool readOnly() const = 0;
|
||||
|
||||
/*!
|
||||
* Since the file can currently only be opened as an argument to the
|
||||
* constructor (sort-of by design), this returns if that open succeeded.
|
||||
*/
|
||||
virtual bool isOpen() const = 0;
|
||||
|
||||
/*!
|
||||
* Move the I/O pointer to \a offset in the stream from position \a p. This
|
||||
* defaults to seeking from the beginning of the stream.
|
||||
*
|
||||
* \see Position
|
||||
*/
|
||||
virtual void seek(long offset, Position p = Beginning) = 0;
|
||||
|
||||
/*!
|
||||
* Reset the end-of-stream and error flags on the stream.
|
||||
*/
|
||||
virtual void clear();
|
||||
|
||||
/*!
|
||||
* Returns the current offset within the stream.
|
||||
*/
|
||||
virtual long tell() const = 0;
|
||||
|
||||
/*!
|
||||
* Returns the length of the stream.
|
||||
*/
|
||||
virtual long length() = 0;
|
||||
|
||||
/*!
|
||||
* Truncates the stream to a \a length.
|
||||
*/
|
||||
virtual void truncate(long length) = 0;
|
||||
|
||||
private:
|
||||
IOStream(const IOStream &);
|
||||
IOStream &operator=(const IOStream &);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
270
3rdparty/taglib/toolkit/tlist.h
vendored
Normal file
270
3rdparty/taglib/toolkit/tlist.h
vendored
Normal file
@@ -0,0 +1,270 @@
|
||||
/***************************************************************************
|
||||
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_LIST_H
|
||||
#define TAGLIB_LIST_H
|
||||
|
||||
#include "taglib.h"
|
||||
|
||||
#include <list>
|
||||
|
||||
namespace TagLib {
|
||||
|
||||
//! A generic, implicitly shared list.
|
||||
|
||||
/*!
|
||||
* This is basic generic list that's somewhere between a std::list and a
|
||||
* QValueList. This class is implicitly shared. For example:
|
||||
*
|
||||
* \code
|
||||
*
|
||||
* TagLib::List<int> l = someOtherIntList;
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* The above example is very cheap. This also makes lists suitable for the
|
||||
* return types of functions. The above example will just copy a pointer rather
|
||||
* than copying the data in the list. When your \e shared list's data changes,
|
||||
* only \e then will the data be copied.
|
||||
*/
|
||||
|
||||
template <class T> class List
|
||||
{
|
||||
public:
|
||||
#ifndef DO_NOT_DOCUMENT
|
||||
typedef typename std::list<T>::iterator Iterator;
|
||||
typedef typename std::list<T>::const_iterator ConstIterator;
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* Constructs an empty list.
|
||||
*/
|
||||
List();
|
||||
|
||||
/*!
|
||||
* Make a shallow, implicitly shared, copy of \a l. Because this is
|
||||
* implicitly shared, this method is lightweight and suitable for
|
||||
* pass-by-value usage.
|
||||
*/
|
||||
List(const List<T> &l);
|
||||
|
||||
/*!
|
||||
* Destroys this List instance. If auto deletion is enabled and this list
|
||||
* contains a pointer type all of the members are also deleted.
|
||||
*/
|
||||
virtual ~List();
|
||||
|
||||
/*!
|
||||
* Returns an STL style iterator to the beginning of the list. See
|
||||
* std::list::const_iterator for the semantics.
|
||||
*/
|
||||
Iterator begin();
|
||||
|
||||
/*!
|
||||
* Returns an STL style constant iterator to the beginning of the list. See
|
||||
* std::list::iterator for the semantics.
|
||||
*/
|
||||
ConstIterator begin() const;
|
||||
|
||||
/*!
|
||||
* Returns an STL style iterator to the end of the list. See
|
||||
* std::list::iterator for the semantics.
|
||||
*/
|
||||
Iterator end();
|
||||
|
||||
/*!
|
||||
* Returns an STL style constant iterator to the end of the list. See
|
||||
* std::list::const_iterator for the semantics.
|
||||
*/
|
||||
ConstIterator end() const;
|
||||
|
||||
/*!
|
||||
* Inserts a copy of \a value before \a it.
|
||||
*/
|
||||
Iterator insert(Iterator it, const T &value);
|
||||
|
||||
/*!
|
||||
* Inserts the \a value into the list. This assumes that the list is
|
||||
* currently sorted. If \a unique is true then the value will not
|
||||
* be inserted if it is already in the list.
|
||||
*/
|
||||
List<T> &sortedInsert(const T &value, bool unique = false);
|
||||
|
||||
/*!
|
||||
* Appends \a item to the end of the list and returns a reference to the
|
||||
* list.
|
||||
*/
|
||||
List<T> &append(const T &item);
|
||||
|
||||
/*!
|
||||
* Appends all of the values in \a l to the end of the list and returns a
|
||||
* reference to the list.
|
||||
*/
|
||||
List<T> &append(const List<T> &l);
|
||||
|
||||
/*!
|
||||
* Prepends \a item to the beginning list and returns a reference to the
|
||||
* list.
|
||||
*/
|
||||
List<T> &prepend(const T &item);
|
||||
|
||||
/*!
|
||||
* Prepends all of the items in \a l to the beginning list and returns a
|
||||
* reference to the list.
|
||||
*/
|
||||
List<T> &prepend(const List<T> &l);
|
||||
|
||||
/*!
|
||||
* Clears the list. If auto deletion is enabled and this list contains a
|
||||
* pointer type the members are also deleted.
|
||||
*
|
||||
* \see setAutoDelete()
|
||||
*/
|
||||
List<T> &clear();
|
||||
|
||||
/*!
|
||||
* Returns the number of elements in the list.
|
||||
*
|
||||
* \see isEmpty()
|
||||
*/
|
||||
unsigned int size() const;
|
||||
|
||||
/*!
|
||||
* Returns whether or not the list is empty.
|
||||
*
|
||||
* \see size()
|
||||
*/
|
||||
bool isEmpty() const;
|
||||
|
||||
/*!
|
||||
* Find the first occurrence of \a value.
|
||||
*/
|
||||
Iterator find(const T &value);
|
||||
|
||||
/*!
|
||||
* Find the first occurrence of \a value.
|
||||
*/
|
||||
ConstIterator find(const T &value) const;
|
||||
|
||||
/*!
|
||||
* Returns true if the list contains \a value.
|
||||
*/
|
||||
bool contains(const T &value) const;
|
||||
|
||||
/*!
|
||||
* Erase the item at \a it from the list.
|
||||
*/
|
||||
Iterator erase(Iterator it);
|
||||
|
||||
/*!
|
||||
* Returns a reference to the first item in the list.
|
||||
*/
|
||||
const T &front() const;
|
||||
|
||||
/*!
|
||||
* Returns a reference to the first item in the list.
|
||||
*/
|
||||
T &front();
|
||||
|
||||
/*!
|
||||
* Returns a reference to the last item in the list.
|
||||
*/
|
||||
const T &back() const;
|
||||
|
||||
/*!
|
||||
* Returns a reference to the last item in the list.
|
||||
*/
|
||||
T &back();
|
||||
|
||||
/*!
|
||||
* Auto delete the members of the list when the last reference to the list
|
||||
* passes out of scope. This will have no effect on lists which do not
|
||||
* contain a pointer type.
|
||||
*
|
||||
* \note This relies on partial template instantiation -- most modern C++
|
||||
* compilers should now support this.
|
||||
*/
|
||||
void setAutoDelete(bool autoDelete);
|
||||
|
||||
/*!
|
||||
* Returns a reference to item \a i in the list.
|
||||
*
|
||||
* \warning This method is slow. Use iterators to loop through the list.
|
||||
*/
|
||||
T &operator[](unsigned int i);
|
||||
|
||||
/*!
|
||||
* Returns a const reference to item \a i in the list.
|
||||
*
|
||||
* \warning This method is slow. Use iterators to loop through the list.
|
||||
*/
|
||||
const T &operator[](unsigned int i) const;
|
||||
|
||||
/*!
|
||||
* Make a shallow, implicitly shared, copy of \a l. Because this is
|
||||
* implicitly shared, this method is lightweight and suitable for
|
||||
* pass-by-value usage.
|
||||
*/
|
||||
List<T> &operator=(const List<T> &l);
|
||||
|
||||
/*!
|
||||
* Exchanges the content of this list by the content of \a l.
|
||||
*/
|
||||
void swap(List<T> &l);
|
||||
|
||||
/*!
|
||||
* Compares this list with \a l and returns true if all of the elements are
|
||||
* the same.
|
||||
*/
|
||||
bool operator==(const List<T> &l) const;
|
||||
|
||||
/*!
|
||||
* Compares this list with \a l and returns true if the lists differ.
|
||||
*/
|
||||
bool operator!=(const List<T> &l) const;
|
||||
|
||||
protected:
|
||||
/*
|
||||
* If this List is being shared via implicit sharing, do a deep copy of the
|
||||
* data and separate from the shared members. This should be called by all
|
||||
* non-const subclass members.
|
||||
*/
|
||||
void detach();
|
||||
|
||||
private:
|
||||
#ifndef DO_NOT_DOCUMENT
|
||||
template <class TP> class ListPrivate;
|
||||
ListPrivate<T> *d;
|
||||
#endif
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
// Since GCC doesn't support the "export" keyword, we have to include the
|
||||
// implementation.
|
||||
|
||||
#include "tlist.tcc"
|
||||
|
||||
#endif
|
||||
323
3rdparty/taglib/toolkit/tlist.tcc
vendored
Normal file
323
3rdparty/taglib/toolkit/tlist.tcc
vendored
Normal file
@@ -0,0 +1,323 @@
|
||||
/***************************************************************************
|
||||
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/ *
|
||||
***************************************************************************/
|
||||
|
||||
#include <algorithm>
|
||||
#include "trefcounter.h"
|
||||
|
||||
namespace TagLib {
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// public members
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// The functionality of List<T>::setAutoDelete() is implemented here partial
|
||||
// template specialization. This is implemented in such a way that calling
|
||||
// setAutoDelete() on non-pointer types will simply have no effect.
|
||||
|
||||
// A base for the generic and specialized private class types. New
|
||||
// non-templatized members should be added here.
|
||||
|
||||
// BIC change to RefCounter
|
||||
class ListPrivateBase : public RefCounterOld
|
||||
{
|
||||
public:
|
||||
ListPrivateBase() : autoDelete(false) {}
|
||||
bool autoDelete;
|
||||
};
|
||||
|
||||
// A generic implementation
|
||||
|
||||
template <class T>
|
||||
template <class TP> class List<T>::ListPrivate : public ListPrivateBase
|
||||
{
|
||||
public:
|
||||
ListPrivate() : ListPrivateBase() {}
|
||||
ListPrivate(const std::list<TP> &l) : ListPrivateBase(), list(l) {}
|
||||
void clear() {
|
||||
list.clear();
|
||||
}
|
||||
std::list<TP> list;
|
||||
};
|
||||
|
||||
// A partial specialization for all pointer types that implements the
|
||||
// setAutoDelete() functionality.
|
||||
|
||||
template <class T>
|
||||
template <class TP> class List<T>::ListPrivate<TP *> : public ListPrivateBase
|
||||
{
|
||||
public:
|
||||
ListPrivate() : ListPrivateBase() {}
|
||||
ListPrivate(const std::list<TP *> &l) : ListPrivateBase(), list(l) {}
|
||||
~ListPrivate() {
|
||||
clear();
|
||||
}
|
||||
void clear() {
|
||||
if(autoDelete) {
|
||||
typename std::list<TP *>::const_iterator it = list.begin();
|
||||
for(; it != list.end(); ++it)
|
||||
delete *it;
|
||||
}
|
||||
list.clear();
|
||||
}
|
||||
std::list<TP *> list;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// public members
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template <class T>
|
||||
List<T>::List() :
|
||||
d(new ListPrivate<T>())
|
||||
{
|
||||
}
|
||||
|
||||
template <class T>
|
||||
List<T>::List(const List<T> &l) : d(l.d)
|
||||
{
|
||||
d->ref();
|
||||
}
|
||||
|
||||
template <class T>
|
||||
List<T>::~List()
|
||||
{
|
||||
if(d->deref())
|
||||
delete d;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
typename List<T>::Iterator List<T>::begin()
|
||||
{
|
||||
detach();
|
||||
return d->list.begin();
|
||||
}
|
||||
|
||||
template <class T>
|
||||
typename List<T>::ConstIterator List<T>::begin() const
|
||||
{
|
||||
return d->list.begin();
|
||||
}
|
||||
|
||||
template <class T>
|
||||
typename List<T>::Iterator List<T>::end()
|
||||
{
|
||||
detach();
|
||||
return d->list.end();
|
||||
}
|
||||
|
||||
template <class T>
|
||||
typename List<T>::ConstIterator List<T>::end() const
|
||||
{
|
||||
return d->list.end();
|
||||
}
|
||||
|
||||
template <class T>
|
||||
typename List<T>::Iterator List<T>::insert(Iterator it, const T &item)
|
||||
{
|
||||
detach();
|
||||
return d->list.insert(it, item);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
List<T> &List<T>::sortedInsert(const T &value, bool unique)
|
||||
{
|
||||
detach();
|
||||
Iterator it = begin();
|
||||
while(it != end() && *it < value)
|
||||
++it;
|
||||
if(unique && it != end() && *it == value)
|
||||
return *this;
|
||||
insert(it, value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
List<T> &List<T>::append(const T &item)
|
||||
{
|
||||
detach();
|
||||
d->list.push_back(item);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
List<T> &List<T>::append(const List<T> &l)
|
||||
{
|
||||
detach();
|
||||
d->list.insert(d->list.end(), l.begin(), l.end());
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
List<T> &List<T>::prepend(const T &item)
|
||||
{
|
||||
detach();
|
||||
d->list.push_front(item);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
List<T> &List<T>::prepend(const List<T> &l)
|
||||
{
|
||||
detach();
|
||||
d->list.insert(d->list.begin(), l.begin(), l.end());
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
List<T> &List<T>::clear()
|
||||
{
|
||||
detach();
|
||||
d->clear();
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
unsigned int List<T>::size() const
|
||||
{
|
||||
return static_cast<unsigned int>(d->list.size());
|
||||
}
|
||||
|
||||
template <class T>
|
||||
bool List<T>::isEmpty() const
|
||||
{
|
||||
return d->list.empty();
|
||||
}
|
||||
|
||||
template <class T>
|
||||
typename List<T>::Iterator List<T>::find(const T &value)
|
||||
{
|
||||
detach();
|
||||
return std::find(d->list.begin(), d->list.end(), value);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
typename List<T>::ConstIterator List<T>::find(const T &value) const
|
||||
{
|
||||
return std::find(d->list.begin(), d->list.end(), value);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
bool List<T>::contains(const T &value) const
|
||||
{
|
||||
return std::find(d->list.begin(), d->list.end(), value) != d->list.end();
|
||||
}
|
||||
|
||||
template <class T>
|
||||
typename List<T>::Iterator List<T>::erase(Iterator it)
|
||||
{
|
||||
return d->list.erase(it);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
const T &List<T>::front() const
|
||||
{
|
||||
return d->list.front();
|
||||
}
|
||||
|
||||
template <class T>
|
||||
T &List<T>::front()
|
||||
{
|
||||
detach();
|
||||
return d->list.front();
|
||||
}
|
||||
|
||||
template <class T>
|
||||
const T &List<T>::back() const
|
||||
{
|
||||
return d->list.back();
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void List<T>::setAutoDelete(bool autoDelete)
|
||||
{
|
||||
d->autoDelete = autoDelete;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
T &List<T>::back()
|
||||
{
|
||||
detach();
|
||||
return d->list.back();
|
||||
}
|
||||
|
||||
template <class T>
|
||||
T &List<T>::operator[](unsigned int i)
|
||||
{
|
||||
Iterator it = d->list.begin();
|
||||
std::advance(it, i);
|
||||
|
||||
return *it;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
const T &List<T>::operator[](unsigned int i) const
|
||||
{
|
||||
ConstIterator it = d->list.begin();
|
||||
std::advance(it, i);
|
||||
|
||||
return *it;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
List<T> &List<T>::operator=(const List<T> &l)
|
||||
{
|
||||
List<T>(l).swap(*this);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void List<T>::swap(List<T> &l)
|
||||
{
|
||||
using std::swap;
|
||||
|
||||
swap(d, l.d);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
bool List<T>::operator==(const List<T> &l) const
|
||||
{
|
||||
return d->list == l.d->list;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
bool List<T>::operator!=(const List<T> &l) const
|
||||
{
|
||||
return d->list != l.d->list;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// protected members
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template <class T>
|
||||
void List<T>::detach()
|
||||
{
|
||||
if(d->count() > 1) {
|
||||
d->deref();
|
||||
d = new ListPrivate<T>(d->list);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace TagLib
|
||||
204
3rdparty/taglib/toolkit/tmap.h
vendored
Normal file
204
3rdparty/taglib/toolkit/tmap.h
vendored
Normal file
@@ -0,0 +1,204 @@
|
||||
/***************************************************************************
|
||||
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_MAP_H
|
||||
#define TAGLIB_MAP_H
|
||||
|
||||
#include <map>
|
||||
|
||||
#include "taglib.h"
|
||||
|
||||
namespace TagLib {
|
||||
|
||||
//! A generic, implicitly shared map.
|
||||
|
||||
/*!
|
||||
* This implements a standard map container that associates a key with a value
|
||||
* and has fast key-based lookups. This map is also implicitly shared making
|
||||
* it suitable for pass-by-value usage.
|
||||
*/
|
||||
|
||||
template <class Key, class T> class Map
|
||||
{
|
||||
public:
|
||||
#ifndef DO_NOT_DOCUMENT
|
||||
#ifdef WANT_CLASS_INSTANTIATION_OF_MAP
|
||||
// Some STL implementations get snippy over the use of the
|
||||
// class keyword to distinguish different templates; Sun Studio
|
||||
// in particular finds multiple specializations in certain rare
|
||||
// cases and complains about that. GCC doesn't seem to mind,
|
||||
// and uses the typedefs further below without the class keyword.
|
||||
// Not all the specializations of Map can use the class keyword
|
||||
// (when T is not actually a class type), so don't apply this
|
||||
// generally.
|
||||
typedef typename std::map<class Key, class T>::iterator Iterator;
|
||||
typedef typename std::map<class Key, class T>::const_iterator ConstIterator;
|
||||
#else
|
||||
typedef typename std::map<Key, T>::iterator Iterator;
|
||||
typedef typename std::map<Key, T>::const_iterator ConstIterator;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* Constructs an empty Map.
|
||||
*/
|
||||
Map();
|
||||
|
||||
/*!
|
||||
* Make a shallow, implicitly shared, copy of \a m. Because this is
|
||||
* implicitly shared, this method is lightweight and suitable for
|
||||
* pass-by-value usage.
|
||||
*/
|
||||
Map(const Map<Key, T> &m);
|
||||
|
||||
/*!
|
||||
* Destroys this instance of the Map.
|
||||
*/
|
||||
virtual ~Map();
|
||||
|
||||
/*!
|
||||
* Returns an STL style iterator to the beginning of the map. See
|
||||
* std::map::iterator for the semantics.
|
||||
*/
|
||||
Iterator begin();
|
||||
|
||||
/*!
|
||||
* Returns an STL style iterator to the beginning of the map. See
|
||||
* std::map::const_iterator for the semantics.
|
||||
*/
|
||||
ConstIterator begin() const;
|
||||
|
||||
/*!
|
||||
* Returns an STL style iterator to the end of the map. See
|
||||
* std::map::iterator for the semantics.
|
||||
*/
|
||||
Iterator end();
|
||||
|
||||
/*!
|
||||
* Returns an STL style iterator to the end of the map. See
|
||||
* std::map::const_iterator for the semantics.
|
||||
*/
|
||||
ConstIterator end() const;
|
||||
|
||||
/*!
|
||||
* Inserts \a value under \a key in the map. If a value for \a key already
|
||||
* exists it will be overwritten.
|
||||
*/
|
||||
Map<Key, T> &insert(const Key &key, const T &value);
|
||||
|
||||
/*!
|
||||
* Removes all of the elements from elements from the map. This however
|
||||
* will not delete pointers if the mapped type is a pointer type.
|
||||
*/
|
||||
Map<Key, T> &clear();
|
||||
|
||||
/*!
|
||||
* The number of elements in the map.
|
||||
*
|
||||
* \see isEmpty()
|
||||
*/
|
||||
unsigned int size() const;
|
||||
|
||||
/*!
|
||||
* Returns true if the map is empty.
|
||||
*
|
||||
* \see size()
|
||||
*/
|
||||
bool isEmpty() const;
|
||||
|
||||
/*!
|
||||
* Find the first occurrence of \a key.
|
||||
*/
|
||||
Iterator find(const Key &key);
|
||||
|
||||
/*!
|
||||
* Find the first occurrence of \a key.
|
||||
*/
|
||||
ConstIterator find(const Key &key) const;
|
||||
|
||||
/*!
|
||||
* Returns true if the map contains an instance of \a key.
|
||||
*/
|
||||
bool contains(const Key &key) const;
|
||||
|
||||
/*!
|
||||
* Erase the item at \a it from the list.
|
||||
*/
|
||||
Map<Key, T> &erase(Iterator it);
|
||||
|
||||
/*!
|
||||
* Erase the item with \a key from the list.
|
||||
*/
|
||||
Map<Key, T> &erase(const Key &key);
|
||||
|
||||
/*!
|
||||
* Returns a reference to the value associated with \a key.
|
||||
*
|
||||
* \note This has undefined behavior if the key is not present in the map.
|
||||
*/
|
||||
const T &operator[](const Key &key) const;
|
||||
|
||||
/*!
|
||||
* Returns a reference to the value associated with \a key.
|
||||
*
|
||||
* \note This has undefined behavior if the key is not present in the map.
|
||||
*/
|
||||
T &operator[](const Key &key);
|
||||
|
||||
/*!
|
||||
* Make a shallow, implicitly shared, copy of \a m. Because this is
|
||||
* implicitly shared, this method is lightweight and suitable for
|
||||
* pass-by-value usage.
|
||||
*/
|
||||
Map<Key, T> &operator=(const Map<Key, T> &m);
|
||||
|
||||
/*!
|
||||
* Exchanges the content of this map by the content of \a m.
|
||||
*/
|
||||
void swap(Map<Key, T> &m);
|
||||
|
||||
protected:
|
||||
/*
|
||||
* If this List is being shared via implicit sharing, do a deep copy of the
|
||||
* data and separate from the shared members. This should be called by all
|
||||
* non-const subclass members.
|
||||
*/
|
||||
void detach();
|
||||
|
||||
private:
|
||||
#ifndef DO_NOT_DOCUMENT
|
||||
template <class KeyP, class TP> class MapPrivate;
|
||||
MapPrivate<Key, T> *d;
|
||||
#endif
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
// Since GCC doesn't support the "export" keyword, we have to include the
|
||||
// implementation.
|
||||
|
||||
#include "tmap.tcc"
|
||||
|
||||
#endif
|
||||
199
3rdparty/taglib/toolkit/tmap.tcc
vendored
Normal file
199
3rdparty/taglib/toolkit/tmap.tcc
vendored
Normal file
@@ -0,0 +1,199 @@
|
||||
/***************************************************************************
|
||||
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/ *
|
||||
***************************************************************************/
|
||||
|
||||
#include "trefcounter.h"
|
||||
|
||||
namespace TagLib {
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// public members
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// BIC change to RefCounter
|
||||
template <class Key, class T>
|
||||
template <class KeyP, class TP>
|
||||
class Map<Key, T>::MapPrivate : public RefCounterOld
|
||||
{
|
||||
public:
|
||||
MapPrivate() : RefCounterOld() {}
|
||||
#ifdef WANT_CLASS_INSTANTIATION_OF_MAP
|
||||
MapPrivate(const std::map<class KeyP, class TP>& m) : RefCounterOld(), map(m) {}
|
||||
std::map<class KeyP, class TP> map;
|
||||
#else
|
||||
MapPrivate(const std::map<KeyP, TP>& m) : RefCounterOld(), map(m) {}
|
||||
std::map<KeyP, TP> map;
|
||||
#endif
|
||||
};
|
||||
|
||||
template <class Key, class T>
|
||||
Map<Key, T>::Map() :
|
||||
d(new MapPrivate<Key, T>())
|
||||
{
|
||||
}
|
||||
|
||||
template <class Key, class T>
|
||||
Map<Key, T>::Map(const Map<Key, T> &m) : d(m.d)
|
||||
{
|
||||
d->ref();
|
||||
}
|
||||
|
||||
template <class Key, class T>
|
||||
Map<Key, T>::~Map()
|
||||
{
|
||||
if(d->deref())
|
||||
delete(d);
|
||||
}
|
||||
|
||||
template <class Key, class T>
|
||||
typename Map<Key, T>::Iterator Map<Key, T>::begin()
|
||||
{
|
||||
detach();
|
||||
return d->map.begin();
|
||||
}
|
||||
|
||||
template <class Key, class T>
|
||||
typename Map<Key, T>::ConstIterator Map<Key, T>::begin() const
|
||||
{
|
||||
return d->map.begin();
|
||||
}
|
||||
|
||||
template <class Key, class T>
|
||||
typename Map<Key, T>::Iterator Map<Key, T>::end()
|
||||
{
|
||||
detach();
|
||||
return d->map.end();
|
||||
}
|
||||
|
||||
template <class Key, class T>
|
||||
typename Map<Key, T>::ConstIterator Map<Key, T>::end() const
|
||||
{
|
||||
return d->map.end();
|
||||
}
|
||||
|
||||
template <class Key, class T>
|
||||
Map<Key, T> &Map<Key, T>::insert(const Key &key, const T &value)
|
||||
{
|
||||
detach();
|
||||
d->map[key] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class Key, class T>
|
||||
Map<Key, T> &Map<Key, T>::clear()
|
||||
{
|
||||
detach();
|
||||
d->map.clear();
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class Key, class T>
|
||||
bool Map<Key, T>::isEmpty() const
|
||||
{
|
||||
return d->map.empty();
|
||||
}
|
||||
|
||||
template <class Key, class T>
|
||||
typename Map<Key, T>::Iterator Map<Key, T>::find(const Key &key)
|
||||
{
|
||||
detach();
|
||||
return d->map.find(key);
|
||||
}
|
||||
|
||||
template <class Key, class T>
|
||||
typename Map<Key,T>::ConstIterator Map<Key, T>::find(const Key &key) const
|
||||
{
|
||||
return d->map.find(key);
|
||||
}
|
||||
|
||||
template <class Key, class T>
|
||||
bool Map<Key, T>::contains(const Key &key) const
|
||||
{
|
||||
return d->map.find(key) != d->map.end();
|
||||
}
|
||||
|
||||
template <class Key, class T>
|
||||
Map<Key, T> &Map<Key,T>::erase(Iterator it)
|
||||
{
|
||||
detach();
|
||||
d->map.erase(it);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class Key, class T>
|
||||
Map<Key, T> &Map<Key,T>::erase(const Key &key)
|
||||
{
|
||||
detach();
|
||||
d->map.erase(key);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class Key, class T>
|
||||
unsigned int Map<Key, T>::size() const
|
||||
{
|
||||
return static_cast<unsigned int>(d->map.size());
|
||||
}
|
||||
|
||||
template <class Key, class T>
|
||||
const T &Map<Key, T>::operator[](const Key &key) const
|
||||
{
|
||||
return d->map[key];
|
||||
}
|
||||
|
||||
template <class Key, class T>
|
||||
T &Map<Key, T>::operator[](const Key &key)
|
||||
{
|
||||
detach();
|
||||
return d->map[key];
|
||||
}
|
||||
|
||||
template <class Key, class T>
|
||||
Map<Key, T> &Map<Key, T>::operator=(const Map<Key, T> &m)
|
||||
{
|
||||
Map<Key, T>(m).swap(*this);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class Key, class T>
|
||||
void Map<Key, T>::swap(Map<Key, T> &m)
|
||||
{
|
||||
using std::swap;
|
||||
|
||||
swap(d, m.d);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// protected members
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template <class Key, class T>
|
||||
void Map<Key, T>::detach()
|
||||
{
|
||||
if(d->count() > 1) {
|
||||
d->deref();
|
||||
d = new MapPrivate<Key, T>(d->map);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace TagLib
|
||||
179
3rdparty/taglib/toolkit/tpropertymap.cpp
vendored
Normal file
179
3rdparty/taglib/toolkit/tpropertymap.cpp
vendored
Normal file
@@ -0,0 +1,179 @@
|
||||
/***************************************************************************
|
||||
copyright : (C) 2012 by Michael Helmling
|
||||
email : helmling@mathematik.uni-kl.de
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* 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/ *
|
||||
***************************************************************************/
|
||||
|
||||
|
||||
#include "tpropertymap.h"
|
||||
using namespace TagLib;
|
||||
|
||||
|
||||
PropertyMap::PropertyMap() : SimplePropertyMap()
|
||||
{
|
||||
}
|
||||
|
||||
PropertyMap::PropertyMap(const PropertyMap &m) : SimplePropertyMap(m), unsupported(m.unsupported)
|
||||
{
|
||||
}
|
||||
|
||||
PropertyMap::PropertyMap(const SimplePropertyMap &m)
|
||||
{
|
||||
for(SimplePropertyMap::ConstIterator it = m.begin(); it != m.end(); ++it){
|
||||
String key = it->first.upper();
|
||||
if(!key.isEmpty())
|
||||
insert(it->first, it->second);
|
||||
else
|
||||
unsupported.append(it->first);
|
||||
}
|
||||
}
|
||||
|
||||
PropertyMap::~PropertyMap()
|
||||
{
|
||||
}
|
||||
|
||||
bool PropertyMap::insert(const String &key, const StringList &values)
|
||||
{
|
||||
String realKey = key.upper();
|
||||
Iterator result = SimplePropertyMap::find(realKey);
|
||||
if(result == end())
|
||||
SimplePropertyMap::insert(realKey, values);
|
||||
else
|
||||
SimplePropertyMap::operator[](realKey).append(values);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PropertyMap::replace(const String &key, const StringList &values)
|
||||
{
|
||||
String realKey = key.upper();
|
||||
SimplePropertyMap::erase(realKey);
|
||||
SimplePropertyMap::insert(realKey, values);
|
||||
return true;
|
||||
}
|
||||
|
||||
PropertyMap::Iterator PropertyMap::find(const String &key)
|
||||
{
|
||||
return SimplePropertyMap::find(key.upper());
|
||||
}
|
||||
|
||||
PropertyMap::ConstIterator PropertyMap::find(const String &key) const
|
||||
{
|
||||
return SimplePropertyMap::find(key.upper());
|
||||
}
|
||||
|
||||
bool PropertyMap::contains(const String &key) const
|
||||
{
|
||||
return SimplePropertyMap::contains(key.upper());
|
||||
}
|
||||
|
||||
bool PropertyMap::contains(const PropertyMap &other) const
|
||||
{
|
||||
for(ConstIterator it = other.begin(); it != other.end(); ++it) {
|
||||
if(!SimplePropertyMap::contains(it->first))
|
||||
return false;
|
||||
if ((*this)[it->first] != it->second)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
PropertyMap &PropertyMap::erase(const String &key)
|
||||
{
|
||||
SimplePropertyMap::erase(key.upper());
|
||||
return *this;
|
||||
}
|
||||
|
||||
PropertyMap &PropertyMap::erase(const PropertyMap &other)
|
||||
{
|
||||
for(ConstIterator it = other.begin(); it != other.end(); ++it)
|
||||
erase(it->first);
|
||||
return *this;
|
||||
}
|
||||
|
||||
PropertyMap &PropertyMap::merge(const PropertyMap &other)
|
||||
{
|
||||
for(PropertyMap::ConstIterator it = other.begin(); it != other.end(); ++it)
|
||||
insert(it->first, it->second);
|
||||
unsupported.append(other.unsupported);
|
||||
return *this;
|
||||
}
|
||||
|
||||
const StringList &PropertyMap::operator[](const String &key) const
|
||||
{
|
||||
return SimplePropertyMap::operator[](key.upper());
|
||||
}
|
||||
|
||||
StringList &PropertyMap::operator[](const String &key)
|
||||
{
|
||||
return SimplePropertyMap::operator[](key.upper());
|
||||
}
|
||||
|
||||
bool PropertyMap::operator==(const PropertyMap &other) const
|
||||
{
|
||||
for(ConstIterator it = other.begin(); it != other.end(); ++it) {
|
||||
ConstIterator thisFind = find(it->first);
|
||||
if( thisFind == end() || (thisFind->second != it->second) )
|
||||
return false;
|
||||
}
|
||||
for(ConstIterator it = begin(); it != end(); ++it) {
|
||||
ConstIterator otherFind = other.find(it->first);
|
||||
if( otherFind == other.end() || (otherFind->second != it->second) )
|
||||
return false;
|
||||
}
|
||||
return unsupported == other.unsupported;
|
||||
}
|
||||
|
||||
bool PropertyMap::operator!=(const PropertyMap &other) const
|
||||
{
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
String PropertyMap::toString() const
|
||||
{
|
||||
String ret;
|
||||
|
||||
for(ConstIterator it = begin(); it != end(); ++it)
|
||||
ret += it->first+"="+it->second.toString(", ") + "\n";
|
||||
if(!unsupported.isEmpty())
|
||||
ret += "Unsupported Data: " + unsupported.toString(", ") + "\n";
|
||||
return ret;
|
||||
}
|
||||
|
||||
void PropertyMap::removeEmpty()
|
||||
{
|
||||
PropertyMap m;
|
||||
for(ConstIterator it = begin(); it != end(); ++it) {
|
||||
if(!it->second.isEmpty())
|
||||
m.insert(it->first, it->second);
|
||||
}
|
||||
*this = m;
|
||||
}
|
||||
|
||||
StringList &PropertyMap::unsupportedData()
|
||||
{
|
||||
return unsupported;
|
||||
}
|
||||
|
||||
const StringList &PropertyMap::unsupportedData() const
|
||||
{
|
||||
return unsupported;
|
||||
}
|
||||
237
3rdparty/taglib/toolkit/tpropertymap.h
vendored
Normal file
237
3rdparty/taglib/toolkit/tpropertymap.h
vendored
Normal file
@@ -0,0 +1,237 @@
|
||||
/***************************************************************************
|
||||
copyright : (C) 2012 by Michael Helmling
|
||||
email : helmling@mathematik.uni-kl.de
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* 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_PROPERTYMAP_H_
|
||||
#define TAGLIB_PROPERTYMAP_H_
|
||||
|
||||
#include "tmap.h"
|
||||
#include "tstringlist.h"
|
||||
|
||||
namespace TagLib {
|
||||
|
||||
typedef Map<String,StringList> SimplePropertyMap;
|
||||
|
||||
//! A map for format-independent <key,valuelist> tag representations.
|
||||
|
||||
/*!
|
||||
* This map implements a generic representation of textual audio metadata
|
||||
* ("tags") realized as pairs of a case-insensitive key
|
||||
* and a nonempty list of corresponding values, each value being an arbitrary
|
||||
* unicode String.
|
||||
*
|
||||
* Note that most metadata formats pose additional conditions on the tag keys. The
|
||||
* most popular ones (Vorbis, APE, ID3v2) should support all ASCII only words of
|
||||
* length between 2 and 16.
|
||||
*
|
||||
* This class can contain any tags, but here is a list of "well-known" tags that
|
||||
* you might want to use:
|
||||
*
|
||||
* Basic tags:
|
||||
*
|
||||
* - TITLE
|
||||
* - ALBUM
|
||||
* - ARTIST
|
||||
* - ALBUMARTIST
|
||||
* - SUBTITLE
|
||||
* - TRACKNUMBER
|
||||
* - DISCNUMBER
|
||||
* - DATE
|
||||
* - ORIGINALDATE
|
||||
* - GENRE
|
||||
* - COMMENT
|
||||
*
|
||||
* Sort names:
|
||||
*
|
||||
* - TITLESORT
|
||||
* - ALBUMSORT
|
||||
* - ARTISTSORT
|
||||
* - ALBUMARTISTSORT
|
||||
*
|
||||
* Credits:
|
||||
*
|
||||
* - COMPOSER
|
||||
* - LYRICIST
|
||||
* - CONDUCTOR
|
||||
* - REMIXER
|
||||
* - PERFORMER:<XXXX>
|
||||
*
|
||||
* Other tags:
|
||||
*
|
||||
* - ISRC
|
||||
* - ASIN
|
||||
* - BPM
|
||||
* - COPYRIGHT
|
||||
* - ENCODEDBY
|
||||
* - MOOD
|
||||
* - COMMENT
|
||||
* - MEDIA
|
||||
* - LABEL
|
||||
* - CATALOGNUMBER
|
||||
* - BARCODE
|
||||
*
|
||||
* MusicBrainz identifiers:
|
||||
*
|
||||
* - MUSICBRAINZ_TRACKID
|
||||
* - MUSICBRAINZ_ALBUMID
|
||||
* - MUSICBRAINZ_RELEASEGROUPID
|
||||
* - MUSICBRAINZ_WORKID
|
||||
* - MUSICBRAINZ_ARTISTID
|
||||
* - MUSICBRAINZ_ALBUMARTISTID
|
||||
* - ACOUSTID_ID
|
||||
* - ACOUSTID_FINGERPRINT
|
||||
* - MUSICIP_PUID
|
||||
*
|
||||
*/
|
||||
|
||||
class TAGLIB_EXPORT PropertyMap: public SimplePropertyMap
|
||||
{
|
||||
public:
|
||||
|
||||
typedef SimplePropertyMap::Iterator Iterator;
|
||||
typedef SimplePropertyMap::ConstIterator ConstIterator;
|
||||
|
||||
PropertyMap();
|
||||
|
||||
PropertyMap(const PropertyMap &m);
|
||||
|
||||
/*!
|
||||
* Creates a PropertyMap initialized from a SimplePropertyMap. Copies all
|
||||
* entries from \a m that have valid keys.
|
||||
* Invalid keys will be appended to the unsupportedData() list.
|
||||
*/
|
||||
PropertyMap(const SimplePropertyMap &m);
|
||||
|
||||
virtual ~PropertyMap();
|
||||
|
||||
/*!
|
||||
* Inserts \a values under \a key in the map. If \a key already exists,
|
||||
* then \a values will be appended to the existing StringList.
|
||||
* The returned value indicates success, i.e. whether \a key is a
|
||||
* valid key.
|
||||
*/
|
||||
bool insert(const String &key, const StringList &values);
|
||||
|
||||
/*!
|
||||
* Replaces any existing values for \a key with the given \a values,
|
||||
* and simply insert them if \a key did not exist before.
|
||||
* The returned value indicates success, i.e. whether \a key is a
|
||||
* valid key.
|
||||
*/
|
||||
bool replace(const String &key, const StringList &values);
|
||||
|
||||
/*!
|
||||
* Find the first occurrence of \a key.
|
||||
*/
|
||||
Iterator find(const String &key);
|
||||
|
||||
/*!
|
||||
* Find the first occurrence of \a key.
|
||||
*/
|
||||
ConstIterator find(const String &key) const;
|
||||
|
||||
/*!
|
||||
* Returns true if the map contains values for \a key.
|
||||
*/
|
||||
bool contains(const String &key) const;
|
||||
|
||||
/*!
|
||||
* Returns true if this map contains all keys of \a other
|
||||
* and the values coincide for that keys. Does not take
|
||||
* the unsupportedData list into account.
|
||||
*/
|
||||
bool contains(const PropertyMap &other) const;
|
||||
|
||||
/*!
|
||||
* Erase the \a key and its values from the map.
|
||||
*/
|
||||
PropertyMap &erase(const String &key);
|
||||
|
||||
/*!
|
||||
* Erases from this map all keys that appear in \a other.
|
||||
*/
|
||||
PropertyMap &erase(const PropertyMap &other);
|
||||
|
||||
/*!
|
||||
* Merge the contents of \a other into this PropertyMap.
|
||||
* If a key is contained in both maps, the values of the second
|
||||
* are appended to that of the first.
|
||||
* The unsupportedData() lists are concatenated as well.
|
||||
*/
|
||||
PropertyMap &merge(const PropertyMap &other);
|
||||
|
||||
/*!
|
||||
* Returns a reference to the value associated with \a key.
|
||||
*
|
||||
* \note: If \a key is not contained in the map, an empty
|
||||
* StringList is returned without error.
|
||||
*/
|
||||
const StringList &operator[](const String &key) const;
|
||||
|
||||
/*!
|
||||
* Returns a reference to the value associated with \a key.
|
||||
*
|
||||
* \note: If \a key is not contained in the map, an empty
|
||||
* StringList is returned. You can also directly add entries
|
||||
* by using this function as an lvalue.
|
||||
*/
|
||||
StringList &operator[](const String &key);
|
||||
|
||||
/*!
|
||||
* Returns true if and only if \other has the same contents as this map.
|
||||
*/
|
||||
bool operator==(const PropertyMap &other) const;
|
||||
|
||||
/*!
|
||||
* Returns false if and only \other has the same contents as this map.
|
||||
*/
|
||||
bool operator!=(const PropertyMap &other) const;
|
||||
|
||||
/*!
|
||||
* If a PropertyMap is read from a File object using File::properties(),
|
||||
* the StringList returned from this function will represent metadata
|
||||
* that could not be parsed into the PropertyMap representation. This could
|
||||
* be e.g. binary data, unknown ID3 frames, etc.
|
||||
* You can remove items from the returned list, which tells TagLib to remove
|
||||
* those unsupported elements if you call File::setProperties() with the
|
||||
* same PropertyMap as argument.
|
||||
*/
|
||||
StringList &unsupportedData();
|
||||
const StringList &unsupportedData() const;
|
||||
|
||||
/*!
|
||||
* Removes all entries which have an empty value list.
|
||||
*/
|
||||
void removeEmpty();
|
||||
|
||||
String toString() const;
|
||||
|
||||
private:
|
||||
|
||||
|
||||
StringList unsupported;
|
||||
};
|
||||
|
||||
}
|
||||
#endif /* TAGLIB_PROPERTYMAP_H_ */
|
||||
101
3rdparty/taglib/toolkit/trefcounter.cpp
vendored
Normal file
101
3rdparty/taglib/toolkit/trefcounter.cpp
vendored
Normal file
@@ -0,0 +1,101 @@
|
||||
/***************************************************************************
|
||||
copyright : (C) 2013 by Tsuda Kageyu
|
||||
email : tsuda.kageyu@gmail.com
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* 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/ *
|
||||
***************************************************************************/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include "trefcounter.h"
|
||||
|
||||
#if defined(HAVE_STD_ATOMIC)
|
||||
# include <atomic>
|
||||
# define ATOMIC_INT std::atomic_int
|
||||
# define ATOMIC_INC(x) (++x)
|
||||
# define ATOMIC_DEC(x) (--x)
|
||||
#elif defined(HAVE_GCC_ATOMIC)
|
||||
# define ATOMIC_INT int
|
||||
# define ATOMIC_INC(x) __sync_add_and_fetch(&x, 1)
|
||||
# define ATOMIC_DEC(x) __sync_sub_and_fetch(&x, 1)
|
||||
#elif defined(HAVE_WIN_ATOMIC)
|
||||
# if !defined(NOMINMAX)
|
||||
# define NOMINMAX
|
||||
# endif
|
||||
# include <windows.h>
|
||||
# define ATOMIC_INT long
|
||||
# define ATOMIC_INC(x) InterlockedIncrement(&x)
|
||||
# define ATOMIC_DEC(x) InterlockedDecrement(&x)
|
||||
#elif defined(HAVE_MAC_ATOMIC)
|
||||
# include <libkern/OSAtomic.h>
|
||||
# define ATOMIC_INT int32_t
|
||||
# define ATOMIC_INC(x) OSAtomicIncrement32Barrier(&x)
|
||||
# define ATOMIC_DEC(x) OSAtomicDecrement32Barrier(&x)
|
||||
#elif defined(HAVE_IA64_ATOMIC)
|
||||
# include <ia64intrin.h>
|
||||
# define ATOMIC_INT int
|
||||
# define ATOMIC_INC(x) __sync_add_and_fetch(&x, 1)
|
||||
# define ATOMIC_DEC(x) __sync_sub_and_fetch(&x, 1)
|
||||
#else
|
||||
# define ATOMIC_INT int
|
||||
# define ATOMIC_INC(x) (++x)
|
||||
# define ATOMIC_DEC(x) (--x)
|
||||
#endif
|
||||
|
||||
namespace TagLib
|
||||
{
|
||||
|
||||
class RefCounter::RefCounterPrivate
|
||||
{
|
||||
public:
|
||||
RefCounterPrivate() :
|
||||
refCount(1) {}
|
||||
|
||||
volatile ATOMIC_INT refCount;
|
||||
};
|
||||
|
||||
RefCounter::RefCounter() :
|
||||
d(new RefCounterPrivate())
|
||||
{
|
||||
}
|
||||
|
||||
RefCounter::~RefCounter()
|
||||
{
|
||||
delete d;
|
||||
}
|
||||
|
||||
void RefCounter::ref()
|
||||
{
|
||||
ATOMIC_INC(d->refCount);
|
||||
}
|
||||
|
||||
bool RefCounter::deref()
|
||||
{
|
||||
return (ATOMIC_DEC(d->refCount) == 0);
|
||||
}
|
||||
|
||||
int RefCounter::count() const
|
||||
{
|
||||
return static_cast<int>(d->refCount);
|
||||
}
|
||||
}
|
||||
114
3rdparty/taglib/toolkit/trefcounter.h
vendored
Normal file
114
3rdparty/taglib/toolkit/trefcounter.h
vendored
Normal file
@@ -0,0 +1,114 @@
|
||||
/***************************************************************************
|
||||
copyright : (C) 2013 by Tsuda Kageyu
|
||||
email : tsuda.kageyu@gmail.com
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* 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_REFCOUNTER_H
|
||||
#define TAGLIB_REFCOUNTER_H
|
||||
|
||||
#include "taglib_export.h"
|
||||
#include "taglib.h"
|
||||
|
||||
#ifdef __APPLE__
|
||||
# define OSATOMIC_DEPRECATED 0
|
||||
# include <libkern/OSAtomic.h>
|
||||
# define TAGLIB_ATOMIC_MAC
|
||||
#elif defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__)
|
||||
# ifndef NOMINMAX
|
||||
# define NOMINMAX
|
||||
# endif
|
||||
# include <windows.h>
|
||||
# define TAGLIB_ATOMIC_WIN
|
||||
#elif defined (__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 401) \
|
||||
&& (defined(__i386__) || defined(__i486__) || defined(__i586__) || \
|
||||
defined(__i686__) || defined(__x86_64) || defined(__ia64)) \
|
||||
&& !defined(__INTEL_COMPILER)
|
||||
# define TAGLIB_ATOMIC_GCC
|
||||
#elif defined(__ia64) && defined(__INTEL_COMPILER)
|
||||
# include <ia64intrin.h>
|
||||
# define TAGLIB_ATOMIC_GCC
|
||||
#endif
|
||||
|
||||
#ifndef DO_NOT_DOCUMENT // Tell Doxygen to skip this class.
|
||||
/*!
|
||||
* \internal
|
||||
* This is just used as a base class for shared classes in TagLib.
|
||||
*
|
||||
* \warning This <b>is not</b> part of the TagLib public API!
|
||||
*/
|
||||
namespace TagLib
|
||||
{
|
||||
|
||||
class TAGLIB_EXPORT RefCounter
|
||||
{
|
||||
public:
|
||||
RefCounter();
|
||||
virtual ~RefCounter();
|
||||
|
||||
void ref();
|
||||
bool deref();
|
||||
int count() const;
|
||||
|
||||
private:
|
||||
class RefCounterPrivate;
|
||||
RefCounterPrivate *d;
|
||||
};
|
||||
|
||||
// BIC this old class is needed by tlist.tcc and tmap.tcc
|
||||
class RefCounterOld
|
||||
{
|
||||
public:
|
||||
RefCounterOld() : refCount(1) {}
|
||||
|
||||
#ifdef TAGLIB_ATOMIC_MAC
|
||||
void ref() { OSAtomicIncrement32Barrier(const_cast<int32_t*>(&refCount)); }
|
||||
bool deref() { return ! OSAtomicDecrement32Barrier(const_cast<int32_t*>(&refCount)); }
|
||||
int32_t count() { return refCount; }
|
||||
private:
|
||||
volatile int32_t refCount;
|
||||
#elif defined(TAGLIB_ATOMIC_WIN)
|
||||
void ref() { InterlockedIncrement(&refCount); }
|
||||
bool deref() { return ! InterlockedDecrement(&refCount); }
|
||||
long count() { return refCount; }
|
||||
private:
|
||||
volatile long refCount;
|
||||
#elif defined(TAGLIB_ATOMIC_GCC)
|
||||
void ref() { __sync_add_and_fetch(&refCount, 1); }
|
||||
bool deref() { return ! __sync_sub_and_fetch(&refCount, 1); }
|
||||
int count() { return refCount; }
|
||||
private:
|
||||
volatile int refCount;
|
||||
#else
|
||||
void ref() { refCount++; }
|
||||
bool deref() { return ! --refCount; }
|
||||
int count() { return refCount; }
|
||||
private:
|
||||
unsigned int refCount;
|
||||
#endif
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // DO_NOT_DOCUMENT
|
||||
#endif
|
||||
|
||||
747
3rdparty/taglib/toolkit/tstring.cpp
vendored
Normal file
747
3rdparty/taglib/toolkit/tstring.cpp
vendored
Normal file
@@ -0,0 +1,747 @@
|
||||
/***************************************************************************
|
||||
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/ *
|
||||
***************************************************************************/
|
||||
|
||||
#include <cerrno>
|
||||
#include <climits>
|
||||
|
||||
#include <utf8-cpp/checked.h>
|
||||
|
||||
#include <tdebug.h>
|
||||
#include <tstringlist.h>
|
||||
#include <trefcounter.h>
|
||||
#include <tutils.h>
|
||||
|
||||
#include "tstring.h"
|
||||
|
||||
namespace
|
||||
{
|
||||
using namespace TagLib;
|
||||
|
||||
// Returns the native format of std::wstring.
|
||||
String::Type wcharByteOrder()
|
||||
{
|
||||
if(Utils::systemByteOrder() == Utils::LittleEndian)
|
||||
return String::UTF16LE;
|
||||
else
|
||||
return String::UTF16BE;
|
||||
}
|
||||
|
||||
// Converts a Latin-1 string into UTF-16(without BOM/CPU byte order)
|
||||
// and copies it to the internal buffer.
|
||||
void copyFromLatin1(std::wstring &data, const char *s, size_t length)
|
||||
{
|
||||
data.resize(length);
|
||||
|
||||
for(size_t i = 0; i < length; ++i)
|
||||
data[i] = static_cast<unsigned char>(s[i]);
|
||||
}
|
||||
|
||||
// Converts a UTF-8 string into UTF-16(without BOM/CPU byte order)
|
||||
// and copies it to the internal buffer.
|
||||
void copyFromUTF8(std::wstring &data, const char *s, size_t length)
|
||||
{
|
||||
data.resize(length);
|
||||
|
||||
try {
|
||||
const std::wstring::iterator dstEnd = utf8::utf8to16(s, s + length, data.begin());
|
||||
data.resize(dstEnd - data.begin());
|
||||
}
|
||||
catch(const utf8::exception &e) {
|
||||
const String message(e.what());
|
||||
debug("String::copyFromUTF8() - UTF8-CPP error: " + message);
|
||||
data.clear();
|
||||
}
|
||||
}
|
||||
|
||||
// Helper functions to read a UTF-16 character from an array.
|
||||
template <typename T>
|
||||
unsigned short nextUTF16(const T **p);
|
||||
|
||||
template <>
|
||||
unsigned short nextUTF16<wchar_t>(const wchar_t **p)
|
||||
{
|
||||
return static_cast<unsigned short>(*(*p)++);
|
||||
}
|
||||
|
||||
template <>
|
||||
unsigned short nextUTF16<char>(const char **p)
|
||||
{
|
||||
union {
|
||||
unsigned short w;
|
||||
char c[2];
|
||||
} u;
|
||||
u.c[0] = *(*p)++;
|
||||
u.c[1] = *(*p)++;
|
||||
return u.w;
|
||||
}
|
||||
|
||||
// Converts a UTF-16 (with BOM), UTF-16LE or UTF16-BE string into
|
||||
// UTF-16(without BOM/CPU byte order) and copies it to the internal buffer.
|
||||
template <typename T>
|
||||
void copyFromUTF16(std::wstring &data, const T *s, size_t length, String::Type t)
|
||||
{
|
||||
bool swap;
|
||||
if(t == String::UTF16) {
|
||||
if(length < 1) {
|
||||
debug("String::copyFromUTF16() - Invalid UTF16 string. Too short to have a BOM.");
|
||||
return;
|
||||
}
|
||||
|
||||
const unsigned short bom = nextUTF16(&s);
|
||||
if(bom == 0xfeff)
|
||||
swap = false; // Same as CPU endian. No need to swap bytes.
|
||||
else if(bom == 0xfffe)
|
||||
swap = true; // Not same as CPU endian. Need to swap bytes.
|
||||
else {
|
||||
debug("String::copyFromUTF16() - Invalid UTF16 string. BOM is broken.");
|
||||
return;
|
||||
}
|
||||
|
||||
length--;
|
||||
}
|
||||
else {
|
||||
swap = (t != wcharByteOrder());
|
||||
}
|
||||
|
||||
data.resize(length);
|
||||
for(size_t i = 0; i < length; ++i) {
|
||||
const unsigned short c = nextUTF16(&s);
|
||||
if(swap)
|
||||
data[i] = Utils::byteSwap(c);
|
||||
else
|
||||
data[i] = c;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
namespace TagLib {
|
||||
|
||||
class String::StringPrivate : public RefCounter
|
||||
{
|
||||
public:
|
||||
StringPrivate() :
|
||||
RefCounter() {}
|
||||
|
||||
/*!
|
||||
* Stores string in UTF-16. The byte order depends on the CPU endian.
|
||||
*/
|
||||
TagLib::wstring data;
|
||||
|
||||
/*!
|
||||
* This is only used to hold the the most recent value of toCString().
|
||||
*/
|
||||
std::string cstring;
|
||||
};
|
||||
|
||||
String String::null;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// public members
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
String::String() :
|
||||
d(new StringPrivate())
|
||||
{
|
||||
}
|
||||
|
||||
String::String(const String &s) :
|
||||
d(s.d)
|
||||
{
|
||||
d->ref();
|
||||
}
|
||||
|
||||
String::String(const std::string &s, Type t) :
|
||||
d(new StringPrivate())
|
||||
{
|
||||
if(t == Latin1)
|
||||
copyFromLatin1(d->data, s.c_str(), s.length());
|
||||
else if(t == String::UTF8)
|
||||
copyFromUTF8(d->data, s.c_str(), s.length());
|
||||
else {
|
||||
debug("String::String() -- std::string should not contain UTF16.");
|
||||
}
|
||||
}
|
||||
|
||||
String::String(const wstring &s, Type t) :
|
||||
d(new StringPrivate())
|
||||
{
|
||||
if(t == UTF16 || t == UTF16BE || t == UTF16LE) {
|
||||
// This looks ugly but needed for the compatibility with TagLib1.8.
|
||||
// Should be removed in TabLib2.0.
|
||||
if (t == UTF16BE)
|
||||
t = wcharByteOrder();
|
||||
else if (t == UTF16LE)
|
||||
t = (wcharByteOrder() == UTF16LE ? UTF16BE : UTF16LE);
|
||||
|
||||
copyFromUTF16(d->data, s.c_str(), s.length(), t);
|
||||
}
|
||||
else {
|
||||
debug("String::String() -- TagLib::wstring should not contain Latin1 or UTF-8.");
|
||||
}
|
||||
}
|
||||
|
||||
String::String(const wchar_t *s, Type t) :
|
||||
d(new StringPrivate())
|
||||
{
|
||||
if(t == UTF16 || t == UTF16BE || t == UTF16LE) {
|
||||
// This looks ugly but needed for the compatibility with TagLib1.8.
|
||||
// Should be removed in TabLib2.0.
|
||||
if (t == UTF16BE)
|
||||
t = wcharByteOrder();
|
||||
else if (t == UTF16LE)
|
||||
t = (wcharByteOrder() == UTF16LE ? UTF16BE : UTF16LE);
|
||||
|
||||
copyFromUTF16(d->data, s, ::wcslen(s), t);
|
||||
}
|
||||
else {
|
||||
debug("String::String() -- const wchar_t * should not contain Latin1 or UTF-8.");
|
||||
}
|
||||
}
|
||||
|
||||
String::String(const char *s, Type t) :
|
||||
d(new StringPrivate())
|
||||
{
|
||||
if(t == Latin1)
|
||||
copyFromLatin1(d->data, s, ::strlen(s));
|
||||
else if(t == String::UTF8)
|
||||
copyFromUTF8(d->data, s, ::strlen(s));
|
||||
else {
|
||||
debug("String::String() -- const char * should not contain UTF16.");
|
||||
}
|
||||
}
|
||||
|
||||
String::String(wchar_t c, Type t) :
|
||||
d(new StringPrivate())
|
||||
{
|
||||
if(t == UTF16 || t == UTF16BE || t == UTF16LE)
|
||||
copyFromUTF16(d->data, &c, 1, t);
|
||||
else {
|
||||
debug("String::String() -- wchar_t should not contain Latin1 or UTF-8.");
|
||||
}
|
||||
}
|
||||
|
||||
String::String(char c, Type t) :
|
||||
d(new StringPrivate())
|
||||
{
|
||||
if(t == Latin1)
|
||||
copyFromLatin1(d->data, &c, 1);
|
||||
else if(t == String::UTF8)
|
||||
copyFromUTF8(d->data, &c, 1);
|
||||
else {
|
||||
debug("String::String() -- char should not contain UTF16.");
|
||||
}
|
||||
}
|
||||
|
||||
String::String(const ByteVector &v, Type t) :
|
||||
d(new StringPrivate())
|
||||
{
|
||||
if(v.isEmpty())
|
||||
return;
|
||||
|
||||
if(t == Latin1)
|
||||
copyFromLatin1(d->data, v.data(), v.size());
|
||||
else if(t == UTF8)
|
||||
copyFromUTF8(d->data, v.data(), v.size());
|
||||
else
|
||||
copyFromUTF16(d->data, v.data(), v.size() / 2, t);
|
||||
|
||||
// If we hit a null in the ByteVector, shrink the string again.
|
||||
d->data.resize(::wcslen(d->data.c_str()));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
String::~String()
|
||||
{
|
||||
if(d->deref())
|
||||
delete d;
|
||||
}
|
||||
|
||||
std::string String::to8Bit(bool unicode) const
|
||||
{
|
||||
const ByteVector v = data(unicode ? UTF8 : Latin1);
|
||||
return std::string(v.data(), v.size());
|
||||
}
|
||||
|
||||
TagLib::wstring String::toWString() const
|
||||
{
|
||||
return d->data;
|
||||
}
|
||||
|
||||
const char *String::toCString(bool unicode) const
|
||||
{
|
||||
d->cstring = to8Bit(unicode);
|
||||
return d->cstring.c_str();
|
||||
}
|
||||
|
||||
const wchar_t *String::toCWString() const
|
||||
{
|
||||
return d->data.c_str();
|
||||
}
|
||||
|
||||
String::Iterator String::begin()
|
||||
{
|
||||
detach();
|
||||
return d->data.begin();
|
||||
}
|
||||
|
||||
String::ConstIterator String::begin() const
|
||||
{
|
||||
return d->data.begin();
|
||||
}
|
||||
|
||||
String::Iterator String::end()
|
||||
{
|
||||
detach();
|
||||
return d->data.end();
|
||||
}
|
||||
|
||||
String::ConstIterator String::end() const
|
||||
{
|
||||
return d->data.end();
|
||||
}
|
||||
|
||||
int String::find(const String &s, int offset) const
|
||||
{
|
||||
return static_cast<int>(d->data.find(s.d->data, offset));
|
||||
}
|
||||
|
||||
int String::rfind(const String &s, int offset) const
|
||||
{
|
||||
return static_cast<int>(d->data.rfind(s.d->data, offset));
|
||||
}
|
||||
|
||||
StringList String::split(const String &separator) const
|
||||
{
|
||||
StringList list;
|
||||
for(int index = 0;;) {
|
||||
int sep = find(separator, index);
|
||||
if(sep < 0) {
|
||||
list.append(substr(index, size() - index));
|
||||
break;
|
||||
}
|
||||
else {
|
||||
list.append(substr(index, sep - index));
|
||||
index = sep + separator.size();
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
bool String::startsWith(const String &s) const
|
||||
{
|
||||
if(s.length() > length())
|
||||
return false;
|
||||
|
||||
return substr(0, s.length()) == s;
|
||||
}
|
||||
|
||||
String String::substr(unsigned int position, unsigned int n) const
|
||||
{
|
||||
if(position == 0 && n >= size())
|
||||
return *this;
|
||||
else
|
||||
return String(d->data.substr(position, n));
|
||||
}
|
||||
|
||||
String &String::append(const String &s)
|
||||
{
|
||||
detach();
|
||||
d->data += s.d->data;
|
||||
return *this;
|
||||
}
|
||||
|
||||
String & String::clear()
|
||||
{
|
||||
*this = String();
|
||||
return *this;
|
||||
}
|
||||
|
||||
String String::upper() const
|
||||
{
|
||||
String s;
|
||||
s.d->data.reserve(size());
|
||||
|
||||
for(ConstIterator it = begin(); it != end(); ++it) {
|
||||
if(*it >= 'a' && *it <= 'z')
|
||||
s.d->data.push_back(*it + 'A' - 'a');
|
||||
else
|
||||
s.d->data.push_back(*it);
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
unsigned int String::size() const
|
||||
{
|
||||
return static_cast<unsigned int>(d->data.size());
|
||||
}
|
||||
|
||||
unsigned int String::length() const
|
||||
{
|
||||
return size();
|
||||
}
|
||||
|
||||
bool String::isEmpty() const
|
||||
{
|
||||
return d->data.empty();
|
||||
}
|
||||
|
||||
bool String::isNull() const
|
||||
{
|
||||
return d == null.d;
|
||||
}
|
||||
|
||||
ByteVector String::data(Type t) const
|
||||
{
|
||||
switch(t)
|
||||
{
|
||||
case Latin1:
|
||||
{
|
||||
ByteVector v(size(), 0);
|
||||
char *p = v.data();
|
||||
|
||||
for(ConstIterator it = begin(); it != end(); ++it)
|
||||
*p++ = static_cast<char>(*it);
|
||||
|
||||
return v;
|
||||
}
|
||||
case UTF8:
|
||||
{
|
||||
ByteVector v(size() * 4, 0);
|
||||
|
||||
try {
|
||||
const ByteVector::Iterator dstEnd = utf8::utf16to8(begin(), end(), v.begin());
|
||||
v.resize(static_cast<unsigned int>(dstEnd - v.begin()));
|
||||
}
|
||||
catch(const utf8::exception &e) {
|
||||
const String message(e.what());
|
||||
debug("String::data() - UTF8-CPP error: " + message);
|
||||
v.clear();
|
||||
}
|
||||
|
||||
return v;
|
||||
}
|
||||
case UTF16:
|
||||
{
|
||||
ByteVector v(2 + size() * 2, 0);
|
||||
char *p = v.data();
|
||||
|
||||
// We use little-endian encoding here and need a BOM.
|
||||
|
||||
*p++ = '\xff';
|
||||
*p++ = '\xfe';
|
||||
|
||||
for(ConstIterator it = begin(); it != end(); ++it) {
|
||||
*p++ = static_cast<char>(*it & 0xff);
|
||||
*p++ = static_cast<char>(*it >> 8);
|
||||
}
|
||||
|
||||
return v;
|
||||
}
|
||||
case UTF16BE:
|
||||
{
|
||||
ByteVector v(size() * 2, 0);
|
||||
char *p = v.data();
|
||||
|
||||
for(ConstIterator it = begin(); it != end(); ++it) {
|
||||
*p++ = static_cast<char>(*it >> 8);
|
||||
*p++ = static_cast<char>(*it & 0xff);
|
||||
}
|
||||
|
||||
return v;
|
||||
}
|
||||
case UTF16LE:
|
||||
{
|
||||
ByteVector v(size() * 2, 0);
|
||||
char *p = v.data();
|
||||
|
||||
for(ConstIterator it = begin(); it != end(); ++it) {
|
||||
*p++ = static_cast<char>(*it & 0xff);
|
||||
*p++ = static_cast<char>(*it >> 8);
|
||||
}
|
||||
|
||||
return v;
|
||||
}
|
||||
default:
|
||||
{
|
||||
debug("String::data() - Invalid Type value.");
|
||||
return ByteVector();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int String::toInt() const
|
||||
{
|
||||
return toInt(0);
|
||||
}
|
||||
|
||||
int String::toInt(bool *ok) const
|
||||
{
|
||||
const wchar_t *begin = d->data.c_str();
|
||||
wchar_t *end;
|
||||
errno = 0;
|
||||
const long value = ::wcstol(begin, &end, 10);
|
||||
|
||||
// Has wcstol() consumed the entire string and not overflowed?
|
||||
if(ok) {
|
||||
*ok = (errno == 0 && end > begin && *end == L'\0');
|
||||
*ok = (*ok && value > INT_MIN && value < INT_MAX);
|
||||
}
|
||||
|
||||
return static_cast<int>(value);
|
||||
}
|
||||
|
||||
String String::stripWhiteSpace() const
|
||||
{
|
||||
static const wchar_t *WhiteSpaceChars = L"\t\n\f\r ";
|
||||
|
||||
const size_t pos1 = d->data.find_first_not_of(WhiteSpaceChars);
|
||||
if(pos1 == std::wstring::npos)
|
||||
return String();
|
||||
|
||||
const size_t pos2 = d->data.find_last_not_of(WhiteSpaceChars);
|
||||
return substr(static_cast<unsigned int>(pos1), static_cast<unsigned int>(pos2 - pos1 + 1));
|
||||
}
|
||||
|
||||
bool String::isLatin1() const
|
||||
{
|
||||
for(ConstIterator it = begin(); it != end(); ++it) {
|
||||
if(*it >= 256)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool String::isAscii() const
|
||||
{
|
||||
for(ConstIterator it = begin(); it != end(); ++it) {
|
||||
if(*it >= 128)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
String String::number(int n) // static
|
||||
{
|
||||
return Utils::formatString("%d", n);
|
||||
}
|
||||
|
||||
wchar_t &String::operator[](int i)
|
||||
{
|
||||
detach();
|
||||
return d->data[i];
|
||||
}
|
||||
|
||||
const wchar_t &String::operator[](int i) const
|
||||
{
|
||||
return d->data[i];
|
||||
}
|
||||
|
||||
bool String::operator==(const String &s) const
|
||||
{
|
||||
return (d == s.d || d->data == s.d->data);
|
||||
}
|
||||
|
||||
bool String::operator!=(const String &s) const
|
||||
{
|
||||
return !(*this == s);
|
||||
}
|
||||
|
||||
bool String::operator==(const char *s) const
|
||||
{
|
||||
const wchar_t *p = toCWString();
|
||||
|
||||
while(*p != L'\0' || *s != '\0') {
|
||||
if(*p++ != static_cast<unsigned char>(*s++))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool String::operator!=(const char *s) const
|
||||
{
|
||||
return !(*this == s);
|
||||
}
|
||||
|
||||
bool String::operator==(const wchar_t *s) const
|
||||
{
|
||||
return (d->data == s);
|
||||
}
|
||||
|
||||
bool String::operator!=(const wchar_t *s) const
|
||||
{
|
||||
return !(*this == s);
|
||||
}
|
||||
|
||||
String &String::operator+=(const String &s)
|
||||
{
|
||||
detach();
|
||||
|
||||
d->data += s.d->data;
|
||||
return *this;
|
||||
}
|
||||
|
||||
String &String::operator+=(const wchar_t *s)
|
||||
{
|
||||
detach();
|
||||
|
||||
d->data += s;
|
||||
return *this;
|
||||
}
|
||||
|
||||
String &String::operator+=(const char *s)
|
||||
{
|
||||
detach();
|
||||
|
||||
for(int i = 0; s[i] != 0; i++)
|
||||
d->data += static_cast<unsigned char>(s[i]);
|
||||
return *this;
|
||||
}
|
||||
|
||||
String &String::operator+=(wchar_t c)
|
||||
{
|
||||
detach();
|
||||
|
||||
d->data += c;
|
||||
return *this;
|
||||
}
|
||||
|
||||
String &String::operator+=(char c)
|
||||
{
|
||||
detach();
|
||||
|
||||
d->data += static_cast<unsigned char>(c);
|
||||
return *this;
|
||||
}
|
||||
|
||||
String &String::operator=(const String &s)
|
||||
{
|
||||
String(s).swap(*this);
|
||||
return *this;
|
||||
}
|
||||
|
||||
String &String::operator=(const std::string &s)
|
||||
{
|
||||
String(s).swap(*this);
|
||||
return *this;
|
||||
}
|
||||
|
||||
String &String::operator=(const wstring &s)
|
||||
{
|
||||
String(s).swap(*this);
|
||||
return *this;
|
||||
}
|
||||
|
||||
String &String::operator=(const wchar_t *s)
|
||||
{
|
||||
String(s).swap(*this);
|
||||
return *this;
|
||||
}
|
||||
|
||||
String &String::operator=(char c)
|
||||
{
|
||||
String(c).swap(*this);
|
||||
return *this;
|
||||
}
|
||||
|
||||
String &String::operator=(wchar_t c)
|
||||
{
|
||||
String(c, wcharByteOrder()).swap(*this);
|
||||
return *this;
|
||||
}
|
||||
|
||||
String &String::operator=(const char *s)
|
||||
{
|
||||
String(s).swap(*this);
|
||||
return *this;
|
||||
}
|
||||
|
||||
String &String::operator=(const ByteVector &v)
|
||||
{
|
||||
String(v).swap(*this);
|
||||
return *this;
|
||||
}
|
||||
|
||||
void String::swap(String &s)
|
||||
{
|
||||
using std::swap;
|
||||
|
||||
swap(d, s.d);
|
||||
}
|
||||
|
||||
bool String::operator<(const String &s) const
|
||||
{
|
||||
return (d->data < s.d->data);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// protected members
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void String::detach()
|
||||
{
|
||||
if(d->count() > 1)
|
||||
String(d->data.c_str()).swap(*this);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// private members
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
const String::Type String::WCharByteOrder = wcharByteOrder();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// related non-member functions
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
const TagLib::String operator+(const TagLib::String &s1, const TagLib::String &s2)
|
||||
{
|
||||
TagLib::String s(s1);
|
||||
s.append(s2);
|
||||
return s;
|
||||
}
|
||||
|
||||
const TagLib::String operator+(const char *s1, const TagLib::String &s2)
|
||||
{
|
||||
TagLib::String s(s1);
|
||||
s.append(s2);
|
||||
return s;
|
||||
}
|
||||
|
||||
const TagLib::String operator+(const TagLib::String &s1, const char *s2)
|
||||
{
|
||||
TagLib::String s(s1);
|
||||
s.append(s2);
|
||||
return s;
|
||||
}
|
||||
|
||||
std::ostream &operator<<(std::ostream &s, const TagLib::String &str)
|
||||
{
|
||||
s << str.to8Bit();
|
||||
return s;
|
||||
}
|
||||
|
||||
580
3rdparty/taglib/toolkit/tstring.h
vendored
Normal file
580
3rdparty/taglib/toolkit/tstring.h
vendored
Normal file
@@ -0,0 +1,580 @@
|
||||
/***************************************************************************
|
||||
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_STRING_H
|
||||
#define TAGLIB_STRING_H
|
||||
|
||||
#include "taglib_export.h"
|
||||
#include "taglib.h"
|
||||
#include "tbytevector.h"
|
||||
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
|
||||
/*!
|
||||
* \relates TagLib::String
|
||||
*
|
||||
* Converts a QString to a TagLib::String without a requirement to link to Qt.
|
||||
*
|
||||
* \note consider conversion via usual char-by-char for loop to avoid UTF16->UTF8->UTF16
|
||||
* conversion happening in the background
|
||||
*/
|
||||
|
||||
#if defined(QT_VERSION) && (QT_VERSION >= 0x040000)
|
||||
#define QStringToTString(s) TagLib::String(s.toUtf8().data(), TagLib::String::UTF8)
|
||||
#else
|
||||
#define QStringToTString(s) TagLib::String(s.utf8().data(), TagLib::String::UTF8)
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* \relates TagLib::String
|
||||
*
|
||||
* Converts a TagLib::String to a QString without a requirement to link to Qt.
|
||||
*
|
||||
* \note consider conversion via usual char-by-char for loop to avoid UTF16->UTF8->UTF16
|
||||
* conversion happening in the background
|
||||
*
|
||||
*/
|
||||
|
||||
#define TStringToQString(s) QString::fromUtf8(s.toCString(true))
|
||||
|
||||
namespace TagLib {
|
||||
|
||||
class StringList;
|
||||
|
||||
//! A \e wide string class suitable for unicode.
|
||||
|
||||
/*!
|
||||
* This is an implicitly shared \e wide string. For storage it uses
|
||||
* TagLib::wstring, but as this is an <i>implementation detail</i> this of
|
||||
* course could change. Strings are stored internally as UTF-16(without BOM/
|
||||
* CPU byte order)
|
||||
*
|
||||
* The use of implicit sharing means that copying a string is cheap, the only
|
||||
* \e cost comes into play when the copy is modified. Prior to that the string
|
||||
* just has a pointer to the data of the \e parent String. This also makes
|
||||
* this class suitable as a function return type.
|
||||
*
|
||||
* In addition to adding implicit sharing, this class keeps track of four
|
||||
* possible encodings, which are the four supported by the ID3v2 standard.
|
||||
*/
|
||||
|
||||
class TAGLIB_EXPORT String
|
||||
{
|
||||
public:
|
||||
|
||||
#ifndef DO_NOT_DOCUMENT
|
||||
typedef TagLib::wstring::iterator Iterator;
|
||||
typedef TagLib::wstring::const_iterator ConstIterator;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* The four types of string encodings supported by the ID3v2 specification.
|
||||
* ID3v1 is assumed to be Latin1 and Ogg Vorbis comments use UTF8.
|
||||
*/
|
||||
enum Type {
|
||||
/*!
|
||||
* IS08859-1, or <i>Latin1</i> encoding. 8 bit characters.
|
||||
*/
|
||||
Latin1 = 0,
|
||||
/*!
|
||||
* UTF16 with a <i>byte order mark</i>. 16 bit characters.
|
||||
*/
|
||||
UTF16 = 1,
|
||||
/*!
|
||||
* UTF16 <i>big endian</i>. 16 bit characters. This is the encoding used
|
||||
* internally by TagLib.
|
||||
*/
|
||||
UTF16BE = 2,
|
||||
/*!
|
||||
* UTF8 encoding. Characters are usually 8 bits but can be up to 32.
|
||||
*/
|
||||
UTF8 = 3,
|
||||
/*!
|
||||
* UTF16 <i>little endian</i>. 16 bit characters.
|
||||
*/
|
||||
UTF16LE = 4
|
||||
};
|
||||
|
||||
/*!
|
||||
* Constructs an empty String.
|
||||
*/
|
||||
String();
|
||||
|
||||
/*!
|
||||
* Make a shallow, implicitly shared, copy of \a s. Because this is
|
||||
* implicitly shared, this method is lightweight and suitable for
|
||||
* pass-by-value usage.
|
||||
*/
|
||||
String(const String &s);
|
||||
|
||||
/*!
|
||||
* Makes a deep copy of the data in \a s.
|
||||
*
|
||||
* \note This should only be used with the 8-bit codecs Latin1 and UTF8, when
|
||||
* used with other codecs it will simply print a warning and exit.
|
||||
*/
|
||||
String(const std::string &s, Type t = Latin1);
|
||||
|
||||
/*!
|
||||
* Makes a deep copy of the data in \a s.
|
||||
*
|
||||
* /note If \a t is UTF16LE, the byte order of \a s will be swapped regardless
|
||||
* of the CPU byte order. If UTF16BE, it will not be swapped. This behavior
|
||||
* will be changed in TagLib2.0.
|
||||
*/
|
||||
String(const wstring &s, Type t = UTF16BE);
|
||||
|
||||
/*!
|
||||
* Makes a deep copy of the data in \a s.
|
||||
*
|
||||
* /note If \a t is UTF16LE, the byte order of \a s will be swapped regardless
|
||||
* of the CPU byte order. If UTF16BE, it will not be swapped. This behavior
|
||||
* will be changed in TagLib2.0.
|
||||
*/
|
||||
String(const wchar_t *s, Type t = UTF16BE);
|
||||
|
||||
/*!
|
||||
* Makes a deep copy of the data in \a c.
|
||||
*
|
||||
* \note This should only be used with the 8-bit codecs Latin1 and UTF8, when
|
||||
* used with other codecs it will simply print a warning and exit.
|
||||
*/
|
||||
String(char c, Type t = Latin1);
|
||||
|
||||
/*!
|
||||
* Makes a deep copy of the data in \a c.
|
||||
*/
|
||||
String(wchar_t c, Type t = Latin1);
|
||||
|
||||
/*!
|
||||
* Makes a deep copy of the data in \a s.
|
||||
*
|
||||
* \note This should only be used with the 8-bit codecs Latin1 and UTF8, when
|
||||
* used with other codecs it will simply print a warning and exit.
|
||||
*/
|
||||
String(const char *s, Type t = Latin1);
|
||||
|
||||
/*!
|
||||
* Makes a deep copy of the data in \a v.
|
||||
*/
|
||||
String(const ByteVector &v, Type t = Latin1);
|
||||
|
||||
/*!
|
||||
* Destroys this String instance.
|
||||
*/
|
||||
virtual ~String();
|
||||
|
||||
/*!
|
||||
* Returns a deep copy of this String as an std::string. The returned string
|
||||
* is encoded in UTF8 if \a unicode is true, otherwise Latin1.
|
||||
*
|
||||
* \see toCString()
|
||||
*/
|
||||
std::string to8Bit(bool unicode = false) const;
|
||||
|
||||
/*!
|
||||
* Returns a deep copy of this String as a wstring. The returned string is
|
||||
* encoded in UTF-16 (without BOM/CPU byte order), not UTF-32 even if wchar_t
|
||||
* is 32-bit wide.
|
||||
*
|
||||
* \see toCWString()
|
||||
*/
|
||||
wstring toWString() const;
|
||||
|
||||
/*!
|
||||
* Creates and returns a standard C-style (null-terminated) version of this
|
||||
* String. The returned string is encoded in UTF8 if \a unicode is true,
|
||||
* otherwise Latin1.
|
||||
*
|
||||
* The returned string is still owned by this String and should not be deleted
|
||||
* by the user.
|
||||
*
|
||||
* The returned pointer remains valid until this String instance is destroyed
|
||||
* or toCString() is called again.
|
||||
*
|
||||
* \warning This however has the side effect that the returned string will remain
|
||||
* in memory <b>in addition to</b> other memory that is consumed by this
|
||||
* String instance. So, this method should not be used on large strings or
|
||||
* where memory is critical. Consider using to8Bit() instead to avoid it.
|
||||
*
|
||||
* \see to8Bit()
|
||||
*/
|
||||
const char *toCString(bool unicode = false) const;
|
||||
|
||||
/*!
|
||||
* Returns a standard C-style (null-terminated) wide character version of
|
||||
* this String. The returned string is encoded in UTF-16 (without BOM/CPU byte
|
||||
* order), not UTF-32 even if wchar_t is 32-bit wide.
|
||||
*
|
||||
* The returned string is still owned by this String and should not be deleted
|
||||
* by the user.
|
||||
*
|
||||
* The returned pointer remains valid until this String instance is destroyed
|
||||
* or any other method of this String is called.
|
||||
*
|
||||
* \note This returns a pointer to the String's internal data without any
|
||||
* conversions.
|
||||
*
|
||||
* \see toWString()
|
||||
*/
|
||||
const wchar_t *toCWString() const;
|
||||
|
||||
/*!
|
||||
* Returns an iterator pointing to the beginning of the string.
|
||||
*/
|
||||
Iterator begin();
|
||||
|
||||
/*!
|
||||
* Returns a const iterator pointing to the beginning of the string.
|
||||
*/
|
||||
ConstIterator begin() const;
|
||||
|
||||
/*!
|
||||
* Returns an iterator pointing to the end of the string (the position
|
||||
* after the last character).
|
||||
*/
|
||||
Iterator end();
|
||||
|
||||
/*!
|
||||
* Returns a const iterator pointing to the end of the string (the position
|
||||
* after the last character).
|
||||
*/
|
||||
ConstIterator end() const;
|
||||
|
||||
/*!
|
||||
* Finds the first occurrence of pattern \a s in this string starting from
|
||||
* \a offset. If the pattern is not found, -1 is returned.
|
||||
*/
|
||||
int find(const String &s, int offset = 0) const;
|
||||
|
||||
/*!
|
||||
* Finds the last occurrence of pattern \a s in this string, searched backwards,
|
||||
* either from the end of the string or starting from \a offset. If the pattern
|
||||
* is not found, -1 is returned.
|
||||
*/
|
||||
int rfind(const String &s, int offset = -1) const;
|
||||
|
||||
/*!
|
||||
* Splits the string on each occurrence of \a separator.
|
||||
*/
|
||||
StringList split(const String &separator = " ") const;
|
||||
|
||||
/*!
|
||||
* Returns true if the strings starts with the substring \a s.
|
||||
*/
|
||||
bool startsWith(const String &s) const;
|
||||
|
||||
/*!
|
||||
* Extract a substring from this string starting at \a position and
|
||||
* continuing for \a n characters.
|
||||
*/
|
||||
String substr(unsigned int position, unsigned int n = 0xffffffff) const;
|
||||
|
||||
/*!
|
||||
* Append \a s to the current string and return a reference to the current
|
||||
* string.
|
||||
*/
|
||||
String &append(const String &s);
|
||||
|
||||
/*!
|
||||
* Clears the string.
|
||||
*/
|
||||
String &clear();
|
||||
|
||||
/*!
|
||||
* Returns an upper case version of the string.
|
||||
*
|
||||
* \warning This only works for the characters in US-ASCII, i.e. A-Z.
|
||||
*/
|
||||
String upper() const;
|
||||
|
||||
/*!
|
||||
* Returns the size of the string.
|
||||
*/
|
||||
unsigned int size() const;
|
||||
|
||||
/*!
|
||||
* Returns the length of the string. Equivalent to size().
|
||||
*/
|
||||
unsigned int length() const;
|
||||
|
||||
/*!
|
||||
* Returns true if the string is empty.
|
||||
*
|
||||
* \see isNull()
|
||||
*/
|
||||
bool isEmpty() const;
|
||||
|
||||
/*!
|
||||
* Returns true if this string is null -- i.e. it is a copy of the
|
||||
* String::null string.
|
||||
*
|
||||
* \note A string can be empty and not null. So do not use this method to
|
||||
* check if the string is empty.
|
||||
*
|
||||
* \see isEmpty()
|
||||
*
|
||||
* \deprecated
|
||||
*/
|
||||
// BIC: remove
|
||||
bool isNull() const;
|
||||
|
||||
/*!
|
||||
* Returns a ByteVector containing the string's data. If \a t is Latin1 or
|
||||
* UTF8, this will return a vector of 8 bit characters, otherwise it will use
|
||||
* 16 bit characters.
|
||||
*
|
||||
* \note If \a t is UTF16, the returned data is encoded in little-endian
|
||||
* format and has a BOM.
|
||||
*
|
||||
* \note The returned data is not null terminated.
|
||||
*/
|
||||
ByteVector data(Type t) const;
|
||||
|
||||
/*!
|
||||
* Convert the string to an integer.
|
||||
*
|
||||
* Returns the integer if the conversion was successful or 0 if the
|
||||
* string does not represent a number.
|
||||
*/
|
||||
// BIC: merge with the method below
|
||||
int toInt() const;
|
||||
|
||||
/*!
|
||||
* Convert the string to an integer.
|
||||
*
|
||||
* If the conversion was successful, it sets the value of \a *ok to
|
||||
* true and returns the integer. Otherwise it sets \a *ok to false
|
||||
* and the result is undefined.
|
||||
*/
|
||||
int toInt(bool *ok) const;
|
||||
|
||||
/*!
|
||||
* Returns a string with the leading and trailing whitespace stripped.
|
||||
*/
|
||||
String stripWhiteSpace() const;
|
||||
|
||||
/*!
|
||||
* Returns true if the file only uses characters required by Latin1.
|
||||
*/
|
||||
bool isLatin1() const;
|
||||
|
||||
/*!
|
||||
* Returns true if the file only uses characters required by (7-bit) ASCII.
|
||||
*/
|
||||
bool isAscii() const;
|
||||
|
||||
/*!
|
||||
* Converts the base-10 integer \a n to a string.
|
||||
*/
|
||||
static String number(int n);
|
||||
|
||||
/*!
|
||||
* Returns a reference to the character at position \a i.
|
||||
*/
|
||||
wchar_t &operator[](int i);
|
||||
|
||||
/*!
|
||||
* Returns a const reference to the character at position \a i.
|
||||
*/
|
||||
const wchar_t &operator[](int i) const;
|
||||
|
||||
/*!
|
||||
* Compares each character of the String with each character of \a s and
|
||||
* returns true if the strings match.
|
||||
*/
|
||||
bool operator==(const String &s) const;
|
||||
|
||||
/*!
|
||||
* Compares each character of the String with each character of \a s and
|
||||
* returns false if the strings match.
|
||||
*/
|
||||
bool operator!=(const String &s) const;
|
||||
|
||||
/*!
|
||||
* Compares each character of the String with each character of \a s and
|
||||
* returns true if the strings match.
|
||||
*/
|
||||
bool operator==(const char *s) const;
|
||||
|
||||
/*!
|
||||
* Compares each character of the String with each character of \a s and
|
||||
* returns false if the strings match.
|
||||
*/
|
||||
bool operator!=(const char *s) const;
|
||||
|
||||
/*!
|
||||
* Compares each character of the String with each character of \a s and
|
||||
* returns true if the strings match.
|
||||
*/
|
||||
bool operator==(const wchar_t *s) const;
|
||||
|
||||
/*!
|
||||
* Compares each character of the String with each character of \a s and
|
||||
* returns false if the strings match.
|
||||
*/
|
||||
bool operator!=(const wchar_t *s) const;
|
||||
|
||||
/*!
|
||||
* Appends \a s to the end of the String.
|
||||
*/
|
||||
String &operator+=(const String &s);
|
||||
|
||||
/*!
|
||||
* Appends \a s to the end of the String.
|
||||
*/
|
||||
String &operator+=(const wchar_t* s);
|
||||
|
||||
/*!
|
||||
* Appends \a s to the end of the String.
|
||||
*/
|
||||
String &operator+=(const char* s);
|
||||
|
||||
/*!
|
||||
* Appends \a s to the end of the String.
|
||||
*/
|
||||
String &operator+=(wchar_t c);
|
||||
|
||||
/*!
|
||||
* Appends \a c to the end of the String.
|
||||
*/
|
||||
String &operator+=(char c);
|
||||
|
||||
/*!
|
||||
* Performs a shallow, implicitly shared, copy of \a s, overwriting the
|
||||
* String's current data.
|
||||
*/
|
||||
String &operator=(const String &s);
|
||||
|
||||
/*!
|
||||
* Performs a deep copy of the data in \a s.
|
||||
*/
|
||||
String &operator=(const std::string &s);
|
||||
|
||||
/*!
|
||||
* Performs a deep copy of the data in \a s.
|
||||
*/
|
||||
String &operator=(const wstring &s);
|
||||
|
||||
/*!
|
||||
* Performs a deep copy of the data in \a s.
|
||||
*/
|
||||
String &operator=(const wchar_t *s);
|
||||
|
||||
/*!
|
||||
* Performs a deep copy of the data in \a s.
|
||||
*/
|
||||
String &operator=(char c);
|
||||
|
||||
/*!
|
||||
* Performs a deep copy of the data in \a s.
|
||||
*/
|
||||
String &operator=(wchar_t c);
|
||||
|
||||
/*!
|
||||
* Performs a deep copy of the data in \a s.
|
||||
*/
|
||||
String &operator=(const char *s);
|
||||
|
||||
/*!
|
||||
* Performs a deep copy of the data in \a v.
|
||||
*/
|
||||
String &operator=(const ByteVector &v);
|
||||
|
||||
/*!
|
||||
* Exchanges the content of the String by the content of \a s.
|
||||
*/
|
||||
void swap(String &s);
|
||||
|
||||
/*!
|
||||
* To be able to use this class in a Map, this operator needed to be
|
||||
* implemented. Returns true if \a s is less than this string in a byte-wise
|
||||
* comparison.
|
||||
*/
|
||||
bool operator<(const String &s) const;
|
||||
|
||||
/*!
|
||||
* A null string provided for convenience.
|
||||
*
|
||||
* \warning Do not modify this variable. It will mess up the internal state
|
||||
* of TagLib.
|
||||
*
|
||||
* \deprecated
|
||||
*/
|
||||
// BIC: remove
|
||||
static String null;
|
||||
|
||||
protected:
|
||||
/*!
|
||||
* If this String is being shared via implicit sharing, do a deep copy of the
|
||||
* data and separate from the shared members. This should be called by all
|
||||
* non-const subclass members.
|
||||
*/
|
||||
void detach();
|
||||
|
||||
private:
|
||||
/*!
|
||||
* \deprecated This variable is no longer used, but NEVER remove this. It
|
||||
* may lead to a linkage error.
|
||||
*/
|
||||
// BIC: remove
|
||||
static const Type WCharByteOrder;
|
||||
|
||||
class StringPrivate;
|
||||
StringPrivate *d;
|
||||
};
|
||||
}
|
||||
|
||||
/*!
|
||||
* \relates TagLib::String
|
||||
*
|
||||
* Concatenates \a s1 and \a s2 and returns the result as a string.
|
||||
*/
|
||||
TAGLIB_EXPORT const TagLib::String operator+(const TagLib::String &s1, const TagLib::String &s2);
|
||||
|
||||
/*!
|
||||
* \relates TagLib::String
|
||||
*
|
||||
* Concatenates \a s1 and \a s2 and returns the result as a string.
|
||||
*/
|
||||
TAGLIB_EXPORT const TagLib::String operator+(const char *s1, const TagLib::String &s2);
|
||||
|
||||
/*!
|
||||
* \relates TagLib::String
|
||||
*
|
||||
* Concatenates \a s1 and \a s2 and returns the result as a string.
|
||||
*/
|
||||
TAGLIB_EXPORT const TagLib::String operator+(const TagLib::String &s1, const char *s2);
|
||||
|
||||
|
||||
/*!
|
||||
* \relates TagLib::String
|
||||
*
|
||||
* Send the string to an output stream.
|
||||
*/
|
||||
TAGLIB_EXPORT std::ostream &operator<<(std::ostream &s, const TagLib::String &str);
|
||||
|
||||
#endif
|
||||
123
3rdparty/taglib/toolkit/tstringlist.cpp
vendored
Normal file
123
3rdparty/taglib/toolkit/tstringlist.cpp
vendored
Normal file
@@ -0,0 +1,123 @@
|
||||
/***************************************************************************
|
||||
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/ *
|
||||
***************************************************************************/
|
||||
|
||||
#include "tstringlist.h"
|
||||
|
||||
using namespace TagLib;
|
||||
|
||||
class StringListPrivate
|
||||
{
|
||||
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// static members
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
StringList StringList::split(const String &s, const String &pattern)
|
||||
{
|
||||
StringList l;
|
||||
|
||||
int previousOffset = 0;
|
||||
for(int offset = s.find(pattern); offset != -1; offset = s.find(pattern, offset + 1)) {
|
||||
l.append(s.substr(previousOffset, offset - previousOffset));
|
||||
previousOffset = offset + 1;
|
||||
}
|
||||
|
||||
l.append(s.substr(previousOffset, s.size() - previousOffset));
|
||||
|
||||
return l;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// public members
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
StringList::StringList() : List<String>()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
StringList::StringList(const StringList &l) : List<String>(l)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
StringList::StringList(const String &s) : List<String>()
|
||||
{
|
||||
append(s);
|
||||
}
|
||||
|
||||
StringList::StringList(const ByteVectorList &bl, String::Type t) : List<String>()
|
||||
{
|
||||
ByteVectorList::ConstIterator i = bl.begin();
|
||||
for(;i != bl.end(); i++) {
|
||||
append(String(*i, t));
|
||||
}
|
||||
}
|
||||
|
||||
StringList::~StringList()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
String StringList::toString(const String &separator) const
|
||||
{
|
||||
String s;
|
||||
|
||||
ConstIterator it = begin();
|
||||
ConstIterator itEnd = end();
|
||||
|
||||
while(it != itEnd) {
|
||||
s += *it;
|
||||
it++;
|
||||
if(it != itEnd)
|
||||
s += separator;
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
StringList &StringList::append(const String &s)
|
||||
{
|
||||
List<String>::append(s);
|
||||
return *this;
|
||||
}
|
||||
|
||||
StringList &StringList::append(const StringList &l)
|
||||
{
|
||||
List<String>::append(l);
|
||||
return *this;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// related functions
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::ostream &operator<<(std::ostream &s, const StringList &l)
|
||||
{
|
||||
s << l.toString();
|
||||
return s;
|
||||
}
|
||||
115
3rdparty/taglib/toolkit/tstringlist.h
vendored
Normal file
115
3rdparty/taglib/toolkit/tstringlist.h
vendored
Normal file
@@ -0,0 +1,115 @@
|
||||
/***************************************************************************
|
||||
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_STRINGLIST_H
|
||||
#define TAGLIB_STRINGLIST_H
|
||||
|
||||
#include "tstring.h"
|
||||
#include "tlist.h"
|
||||
#include "tbytevectorlist.h"
|
||||
#include "taglib_export.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
namespace TagLib {
|
||||
|
||||
//! A list of strings
|
||||
|
||||
/*!
|
||||
* This is a specialization of the List class with some members convention for
|
||||
* string operations.
|
||||
*/
|
||||
|
||||
class TAGLIB_EXPORT StringList : public List<String>
|
||||
{
|
||||
public:
|
||||
|
||||
/*!
|
||||
* Constructs an empty StringList.
|
||||
*/
|
||||
StringList();
|
||||
|
||||
/*!
|
||||
* Make a shallow, implicitly shared, copy of \a l. Because this is
|
||||
* implicitly shared, this method is lightweight and suitable for
|
||||
* pass-by-value usage.
|
||||
*/
|
||||
StringList(const StringList &l);
|
||||
|
||||
/*!
|
||||
* Constructs a StringList with \a s as a member.
|
||||
*/
|
||||
StringList(const String &s);
|
||||
|
||||
/*!
|
||||
* Makes a deep copy of the data in \a vl.
|
||||
*
|
||||
* \note This should only be used with the 8-bit codecs Latin1 and UTF8, when
|
||||
* used with other codecs it will simply print a warning and exit.
|
||||
*/
|
||||
StringList(const ByteVectorList &vl, String::Type t = String::Latin1);
|
||||
|
||||
/*!
|
||||
* Destroys this StringList instance.
|
||||
*/
|
||||
virtual ~StringList();
|
||||
|
||||
/*!
|
||||
* Concatenate the list of strings into one string separated by \a separator.
|
||||
*/
|
||||
String toString(const String &separator = " ") const;
|
||||
|
||||
/*!
|
||||
* Appends \a s to the end of the list and returns a reference to the
|
||||
* list.
|
||||
*/
|
||||
StringList &append(const String &s);
|
||||
|
||||
/*!
|
||||
* Appends all of the values in \a l to the end of the list and returns a
|
||||
* reference to the list.
|
||||
*/
|
||||
StringList &append(const StringList &l);
|
||||
|
||||
/*!
|
||||
* Splits the String \a s into several strings at \a pattern. This will not include
|
||||
* the pattern in the returned strings.
|
||||
*/
|
||||
static StringList split(const String &s, const String &pattern);
|
||||
|
||||
private:
|
||||
class StringListPrivate;
|
||||
StringListPrivate *d;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
/*!
|
||||
* \related TagLib::StringList
|
||||
* Send the StringList to an output stream.
|
||||
*/
|
||||
std::ostream &operator<<(std::ostream &s, const TagLib::StringList &l);
|
||||
|
||||
#endif
|
||||
243
3rdparty/taglib/toolkit/tutils.h
vendored
Normal file
243
3rdparty/taglib/toolkit/tutils.h
vendored
Normal file
@@ -0,0 +1,243 @@
|
||||
/***************************************************************************
|
||||
copyright : (C) 2013 by Tsuda Kageyu
|
||||
email : tsuda.kageyu@gmail.com
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* 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_TUTILS_H
|
||||
#define TAGLIB_TUTILS_H
|
||||
|
||||
// THIS FILE IS NOT A PART OF THE TAGLIB API
|
||||
|
||||
#ifndef DO_NOT_DOCUMENT // tell Doxygen not to document this header
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_MSC_BYTESWAP)
|
||||
# include <stdlib.h>
|
||||
#elif defined(HAVE_GLIBC_BYTESWAP)
|
||||
# include <byteswap.h>
|
||||
#elif defined(HAVE_MAC_BYTESWAP)
|
||||
# include <libkern/OSByteOrder.h>
|
||||
#elif defined(HAVE_OPENBSD_BYTESWAP)
|
||||
# include <sys/endian.h>
|
||||
#endif
|
||||
|
||||
#include <tstring.h>
|
||||
#include <cstdio>
|
||||
#include <cstdarg>
|
||||
#include <cstring>
|
||||
|
||||
namespace TagLib
|
||||
{
|
||||
namespace Utils
|
||||
{
|
||||
namespace
|
||||
{
|
||||
|
||||
/*!
|
||||
* Reverses the order of bytes in an 16-bit integer.
|
||||
*/
|
||||
inline unsigned short byteSwap(unsigned short x)
|
||||
{
|
||||
#if defined(HAVE_GCC_BYTESWAP)
|
||||
|
||||
return __builtin_bswap16(x);
|
||||
|
||||
#elif defined(HAVE_MSC_BYTESWAP)
|
||||
|
||||
return _byteswap_ushort(x);
|
||||
|
||||
#elif defined(HAVE_GLIBC_BYTESWAP)
|
||||
|
||||
return __bswap_16(x);
|
||||
|
||||
#elif defined(HAVE_MAC_BYTESWAP)
|
||||
|
||||
return OSSwapInt16(x);
|
||||
|
||||
#elif defined(HAVE_OPENBSD_BYTESWAP)
|
||||
|
||||
return swap16(x);
|
||||
|
||||
#else
|
||||
|
||||
return ((x >> 8) & 0xff) | ((x & 0xff) << 8);
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
/*!
|
||||
* Reverses the order of bytes in an 32-bit integer.
|
||||
*/
|
||||
inline unsigned int byteSwap(unsigned int x)
|
||||
{
|
||||
#if defined(HAVE_GCC_BYTESWAP)
|
||||
|
||||
return __builtin_bswap32(x);
|
||||
|
||||
#elif defined(HAVE_MSC_BYTESWAP)
|
||||
|
||||
return _byteswap_ulong(x);
|
||||
|
||||
#elif defined(HAVE_GLIBC_BYTESWAP)
|
||||
|
||||
return __bswap_32(x);
|
||||
|
||||
#elif defined(HAVE_MAC_BYTESWAP)
|
||||
|
||||
return OSSwapInt32(x);
|
||||
|
||||
#elif defined(HAVE_OPENBSD_BYTESWAP)
|
||||
|
||||
return swap32(x);
|
||||
|
||||
#else
|
||||
|
||||
return ((x & 0xff000000u) >> 24)
|
||||
| ((x & 0x00ff0000u) >> 8)
|
||||
| ((x & 0x0000ff00u) << 8)
|
||||
| ((x & 0x000000ffu) << 24);
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
/*!
|
||||
* Reverses the order of bytes in an 64-bit integer.
|
||||
*/
|
||||
inline unsigned long long byteSwap(unsigned long long x)
|
||||
{
|
||||
#if defined(HAVE_GCC_BYTESWAP)
|
||||
|
||||
return __builtin_bswap64(x);
|
||||
|
||||
#elif defined(HAVE_MSC_BYTESWAP)
|
||||
|
||||
return _byteswap_uint64(x);
|
||||
|
||||
#elif defined(HAVE_GLIBC_BYTESWAP)
|
||||
|
||||
return __bswap_64(x);
|
||||
|
||||
#elif defined(HAVE_MAC_BYTESWAP)
|
||||
|
||||
return OSSwapInt64(x);
|
||||
|
||||
#elif defined(HAVE_OPENBSD_BYTESWAP)
|
||||
|
||||
return swap64(x);
|
||||
|
||||
#else
|
||||
|
||||
return ((x & 0xff00000000000000ull) >> 56)
|
||||
| ((x & 0x00ff000000000000ull) >> 40)
|
||||
| ((x & 0x0000ff0000000000ull) >> 24)
|
||||
| ((x & 0x000000ff00000000ull) >> 8)
|
||||
| ((x & 0x00000000ff000000ull) << 8)
|
||||
| ((x & 0x0000000000ff0000ull) << 24)
|
||||
| ((x & 0x000000000000ff00ull) << 40)
|
||||
| ((x & 0x00000000000000ffull) << 56);
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
/*!
|
||||
* Returns a formatted string just like standard sprintf(), but makes use of
|
||||
* safer functions such as snprintf() if available.
|
||||
*/
|
||||
inline String formatString(const char *format, ...)
|
||||
{
|
||||
// Sufficient buffer size for the current internal uses.
|
||||
// Consider changing this value when you use this function.
|
||||
|
||||
static const size_t BufferSize = 128;
|
||||
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
|
||||
char buf[BufferSize];
|
||||
int length;
|
||||
|
||||
#if defined(HAVE_VSNPRINTF)
|
||||
|
||||
length = vsnprintf(buf, BufferSize, format, args);
|
||||
|
||||
#elif defined(HAVE_VSPRINTF_S)
|
||||
|
||||
length = vsprintf_s(buf, format, args);
|
||||
|
||||
#else
|
||||
|
||||
// The last resort. May cause a buffer overflow.
|
||||
|
||||
length = vsprintf(buf, format, args);
|
||||
if(length >= BufferSize) {
|
||||
debug("Utils::formatString() - Buffer overflow! Returning an empty string.");
|
||||
length = -1;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
va_end(args);
|
||||
|
||||
if(length > 0)
|
||||
return String(buf);
|
||||
else
|
||||
return String();
|
||||
}
|
||||
|
||||
/*!
|
||||
* The types of byte order of the running system.
|
||||
*/
|
||||
enum ByteOrder
|
||||
{
|
||||
//! Little endian systems.
|
||||
LittleEndian,
|
||||
//! Big endian systems.
|
||||
BigEndian
|
||||
};
|
||||
|
||||
/*!
|
||||
* Returns the byte order of the system.
|
||||
*/
|
||||
inline ByteOrder systemByteOrder()
|
||||
{
|
||||
union {
|
||||
int i;
|
||||
char c;
|
||||
} u;
|
||||
|
||||
u.i = 1;
|
||||
if(u.c == 1)
|
||||
return LittleEndian;
|
||||
else
|
||||
return BigEndian;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
106
3rdparty/taglib/toolkit/tzlib.cpp
vendored
Normal file
106
3rdparty/taglib/toolkit/tzlib.cpp
vendored
Normal file
@@ -0,0 +1,106 @@
|
||||
/***************************************************************************
|
||||
copyright : (C) 2016 by Tsuda Kageyu
|
||||
email : tsuda.kageyu@gmail.com
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* 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/ *
|
||||
***************************************************************************/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_ZLIB
|
||||
# include <zlib.h>
|
||||
# include <tstring.h>
|
||||
# include <tdebug.h>
|
||||
#endif
|
||||
|
||||
#include "tzlib.h"
|
||||
|
||||
using namespace TagLib;
|
||||
|
||||
bool zlib::isAvailable()
|
||||
{
|
||||
#ifdef HAVE_ZLIB
|
||||
|
||||
return true;
|
||||
|
||||
#else
|
||||
|
||||
return false;
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
ByteVector zlib::decompress(const ByteVector &data)
|
||||
{
|
||||
#ifdef HAVE_ZLIB
|
||||
|
||||
z_stream stream = {};
|
||||
|
||||
if(inflateInit(&stream) != Z_OK) {
|
||||
debug("zlib::decompress() - Failed to initizlize zlib.");
|
||||
return ByteVector();
|
||||
}
|
||||
|
||||
ByteVector inData = data;
|
||||
|
||||
stream.avail_in = static_cast<uInt>(inData.size());
|
||||
stream.next_in = reinterpret_cast<Bytef *>(inData.data());
|
||||
|
||||
const unsigned int chunkSize = 1024;
|
||||
|
||||
ByteVector outData;
|
||||
|
||||
do {
|
||||
const size_t offset = outData.size();
|
||||
outData.resize(outData.size() + chunkSize);
|
||||
|
||||
stream.avail_out = static_cast<uInt>(chunkSize);
|
||||
stream.next_out = reinterpret_cast<Bytef *>(outData.data() + offset);
|
||||
|
||||
const int result = inflate(&stream, Z_NO_FLUSH);
|
||||
|
||||
if(result == Z_STREAM_ERROR ||
|
||||
result == Z_NEED_DICT ||
|
||||
result == Z_DATA_ERROR ||
|
||||
result == Z_MEM_ERROR)
|
||||
{
|
||||
if(result != Z_STREAM_ERROR)
|
||||
inflateEnd(&stream);
|
||||
|
||||
debug("zlib::decompress() - Error reading compressed stream.");
|
||||
return ByteVector();
|
||||
}
|
||||
|
||||
outData.resize(outData.size() - stream.avail_out);
|
||||
} while(stream.avail_out == 0);
|
||||
|
||||
inflateEnd(&stream);
|
||||
|
||||
return outData;
|
||||
|
||||
#else
|
||||
|
||||
return ByteVector();
|
||||
|
||||
#endif
|
||||
}
|
||||
54
3rdparty/taglib/toolkit/tzlib.h
vendored
Normal file
54
3rdparty/taglib/toolkit/tzlib.h
vendored
Normal file
@@ -0,0 +1,54 @@
|
||||
/***************************************************************************
|
||||
copyright : (C) 2016 by Tsuda Kageyu
|
||||
email : tsuda.kageyu@gmail.com
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* 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_TZLIB_H
|
||||
#define TAGLIB_TZLIB_H
|
||||
|
||||
#include <tbytevector.h>
|
||||
|
||||
// THIS FILE IS NOT A PART OF THE TAGLIB API
|
||||
|
||||
#ifndef DO_NOT_DOCUMENT // tell Doxygen not to document this header
|
||||
|
||||
namespace TagLib {
|
||||
|
||||
namespace zlib {
|
||||
|
||||
/*!
|
||||
* Returns whether or not zlib is installed and ready to use.
|
||||
*/
|
||||
bool isAvailable();
|
||||
|
||||
/*!
|
||||
* Decompress \a data by zlib.
|
||||
*/
|
||||
ByteVector decompress(const ByteVector &data);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user