aboutsummaryrefslogtreecommitdiff
path: root/src/tag_impl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/tag_impl.cpp')
-rw-r--r--src/tag_impl.cpp331
1 files changed, 331 insertions, 0 deletions
diff --git a/src/tag_impl.cpp b/src/tag_impl.cpp
new file mode 100644
index 0000000..68fef52
--- /dev/null
+++ b/src/tag_impl.cpp
@@ -0,0 +1,331 @@
+// $Id: tag_impl.cpp,v 1.13 2002/09/21 17:23:32 t1mpy Exp $
+
+// id3lib: a C++ library for creating and manipulating id3v1/v2 tags
+// Copyright 1999, 2000 Scott Thomas Haug
+// Copyright 2002 Thijmen Klok (thijmen@id3lib.org)
+
+// This library is free software; you can redistribute it and/or modify it
+// under the terms of the GNU Library General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or (at your
+// option) any later version.
+//
+// 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 Library General Public
+// License for more details.
+//
+// You should have received a copy of the GNU Library General Public License
+// along with this library; if not, write to the Free Software Foundation,
+// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+// The id3lib authors encourage improvements and optimisations to be sent to
+// the id3lib coordinator. Please see the README file for details on where to
+// send such submissions. See the AUTHORS file for a list of people who have
+// contributed to id3lib. See the ChangeLog file for a list of changes to
+// id3lib. These files are distributed with id3lib at
+// http://download.sourceforge.net/id3lib/
+
+#if defined HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+
+#include "tag_impl.h" //has <stdio.h> "tag.h" "header_tag.h" "frame.h" "field.h" "spec.h" "id3lib_strings.h" "utils.h"
+//#include "io_helpers.h"
+#include "io_strings.h"
+
+using namespace dami;
+
+size_t ID3_TagImpl::IsV2Tag(ID3_Reader& reader)
+{
+ io::ExitTrigger et(reader);
+ size_t tagSize = 0;
+ String id = io::readText(reader, ID3_TagHeader::ID_SIZE);
+ String ver = io::readText(reader, 2);
+ char flags = reader.readChar();
+ String size = io::readText(reader, 4);
+
+ if (id == ID3_TagHeader::ID &&
+ (uchar) ver [0] < 0xFF && (uchar) ver [1] < 0xFF &&
+ (uchar) size[0] < 0x80 && (uchar) size[1] < 0x80 &&
+ (uchar) size[2] < 0x80 && (uchar) size[3] < 0x80)
+ {
+ io::StringReader sr(size);
+ tagSize = io::readUInt28(sr) + ID3_TagHeader::SIZE;
+ }
+ else if (id != ID3_TagHeader::ID)
+ {
+ // clog << "*** IsV2Tag: Not an id3v2 tag header" << endl;
+ }
+ else if ((uchar)ver[0] >= 0xFF)
+ {
+ // clog << "*** IsV2Tag: Major offset" << endl;
+ }
+ else if ((uchar)ver[1] >= 0xFF)
+ {
+ // clog << "*** ISV2Tag: Minor offset" << endl;
+ }
+ else if ((uchar)size[0] >= 0x80)
+ {
+ // clog << "*** ISV2Tag: 1st size offset" << endl;
+ }
+ else if ((uchar)size[1] >= 0x80)
+ {
+ // clog << "*** ISV2Tag: 2nd size offset" << endl;
+ }
+ else if ((uchar)size[2] >= 0x80)
+ {
+ // clog << "*** ISV2Tag: 3rd size offset" << endl;
+ }
+ else if ((uchar)size[3] >= 0x80)
+ {
+ // clog << "*** ISV2Tag: 4th size offset" << endl;
+ }
+ else
+ {
+ // clog << "*** shouldn't get here!" << endl;
+ }
+
+ return tagSize;
+}
+
+#ifdef WIN32
+ID3_TagImpl::ID3_TagImpl(const wchar_t *name)
+#else
+ID3_TagImpl::ID3_TagImpl(const char *name)
+#endif
+ : _frames(),
+ _cursor(_frames.begin()),
+ _file_name(),
+ _file_size(0),
+ _prepended_bytes(0),
+ _appended_bytes(0),
+ _is_file_writable(false),
+ _mp3_info(NULL) // need to do this before this->Clear()
+{
+ this->Clear();
+ if (name)
+ {
+ this->Link(name);
+ }
+}
+
+ID3_TagImpl::ID3_TagImpl(const ID3_Tag &tag)
+ : _frames(),
+ _cursor(_frames.begin()),
+ _file_name(),
+ _file_size(0),
+ _prepended_bytes(0),
+ _appended_bytes(0),
+ _is_file_writable(false),
+ _mp3_info(NULL) // need to do this before this->Clear()
+{
+ *this = tag;
+}
+
+ID3_TagImpl::~ID3_TagImpl()
+{
+ this->Clear();
+}
+
+void ID3_TagImpl::Clear()
+{
+ for (iterator cur = _frames.begin(); cur != _frames.end(); ++cur)
+ {
+ if (*cur)
+ {
+ delete *cur;
+ *cur = NULL;
+ }
+ }
+ _frames.clear();
+ _cursor = _frames.begin();
+ _is_padded = true;
+
+ _hdr.Clear();
+ _hdr.SetSpec(ID3V2_LATEST);
+
+ _tags_to_parse.clear();
+ if (_mp3_info)
+ delete _mp3_info; // Also deletes _mp3_header
+
+ _mp3_info = NULL;
+
+ _changed = true;
+}
+
+
+void ID3_TagImpl::AddFrame(const ID3_Frame& frame)
+{
+ this->AddFrame(&frame);
+}
+
+void ID3_TagImpl::AddFrame(const ID3_Frame* frame)
+{
+ if (frame)
+ {
+ ID3_Frame* frm = new ID3_Frame(*frame);
+ this->AttachFrame(frm);
+ }
+}
+
+bool ID3_TagImpl::AttachFrame(ID3_Frame *frame)
+{
+
+ if (NULL == frame)
+ {
+ // log this
+ return false;
+ //ID3_THROW(ID3E_NoData);
+ }
+
+ _frames.push_back(frame);
+ _cursor = _frames.begin();
+
+ _changed = true;
+ return true;
+}
+
+
+ID3_Frame* ID3_TagImpl::RemoveFrame(const ID3_Frame *frame)
+{
+ ID3_Frame *frm = NULL;
+
+ iterator fi = Find(frame);
+ if (fi != _frames.end())
+ {
+ frm = *fi;
+ _frames.erase(fi);
+ _cursor = _frames.begin();
+ _changed = true;
+ }
+
+ return frm;
+}
+
+
+bool ID3_TagImpl::HasChanged() const
+{
+ bool changed = _changed;
+
+ if (! changed)
+ {
+ for (const_iterator fi = _frames.begin(); fi != _frames.end(); ++fi)
+ {
+ if (*fi)
+ {
+ changed = (*fi)->HasChanged();
+ }
+
+ if (changed)
+ {
+ break;
+ }
+ }
+ }
+
+ return changed;
+}
+
+bool ID3_TagImpl::SetSpec(ID3_V2Spec spec)
+{
+ bool changed = _hdr.SetSpec(spec);
+ _changed = _changed || changed;
+ return changed;
+}
+
+ID3_V2Spec ID3_TagImpl::GetSpec() const
+{
+ return _hdr.GetSpec();
+}
+
+bool ID3_TagImpl::SetUnsync(bool b)
+{
+ bool changed = _hdr.SetUnsync(b);
+ _changed = changed || _changed;
+ return changed;
+}
+
+bool ID3_TagImpl::SetExtended(bool ext)
+{
+ bool changed = _hdr.SetExtended(ext);
+ _changed = changed || _changed;
+ return changed;
+}
+
+bool ID3_TagImpl::SetExperimental(bool exp)
+{
+ bool changed = _hdr.SetExperimental(exp);
+ _changed = changed || _changed;
+ return changed;
+}
+
+bool ID3_TagImpl::GetUnsync() const
+{
+ return _hdr.GetUnsync();
+}
+
+bool ID3_TagImpl::GetExtended() const
+{
+ return _hdr.GetExtended();
+}
+
+bool ID3_TagImpl::GetExperimental() const
+{
+ return _hdr.GetExperimental();
+}
+
+bool ID3_TagImpl::GetFooter() const
+{
+ return _hdr.GetFooter();
+}
+
+size_t ID3_TagImpl::GetExtendedBytes() const
+{
+ if (this->GetExtended())
+ if (this->GetSpec() == ID3V2_4_0)
+ return 6; //minimal ID3v2.4 ext header size
+ else if (this->GetSpec() == ID3V2_3_0)
+ return 10; //minimal ID3v2.3 ext header size
+ else
+ return 0; //not implemented
+ else
+ return 0;;
+}
+
+bool ID3_TagImpl::SetPadding(bool pad)
+{
+ bool changed = (_is_padded != pad);
+ _changed = changed || _changed;
+ if (changed)
+ {
+ _is_padded = pad;
+ }
+
+ return changed;
+}
+
+
+ID3_TagImpl &
+ID3_TagImpl::operator=( const ID3_Tag &rTag )
+{
+ this->Clear();
+
+ this->SetUnsync(rTag.GetUnsync());
+ this->SetExtended(rTag.GetExtendedHeader());
+ this->SetExperimental(rTag.GetExperimental());
+
+ ID3_Tag::ConstIterator* iter = rTag.CreateIterator();
+ const ID3_Frame* frame = NULL;
+ while (NULL != (frame = iter->GetNext()))
+ {
+ this->AttachFrame(new ID3_Frame(*frame));
+ }
+ delete iter;
+ return *this;
+}
+
+size_t ID3_GetDataSize(const ID3_TagImpl& tag)
+{
+ return tag.GetFileSize() - tag.GetPrependedBytes() - tag.GetAppendedBytes();
+}
+