00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #include "writers.h"
00030 #include "tag_impl.h"
00031
00032 using namespace dami;
00033
00289 ID3_Tag::ID3_Tag(const char *name)
00290 : _impl(new ID3_TagImpl(name))
00291 {
00292 }
00293
00298 ID3_Tag::ID3_Tag(const ID3_Tag &tag)
00299 : _impl(new ID3_TagImpl(tag))
00300 {
00301 }
00302
00303 ID3_Tag::~ID3_Tag()
00304 {
00305 delete _impl;
00306 }
00307
00314 void ID3_Tag::Clear()
00315 {
00316 _impl->Clear();
00317 }
00318
00319
00343 bool ID3_Tag::HasChanged() const
00344 {
00345 return _impl->HasChanged();
00346 }
00347
00378 size_t ID3_Tag::Size() const
00379 {
00380 return _impl->Size();
00381 }
00382
00400 bool ID3_Tag::SetUnsync(bool b)
00401 {
00402 return _impl->SetUnsync(b);
00403 }
00404
00405
00419 bool ID3_Tag::SetExtendedHeader(bool ext)
00420 {
00421 return _impl->SetExtended(ext);
00422 }
00423
00453 bool ID3_Tag::SetPadding(bool pad)
00454 {
00455 return _impl->SetPadding(pad);
00456 }
00457
00458 bool ID3_Tag::SetExperimental(bool exp)
00459 {
00460 return _impl->SetExperimental(exp);
00461 }
00462
00463 bool ID3_Tag::GetUnsync() const
00464 {
00465 return _impl->GetUnsync();
00466 }
00467
00468 bool ID3_Tag::GetExtendedHeader() const
00469 {
00470 return _impl->GetExtended();
00471 }
00472
00473 bool ID3_Tag::GetExperimental() const
00474 {
00475 return _impl->GetExperimental();
00476 }
00477
00478 void ID3_Tag::AddFrame(const ID3_Frame& frame)
00479 {
00480 _impl->AddFrame(frame);
00481 }
00482
00502 void ID3_Tag::AddFrame(const ID3_Frame* frame)
00503 {
00504 _impl->AddFrame(frame);
00505 }
00506
00521 bool ID3_Tag::AttachFrame(ID3_Frame *frame)
00522 {
00523 return _impl->AttachFrame(frame);
00524 }
00525
00526
00547 ID3_Frame* ID3_Tag::RemoveFrame(const ID3_Frame *frame)
00548 {
00549 return _impl->RemoveFrame(frame);
00550 }
00551
00552 bool ID3_Tag::Parse(ID3_Reader& reader)
00553 {
00554 return id3::v2::parse(*_impl, reader);
00555 }
00556
00557 size_t ID3_Tag::Parse(const uchar* buffer, size_t bytes)
00558 {
00559 ID3_MemoryReader mr(buffer, bytes);
00560 ID3_Reader::pos_type beg = mr.getCur();
00561 id3::v2::parse(*_impl, mr);
00562 return mr.getEnd() - beg;
00563 }
00564
00604 size_t ID3_Tag::Parse(const uchar header[ID3_TAGHEADERSIZE], const uchar *buffer)
00605 {
00606 size_t size = ID3_Tag::IsV2Tag(header);
00607 if (0 == size)
00608 {
00609 return 0;
00610 }
00611 BString buf;
00612 buf.reserve(ID3_TagHeader::SIZE + size);
00613 buf.append(reinterpret_cast<const BString::value_type *>(header),
00614 ID3_TagHeader::SIZE);
00615 buf.append(reinterpret_cast<const BString::value_type *>(buffer), size);
00616 return this->Parse(buf.data(), buf.size());
00617 }
00618
00647 size_t ID3_Tag::Render(uchar* buffer, ID3_TagType tt) const
00648 {
00649 ID3_MemoryWriter mw(buffer, -1);
00650 return this->Render(mw, tt);
00651 }
00652
00653 size_t ID3_Tag::Render(ID3_Writer& writer, ID3_TagType tt) const
00654 {
00655 ID3_Writer::pos_type beg = writer.getCur();
00656 if (ID3TT_ID3V2 & tt)
00657 {
00658 id3::v2::render(writer, *this);
00659 }
00660 else if (ID3TT_ID3V1 & tt)
00661 {
00662 id3::v1::render(writer, *this);
00663 }
00664 return writer.getCur() - beg;
00665 }
00666
00667
00704 size_t ID3_Tag::Link(const char *fileInfo, flags_t flags)
00705 {
00706 return _impl->Link(fileInfo, flags);
00707 }
00708
00712 size_t ID3_Tag::Link(ID3_Reader &reader, flags_t flags)
00713 {
00714 return _impl->Link(reader, flags);
00715 }
00716
00717 flags_t ID3_Tag::Update(flags_t flags)
00718 {
00719 return _impl->Update(flags);
00720 }
00721
00727 const Mp3_Headerinfo* ID3_Tag::GetMp3HeaderInfo() const
00728 {
00729 return _impl->GetMp3HeaderInfo();
00730 }
00731
00738 flags_t ID3_Tag::Strip(flags_t flags)
00739 {
00740 return _impl->Strip(flags);
00741 }
00742
00743 size_t ID3_Tag::GetPrependedBytes() const
00744 {
00745 return _impl->GetPrependedBytes();
00746 }
00747
00748 size_t ID3_Tag::GetAppendedBytes() const
00749 {
00750 return _impl->GetAppendedBytes();
00751 }
00752
00753 size_t ID3_Tag::GetFileSize() const
00754 {
00755 return _impl->GetFileSize();
00756 }
00757
00758 const char* ID3_Tag::GetFileName() const
00759 {
00760
00761 String fn = _impl->GetFileName();
00762 if (fn.size())
00763 {
00764 memset((char *)_tmp_filename, 0, ID3_PATH_LENGTH);
00765 memmove((char *)_tmp_filename, fn.c_str(), fn.size());
00766 return _tmp_filename;
00767 }
00768 else
00769 return NULL;
00770 }
00771
00773
00836 ID3_Frame* ID3_Tag::Find(ID3_FrameID id) const
00837 {
00838 return _impl->Find(id);
00839 }
00840
00842 ID3_Frame* ID3_Tag::Find(ID3_FrameID id, ID3_FieldID fld, uint32 data) const
00843 {
00844 return _impl->Find(id, fld, data);
00845 }
00846
00848 ID3_Frame* ID3_Tag::Find(ID3_FrameID id, ID3_FieldID fld, const char* data) const
00849 {
00850 String str(data);
00851 return _impl->Find(id, fld, str);
00852 }
00853
00855 ID3_Frame* ID3_Tag::Find(ID3_FrameID id, ID3_FieldID fld, const unicode_t* data) const
00856 {
00857 WString str = toWString(data, ucslen(data));
00858 return _impl->Find(id, fld, str);
00859 }
00860
00868 size_t ID3_Tag::NumFrames() const
00869 {
00870 return _impl->NumFrames();
00871 }
00872
00887
00888
00889
00890
00891
00892
00893
00894
00895
00896
00897
00898
00899
00900
00901
00902
00903
00904
00905
00906
00907
00908
00909
00910
00911
00920
00921
00922
00923
00924
00925
00926
00927 ID3_Tag& ID3_Tag::operator=( const ID3_Tag &rTag )
00928 {
00929 if (this != &rTag)
00930 {
00931 *_impl = rTag;
00932 }
00933 return *this;
00934 }
00935
00936 bool ID3_Tag::HasTagType(ID3_TagType tt) const
00937 {
00938 return _impl->HasTagType(tt);
00939 }
00940
00941 ID3_V2Spec ID3_Tag::GetSpec() const
00942 {
00943 return _impl->GetSpec();
00944 }
00945
00946 bool ID3_Tag::SetSpec(ID3_V2Spec spec)
00947 {
00948 return _impl->SetSpec(spec);
00949 }
00950
00955 size_t ID3_Tag::IsV2Tag(const uchar* const data)
00956 {
00957 ID3_MemoryReader mr(data, ID3_TagHeader::SIZE);
00958 return ID3_TagImpl::IsV2Tag(mr);
00959 }
00960
00961 size_t ID3_Tag::IsV2Tag(ID3_Reader& reader)
00962 {
00963 return ID3_TagImpl::IsV2Tag(reader);
00964 }
00965
00967 void ID3_Tag::AddNewFrame(ID3_Frame* f)
00968 {
00969 _impl->AttachFrame(f);
00970 }
00971
00988 void ID3_Tag::AddFrames(const ID3_Frame *frames, size_t numFrames)
00989 {
00990 for (int i = numFrames - 1; i >= 0; i--)
00991 {
00992 this->AddFrame(frames[i]);
00993 }
00994 }
00995
00996 size_t ID3_Tag::Link(const char *fileInfo, bool parseID3v1, bool parseLyrics3)
00997 {
00998 return _impl->Link(fileInfo, parseID3v1, parseLyrics3);
00999 }
01000
01001 void ID3_Tag::SetCompression(bool b)
01002 {
01003 ;
01004 }
01005
01006 bool ID3_Tag::HasLyrics() const
01007 {
01008 return this->HasTagType(ID3TT_LYRICS);
01009 }
01010 bool ID3_Tag::HasV2Tag() const
01011 {
01012 return this->HasTagType(ID3TT_ID3V2);
01013 }
01014 bool ID3_Tag::HasV1Tag() const
01015 {
01016 return this->HasTagType(ID3TT_ID3V1);
01017 }
01018
01038 ID3_Tag& ID3_Tag::operator<<(const ID3_Frame& frame)
01039 {
01040 this->AddFrame(frame);
01041 return *this;
01042 }
01043
01044
01045 ID3_Tag& ID3_Tag::operator<<(const ID3_Frame* frame)
01046 {
01047 if (frame)
01048 {
01049 this->AddFrame(frame);
01050 }
01051 return *this;
01052 }
01053
01054 int32 ID3_IsTagHeader(const uchar data[ID3_TAGHEADERSIZE])
01055 {
01056 size_t size = ID3_Tag::IsV2Tag(data);
01057
01058 if (!size)
01059 {
01060 return -1;
01061 }
01062
01063 return size - ID3_TagHeader::SIZE;
01064 }
01065
01066
01067 namespace
01068 {
01069 class IteratorImpl : public ID3_Tag::Iterator
01070 {
01071 ID3_TagImpl::iterator _cur;
01072 ID3_TagImpl::iterator _end;
01073 public:
01074 IteratorImpl(ID3_TagImpl& tag)
01075 : _cur(tag.begin()), _end(tag.end())
01076 {
01077 }
01078
01079 ID3_Frame* GetNext()
01080 {
01081 ID3_Frame* next = NULL;
01082 while (next == NULL && _cur != _end)
01083 {
01084 next = *_cur;
01085 ++_cur;
01086 }
01087 return next;
01088 }
01089 };
01090
01091
01092 class ConstIteratorImpl : public ID3_Tag::ConstIterator
01093 {
01094 ID3_TagImpl::const_iterator _cur;
01095 ID3_TagImpl::const_iterator _end;
01096 public:
01097 ConstIteratorImpl(ID3_TagImpl& tag)
01098 : _cur(tag.begin()), _end(tag.end())
01099 {
01100 }
01101 const ID3_Frame* GetNext()
01102 {
01103 ID3_Frame* next = NULL;
01104 while (next == NULL && _cur != _end)
01105 {
01106 next = *_cur;
01107 ++_cur;
01108 }
01109 return next;
01110 }
01111 };
01112 }
01113
01114 ID3_Tag::Iterator*
01115 ID3_Tag::CreateIterator()
01116 {
01117 return new IteratorImpl(*_impl);
01118 }
01119
01120 ID3_Tag::ConstIterator*
01121 ID3_Tag::CreateIterator() const
01122 {
01123 return new ConstIteratorImpl(*_impl);
01124 }
01125