From 1f4e06ea7c60e0a72f04290abf6f57db803f3a12 Mon Sep 17 00:00:00 2001 From: Tsuda kageyu Date: Wed, 17 Apr 2013 22:54:56 +0900 Subject: [PATCH] Revert changes concerning the smart pointer --- ConfigureChecks.cmake | 25 +--- config-taglib.h.cmake | 4 - taglib/CMakeLists.txt | 5 - taglib/asf/asfattribute.cpp | 24 +-- taglib/asf/asfattribute.h | 2 +- taglib/asf/asfpicture.cpp | 14 +- taglib/asf/asfpicture.h | 8 +- taglib/fileref.cpp | 66 ++++----- taglib/fileref.h | 2 +- taglib/mp4/mp4coverart.cpp | 14 +- taglib/mp4/mp4coverart.h | 2 +- taglib/mp4/mp4item.cpp | 32 ++-- taglib/mp4/mp4item.h | 2 +- taglib/mpeg/mpegheader.cpp | 17 ++- taglib/mpeg/mpegheader.h | 3 +- taglib/toolkit/taglib.h | 66 ++++++++- taglib/toolkit/tbytevector.cpp | 65 +++++++-- taglib/toolkit/tbytevector.h | 6 +- taglib/toolkit/tiostream.h | 5 - taglib/toolkit/tlist.h | 4 +- taglib/toolkit/tlist.tcc | 52 +++---- taglib/toolkit/tmap.h | 5 +- taglib/toolkit/tmap.tcc | 47 +++--- taglib/toolkit/trefcountptr.h | 257 --------------------------------- taglib/toolkit/tstring.cpp | 59 ++++++-- taglib/toolkit/tstring.h | 6 +- 26 files changed, 329 insertions(+), 463 deletions(-) delete mode 100644 taglib/toolkit/trefcountptr.h diff --git a/ConfigureChecks.cmake b/ConfigureChecks.cmake index ec0da6d1..e4a6d1fa 100644 --- a/ConfigureChecks.cmake +++ b/ConfigureChecks.cmake @@ -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 is defined regardless of C++11 support. - -check_cxx_source_compiles(" - #include - int main() { std::tr1::shared_ptr x; return 0; } -" HAVE_STD_SHARED_PTR) - -check_cxx_source_compiles(" - #include - int main() { std::tr1::shared_ptr x; return 0; } -" HAVE_TR1_SHARED_PTR) - -check_cxx_source_compiles(" - #include - int main() { boost::shared_ptr 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() diff --git a/config-taglib.h.cmake b/config-taglib.h.cmake index 8ce6798b..9c2f487d 100644 --- a/config-taglib.h.cmake +++ b/config-taglib.h.cmake @@ -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 diff --git a/taglib/CMakeLists.txt b/taglib/CMakeLists.txt index dab3430e..a940caf5 100644 --- a/taglib/CMakeLists.txt +++ b/taglib/CMakeLists.txt @@ -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} diff --git a/taglib/asf/asfattribute.cpp b/taglib/asf/asfattribute.cpp index 4ba2689b..2cfada7b 100644 --- a/taglib/asf/asfattribute.cpp +++ b/taglib/asf/asfattribute.cpp @@ -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; } diff --git a/taglib/asf/asfattribute.h b/taglib/asf/asfattribute.h index ca26aec3..54eb0c7d 100644 --- a/taglib/asf/asfattribute.h +++ b/taglib/asf/asfattribute.h @@ -194,7 +194,7 @@ namespace TagLib ByteVector render(const String &name, int kind = 0) const; class AttributePrivate; - RefCountPtr d; + AttributePrivate *d; }; } diff --git a/taglib/asf/asfpicture.cpp b/taglib/asf/asfpicture.cpp index 82a38b6b..c36ffa3a 100644 --- a/taglib/asf/asfpicture.cpp +++ b/taglib/asf/asfpicture.cpp @@ -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; } diff --git a/taglib/asf/asfpicture.h b/taglib/asf/asfpicture.h index aa838974..aa0a060c 100644 --- a/taglib/asf/asfpicture.h +++ b/taglib/asf/asfpicture.h @@ -207,10 +207,10 @@ namespace TagLib static Picture fromInvalid(); friend class Attribute; #endif - private: - class PicturePrivate; - RefCountPtr d; - }; + private: + class PicturePrivate; + PicturePrivate *d; + }; } } diff --git a/taglib/fileref.cpp b/taglib/fileref.cpp index f3b4ef3c..859f3155 100644 --- a/taglib/fileref.cpp +++ b/taglib/fileref.cpp @@ -31,10 +31,6 @@ #include #endif -#ifdef _WIN32 -# include -#endif - #include #include #include @@ -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; static List fileTypeResolvers; }; @@ -77,28 +76,30 @@ List 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") diff --git a/taglib/fileref.h b/taglib/fileref.h index 907727c7..0f0c21a4 100644 --- a/taglib/fileref.h +++ b/taglib/fileref.h @@ -255,7 +255,7 @@ namespace TagLib { private: class FileRefPrivate; - RefCountPtr d; + FileRefPrivate *d; }; } // namespace TagLib diff --git a/taglib/mp4/mp4coverart.cpp b/taglib/mp4/mp4coverart.cpp index 5b6e6e23..928e3c4a 100644 --- a/taglib/mp4/mp4coverart.cpp +++ b/taglib/mp4/mp4coverart.cpp @@ -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 diff --git a/taglib/mp4/mp4coverart.h b/taglib/mp4/mp4coverart.h index b6b44c49..64115b45 100644 --- a/taglib/mp4/mp4coverart.h +++ b/taglib/mp4/mp4coverart.h @@ -63,7 +63,7 @@ namespace TagLib { private: class CoverArtPrivate; - RefCountPtr d; + CoverArtPrivate *d; }; typedef List CoverArtList; diff --git a/taglib/mp4/mp4item.cpp b/taglib/mp4/mp4item.cpp index 6a303652..af2cc65c 100644 --- a/taglib/mp4/mp4item.cpp +++ b/taglib/mp4/mp4item.cpp @@ -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; } diff --git a/taglib/mp4/mp4item.h b/taglib/mp4/mp4item.h index 3b4e23cd..be7aa1a1 100644 --- a/taglib/mp4/mp4item.h +++ b/taglib/mp4/mp4item.h @@ -73,7 +73,7 @@ namespace TagLib { private: class ItemPrivate; - RefCountPtr d; + ItemPrivate *d; }; } diff --git a/taglib/mpeg/mpegheader.cpp b/taglib/mpeg/mpegheader.cpp index bc98f4c9..c715dbc1 100644 --- a/taglib/mpeg/mpegheader.cpp +++ b/taglib/mpeg/mpegheader.cpp @@ -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; } diff --git a/taglib/mpeg/mpegheader.h b/taglib/mpeg/mpegheader.h index 7a352ed7..020ebd06 100644 --- a/taglib/mpeg/mpegheader.h +++ b/taglib/mpeg/mpegheader.h @@ -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 d; + HeaderPrivate *d; }; } } diff --git a/taglib/toolkit/taglib.h b/taglib/toolkit/taglib.h index 03d16724..dd4ee69d 100755 --- a/taglib/toolkit/taglib.h +++ b/taglib/toolkit/taglib.h @@ -45,11 +45,23 @@ #include #include -#ifdef _WIN32 -# if !defined(NOMINMAX) -# define NOMINMAX -# endif -# include +#ifdef __APPLE__ +# include +# define TAGLIB_ATOMIC_MAC +#elif defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) +# if !defined(NOMINMAX) +# define NOMINMAX +# endif +# include +# 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 +# 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 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 is not part of the TagLib public API! + */ + + class RefCounter + { + public: + RefCounter() : refCount(1) {} + +#ifdef TAGLIB_ATOMIC_MAC + void ref() { OSAtomicIncrement32Barrier(const_cast(&refCount)); } + bool deref() { return ! OSAtomicDecrement32Barrier(const_cast(&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 + } /*! diff --git a/taglib/toolkit/tbytevector.cpp b/taglib/toolkit/tbytevector.cpp index aa76d6bf..ca65cfaa 100644 --- a/taglib/toolkit/tbytevector.cpp +++ b/taglib/toolkit/tbytevector.cpp @@ -236,7 +236,7 @@ ByteVector fromNumber(T value, bool mostSignificantByteFirst) return ByteVector(reinterpret_cast(&value), size); } -class DataPrivate +class DataPrivate : public RefCounter { public: DataPrivate() @@ -262,39 +262,45 @@ public: std::vector data; }; -class ByteVector::ByteVectorPrivate +class ByteVector::ByteVectorPrivate : public RefCounter { public: ByteVectorPrivate() - : data(new DataPrivate()) + : RefCounter() + , data(new DataPrivate()) , offset(0) , length(0) { } - ByteVectorPrivate(RefCountPtr 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 &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 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); + } } } diff --git a/taglib/toolkit/tbytevector.h b/taglib/toolkit/tbytevector.h index cf7f66d5..ca810130 100644 --- a/taglib/toolkit/tbytevector.h +++ b/taglib/toolkit/tbytevector.h @@ -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 #include @@ -446,7 +446,7 @@ namespace TagLib { private: class ByteVectorPrivate; - RefCountPtr d; + ByteVectorPrivate *d; }; } diff --git a/taglib/toolkit/tiostream.h b/taglib/toolkit/tiostream.h index ce1a0d0d..3e7de22a 100644 --- a/taglib/toolkit/tiostream.h +++ b/taglib/toolkit/tiostream.h @@ -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; diff --git a/taglib/toolkit/tlist.h b/taglib/toolkit/tlist.h index 535b374f..0099dad5 100644 --- a/taglib/toolkit/tlist.h +++ b/taglib/toolkit/tlist.h @@ -27,7 +27,7 @@ #define TAGLIB_LIST_H #include "taglib.h" -#include "trefcountptr.h" + #include namespace TagLib { @@ -243,7 +243,7 @@ namespace TagLib { private: #ifndef DO_NOT_DOCUMENT template class ListPrivate; - RefCountPtr > d; + ListPrivate *d; #endif }; diff --git a/taglib/toolkit/tlist.tcc b/taglib/toolkit/tlist.tcc index 17d68a5a..37817f05 100644 --- a/taglib/toolkit/tlist.tcc +++ b/taglib/toolkit/tlist.tcc @@ -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 List::ListPrivate : public ListPrivateBase public: ListPrivate() : ListPrivateBase() {} ListPrivate(const std::list &l) : ListPrivateBase(), list(l) {} - void clear() { - std::list().swap(list); + list.clear(); } std::list list; }; @@ -69,27 +68,18 @@ template class List::ListPrivate : public ListPrivateBase public: ListPrivate() : ListPrivateBase() {} ListPrivate(const std::list &l) : ListPrivateBase(), list(l) {} - ~ListPrivate() { - deletePointers(); + clear(); } - void clear() { - deletePointers(); - std::list().swap(list); + if(autoDelete) { + typename std::list::const_iterator it = list.begin(); + for(; it != list.end(); ++it) + delete *it; + } + list.clear(); } - std::list list; - -private: - void deletePointers() { - if(!autoDelete) - return; - - typename std::list::const_iterator it = list.begin(); - for(; it != list.end(); ++it) - delete *it; - } }; //////////////////////////////////////////////////////////////////////////////// @@ -98,19 +88,21 @@ private: template List::List() - : d(new ListPrivate()) { + d = new ListPrivate; } template -List::List(const List &l) - : d(l.d) +List::List(const List &l) : d(l.d) { + d->ref(); } template List::~List() { + if(d->deref()) + delete d; } template @@ -187,7 +179,7 @@ template List &List::prepend(const List &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 &List::clear() } template -uint List::size() const +TagLib::uint List::size() const { return d->list.size(); } @@ -292,7 +284,13 @@ const T &List::operator[](uint i) const template List &List::operator=(const List &l) { + if(&l == this) + return *this; + + if(d->deref()) + delete d; d = l.d; + d->ref(); return *this; } @@ -315,8 +313,10 @@ bool List::operator!=(const List &l) const template void List::detach() { - if(!d.unique()) - d.reset(new ListPrivate(d->list)); + if(d->count() > 1) { + d->deref(); + d = new ListPrivate(d->list); + } } } // namespace TagLib diff --git a/taglib/toolkit/tmap.h b/taglib/toolkit/tmap.h index b5748e66..a7d99303 100644 --- a/taglib/toolkit/tmap.h +++ b/taglib/toolkit/tmap.h @@ -26,10 +26,9 @@ #ifndef TAGLIB_MAP_H #define TAGLIB_MAP_H -#include "taglib.h" -#include "trefcountptr.h" #include +#include "taglib.h" namespace TagLib { @@ -186,7 +185,7 @@ namespace TagLib { private: #ifndef DO_NOT_DOCUMENT template class MapPrivate; - RefCountPtr > d; + MapPrivate *d; #endif }; diff --git a/taglib/toolkit/tmap.tcc b/taglib/toolkit/tmap.tcc index 783f99cc..0f2b9933 100644 --- a/taglib/toolkit/tmap.tcc +++ b/taglib/toolkit/tmap.tcc @@ -31,49 +31,36 @@ namespace TagLib { template template -class Map::MapPrivate +class Map::MapPrivate : public RefCounter { public: - MapPrivate() {} - + MapPrivate() : RefCounter() {} #ifdef WANT_CLASS_INSTANTIATION_OF_MAP - - MapPrivate(const std::map &m) : RefCounter(), map(m) {} - - void clear() { - std::map().swap(map); - } - + MapPrivate(const std::map& m) : RefCounter(), map(m) {} std::map map; - #else - - MapPrivate(const std::map& m) : map(m) {} - - void clear() { - std::map().swap(map); - } - + MapPrivate(const std::map& m) : RefCounter(), map(m) {} std::map map; - #endif }; template Map::Map() - : d(new MapPrivate()) { + d = new MapPrivate; } template -Map::Map(const Map &m) - : d(m.d) +Map::Map(const Map &m) : d(m.d) { + d->ref(); } template Map::~Map() { + if(d->deref()) + delete(d); } template @@ -162,7 +149,7 @@ Map &Map::erase(const Key &key) } template -uint Map::size() const +TagLib::uint Map::size() const { return d->map.size(); } @@ -183,7 +170,13 @@ T &Map::operator[](const Key &key) template Map &Map::operator=(const Map &m) { + if(&m == this) + return *this; + + if(d->deref()) + delete(d); d = m.d; + d->ref(); return *this; } @@ -194,8 +187,10 @@ Map &Map::operator=(const Map &m) template void Map::detach() { - if(!d.unique()) - d.reset(new MapPrivate(d->map)); + if(d->count() > 1) { + d->deref(); + d = new MapPrivate(d->map); + } } -} // namespace TagLib \ No newline at end of file +} // namespace TagLib diff --git a/taglib/toolkit/trefcountptr.h b/taglib/toolkit/trefcountptr.h deleted file mode 100644 index 492afcd5..00000000 --- a/taglib/toolkit/trefcountptr.h +++ /dev/null @@ -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 is not part of the TagLib public API! - */ - -// RefCountPtr is just an alias of shared_ptr if it is available. - -#if defined(HAVE_STD_SHARED_PTR) -# include -# define RefCountPtr std::tr1::shared_ptr - -#elif defined(HAVE_TR1_SHARED_PTR) -# include -# define RefCountPtr std::tr1::shared_ptr - -#elif defined(HAVE_BOOST_SHARED_PTR) -# include -# define RefCountPtr boost::shared_ptr - -#else -# ifdef __APPLE__ -# include -# 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 -# define TAGLIB_ATOMIC_GCC -# endif - -namespace TagLib { - - // RefCountPtr mimics std::shared_ptr if it is not available. - - template - 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(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 - 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 - explicit RefCountPtr(U *p) - : counter(new CounterImpl(p)) - { - } - - RefCountPtr(const RefCountPtr &x) - { - counter = x.counter; - counter->addref(); - } - - ~RefCountPtr() - { - counter->release(); - } - - T *get() const - { - return static_cast*>(counter)->get(); - } - - long use_count() const - { - return counter->use_count(); - } - - bool unique() const - { - return (use_count() == 1); - } - - template - void reset(U *p) - { - if(get() != p) - { - counter->release(); - counter = new CounterImpl(p); - } - } - - RefCountPtr &operator=(const RefCountPtr &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 &x) const - { - return (get() == x.get()); - } - - bool operator!=(const RefCountPtr &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 diff --git a/taglib/toolkit/tstring.cpp b/taglib/toolkit/tstring.cpp index 14abae2f..219d3daf 100644 --- a/taglib/toolkit/tstring.cpp +++ b/taglib/toolkit/tstring.cpp @@ -30,6 +30,7 @@ #include "tstringlist.h" #include "tbyteswap.h" +#include #include // 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(n), c) + : RefCounter() + , data(static_cast(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(c))); + if(d->deref()) + delete d; + + d = new StringPrivate(1, static_cast(c)); return *this; } String &String::operator=(wchar_t c) { - d.reset(new StringPrivate(1, static_cast(c))); + if(d->deref()) + delete d; + + d = new StringPrivate(1, static_cast(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); + } } //////////////////////////////////////////////////////////////////////////////// diff --git a/taglib/toolkit/tstring.h b/taglib/toolkit/tstring.h index 652c6ca7..150d7c37 100644 --- a/taglib/toolkit/tstring.h +++ b/taglib/toolkit/tstring.h @@ -26,8 +26,12 @@ #ifndef TAGLIB_STRING_H #define TAGLIB_STRING_H +#include "taglib_export.h" +#include "taglib.h" #include "tbytevector.h" + #include +#include /*! * \relates TagLib::String @@ -481,7 +485,7 @@ namespace TagLib { static const Type WCharByteOrder; class StringPrivate; - RefCountPtr d; + StringPrivate *d; }; } -- 2.40.0