mirror of
https://github.com/taglib/taglib.git
synced 2025-11-15 14:12:56 -05:00
Merge pull request #214 from TsudaKageyu/removeptr
Removed smart pointers from public headers
This commit is contained in:
@ -118,54 +118,113 @@ if(NOT HAVE_GCC_BYTESWAP_16 OR NOT HAVE_GCC_BYTESWAP_32 OR NOT HAVE_GCC_BYTESWAP
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Determine where shared_ptr<T> is defined regardless of C++11 support.
|
||||
|
||||
check_cxx_source_compiles("
|
||||
#include <memory>
|
||||
int main() { std::shared_ptr<int> x; return 0; }
|
||||
" HAVE_STD_SHARED_PTR)
|
||||
|
||||
if(NOT 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)
|
||||
|
||||
if(NOT 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)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Determine where unique_ptr<T> or scoped_ptr<T> is defined regardless of C++11 support.
|
||||
|
||||
check_cxx_source_compiles("
|
||||
#include <memory>
|
||||
int main() { std::unique_ptr<int> x; return 0; }
|
||||
" HAVE_STD_UNIQUE_PTR)
|
||||
|
||||
if(NOT HAVE_STD_UNIQUE_PTR)
|
||||
check_cxx_source_compiles("
|
||||
#include <boost/scoped_ptr.hpp>
|
||||
int main() { boost::scoped_ptr<int> x; return 0; }
|
||||
" HAVE_BOOST_SCOPED_PTR)
|
||||
endif()
|
||||
|
||||
# Determine which kind of atomic operations your compiler supports.
|
||||
|
||||
check_cxx_source_compiles("
|
||||
#include <atomic>
|
||||
int main() {
|
||||
volatile int x;
|
||||
__sync_add_and_fetch(&x, 1);
|
||||
int y = __sync_sub_and_fetch(&x, 1);
|
||||
std::atomic<unsigned int> x;
|
||||
x.fetch_add(1);
|
||||
x.fetch_sub(1);
|
||||
return 0;
|
||||
}
|
||||
" HAVE_GCC_ATOMIC)
|
||||
" HAVE_STD_ATOMIC)
|
||||
|
||||
if(NOT HAVE_GCC_ATOMIC)
|
||||
if(NOT HAVE_STD_ATOMIC)
|
||||
check_cxx_source_compiles("
|
||||
#include <libkern/OSAtomic.h>
|
||||
#include <boost/atomic.hpp>
|
||||
int main() {
|
||||
volatile int32_t x;
|
||||
OSAtomicIncrement32Barrier(&x);
|
||||
int32_t y = OSAtomicDecrement32Barrier(&x);
|
||||
boost::atomic<unsigned int> x(1);
|
||||
x.fetch_add(1);
|
||||
x.fetch_sub(1);
|
||||
return 0;
|
||||
}
|
||||
" HAVE_MAC_ATOMIC)
|
||||
" HAVE_BOOST_ATOMIC)
|
||||
|
||||
if(NOT HAVE_MAC_ATOMIC)
|
||||
if(NOT HAVE_BOOST_ATOMIC)
|
||||
check_cxx_source_compiles("
|
||||
#include <windows.h>
|
||||
int main() {
|
||||
volatile LONG x;
|
||||
InterlockedIncrement(&x);
|
||||
LONG y = InterlockedDecrement(&x);
|
||||
volatile int x;
|
||||
__sync_add_and_fetch(&x, 1);
|
||||
int y = __sync_sub_and_fetch(&x, 1);
|
||||
return 0;
|
||||
}
|
||||
" HAVE_WIN_ATOMIC)
|
||||
" HAVE_GCC_ATOMIC)
|
||||
|
||||
if(NOT HAVE_WIN_ATOMIC)
|
||||
if(NOT HAVE_GCC_ATOMIC)
|
||||
check_cxx_source_compiles("
|
||||
#include <ia64intrin.h>
|
||||
#include <libkern/OSAtomic.h>
|
||||
int main() {
|
||||
volatile int x;
|
||||
__sync_add_and_fetch(&x, 1);
|
||||
int y = __sync_sub_and_fetch(&x, 1);
|
||||
volatile int32_t x;
|
||||
OSAtomicIncrement32Barrier(&x);
|
||||
int32_t y = OSAtomicDecrement32Barrier(&x);
|
||||
return 0;
|
||||
}
|
||||
" HAVE_IA64_ATOMIC)
|
||||
" HAVE_MAC_ATOMIC)
|
||||
|
||||
if(NOT HAVE_MAC_ATOMIC)
|
||||
check_cxx_source_compiles("
|
||||
#include <windows.h>
|
||||
int main() {
|
||||
volatile LONG x;
|
||||
InterlockedIncrement(&x);
|
||||
LONG y = InterlockedDecrement(&x);
|
||||
return 0;
|
||||
}
|
||||
" HAVE_WIN_ATOMIC)
|
||||
|
||||
if(NOT HAVE_WIN_ATOMIC)
|
||||
check_cxx_source_compiles("
|
||||
#include <ia64intrin.h>
|
||||
int main() {
|
||||
volatile int x;
|
||||
__sync_add_and_fetch(&x, 1);
|
||||
int y = __sync_sub_and_fetch(&x, 1);
|
||||
return 0;
|
||||
}
|
||||
" HAVE_IA64_ATOMIC)
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Determine whether your compiler supports some safer version of sprintf.
|
||||
# Determine whether your compiler supports snpritf or sprintf_s.
|
||||
|
||||
check_cxx_source_compiles("
|
||||
#include <cstdio>
|
||||
@ -198,52 +257,6 @@ else()
|
||||
set(HAVE_ZLIB 0)
|
||||
endif()
|
||||
|
||||
# Determine whether your compiler supports move semantics.
|
||||
|
||||
check_cxx_source_compiles("
|
||||
#ifdef __clang__
|
||||
# pragma clang diagnostic error \"-Wc++11-extensions\"
|
||||
#endif
|
||||
#include <utility>
|
||||
int func(int &&x) { return x - 1; }
|
||||
int main() { return func(std::move(1)); }
|
||||
" TAGLIB_USE_MOVE_SEMANTICS)
|
||||
|
||||
# Determine where shared_ptr<T> is defined regardless of C++11 support.
|
||||
|
||||
check_cxx_source_compiles("
|
||||
#include <memory>
|
||||
int main() { std::shared_ptr<int> x; return 0; }
|
||||
" TAGLIB_USE_STD_SHARED_PTR)
|
||||
|
||||
if(NOT TAGLIB_USE_STD_SHARED_PTR)
|
||||
check_cxx_source_compiles("
|
||||
#include <tr1/memory>
|
||||
int main() { std::tr1::shared_ptr<int> x; return 0; }
|
||||
" TAGLIB_USE_TR1_SHARED_PTR)
|
||||
|
||||
if(NOT TAGLIB_USE_TR1_SHARED_PTR)
|
||||
check_cxx_source_compiles("
|
||||
#include <boost/shared_ptr.hpp>
|
||||
int main() { boost::shared_ptr<int> x; return 0; }
|
||||
" TAGLIB_USE_BOOST_SHARED_PTR)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Determine where unique_ptr<T> or scoped_ptr<T> is defined regardless of C++11 support.
|
||||
|
||||
check_cxx_source_compiles("
|
||||
#include <memory>
|
||||
int main() { std::unique_ptr<int> x; return 0; }
|
||||
" TAGLIB_USE_STD_UNIQUE_PTR)
|
||||
|
||||
if(NOT TAGLIB_USE_STD_UNIQUE_PTR)
|
||||
check_cxx_source_compiles("
|
||||
#include <boost/scoped_ptr.hpp>
|
||||
int main() { boost::scoped_ptr<int> x; return 0; }
|
||||
" TAGLIB_USE_BOOST_SCOPED_PTR)
|
||||
endif()
|
||||
|
||||
# Determine whether CppUnit is installed.
|
||||
|
||||
set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules)
|
||||
|
||||
@ -18,13 +18,24 @@
|
||||
#cmakedefine HAVE_MAC_BYTESWAP 1
|
||||
#cmakedefine HAVE_OPENBSD_BYTESWAP 1
|
||||
|
||||
/* Defined if your compiler supports shared_ptr */
|
||||
#cmakedefine HAVE_STD_SHARED_PTR 1 // #include <memory> / std::shared_ptr<T>
|
||||
#cmakedefine HAVE_TR1_SHARED_PTR 1 // #include <tr1/memory> / std::tr1::shared_ptr<T>
|
||||
#cmakedefine HAVE_BOOST_SHARED_PTR 1 // #include <boost/shared_ptr.hpp> / boost::shared_ptr<T>
|
||||
|
||||
/* Defined if your compiler supports unique_ptr or scoped_ptr */
|
||||
#cmakedefine HAVE_STD_UNIQUE_PTR 1 // #include <memory> / std::unique_ptr<T>
|
||||
#cmakedefine HAVE_BOOST_SCOPED_PTR 1 // #include <boost/scoped_ptr.hpp> / boost::scoped_ptr<T>
|
||||
|
||||
/* Defined if your compiler supports some atomic operations */
|
||||
#cmakedefine HAVE_STD_ATOMIC 1
|
||||
#cmakedefine HAVE_BOOST_ATOMIC 1
|
||||
#cmakedefine HAVE_GCC_ATOMIC 1
|
||||
#cmakedefine HAVE_MAC_ATOMIC 1
|
||||
#cmakedefine HAVE_WIN_ATOMIC 1
|
||||
#cmakedefine HAVE_IA64_ATOMIC 1
|
||||
|
||||
/* Defined if your compiler supports some safer version of sprintf */
|
||||
/* Defined if your compiler supports snpritf or sprintf_s. */
|
||||
#cmakedefine HAVE_SNPRINTF 1
|
||||
#cmakedefine HAVE_SPRINTF_S 1
|
||||
|
||||
|
||||
@ -53,7 +53,7 @@ set(tag_HDRS
|
||||
toolkit/tmap.h
|
||||
toolkit/tmap.tcc
|
||||
toolkit/tpropertymap.h
|
||||
toolkit/tsmartptr.h
|
||||
toolkit/trefcounter.h
|
||||
mpeg/mpegfile.h
|
||||
mpeg/mpegproperties.h
|
||||
mpeg/mpegheader.h
|
||||
@ -300,7 +300,7 @@ set(toolkit_SRCS
|
||||
toolkit/tfilestream.cpp
|
||||
toolkit/tdebug.cpp
|
||||
toolkit/tpropertymap.cpp
|
||||
toolkit/tsmartptr.cpp
|
||||
toolkit/trefcounter.cpp
|
||||
toolkit/unicode.cpp
|
||||
)
|
||||
|
||||
|
||||
@ -23,32 +23,45 @@
|
||||
* http://www.mozilla.org/MPL/ *
|
||||
***************************************************************************/
|
||||
|
||||
#include <taglib.h>
|
||||
#include <tdebug.h>
|
||||
#include "taglib.h"
|
||||
#include "tdebug.h"
|
||||
#include "tsmartptr.h"
|
||||
#include "asfattribute.h"
|
||||
#include "asffile.h"
|
||||
|
||||
using namespace TagLib;
|
||||
|
||||
namespace
|
||||
{
|
||||
struct AttributeData
|
||||
{
|
||||
ASF::Attribute::AttributeTypes type;
|
||||
String stringValue;
|
||||
ByteVector byteVectorValue;
|
||||
ASF::Picture pictureValue;
|
||||
union {
|
||||
unsigned int intValue;
|
||||
unsigned short shortValue;
|
||||
unsigned long long longLongValue;
|
||||
bool boolValue;
|
||||
};
|
||||
int stream;
|
||||
int language;
|
||||
};
|
||||
}
|
||||
|
||||
class ASF::Attribute::AttributePrivate
|
||||
{
|
||||
public:
|
||||
AttributePrivate()
|
||||
: pictureValue(ASF::Picture::fromInvalid()),
|
||||
stream(0),
|
||||
language(0) {}
|
||||
AttributeTypes type;
|
||||
String stringValue;
|
||||
ByteVector byteVectorValue;
|
||||
ASF::Picture pictureValue;
|
||||
union {
|
||||
unsigned int intValue;
|
||||
unsigned short shortValue;
|
||||
unsigned long long longLongValue;
|
||||
bool boolValue;
|
||||
};
|
||||
int stream;
|
||||
int language;
|
||||
: data(new AttributeData())
|
||||
{
|
||||
data->pictureValue = ASF::Picture::fromInvalid();
|
||||
data->stream = 0;
|
||||
data->language = 0;
|
||||
}
|
||||
|
||||
SHARED_PTR<AttributeData> data;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@ -58,135 +71,127 @@ public:
|
||||
ASF::Attribute::Attribute()
|
||||
: d(new AttributePrivate())
|
||||
{
|
||||
d->type = UnicodeType;
|
||||
d->data->type = UnicodeType;
|
||||
}
|
||||
|
||||
ASF::Attribute::Attribute(const ASF::Attribute &other)
|
||||
: d(other.d)
|
||||
: d(new AttributePrivate(*other.d))
|
||||
{
|
||||
}
|
||||
|
||||
ASF::Attribute::Attribute(const String &value)
|
||||
: d(new AttributePrivate())
|
||||
{
|
||||
d->type = UnicodeType;
|
||||
d->stringValue = value;
|
||||
d->data->type = UnicodeType;
|
||||
d->data->stringValue = value;
|
||||
}
|
||||
|
||||
ASF::Attribute::Attribute(const ByteVector &value)
|
||||
: d(new AttributePrivate())
|
||||
{
|
||||
d->type = BytesType;
|
||||
d->byteVectorValue = value;
|
||||
d->data->type = BytesType;
|
||||
d->data->byteVectorValue = value;
|
||||
}
|
||||
|
||||
ASF::Attribute::Attribute(const ASF::Picture &value)
|
||||
: d(new AttributePrivate())
|
||||
{
|
||||
d->type = BytesType;
|
||||
d->pictureValue = value;
|
||||
d->data->type = BytesType;
|
||||
d->data->pictureValue = value;
|
||||
}
|
||||
|
||||
ASF::Attribute::Attribute(unsigned int value)
|
||||
: d(new AttributePrivate())
|
||||
{
|
||||
d->type = DWordType;
|
||||
d->intValue = value;
|
||||
d->data->type = DWordType;
|
||||
d->data->intValue = value;
|
||||
}
|
||||
|
||||
ASF::Attribute::Attribute(unsigned long long value)
|
||||
: d(new AttributePrivate())
|
||||
{
|
||||
d->type = QWordType;
|
||||
d->longLongValue = value;
|
||||
d->data->type = QWordType;
|
||||
d->data->longLongValue = value;
|
||||
}
|
||||
|
||||
ASF::Attribute::Attribute(unsigned short value)
|
||||
: d(new AttributePrivate())
|
||||
{
|
||||
d->type = WordType;
|
||||
d->shortValue = value;
|
||||
d->data->type = WordType;
|
||||
d->data->shortValue = value;
|
||||
}
|
||||
|
||||
ASF::Attribute::Attribute(bool value)
|
||||
: d(new AttributePrivate())
|
||||
{
|
||||
d->type = BoolType;
|
||||
d->boolValue = value;
|
||||
d->data->type = BoolType;
|
||||
d->data->boolValue = value;
|
||||
}
|
||||
|
||||
ASF::Attribute::~Attribute()
|
||||
{
|
||||
delete d;
|
||||
}
|
||||
|
||||
ASF::Attribute &ASF::Attribute::operator=(const ASF::Attribute &other)
|
||||
{
|
||||
d = other.d;
|
||||
*d = *other.d;
|
||||
return *this;
|
||||
}
|
||||
|
||||
#ifdef TAGLIB_USE_MOVE_SEMANTICS
|
||||
|
||||
ASF::Attribute &ASF::Attribute::operator=(ASF::Attribute &&other)
|
||||
{
|
||||
d = std::move(other.d);
|
||||
return *this;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
ASF::Attribute::AttributeTypes ASF::Attribute::type() const
|
||||
{
|
||||
return d->type;
|
||||
return d->data->type;
|
||||
}
|
||||
|
||||
String ASF::Attribute::toString() const
|
||||
{
|
||||
return d->stringValue;
|
||||
return d->data->stringValue;
|
||||
}
|
||||
|
||||
ByteVector ASF::Attribute::toByteVector() const
|
||||
{
|
||||
if(d->pictureValue.isValid())
|
||||
return d->pictureValue.render();
|
||||
return d->byteVectorValue;
|
||||
if(d->data->pictureValue.isValid())
|
||||
return d->data->pictureValue.render();
|
||||
|
||||
return d->data->byteVectorValue;
|
||||
}
|
||||
|
||||
unsigned short ASF::Attribute::toBool() const
|
||||
{
|
||||
return d->shortValue;
|
||||
return d->data->shortValue;
|
||||
}
|
||||
|
||||
unsigned short ASF::Attribute::toUShort() const
|
||||
{
|
||||
return d->shortValue;
|
||||
return d->data->shortValue;
|
||||
}
|
||||
|
||||
unsigned int ASF::Attribute::toUInt() const
|
||||
{
|
||||
return d->intValue;
|
||||
return d->data->intValue;
|
||||
}
|
||||
|
||||
unsigned long long ASF::Attribute::toULongLong() const
|
||||
{
|
||||
return d->longLongValue;
|
||||
return d->data->longLongValue;
|
||||
}
|
||||
|
||||
ASF::Picture ASF::Attribute::toPicture() const
|
||||
{
|
||||
return d->pictureValue;
|
||||
return d->data->pictureValue;
|
||||
}
|
||||
|
||||
String ASF::Attribute::parse(ASF::File &f, int kind)
|
||||
{
|
||||
uint size, nameLength;
|
||||
String name;
|
||||
d->pictureValue = Picture::fromInvalid();
|
||||
d->data->pictureValue = Picture::fromInvalid();
|
||||
// extended content descriptor
|
||||
if(kind == 0) {
|
||||
nameLength = f.readWORD();
|
||||
name = f.readString(nameLength);
|
||||
d->type = ASF::Attribute::AttributeTypes(f.readWORD());
|
||||
d->data->type = ASF::Attribute::AttributeTypes(f.readWORD());
|
||||
size = f.readWORD();
|
||||
}
|
||||
// metadata & metadata library
|
||||
@ -194,11 +199,11 @@ String ASF::Attribute::parse(ASF::File &f, int kind)
|
||||
int temp = f.readWORD();
|
||||
// metadata library
|
||||
if(kind == 2) {
|
||||
d->language = temp;
|
||||
d->data->language = temp;
|
||||
}
|
||||
d->stream = f.readWORD();
|
||||
d->data->stream = f.readWORD();
|
||||
nameLength = f.readWORD();
|
||||
d->type = ASF::Attribute::AttributeTypes(f.readWORD());
|
||||
d->data->type = ASF::Attribute::AttributeTypes(f.readWORD());
|
||||
size = f.readDWORD();
|
||||
name = f.readString(nameLength);
|
||||
}
|
||||
@ -207,42 +212,42 @@ String ASF::Attribute::parse(ASF::File &f, int kind)
|
||||
debug("ASF::Attribute::parse() -- Value larger than 64kB");
|
||||
}
|
||||
|
||||
switch(d->type) {
|
||||
switch(d->data->type) {
|
||||
case WordType:
|
||||
d->shortValue = f.readWORD();
|
||||
d->data->shortValue = f.readWORD();
|
||||
break;
|
||||
|
||||
case BoolType:
|
||||
if(kind == 0) {
|
||||
d->boolValue = f.readDWORD() == 1;
|
||||
d->data->boolValue = f.readDWORD() == 1;
|
||||
}
|
||||
else {
|
||||
d->boolValue = f.readWORD() == 1;
|
||||
d->data->boolValue = f.readWORD() == 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case DWordType:
|
||||
d->intValue = f.readDWORD();
|
||||
d->data->intValue = f.readDWORD();
|
||||
break;
|
||||
|
||||
case QWordType:
|
||||
d->longLongValue = f.readQWORD();
|
||||
d->data->longLongValue = f.readQWORD();
|
||||
break;
|
||||
|
||||
case UnicodeType:
|
||||
d->stringValue = f.readString(size);
|
||||
d->data->stringValue = f.readString(size);
|
||||
break;
|
||||
|
||||
case BytesType:
|
||||
case GuidType:
|
||||
d->byteVectorValue = f.readBlock(size);
|
||||
d->data->byteVectorValue = f.readBlock(size);
|
||||
break;
|
||||
}
|
||||
|
||||
if(d->type == BytesType && name == "WM/Picture") {
|
||||
d->pictureValue.parse(d->byteVectorValue);
|
||||
if(d->pictureValue.isValid()) {
|
||||
d->byteVectorValue.clear();
|
||||
if(d->data->type == BytesType && name == "WM/Picture") {
|
||||
d->data->pictureValue.parse(d->data->byteVectorValue);
|
||||
if(d->data->pictureValue.isValid()) {
|
||||
d->data->byteVectorValue.clear();
|
||||
}
|
||||
}
|
||||
|
||||
@ -251,7 +256,7 @@ String ASF::Attribute::parse(ASF::File &f, int kind)
|
||||
|
||||
int ASF::Attribute::dataSize() const
|
||||
{
|
||||
switch (d->type) {
|
||||
switch (d->data->type) {
|
||||
case WordType:
|
||||
return 2;
|
||||
case BoolType:
|
||||
@ -261,12 +266,12 @@ int ASF::Attribute::dataSize() const
|
||||
case QWordType:
|
||||
return 5;
|
||||
case UnicodeType:
|
||||
return static_cast<int>(d->stringValue.size() * 2 + 2);
|
||||
return static_cast<int>(d->data->stringValue.size() * 2 + 2);
|
||||
case BytesType:
|
||||
if(d->pictureValue.isValid())
|
||||
return d->pictureValue.dataSize();
|
||||
if(d->data->pictureValue.isValid())
|
||||
return d->data->pictureValue.dataSize();
|
||||
case GuidType:
|
||||
return static_cast<int>(d->byteVectorValue.size());
|
||||
return static_cast<int>(d->data->byteVectorValue.size());
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -275,54 +280,54 @@ ByteVector ASF::Attribute::render(const String &name, int kind) const
|
||||
{
|
||||
ByteVector data;
|
||||
|
||||
switch (d->type) {
|
||||
switch (d->data->type) {
|
||||
case WordType:
|
||||
data.append(ByteVector::fromUInt16LE(d->shortValue));
|
||||
data.append(ByteVector::fromUInt16LE(d->data->shortValue));
|
||||
break;
|
||||
|
||||
case BoolType:
|
||||
if(kind == 0) {
|
||||
data.append(ByteVector::fromUInt32LE(d->boolValue ? 1 : 0));
|
||||
data.append(ByteVector::fromUInt32LE(d->data->boolValue ? 1 : 0));
|
||||
}
|
||||
else {
|
||||
data.append(ByteVector::fromUInt16LE(d->boolValue ? 1 : 0));
|
||||
data.append(ByteVector::fromUInt16LE(d->data->boolValue ? 1 : 0));
|
||||
}
|
||||
break;
|
||||
|
||||
case DWordType:
|
||||
data.append(ByteVector::fromUInt32LE(d->intValue));
|
||||
data.append(ByteVector::fromUInt32LE(d->data->intValue));
|
||||
break;
|
||||
|
||||
case QWordType:
|
||||
data.append(ByteVector::fromUInt64LE(d->longLongValue));
|
||||
data.append(ByteVector::fromUInt64LE(d->data->longLongValue));
|
||||
break;
|
||||
|
||||
case UnicodeType:
|
||||
data.append(File::renderString(d->stringValue));
|
||||
data.append(File::renderString(d->data->stringValue));
|
||||
break;
|
||||
|
||||
case BytesType:
|
||||
if(d->pictureValue.isValid()) {
|
||||
data.append(d->pictureValue.render());
|
||||
if(d->data->pictureValue.isValid()) {
|
||||
data.append(d->data->pictureValue.render());
|
||||
break;
|
||||
}
|
||||
case GuidType:
|
||||
data.append(d->byteVectorValue);
|
||||
data.append(d->data->byteVectorValue);
|
||||
break;
|
||||
}
|
||||
|
||||
if(kind == 0) {
|
||||
data = File::renderString(name, true) +
|
||||
ByteVector::fromUInt16LE((int)d->type) +
|
||||
ByteVector::fromUInt16LE((int)d->data->type) +
|
||||
ByteVector::fromUInt16LE(data.size()) +
|
||||
data;
|
||||
}
|
||||
else {
|
||||
ByteVector nameData = File::renderString(name);
|
||||
data = ByteVector::fromUInt16LE(kind == 2 ? d->language : 0) +
|
||||
ByteVector::fromUInt16LE(d->stream) +
|
||||
data = ByteVector::fromUInt16LE(kind == 2 ? d->data->language : 0) +
|
||||
ByteVector::fromUInt16LE(d->data->stream) +
|
||||
ByteVector::fromUInt16LE(nameData.size()) +
|
||||
ByteVector::fromUInt16LE((int)d->type) +
|
||||
ByteVector::fromUInt16LE((int)d->data->type) +
|
||||
ByteVector::fromUInt32LE(data.size()) +
|
||||
nameData +
|
||||
data;
|
||||
@ -333,21 +338,21 @@ ByteVector ASF::Attribute::render(const String &name, int kind) const
|
||||
|
||||
int ASF::Attribute::language() const
|
||||
{
|
||||
return d->language;
|
||||
return d->data->language;
|
||||
}
|
||||
|
||||
void ASF::Attribute::setLanguage(int value)
|
||||
{
|
||||
d->language = value;
|
||||
d->data->language = value;
|
||||
}
|
||||
|
||||
int ASF::Attribute::stream() const
|
||||
{
|
||||
return d->stream;
|
||||
return d->data->stream;
|
||||
}
|
||||
|
||||
void ASF::Attribute::setStream(int value)
|
||||
{
|
||||
d->stream = value;
|
||||
d->data->stream = value;
|
||||
}
|
||||
|
||||
|
||||
@ -36,7 +36,6 @@ namespace TagLib
|
||||
|
||||
namespace ASF
|
||||
{
|
||||
|
||||
class File;
|
||||
class Picture;
|
||||
|
||||
@ -115,17 +114,6 @@ namespace TagLib
|
||||
*/
|
||||
ASF::Attribute &operator=(const Attribute &other);
|
||||
|
||||
#ifdef TAGLIB_USE_MOVE_SEMANTICS
|
||||
|
||||
/*!
|
||||
* Moves the contents of \a other into this item.
|
||||
*
|
||||
* \note Not available unless TAGLIB_USE_MOVE_SEMANTICS macro is defined.
|
||||
*/
|
||||
ASF::Attribute &operator=(Attribute &&other);
|
||||
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* Destroys the attribute.
|
||||
*/
|
||||
@ -191,21 +179,17 @@ namespace TagLib
|
||||
*/
|
||||
void setStream(int value);
|
||||
|
||||
#ifndef DO_NOT_DOCUMENT
|
||||
/* THIS IS PRIVATE, DON'T TOUCH IT! */
|
||||
String parse(ASF::File &file, int kind = 0);
|
||||
#endif
|
||||
|
||||
//! Returns the size of the stored data
|
||||
int dataSize() const;
|
||||
|
||||
private:
|
||||
friend class File;
|
||||
|
||||
String parse(ASF::File &file, int kind = 0);
|
||||
ByteVector render(const String &name, int kind = 0) const;
|
||||
|
||||
class AttributePrivate;
|
||||
RefCountPtr<AttributePrivate> d;
|
||||
AttributePrivate *d;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -23,24 +23,39 @@
|
||||
* http://www.mozilla.org/MPL/ *
|
||||
***************************************************************************/
|
||||
|
||||
#include <taglib.h>
|
||||
#include <tdebug.h>
|
||||
#include "taglib.h"
|
||||
#include "tdebug.h"
|
||||
#include "tsmartptr.h"
|
||||
#include "asfattribute.h"
|
||||
#include "asffile.h"
|
||||
#include "asfpicture.h"
|
||||
|
||||
using namespace TagLib;
|
||||
|
||||
namespace
|
||||
{
|
||||
struct PictureData
|
||||
{
|
||||
bool valid;
|
||||
ASF::Picture::Type type;
|
||||
String mimeType;
|
||||
String description;
|
||||
ByteVector picture;
|
||||
};
|
||||
}
|
||||
|
||||
class ASF::Picture::PicturePrivate
|
||||
{
|
||||
public:
|
||||
bool valid;
|
||||
Type type;
|
||||
String mimeType;
|
||||
String description;
|
||||
ByteVector picture;
|
||||
PicturePrivate()
|
||||
: data(new PictureData())
|
||||
{
|
||||
}
|
||||
|
||||
SHARED_PTR<PictureData> data;
|
||||
};
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Picture class members
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@ -48,115 +63,96 @@ public:
|
||||
ASF::Picture::Picture()
|
||||
: d(new PicturePrivate())
|
||||
{
|
||||
d->valid = true;
|
||||
d->data->valid = true;
|
||||
}
|
||||
|
||||
ASF::Picture::Picture(const Picture& other)
|
||||
: d(other.d)
|
||||
: d(new PicturePrivate(*other.d))
|
||||
{
|
||||
}
|
||||
|
||||
#ifdef TAGLIB_USE_MOVE_SEMANTICS
|
||||
|
||||
ASF::Picture::Picture(Picture &&other)
|
||||
: d(std::move(other.d))
|
||||
{
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
ASF::Picture::~Picture()
|
||||
{
|
||||
delete d;
|
||||
}
|
||||
|
||||
bool ASF::Picture::isValid() const
|
||||
{
|
||||
return d->valid;
|
||||
return d->data->valid;
|
||||
}
|
||||
|
||||
String ASF::Picture::mimeType() const
|
||||
{
|
||||
return d->mimeType;
|
||||
return d->data->mimeType;
|
||||
}
|
||||
|
||||
void ASF::Picture::setMimeType(const String &value)
|
||||
{
|
||||
d->mimeType = value;
|
||||
d->data->mimeType = value;
|
||||
}
|
||||
|
||||
ASF::Picture::Type ASF::Picture::type() const
|
||||
{
|
||||
return d->type;
|
||||
return d->data->type;
|
||||
}
|
||||
|
||||
void ASF::Picture::setType(const ASF::Picture::Type& t)
|
||||
{
|
||||
d->type = t;
|
||||
d->data->type = t;
|
||||
}
|
||||
|
||||
String ASF::Picture::description() const
|
||||
{
|
||||
return d->description;
|
||||
return d->data->description;
|
||||
}
|
||||
|
||||
void ASF::Picture::setDescription(const String &desc)
|
||||
{
|
||||
d->description = desc;
|
||||
d->data->description = desc;
|
||||
}
|
||||
|
||||
ByteVector ASF::Picture::picture() const
|
||||
{
|
||||
return d->picture;
|
||||
return d->data->picture;
|
||||
}
|
||||
|
||||
void ASF::Picture::setPicture(const ByteVector &p)
|
||||
{
|
||||
d->picture = p;
|
||||
d->data->picture = p;
|
||||
}
|
||||
|
||||
int ASF::Picture::dataSize() const
|
||||
{
|
||||
return static_cast<int>(
|
||||
9 + (d->mimeType.length() + d->description.length()) * 2 +
|
||||
d->picture.size());
|
||||
9 + (d->data->mimeType.length() + d->data->description.length()) * 2 +
|
||||
d->data->picture.size());
|
||||
}
|
||||
|
||||
ASF::Picture& ASF::Picture::operator=(const ASF::Picture& other)
|
||||
{
|
||||
d = other.d;
|
||||
*d = *other.d;
|
||||
return *this;
|
||||
}
|
||||
|
||||
#ifdef TAGLIB_USE_MOVE_SEMANTICS
|
||||
|
||||
ASF::Picture& ASF::Picture::operator=(ASF::Picture &&other)
|
||||
{
|
||||
d = std::move(other.d);
|
||||
return *this;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
ByteVector ASF::Picture::render() const
|
||||
{
|
||||
if(!isValid())
|
||||
return ByteVector::null;
|
||||
return
|
||||
ByteVector((char)d->type) +
|
||||
ByteVector::fromUInt32LE(d->picture.size()) +
|
||||
ASF::File::renderString(d->mimeType) +
|
||||
ASF::File::renderString(d->description) +
|
||||
d->picture;
|
||||
ByteVector((char)d->data->type) +
|
||||
ByteVector::fromUInt32LE(d->data->picture.size()) +
|
||||
ASF::File::renderString(d->data->mimeType) +
|
||||
ASF::File::renderString(d->data->description) +
|
||||
d->data->picture;
|
||||
}
|
||||
|
||||
void ASF::Picture::parse(const ByteVector& bytes)
|
||||
{
|
||||
d->valid = false;
|
||||
d->data->valid = false;
|
||||
if(bytes.size() < 9)
|
||||
return;
|
||||
size_t pos = 0;
|
||||
d->type = (Type)bytes[0]; ++pos;
|
||||
d->data->type = (Type)bytes[0]; ++pos;
|
||||
const uint dataLen = bytes.toUInt32LE(pos); pos+=4;
|
||||
|
||||
const ByteVector nullStringTerminator(2, 0);
|
||||
@ -164,27 +160,27 @@ void ASF::Picture::parse(const ByteVector& bytes)
|
||||
size_t endPos = bytes.find(nullStringTerminator, pos, 2);
|
||||
if(endPos == ByteVector::npos)
|
||||
return;
|
||||
d->mimeType = String(bytes.mid(pos, endPos - pos), String::UTF16LE);
|
||||
d->data->mimeType = String(bytes.mid(pos, endPos - pos), String::UTF16LE);
|
||||
pos = endPos+2;
|
||||
|
||||
endPos = bytes.find(nullStringTerminator, pos, 2);
|
||||
if(endPos == ByteVector::npos)
|
||||
return;
|
||||
d->description = String(bytes.mid(pos, endPos - pos), String::UTF16LE);
|
||||
d->data->description = String(bytes.mid(pos, endPos - pos), String::UTF16LE);
|
||||
pos = endPos+2;
|
||||
|
||||
if(dataLen + pos != bytes.size())
|
||||
return;
|
||||
|
||||
d->picture = bytes.mid(pos, dataLen);
|
||||
d->valid = true;
|
||||
d->data->picture = bytes.mid(pos, dataLen);
|
||||
d->data->valid = true;
|
||||
return;
|
||||
}
|
||||
|
||||
ASF::Picture ASF::Picture::fromInvalid()
|
||||
{
|
||||
Picture ret;
|
||||
ret.d->valid = false;
|
||||
ret.d->data->valid = false;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@ -35,6 +35,7 @@ namespace TagLib
|
||||
{
|
||||
namespace ASF
|
||||
{
|
||||
class Attribute;
|
||||
|
||||
//! An ASF attached picture interface implementation
|
||||
|
||||
@ -46,7 +47,8 @@ namespace TagLib
|
||||
* \see Attribute::toPicture()
|
||||
* \see Attribute::Attribute(const Picture& picture)
|
||||
*/
|
||||
class TAGLIB_EXPORT Picture {
|
||||
class TAGLIB_EXPORT Picture
|
||||
{
|
||||
public:
|
||||
|
||||
/*!
|
||||
@ -107,17 +109,6 @@ namespace TagLib
|
||||
*/
|
||||
Picture(const Picture& other);
|
||||
|
||||
#ifdef TAGLIB_USE_MOVE_SEMANTICS
|
||||
|
||||
/*!
|
||||
* Constructs an picture equivalent to \a other.
|
||||
*
|
||||
* \note Not available unless TAGLIB_USE_MOVE_SEMANTICS macro is defined.
|
||||
*/
|
||||
Picture(Picture &&other);
|
||||
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* Destroys the picture.
|
||||
*/
|
||||
@ -128,17 +119,6 @@ namespace TagLib
|
||||
*/
|
||||
Picture& operator=(const Picture& other);
|
||||
|
||||
#ifdef TAGLIB_USE_MOVE_SEMANTICS
|
||||
|
||||
/*!
|
||||
* Moves the contents of \a other into this picture.
|
||||
*
|
||||
* \note Not available unless TAGLIB_USE_MOVE_SEMANTICS macro is defined.
|
||||
*/
|
||||
Picture& operator=(Picture &&other);
|
||||
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* Returns true if Picture stores valid picture
|
||||
*/
|
||||
@ -223,15 +203,14 @@ namespace TagLib
|
||||
*/
|
||||
int dataSize() const;
|
||||
|
||||
#ifndef DO_NOT_DOCUMENT
|
||||
/* THIS IS PRIVATE, DON'T TOUCH IT! */
|
||||
void parse(const ByteVector& );
|
||||
static Picture fromInvalid();
|
||||
friend class Attribute;
|
||||
#endif
|
||||
private:
|
||||
friend class Attribute;
|
||||
|
||||
void parse(const ByteVector &);
|
||||
static Picture fromInvalid();
|
||||
|
||||
class PicturePrivate;
|
||||
RefCountPtr<PicturePrivate> d;
|
||||
PicturePrivate *d;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@ -104,6 +104,7 @@ namespace TagLib {
|
||||
AudioProperties(ReadStyle style);
|
||||
|
||||
private:
|
||||
// Noncopyable. Derived classes as well.
|
||||
AudioProperties(const AudioProperties &);
|
||||
AudioProperties &operator=(const AudioProperties &);
|
||||
|
||||
|
||||
@ -33,9 +33,10 @@
|
||||
# include <Shlwapi.h>
|
||||
#endif
|
||||
|
||||
#include <tfile.h>
|
||||
#include <tstring.h>
|
||||
#include <tdebug.h>
|
||||
#include "tfile.h"
|
||||
#include "tstring.h"
|
||||
#include "tdebug.h"
|
||||
#include "tsmartptr.h"
|
||||
|
||||
#include "fileref.h"
|
||||
#include "asffile.h"
|
||||
@ -66,12 +67,12 @@ namespace
|
||||
|
||||
ResolverList fileTypeResolvers;
|
||||
|
||||
RefCountPtr<File> create(
|
||||
SHARED_PTR<File> create(
|
||||
FileName fileName,
|
||||
bool readAudioProperties,
|
||||
AudioProperties::ReadStyle audioPropertiesStyle)
|
||||
{
|
||||
RefCountPtr<File> file;
|
||||
SHARED_PTR<File> file;
|
||||
for(ResolverConstIterator it = fileTypeResolvers.begin(); it != fileTypeResolvers.end(); ++it)
|
||||
{
|
||||
file.reset((*it)->createFile(fileName, readAudioProperties, audioPropertiesStyle));
|
||||
@ -169,12 +170,12 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
FileRefPrivate(RefCountPtr<File> f)
|
||||
: file(f)
|
||||
FileRefPrivate(const SHARED_PTR<File> &f)
|
||||
: file(f)
|
||||
{
|
||||
}
|
||||
|
||||
RefCountPtr<File> file;
|
||||
SHARED_PTR<File> file;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@ -187,7 +188,8 @@ FileRef::FileRef()
|
||||
}
|
||||
|
||||
FileRef::FileRef(FileName fileName,
|
||||
bool readAudioProperties, AudioProperties::ReadStyle audioPropertiesStyle)
|
||||
bool readAudioProperties,
|
||||
AudioProperties::ReadStyle audioPropertiesStyle)
|
||||
: d(new FileRefPrivate(create(fileName, readAudioProperties, audioPropertiesStyle)))
|
||||
{
|
||||
}
|
||||
@ -198,21 +200,13 @@ FileRef::FileRef(File *file)
|
||||
}
|
||||
|
||||
FileRef::FileRef(const FileRef &ref)
|
||||
: d(ref.d)
|
||||
: d(new FileRefPrivate(ref.d->file))
|
||||
{
|
||||
}
|
||||
|
||||
#ifdef TAGLIB_USE_MOVE_SEMANTICS
|
||||
|
||||
FileRef::FileRef(FileRef &&ref)
|
||||
: d(std::move(ref.d))
|
||||
{
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
FileRef::~FileRef()
|
||||
{
|
||||
delete d;
|
||||
}
|
||||
|
||||
Tag *FileRef::tag() const
|
||||
@ -330,26 +324,16 @@ bool FileRef::isNull() const
|
||||
|
||||
FileRef &FileRef::operator=(const FileRef &ref)
|
||||
{
|
||||
d = ref.d;
|
||||
*d = *ref.d;
|
||||
return *this;
|
||||
}
|
||||
|
||||
#ifdef TAGLIB_USE_MOVE_SEMANTICS
|
||||
|
||||
FileRef &FileRef::operator=(FileRef &&ref)
|
||||
{
|
||||
d = std::move(ref.d);
|
||||
return *this;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
bool FileRef::operator==(const FileRef &ref) const
|
||||
{
|
||||
return ref.d->file == d->file;
|
||||
return (d->file == ref.d->file);
|
||||
}
|
||||
|
||||
bool FileRef::operator!=(const FileRef &ref) const
|
||||
{
|
||||
return ref.d->file != d->file;
|
||||
return (d->file != ref.d->file);
|
||||
}
|
||||
|
||||
@ -143,17 +143,6 @@ namespace TagLib {
|
||||
*/
|
||||
FileRef(const FileRef &ref);
|
||||
|
||||
#ifdef TAGLIB_USE_MOVE_SEMANTICS
|
||||
|
||||
/*!
|
||||
* Move \a ref into the FileRef.
|
||||
*
|
||||
* \note Not available unless TAGLIB_USE_MOVE_SEMANTICS macro is defined.
|
||||
*/
|
||||
FileRef(FileRef &&ref);
|
||||
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* Destroys this FileRef instance.
|
||||
*/
|
||||
@ -286,17 +275,6 @@ namespace TagLib {
|
||||
*/
|
||||
FileRef &operator=(const FileRef &ref);
|
||||
|
||||
#ifdef TAGLIB_USE_MOVE_SEMANTICS
|
||||
|
||||
/*!
|
||||
* Moves \a ref into this FileRef.
|
||||
*
|
||||
* \note Not available unless TAGLIB_USE_MOVE_SEMANTICS macro is defined.
|
||||
*/
|
||||
FileRef &operator=(FileRef &&ref);
|
||||
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* Returns true if this FileRef and \a ref point to the same File object.
|
||||
*/
|
||||
@ -310,7 +288,7 @@ namespace TagLib {
|
||||
|
||||
private:
|
||||
class FileRefPrivate;
|
||||
RefCountPtr<FileRefPrivate> d;
|
||||
FileRefPrivate *d;
|
||||
};
|
||||
|
||||
} // namespace TagLib
|
||||
|
||||
@ -199,8 +199,6 @@ namespace TagLib {
|
||||
PicturePrivate *d;
|
||||
};
|
||||
|
||||
typedef List<Picture> PictureList;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -23,63 +23,66 @@
|
||||
* http://www.mozilla.org/MPL/ *
|
||||
***************************************************************************/
|
||||
|
||||
#include <taglib.h>
|
||||
#include <tdebug.h>
|
||||
#include "taglib.h"
|
||||
#include "tdebug.h"
|
||||
#include "tsmartptr.h"
|
||||
#include "mp4coverart.h"
|
||||
|
||||
using namespace TagLib;
|
||||
|
||||
namespace
|
||||
{
|
||||
struct CoverArtData
|
||||
{
|
||||
MP4::CoverArt::Format format;
|
||||
ByteVector data;
|
||||
};
|
||||
}
|
||||
|
||||
class MP4::CoverArt::CoverArtPrivate
|
||||
{
|
||||
public:
|
||||
CoverArtPrivate() : format(MP4::CoverArt::JPEG) {}
|
||||
CoverArtPrivate(Format f, const ByteVector &v)
|
||||
: data(new CoverArtData())
|
||||
{
|
||||
data->format = f;
|
||||
data->data = v;
|
||||
}
|
||||
|
||||
Format format;
|
||||
ByteVector data;
|
||||
SHARED_PTR<CoverArtData> data;
|
||||
};
|
||||
|
||||
MP4::CoverArt::CoverArt(Format format, const ByteVector &data)
|
||||
: d(new CoverArtPrivate())
|
||||
: d(new CoverArtPrivate(format, data))
|
||||
{
|
||||
d->format = format;
|
||||
d->data = data;
|
||||
}
|
||||
|
||||
MP4::CoverArt::CoverArt(const CoverArt &item) : d(item.d)
|
||||
MP4::CoverArt::CoverArt(const CoverArt &item)
|
||||
: d(new CoverArtPrivate(*item.d))
|
||||
{
|
||||
}
|
||||
|
||||
MP4::CoverArt &
|
||||
MP4::CoverArt::operator=(const CoverArt &item)
|
||||
MP4::CoverArt::operator=(const CoverArt &item)
|
||||
{
|
||||
d = item.d;
|
||||
*d = *item.d;
|
||||
return *this;
|
||||
}
|
||||
|
||||
#ifdef TAGLIB_USE_MOVE_SEMANTICS
|
||||
|
||||
MP4::CoverArt &
|
||||
MP4::CoverArt::operator=(CoverArt &&item)
|
||||
{
|
||||
d = std::move(item.d);
|
||||
return *this;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
MP4::CoverArt::~CoverArt()
|
||||
{
|
||||
delete d;
|
||||
}
|
||||
|
||||
MP4::CoverArt::Format
|
||||
MP4::CoverArt::format() const
|
||||
{
|
||||
return d->format;
|
||||
return d->data->format;
|
||||
}
|
||||
|
||||
ByteVector
|
||||
MP4::CoverArt::data() const
|
||||
{
|
||||
return d->data;
|
||||
return d->data->data;
|
||||
}
|
||||
|
||||
|
||||
@ -54,9 +54,6 @@ namespace TagLib {
|
||||
|
||||
CoverArt(const CoverArt &item);
|
||||
CoverArt &operator=(const CoverArt &item);
|
||||
#ifdef TAGLIB_USE_MOVE_SEMANTICS
|
||||
CoverArt &operator=(CoverArt &&item);
|
||||
#endif
|
||||
|
||||
//! Format of the image
|
||||
Format format() const;
|
||||
@ -66,13 +63,11 @@ namespace TagLib {
|
||||
|
||||
private:
|
||||
class CoverArtPrivate;
|
||||
RefCountPtr<CoverArtPrivate> d;
|
||||
CoverArtPrivate *d;
|
||||
};
|
||||
|
||||
typedef List<CoverArt> CoverArtList;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@ -23,10 +23,14 @@
|
||||
* http://www.mozilla.org/MPL/ *
|
||||
***************************************************************************/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstdarg>
|
||||
#include <taglib.h>
|
||||
#include <tdebug.h>
|
||||
|
||||
#include "taglib.h"
|
||||
#include "tdebug.h"
|
||||
#include "tsmartptr.h"
|
||||
#include "mp4item.h"
|
||||
|
||||
using namespace TagLib;
|
||||
@ -59,234 +63,227 @@ namespace
|
||||
|
||||
return String(buf);
|
||||
}
|
||||
|
||||
struct ItemData
|
||||
{
|
||||
bool valid;
|
||||
MP4::AtomDataType atomDataType;
|
||||
MP4::Item::ItemType type;
|
||||
union {
|
||||
bool m_bool;
|
||||
int m_int;
|
||||
MP4::Item::IntPair m_intPair;
|
||||
uchar m_byte;
|
||||
uint m_uint;
|
||||
long long m_longlong;
|
||||
};
|
||||
StringList m_stringList;
|
||||
ByteVectorList m_byteVectorList;
|
||||
MP4::CoverArtList m_coverArtList;
|
||||
};
|
||||
}
|
||||
|
||||
class MP4::Item::ItemPrivate
|
||||
{
|
||||
public:
|
||||
ItemPrivate() : valid(true), atomDataType(MP4::TypeUndefined), type(MP4::Item::TypeUndefined) {}
|
||||
ItemPrivate()
|
||||
: data(new ItemData())
|
||||
{
|
||||
data->valid = true;
|
||||
data->atomDataType = MP4::TypeUndefined;
|
||||
data->type = MP4::Item::TypeUndefined;
|
||||
}
|
||||
|
||||
bool valid;
|
||||
AtomDataType atomDataType;
|
||||
ItemType type;
|
||||
union {
|
||||
bool m_bool;
|
||||
int m_int;
|
||||
IntPair m_intPair;
|
||||
uchar m_byte;
|
||||
uint m_uint;
|
||||
long long m_longlong;
|
||||
};
|
||||
StringList m_stringList;
|
||||
ByteVectorList m_byteVectorList;
|
||||
MP4::CoverArtList m_coverArtList;
|
||||
SHARED_PTR<ItemData> data;
|
||||
};
|
||||
|
||||
MP4::Item::Item()
|
||||
: d(new ItemPrivate())
|
||||
{
|
||||
d->valid = false;
|
||||
d->data->valid = false;
|
||||
}
|
||||
|
||||
MP4::Item::Item(const Item &item)
|
||||
: d(item.d)
|
||||
: d(new ItemPrivate(*item.d))
|
||||
{
|
||||
}
|
||||
|
||||
#ifdef TAGLIB_USE_MOVE_SEMANTICS
|
||||
|
||||
MP4::Item::Item(Item &&item)
|
||||
: d(std::move(item.d))
|
||||
{
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
MP4::Item &
|
||||
MP4::Item::operator=(const Item &item)
|
||||
{
|
||||
d = item.d;
|
||||
*d = *item.d;
|
||||
return *this;
|
||||
}
|
||||
|
||||
#ifdef TAGLIB_USE_MOVE_SEMANTICS
|
||||
|
||||
MP4::Item &
|
||||
MP4::Item::operator=(Item &&item)
|
||||
{
|
||||
d = std::move(item.d);
|
||||
return *this;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
MP4::Item::~Item()
|
||||
{
|
||||
delete d;
|
||||
}
|
||||
|
||||
MP4::Item::Item(bool value)
|
||||
: d(new ItemPrivate())
|
||||
{
|
||||
d->m_bool = value;
|
||||
d->type = TypeBool;
|
||||
d->data->m_bool = value;
|
||||
d->data->type = TypeBool;
|
||||
}
|
||||
|
||||
MP4::Item::Item(int value)
|
||||
: d(new ItemPrivate())
|
||||
{
|
||||
d->m_int = value;
|
||||
d->type = TypeInt;
|
||||
d->data->m_int = value;
|
||||
d->data->type = TypeInt;
|
||||
}
|
||||
|
||||
MP4::Item::Item(uchar value)
|
||||
: d(new ItemPrivate())
|
||||
{
|
||||
d->m_byte = value;
|
||||
d->type = TypeByte;
|
||||
d->data->m_byte = value;
|
||||
d->data->type = TypeByte;
|
||||
}
|
||||
|
||||
MP4::Item::Item(uint value)
|
||||
: d(new ItemPrivate())
|
||||
{
|
||||
d->m_uint = value;
|
||||
d->type = TypeUInt;
|
||||
d->data->m_uint = value;
|
||||
d->data->type = TypeUInt;
|
||||
}
|
||||
|
||||
MP4::Item::Item(long long value)
|
||||
: d(new ItemPrivate())
|
||||
{
|
||||
d->m_longlong = value;
|
||||
d->type = TypeLongLong;
|
||||
d->data->m_longlong = value;
|
||||
d->data->type = TypeLongLong;
|
||||
}
|
||||
|
||||
MP4::Item::Item(int value1, int value2)
|
||||
: d(new ItemPrivate())
|
||||
{
|
||||
d->m_intPair.first = value1;
|
||||
d->m_intPair.second = value2;
|
||||
d->type = TypeIntPair;
|
||||
d->data->m_intPair.first = value1;
|
||||
d->data->m_intPair.second = value2;
|
||||
d->data->type = TypeIntPair;
|
||||
}
|
||||
|
||||
MP4::Item::Item(const ByteVectorList &value)
|
||||
: d(new ItemPrivate())
|
||||
{
|
||||
d->m_byteVectorList = value;
|
||||
d->type = TypeByteVectorList;
|
||||
d->data->m_byteVectorList = value;
|
||||
d->data->type = TypeByteVectorList;
|
||||
}
|
||||
|
||||
MP4::Item::Item(const StringList &value)
|
||||
: d(new ItemPrivate())
|
||||
{
|
||||
d->m_stringList = value;
|
||||
d->type = TypeStringList;
|
||||
d->data->m_stringList = value;
|
||||
d->data->type = TypeStringList;
|
||||
}
|
||||
|
||||
MP4::Item::Item(const MP4::CoverArtList &value)
|
||||
: d(new ItemPrivate())
|
||||
{
|
||||
d->m_coverArtList = value;
|
||||
d->type = TypeCoverArtList;
|
||||
d->data->m_coverArtList = value;
|
||||
d->data->type = TypeCoverArtList;
|
||||
}
|
||||
|
||||
void MP4::Item::setAtomDataType(MP4::AtomDataType type)
|
||||
{
|
||||
d->atomDataType = type;
|
||||
d->data->atomDataType = type;
|
||||
}
|
||||
|
||||
MP4::AtomDataType MP4::Item::atomDataType() const
|
||||
{
|
||||
return d->atomDataType;
|
||||
return d->data->atomDataType;
|
||||
}
|
||||
|
||||
bool
|
||||
MP4::Item::toBool() const
|
||||
{
|
||||
return d->m_bool;
|
||||
return d->data->m_bool;
|
||||
}
|
||||
|
||||
int
|
||||
MP4::Item::toInt() const
|
||||
{
|
||||
return d->m_int;
|
||||
return d->data->m_int;
|
||||
}
|
||||
|
||||
uchar
|
||||
MP4::Item::toByte() const
|
||||
{
|
||||
return d->m_byte;
|
||||
return d->data->m_byte;
|
||||
}
|
||||
|
||||
TagLib::uint
|
||||
MP4::Item::toUInt() const
|
||||
{
|
||||
return d->m_uint;
|
||||
return d->data->m_uint;
|
||||
}
|
||||
|
||||
long long
|
||||
MP4::Item::toLongLong() const
|
||||
{
|
||||
return d->m_longlong;
|
||||
return d->data->m_longlong;
|
||||
}
|
||||
|
||||
MP4::Item::IntPair
|
||||
MP4::Item::toIntPair() const
|
||||
{
|
||||
return d->m_intPair;
|
||||
return d->data->m_intPair;
|
||||
}
|
||||
|
||||
StringList
|
||||
MP4::Item::toStringList() const
|
||||
{
|
||||
return d->m_stringList;
|
||||
return d->data->m_stringList;
|
||||
}
|
||||
|
||||
ByteVectorList
|
||||
MP4::Item::toByteVectorList() const
|
||||
{
|
||||
return d->m_byteVectorList;
|
||||
return d->data->m_byteVectorList;
|
||||
}
|
||||
|
||||
MP4::CoverArtList
|
||||
MP4::Item::toCoverArtList() const
|
||||
{
|
||||
return d->m_coverArtList;
|
||||
return d->data->m_coverArtList;
|
||||
}
|
||||
|
||||
bool
|
||||
MP4::Item::isValid() const
|
||||
{
|
||||
return d->valid;
|
||||
return d->data->valid;
|
||||
}
|
||||
|
||||
String
|
||||
MP4::Item::toString() const
|
||||
{
|
||||
StringList desc;
|
||||
switch (d->type) {
|
||||
switch (d->data->type) {
|
||||
case TypeBool:
|
||||
return d->m_bool ? "true" : "false";
|
||||
return d->data->m_bool ? "true" : "false";
|
||||
case TypeInt:
|
||||
return format("%d", d->m_int);
|
||||
return format("%d", d->data->m_int);
|
||||
case TypeIntPair:
|
||||
return format("%d/%d", d->m_intPair.first, d->m_intPair.second);
|
||||
return format("%d/%d", d->data->m_intPair.first, d->data->m_intPair.second);
|
||||
case TypeByte:
|
||||
return format("%d", d->m_byte);
|
||||
return format("%d", d->data->m_byte);
|
||||
case TypeUInt:
|
||||
return format("%u", d->m_uint);
|
||||
return format("%u", d->data->m_uint);
|
||||
case TypeLongLong:
|
||||
return format("%lld", d->m_longlong);
|
||||
return format("%lld", d->data->m_longlong);
|
||||
case TypeStringList:
|
||||
return d->m_stringList.toString(" / ");
|
||||
return d->data->m_stringList.toString(" / ");
|
||||
case TypeByteVectorList:
|
||||
for(TagLib::uint i = 0; i < d->m_byteVectorList.size(); i++) {
|
||||
for(TagLib::uint i = 0; i < d->data->m_byteVectorList.size(); i++) {
|
||||
desc.append(format(
|
||||
"[%d bytes of data]", static_cast<int>(d->m_byteVectorList[i].size())));
|
||||
"[%d bytes of data]", static_cast<int>(d->data->m_byteVectorList[i].size())));
|
||||
}
|
||||
return desc.toString(", ");
|
||||
case TypeCoverArtList:
|
||||
for(TagLib::uint i = 0; i < d->m_coverArtList.size(); i++) {
|
||||
for(TagLib::uint i = 0; i < d->data->m_coverArtList.size(); i++) {
|
||||
desc.append(format(
|
||||
"[%d bytes of data]", static_cast<int>(d->m_coverArtList[i].data().size())));
|
||||
"[%d bytes of data]", static_cast<int>(d->data->m_coverArtList[i].data().size())));
|
||||
}
|
||||
return desc.toString(", ");
|
||||
case TypeUndefined:
|
||||
|
||||
@ -56,14 +56,8 @@ namespace TagLib {
|
||||
|
||||
Item();
|
||||
Item(const Item &item);
|
||||
#ifdef TAGLIB_USE_MOVE_SEMANTICS
|
||||
Item(Item &&item);
|
||||
#endif
|
||||
|
||||
Item &operator=(const Item &item);
|
||||
#ifdef TAGLIB_USE_MOVE_SEMANTICS
|
||||
Item &operator=(Item &&item);
|
||||
#endif
|
||||
~Item();
|
||||
|
||||
Item(int value);
|
||||
@ -97,7 +91,7 @@ namespace TagLib {
|
||||
|
||||
private:
|
||||
class ItemPrivate;
|
||||
RefCountPtr<ItemPrivate> d;
|
||||
ItemPrivate *d;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@ -48,10 +48,16 @@ using namespace ID3v2;
|
||||
class ID3v2::Tag::TagPrivate
|
||||
{
|
||||
public:
|
||||
TagPrivate() : file(0), tagOffset(-1), extendedHeader(0), footer(0), paddingSize(0)
|
||||
TagPrivate()
|
||||
: file(0)
|
||||
, tagOffset(-1)
|
||||
, extendedHeader(0)
|
||||
, footer(0)
|
||||
, paddingSize(0)
|
||||
{
|
||||
frameList.setAutoDelete(true);
|
||||
}
|
||||
|
||||
~TagPrivate()
|
||||
{
|
||||
delete extendedHeader;
|
||||
|
||||
@ -25,41 +25,51 @@
|
||||
|
||||
#include <bitset>
|
||||
|
||||
#include <tbytevector.h>
|
||||
#include <tstring.h>
|
||||
#include <tdebug.h>
|
||||
#include "tstring.h"
|
||||
#include "tdebug.h"
|
||||
#include "tsmartptr.h"
|
||||
#include "mpegheader.h"
|
||||
|
||||
using namespace TagLib;
|
||||
|
||||
namespace
|
||||
{
|
||||
struct HeaderData
|
||||
{
|
||||
bool isValid;
|
||||
MPEG::Header::Version version;
|
||||
int layer;
|
||||
bool protectionEnabled;
|
||||
int bitrate;
|
||||
int sampleRate;
|
||||
bool isPadded;
|
||||
MPEG::Header::ChannelMode channelMode;
|
||||
bool isCopyrighted;
|
||||
bool isOriginal;
|
||||
int frameLength;
|
||||
int samplesPerFrame;
|
||||
};
|
||||
}
|
||||
class MPEG::Header::HeaderPrivate
|
||||
{
|
||||
public:
|
||||
HeaderPrivate() :
|
||||
isValid(false),
|
||||
version(Version1),
|
||||
layer(0),
|
||||
protectionEnabled(false),
|
||||
sampleRate(0),
|
||||
isPadded(false),
|
||||
channelMode(Stereo),
|
||||
isCopyrighted(false),
|
||||
isOriginal(false),
|
||||
frameLength(0),
|
||||
samplesPerFrame(0) {}
|
||||
HeaderPrivate()
|
||||
: data(new HeaderData())
|
||||
{
|
||||
data->isValid = false;
|
||||
data->layer = 0;
|
||||
data->version = Version1;
|
||||
data->protectionEnabled = false;
|
||||
data->sampleRate = 0;
|
||||
data->isPadded = false;
|
||||
data->channelMode = Stereo;
|
||||
data->isCopyrighted = false;
|
||||
data->isOriginal = false;
|
||||
data->frameLength = 0;
|
||||
data->samplesPerFrame = 0;
|
||||
}
|
||||
|
||||
bool isValid;
|
||||
Version version;
|
||||
int layer;
|
||||
bool protectionEnabled;
|
||||
int bitrate;
|
||||
int sampleRate;
|
||||
bool isPadded;
|
||||
ChannelMode channelMode;
|
||||
bool isCopyrighted;
|
||||
bool isOriginal;
|
||||
int frameLength;
|
||||
int samplesPerFrame;
|
||||
SHARED_PTR<HeaderData> data;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@ -73,99 +83,80 @@ MPEG::Header::Header(const ByteVector &data)
|
||||
}
|
||||
|
||||
MPEG::Header::Header(const Header &h)
|
||||
: d(h.d)
|
||||
: d(new HeaderPrivate(*h.d))
|
||||
{
|
||||
}
|
||||
|
||||
#ifdef TAGLIB_USE_MOVE_SEMANTICS
|
||||
|
||||
MPEG::Header::Header(Header &&h)
|
||||
: d(std::move(h.d))
|
||||
{
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
MPEG::Header::~Header()
|
||||
{
|
||||
}
|
||||
|
||||
bool MPEG::Header::isValid() const
|
||||
{
|
||||
return d->isValid;
|
||||
return d->data->isValid;
|
||||
}
|
||||
|
||||
MPEG::Header::Version MPEG::Header::version() const
|
||||
{
|
||||
return d->version;
|
||||
return d->data->version;
|
||||
}
|
||||
|
||||
int MPEG::Header::layer() const
|
||||
{
|
||||
return d->layer;
|
||||
return d->data->layer;
|
||||
}
|
||||
|
||||
bool MPEG::Header::protectionEnabled() const
|
||||
{
|
||||
return d->protectionEnabled;
|
||||
return d->data->protectionEnabled;
|
||||
}
|
||||
|
||||
int MPEG::Header::bitrate() const
|
||||
{
|
||||
return d->bitrate;
|
||||
return d->data->bitrate;
|
||||
}
|
||||
|
||||
int MPEG::Header::sampleRate() const
|
||||
{
|
||||
return d->sampleRate;
|
||||
return d->data->sampleRate;
|
||||
}
|
||||
|
||||
bool MPEG::Header::isPadded() const
|
||||
{
|
||||
return d->isPadded;
|
||||
return d->data->isPadded;
|
||||
}
|
||||
|
||||
MPEG::Header::ChannelMode MPEG::Header::channelMode() const
|
||||
{
|
||||
return d->channelMode;
|
||||
return d->data->channelMode;
|
||||
}
|
||||
|
||||
bool MPEG::Header::isCopyrighted() const
|
||||
{
|
||||
return d->isCopyrighted;
|
||||
return d->data->isCopyrighted;
|
||||
}
|
||||
|
||||
bool MPEG::Header::isOriginal() const
|
||||
{
|
||||
return d->isOriginal;
|
||||
return d->data->isOriginal;
|
||||
}
|
||||
|
||||
int MPEG::Header::frameLength() const
|
||||
{
|
||||
return d->frameLength;
|
||||
return d->data->frameLength;
|
||||
}
|
||||
|
||||
int MPEG::Header::samplesPerFrame() const
|
||||
{
|
||||
return d->samplesPerFrame;
|
||||
return d->data->samplesPerFrame;
|
||||
}
|
||||
|
||||
MPEG::Header &MPEG::Header::operator=(const Header &h)
|
||||
{
|
||||
d = h.d;
|
||||
*d = *h.d;
|
||||
return *this;
|
||||
}
|
||||
|
||||
#ifdef TAGLIB_USE_MOVE_SEMANTICS
|
||||
|
||||
MPEG::Header &MPEG::Header::operator=(Header &&h)
|
||||
{
|
||||
d = std::move(h.d);
|
||||
return *this;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// private members
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@ -189,22 +180,22 @@ void MPEG::Header::parse(const ByteVector &data)
|
||||
// Set the MPEG version
|
||||
|
||||
if(!flags[20] && !flags[19])
|
||||
d->version = Version2_5;
|
||||
d->data->version = Version2_5;
|
||||
else if(flags[20] && !flags[19])
|
||||
d->version = Version2;
|
||||
d->data->version = Version2;
|
||||
else if(flags[20] && flags[19])
|
||||
d->version = Version1;
|
||||
d->data->version = Version1;
|
||||
|
||||
// Set the MPEG layer
|
||||
|
||||
if(!flags[18] && flags[17])
|
||||
d->layer = 3;
|
||||
d->data->layer = 3;
|
||||
else if(flags[18] && !flags[17])
|
||||
d->layer = 2;
|
||||
d->data->layer = 2;
|
||||
else if(flags[18] && flags[17])
|
||||
d->layer = 1;
|
||||
d->data->layer = 1;
|
||||
|
||||
d->protectionEnabled = !flags[16];
|
||||
d->data->protectionEnabled = !flags[16];
|
||||
|
||||
// Set the bitrate
|
||||
|
||||
@ -221,15 +212,15 @@ void MPEG::Header::parse(const ByteVector &data)
|
||||
}
|
||||
};
|
||||
|
||||
const int versionIndex = d->version == Version1 ? 0 : 1;
|
||||
const int layerIndex = d->layer > 0 ? d->layer - 1 : 0;
|
||||
const int versionIndex = d->data->version == Version1 ? 0 : 1;
|
||||
const int layerIndex = d->data->layer > 0 ? d->data->layer - 1 : 0;
|
||||
|
||||
// The bitrate index is encoded as the first 4 bits of the 3rd byte,
|
||||
// i.e. 1111xxxx
|
||||
|
||||
int i = uchar(data[2]) >> 4;
|
||||
|
||||
d->bitrate = bitrates[versionIndex][layerIndex][i];
|
||||
d->data->bitrate = bitrates[versionIndex][layerIndex][i];
|
||||
|
||||
// Set the sample rate
|
||||
|
||||
@ -243,9 +234,9 @@ void MPEG::Header::parse(const ByteVector &data)
|
||||
|
||||
i = uchar(data[2]) >> 2 & 0x03;
|
||||
|
||||
d->sampleRate = sampleRates[d->version][i];
|
||||
d->data->sampleRate = sampleRates[d->data->version][i];
|
||||
|
||||
if(d->sampleRate == 0) {
|
||||
if(d->data->sampleRate == 0) {
|
||||
debug("MPEG::Header::parse() -- Invalid sample rate.");
|
||||
return;
|
||||
}
|
||||
@ -253,20 +244,20 @@ void MPEG::Header::parse(const ByteVector &data)
|
||||
// The channel mode is encoded as a 2 bit value at the end of the 3nd byte,
|
||||
// i.e. xxxxxx11
|
||||
|
||||
d->channelMode = ChannelMode((uchar(data[3]) & 0xC0) >> 6);
|
||||
d->data->channelMode = ChannelMode((uchar(data[3]) & 0xC0) >> 6);
|
||||
|
||||
// TODO: Add mode extension for completeness
|
||||
|
||||
d->isOriginal = flags[2];
|
||||
d->isCopyrighted = flags[3];
|
||||
d->isPadded = flags[9];
|
||||
d->data->isOriginal = flags[2];
|
||||
d->data->isCopyrighted = flags[3];
|
||||
d->data->isPadded = flags[9];
|
||||
|
||||
// Calculate the frame length
|
||||
|
||||
if(d->layer == 1)
|
||||
d->frameLength = 24000 * 2 * d->bitrate / d->sampleRate + int(d->isPadded);
|
||||
if(d->data->layer == 1)
|
||||
d->data->frameLength = 24000 * 2 * d->data->bitrate / d->data->sampleRate + int(d->data->isPadded);
|
||||
else
|
||||
d->frameLength = 72000 * d->bitrate / d->sampleRate + int(d->isPadded);
|
||||
d->data->frameLength = 72000 * d->data->bitrate / d->data->sampleRate + int(d->data->isPadded);
|
||||
|
||||
// Samples per frame
|
||||
|
||||
@ -277,9 +268,9 @@ void MPEG::Header::parse(const ByteVector &data)
|
||||
{ 1152, 576 } // Layer III
|
||||
};
|
||||
|
||||
d->samplesPerFrame = samplesPerFrame[layerIndex][versionIndex];
|
||||
d->data->samplesPerFrame = samplesPerFrame[layerIndex][versionIndex];
|
||||
|
||||
// Now that we're done parsing, set this to be a valid frame.
|
||||
|
||||
d->isValid = true;
|
||||
d->data->isValid = true;
|
||||
}
|
||||
|
||||
@ -27,7 +27,6 @@
|
||||
#define TAGLIB_MPEGHEADER_H
|
||||
|
||||
#include "taglib_export.h"
|
||||
#include "tsmartptr.h"
|
||||
|
||||
namespace TagLib {
|
||||
|
||||
@ -57,17 +56,6 @@ namespace TagLib {
|
||||
*/
|
||||
Header(const Header &h);
|
||||
|
||||
#ifdef TAGLIB_USE_MOVE_SEMANTICS
|
||||
|
||||
/*!
|
||||
* Moves \a h into this Header.
|
||||
*
|
||||
* \note Not available unless TAGLIB_USE_MOVE_SEMANTICS macro is defined.
|
||||
*/
|
||||
Header(Header &&h);
|
||||
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* Destroys this Header instance.
|
||||
*/
|
||||
@ -166,22 +154,11 @@ namespace TagLib {
|
||||
*/
|
||||
Header &operator=(const Header &h);
|
||||
|
||||
#ifdef TAGLIB_USE_MOVE_SEMANTICS
|
||||
|
||||
/*!
|
||||
* Moves \a h into this Header.
|
||||
*
|
||||
* \note Not available unless TAGLIB_USE_MOVE_SEMANTICS macro is defined.
|
||||
*/
|
||||
Header &operator=(Header &&h);
|
||||
|
||||
#endif
|
||||
|
||||
private:
|
||||
void parse(const ByteVector &data);
|
||||
|
||||
class HeaderPrivate;
|
||||
RefCountPtr<HeaderPrivate> d;
|
||||
HeaderPrivate *d;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@ -40,7 +40,6 @@ public:
|
||||
sampleWidth(0),
|
||||
sampleFrames(0)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
int length;
|
||||
@ -64,11 +63,12 @@ RIFF::AIFF::AudioProperties::AudioProperties(const ByteVector &data, ReadStyle s
|
||||
|
||||
RIFF::AIFF::AudioProperties::~AudioProperties()
|
||||
{
|
||||
delete d;
|
||||
}
|
||||
|
||||
bool RIFF::AIFF::AudioProperties::isNull() const
|
||||
{
|
||||
return (static_cast<bool>(d));
|
||||
return (d == 0);
|
||||
}
|
||||
|
||||
int RIFF::AIFF::AudioProperties::length() const
|
||||
|
||||
@ -73,7 +73,7 @@ namespace TagLib {
|
||||
void read(const ByteVector &data);
|
||||
|
||||
class PropertiesPrivate;
|
||||
RefCountPtr<PropertiesPrivate> d;
|
||||
PropertiesPrivate *d;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,17 +1,3 @@
|
||||
/* taglib_config.h. Generated by cmake from taglib_config.h.cmake */
|
||||
|
||||
/* The variables below indicate the compiler capability. */
|
||||
/* DO NOT MODIFY them manually. It may break the binary compatibility. */
|
||||
|
||||
/* Defined if your compiler supports the move semantics */
|
||||
#cmakedefine TAGLIB_USE_MOVE_SEMANTICS 1
|
||||
|
||||
/* Defined if your compiler supports shared_ptr */
|
||||
#cmakedefine TAGLIB_USE_STD_SHARED_PTR 1 // #include <memory> / std::shared_ptr<T>
|
||||
#cmakedefine TAGLIB_USE_TR1_SHARED_PTR 1 // #include <tr1/memory> / std::tr1::shared_ptr<T>
|
||||
#cmakedefine TAGLIB_USE_BOOST_SHARED_PTR 1 // #include <boost/shared_ptr.hpp> / boost::shared_ptr<T>
|
||||
|
||||
/* Defined if your compiler supports unique_ptr or scoped_ptr */
|
||||
#cmakedefine TAGLIB_USE_STD_UNIQUE_PTR 1 // #include <memory> / std::unique_ptr<T>
|
||||
#cmakedefine TAGLIB_USE_BOOST_SCOPED_PTR 1 // #include <boost/scoped_ptr.hpp> / boost::scoped_ptr<T>
|
||||
|
||||
|
||||
@ -26,7 +26,7 @@
|
||||
#include "tagunion.h"
|
||||
#include "tstringlist.h"
|
||||
#include "tpropertymap.h"
|
||||
|
||||
#include "tsmartptr.h"
|
||||
|
||||
#define stringUnion(method) \
|
||||
for(size_t j = 0; j < COUNT; ++j) { \
|
||||
@ -56,7 +56,7 @@ namespace TagLib
|
||||
class TagUnion<COUNT>::TagUnionPrivate
|
||||
{
|
||||
public:
|
||||
NonRefCountPtr<Tag> tags[COUNT];
|
||||
SCOPED_PTR<Tag> tags[COUNT];
|
||||
};
|
||||
|
||||
template <size_t COUNT>
|
||||
@ -68,6 +68,7 @@ namespace TagLib
|
||||
template <size_t COUNT>
|
||||
TagUnion<COUNT>::~TagUnion()
|
||||
{
|
||||
delete d;
|
||||
}
|
||||
|
||||
template <size_t COUNT>
|
||||
|
||||
@ -26,6 +26,8 @@
|
||||
#ifndef TAGLIB_TAGUNION_H
|
||||
#define TAGLIB_TAGUNION_H
|
||||
|
||||
// This file is not a part of TagLib public interface. This is not installed.
|
||||
|
||||
#include "tag.h"
|
||||
|
||||
#ifndef DO_NOT_DOCUMENT
|
||||
@ -87,7 +89,7 @@ namespace TagLib {
|
||||
|
||||
private:
|
||||
class TagUnionPrivate;
|
||||
NonRefCountPtr<TagUnionPrivate> d;
|
||||
TagUnionPrivate *d;
|
||||
};
|
||||
|
||||
// If you add a new typedef here, add a corresponding explicit instantiation
|
||||
|
||||
@ -41,8 +41,9 @@
|
||||
# include <sys/endian.h>
|
||||
#endif
|
||||
|
||||
#include <tstring.h>
|
||||
#include <tdebug.h>
|
||||
#include "tstring.h"
|
||||
#include "tdebug.h"
|
||||
#include "tsmartptr.h"
|
||||
#include "tbytevector.h"
|
||||
|
||||
// This is a bit ugly to keep writing over and over again.
|
||||
@ -366,20 +367,13 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
ByteVectorPrivate(RefCountPtr<ByteVectorPrivate> d, size_t o, size_t l)
|
||||
ByteVectorPrivate(ByteVectorPrivate* d, size_t o, size_t l)
|
||||
: data(d->data)
|
||||
, offset(d->offset + o)
|
||||
, length(l)
|
||||
{
|
||||
}
|
||||
|
||||
ByteVectorPrivate(const std::vector<char> &v, size_t o, size_t l)
|
||||
: data(new std::vector<char>(v.begin() + o, v.begin() + o + l))
|
||||
, offset(0)
|
||||
, length(l)
|
||||
{
|
||||
}
|
||||
|
||||
ByteVectorPrivate(size_t l, char c)
|
||||
: data(new std::vector<char>(l, c))
|
||||
, offset(0)
|
||||
@ -406,15 +400,7 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
ByteVectorPrivate &operator=(const ByteVectorPrivate &x)
|
||||
{
|
||||
if(&x != this)
|
||||
data = x.data;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
RefCountPtr<std::vector<char> > data;
|
||||
SHARED_PTR<std::vector<char> > data;
|
||||
size_t offset;
|
||||
size_t length;
|
||||
};
|
||||
@ -480,7 +466,7 @@ ByteVector::ByteVector(size_t size, char value)
|
||||
}
|
||||
|
||||
ByteVector::ByteVector(const ByteVector &v)
|
||||
: d(v.d)
|
||||
: d(new ByteVectorPrivate(*v.d))
|
||||
{
|
||||
}
|
||||
|
||||
@ -489,15 +475,6 @@ ByteVector::ByteVector(const ByteVector &v, size_t offset, size_t length)
|
||||
{
|
||||
}
|
||||
|
||||
#ifdef TAGLIB_USE_MOVE_SEMANTICS
|
||||
|
||||
ByteVector::ByteVector(ByteVector &&v)
|
||||
: d(std::move(v.d))
|
||||
{
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
ByteVector::ByteVector(char c)
|
||||
: d(new ByteVectorPrivate(1, c))
|
||||
{
|
||||
@ -515,6 +492,7 @@ ByteVector::ByteVector(const char *data)
|
||||
|
||||
ByteVector::~ByteVector()
|
||||
{
|
||||
delete d;
|
||||
}
|
||||
|
||||
ByteVector &ByteVector::setData(const char *data, size_t length)
|
||||
@ -641,8 +619,8 @@ ByteVector &ByteVector::replace(const ByteVector &pattern, const ByteVector &wit
|
||||
}
|
||||
|
||||
// new private data of appropriate size:
|
||||
ByteVectorPrivate *newData = new ByteVectorPrivate(newSize, 0);
|
||||
char *target = DATA(newData);
|
||||
ByteVectorPrivate newData(newSize, '\0');
|
||||
char *target = &(*newData.data)[0];
|
||||
const char *source = DATA(d);
|
||||
|
||||
// copy modified data into new private data:
|
||||
@ -662,7 +640,7 @@ ByteVector &ByteVector::replace(const ByteVector &pattern, const ByteVector &wit
|
||||
}
|
||||
|
||||
// replace private data:
|
||||
d.reset(newData);
|
||||
*d = newData;
|
||||
|
||||
return *this;
|
||||
}
|
||||
@ -708,7 +686,7 @@ ByteVector &ByteVector::append(char c)
|
||||
ByteVector &ByteVector::clear()
|
||||
{
|
||||
detach();
|
||||
*this = ByteVector();
|
||||
*d = *ByteVector::null.d;
|
||||
|
||||
return *this;
|
||||
}
|
||||
@ -1071,30 +1049,20 @@ ByteVector ByteVector::operator+(const ByteVector &v) const
|
||||
|
||||
ByteVector &ByteVector::operator=(const ByteVector &v)
|
||||
{
|
||||
d = v.d;
|
||||
*d = *v.d;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
#ifdef TAGLIB_USE_MOVE_SEMANTICS
|
||||
|
||||
ByteVector &ByteVector::operator=(ByteVector &&v)
|
||||
{
|
||||
d = std::move(v.d);
|
||||
return *this;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
ByteVector &ByteVector::operator=(char c)
|
||||
{
|
||||
d = ByteVector(c).d;
|
||||
*this = ByteVector(c);
|
||||
return *this;
|
||||
}
|
||||
|
||||
ByteVector &ByteVector::operator=(const char *data)
|
||||
{
|
||||
d = ByteVector(data).d;
|
||||
*this = ByteVector(data);
|
||||
return *this;
|
||||
}
|
||||
|
||||
@ -1119,9 +1087,6 @@ ByteVector ByteVector::toHex() const
|
||||
void ByteVector::detach()
|
||||
{
|
||||
d->detach();
|
||||
|
||||
if(!d.unique())
|
||||
d.reset(new ByteVectorPrivate(*(d->data), d->offset, d->length));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@ -28,7 +28,6 @@
|
||||
|
||||
#include "taglib_export.h"
|
||||
#include "taglib.h"
|
||||
#include "tsmartptr.h"
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
|
||||
@ -68,17 +67,6 @@ namespace TagLib {
|
||||
*/
|
||||
ByteVector(const ByteVector &v);
|
||||
|
||||
#ifdef TAGLIB_USE_MOVE_SEMANTICS
|
||||
|
||||
/*!
|
||||
* Constructs a byte vector equivalent to \a v.
|
||||
*
|
||||
* \note Not available unless TAGLIB_USE_MOVE_SEMANTICS macro is defined.
|
||||
*/
|
||||
ByteVector(ByteVector &&v);
|
||||
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* Constructs a byte vector that is a copy of \a v.
|
||||
*/
|
||||
@ -502,17 +490,6 @@ namespace TagLib {
|
||||
*/
|
||||
ByteVector &operator=(const ByteVector &v);
|
||||
|
||||
#ifdef TAGLIB_USE_MOVE_SEMANTICS
|
||||
|
||||
/*!
|
||||
* Moves \a v into this ByteVector.
|
||||
*
|
||||
* \note Not available unless TAGLIB_USE_MOVE_SEMANTICS macro is defined.
|
||||
*/
|
||||
ByteVector &operator=(ByteVector &&v);
|
||||
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* Copies ByteVector \a v.
|
||||
*/
|
||||
@ -551,7 +528,7 @@ namespace TagLib {
|
||||
|
||||
private:
|
||||
class ByteVectorPrivate;
|
||||
RefCountPtr<ByteVectorPrivate> d;
|
||||
ByteVectorPrivate *d;
|
||||
};
|
||||
|
||||
/*!
|
||||
|
||||
@ -27,6 +27,7 @@
|
||||
#include "tfilestream.h"
|
||||
#include "tstring.h"
|
||||
#include "tdebug.h"
|
||||
#include "tsmartptr.h"
|
||||
#include "tpropertymap.h"
|
||||
#include "audioproperties.h"
|
||||
|
||||
@ -65,7 +66,7 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
NonRefCountPtr<IOStream> p;
|
||||
SCOPED_PTR<IOStream> p;
|
||||
};
|
||||
|
||||
// FilePrivate implementation which doesn't take ownership of the stream.
|
||||
@ -93,6 +94,7 @@ private:
|
||||
|
||||
File::~File()
|
||||
{
|
||||
delete d;
|
||||
}
|
||||
|
||||
FileName File::name() const
|
||||
|
||||
@ -278,13 +278,14 @@ namespace TagLib {
|
||||
static size_t bufferSize();
|
||||
|
||||
private:
|
||||
// Noncopyable. Derived classes as well.
|
||||
File(const File &);
|
||||
File &operator=(const File &);
|
||||
|
||||
class FilePrivateBase;
|
||||
class ManagedFilePrivate;
|
||||
class UnmanagedFilePrivate;
|
||||
NonRefCountPtr<FilePrivateBase> d;
|
||||
FilePrivateBase *d;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@ -194,6 +194,8 @@ FileStream::~FileStream()
|
||||
{
|
||||
if(isOpen())
|
||||
closeFile(d->file);
|
||||
|
||||
delete d;
|
||||
}
|
||||
|
||||
FileName FileStream::name() const
|
||||
|
||||
@ -142,7 +142,7 @@ namespace TagLib {
|
||||
|
||||
private:
|
||||
class FileStreamPrivate;
|
||||
NonRefCountPtr<FileStreamPrivate> d;
|
||||
FileStreamPrivate *d;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@ -158,6 +158,8 @@ namespace TagLib {
|
||||
virtual void truncate(offset_t length) = 0;
|
||||
|
||||
private:
|
||||
// Noncopyable. Derived classes as well.
|
||||
|
||||
IOStream(const IOStream &);
|
||||
IOStream &operator=(const IOStream &);
|
||||
};
|
||||
|
||||
@ -27,7 +27,6 @@
|
||||
#define TAGLIB_LIST_H
|
||||
|
||||
#include "taglib.h"
|
||||
#include "tsmartptr.h"
|
||||
#include <list>
|
||||
|
||||
namespace TagLib {
|
||||
@ -70,17 +69,6 @@ namespace TagLib {
|
||||
*/
|
||||
List(const List<T> &l);
|
||||
|
||||
#ifdef TAGLIB_USE_MOVE_SEMANTICS
|
||||
|
||||
/*!
|
||||
* Moves \a l into this List.
|
||||
*
|
||||
* \note Not available unless TAGLIB_USE_MOVE_SEMANTICS macro is defined.
|
||||
*/
|
||||
List(List<T> &&l);
|
||||
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* Destroys this List instance. If auto deletion is enabled and this list
|
||||
* contains a pointer type all of the memebers are also deleted.
|
||||
@ -135,26 +123,6 @@ namespace TagLib {
|
||||
*/
|
||||
List<T> &append(const List<T> &l);
|
||||
|
||||
#ifdef TAGLIB_USE_MOVE_SEMANTICS
|
||||
|
||||
/*!
|
||||
* Appends \a item to the end of the list and returns a reference to the
|
||||
* list.
|
||||
*
|
||||
* \note Not available unless TAGLIB_USE_MOVE_SEMANTICS macro is defined.
|
||||
*/
|
||||
List<T> &append(T &&item);
|
||||
|
||||
/*!
|
||||
* Appends all of the values in \a l to the end of the list and returns a
|
||||
* reference to the list.
|
||||
*
|
||||
* \note Not available unless TAGLIB_USE_MOVE_SEMANTICS macro is defined.
|
||||
*/
|
||||
List<T> &append(List<T> &&l);
|
||||
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* Prepends \a item to the beginning list and returns a reference to the
|
||||
* list.
|
||||
@ -167,26 +135,6 @@ namespace TagLib {
|
||||
*/
|
||||
List<T> &prepend(const List<T> &l);
|
||||
|
||||
#ifdef TAGLIB_USE_MOVE_SEMANTICS
|
||||
|
||||
/*!
|
||||
* Prepends \a item to the beginning list and returns a reference to the
|
||||
* list.
|
||||
*
|
||||
* \note Not available unless TAGLIB_USE_MOVE_SEMANTICS macro is defined.
|
||||
*/
|
||||
List<T> &prepend(T &&item);
|
||||
|
||||
/*!
|
||||
* Prepends all of the items in \a l to the beginning list and returns a
|
||||
* reference to the list.
|
||||
*
|
||||
* \note Not available unless TAGLIB_USE_MOVE_SEMANTICS macro is defined.
|
||||
*/
|
||||
List<T> &prepend(List<T> &&l);
|
||||
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* Clears the list. If auto deletion is enabled and this list contains a
|
||||
* pointer type the members are also deleted.
|
||||
@ -275,17 +223,6 @@ namespace TagLib {
|
||||
*/
|
||||
List<T> &operator=(const List<T> &l);
|
||||
|
||||
#ifdef TAGLIB_USE_MOVE_SEMANTICS
|
||||
|
||||
/*!
|
||||
* Moves \a l into this List.
|
||||
*
|
||||
* \note Not available unless TAGLIB_USE_MOVE_SEMANTICS macro is defined.
|
||||
*/
|
||||
List<T> &operator=(List<T> &&l);
|
||||
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* Compares this list with \a l and returns true if all of the elements are
|
||||
* the same.
|
||||
@ -308,7 +245,7 @@ namespace TagLib {
|
||||
private:
|
||||
#ifndef DO_NOT_DOCUMENT
|
||||
template <class TP> class ListPrivate;
|
||||
RefCountPtr<ListPrivate<T> > d;
|
||||
ListPrivate<T> *d;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
|
||||
/***************************************************************************
|
||||
copyright : (C) 2002 - 2008 by Scott Wheeler
|
||||
email : wheeler@kde.org
|
||||
@ -23,8 +24,8 @@
|
||||
* http://www.mozilla.org/MPL/ *
|
||||
***************************************************************************/
|
||||
|
||||
#include <config.h>
|
||||
#include <algorithm>
|
||||
#include "trefcounter.h"
|
||||
|
||||
namespace TagLib {
|
||||
|
||||
@ -36,34 +37,30 @@ namespace TagLib {
|
||||
// template specialization. This is implemented in such a way that calling
|
||||
// setAutoDelete() on non-pointer types will simply have no effect.
|
||||
|
||||
// A base for the generic and specialized private class types. New
|
||||
// non-templatized members should be added here.
|
||||
|
||||
class ListPrivateBase
|
||||
{
|
||||
public:
|
||||
ListPrivateBase() : autoDelete(false) {}
|
||||
bool autoDelete;
|
||||
};
|
||||
|
||||
// A generic implementation
|
||||
|
||||
template <class T>
|
||||
template <class TP> class List<T>::ListPrivate : public ListPrivateBase
|
||||
template <class TP> class List<T>::ListPrivate : public RefCounter
|
||||
{
|
||||
public:
|
||||
ListPrivate() : ListPrivateBase() {}
|
||||
ListPrivate(const std::list<TP> &l) : ListPrivateBase(), list(l) {}
|
||||
ListPrivate()
|
||||
{
|
||||
}
|
||||
|
||||
#ifdef TAGLIB_USE_MOVE_SEMANTICS
|
||||
ListPrivate(const std::list<TP> &l)
|
||||
: list(l)
|
||||
{
|
||||
}
|
||||
|
||||
ListPrivate(std::list<TP> &&l) : ListPrivateBase(), list(l) {}
|
||||
|
||||
#endif
|
||||
|
||||
void clear() {
|
||||
void clear()
|
||||
{
|
||||
std::list<TP>().swap(list);
|
||||
}
|
||||
|
||||
void setAutoDelete(bool)
|
||||
{
|
||||
}
|
||||
|
||||
std::list<TP> list;
|
||||
};
|
||||
|
||||
@ -71,38 +68,49 @@ public:
|
||||
// setAutoDelete() functionality.
|
||||
|
||||
template <class T>
|
||||
template <class TP> class List<T>::ListPrivate<TP *> : public ListPrivateBase
|
||||
template <class TP> class List<T>::ListPrivate<TP *> : public RefCounter
|
||||
{
|
||||
public:
|
||||
ListPrivate() : ListPrivateBase() {}
|
||||
ListPrivate(const std::list<TP *> &l) : ListPrivateBase(), list(l) {}
|
||||
ListPrivate()
|
||||
: autoDelete(false)
|
||||
{
|
||||
}
|
||||
|
||||
#ifdef TAGLIB_USE_MOVE_SEMANTICS
|
||||
ListPrivate(const std::list<TP *> &l)
|
||||
: list(l)
|
||||
, autoDelete(false)
|
||||
{
|
||||
}
|
||||
|
||||
ListPrivate(std::list<TP *> &&l) : ListPrivateBase(), list(l) {}
|
||||
|
||||
#endif
|
||||
|
||||
~ListPrivate() {
|
||||
~ListPrivate()
|
||||
{
|
||||
deletePointers();
|
||||
}
|
||||
|
||||
void clear() {
|
||||
void clear()
|
||||
{
|
||||
deletePointers();
|
||||
std::list<TP *>().swap(list);
|
||||
}
|
||||
|
||||
void setAutoDelete(bool del)
|
||||
{
|
||||
autoDelete = del;
|
||||
}
|
||||
|
||||
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;
|
||||
void deletePointers()
|
||||
{
|
||||
if(autoDelete) {
|
||||
typename std::list<TP *>::const_iterator it = list.begin();
|
||||
for(; it != list.end(); ++it)
|
||||
delete *it;
|
||||
}
|
||||
}
|
||||
|
||||
bool autoDelete;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@ -111,29 +119,22 @@ 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)
|
||||
: d(l.d)
|
||||
{
|
||||
d->ref();
|
||||
}
|
||||
|
||||
#ifdef TAGLIB_USE_MOVE_SEMANTICS
|
||||
|
||||
template <class T>
|
||||
List<T>::List(List<T> &&l)
|
||||
: d(std::move(l.d))
|
||||
{
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
template <class T>
|
||||
List<T>::~List()
|
||||
{
|
||||
if(d->deref())
|
||||
delete d;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
@ -198,29 +199,6 @@ List<T> &List<T>::append(const List<T> &l)
|
||||
return *this;
|
||||
}
|
||||
|
||||
#ifdef TAGLIB_USE_MOVE_SEMANTICS
|
||||
|
||||
template <class T>
|
||||
List<T> &List<T>::append(T &&item)
|
||||
{
|
||||
detach();
|
||||
d->list.push_back(item);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
List<T> &List<T>::append(List<T> &&l)
|
||||
{
|
||||
detach();
|
||||
|
||||
for(Iterator it = l.begin(); it != l.end(); ++it)
|
||||
d->list.push_back(std::move(*it));
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
template <class T>
|
||||
List<T> &List<T>::prepend(const T &item)
|
||||
{
|
||||
@ -233,33 +211,10 @@ 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;
|
||||
}
|
||||
|
||||
#ifdef TAGLIB_USE_MOVE_SEMANTICS
|
||||
|
||||
template <class T>
|
||||
List<T> &List<T>::prepend(T &&item)
|
||||
{
|
||||
detach();
|
||||
d->list.push_front(item);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
List<T> &List<T>::prepend(List<T> &&l)
|
||||
{
|
||||
detach();
|
||||
|
||||
for(typename std::list<T>::reverse_iterator it = l.d->list.rbegin(); it != l.d->list.rend(); ++it)
|
||||
d->list.push_front(std::move(*it));
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
template <class T>
|
||||
List<T> &List<T>::clear()
|
||||
{
|
||||
@ -329,7 +284,7 @@ const T &List<T>::back() const
|
||||
template <class T>
|
||||
void List<T>::setAutoDelete(bool autoDelete)
|
||||
{
|
||||
d->autoDelete = autoDelete;
|
||||
d->setAutoDelete(autoDelete);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
@ -364,21 +319,16 @@ const T &List<T>::operator[](size_t 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;
|
||||
}
|
||||
|
||||
#ifdef TAGLIB_USE_MOVE_SEMANTICS
|
||||
|
||||
template <class T>
|
||||
List<T> &List<T>::operator=(List<T> &&l)
|
||||
{
|
||||
d = std::move(l.d);
|
||||
return *this;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
template <class T>
|
||||
bool List<T>::operator==(const List<T> &l) const
|
||||
{
|
||||
@ -398,8 +348,11 @@ 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->unique()) {
|
||||
d->deref();
|
||||
d = new ListPrivate<T>(d->list);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace TagLib
|
||||
|
||||
|
||||
@ -27,7 +27,6 @@
|
||||
#define TAGLIB_MAP_H
|
||||
|
||||
#include "taglib.h"
|
||||
#include "tsmartptr.h"
|
||||
#include <map>
|
||||
|
||||
namespace TagLib {
|
||||
@ -42,7 +41,7 @@ namespace TagLib {
|
||||
|
||||
template <class Key, class T> class Map
|
||||
{
|
||||
public:
|
||||
private:
|
||||
#ifndef DO_NOT_DOCUMENT
|
||||
#ifdef WANT_CLASS_INSTANTIATION_OF_MAP
|
||||
// Some STL implementations get snippy over the use of the
|
||||
@ -53,14 +52,18 @@ namespace TagLib {
|
||||
// Not all the specializations of Map can use the class keyword
|
||||
// (when T is not actually a class type), so don't apply this
|
||||
// generally.
|
||||
typedef typename std::map<class Key, class T>::iterator Iterator;
|
||||
typedef typename std::map<class Key, class T>::const_iterator ConstIterator;
|
||||
typedef std::map<class Key, class T> MapType;
|
||||
#else
|
||||
typedef typename std::map<Key, T>::iterator Iterator;
|
||||
typedef typename std::map<Key, T>::const_iterator ConstIterator;
|
||||
typedef std::map<Key, T> MapType;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
public:
|
||||
#ifndef DO_NOT_DOCUMENT
|
||||
typedef typename MapType::iterator Iterator;
|
||||
typedef typename MapType::const_iterator ConstIterator;
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* Constructs an empty Map.
|
||||
*/
|
||||
@ -73,17 +76,6 @@ namespace TagLib {
|
||||
*/
|
||||
Map(const Map<Key, T> &m);
|
||||
|
||||
#ifdef TAGLIB_USE_MOVE_SEMANTICS
|
||||
|
||||
/*!
|
||||
* Moves \a m into this Map.
|
||||
*
|
||||
* \note Not available unless TAGLIB_USE_MOVE_SEMANTICS macro is defined.
|
||||
*/
|
||||
Map(Map<Key, T> &&m);
|
||||
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* Destroys this instance of the Map.
|
||||
*/
|
||||
@ -119,18 +111,6 @@ namespace TagLib {
|
||||
*/
|
||||
Map<Key, T> &insert(const Key &key, const T &value);
|
||||
|
||||
#ifdef TAGLIB_USE_MOVE_SEMANTICS
|
||||
|
||||
/*!
|
||||
* Inserts \a value under \a key in the map. If a value for \a key already
|
||||
* exists it will be overwritten.
|
||||
*
|
||||
* \note Not available unless TAGLIB_USE_MOVE_SEMANTICS macro is defined.
|
||||
*/
|
||||
Map<Key, T> &insert(const Key &key, T &&value);
|
||||
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* Removes all of the elements from elements from the map. This however
|
||||
* will not delete pointers if the mapped type is a pointer type.
|
||||
@ -197,17 +177,6 @@ namespace TagLib {
|
||||
*/
|
||||
Map<Key, T> &operator=(const Map<Key, T> &m);
|
||||
|
||||
#ifdef TAGLIB_USE_MOVE_SEMANTICS
|
||||
|
||||
/*!
|
||||
* Moves \a m into this Map.
|
||||
*
|
||||
* \note Not available unless TAGLIB_USE_MOVE_SEMANTICS macro is defined.
|
||||
*/
|
||||
Map<Key, T> &operator=(Map<Key, T> &&m);
|
||||
|
||||
#endif
|
||||
|
||||
protected:
|
||||
/*
|
||||
* If this List is being shared via implicit sharing, do a deep copy of the
|
||||
@ -219,8 +188,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
|
||||
};
|
||||
}
|
||||
|
||||
@ -23,6 +23,8 @@
|
||||
* http://www.mozilla.org/MPL/ *
|
||||
***************************************************************************/
|
||||
|
||||
#include "trefcounter.h"
|
||||
|
||||
namespace TagLib {
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@ -31,44 +33,21 @@ 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() {}
|
||||
|
||||
#ifdef WANT_CLASS_INSTANTIATION_OF_MAP
|
||||
|
||||
MapPrivate(const std::map<class KeyP, class TP> &m) : RefCounter(), map(m) {}
|
||||
|
||||
# ifdef TAGLIB_USE_MOVE_SEMANTICS
|
||||
|
||||
MapPrivate(std::map<class KeyP, class TP> &&m) : RefCounter(), map(m) {}
|
||||
|
||||
# endif
|
||||
|
||||
void clear() {
|
||||
std::map<class KeyP, class TP>().swap(map);
|
||||
MapPrivate()
|
||||
: RefCounter()
|
||||
{
|
||||
}
|
||||
|
||||
std::map<class KeyP, class TP> map;
|
||||
|
||||
#else
|
||||
|
||||
MapPrivate(const std::map<KeyP, TP>& m) : map(m) {}
|
||||
|
||||
# ifdef TAGLIB_USE_MOVE_SEMANTICS
|
||||
|
||||
MapPrivate(std::map<KeyP, TP> &&m) : map(m) {}
|
||||
|
||||
# endif
|
||||
|
||||
void clear() {
|
||||
std::map<KeyP, TP>().swap(map);
|
||||
MapPrivate(const MapType &m)
|
||||
: RefCounter()
|
||||
, map(m)
|
||||
{
|
||||
}
|
||||
|
||||
std::map<KeyP, TP> map;
|
||||
|
||||
#endif
|
||||
|
||||
MapType map;
|
||||
};
|
||||
|
||||
template <class Key, class T>
|
||||
@ -78,24 +57,16 @@ Map<Key, T>::Map()
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
#ifdef TAGLIB_USE_MOVE_SEMANTICS
|
||||
|
||||
template <class Key, class T>
|
||||
TagLib::Map<Key, T>::Map(Map<Key, T> &&m)
|
||||
: d(std::move(m.d))
|
||||
{
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
template <class Key, class T>
|
||||
Map<Key, T>::~Map()
|
||||
{
|
||||
if(d->deref())
|
||||
delete d;
|
||||
}
|
||||
|
||||
template <class Key, class T>
|
||||
@ -132,18 +103,6 @@ Map<Key, T> &Map<Key, T>::insert(const Key &key, const T &value)
|
||||
return *this;
|
||||
}
|
||||
|
||||
#ifdef TAGLIB_USE_MOVE_SEMANTICS
|
||||
|
||||
template <class Key, class T>
|
||||
Map<Key, T> &Map<Key, T>::insert(const Key &key, T &&value)
|
||||
{
|
||||
detach();
|
||||
d->map[key] = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
template <class Key, class T>
|
||||
Map<Key, T> &Map<Key, T>::clear()
|
||||
{
|
||||
@ -217,21 +176,16 @@ 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;
|
||||
}
|
||||
|
||||
#ifdef TAGLIB_USE_MOVE_SEMANTICS
|
||||
|
||||
template <class Key, class T>
|
||||
Map<Key, T> &Map<Key, T>::operator=(Map<Key, T> &&m)
|
||||
{
|
||||
d = std::move(m.d);
|
||||
return *this;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// protected members
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@ -239,8 +193,12 @@ Map<Key, T> &Map<Key, T>::operator=(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->unique()) {
|
||||
d->deref();
|
||||
d = new MapPrivate<Key, T>(d->map);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace TagLib
|
||||
|
||||
|
||||
|
||||
@ -23,14 +23,8 @@
|
||||
* http://www.mozilla.org/MPL/ *
|
||||
***************************************************************************/
|
||||
|
||||
#include "taglib_config.h"
|
||||
|
||||
#if !defined(TAGLIB_USE_STD_SHARED_PTR) \
|
||||
&& !defined(TAGLIB_USE_TR1_SHARED_PTR) \
|
||||
&& !defined(TAGLIB_USE_BOOST_SHARED_PTR)
|
||||
|
||||
#include "config.h"
|
||||
#include "tsmartptr.h"
|
||||
#include "trefcounter.h"
|
||||
|
||||
#if defined(HAVE_STD_ATOMIC)
|
||||
# include <atomic>
|
||||
@ -72,10 +66,10 @@
|
||||
|
||||
namespace TagLib
|
||||
{
|
||||
class CounterBase::CounterBasePrivate
|
||||
class RefCounter::RefCounterPrivate
|
||||
{
|
||||
public:
|
||||
CounterBasePrivate()
|
||||
RefCounterPrivate()
|
||||
: refCount(1)
|
||||
{
|
||||
}
|
||||
@ -83,33 +77,28 @@ namespace TagLib
|
||||
volatile ATOMIC_INT refCount;
|
||||
};
|
||||
|
||||
CounterBase::CounterBase()
|
||||
: d(new CounterBasePrivate())
|
||||
RefCounter::RefCounter()
|
||||
: d(new RefCounterPrivate())
|
||||
{
|
||||
}
|
||||
|
||||
CounterBase::~CounterBase()
|
||||
RefCounter::~RefCounter()
|
||||
{
|
||||
delete d;
|
||||
}
|
||||
|
||||
void CounterBase::addref()
|
||||
{
|
||||
void RefCounter::ref()
|
||||
{
|
||||
ATOMIC_INC(d->refCount);
|
||||
}
|
||||
|
||||
void CounterBase::release()
|
||||
{
|
||||
if(ATOMIC_DEC(d->refCount) == 0) {
|
||||
dispose();
|
||||
delete this;
|
||||
}
|
||||
bool RefCounter::deref()
|
||||
{
|
||||
return (ATOMIC_DEC(d->refCount) == 0);
|
||||
}
|
||||
|
||||
long CounterBase::use_count() const
|
||||
{
|
||||
return static_cast<long>(d->refCount);
|
||||
bool RefCounter::unique() const
|
||||
{
|
||||
return (d->refCount == 1);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
54
taglib/toolkit/trefcounter.h
Normal file
54
taglib/toolkit/trefcounter.h
Normal file
@ -0,0 +1,54 @@
|
||||
/***************************************************************************
|
||||
copyright : (C) 2013 by Tsuda Kageyu
|
||||
email : tsuda.kageyu@gmail.com
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* This library is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU Lesser General Public License version *
|
||||
* 2.1 as published by the Free Software Foundation. *
|
||||
* *
|
||||
* This library is distributed in the hope that it will be useful, but *
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
|
||||
* Lesser General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Lesser General Public *
|
||||
* License along with this library; if not, write to the Free Software *
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA *
|
||||
* 02110-1301 USA *
|
||||
* *
|
||||
* Alternatively, this file is available under the Mozilla Public *
|
||||
* License Version 1.1. You may obtain a copy of the License at *
|
||||
* http://www.mozilla.org/MPL/ *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef TAGLIB_REFCOUNTER_H
|
||||
#define TAGLIB_REFCOUNTER_H
|
||||
|
||||
#include "taglib.h"
|
||||
|
||||
#ifndef DO_NOT_DOCUMENT // Tell Doxygen to skip this class.
|
||||
/*!
|
||||
* \warning This <b>is not</b> part of the TagLib public API!
|
||||
*/
|
||||
namespace TagLib
|
||||
{
|
||||
class RefCounter
|
||||
{
|
||||
public:
|
||||
RefCounter();
|
||||
virtual ~RefCounter();
|
||||
|
||||
void ref();
|
||||
bool deref();
|
||||
bool unique() const;
|
||||
|
||||
private:
|
||||
class RefCounterPrivate;
|
||||
RefCounterPrivate *d;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // DO_NOT_DOCUMENT
|
||||
#endif
|
||||
@ -26,179 +26,64 @@
|
||||
#ifndef TAGLIB_SMARTPTR_H
|
||||
#define TAGLIB_SMARTPTR_H
|
||||
|
||||
#include "taglib_config.h"
|
||||
#include <algorithm>
|
||||
// This file is not a part of TagLib public interface. This is not installed.
|
||||
|
||||
#if defined(TAGLIB_USE_STD_SHARED_PTR)
|
||||
# include <memory>
|
||||
#elif defined(TAGLIB_USE_TR1_SHARED_PTR)
|
||||
# include <tr1/memory>
|
||||
#elif defined(TAGLIB_USE_BOOST_SHARED_PTR)
|
||||
# include <boost/shared_ptr.hpp>
|
||||
#endif
|
||||
|
||||
#if defined(TAGLIB_USE_STD_UNIQUE_PTR)
|
||||
# include <memory>
|
||||
#elif defined(TAGLIB_USE_BOOST_SCOPED_PTR)
|
||||
# include <boost/scoped_ptr.hpp>
|
||||
#endif
|
||||
#include "config.h"
|
||||
|
||||
#ifndef DO_NOT_DOCUMENT // Tell Doxygen to skip this class.
|
||||
/*!
|
||||
* \warning This <b>is not</b> part of the TagLib public API!
|
||||
*/
|
||||
|
||||
#if defined(HAVE_STD_SHARED_PTR)
|
||||
|
||||
# include <memory>
|
||||
# define SHARED_PTR std::shared_ptr
|
||||
|
||||
#elif defined(HAVE_TR1_SHARED_PTR)
|
||||
|
||||
# include <tr1/memory>
|
||||
# define SHARED_PTR std::tr1::shared_ptr
|
||||
|
||||
#elif defined(HAVE_BOOST_SHARED_PTR)
|
||||
|
||||
# include <boost/shared_ptr.hpp>
|
||||
# define SHARED_PTR boost::shared_ptr
|
||||
|
||||
#else // HAVE_STD_SHARED_PTR
|
||||
|
||||
# include <algorithm>
|
||||
|
||||
# if defined(HAVE_GCC_ATOMIC)
|
||||
# define ATOMIC_INT int
|
||||
# define ATOMIC_INC(x) __sync_add_and_fetch(&x, 1)
|
||||
# define ATOMIC_DEC(x) __sync_sub_and_fetch(&x, 1)
|
||||
# elif defined(HAVE_WIN_ATOMIC)
|
||||
# if !defined(NOMINMAX)
|
||||
# define NOMINMAX
|
||||
# endif
|
||||
# include <windows.h>
|
||||
# define ATOMIC_INT long
|
||||
# define ATOMIC_INC(x) InterlockedIncrement(&x)
|
||||
# define ATOMIC_DEC(x) InterlockedDecrement(&x)
|
||||
# elif defined(HAVE_MAC_ATOMIC)
|
||||
# include <libkern/OSAtomic.h>
|
||||
# define ATOMIC_INT int32_t
|
||||
# define ATOMIC_INC(x) OSAtomicIncrement32Barrier(&x)
|
||||
# define ATOMIC_DEC(x) OSAtomicDecrement32Barrier(&x)
|
||||
# elif defined(HAVE_IA64_ATOMIC)
|
||||
# include <ia64intrin.h>
|
||||
# define ATOMIC_INT int
|
||||
# define ATOMIC_INC(x) __sync_add_and_fetch(&x, 1)
|
||||
# define ATOMIC_DEC(x) __sync_sub_and_fetch(&x, 1)
|
||||
# else
|
||||
# define ATOMIC_INT int
|
||||
# define ATOMIC_INC(x) (++x)
|
||||
# define ATOMIC_DEC(x) (--x)
|
||||
# endif
|
||||
|
||||
namespace TagLib
|
||||
{
|
||||
#if defined(TAGLIB_USE_STD_SHARED_PTR) \
|
||||
|| defined(TAGLIB_USE_TR1_SHARED_PTR) \
|
||||
|| defined(TAGLIB_USE_BOOST_SHARED_PTR)
|
||||
|
||||
// RefCountPtr<T> is just a thin wrapper of shared_ptr<T>.
|
||||
// It will be optimized out by compilers and performs equivalent to them.
|
||||
|
||||
template <typename T>
|
||||
class RefCountPtr
|
||||
{
|
||||
public:
|
||||
RefCountPtr()
|
||||
: sp()
|
||||
{
|
||||
}
|
||||
|
||||
template <typename U>
|
||||
explicit RefCountPtr(U *p)
|
||||
: sp(p)
|
||||
{
|
||||
}
|
||||
|
||||
RefCountPtr(const RefCountPtr<T> &x)
|
||||
: sp(x.sp)
|
||||
{
|
||||
}
|
||||
|
||||
template <typename U>
|
||||
RefCountPtr(const RefCountPtr<U> &x)
|
||||
: sp(x.sp)
|
||||
{
|
||||
}
|
||||
|
||||
# ifdef TAGLIB_USE_MOVE_SEMANTICS
|
||||
|
||||
RefCountPtr(RefCountPtr<T> &&x)
|
||||
: sp(std::move(x.sp))
|
||||
{
|
||||
}
|
||||
|
||||
template <typename U>
|
||||
RefCountPtr(RefCountPtr<U> &&x)
|
||||
: sp(std::move(x.sp))
|
||||
{
|
||||
}
|
||||
|
||||
# endif
|
||||
|
||||
T *get() const
|
||||
{
|
||||
return sp.get();
|
||||
}
|
||||
|
||||
long use_count() const
|
||||
{
|
||||
return sp.use_count();
|
||||
}
|
||||
|
||||
bool unique() const
|
||||
{
|
||||
return sp.unique();
|
||||
}
|
||||
|
||||
template <typename U>
|
||||
void reset(U *p)
|
||||
{
|
||||
sp.reset(p);
|
||||
}
|
||||
|
||||
void reset()
|
||||
{
|
||||
sp.reset();
|
||||
}
|
||||
|
||||
void swap(RefCountPtr<T> &x)
|
||||
{
|
||||
sp.swap(x.sp);
|
||||
}
|
||||
|
||||
RefCountPtr<T> &operator=(const RefCountPtr<T> &x)
|
||||
{
|
||||
sp = x.sp;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename U>
|
||||
RefCountPtr<T> &operator=(const RefCountPtr<U> &x)
|
||||
{
|
||||
sp = x.sp;
|
||||
return *this;
|
||||
}
|
||||
|
||||
# ifdef TAGLIB_USE_MOVE_SEMANTICS
|
||||
|
||||
RefCountPtr<T> &operator=(RefCountPtr<T> &&x)
|
||||
{
|
||||
sp = std::move(x.sp);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename U>
|
||||
RefCountPtr<T> &operator=(RefCountPtr<U> &&x)
|
||||
{
|
||||
sp = std::move(x.sp);
|
||||
return *this;
|
||||
}
|
||||
|
||||
# endif
|
||||
|
||||
T& operator*() const
|
||||
{
|
||||
return sp.operator*();
|
||||
}
|
||||
|
||||
T* operator->() const
|
||||
{
|
||||
return sp.operator->();
|
||||
}
|
||||
|
||||
operator bool() const
|
||||
{
|
||||
return static_cast<bool>(sp);
|
||||
}
|
||||
|
||||
bool operator!() const
|
||||
{
|
||||
return !static_cast<bool>(sp);
|
||||
}
|
||||
|
||||
private:
|
||||
template <typename U> friend class RefCountPtr;
|
||||
|
||||
# if defined(TAGLIB_USE_STD_SHARED_PTR)
|
||||
|
||||
std::shared_ptr<T> sp;
|
||||
|
||||
# elif defined(TAGLIB_USE_TR1_SHARED_PTR)
|
||||
|
||||
std::tr1::shared_ptr<T> sp;
|
||||
|
||||
# else
|
||||
|
||||
boost::shared_ptr<T> sp;
|
||||
|
||||
# endif
|
||||
};
|
||||
|
||||
#else // TAGLIB_USE_STD_SHARED_PTR etc.
|
||||
|
||||
// Self-implements RefCountPtr<T> if shared_ptr<T> is not available.
|
||||
// I STRONGLY RECOMMEND using standard shared_ptr<T> rather than this class.
|
||||
|
||||
@ -207,18 +92,37 @@ namespace TagLib
|
||||
class CounterBase
|
||||
{
|
||||
public:
|
||||
CounterBase();
|
||||
virtual ~CounterBase();
|
||||
CounterBase()
|
||||
: refCount(1)
|
||||
{
|
||||
}
|
||||
|
||||
void addref();
|
||||
void release();
|
||||
long use_count() const;
|
||||
virtual ~CounterBase()
|
||||
{
|
||||
}
|
||||
|
||||
void addref()
|
||||
{
|
||||
ATOMIC_INC(refCount);
|
||||
}
|
||||
|
||||
void release()
|
||||
{
|
||||
if(ATOMIC_DEC(refCount) == 0) {
|
||||
dispose();
|
||||
delete this;
|
||||
}
|
||||
}
|
||||
|
||||
long use_count() const
|
||||
{
|
||||
return static_cast<long>(refCount);
|
||||
}
|
||||
|
||||
virtual void dispose() = 0;
|
||||
|
||||
private:
|
||||
class CounterBasePrivate;
|
||||
CounterBasePrivate *d;
|
||||
volatile ATOMIC_INT refCount;
|
||||
};
|
||||
|
||||
// Counter impl class. Provides a dynamic deleter.
|
||||
@ -380,83 +284,45 @@ namespace TagLib
|
||||
template <typename U> friend class RefCountPtr;
|
||||
};
|
||||
|
||||
#endif // TAGLIB_USE_STD_SHARED_PTR etc.
|
||||
|
||||
#if defined(TAGLIB_USE_STD_UNIQUE_PTR) || defined(TAGLIB_USE_BOOST_SCOPED_PTR)
|
||||
|
||||
// NonRefCountPtr<T> is just a thin wrapper of unique_ptr<T> or scoped_ptr<T>.
|
||||
// It will be optimized out by compilers and performs equivalent to them.
|
||||
|
||||
template<typename T>
|
||||
class NonRefCountPtr
|
||||
template <typename T, typename U>
|
||||
bool operator==(const RefCountPtr<T> &a, const RefCountPtr<U> &b)
|
||||
{
|
||||
public:
|
||||
explicit NonRefCountPtr(T *p = 0)
|
||||
: up(p)
|
||||
{
|
||||
}
|
||||
return (a.get() == b.get());
|
||||
}
|
||||
|
||||
~NonRefCountPtr()
|
||||
{
|
||||
}
|
||||
template <typename T, typename U>
|
||||
bool operator!=(const RefCountPtr<T> &a, const RefCountPtr<U> &b)
|
||||
{
|
||||
return (a.get() != b.get());
|
||||
}
|
||||
|
||||
void reset(T *p = 0)
|
||||
{
|
||||
NonRefCountPtr<T>(p).swap(*this);
|
||||
}
|
||||
template <typename T>
|
||||
void swap(RefCountPtr<T> &a, RefCountPtr<T> &b)
|
||||
{
|
||||
a.swap(b);
|
||||
}
|
||||
}
|
||||
|
||||
T &operator*() const
|
||||
{
|
||||
return up.operator*();
|
||||
}
|
||||
# define SHARED_PTR TagLib::RefCountPtr
|
||||
|
||||
T *operator->() const
|
||||
{
|
||||
return up.operator->();
|
||||
}
|
||||
#endif // HAVE_STD_SHARED_PTR etc.
|
||||
|
||||
T *get() const
|
||||
{
|
||||
return up.get();
|
||||
}
|
||||
#if defined(HAVE_STD_UNIQUE_PTR)
|
||||
|
||||
operator bool() const
|
||||
{
|
||||
return static_cast<bool>(up);
|
||||
}
|
||||
# include <memory>
|
||||
# define SCOPED_PTR std::unique_ptr
|
||||
|
||||
bool operator!() const
|
||||
{
|
||||
return !static_cast<bool>(up);
|
||||
}
|
||||
#elif defined(HAVE_BOOST_SCOPED_PTR)
|
||||
|
||||
void swap(NonRefCountPtr &x)
|
||||
{
|
||||
up.swap(x.up);
|
||||
}
|
||||
# include <boost/scoped_ptr.hpp>
|
||||
# define SCOPED_PTR boost::scoped_ptr
|
||||
|
||||
private:
|
||||
|
||||
// Noncopyable
|
||||
NonRefCountPtr(const NonRefCountPtr &);
|
||||
NonRefCountPtr &operator=(const NonRefCountPtr &);
|
||||
|
||||
void operator==(const NonRefCountPtr &) const;
|
||||
void operator!=(const NonRefCountPtr &) const;
|
||||
|
||||
# if defined(TAGLIB_USE_STD_UNIQUE_PTR)
|
||||
|
||||
std::unique_ptr<T> up;
|
||||
|
||||
# else
|
||||
|
||||
boost::scoped_ptr<T> up;
|
||||
|
||||
# endif
|
||||
};
|
||||
|
||||
#else // TAGLIB_USE_STD_UNIQUE_PTR
|
||||
#else // HAVE_STD_UNIQUE_PTR
|
||||
|
||||
# include <algorithm>
|
||||
|
||||
namespace TagLib
|
||||
{
|
||||
// Self-implements NonRefCountPtr<T> if unique_ptr<T> is not available.
|
||||
// I STRONGLY RECOMMEND using standard unique_ptr<T> rather than this class.
|
||||
|
||||
@ -522,34 +388,6 @@ namespace TagLib
|
||||
T *px;
|
||||
};
|
||||
|
||||
#endif // TAGLIB_USE_STD_UNIQUE_PTR
|
||||
|
||||
// Comparison operators for smart pointers.
|
||||
|
||||
template <typename T, typename U>
|
||||
bool operator==(const RefCountPtr<T> &a, const RefCountPtr<U> &b)
|
||||
{
|
||||
return (a.get() == b.get());
|
||||
}
|
||||
|
||||
template <typename T, typename U>
|
||||
bool operator!=(const RefCountPtr<T> &a, const RefCountPtr<U> &b)
|
||||
{
|
||||
return (a.get() != b.get());
|
||||
}
|
||||
|
||||
template <typename T, typename U>
|
||||
bool operator==(const RefCountPtr<T> &a, U *b)
|
||||
{
|
||||
return (a.get() == b);
|
||||
}
|
||||
|
||||
template <typename T, typename U>
|
||||
bool operator!=(const RefCountPtr<T> &a, U *b)
|
||||
{
|
||||
return (a.get() != b);
|
||||
}
|
||||
|
||||
template <typename T, typename U>
|
||||
bool operator==(const NonRefCountPtr<T> &a, U *b)
|
||||
{
|
||||
@ -562,42 +400,17 @@ namespace TagLib
|
||||
return (a.get() != b);
|
||||
}
|
||||
|
||||
template <typename T, typename U>
|
||||
bool operator==(T *a, const RefCountPtr<U> &b)
|
||||
{
|
||||
return (a == b.get());
|
||||
}
|
||||
|
||||
template <typename T, typename U>
|
||||
bool operator!=(T *a, const RefCountPtr<U> &b)
|
||||
{
|
||||
return (a != b.get());
|
||||
}
|
||||
|
||||
template <typename T, typename U>
|
||||
bool operator==(T *a, const NonRefCountPtr<U> &b)
|
||||
{
|
||||
return (a == b.get());
|
||||
}
|
||||
|
||||
template <typename T, typename U>
|
||||
bool operator!=(T *a, const NonRefCountPtr<U> &b)
|
||||
{
|
||||
return (a != b.get());
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void swap(RefCountPtr<T> &a, RefCountPtr<T> &b)
|
||||
{
|
||||
a.swap(b);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void swap(NonRefCountPtr<T> &a, NonRefCountPtr<T> &b)
|
||||
void swap(NonRefCountPtr<T> &a, NonRefCountPtr<T> &b)
|
||||
{
|
||||
a.swap(b);
|
||||
}
|
||||
}
|
||||
|
||||
# define SCOPED_PTR TagLib::NonRefCountPtr
|
||||
|
||||
#endif // HAVE_STD_UNIQUE_PTR etc.
|
||||
|
||||
|
||||
#endif // DO_NOT_DOCUMENT
|
||||
#endif
|
||||
|
||||
@ -30,6 +30,7 @@
|
||||
#include "tstring.h"
|
||||
#include "tdebug.h"
|
||||
#include "tstringlist.h"
|
||||
#include "tsmartptr.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <cstdio>
|
||||
@ -185,38 +186,30 @@ namespace TagLib {
|
||||
class String::StringPrivate
|
||||
{
|
||||
public:
|
||||
StringPrivate()
|
||||
StringPrivate()
|
||||
: data(new std::wstring())
|
||||
{
|
||||
}
|
||||
|
||||
StringPrivate(const std::wstring &s)
|
||||
: data(s)
|
||||
: data(new std::wstring(s))
|
||||
{
|
||||
}
|
||||
|
||||
#ifdef TAGLIB_USE_MOVE_SEMANTICS
|
||||
|
||||
StringPrivate(std::wstring &&s)
|
||||
: data(s)
|
||||
{
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
StringPrivate(size_t n, wchar_t c)
|
||||
: data(n, c)
|
||||
: data(new std::wstring(n, c))
|
||||
{
|
||||
}
|
||||
|
||||
/*!
|
||||
* Stores string in UTF-16. The byte order depends on the CPU endian.
|
||||
*/
|
||||
std::wstring data;
|
||||
SHARED_PTR<std::wstring> data;
|
||||
|
||||
/*!
|
||||
* This is only used to hold the the most recent value of toCString().
|
||||
*/
|
||||
std::string cstring;
|
||||
SHARED_PTR<std::string> cstring;
|
||||
};
|
||||
|
||||
const String String::null;
|
||||
@ -232,19 +225,10 @@ String::String()
|
||||
}
|
||||
|
||||
String::String(const String &s)
|
||||
: d(s.d)
|
||||
: d(new StringPrivate(*s.d))
|
||||
{
|
||||
}
|
||||
|
||||
#ifdef TAGLIB_USE_MOVE_SEMANTICS
|
||||
|
||||
String::String(String &&s)
|
||||
: d(std::move(s.d))
|
||||
{
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
String::String(const std::string &s, Type t)
|
||||
: d(new StringPrivate())
|
||||
{
|
||||
@ -325,6 +309,7 @@ String::String(const ByteVector &v, Type t)
|
||||
|
||||
String::~String()
|
||||
{
|
||||
delete d;
|
||||
}
|
||||
|
||||
std::string String::to8Bit(bool unicode) const
|
||||
@ -332,18 +317,18 @@ std::string String::to8Bit(bool unicode) const
|
||||
std::string s;
|
||||
|
||||
if(!unicode) {
|
||||
s.resize(d->data.size());
|
||||
s.resize(d->data->size());
|
||||
|
||||
std::string::iterator targetIt = s.begin();
|
||||
for(std::wstring::const_iterator it = d->data.begin(); it != d->data.end(); it++) {
|
||||
for(std::wstring::const_iterator it = d->data->begin(); it != d->data->end(); it++) {
|
||||
*targetIt = static_cast<char>(*it);
|
||||
++targetIt;
|
||||
}
|
||||
}
|
||||
else {
|
||||
s.resize(d->data.size() * 4 + 1);
|
||||
s.resize(d->data->size() * 4 + 1);
|
||||
|
||||
UTF16toUTF8(&d->data[0], d->data.size(), &s[0], s.size());
|
||||
UTF16toUTF8(&(*d->data)[0], d->data->size(), &s[0], s.size());
|
||||
s.resize(::strlen(s.c_str()));
|
||||
}
|
||||
|
||||
@ -352,43 +337,43 @@ std::string String::to8Bit(bool unicode) const
|
||||
|
||||
const std::wstring &String::toWString() const
|
||||
{
|
||||
return d->data;
|
||||
return *d->data;
|
||||
}
|
||||
|
||||
const char *String::toCString(bool unicode) const
|
||||
{
|
||||
d->cstring = to8Bit(unicode);
|
||||
return d->cstring.c_str();
|
||||
d->cstring.reset(new std::string(to8Bit(unicode)));
|
||||
return d->cstring->c_str();
|
||||
}
|
||||
|
||||
String::Iterator String::begin()
|
||||
{
|
||||
return d->data.begin();
|
||||
return d->data->begin();
|
||||
}
|
||||
|
||||
String::ConstIterator String::begin() const
|
||||
{
|
||||
return d->data.begin();
|
||||
return d->data->begin();
|
||||
}
|
||||
|
||||
String::Iterator String::end()
|
||||
{
|
||||
return d->data.end();
|
||||
return d->data->end();
|
||||
}
|
||||
|
||||
String::ConstIterator String::end() const
|
||||
{
|
||||
return d->data.end();
|
||||
return d->data->end();
|
||||
}
|
||||
|
||||
size_t String::find(const String &s, size_t offset) const
|
||||
{
|
||||
return d->data.find(s.d->data, offset);
|
||||
return d->data->find(*s.d->data, offset);
|
||||
}
|
||||
|
||||
size_t String::rfind(const String &s, size_t offset) const
|
||||
{
|
||||
return d->data.rfind(s.d->data, offset);
|
||||
return d->data->rfind(*s.d->data, offset);
|
||||
}
|
||||
|
||||
StringList String::split(const String &separator) const
|
||||
@ -421,13 +406,13 @@ bool String::startsWith(const String &s) const
|
||||
|
||||
String String::substr(size_t position, size_t length) const
|
||||
{
|
||||
return String(d->data.substr(position, length));
|
||||
return String(d->data->substr(position, length));
|
||||
}
|
||||
|
||||
String &String::append(const String &s)
|
||||
{
|
||||
detach();
|
||||
d->data += s.d->data;
|
||||
*d->data += *s.d->data;
|
||||
return *this;
|
||||
}
|
||||
|
||||
@ -435,15 +420,10 @@ String String::upper() const
|
||||
{
|
||||
static const int shift = 'A' - 'a';
|
||||
|
||||
String s;
|
||||
s.d->data.resize(d->data.size());
|
||||
|
||||
wchar_t *p = &s.d->data[0];
|
||||
for(std::wstring::const_iterator it = d->data.begin(); it != d->data.end(); ++it) {
|
||||
String s(*this);
|
||||
for(Iterator it = s.begin(); it != s.end(); ++it) {
|
||||
if(*it >= 'a' && *it <= 'z')
|
||||
*p++ = *it + shift;
|
||||
else
|
||||
*p++ = *it;
|
||||
*it = *it + shift;
|
||||
}
|
||||
|
||||
return s;
|
||||
@ -451,7 +431,7 @@ String String::upper() const
|
||||
|
||||
size_t String::size() const
|
||||
{
|
||||
return d->data.size();
|
||||
return d->data->size();
|
||||
}
|
||||
|
||||
size_t String::length() const
|
||||
@ -461,7 +441,7 @@ size_t String::length() const
|
||||
|
||||
bool String::isEmpty() const
|
||||
{
|
||||
return d->data.empty();
|
||||
return d->data->empty();
|
||||
}
|
||||
|
||||
bool String::isNull() const
|
||||
@ -478,7 +458,7 @@ ByteVector String::data(Type t) const
|
||||
ByteVector v(size(), 0);
|
||||
char *p = v.data();
|
||||
|
||||
for(std::wstring::const_iterator it = d->data.begin(); it != d->data.end(); it++)
|
||||
for(std::wstring::const_iterator it = d->data->begin(); it != d->data->end(); it++)
|
||||
*p++ = static_cast<char>(*it);
|
||||
|
||||
return v;
|
||||
@ -487,7 +467,7 @@ ByteVector String::data(Type t) const
|
||||
{
|
||||
ByteVector v(size() * 4 + 1, 0);
|
||||
|
||||
UTF16toUTF8(&d->data[0], d->data.size(), v.data(), v.size());
|
||||
UTF16toUTF8(&(*d->data)[0], d->data->size(), v.data(), v.size());
|
||||
v.resize(::strlen(v.data()));
|
||||
|
||||
return v;
|
||||
@ -503,7 +483,7 @@ ByteVector String::data(Type t) const
|
||||
*p++ = '\xff';
|
||||
*p++ = '\xfe';
|
||||
|
||||
for(std::wstring::const_iterator it = d->data.begin(); it != d->data.end(); it++) {
|
||||
for(std::wstring::const_iterator it = d->data->begin(); it != d->data->end(); it++) {
|
||||
*p++ = static_cast<char>(*it & 0xff);
|
||||
*p++ = static_cast<char>(*it >> 8);
|
||||
}
|
||||
@ -515,7 +495,7 @@ ByteVector String::data(Type t) const
|
||||
ByteVector v(size() * 2, 0);
|
||||
char *p = v.data();
|
||||
|
||||
for(std::wstring::const_iterator it = d->data.begin(); it != d->data.end(); it++) {
|
||||
for(std::wstring::const_iterator it = d->data->begin(); it != d->data->end(); it++) {
|
||||
*p++ = static_cast<char>(*it >> 8);
|
||||
*p++ = static_cast<char>(*it & 0xff);
|
||||
}
|
||||
@ -527,7 +507,7 @@ ByteVector String::data(Type t) const
|
||||
ByteVector v(size() * 2, 0);
|
||||
char *p = v.data();
|
||||
|
||||
for(std::wstring::const_iterator it = d->data.begin(); it != d->data.end(); it++) {
|
||||
for(std::wstring::const_iterator it = d->data->begin(); it != d->data->end(); it++) {
|
||||
*p++ = static_cast<char>(*it & 0xff);
|
||||
*p++ = static_cast<char>(*it >> 8);
|
||||
}
|
||||
@ -546,13 +526,13 @@ int String::toInt(bool *ok) const
|
||||
{
|
||||
int value = 0;
|
||||
|
||||
const size_t size = d->data.size();
|
||||
const bool negative = size > 0 && d->data[0] == '-';
|
||||
const size_t size = d->data->size();
|
||||
const bool negative = size > 0 && (*d->data)[0] == '-';
|
||||
const size_t start = negative ? 1 : 0;
|
||||
|
||||
size_t i = start;
|
||||
for(; i < size && d->data[i] >= '0' && d->data[i] <= '9'; i++)
|
||||
value = value * 10 + (d->data[i] - '0');
|
||||
for(; i < size && (*d->data)[i] >= '0' && (*d->data)[i] <= '9'; i++)
|
||||
value = value * 10 + ((*d->data)[i] - '0');
|
||||
|
||||
if(negative)
|
||||
value = value * -1;
|
||||
@ -565,8 +545,8 @@ int String::toInt(bool *ok) const
|
||||
|
||||
String String::stripWhiteSpace() const
|
||||
{
|
||||
std::wstring::const_iterator begin = d->data.begin();
|
||||
std::wstring::const_iterator end = d->data.end();
|
||||
std::wstring::const_iterator begin = d->data->begin();
|
||||
std::wstring::const_iterator end = d->data->end();
|
||||
|
||||
while(begin != end &&
|
||||
(*begin == '\t' || *begin == '\n' || *begin == '\f' ||
|
||||
@ -591,7 +571,7 @@ String String::stripWhiteSpace() const
|
||||
|
||||
bool String::isLatin1() const
|
||||
{
|
||||
for(std::wstring::const_iterator it = d->data.begin(); it != d->data.end(); it++) {
|
||||
for(std::wstring::const_iterator it = d->data->begin(); it != d->data->end(); it++) {
|
||||
if(*it >= 256)
|
||||
return false;
|
||||
}
|
||||
@ -600,7 +580,7 @@ bool String::isLatin1() const
|
||||
|
||||
bool String::isAscii() const
|
||||
{
|
||||
for(std::wstring::const_iterator it = d->data.begin(); it != d->data.end(); it++) {
|
||||
for(std::wstring::const_iterator it = d->data->begin(); it != d->data->end(); it++) {
|
||||
if(*it >= 128)
|
||||
return false;
|
||||
}
|
||||
@ -638,22 +618,22 @@ String String::number(int n) // static
|
||||
TagLib::wchar &String::operator[](size_t i)
|
||||
{
|
||||
detach();
|
||||
return d->data[i];
|
||||
return (*d->data)[i];
|
||||
}
|
||||
|
||||
const TagLib::wchar &String::operator[](size_t i) const
|
||||
{
|
||||
return d->data[i];
|
||||
return (*d->data)[i];
|
||||
}
|
||||
|
||||
bool String::operator==(const String &s) const
|
||||
{
|
||||
return (d == s.d || d->data == s.d->data);
|
||||
return (d->data == s.d->data || *d->data == *s.d->data);
|
||||
}
|
||||
|
||||
bool String::operator==(const char *s) const
|
||||
{
|
||||
for(std::wstring::const_iterator it = d->data.begin(); it != d->data.end(); it++) {
|
||||
for(std::wstring::const_iterator it = d->data->begin(); it != d->data->end(); it++) {
|
||||
if(*it != static_cast<uchar>(*s))
|
||||
return false;
|
||||
|
||||
@ -665,7 +645,7 @@ bool String::operator==(const char *s) const
|
||||
|
||||
bool String::operator==(const wchar_t *s) const
|
||||
{
|
||||
return (d->data == s);
|
||||
return (*d->data == s);
|
||||
}
|
||||
|
||||
bool String::operator!=(const String &s) const
|
||||
@ -677,7 +657,7 @@ String &String::operator+=(const String &s)
|
||||
{
|
||||
detach();
|
||||
|
||||
d->data += s.d->data;
|
||||
*d->data += *s.d->data;
|
||||
return *this;
|
||||
}
|
||||
|
||||
@ -685,7 +665,7 @@ String &String::operator+=(const wchar_t *s)
|
||||
{
|
||||
detach();
|
||||
|
||||
d->data += s;
|
||||
*d->data += *s;
|
||||
return *this;
|
||||
}
|
||||
|
||||
@ -694,7 +674,7 @@ String &String::operator+=(const char *s)
|
||||
detach();
|
||||
|
||||
for(int i = 0; s[i] != 0; i++)
|
||||
d->data += uchar(s[i]);
|
||||
*d->data += uchar(s[i]);
|
||||
return *this;
|
||||
}
|
||||
|
||||
@ -702,7 +682,7 @@ String &String::operator+=(wchar_t c)
|
||||
{
|
||||
detach();
|
||||
|
||||
d->data += c;
|
||||
*d->data += c;
|
||||
return *this;
|
||||
}
|
||||
|
||||
@ -710,29 +690,19 @@ String &String::operator+=(char c)
|
||||
{
|
||||
detach();
|
||||
|
||||
d->data += uchar(c);
|
||||
*d->data += uchar(c);
|
||||
return *this;
|
||||
}
|
||||
|
||||
String &String::operator=(const String &s)
|
||||
{
|
||||
d = s.d;
|
||||
*d = *s.d;
|
||||
return *this;
|
||||
}
|
||||
|
||||
#ifdef TAGLIB_USE_MOVE_SEMANTICS
|
||||
|
||||
String &String::operator=(String &&s)
|
||||
{
|
||||
d = std::move(s.d);
|
||||
return *this;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
String &String::operator=(const std::string &s)
|
||||
{
|
||||
d.reset(new StringPrivate());
|
||||
d->data.reset(new std::wstring());
|
||||
copyFromLatin1(s.c_str(), s.length());
|
||||
|
||||
return *this;
|
||||
@ -740,23 +710,13 @@ String &String::operator=(const std::string &s)
|
||||
|
||||
String &String::operator=(const std::wstring &s)
|
||||
{
|
||||
d.reset(new StringPrivate(s));
|
||||
d->data.reset(new std::wstring(s));
|
||||
return *this;
|
||||
}
|
||||
|
||||
#ifdef TAGLIB_USE_MOVE_SEMANTICS
|
||||
|
||||
String &String::operator=(std::wstring &&s)
|
||||
{
|
||||
d.reset(new StringPrivate(s));
|
||||
return *this;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
String &String::operator=(const wchar_t *s)
|
||||
{
|
||||
d.reset(new StringPrivate());
|
||||
d->data.reset(new std::wstring());
|
||||
copyFromUTF16(s, ::wcslen(s), WCharByteOrder);
|
||||
|
||||
return *this;
|
||||
@ -764,19 +724,19 @@ String &String::operator=(const wchar_t *s)
|
||||
|
||||
String &String::operator=(char c)
|
||||
{
|
||||
d.reset(new StringPrivate(1, static_cast<uchar>(c)));
|
||||
d->data.reset(new std::wstring(1, c));
|
||||
return *this;
|
||||
}
|
||||
|
||||
String &String::operator=(wchar_t c)
|
||||
{
|
||||
d.reset(new StringPrivate(1, c));
|
||||
d->data.reset(new std::wstring(1, c));
|
||||
return *this;
|
||||
}
|
||||
|
||||
String &String::operator=(const char *s)
|
||||
{
|
||||
d.reset(new StringPrivate());
|
||||
d->data.reset(new std::wstring());
|
||||
copyFromLatin1(s, ::strlen(s));
|
||||
|
||||
return *this;
|
||||
@ -784,18 +744,18 @@ String &String::operator=(const char *s)
|
||||
|
||||
String &String::operator=(const ByteVector &v)
|
||||
{
|
||||
d.reset(new StringPrivate());
|
||||
d->data.reset(new std::wstring());
|
||||
copyFromLatin1(v.data(), v.size());
|
||||
|
||||
// If we hit a null in the ByteVector, shrink the string again.
|
||||
d->data.resize(::wcslen(d->data.c_str()));
|
||||
d->data->resize(::wcslen(d->data->c_str()));
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool String::operator<(const String &s) const
|
||||
{
|
||||
return d->data < s.d->data;
|
||||
return *d->data < *s.d->data;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@ -804,8 +764,8 @@ bool String::operator<(const String &s) const
|
||||
|
||||
void String::detach()
|
||||
{
|
||||
if(!d.unique())
|
||||
d.reset(new StringPrivate(d->data));
|
||||
if(!d->data.unique())
|
||||
d->data.reset(new std::wstring(*d->data));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@ -814,18 +774,18 @@ void String::detach()
|
||||
|
||||
void String::copyFromLatin1(const char *s, size_t length)
|
||||
{
|
||||
d->data.resize(length);
|
||||
d->data->resize(length);
|
||||
|
||||
for(size_t i = 0; i < length; ++i)
|
||||
d->data[i] = static_cast<uchar>(s[i]);
|
||||
(*d->data)[i] = static_cast<uchar>(s[i]);
|
||||
}
|
||||
|
||||
void String::copyFromUTF8(const char *s, size_t length)
|
||||
{
|
||||
d->data.resize(length);
|
||||
d->data->resize(length);
|
||||
|
||||
UTF8toUTF16(s, length, &d->data[0], d->data.size());
|
||||
d->data.resize(::wcslen(d->data.c_str()));
|
||||
UTF8toUTF16(s, length, &(*d->data)[0], d->data->size());
|
||||
d->data->resize(::wcslen(d->data->c_str()));
|
||||
}
|
||||
|
||||
void String::copyFromUTF16(const wchar_t *s, size_t length, Type t)
|
||||
@ -847,12 +807,12 @@ void String::copyFromUTF16(const wchar_t *s, size_t length, Type t)
|
||||
else
|
||||
swap = (t != WCharByteOrder);
|
||||
|
||||
d->data.resize(length);
|
||||
memcpy(&d->data[0], s, length * sizeof(wchar_t));
|
||||
d->data->resize(length);
|
||||
memcpy(&(*d->data)[0], s, length * sizeof(wchar_t));
|
||||
|
||||
if(swap) {
|
||||
for(size_t i = 0; i < length; ++i)
|
||||
d->data[i] = byteSwap(static_cast<ushort>(s[i]));
|
||||
(*d->data)[i] = byteSwap(static_cast<ushort>(s[i]));
|
||||
}
|
||||
}
|
||||
|
||||
@ -884,9 +844,9 @@ void String::copyFromUTF16(const char *s, size_t length, Type t)
|
||||
else
|
||||
swap = (t != WCharByteOrder);
|
||||
|
||||
d->data.resize(length / 2);
|
||||
d->data->resize(length / 2);
|
||||
for(size_t i = 0; i < length / 2; ++i) {
|
||||
d->data[i] = swap ? combine(*s, *(s + 1)) : combine(*(s + 1), *s);
|
||||
(*d->data)[i] = swap ? combine(*s, *(s + 1)) : combine(*(s + 1), *s);
|
||||
s += 2;
|
||||
}
|
||||
}
|
||||
|
||||
@ -119,17 +119,6 @@ namespace TagLib {
|
||||
*/
|
||||
String(const String &s);
|
||||
|
||||
#ifdef TAGLIB_USE_MOVE_SEMANTICS
|
||||
|
||||
/*!
|
||||
* Constructs a String equivalent to \a s.
|
||||
*
|
||||
* \note Not available unless TAGLIB_USE_MOVE_SEMANTICS macro is defined.
|
||||
*/
|
||||
String(String &&s);
|
||||
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* Makes a deep copy of the data in \a s.
|
||||
*
|
||||
@ -403,17 +392,6 @@ namespace TagLib {
|
||||
*/
|
||||
String &operator=(const String &s);
|
||||
|
||||
#ifdef TAGLIB_USE_MOVE_SEMANTICS
|
||||
|
||||
/*!
|
||||
* Moves \a s into this String.
|
||||
*
|
||||
* \note Not available unless TAGLIB_USE_MOVE_SEMANTICS macro is defined.
|
||||
*/
|
||||
String &operator=(String &&s);
|
||||
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* Performs a deep copy of the data in \a s.
|
||||
*/
|
||||
@ -424,17 +402,6 @@ namespace TagLib {
|
||||
*/
|
||||
String &operator=(const std::wstring &s);
|
||||
|
||||
#ifdef TAGLIB_USE_MOVE_SEMANTICS
|
||||
|
||||
/*!
|
||||
* Moves \a s into this String.
|
||||
*
|
||||
* \note Not available unless TAGLIB_USE_MOVE_SEMANTICS macro is defined.
|
||||
*/
|
||||
String &operator=(std::wstring &&s);
|
||||
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* Performs a deep copy of the data in \a s.
|
||||
*/
|
||||
@ -520,7 +487,7 @@ namespace TagLib {
|
||||
static const Type WCharByteOrder;
|
||||
|
||||
class StringPrivate;
|
||||
RefCountPtr<StringPrivate> d;
|
||||
StringPrivate *d;
|
||||
};
|
||||
|
||||
/*!
|
||||
|
||||
@ -26,7 +26,7 @@ public:
|
||||
void testSharedptrBasic()
|
||||
{
|
||||
int * ip = new int;
|
||||
RefCountPtr<int> cp ( ip );
|
||||
SHARED_PTR<int> cp ( ip );
|
||||
CPPUNIT_ASSERT( ip == cp.get() );
|
||||
CPPUNIT_ASSERT( cp.use_count() == 1 );
|
||||
|
||||
@ -36,7 +36,7 @@ public:
|
||||
ck( static_cast<int*>(cp.get()), 54321 );
|
||||
ck( static_cast<int*>(ip), *cp );
|
||||
|
||||
RefCountPtr<int> cp2 ( cp );
|
||||
SHARED_PTR<int> cp2 ( cp );
|
||||
CPPUNIT_ASSERT( ip == cp2.get() );
|
||||
CPPUNIT_ASSERT( cp.use_count() == 2 );
|
||||
CPPUNIT_ASSERT( cp2.use_count() == 2 );
|
||||
@ -46,7 +46,7 @@ public:
|
||||
ck( static_cast<int*>(cp2.get()), 54321 );
|
||||
ck( static_cast<int*>(ip), *cp2 );
|
||||
|
||||
RefCountPtr<int> cp3 ( cp );
|
||||
SHARED_PTR<int> cp3 ( cp );
|
||||
CPPUNIT_ASSERT( cp.use_count() == 3 );
|
||||
CPPUNIT_ASSERT( cp2.use_count() == 3 );
|
||||
CPPUNIT_ASSERT( cp3.use_count() == 3 );
|
||||
@ -76,16 +76,16 @@ public:
|
||||
CPPUNIT_ASSERT( cp.use_count() == 3 );
|
||||
CPPUNIT_ASSERT( *cp == 87654 );
|
||||
|
||||
RefCountPtr<int> cp4;
|
||||
SHARED_PTR<int> cp4;
|
||||
swap( cp2, cp4 );
|
||||
CPPUNIT_ASSERT( cp4.use_count() == 3 );
|
||||
CPPUNIT_ASSERT( *cp4 == 87654 );
|
||||
CPPUNIT_ASSERT( cp2.get() == 0 );
|
||||
|
||||
std::set< RefCountPtr<int> > scp;
|
||||
std::set< SHARED_PTR<int> > scp;
|
||||
scp.insert(cp4);
|
||||
CPPUNIT_ASSERT( scp.find(cp4) != scp.end() );
|
||||
CPPUNIT_ASSERT( scp.find(cp4) == scp.find( RefCountPtr<int>(cp4) ) );
|
||||
CPPUNIT_ASSERT( scp.find(cp4) == scp.find( SHARED_PTR<int>(cp4) ) );
|
||||
}
|
||||
|
||||
private:
|
||||
@ -130,7 +130,7 @@ public:
|
||||
derivedDestructorCalled = false;
|
||||
|
||||
{
|
||||
RefCountPtr<DummyBase> p1(new DummyDerived(100));
|
||||
SHARED_PTR<DummyBase> p1(new DummyDerived(100));
|
||||
CPPUNIT_ASSERT(p1->getValue() == 100);
|
||||
}
|
||||
|
||||
@ -141,8 +141,8 @@ public:
|
||||
derivedDestructorCalled = false;
|
||||
|
||||
{
|
||||
RefCountPtr<DummyDerived> p1(new DummyDerived(100));
|
||||
RefCountPtr<DummyBase> p2 = p1;
|
||||
SHARED_PTR<DummyDerived> p1(new DummyDerived(100));
|
||||
SHARED_PTR<DummyBase> p2 = p1;
|
||||
|
||||
CPPUNIT_ASSERT(p1->getValue() == 100);
|
||||
CPPUNIT_ASSERT(p2->getValue() == 100);
|
||||
@ -155,8 +155,8 @@ public:
|
||||
derivedDestructorCalled = false;
|
||||
|
||||
{
|
||||
RefCountPtr<DummyDerived> p1;
|
||||
RefCountPtr<DummyBase> p2;
|
||||
SHARED_PTR<DummyDerived> p1;
|
||||
SHARED_PTR<DummyBase> p2;
|
||||
|
||||
p1.reset(new DummyDerived(100));
|
||||
p2 = p1;
|
||||
@ -171,7 +171,7 @@ public:
|
||||
|
||||
private:
|
||||
class DummyIncomplete;
|
||||
RefCountPtr<DummyIncomplete> pincomplete;
|
||||
SHARED_PTR<DummyIncomplete> pincomplete;
|
||||
|
||||
class DummyIncomplete
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user