id3lib  3.8.3
tag.cpp
Go to the documentation of this file.
1 // $Id: tag.cpp,v 1.55 2003/03/02 13:35:58 t1mpy Exp $
2 
3 // id3lib: a C++ library for creating and manipulating id3v1/v2 tags
4 // Copyright 1999, 2000 Scott Thomas Haug
5 // Copyright 2002 Thijmen Klok (thijmen@id3lib.org)
6 
7 // This library is free software; you can redistribute it and/or modify it
8 // under the terms of the GNU Library General Public License as published by
9 // the Free Software Foundation; either version 2 of the License, or (at your
10 // option) any later version.
11 //
12 // This library is distributed in the hope that it will be useful, but WITHOUT
13 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
15 // License for more details.
16 //
17 // You should have received a copy of the GNU Library General Public License
18 // along with this library; if not, write to the Free Software Foundation,
19 // Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 
21 // The id3lib authors encourage improvements and optimisations to be sent to
22 // the id3lib coordinator. Please see the README file for details on where to
23 // send such submissions. See the AUTHORS file for a list of people who have
24 // contributed to id3lib. See the ChangeLog file for a list of changes to
25 // id3lib. These files are distributed with id3lib at
26 // http://download.sourceforge.net/id3lib/
27 
28 //#include "readers.h"
29 #include "writers.h"
30 #include "tag_impl.h" //has <stdio.h> "tag.h" "header_tag.h" "frame.h" "field.h" "spec.h" "id3lib_strings.h" "utils.h"
31 
32 using namespace dami;
33 
289 ID3_Tag::ID3_Tag(const char *name)
290  : _impl(new ID3_TagImpl(name))
291 {
292 }
293 
299  : _impl(new ID3_TagImpl(tag))
300 {
301 }
302 
304 {
305  delete _impl;
306 }
307 
315 {
316  _impl->Clear();
317 }
318 
319 
344 {
345  return _impl->HasChanged();
346 }
347 
378 size_t ID3_Tag::Size() const
379 {
380  return _impl->Size();
381 }
382 
400 bool ID3_Tag::SetUnsync(bool b)
401 {
402  return _impl->SetUnsync(b);
403 }
404 
405 
420 {
421  return _impl->SetExtended(ext);
422 }
423 
453 bool ID3_Tag::SetPadding(bool pad)
454 {
455  return _impl->SetPadding(pad);
456 }
457 
459 {
460  return _impl->SetExperimental(exp);
461 }
462 
463 bool ID3_Tag::GetUnsync() const
464 {
465  return _impl->GetUnsync();
466 }
467 
469 {
470  return _impl->GetExtended();
471 }
472 
474 {
475  return _impl->GetExperimental();
476 }
477 
478 void ID3_Tag::AddFrame(const ID3_Frame& frame)
479 {
480  _impl->AddFrame(frame);
481 }
482 
502 void ID3_Tag::AddFrame(const ID3_Frame* frame)
503 {
504  _impl->AddFrame(frame);
505 }
506 
522 {
523  return _impl->AttachFrame(frame);
524 }
525 
526 
548 {
549  return _impl->RemoveFrame(frame);
550 }
551 
553 {
554  return id3::v2::parse(*_impl, reader);
555 }
556 
557 size_t ID3_Tag::Parse(const uchar* buffer, size_t bytes)
558 {
559  ID3_MemoryReader mr(buffer, bytes);
560  ID3_Reader::pos_type beg = mr.getCur();
561  id3::v2::parse(*_impl, mr);
562  return mr.getEnd() - beg;
563 }
564 
604 size_t ID3_Tag::Parse(const uchar header[ID3_TAGHEADERSIZE], const uchar *buffer)
605 {
606  size_t size = ID3_Tag::IsV2Tag(header);
607  if (0 == size)
608  {
609  return 0;
610  }
611  BString buf;
612  buf.reserve(ID3_TagHeader::SIZE + size);
613  buf.append(reinterpret_cast<const BString::value_type *>(header),
615  buf.append(reinterpret_cast<const BString::value_type *>(buffer), size);
616  return this->Parse(buf.data(), buf.size());
617 }
618 
647 size_t ID3_Tag::Render(uchar* buffer, ID3_TagType tt) const
648 {
649  ID3_MemoryWriter mw(buffer, static_cast<unsigned int>(-1));
650  return this->Render(mw, tt);
651 }
652 
653 size_t ID3_Tag::Render(ID3_Writer& writer, ID3_TagType tt) const
654 {
655  ID3_Writer::pos_type beg = writer.getCur();
656  if (ID3TT_ID3V2 & tt)
657  {
658  id3::v2::render(writer, *this);
659  }
660  else if (ID3TT_ID3V1 & tt)
661  {
662  id3::v1::render(writer, *this);
663  }
664  return writer.getCur() - beg;
665 }
666 
667 
704 size_t ID3_Tag::Link(const char *fileInfo, flags_t flags)
705 {
706  return _impl->Link(fileInfo, flags);
707 }
708 
712 size_t ID3_Tag::Link(ID3_Reader &reader, flags_t flags)
713 {
714  return _impl->Link(reader, flags);
715 }
716 
718 {
719  return _impl->Update(flags);
720 }
721 
728 {
729  return _impl->GetMp3HeaderInfo();
730 }
731 
739 {
740  return _impl->Strip(flags);
741 }
742 
744 {
745  return _impl->GetPrependedBytes();
746 }
747 
749 {
750  return _impl->GetAppendedBytes();
751 }
752 
753 size_t ID3_Tag::GetFileSize() const
754 {
755  return _impl->GetFileSize();
756 }
757 
758 const char* ID3_Tag::GetFileName() const
759 {
760  //fix because GetFileName need to return a pointer which keeps to be valid
761  String fn = _impl->GetFileName();
762  if (fn.size())
763  {
764  memset((char *)_tmp_filename, 0, ID3_PATH_LENGTH);
765  memmove((char *)_tmp_filename, fn.c_str(), fn.size());
766  return _tmp_filename; //_impl->GetFileName().c_str();
767  }
768  else
769  return NULL;
770 }
771 
773 
837 {
838  return _impl->Find(id);
839 }
840 
842 ID3_Frame* ID3_Tag::Find(ID3_FrameID id, ID3_FieldID fld, uint32 data) const
843 {
844  return _impl->Find(id, fld, data);
845 }
846 
848 ID3_Frame* ID3_Tag::Find(ID3_FrameID id, ID3_FieldID fld, const char* data) const
849 {
850  String str(data);
851  return _impl->Find(id, fld, str);
852 }
853 
856 {
857  WString str = toWString(data, ucslen(data));
858  return _impl->Find(id, fld, str);
859 }
860 
868 size_t ID3_Tag::NumFrames() const
869 {
870  return _impl->NumFrames();
871 }
872 
887 /*
888 ID3_Frame* ID3_Tag::GetFrameNum(size_t num) const
889 {
890  const size_t numFrames = this->NumFrames();
891  if (num >= numFrames)
892  {
893  return NULL;
894  }
895 
896  ID3_Frame* frame = NULL;
897  size_t curNum = 0;
898  // search from the cursor to the end
899  for (ID3_TagImpl::const_iterator cur = _impl->begin(); cur != _impl->end(); ++cur)
900  {
901  if (curNum++ == num)
902  {
903  frame = *cur;
904  break;
905  }
906  }
907 
908  return frame;
909 }
910 */
911 
920 /*
921 ID3_Frame* ID3_Tag::operator[](size_t index) const
922 {
923  return this->GetFrameNum(index);
924 }
925 */
926 
928 {
929  if (this != &rTag)
930  {
931  *_impl = rTag;
932  }
933  return *this;
934 }
935 
937 {
938  return _impl->HasTagType(tt);
939 }
940 
942 {
943  return _impl->GetSpec();
944 }
945 
947 {
948  return _impl->SetSpec(spec);
949 }
950 
955 size_t ID3_Tag::IsV2Tag(const uchar* const data)
956 {
958  return ID3_TagImpl::IsV2Tag(mr);
959 }
960 
962 {
963  return ID3_TagImpl::IsV2Tag(reader);
964 }
965 
968 {
969  _impl->AttachFrame(f);
970 }
971 
988 void ID3_Tag::AddFrames(const ID3_Frame *frames, size_t numFrames)
989 {
990  for (int i = numFrames - 1; i >= 0; i--)
991  {
992  this->AddFrame(frames[i]);
993  }
994 }
995 
996 size_t ID3_Tag::Link(const char *fileInfo, bool parseID3v1, bool parseLyrics3)
997 {
998  return _impl->Link(fileInfo, parseID3v1, parseLyrics3);
999 }
1000 
1002 {
1003  ;
1004 }
1005 
1007 {
1008  return this->HasTagType(ID3TT_LYRICS);
1009 }
1010 bool ID3_Tag::HasV2Tag() const
1011 {
1012  return this->HasTagType(ID3TT_ID3V2);
1013 }
1014 bool ID3_Tag::HasV1Tag() const
1015 {
1016  return this->HasTagType(ID3TT_ID3V1);
1017 }
1018 
1039 {
1040  this->AddFrame(frame);
1041  return *this;
1042 }
1043 
1044 
1046 {
1047  if (frame)
1048  {
1049  this->AddFrame(frame);
1050  }
1051  return *this;
1052 }
1053 
1055 {
1056  size_t size = ID3_Tag::IsV2Tag(data);
1057 
1058  if (!size)
1059  {
1060  return -1;
1061  }
1062 
1063  return size - ID3_TagHeader::SIZE;
1064 }
1065 
1066 
1067 namespace
1068 {
1069  class IteratorImpl : public ID3_Tag::Iterator
1070  {
1071  ID3_TagImpl::iterator _cur;
1072  ID3_TagImpl::iterator _end;
1073  public:
1074  IteratorImpl(ID3_TagImpl& tag)
1075  : _cur(tag.begin()), _end(tag.end())
1076  {
1077  }
1078 
1079  ID3_Frame* GetNext()
1080  {
1081  ID3_Frame* next = NULL;
1082  while (next == NULL && _cur != _end)
1083  {
1084  next = *_cur;
1085  ++_cur;
1086  }
1087  return next;
1088  }
1089  };
1090 
1091 
1092  class ConstIteratorImpl : public ID3_Tag::ConstIterator
1093  {
1096  public:
1097  ConstIteratorImpl(ID3_TagImpl& tag)
1098  : _cur(tag.begin()), _end(tag.end())
1099  {
1100  }
1101  const ID3_Frame* GetNext()
1102  {
1103  ID3_Frame* next = NULL;
1104  while (next == NULL && _cur != _end)
1105  {
1106  next = *_cur;
1107  ++_cur;
1108  }
1109  return next;
1110  }
1111  };
1112 }
1113 
1116 {
1117  return new IteratorImpl(*_impl);
1118 }
1119 
1122 {
1123  return new ConstIteratorImpl(*_impl);
1124 }
1125 
The representative class of an id3v2 frame.
virtual pos_type getCur()
Return the current position in the reader.
Definition: readers.h:134
virtual pos_type getEnd()
Return the ending position in the reader.
Definition: readers.h:144
uint32 pos_type
Definition: reader.h:38
virtual const ID3_Frame * GetNext()=0
virtual ID3_Frame * GetNext()=0
The representative class of an id3 tag.
Definition: tag.h:42
void AddFrame(const ID3_Frame &)
Definition: tag.cpp:478
bool SetExperimental(bool)
Definition: tag.cpp:458
void SetCompression(bool)
Deprecated.
Definition: tag.cpp:1001
bool SetPadding(bool)
Turns padding on or off, dependant on the value of the boolean parameter.
Definition: tag.cpp:453
flags_t Strip(flags_t=(flags_t) ID3TT_ALL)
Strips the tag(s) from the attached file.
Definition: tag.cpp:738
bool HasLyrics() const
Deprecated.
Definition: tag.cpp:1006
bool GetUnsync() const
Definition: tag.cpp:463
virtual ~ID3_Tag()
Definition: tag.cpp:303
bool HasV1Tag() const
Deprecated.
Definition: tag.cpp:1014
ID3_V2Spec GetSpec() const
Deprecated.
Definition: tag.cpp:941
size_t Size() const
Returns an over estimate of the number of bytes required to store a binary version of a tag.
Definition: tag.cpp:378
void Clear()
Clears the object and disassociates it from any files.
Definition: tag.cpp:314
size_t GetAppendedBytes() const
Definition: tag.cpp:748
flags_t Update(flags_t=(flags_t) ID3TT_ALL)
Definition: tag.cpp:717
bool GetExperimental() const
Definition: tag.cpp:473
void AddNewFrame(ID3_Frame *f)
Deprecated.
Definition: tag.cpp:967
bool HasChanged() const
Indicates whether the tag has been altered since the last parse, render, or update.
Definition: tag.cpp:343
ID3_Tag & operator=(const ID3_Tag &)
Deprecated.
Definition: tag.cpp:927
const Mp3_Headerinfo * GetMp3HeaderInfo() const
Get's the mp3 Info like bitrate, mpeg version, etc.
Definition: tag.cpp:727
size_t NumFrames() const
Returns the number of frames present in the tag object.
Definition: tag.cpp:868
bool AttachFrame(ID3_Frame *)
Attaches a frame to the tag; the tag takes responsibility for releasing the frame's memory when tag g...
Definition: tag.cpp:521
bool SetUnsync(bool)
Turns unsynchronization on or off, dependant on the value of the boolean parameter.
Definition: tag.cpp:400
bool HasV2Tag() const
Deprecated.
Definition: tag.cpp:1010
size_t GetFileSize() const
Definition: tag.cpp:753
size_t Render(uchar *, ID3_TagType=ID3TT_ID3V2) const
Renders the tag and writes it to the attached file; the type of tag rendered can be specified as a pa...
Definition: tag.cpp:647
bool GetExtendedHeader() const
Definition: tag.cpp:468
size_t Parse(const uchar *, size_t)
Definition: tag.cpp:557
size_t GetPrependedBytes() const
Definition: tag.cpp:743
bool SetExtendedHeader(bool)
Turns extended header rendering on or off, dependant on the value of the boolean parameter.
Definition: tag.cpp:419
ID3_Frame * Find(ID3_FrameID) const
Finds frame with given frame id, fld id, and integer data.
Definition: tag.cpp:836
size_t Link(const char *fileInfo, flags_t=(flags_t) ID3TT_ALL)
Attaches a file to the tag, parses the file, and adds any tag information found in the file to the ta...
Definition: tag.cpp:704
static size_t IsV2Tag(const uchar *)
Analyses a buffer to determine if we have a valid ID3v2 tag header.
Definition: tag.cpp:955
void AddFrames(const ID3_Frame *, size_t)
Copies an array of frames to the tag.
Definition: tag.cpp:988
ID3_Tag & operator<<(const ID3_Frame &)
Definition: tag.cpp:1038
Iterator * CreateIterator()
Definition: tag.cpp:1115
bool SetSpec(ID3_V2Spec)
Deprecated.
Definition: tag.cpp:946
ID3_Frame * RemoveFrame(const ID3_Frame *)
Removes a frame from the tag.
Definition: tag.cpp:547
const char * GetFileName() const
Definition: tag.cpp:758
bool HasTagType(ID3_TagType tt) const
Deprecated.
Definition: tag.cpp:936
ID3_Tag(const char *name=NULL)
Default constructor; it can accept an optional filename as a parameter.
Definition: tag.cpp:289
flags_t Strip(flags_t=(flags_t) ID3TT_ALL)
Definition: tag_file.cpp:371
size_t GetFileSize() const
Definition: tag_impl.h:113
size_t GetAppendedBytes() const
Definition: tag_impl.h:112
bool HasTagType(ID3_TagType tt) const
Definition: tag_impl.h:124
dami::String GetFileName() const
Definition: tag_impl.h:114
bool SetSpec(ID3_V2Spec)
Definition: tag_impl.cpp:225
bool SetExperimental(bool)
Definition: tag_impl.cpp:251
ID3_Frame * Find(ID3_FrameID id) const
Definition: tag_find.cpp:61
void AddFrame(const ID3_Frame &)
Definition: tag_impl.cpp:153
bool GetExperimental() const
Definition: tag_impl.cpp:268
size_t NumFrames() const
Definition: tag_impl.h:121
const Mp3_Headerinfo * GetMp3HeaderInfo() const
Definition: tag_impl.h:130
bool GetUnsync() const
Definition: tag_impl.cpp:258
Frames::iterator iterator
Definition: tag_impl.h:77
size_t GetPrependedBytes() const
Definition: tag_impl.h:111
bool SetExtended(bool)
Definition: tag_impl.cpp:244
bool SetPadding(bool)
Definition: tag_impl.cpp:291
flags_t Update(flags_t=(flags_t) ID3TT_ALL)
Definition: tag_file.cpp:323
size_t Link(const char *fileInfo, flags_t=(flags_t) ID3TT_ALL)
Definition: tag_file.cpp:131
bool GetExtended() const
Definition: tag_impl.cpp:263
Frames::const_iterator const_iterator
Definition: tag_impl.h:78
ID3_Frame * RemoveFrame(const ID3_Frame *)
Definition: tag_impl.cpp:185
bool SetUnsync(bool)
Definition: tag_impl.cpp:237
ID3_V2Spec GetSpec() const
Definition: tag_impl.cpp:232
static size_t IsV2Tag(ID3_Reader &)
Definition: tag_impl.cpp:38
size_t Size() const
Definition: tag_render.cpp:140
bool AttachFrame(ID3_Frame *)
Definition: tag_impl.cpp:167
bool HasChanged() const
Definition: tag_impl.cpp:202
void Clear()
Definition: tag_impl.cpp:126
virtual pos_type getCur()=0
Return the next position that will be written to.
uint32 pos_type
Definition: writer.h:38
#define NULL
Definition: globals.h:743
ID3_FieldID
Enumeration of the different types of fields in a frame.
Definition: globals.h:198
ID3_TagType
The various types of tags that id3lib can handle.
Definition: globals.h:175
@ ID3TT_ID3V2
Represents an id3v2 tag.
Definition: globals.h:178
@ ID3TT_LYRICS
Definition: globals.h:183
@ ID3TT_ID3V1
Represents an id3v1 or id3v1.1 tag.
Definition: globals.h:177
ID3_V2Spec
Definition: globals.h:162
unsigned char uchar
Definition: globals.h:114
uint16 unicode_t
Definition: globals.h:117
ID3_FrameID
Enumeration of the different types of frames recognized by id3lib.
Definition: globals.h:230
uint16 flags_t
Definition: globals.h:118
#define ID3_TAGHEADERSIZE
Definition: globals.h:104
bool parse(ID3_TagImpl &, ID3_Reader &)
void render(ID3_Writer &, const ID3_TagImpl &)
Definition: tag_render.cpp:42
Definition: tag_impl.h:42
WString ID3_C_EXPORT toWString(const unicode_t[], size_t)
Definition: utils.cpp:383
size_t ID3_C_EXPORT ucslen(const unicode_t *unicode)
Definition: utils.cpp:216
int32 ID3_IsTagHeader(const uchar data[ID3_TAGHEADERSIZE])
Definition: tag.cpp:1054
#define ID3_PATH_LENGTH
Definition: utils.h:46