Standard stuff -- make it fit with the coding style of the rest of TagLib

and make it build.  There are still some missing API docs and I'm not sure
how I feel about non-opaque types (Item in this case) since they're not used
elsewhere in the API, but this will do for now.


git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@333117 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
This commit is contained in:
Scott Wheeler 2004-07-27 02:35:47 +00:00
parent b7d9398052
commit 06122de67f
3 changed files with 122 additions and 114 deletions

View File

@ -30,6 +30,49 @@
using namespace TagLib;
using namespace APE;
static ByteVector renderAPEItem(const String &key, const Item &item)
{
ByteVector data;
TagLib::uint flags = ((item.readOnly) ? 1 : 0) | ((item.locator) ? 2 : 0);
ByteVector value;
if(item.value.isEmpty())
return data;
StringList::ConstIterator it = item.value.begin();
value.append(it->data(String::UTF8));
it++;
while(it != item.value.end()) {
value.append('\0');
value.append(it->data(String::UTF8));
it++;
}
data.append(ByteVector::fromUInt(value.size(), false));
data.append(ByteVector::fromUInt(flags, false));
data.append(key.data(String::UTF8));
data.append(ByteVector('\0'));
data.append(value);
return data;
}
static StringList parseAPEString(const ByteVector &data)
{
StringList value;
int pOld = 0;
int p = data.find('\0');
while (p != -1) {
value.append(String(data.mid(pOld, p), String::UTF8));
pOld = p + 1;
p = data.find('\0', pOld);
}
value.append(String(data.mid(pOld), String::UTF8));
return value;
}
class APE::Tag::TagPrivate
{
public:
@ -45,11 +88,13 @@ public:
Map<const String, ByteVector> binaries;
};
APE::Item::Item(const String& str) : readOnly(false), locator(false) {
APE::Item::Item(const String& str) : readOnly(false), locator(false)
{
value.append(str);
}
APE::Item::Item(const StringList& values) : readOnly(false), locator(false) {
APE::Item::Item(const StringList& values) : readOnly(false), locator(false)
{
value.append(values);
}
@ -81,54 +126,28 @@ APE::Tag::~Tag()
delete d;
}
using TagLib::uint;
static ByteVector _render_APEItem(String key, Item item)
{
ByteVector data;
uint flags = ((item.readOnly) ? 1 : 0) | ((item.locator) ? 2 : 0);
ByteVector value;
if (item.value.isEmpty()) return data;
StringList::Iterator it = item.value.begin();
value.append(it->data(String::UTF8));
it++;
while (it != item.value.end()) {
value.append('\0');
value.append(it->data(String::UTF8));
it++;
}
data.append(ByteVector::fromUInt(value.size(), false));
data.append(ByteVector::fromUInt(flags, false));
data.append(key.data(String::UTF8));
data.append(ByteVector('\0'));
data.append(value);
return data;
}
ByteVector APE::Tag::render() const
{
ByteVector data;
uint itemCount = 0;
{ Map<const String,Item>::Iterator i = d->itemListMap.begin();
while (i != d->itemListMap.end()) {
if (!i->second.value.isEmpty()) {
data.append(_render_APEItem(i->first, i->second));
{
Map<const String,Item>::Iterator i = d->itemListMap.begin();
while(i != d->itemListMap.end()) {
if(!i->second.value.isEmpty()) {
data.append(renderAPEItem(i->first, i->second));
itemCount++;
}
i++;
}
}
{ Map<String,ByteVector>::Iterator i = d->binaries.begin();
while (i != d->binaries.end()) {
if (!i->second.isEmpty()) {
data.append(i->second);
itemCount++;
{
Map<String,ByteVector>::Iterator i = d->binaries.begin();
while(i != d->binaries.end()) {
if(!i->second.isEmpty()) {
data.append(i->second);
itemCount++;
}
i++;
}
@ -235,7 +254,7 @@ void APE::Tag::setTrack(uint i)
addValue("TRACK", String::number(i), true);
}
APE::Footer* APE::Tag::footer() const
APE::Footer *APE::Tag::footer() const
{
return &d->footer;
}
@ -245,7 +264,8 @@ const APE::ItemListMap& APE::Tag::itemListMap() const
return d->itemListMap;
}
void APE::Tag::removeItem(const String &key) {
void APE::Tag::removeItem(const String &key)
{
Map<const String, Item>::Iterator it = d->itemListMap.find(key.upper());
if(it != d->itemListMap.end())
d->itemListMap.erase(it);
@ -257,7 +277,7 @@ void APE::Tag::addValue(const String &key, const String &value, bool replace)
removeItem(key);
if(!value.isEmpty()) {
Map<const String, Item>::Iterator it = d->itemListMap.find(key.upper());
if (it != d->itemListMap.end())
if(it != d->itemListMap.end())
d->itemListMap[key].value.append(value);
else
setItem(key, Item(value));
@ -280,7 +300,8 @@ void APE::Tag::read()
d->file->seek(d->tagOffset);
d->footer.setData(d->file->readBlock(Footer::size()));
if(d->footer.tagSize() == 0 || d->footer.tagSize() > d->file->length())
if(d->footer.tagSize() == 0 ||
d->footer.tagSize() > uint(d->file->length()))
return;
d->file->seek(d->tagOffset + Footer::size() - d->footer.tagSize());
@ -288,41 +309,25 @@ void APE::Tag::read()
}
}
static StringList _parse_APEString(ByteVector val)
{
StringList value;
int pold = 0;
int p = val.find('\0');
while (p != -1) {
value.append(String(val.mid(pold, p), String::UTF8));
pold = p+1;
p = val.find('\0', pold);
};
value.append(String(val.mid(pold), String::UTF8));
return value;
}
void APE::Tag::parse(const ByteVector &data, uint count)
{
uint pos = 0;
uint vallen, flags;
String key, value;
while(count > 0) {
vallen = data.mid(pos+0,4).toUInt(false);
flags = data.mid(pos+4,4).toUInt(false);
key = String(data.mid(pos+8), String::UTF8);
uint valueLength = data.mid(pos + 0, 4).toUInt(false);
uint flags = data.mid(pos + 4, 4).toUInt(false);
String key = String(data.mid(pos + 8), String::UTF8);
key = key.upper();
APE::Item item;
if (flags < 4 ) {
ByteVector val = data.mid(pos+8+key.size()+1, vallen);
d->itemListMap.insert(key, Item(_parse_APEString(val)));
} else {
d->binaries.insert(key,data.mid(pos, 8+key.size()+1+vallen));
if(flags < 4 ) {
ByteVector val = data.mid(pos + 8 + key.size() + 1, valueLength);
d->itemListMap.insert(key, Item(parseAPEString(val)));
}
else
d->binaries.insert(key, data.mid(pos, 8 + key.size() + 1 + valueLength));
pos += 8 + key.size() + 1 + vallen;
pos += 8 + key.size() + 1 + valueLength;
count--;
}
}

View File

@ -39,14 +39,18 @@ namespace TagLib {
/*!
* A non-binary APE-item.
*/
struct Item {
Item() {};
explicit Item(const String&);
explicit Item(const StringList&);
bool readOnly;
bool locator; // URL to external data
StringList value;
bool isEmpty() const;
struct Item
{
Item() {};
explicit Item(const String &);
explicit Item(const StringList &);
bool readOnly;
/*!
* The value is a URL to external data
*/
bool locator;
StringList value;
bool isEmpty() const;
};
/*!
@ -57,7 +61,7 @@ namespace TagLib {
typedef Map<const String, Item> ItemListMap;
//! An APE tag implementation
//! An APE tag implementation
class Tag : public TagLib::Tag
{

View File

@ -58,7 +58,7 @@ public:
}
APE::Tag *APETag;
long APEFooter;
// long APEFooter;
long APELocation;
uint APESize;
@ -110,39 +110,32 @@ bool MPC::File::save()
// Update ID3v1 tag
if(d->ID3v1Tag)
{
if(d->hasID3v1)
{
seek(-128, End);
writeBlock(d->ID3v1Tag->render());
if(d->ID3v1Tag) {
if(d->hasID3v1) {
seek(-128, End);
writeBlock(d->ID3v1Tag->render());
}
else
{
seek(0, End);
writeBlock(d->ID3v1Tag->render());
else {
seek(0, End);
writeBlock(d->ID3v1Tag->render());
}
}
// Update APE tag
if(d->APETag)
{
if(d->APETag) {
if(d->hasAPE)
{
insert(d->APETag->render(), d->APELocation, d->APESize);
}
else
if (d->hasID3v1)
{
insert(d->APETag->render(), d->APELocation, d->APESize);
else {
if(d->hasID3v1) {
seek(-128, End);
insert(d->APETag->render(), tell(), 0);
}
else
{
else {
seek(0, End);
writeBlock(d->APETag->render());
}
}
}
return true;
@ -156,10 +149,12 @@ ID3v1::Tag *MPC::File::ID3v1Tag(bool create)
// no ID3v1 tag exists and we've been asked to create one
d->ID3v1Tag = new ID3v1::Tag;
if (d->APETag)
if(d->APETag)
d->tag = new CombinedTag(d->APETag, d->ID3v1Tag);
else
d->tag = d->ID3v1Tag;
return d->ID3v1Tag;
}
@ -171,10 +166,12 @@ APE::Tag *MPC::File::APETag(bool create)
// no APE tag exists and we've been asked to create one
d->APETag = new APE::Tag;
if (d->ID3v1Tag)
if(d->ID3v1Tag)
d->tag = new CombinedTag(d->APETag, d->ID3v1Tag);
else
d->tag = d->APETag;
return d->APETag;
}
@ -207,16 +204,18 @@ void MPC::File::read(bool readProperties, Properties::ReadStyle /* propertiesSty
d->hasAPE = true;
}
if (d->hasID3v1 && d->hasAPE)
if(d->hasID3v1 && d->hasAPE)
d->tag = new CombinedTag(d->APETag, d->ID3v1Tag);
else
if (d->hasID3v1)
d->tag = d->ID3v1Tag;
else
if (d->hasAPE)
d->tag = d->APETag;
else
d->tag = d->APETag = new APE::Tag();
else {
if(d->hasID3v1)
d->tag = d->ID3v1Tag;
else {
if(d->hasAPE)
d->tag = d->APETag;
else
d->tag = d->APETag = new APE::Tag();
}
}
// Look for and skip an ID3v2 tag
@ -244,11 +243,11 @@ void MPC::File::read(bool readProperties, Properties::ReadStyle /* propertiesSty
long MPC::File::findAPE()
{
if(isValid()) {
if (d->hasID3v1)
seek(-160, End);
if(isValid()) {
if(d->hasID3v1)
seek(-160, End);
else
seek(-32, End);
seek(-32, End);
long p = tell();