mirror of
https://github.com/taglib/taglib.git
synced 2025-05-27 21:20:26 -04:00
Revert changes concerning the smart pointer
This commit is contained in:
parent
b6c9fb2da1
commit
1f4e06ea7c
@ -9,32 +9,15 @@ include(CheckCXXSourceCompiles)
|
||||
# check for libz using the cmake supplied FindZLIB.cmake
|
||||
find_package(ZLIB)
|
||||
if(ZLIB_FOUND)
|
||||
set(HAVE_ZLIB 1)
|
||||
set(HAVE_ZLIB 1)
|
||||
else()
|
||||
set(HAVE_ZLIB 0)
|
||||
set(HAVE_ZLIB 0)
|
||||
endif()
|
||||
|
||||
# Determine where shared_ptr<T> is defined regardless of C++11 support.
|
||||
|
||||
check_cxx_source_compiles("
|
||||
#include <memory>
|
||||
int main() { std::tr1::shared_ptr<int> x; return 0; }
|
||||
" HAVE_STD_SHARED_PTR)
|
||||
|
||||
check_cxx_source_compiles("
|
||||
#include <tr1/memory>
|
||||
int main() { std::tr1::shared_ptr<int> x; return 0; }
|
||||
" HAVE_TR1_SHARED_PTR)
|
||||
|
||||
check_cxx_source_compiles("
|
||||
#include <boost/shared_ptr.hpp>
|
||||
int main() { boost::shared_ptr<int> x; return 0; }
|
||||
" HAVE_BOOST_SHARED_PTR)
|
||||
|
||||
set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules)
|
||||
find_package(CppUnit)
|
||||
if(NOT CppUnit_FOUND AND BUILD_TESTS)
|
||||
message(STATUS "CppUnit not found, disabling tests.")
|
||||
set(BUILD_TESTS OFF)
|
||||
message(STATUS "CppUnit not found, disabling tests.")
|
||||
set(BUILD_TESTS OFF)
|
||||
endif()
|
||||
|
||||
|
@ -3,10 +3,6 @@
|
||||
/* Define if you have libz */
|
||||
#cmakedefine HAVE_ZLIB 1
|
||||
|
||||
#cmakedefine HAVE_STD_SHARED_PTR 1
|
||||
#cmakedefine HAVE_TR1_SHARED_PTR 1
|
||||
#cmakedefine HAVE_BOOST_SHARED_PTR 1
|
||||
|
||||
#cmakedefine NO_ITUNES_HACKS 1
|
||||
#cmakedefine WITH_ASF 1
|
||||
#cmakedefine WITH_MP4 1
|
||||
|
@ -51,7 +51,6 @@ set(tag_HDRS
|
||||
toolkit/tmap.tcc
|
||||
toolkit/tpropertymap.h
|
||||
toolkit/tbyteswap.h
|
||||
toolkit/trefcountptr.h
|
||||
mpeg/mpegfile.h
|
||||
mpeg/mpegproperties.h
|
||||
mpeg/mpegheader.h
|
||||
@ -312,10 +311,6 @@ if(ZLIB_FOUND)
|
||||
target_link_libraries(tag ${ZLIB_LIBRARIES})
|
||||
endif()
|
||||
|
||||
if(WIN32 AND NOT TAGLIB_STATIC)
|
||||
target_link_libraries(tag shlwapi.lib)
|
||||
endif()
|
||||
|
||||
set_target_properties(tag PROPERTIES
|
||||
VERSION ${TAGLIB_SOVERSION_MAJOR}.${TAGLIB_SOVERSION_MINOR}.${TAGLIB_SOVERSION_PATCH}
|
||||
SOVERSION ${TAGLIB_SOVERSION_MAJOR}
|
||||
|
@ -34,7 +34,7 @@
|
||||
|
||||
using namespace TagLib;
|
||||
|
||||
class ASF::Attribute::AttributePrivate
|
||||
class ASF::Attribute::AttributePrivate : public RefCounter
|
||||
{
|
||||
public:
|
||||
AttributePrivate()
|
||||
@ -60,71 +60,77 @@ public:
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ASF::Attribute::Attribute()
|
||||
: d(new AttributePrivate())
|
||||
{
|
||||
d = new AttributePrivate;
|
||||
d->type = UnicodeType;
|
||||
}
|
||||
|
||||
ASF::Attribute::Attribute(const ASF::Attribute &other)
|
||||
: d(other.d)
|
||||
{
|
||||
d->ref();
|
||||
}
|
||||
|
||||
ASF::Attribute &ASF::Attribute::operator=(const ASF::Attribute &other)
|
||||
{
|
||||
if(d->deref())
|
||||
delete d;
|
||||
d = other.d;
|
||||
d->ref();
|
||||
return *this;
|
||||
}
|
||||
|
||||
ASF::Attribute::~Attribute()
|
||||
{
|
||||
if(d->deref())
|
||||
delete d;
|
||||
}
|
||||
|
||||
ASF::Attribute::Attribute(const String &value)
|
||||
: d(new AttributePrivate())
|
||||
{
|
||||
d = new AttributePrivate;
|
||||
d->type = UnicodeType;
|
||||
d->stringValue = value;
|
||||
}
|
||||
|
||||
ASF::Attribute::Attribute(const ByteVector &value)
|
||||
: d(new AttributePrivate())
|
||||
{
|
||||
d = new AttributePrivate;
|
||||
d->type = BytesType;
|
||||
d->byteVectorValue = value;
|
||||
}
|
||||
|
||||
ASF::Attribute::Attribute(const ASF::Picture &value)
|
||||
: d(new AttributePrivate())
|
||||
{
|
||||
d = new AttributePrivate;
|
||||
d->type = BytesType;
|
||||
d->pictureValue = value;
|
||||
}
|
||||
|
||||
ASF::Attribute::Attribute(unsigned int value)
|
||||
: d(new AttributePrivate())
|
||||
{
|
||||
d = new AttributePrivate;
|
||||
d->type = DWordType;
|
||||
d->intValue = value;
|
||||
}
|
||||
|
||||
ASF::Attribute::Attribute(unsigned long long value)
|
||||
: d(new AttributePrivate())
|
||||
{
|
||||
d = new AttributePrivate;
|
||||
d->type = QWordType;
|
||||
d->longLongValue = value;
|
||||
}
|
||||
|
||||
ASF::Attribute::Attribute(unsigned short value)
|
||||
: d(new AttributePrivate())
|
||||
{
|
||||
d = new AttributePrivate;
|
||||
d->type = WordType;
|
||||
d->shortValue = value;
|
||||
}
|
||||
|
||||
ASF::Attribute::Attribute(bool value)
|
||||
: d(new AttributePrivate())
|
||||
{
|
||||
d = new AttributePrivate;
|
||||
d->type = BoolType;
|
||||
d->boolValue = value;
|
||||
}
|
||||
|
@ -194,7 +194,7 @@ namespace TagLib
|
||||
ByteVector render(const String &name, int kind = 0) const;
|
||||
|
||||
class AttributePrivate;
|
||||
RefCountPtr<AttributePrivate> d;
|
||||
AttributePrivate *d;
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -35,7 +35,7 @@
|
||||
|
||||
using namespace TagLib;
|
||||
|
||||
class ASF::Picture::PicturePrivate
|
||||
class ASF::Picture::PicturePrivate : public RefCounter
|
||||
{
|
||||
public:
|
||||
bool valid;
|
||||
@ -50,18 +50,21 @@ public:
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ASF::Picture::Picture()
|
||||
: d(new PicturePrivate())
|
||||
{
|
||||
d = new PicturePrivate();
|
||||
d->valid = true;
|
||||
}
|
||||
|
||||
ASF::Picture::Picture(const Picture& other)
|
||||
: d(other.d)
|
||||
{
|
||||
d->ref();
|
||||
}
|
||||
|
||||
ASF::Picture::~Picture()
|
||||
{
|
||||
if(d->deref())
|
||||
delete d;
|
||||
}
|
||||
|
||||
bool ASF::Picture::isValid() const
|
||||
@ -118,7 +121,12 @@ int ASF::Picture::dataSize() const
|
||||
|
||||
ASF::Picture& ASF::Picture::operator=(const ASF::Picture& other)
|
||||
{
|
||||
d = other.d;
|
||||
if(other.d != d) {
|
||||
if(d->deref())
|
||||
delete d;
|
||||
d = other.d;
|
||||
d->ref();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
@ -207,10 +207,10 @@ namespace TagLib
|
||||
static Picture fromInvalid();
|
||||
friend class Attribute;
|
||||
#endif
|
||||
private:
|
||||
class PicturePrivate;
|
||||
RefCountPtr<PicturePrivate> d;
|
||||
};
|
||||
private:
|
||||
class PicturePrivate;
|
||||
PicturePrivate *d;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -31,10 +31,6 @@
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
# include <Shlwapi.h>
|
||||
#endif
|
||||
|
||||
#include <tfile.h>
|
||||
#include <tstring.h>
|
||||
#include <tdebug.h>
|
||||
@ -61,12 +57,15 @@
|
||||
|
||||
using namespace TagLib;
|
||||
|
||||
class FileRef::FileRefPrivate
|
||||
class FileRef::FileRefPrivate : public RefCounter
|
||||
{
|
||||
public:
|
||||
FileRefPrivate(File *f) : file(f) {}
|
||||
FileRefPrivate(File *f) : RefCounter(), file(f) {}
|
||||
~FileRefPrivate() {
|
||||
delete file;
|
||||
}
|
||||
|
||||
RefCountPtr<File> file;
|
||||
File *file;
|
||||
static List<const FileTypeResolver *> fileTypeResolvers;
|
||||
};
|
||||
|
||||
@ -77,28 +76,30 @@ List<const FileRef::FileTypeResolver *> FileRef::FileRefPrivate::fileTypeResolve
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
FileRef::FileRef()
|
||||
: d(new FileRefPrivate(0))
|
||||
{
|
||||
d = new FileRefPrivate(0);
|
||||
}
|
||||
|
||||
FileRef::FileRef(
|
||||
FileName fileName, bool readAudioProperties, AudioProperties::ReadStyle audioPropertiesStyle)
|
||||
: d(new FileRefPrivate(create(fileName, readAudioProperties, audioPropertiesStyle)))
|
||||
FileRef::FileRef(FileName fileName, bool readAudioProperties,
|
||||
AudioProperties::ReadStyle audioPropertiesStyle)
|
||||
{
|
||||
d = new FileRefPrivate(create(fileName, readAudioProperties, audioPropertiesStyle));
|
||||
}
|
||||
|
||||
FileRef::FileRef(File *file)
|
||||
: d(new FileRefPrivate(file))
|
||||
{
|
||||
d = new FileRefPrivate(file);
|
||||
}
|
||||
|
||||
FileRef::FileRef(const FileRef &ref)
|
||||
: d(ref.d)
|
||||
FileRef::FileRef(const FileRef &ref) : d(ref.d)
|
||||
{
|
||||
d->ref();
|
||||
}
|
||||
|
||||
FileRef::~FileRef()
|
||||
{
|
||||
if(d->deref())
|
||||
delete d;
|
||||
}
|
||||
|
||||
Tag *FileRef::tag() const
|
||||
@ -121,7 +122,7 @@ AudioProperties *FileRef::audioProperties() const
|
||||
|
||||
File *FileRef::file() const
|
||||
{
|
||||
return d->file.get();
|
||||
return d->file;
|
||||
}
|
||||
|
||||
bool FileRef::save()
|
||||
@ -181,7 +182,15 @@ bool FileRef::isNull() const
|
||||
|
||||
FileRef &FileRef::operator=(const FileRef &ref)
|
||||
{
|
||||
if(&ref == this)
|
||||
return *this;
|
||||
|
||||
if(d->deref())
|
||||
delete d;
|
||||
|
||||
d = ref.d;
|
||||
d->ref();
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
@ -209,36 +218,21 @@ File *FileRef::create(FileName fileName, bool readAudioProperties,
|
||||
|
||||
// Ok, this is really dumb for now, but it works for testing.
|
||||
|
||||
String ext;
|
||||
String s;
|
||||
|
||||
#ifdef _WIN32
|
||||
// Avoids direct conversion from FileName to String
|
||||
// because String can't accept non-Latin-1 string in char array.
|
||||
|
||||
if(!fileName.wstr().empty()) {
|
||||
const wchar_t *pext = PathFindExtensionW(fileName.wstr().c_str());
|
||||
if(*pext == L'.')
|
||||
ext = String(pext + 1).upper();
|
||||
}
|
||||
else {
|
||||
const char *pext = PathFindExtensionA(fileName.str().c_str());
|
||||
if(*pext == '.')
|
||||
ext = String(pext + 1).upper();
|
||||
}
|
||||
s = (wcslen((const wchar_t *) fileName) > 0) ? String((const wchar_t *) fileName) : String((const char *) fileName);
|
||||
#else
|
||||
{
|
||||
String s = fileName;
|
||||
const int pos = s.rfind(".");
|
||||
if(pos != -1)
|
||||
ext = s.substr(pos + 1).upper();
|
||||
}
|
||||
s = fileName;
|
||||
#endif
|
||||
|
||||
// If this list is updated, the method defaultFileExtensions() should also be
|
||||
// updated. However at some point that list should be created at the same time
|
||||
// that a default file type resolver is created.
|
||||
|
||||
if(!ext.isEmpty()) {
|
||||
int pos = s.rfind(".");
|
||||
if(pos != -1) {
|
||||
String ext = s.substr(pos + 1).upper();
|
||||
if(ext == "MP3")
|
||||
return new MPEG::File(fileName, readAudioProperties, audioPropertiesStyle);
|
||||
if(ext == "OGG")
|
||||
|
@ -255,7 +255,7 @@ namespace TagLib {
|
||||
|
||||
private:
|
||||
class FileRefPrivate;
|
||||
RefCountPtr<FileRefPrivate> d;
|
||||
FileRefPrivate *d;
|
||||
};
|
||||
|
||||
} // namespace TagLib
|
||||
|
@ -33,35 +33,43 @@
|
||||
|
||||
using namespace TagLib;
|
||||
|
||||
class MP4::CoverArt::CoverArtPrivate
|
||||
class MP4::CoverArt::CoverArtPrivate : public RefCounter
|
||||
{
|
||||
public:
|
||||
CoverArtPrivate() : format(MP4::CoverArt::JPEG) {}
|
||||
CoverArtPrivate() : RefCounter(), format(MP4::CoverArt::JPEG) {}
|
||||
|
||||
Format format;
|
||||
ByteVector data;
|
||||
};
|
||||
|
||||
MP4::CoverArt::CoverArt(Format format, const ByteVector &data)
|
||||
: d(new CoverArtPrivate())
|
||||
{
|
||||
d = new CoverArtPrivate;
|
||||
d->format = format;
|
||||
d->data = data;
|
||||
}
|
||||
|
||||
MP4::CoverArt::CoverArt(const CoverArt &item) : d(item.d)
|
||||
{
|
||||
d->ref();
|
||||
}
|
||||
|
||||
MP4::CoverArt &
|
||||
MP4::CoverArt::operator=(const CoverArt &item)
|
||||
{
|
||||
if(d->deref()) {
|
||||
delete d;
|
||||
}
|
||||
d = item.d;
|
||||
d->ref();
|
||||
return *this;
|
||||
}
|
||||
|
||||
MP4::CoverArt::~CoverArt()
|
||||
{
|
||||
if(d->deref()) {
|
||||
delete d;
|
||||
}
|
||||
}
|
||||
|
||||
MP4::CoverArt::Format
|
||||
|
@ -63,7 +63,7 @@ namespace TagLib {
|
||||
|
||||
private:
|
||||
class CoverArtPrivate;
|
||||
RefCountPtr<CoverArtPrivate> d;
|
||||
CoverArtPrivate *d;
|
||||
};
|
||||
|
||||
typedef List<CoverArt> CoverArtList;
|
||||
|
@ -33,10 +33,10 @@
|
||||
|
||||
using namespace TagLib;
|
||||
|
||||
class MP4::Item::ItemPrivate
|
||||
class MP4::Item::ItemPrivate : public RefCounter
|
||||
{
|
||||
public:
|
||||
ItemPrivate() : valid(true), atomDataType(TypeUndefined) {}
|
||||
ItemPrivate() : RefCounter(), valid(true), atomDataType(TypeUndefined) {}
|
||||
|
||||
bool valid;
|
||||
AtomDataType atomDataType;
|
||||
@ -54,78 +54,86 @@ public:
|
||||
};
|
||||
|
||||
MP4::Item::Item()
|
||||
: d(new ItemPrivate())
|
||||
{
|
||||
d = new ItemPrivate;
|
||||
d->valid = false;
|
||||
}
|
||||
|
||||
MP4::Item::Item(const Item &item) : d(item.d)
|
||||
{
|
||||
d->ref();
|
||||
}
|
||||
|
||||
MP4::Item &
|
||||
MP4::Item::operator=(const Item &item)
|
||||
{
|
||||
if(d->deref()) {
|
||||
delete d;
|
||||
}
|
||||
d = item.d;
|
||||
d->ref();
|
||||
return *this;
|
||||
}
|
||||
|
||||
MP4::Item::~Item()
|
||||
{
|
||||
if(d->deref()) {
|
||||
delete d;
|
||||
}
|
||||
}
|
||||
|
||||
MP4::Item::Item(bool value)
|
||||
: d(new ItemPrivate())
|
||||
{
|
||||
d = new ItemPrivate;
|
||||
d->m_bool = value;
|
||||
}
|
||||
|
||||
MP4::Item::Item(int value)
|
||||
: d(new ItemPrivate())
|
||||
{
|
||||
d = new ItemPrivate;
|
||||
d->m_int = value;
|
||||
}
|
||||
|
||||
MP4::Item::Item(uchar value)
|
||||
: d(new ItemPrivate())
|
||||
{
|
||||
d = new ItemPrivate;
|
||||
d->m_byte = value;
|
||||
}
|
||||
|
||||
MP4::Item::Item(uint value)
|
||||
: d(new ItemPrivate())
|
||||
{
|
||||
d = new ItemPrivate;
|
||||
d->m_uint = value;
|
||||
}
|
||||
|
||||
MP4::Item::Item(long long value)
|
||||
: d(new ItemPrivate())
|
||||
{
|
||||
d = new ItemPrivate;
|
||||
d->m_longlong = value;
|
||||
}
|
||||
|
||||
MP4::Item::Item(int value1, int value2)
|
||||
: d(new ItemPrivate())
|
||||
{
|
||||
d = new ItemPrivate;
|
||||
d->m_intPair.first = value1;
|
||||
d->m_intPair.second = value2;
|
||||
}
|
||||
|
||||
MP4::Item::Item(const ByteVectorList &value)
|
||||
: d(new ItemPrivate())
|
||||
{
|
||||
d = new ItemPrivate;
|
||||
d->m_byteVectorList = value;
|
||||
}
|
||||
|
||||
MP4::Item::Item(const StringList &value)
|
||||
: d(new ItemPrivate())
|
||||
{
|
||||
d = new ItemPrivate;
|
||||
d->m_stringList = value;
|
||||
}
|
||||
|
||||
MP4::Item::Item(const MP4::CoverArtList &value)
|
||||
: d(new ItemPrivate())
|
||||
{
|
||||
d = new ItemPrivate;
|
||||
d->m_coverArtList = value;
|
||||
}
|
||||
|
||||
|
@ -73,7 +73,7 @@ namespace TagLib {
|
||||
|
||||
private:
|
||||
class ItemPrivate;
|
||||
RefCountPtr<ItemPrivate> d;
|
||||
ItemPrivate *d;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -33,7 +33,7 @@
|
||||
|
||||
using namespace TagLib;
|
||||
|
||||
class MPEG::Header::HeaderPrivate
|
||||
class MPEG::Header::HeaderPrivate : public RefCounter
|
||||
{
|
||||
public:
|
||||
HeaderPrivate() :
|
||||
@ -68,18 +68,20 @@ public:
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
MPEG::Header::Header(const ByteVector &data)
|
||||
: d(new HeaderPrivate())
|
||||
{
|
||||
d = new HeaderPrivate;
|
||||
parse(data);
|
||||
}
|
||||
|
||||
MPEG::Header::Header(const Header &h)
|
||||
: d(h.d)
|
||||
MPEG::Header::Header(const Header &h) : d(h.d)
|
||||
{
|
||||
d->ref();
|
||||
}
|
||||
|
||||
MPEG::Header::~Header()
|
||||
{
|
||||
if (d->deref())
|
||||
delete d;
|
||||
}
|
||||
|
||||
bool MPEG::Header::isValid() const
|
||||
@ -144,7 +146,14 @@ int MPEG::Header::samplesPerFrame() const
|
||||
|
||||
MPEG::Header &MPEG::Header::operator=(const Header &h)
|
||||
{
|
||||
if(&h == this)
|
||||
return *this;
|
||||
|
||||
if(d->deref())
|
||||
delete d;
|
||||
|
||||
d = h.d;
|
||||
d->ref();
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
@ -27,7 +27,6 @@
|
||||
#define TAGLIB_MPEGHEADER_H
|
||||
|
||||
#include "taglib_export.h"
|
||||
#include "trefcountptr.h"
|
||||
|
||||
namespace TagLib {
|
||||
|
||||
@ -159,7 +158,7 @@ namespace TagLib {
|
||||
void parse(const ByteVector &data);
|
||||
|
||||
class HeaderPrivate;
|
||||
RefCountPtr<HeaderPrivate> d;
|
||||
HeaderPrivate *d;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -45,11 +45,23 @@
|
||||
#include <string>
|
||||
#include <climits>
|
||||
|
||||
#ifdef _WIN32
|
||||
# if !defined(NOMINMAX)
|
||||
# define NOMINMAX
|
||||
# endif
|
||||
# include <windows.h>
|
||||
#ifdef __APPLE__
|
||||
# include <libkern/OSAtomic.h>
|
||||
# define TAGLIB_ATOMIC_MAC
|
||||
#elif defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__)
|
||||
# if !defined(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
|
||||
|
||||
// Check the widths of integral types.
|
||||
@ -104,6 +116,50 @@ namespace TagLib {
|
||||
* so I'm providing something here that should be constant.
|
||||
*/
|
||||
typedef std::basic_string<wchar> wstring;
|
||||
|
||||
#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!
|
||||
*/
|
||||
|
||||
class RefCounter
|
||||
{
|
||||
public:
|
||||
RefCounter() : 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:
|
||||
uint refCount;
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
#endif // DO_NOT_DOCUMENT
|
||||
|
||||
}
|
||||
|
||||
/*!
|
||||
|
@ -236,7 +236,7 @@ ByteVector fromNumber(T value, bool mostSignificantByteFirst)
|
||||
return ByteVector(reinterpret_cast<const char *>(&value), size);
|
||||
}
|
||||
|
||||
class DataPrivate
|
||||
class DataPrivate : public RefCounter
|
||||
{
|
||||
public:
|
||||
DataPrivate()
|
||||
@ -262,39 +262,45 @@ public:
|
||||
std::vector<char> data;
|
||||
};
|
||||
|
||||
class ByteVector::ByteVectorPrivate
|
||||
class ByteVector::ByteVectorPrivate : public RefCounter
|
||||
{
|
||||
public:
|
||||
ByteVectorPrivate()
|
||||
: data(new DataPrivate())
|
||||
: RefCounter()
|
||||
, data(new DataPrivate())
|
||||
, offset(0)
|
||||
, length(0)
|
||||
{
|
||||
}
|
||||
|
||||
ByteVectorPrivate(RefCountPtr<ByteVectorPrivate> d, uint o, uint l)
|
||||
: data(d->data)
|
||||
ByteVectorPrivate(ByteVectorPrivate *d, uint o, uint l)
|
||||
: RefCounter()
|
||||
, data(d->data)
|
||||
, offset(d->offset + o)
|
||||
, length(l)
|
||||
{
|
||||
data->ref();
|
||||
}
|
||||
|
||||
ByteVectorPrivate(const std::vector<char> &v, uint o, uint l)
|
||||
: data(new DataPrivate(v, o, l))
|
||||
: RefCounter()
|
||||
, data(new DataPrivate(v, o, l))
|
||||
, offset(0)
|
||||
, length(l)
|
||||
{
|
||||
}
|
||||
|
||||
ByteVectorPrivate(uint l, char c)
|
||||
: data(new DataPrivate(l, c))
|
||||
: RefCounter()
|
||||
, data(new DataPrivate(l, c))
|
||||
, offset(0)
|
||||
, length(l)
|
||||
{
|
||||
}
|
||||
|
||||
ByteVectorPrivate(const char *s, uint l)
|
||||
: data(new DataPrivate(s, s + l))
|
||||
: RefCounter()
|
||||
, data(new DataPrivate(s, s + l))
|
||||
, offset(0)
|
||||
, length(l)
|
||||
{
|
||||
@ -302,25 +308,34 @@ public:
|
||||
|
||||
void detach()
|
||||
{
|
||||
if(!data.unique()) {
|
||||
data.reset(new DataPrivate(data->data, offset, length));
|
||||
if(data->count() > 1) {
|
||||
data->deref();
|
||||
data = new DataPrivate(data->data, offset, length);
|
||||
offset = 0;
|
||||
}
|
||||
}
|
||||
|
||||
~ByteVectorPrivate()
|
||||
{
|
||||
if(data->deref())
|
||||
delete data;
|
||||
}
|
||||
|
||||
ByteVectorPrivate &operator=(const ByteVectorPrivate &x)
|
||||
{
|
||||
if(&x != this)
|
||||
{
|
||||
if(data->deref())
|
||||
delete data;
|
||||
|
||||
data = x.data;
|
||||
data->ref();
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
RefCountPtr<DataPrivate> data;
|
||||
DataPrivate *data;
|
||||
uint offset;
|
||||
uint length;
|
||||
};
|
||||
@ -371,11 +386,13 @@ ByteVector::ByteVector(uint size, char value)
|
||||
ByteVector::ByteVector(const ByteVector &v)
|
||||
: d(v.d)
|
||||
{
|
||||
d->ref();
|
||||
}
|
||||
|
||||
ByteVector::ByteVector(const ByteVector &v, uint offset, uint length)
|
||||
: d(new ByteVectorPrivate(v.d, offset, length))
|
||||
{
|
||||
d->ref();
|
||||
}
|
||||
|
||||
ByteVector::ByteVector(char c)
|
||||
@ -395,6 +412,8 @@ ByteVector::ByteVector(const char *data)
|
||||
|
||||
ByteVector::~ByteVector()
|
||||
{
|
||||
if(d->deref())
|
||||
delete d;
|
||||
}
|
||||
|
||||
ByteVector &ByteVector::setData(const char *s, uint length)
|
||||
@ -544,7 +563,10 @@ ByteVector &ByteVector::replace(const ByteVector &pattern, const ByteVector &wit
|
||||
}
|
||||
|
||||
// replace private data:
|
||||
d.reset(newData);
|
||||
if(d->deref())
|
||||
delete d;
|
||||
|
||||
d = newData;
|
||||
|
||||
return *this;
|
||||
}
|
||||
@ -743,7 +765,14 @@ ByteVector ByteVector::operator+(const ByteVector &v) const
|
||||
|
||||
ByteVector &ByteVector::operator=(const ByteVector &v)
|
||||
{
|
||||
if(&v == this)
|
||||
return *this;
|
||||
|
||||
if(d->deref())
|
||||
delete d;
|
||||
|
||||
d = v.d;
|
||||
d->ref();
|
||||
return *this;
|
||||
}
|
||||
|
||||
@ -779,10 +808,16 @@ ByteVector ByteVector::toHex() const
|
||||
|
||||
void ByteVector::detach()
|
||||
{
|
||||
d->detach();
|
||||
if(d->data->count() > 1) {
|
||||
d->data->deref();
|
||||
d->data = new DataPrivate(d->data->data, d->offset, d->length);
|
||||
d->offset = 0;
|
||||
}
|
||||
|
||||
if(!d.unique())
|
||||
d.reset(new ByteVectorPrivate(d->data->data, d->offset, d->length));
|
||||
if(d->count() > 1) {
|
||||
d->deref();
|
||||
d = new ByteVectorPrivate(d->data->data, d->offset, d->length);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -26,9 +26,9 @@
|
||||
#ifndef TAGLIB_BYTEVECTOR_H
|
||||
#define TAGLIB_BYTEVECTOR_H
|
||||
|
||||
#include "taglib_export.h"
|
||||
#include "taglib.h"
|
||||
#include "trefcountptr.h"
|
||||
#include "taglib_export.h"
|
||||
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
|
||||
@ -446,7 +446,7 @@ namespace TagLib {
|
||||
|
||||
private:
|
||||
class ByteVectorPrivate;
|
||||
RefCountPtr<ByteVectorPrivate> d;
|
||||
ByteVectorPrivate *d;
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -38,13 +38,8 @@ namespace TagLib {
|
||||
public:
|
||||
FileName(const wchar_t *name) : m_wname(name) {}
|
||||
FileName(const char *name) : m_name(name) {}
|
||||
|
||||
operator const wchar_t *() const { return m_wname.c_str(); }
|
||||
operator const char *() const { return m_name.c_str(); }
|
||||
|
||||
const std::wstring &wstr() const { return m_wname; }
|
||||
const std::string &str() const { return m_name; }
|
||||
|
||||
private:
|
||||
std::string m_name;
|
||||
std::wstring m_wname;
|
||||
|
@ -27,7 +27,7 @@
|
||||
#define TAGLIB_LIST_H
|
||||
|
||||
#include "taglib.h"
|
||||
#include "trefcountptr.h"
|
||||
|
||||
#include <list>
|
||||
|
||||
namespace TagLib {
|
||||
@ -243,7 +243,7 @@ namespace TagLib {
|
||||
private:
|
||||
#ifndef DO_NOT_DOCUMENT
|
||||
template <class TP> class ListPrivate;
|
||||
RefCountPtr<ListPrivate<T> > d;
|
||||
ListPrivate<T> *d;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
@ -38,7 +38,7 @@ namespace TagLib {
|
||||
// A base for the generic and specialized private class types. New
|
||||
// non-templatized members should be added here.
|
||||
|
||||
class ListPrivateBase
|
||||
class ListPrivateBase : public RefCounter
|
||||
{
|
||||
public:
|
||||
ListPrivateBase() : autoDelete(false) {}
|
||||
@ -53,9 +53,8 @@ template <class TP> class List<T>::ListPrivate : public ListPrivateBase
|
||||
public:
|
||||
ListPrivate() : ListPrivateBase() {}
|
||||
ListPrivate(const std::list<TP> &l) : ListPrivateBase(), list(l) {}
|
||||
|
||||
void clear() {
|
||||
std::list<TP>().swap(list);
|
||||
list.clear();
|
||||
}
|
||||
std::list<TP> list;
|
||||
};
|
||||
@ -69,27 +68,18 @@ template <class TP> class List<T>::ListPrivate<TP *> : public ListPrivateBase
|
||||
public:
|
||||
ListPrivate() : ListPrivateBase() {}
|
||||
ListPrivate(const std::list<TP *> &l) : ListPrivateBase(), list(l) {}
|
||||
|
||||
~ListPrivate() {
|
||||
deletePointers();
|
||||
clear();
|
||||
}
|
||||
|
||||
void clear() {
|
||||
deletePointers();
|
||||
std::list<TP *>().swap(list);
|
||||
if(autoDelete) {
|
||||
typename std::list<TP *>::const_iterator it = list.begin();
|
||||
for(; it != list.end(); ++it)
|
||||
delete *it;
|
||||
}
|
||||
list.clear();
|
||||
}
|
||||
|
||||
std::list<TP *> list;
|
||||
|
||||
private:
|
||||
void deletePointers() {
|
||||
if(!autoDelete)
|
||||
return;
|
||||
|
||||
typename std::list<TP *>::const_iterator it = list.begin();
|
||||
for(; it != list.end(); ++it)
|
||||
delete *it;
|
||||
}
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@ -98,19 +88,21 @@ private:
|
||||
|
||||
template <class T>
|
||||
List<T>::List()
|
||||
: d(new ListPrivate<T>())
|
||||
{
|
||||
d = new ListPrivate<T>;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
List<T>::List(const List<T> &l)
|
||||
: d(l.d)
|
||||
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>
|
||||
@ -187,7 +179,7 @@ template <class T>
|
||||
List<T> &List<T>::prepend(const List<T> &l)
|
||||
{
|
||||
detach();
|
||||
d->list.insert(d->list.begin(), l.d->list.begin(), l.d->list.end());
|
||||
d->list.insert(d->list.begin(), l.begin(), l.end());
|
||||
return *this;
|
||||
}
|
||||
|
||||
@ -200,7 +192,7 @@ List<T> &List<T>::clear()
|
||||
}
|
||||
|
||||
template <class T>
|
||||
uint List<T>::size() const
|
||||
TagLib::uint List<T>::size() const
|
||||
{
|
||||
return d->list.size();
|
||||
}
|
||||
@ -292,7 +284,13 @@ const T &List<T>::operator[](uint i) const
|
||||
template <class T>
|
||||
List<T> &List<T>::operator=(const List<T> &l)
|
||||
{
|
||||
if(&l == this)
|
||||
return *this;
|
||||
|
||||
if(d->deref())
|
||||
delete d;
|
||||
d = l.d;
|
||||
d->ref();
|
||||
return *this;
|
||||
}
|
||||
|
||||
@ -315,8 +313,10 @@ bool List<T>::operator!=(const List<T> &l) const
|
||||
template <class T>
|
||||
void List<T>::detach()
|
||||
{
|
||||
if(!d.unique())
|
||||
d.reset(new ListPrivate<T>(d->list));
|
||||
if(d->count() > 1) {
|
||||
d->deref();
|
||||
d = new ListPrivate<T>(d->list);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace TagLib
|
||||
|
@ -26,10 +26,9 @@
|
||||
#ifndef TAGLIB_MAP_H
|
||||
#define TAGLIB_MAP_H
|
||||
|
||||
#include "taglib.h"
|
||||
#include "trefcountptr.h"
|
||||
#include <map>
|
||||
|
||||
#include "taglib.h"
|
||||
|
||||
namespace TagLib {
|
||||
|
||||
@ -186,7 +185,7 @@ namespace TagLib {
|
||||
private:
|
||||
#ifndef DO_NOT_DOCUMENT
|
||||
template <class KeyP, class TP> class MapPrivate;
|
||||
RefCountPtr<MapPrivate<Key, T> > d;
|
||||
MapPrivate<Key, T> *d;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
@ -31,49 +31,36 @@ namespace TagLib {
|
||||
|
||||
template <class Key, class T>
|
||||
template <class KeyP, class TP>
|
||||
class Map<Key, T>::MapPrivate
|
||||
class Map<Key, T>::MapPrivate : public RefCounter
|
||||
{
|
||||
public:
|
||||
MapPrivate() {}
|
||||
|
||||
MapPrivate() : RefCounter() {}
|
||||
#ifdef WANT_CLASS_INSTANTIATION_OF_MAP
|
||||
|
||||
MapPrivate(const std::map<class KeyP, class TP> &m) : RefCounter(), map(m) {}
|
||||
|
||||
void clear() {
|
||||
std::map<class KeyP, class TP>().swap(map);
|
||||
}
|
||||
|
||||
MapPrivate(const std::map<class KeyP, class TP>& m) : RefCounter(), map(m) {}
|
||||
std::map<class KeyP, class TP> map;
|
||||
|
||||
#else
|
||||
|
||||
MapPrivate(const std::map<KeyP, TP>& m) : map(m) {}
|
||||
|
||||
void clear() {
|
||||
std::map<KeyP, TP>().swap(map);
|
||||
}
|
||||
|
||||
MapPrivate(const std::map<KeyP, TP>& m) : RefCounter(), map(m) {}
|
||||
std::map<KeyP, TP> map;
|
||||
|
||||
#endif
|
||||
};
|
||||
|
||||
template <class Key, class T>
|
||||
Map<Key, T>::Map()
|
||||
: d(new MapPrivate<Key, T>())
|
||||
{
|
||||
d = new MapPrivate<Key, T>;
|
||||
}
|
||||
|
||||
template <class Key, class T>
|
||||
Map<Key, T>::Map(const Map<Key, T> &m)
|
||||
: d(m.d)
|
||||
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>
|
||||
@ -162,7 +149,7 @@ Map<Key, T> &Map<Key,T>::erase(const Key &key)
|
||||
}
|
||||
|
||||
template <class Key, class T>
|
||||
uint Map<Key, T>::size() const
|
||||
TagLib::uint Map<Key, T>::size() const
|
||||
{
|
||||
return d->map.size();
|
||||
}
|
||||
@ -183,7 +170,13 @@ T &Map<Key, T>::operator[](const Key &key)
|
||||
template <class Key, class T>
|
||||
Map<Key, T> &Map<Key, T>::operator=(const Map<Key, T> &m)
|
||||
{
|
||||
if(&m == this)
|
||||
return *this;
|
||||
|
||||
if(d->deref())
|
||||
delete(d);
|
||||
d = m.d;
|
||||
d->ref();
|
||||
return *this;
|
||||
}
|
||||
|
||||
@ -194,8 +187,10 @@ Map<Key, T> &Map<Key, T>::operator=(const Map<Key, T> &m)
|
||||
template <class Key, class T>
|
||||
void Map<Key, T>::detach()
|
||||
{
|
||||
if(!d.unique())
|
||||
d.reset(new MapPrivate<Key, T>(d->map));
|
||||
if(d->count() > 1) {
|
||||
d->deref();
|
||||
d = new MapPrivate<Key, T>(d->map);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace TagLib
|
||||
} // namespace TagLib
|
||||
|
@ -1,257 +0,0 @@
|
||||
/***************************************************************************
|
||||
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_REFCOUNTPTR_H
|
||||
#define TAGLIB_REFCOUNTPTR_H
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#ifndef DO_NOT_DOCUMENT // Tell Doxygen to skip this class.
|
||||
/*!
|
||||
* \internal
|
||||
* This is just used as a smart pointer for shared classes in TagLib.
|
||||
*
|
||||
* \warning This <b>is not</b> part of the TagLib public API!
|
||||
*/
|
||||
|
||||
// RefCountPtr<T> is just an alias of shared_ptr<T> if it is available.
|
||||
|
||||
#if defined(HAVE_STD_SHARED_PTR)
|
||||
# include <memory>
|
||||
# define RefCountPtr std::tr1::shared_ptr
|
||||
|
||||
#elif defined(HAVE_TR1_SHARED_PTR)
|
||||
# include <tr1/memory>
|
||||
# define RefCountPtr std::tr1::shared_ptr
|
||||
|
||||
#elif defined(HAVE_BOOST_SHARED_PTR)
|
||||
# include <boost/shared_ptr.hpp>
|
||||
# define RefCountPtr boost::shared_ptr
|
||||
|
||||
#else
|
||||
# ifdef __APPLE__
|
||||
# include <libkern/OSAtomic.h>
|
||||
# define TAGLIB_ATOMIC_MAC
|
||||
# elif defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__)
|
||||
# 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
|
||||
|
||||
namespace TagLib {
|
||||
|
||||
// RefCountPtr<T> mimics std::shared_ptr<T> if it is not available.
|
||||
|
||||
template<typename T>
|
||||
class RefCountPtr
|
||||
{
|
||||
private:
|
||||
|
||||
// Counter base class. Provides a reference counter.
|
||||
|
||||
class CounterBase
|
||||
{
|
||||
public:
|
||||
CounterBase()
|
||||
: count(1)
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~CounterBase()
|
||||
{
|
||||
}
|
||||
|
||||
void addref()
|
||||
{
|
||||
increment(&count);
|
||||
}
|
||||
|
||||
void release()
|
||||
{
|
||||
if(decrement(&count) == 0) {
|
||||
dispose();
|
||||
delete this;
|
||||
}
|
||||
}
|
||||
|
||||
long use_count() const
|
||||
{
|
||||
return static_cast<long>(count);
|
||||
}
|
||||
|
||||
virtual void dispose() = 0;
|
||||
|
||||
private:
|
||||
# if defined(TAGLIB_ATOMIC_MAC)
|
||||
typedef volatile int32_t counter_t;
|
||||
|
||||
inline static void increment(counter_t *c) { OSAtomicIncrement32Barrier(c); }
|
||||
inline static counter_t decrement(counter_t *c) { return OSAtomicDecrement32Barrier(c); }
|
||||
|
||||
# elif defined(TAGLIB_ATOMIC_WIN)
|
||||
typedef volatile long counter_t;
|
||||
|
||||
inline static void increment(counter_t *c) { InterlockedIncrement(c); }
|
||||
inline static counter_t decrement(counter_t *c) { return InterlockedDecrement(c); }
|
||||
|
||||
# elif defined(TAGLIB_ATOMIC_GCC)
|
||||
typedef volatile int counter_t;
|
||||
|
||||
inline static void increment(counter_t *c) { __sync_add_and_fetch(c, 1); }
|
||||
inline static counter_t decrement(counter_t *c) { return __sync_sub_and_fetch(c, 1); }
|
||||
|
||||
# else
|
||||
typedef uint counter_t;
|
||||
|
||||
inline static void increment(counter_t *c) { ++(*c) }
|
||||
inline static counter_t decrement(counter_t *c) { return --(*c); }
|
||||
|
||||
# endif
|
||||
|
||||
counter_t count;
|
||||
};
|
||||
|
||||
// Counter impl class. Provides a dynamic deleter.
|
||||
|
||||
template <typename U>
|
||||
class CounterImpl : public CounterBase
|
||||
{
|
||||
public:
|
||||
CounterImpl(U *p)
|
||||
: p(p)
|
||||
{
|
||||
}
|
||||
|
||||
virtual void dispose()
|
||||
{
|
||||
delete p;
|
||||
}
|
||||
|
||||
U *get() const
|
||||
{
|
||||
return p;
|
||||
}
|
||||
|
||||
private:
|
||||
U *p;
|
||||
};
|
||||
|
||||
public:
|
||||
template <typename U>
|
||||
explicit RefCountPtr(U *p)
|
||||
: counter(new CounterImpl<U>(p))
|
||||
{
|
||||
}
|
||||
|
||||
RefCountPtr(const RefCountPtr &x)
|
||||
{
|
||||
counter = x.counter;
|
||||
counter->addref();
|
||||
}
|
||||
|
||||
~RefCountPtr()
|
||||
{
|
||||
counter->release();
|
||||
}
|
||||
|
||||
T *get() const
|
||||
{
|
||||
return static_cast<CounterImpl<T>*>(counter)->get();
|
||||
}
|
||||
|
||||
long use_count() const
|
||||
{
|
||||
return counter->use_count();
|
||||
}
|
||||
|
||||
bool unique() const
|
||||
{
|
||||
return (use_count() == 1);
|
||||
}
|
||||
|
||||
template <typename U>
|
||||
void reset(U *p)
|
||||
{
|
||||
if(get() != p)
|
||||
{
|
||||
counter->release();
|
||||
counter = new CounterImpl<U>(p);
|
||||
}
|
||||
}
|
||||
|
||||
RefCountPtr<T> &operator=(const RefCountPtr<T> &x)
|
||||
{
|
||||
if(get() != x.get())
|
||||
{
|
||||
counter->release();
|
||||
|
||||
counter = x.counter;
|
||||
counter->addref();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
T& operator*() const
|
||||
{
|
||||
return *get();
|
||||
}
|
||||
|
||||
T* operator->() const
|
||||
{
|
||||
return get();
|
||||
}
|
||||
|
||||
bool operator==(const RefCountPtr<T> &x) const
|
||||
{
|
||||
return (get() == x.get());
|
||||
}
|
||||
|
||||
bool operator!=(const RefCountPtr<T> &x) const
|
||||
{
|
||||
return !operator==(x);
|
||||
}
|
||||
|
||||
operator bool() const
|
||||
{
|
||||
return (get() != 0);
|
||||
}
|
||||
|
||||
private:
|
||||
CounterBase *counter;
|
||||
};
|
||||
}
|
||||
#endif // TAGLIB_USE_CXX11
|
||||
|
||||
#endif // DO_NOT_DOCUMENT
|
||||
|
||||
#endif
|
@ -30,6 +30,7 @@
|
||||
#include "tstringlist.h"
|
||||
#include "tbyteswap.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <string.h>
|
||||
|
||||
// Determine if the compiler supports codecvt.
|
||||
@ -55,20 +56,23 @@ namespace {
|
||||
|
||||
namespace TagLib {
|
||||
|
||||
class String::StringPrivate
|
||||
class String::StringPrivate : public RefCounter
|
||||
{
|
||||
public:
|
||||
StringPrivate()
|
||||
: RefCounter()
|
||||
{
|
||||
}
|
||||
|
||||
StringPrivate(const wstring &s)
|
||||
: data(s)
|
||||
: RefCounter()
|
||||
, data(s)
|
||||
{
|
||||
}
|
||||
|
||||
StringPrivate(uint n, wchar_t c)
|
||||
: data(static_cast<size_t>(n), c)
|
||||
: RefCounter()
|
||||
, data(static_cast<size_t>(n), c)
|
||||
{
|
||||
}
|
||||
|
||||
@ -95,6 +99,7 @@ String::String()
|
||||
String::String(const String &s)
|
||||
: d(s.d)
|
||||
{
|
||||
d->ref();
|
||||
}
|
||||
|
||||
String::String(const std::string &s, Type t)
|
||||
@ -177,6 +182,8 @@ String::String(const ByteVector &v, Type t)
|
||||
|
||||
String::~String()
|
||||
{
|
||||
if(d->deref())
|
||||
delete d;
|
||||
}
|
||||
|
||||
std::string String::to8Bit(bool unicode) const
|
||||
@ -609,13 +616,22 @@ String &String::operator+=(char c)
|
||||
|
||||
String &String::operator=(const String &s)
|
||||
{
|
||||
if(&s == this)
|
||||
return *this;
|
||||
|
||||
if(d->deref())
|
||||
delete d;
|
||||
d = s.d;
|
||||
d->ref();
|
||||
return *this;
|
||||
}
|
||||
|
||||
String &String::operator=(const std::string &s)
|
||||
{
|
||||
d.reset(new StringPrivate());
|
||||
if(d->deref())
|
||||
delete d;
|
||||
|
||||
d = new StringPrivate;
|
||||
copyFromLatin1(s.c_str(), s.length());
|
||||
|
||||
return *this;
|
||||
@ -623,33 +639,45 @@ String &String::operator=(const std::string &s)
|
||||
|
||||
String &String::operator=(const wstring &s)
|
||||
{
|
||||
d.reset(new StringPrivate(s));
|
||||
if(d->deref())
|
||||
delete d;
|
||||
d = new StringPrivate(s);
|
||||
return *this;
|
||||
}
|
||||
|
||||
String &String::operator=(const wchar_t *s)
|
||||
{
|
||||
d.reset(new StringPrivate());
|
||||
copyFromUTF16(s, ::wcslen(s), WCharByteOrder);
|
||||
if(d->deref())
|
||||
delete d;
|
||||
|
||||
d = new StringPrivate(s);
|
||||
return *this;
|
||||
}
|
||||
|
||||
String &String::operator=(char c)
|
||||
{
|
||||
d.reset(new StringPrivate(1, static_cast<uchar>(c)));
|
||||
if(d->deref())
|
||||
delete d;
|
||||
|
||||
d = new StringPrivate(1, static_cast<uchar>(c));
|
||||
return *this;
|
||||
}
|
||||
|
||||
String &String::operator=(wchar_t c)
|
||||
{
|
||||
d.reset(new StringPrivate(1, static_cast<uchar>(c)));
|
||||
if(d->deref())
|
||||
delete d;
|
||||
|
||||
d = new StringPrivate(1, static_cast<uchar>(c));
|
||||
return *this;
|
||||
}
|
||||
|
||||
String &String::operator=(const char *s)
|
||||
{
|
||||
d.reset(new StringPrivate());
|
||||
if(d->deref())
|
||||
delete d;
|
||||
|
||||
d = new StringPrivate;
|
||||
copyFromLatin1(s, ::strlen(s));
|
||||
|
||||
return *this;
|
||||
@ -657,7 +685,10 @@ String &String::operator=(const char *s)
|
||||
|
||||
String &String::operator=(const ByteVector &v)
|
||||
{
|
||||
d.reset(new StringPrivate());
|
||||
if(d->deref())
|
||||
delete d;
|
||||
|
||||
d = new StringPrivate;
|
||||
copyFromLatin1(v.data(), v.size());
|
||||
|
||||
// If we hit a null in the ByteVector, shrink the string again.
|
||||
@ -677,8 +708,10 @@ bool String::operator<(const String &s) const
|
||||
|
||||
void String::detach()
|
||||
{
|
||||
if(!d.unique())
|
||||
d.reset(new StringPrivate(d->data));
|
||||
if(d->count() > 1) {
|
||||
d->deref();
|
||||
d = new StringPrivate(d->data);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -26,8 +26,12 @@
|
||||
#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
|
||||
@ -481,7 +485,7 @@ namespace TagLib {
|
||||
static const Type WCharByteOrder;
|
||||
|
||||
class StringPrivate;
|
||||
RefCountPtr<StringPrivate> d;
|
||||
StringPrivate *d;
|
||||
};
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user