diff --git a/taglib/ape/apefile.cpp b/taglib/ape/apefile.cpp index 8fd8a50a..e0819715 100644 --- a/taglib/ape/apefile.cpp +++ b/taglib/ape/apefile.cpp @@ -39,6 +39,7 @@ #include #include #include +#include #include "apefile.h" #include "apetag.h" @@ -58,29 +59,21 @@ public: APELocation(-1), APESize(0), ID3v1Location(-1), - ID3v2Header(0), ID3v2Location(-1), - ID3v2Size(0), - properties(0) {} - - ~FilePrivate() - { - delete ID3v2Header; - delete properties; - } + ID3v2Size(0) {} long long APELocation; long long APESize; long long ID3v1Location; - ID3v2::Header *ID3v2Header; + SCOPED_PTR ID3v2Header; long long ID3v2Location; long long ID3v2Size; DoubleTagUnion tag; - AudioProperties *properties; + SCOPED_PTR properties; }; //////////////////////////////////////////////////////////////////////////////// @@ -123,7 +116,7 @@ PropertyMap APE::File::setProperties(const PropertyMap &properties) APE::AudioProperties *APE::File::audioProperties() const { - return d->properties; + return d->properties.get(); } bool APE::File::save() @@ -242,7 +235,7 @@ void APE::File::read(bool readProperties) if(d->ID3v2Location >= 0) { seek(d->ID3v2Location); - d->ID3v2Header = new ID3v2::Header(readBlock(ID3v2::Header::size())); + d->ID3v2Header.reset(new ID3v2::Header(readBlock(ID3v2::Header::size()))); d->ID3v2Size = d->ID3v2Header->completeTagSize(); } @@ -287,6 +280,6 @@ void APE::File::read(bool readProperties) seek(0); } - d->properties = new AudioProperties(this, streamLength); + d->properties.reset(new AudioProperties(this, streamLength)); } } diff --git a/taglib/ape/apeitem.cpp b/taglib/ape/apeitem.cpp index 661d2412..b0d46688 100644 --- a/taglib/ape/apeitem.cpp +++ b/taglib/ape/apeitem.cpp @@ -25,17 +25,17 @@ #include #include +#include #include "apeitem.h" using namespace TagLib; using namespace APE; -class APE::Item::ItemPrivate +struct ItemData { -public: - ItemPrivate() : - type(Text), + ItemData() : + type(Item::Text), readOnly(false) {} Item::ItemTypes type; @@ -45,6 +45,15 @@ public: bool readOnly; }; +class APE::Item::ItemPrivate +{ +public: + ItemPrivate() : + data(new ItemData()) {} + + SHARED_PTR data; +}; + //////////////////////////////////////////////////////////////////////////////// // public members //////////////////////////////////////////////////////////////////////////////// @@ -57,27 +66,27 @@ APE::Item::Item() : APE::Item::Item(const String &key, const String &value) : d(new ItemPrivate()) { - d->key = key; - d->text.append(value); + d->data->key = key; + d->data->text.append(value); } APE::Item::Item(const String &key, const StringList &values) : d(new ItemPrivate()) { - d->key = key; - d->text = values; + d->data->key = key; + d->data->text = values; } APE::Item::Item(const String &key, const ByteVector &value, bool binary) : d(new ItemPrivate()) { - d->key = key; + d->data->key = key; if(binary) { - d->type = Binary; - d->value = value; + d->data->type = Binary; + d->data->value = value; } else { - d->text.append(value); + d->data->text.append(value); } } @@ -106,92 +115,92 @@ void APE::Item::swap(Item &item) void APE::Item::setReadOnly(bool readOnly) { - d->readOnly = readOnly; + d->data->readOnly = readOnly; } bool APE::Item::isReadOnly() const { - return d->readOnly; + return d->data->readOnly; } void APE::Item::setType(APE::Item::ItemTypes val) { - d->type = val; + d->data->type = val; } APE::Item::ItemTypes APE::Item::type() const { - return d->type; + return d->data->type; } String APE::Item::key() const { - return d->key; + return d->data->key; } ByteVector APE::Item::binaryData() const { - return d->value; + return d->data->value; } void APE::Item::setBinaryData(const ByteVector &value) { - d->type = Binary; - d->value = value; - d->text.clear(); + d->data->type = Binary; + d->data->value = value; + d->data->text.clear(); } void APE::Item::setKey(const String &key) { - d->key = key; + d->data->key = key; } void APE::Item::setValue(const String &value) { - d->type = Text; - d->text = value; - d->value.clear(); + d->data->type = Text; + d->data->text = value; + d->data->value.clear(); } void APE::Item::setValues(const StringList &value) { - d->type = Text; - d->text = value; - d->value.clear(); + d->data->type = Text; + d->data->text = value; + d->data->value.clear(); } void APE::Item::appendValue(const String &value) { - d->type = Text; - d->text.append(value); - d->value.clear(); + d->data->type = Text; + d->data->text.append(value); + d->data->value.clear(); } void APE::Item::appendValues(const StringList &values) { - d->type = Text; - d->text.append(values); - d->value.clear(); + d->data->type = Text; + d->data->text.append(values); + d->data->value.clear(); } int APE::Item::size() const { - size_t result = 8 + d->key.size() + 1; - switch(d->type) { + size_t result = 8 + d->data->key.size() + 1; + switch(d->data->type) { case Text: - if(!d->text.isEmpty()) { - StringList::ConstIterator it = d->text.begin(); + if(!d->data->text.isEmpty()) { + StringList::ConstIterator it = d->data->text.begin(); result += it->data(String::UTF8).size(); it++; - for(; it != d->text.end(); ++it) + for(; it != d->data->text.end(); ++it) result += 1 + it->data(String::UTF8).size(); } break; case Binary: case Locator: - result += d->value.size(); + result += d->data->value.size(); break; } return static_cast(result); @@ -199,29 +208,29 @@ int APE::Item::size() const StringList APE::Item::values() const { - return d->text; + return d->data->text; } String APE::Item::toString() const { - if(d->type == Text && !isEmpty()) - return d->text.front(); + if(d->data->type == Text && !isEmpty()) + return d->data->text.front(); else return String(); } bool APE::Item::isEmpty() const { - switch(d->type) { + switch(d->data->type) { case Text: - if(d->text.isEmpty()) + if(d->data->text.isEmpty()) return true; - if(d->text.size() == 1 && d->text.front().isEmpty()) + if(d->data->text.size() == 1 && d->data->text.front().isEmpty()) return true; return false; case Binary: case Locator: - return d->value.isEmpty(); + return d->data->value.isEmpty(); default: return false; } @@ -242,45 +251,45 @@ void APE::Item::parse(const ByteVector &data) // An item key can contain ASCII characters from 0x20 up to 0x7E, not UTF-8. // We assume that the validity of the given key has been checked. - d->key = String(&data[8], String::Latin1); + d->data->key = String(&data[8], String::Latin1); - const ByteVector value = data.mid(8 + d->key.size() + 1, valueLength); + const ByteVector value = data.mid(8 + d->data->key.size() + 1, valueLength); setReadOnly(flags & 1); setType(ItemTypes((flags >> 1) & 3)); - if(Text == d->type) - d->text = StringList(ByteVectorList::split(value, '\0'), String::UTF8); + if(Text == d->data->type) + d->data->text = StringList(ByteVectorList::split(value, '\0'), String::UTF8); else - d->value = value; + d->data->value = value; } ByteVector APE::Item::render() const { ByteVector data; - unsigned int flags = ((d->readOnly) ? 1 : 0) | (d->type << 1); + unsigned int flags = ((d->data->readOnly) ? 1 : 0) | (d->data->type << 1); ByteVector value; if(isEmpty()) return data; - if(d->type == Text) { - StringList::ConstIterator it = d->text.begin(); + if(d->data->type == Text) { + StringList::ConstIterator it = d->data->text.begin(); value.append(it->data(String::UTF8)); it++; - for(; it != d->text.end(); ++it) { + for(; it != d->data->text.end(); ++it) { value.append('\0'); value.append(it->data(String::UTF8)); } - d->value = value; + d->data->value = value; } else - value.append(d->value); + value.append(d->data->value); data.append(ByteVector::fromUInt32LE(value.size())); data.append(ByteVector::fromUInt32LE(flags)); - data.append(d->key.data(String::Latin1)); + data.append(d->data->key.data(String::Latin1)); data.append(ByteVector('\0')); data.append(value);