# 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()
/* 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
toolkit/tmap.tcc
toolkit/tpropertymap.h
toolkit/tbyteswap.h
- toolkit/trefcountptr.h
mpeg/mpegfile.h
mpeg/mpegproperties.h
mpeg/mpegheader.h
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}
using namespace TagLib;
-class ASF::Attribute::AttributePrivate
+class ASF::Attribute::AttributePrivate : public RefCounter
{
public:
AttributePrivate()
////////////////////////////////////////////////////////////////////////////////
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;
}
ByteVector render(const String &name, int kind = 0) const;
class AttributePrivate;
- RefCountPtr<AttributePrivate> d;
+ AttributePrivate *d;
};
}
using namespace TagLib;
-class ASF::Picture::PicturePrivate
+class ASF::Picture::PicturePrivate : public RefCounter
{
public:
bool valid;
////////////////////////////////////////////////////////////////////////////////
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
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;
}
static Picture fromInvalid();
friend class Attribute;
#endif
- private:
- class PicturePrivate;
- RefCountPtr<PicturePrivate> d;
- };
+ private:
+ class PicturePrivate;
+ PicturePrivate *d;
+ };
}
}
#include <config.h>
#endif
-#ifdef _WIN32
-# include <Shlwapi.h>
-#endif
-
#include <tfile.h>
#include <tstring.h>
#include <tdebug.h>
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;
};
////////////////////////////////////////////////////////////////////////////////
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
File *FileRef::file() const
{
- return d->file.get();
+ return d->file;
}
bool FileRef::save()
FileRef &FileRef::operator=(const FileRef &ref)
{
+ if(&ref == this)
+ return *this;
+
+ if(d->deref())
+ delete d;
+
d = ref.d;
+ d->ref();
+
return *this;
}
// 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")
private:
class FileRefPrivate;
- RefCountPtr<FileRefPrivate> d;
+ FileRefPrivate *d;
};
} // namespace TagLib
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
private:
class CoverArtPrivate;
- RefCountPtr<CoverArtPrivate> d;
+ CoverArtPrivate *d;
};
typedef List<CoverArt> CoverArtList;
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;
};
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;
}
private:
class ItemPrivate;
- RefCountPtr<ItemPrivate> d;
+ ItemPrivate *d;
};
}
using namespace TagLib;
-class MPEG::Header::HeaderPrivate
+class MPEG::Header::HeaderPrivate : public RefCounter
{
public:
HeaderPrivate() :
////////////////////////////////////////////////////////////////////////////////
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
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;
}
#define TAGLIB_MPEGHEADER_H
#include "taglib_export.h"
-#include "trefcountptr.h"
namespace TagLib {
void parse(const ByteVector &data);
class HeaderPrivate;
- RefCountPtr<HeaderPrivate> d;
+ HeaderPrivate *d;
};
}
}
#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.
* 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
+
}
/*!
return ByteVector(reinterpret_cast<const char *>(&value), size);
}
-class DataPrivate
+class DataPrivate : public RefCounter
{
public:
DataPrivate()
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)
{
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;
};
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)
ByteVector::~ByteVector()
{
+ if(d->deref())
+ delete d;
}
ByteVector &ByteVector::setData(const char *s, uint length)
}
// replace private data:
- d.reset(newData);
+ if(d->deref())
+ delete d;
+
+ d = newData;
return *this;
}
ByteVector &ByteVector::operator=(const ByteVector &v)
{
+ if(&v == this)
+ return *this;
+
+ if(d->deref())
+ delete d;
+
d = v.d;
+ d->ref();
return *this;
}
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);
+ }
}
}
#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>
private:
class ByteVectorPrivate;
- RefCountPtr<ByteVectorPrivate> d;
+ ByteVectorPrivate *d;
};
}
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;
#define TAGLIB_LIST_H
#include "taglib.h"
-#include "trefcountptr.h"
+
#include <list>
namespace TagLib {
private:
#ifndef DO_NOT_DOCUMENT
template <class TP> class ListPrivate;
- RefCountPtr<ListPrivate<T> > d;
+ ListPrivate<T> *d;
#endif
};
// 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) {}
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;
};
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;
- }
};
////////////////////////////////////////////////////////////////////////////////
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>
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;
}
}
template <class T>
-uint List<T>::size() const
+TagLib::uint List<T>::size() const
{
return d->list.size();
}
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;
}
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
#ifndef TAGLIB_MAP_H
#define TAGLIB_MAP_H
-#include "taglib.h"
-#include "trefcountptr.h"
#include <map>
+#include "taglib.h"
namespace TagLib {
private:
#ifndef DO_NOT_DOCUMENT
template <class KeyP, class TP> class MapPrivate;
- RefCountPtr<MapPrivate<Key, T> > d;
+ MapPrivate<Key, T> *d;
#endif
};
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>
}
template <class Key, class T>
-uint Map<Key, T>::size() const
+TagLib::uint Map<Key, T>::size() const
{
return d->map.size();
}
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;
}
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
\ No newline at end of file
+} // namespace TagLib
+++ /dev/null
-/***************************************************************************
- 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
\ No newline at end of file
#include "tstringlist.h"
#include "tbyteswap.h"
+#include <iostream>
#include <string.h>
// Determine if the compiler supports codecvt.
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)
{
}
String::String(const String &s)
: d(s.d)
{
+ d->ref();
}
String::String(const std::string &s, Type t)
String::~String()
{
+ if(d->deref())
+ delete d;
}
std::string String::to8Bit(bool unicode) const
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;
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;
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.
void String::detach()
{
- if(!d.unique())
- d.reset(new StringPrivate(d->data));
+ if(d->count() > 1) {
+ d->deref();
+ d = new StringPrivate(d->data);
+ }
}
////////////////////////////////////////////////////////////////////////////////
#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
static const Type WCharByteOrder;
class StringPrivate;
- RefCountPtr<StringPrivate> d;
+ StringPrivate *d;
};
}