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 String fn = _impl->GetFileName();
00761 if (fn.size())
00762 {
00763 memset((char *)_tmp_filename, 0, 260);
00764 memmove((char *)_tmp_filename, fn.c_str(), fn.size());
00765 return _tmp_filename;
00766 }
00767 else
00768 return NULL;
00769 }
00770
00772
00835 ID3_Frame* ID3_Tag::Find(ID3_FrameID id) const
00836 {
00837 return _impl->Find(id);
00838 }
00839
00841 ID3_Frame* ID3_Tag::Find(ID3_FrameID id, ID3_FieldID fld, uint32 data) const
00842 {
00843 return _impl->Find(id, fld, data);
00844 }
00845
00847 ID3_Frame* ID3_Tag::Find(ID3_FrameID id, ID3_FieldID fld, const char* data) const
00848 {
00849 String str(data);
00850 return _impl->Find(id, fld, str);
00851 }
00852
00854 ID3_Frame* ID3_Tag::Find(ID3_FrameID id, ID3_FieldID fld, const unicode_t* data) const
00855 {
00856 WString str = toWString(data, ucslen(data));
00857 return _impl->Find(id, fld, str);
00858 }
00859
00867 size_t ID3_Tag::NumFrames() const
00868 {
00869 return _impl->NumFrames();
00870 }
00871
00886
00887
00888
00889
00890
00891
00892
00893
00894
00895
00896
00897
00898
00899
00900
00901
00902
00903
00904
00905
00906
00907
00908
00909
00910
00919
00920
00921
00922
00923
00924
00925
00926 ID3_Tag& ID3_Tag::operator=( const ID3_Tag &rTag )
00927 {
00928 if (this != &rTag)
00929 {
00930 *_impl = rTag;
00931 }
00932 return *this;
00933 }
00934
00935 bool ID3_Tag::HasTagType(ID3_TagType tt) const
00936 {
00937 return _impl->HasTagType(tt);
00938 }
00939
00940 ID3_V2Spec ID3_Tag::GetSpec() const
00941 {
00942 return _impl->GetSpec();
00943 }
00944
00945 bool ID3_Tag::SetSpec(ID3_V2Spec spec)
00946 {
00947 return _impl->SetSpec(spec);
00948 }
00949
00954 size_t ID3_Tag::IsV2Tag(const uchar* const data)
00955 {
00956 ID3_MemoryReader mr(data, ID3_TagHeader::SIZE);
00957 return ID3_TagImpl::IsV2Tag(mr);
00958 }
00959
00960 size_t ID3_Tag::IsV2Tag(ID3_Reader& reader)
00961 {
00962 return ID3_TagImpl::IsV2Tag(reader);
00963 }
00964
00966 void ID3_Tag::AddNewFrame(ID3_Frame* f)
00967 {
00968 _impl->AttachFrame(f);
00969 }
00970
00987 void ID3_Tag::AddFrames(const ID3_Frame *frames, size_t numFrames)
00988 {
00989 for (int i = numFrames - 1; i >= 0; i--)
00990 {
00991 this->AddFrame(frames[i]);
00992 }
00993 }
00994
00995 size_t ID3_Tag::Link(const char *fileInfo, bool parseID3v1, bool parseLyrics3)
00996 {
00997 return _impl->Link(fileInfo, parseID3v1, parseLyrics3);
00998 }
00999
01000 void ID3_Tag::SetCompression(bool b)
01001 {
01002 ;
01003 }
01004
01005 bool ID3_Tag::HasLyrics() const
01006 {
01007 return this->HasTagType(ID3TT_LYRICS);
01008 }
01009 bool ID3_Tag::HasV2Tag() const
01010 {
01011 return this->HasTagType(ID3TT_ID3V2);
01012 }
01013 bool ID3_Tag::HasV1Tag() const
01014 {
01015 return this->HasTagType(ID3TT_ID3V1);
01016 }
01017
01037 ID3_Tag& ID3_Tag::operator<<(const ID3_Frame& frame)
01038 {
01039 this->AddFrame(frame);
01040 return *this;
01041 }
01042
01043
01044 ID3_Tag& ID3_Tag::operator<<(const ID3_Frame* frame)
01045 {
01046 if (frame)
01047 {
01048 this->AddFrame(frame);
01049 }
01050 return *this;
01051 }
01052
01053 int32 ID3_IsTagHeader(const uchar data[ID3_TAGHEADERSIZE])
01054 {
01055 size_t size = ID3_Tag::IsV2Tag(data);
01056
01057 if (!size)
01058 {
01059 return -1;
01060 }
01061
01062 return size - ID3_TagHeader::SIZE;
01063 }
01064
01065
01066 namespace
01067 {
01068 class IteratorImpl : public ID3_Tag::Iterator
01069 {
01070 ID3_TagImpl::iterator _cur;
01071 ID3_TagImpl::iterator _end;
01072 public:
01073 IteratorImpl(ID3_TagImpl& tag)
01074 : _cur(tag.begin()), _end(tag.end())
01075 {
01076 }
01077
01078 ID3_Frame* GetNext()
01079 {
01080 ID3_Frame* next = NULL;
01081 while (next == NULL && _cur != _end)
01082 {
01083 next = *_cur;
01084 ++_cur;
01085 }
01086 return next;
01087 }
01088 };
01089
01090
01091 class ConstIteratorImpl : public ID3_Tag::ConstIterator
01092 {
01093 ID3_TagImpl::const_iterator _cur;
01094 ID3_TagImpl::const_iterator _end;
01095 public:
01096 ConstIteratorImpl(ID3_TagImpl& tag)
01097 : _cur(tag.begin()), _end(tag.end())
01098 {
01099 }
01100 const ID3_Frame* GetNext()
01101 {
01102 ID3_Frame* next = NULL;
01103 while (next == NULL && _cur != _end)
01104 {
01105 next = *_cur;
01106 ++_cur;
01107 }
01108 return next;
01109 }
01110 };
01111 }
01112
01113 ID3_Tag::Iterator*
01114 ID3_Tag::CreateIterator()
01115 {
01116 return new IteratorImpl(*_impl);
01117 }
01118
01119 ID3_Tag::ConstIterator*
01120 ID3_Tag::CreateIterator() const
01121 {
01122 return new ConstIteratorImpl(*_impl);
01123 }
01124