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 #if defined HAVE_CONFIG_H
00028 #include <config.h>
00029 #endif
00030
00031 #include "tag.h"
00032 #include "readers.h"
00033 #include "writers.h"
00034 #include "tag_impl.h"
00035 #include "strings.h"
00036 #include "utils.h"
00037
00038 using namespace dami;
00039
00295 ID3_Tag::ID3_Tag(const char *name)
00296 : _impl(new ID3_TagImpl(name))
00297 {
00298 }
00299
00304 ID3_Tag::ID3_Tag(const ID3_Tag &tag)
00305 : _impl(new ID3_TagImpl(tag))
00306 {
00307 }
00308
00309 ID3_Tag::~ID3_Tag()
00310 {
00311 delete _impl;
00312 }
00313
00320 void ID3_Tag::Clear()
00321 {
00322 _impl->Clear();
00323 }
00324
00325
00349 bool ID3_Tag::HasChanged() const
00350 {
00351 return _impl->HasChanged();
00352 }
00353
00384 size_t ID3_Tag::Size() const
00385 {
00386 return _impl->Size();
00387 }
00388
00406 bool ID3_Tag::SetUnsync(bool b)
00407 {
00408 return _impl->SetUnsync(b);
00409 }
00410
00411
00425 bool ID3_Tag::SetExtendedHeader(bool ext)
00426 {
00427 return _impl->SetExtended(ext);
00428 }
00429
00459 bool ID3_Tag::SetPadding(bool pad)
00460 {
00461 return _impl->SetPadding(pad);
00462 }
00463
00464 bool ID3_Tag::SetExperimental(bool exp)
00465 {
00466 return _impl->SetExperimental(exp);
00467 }
00468
00469 bool ID3_Tag::GetUnsync() const
00470 {
00471 return _impl->GetUnsync();
00472 }
00473
00474 bool ID3_Tag::GetExtendedHeader() const
00475 {
00476 return _impl->GetExtended();
00477 }
00478
00479 bool ID3_Tag::GetExperimental() const
00480 {
00481 return _impl->GetExperimental();
00482 }
00483
00484 void ID3_Tag::AddFrame(const ID3_Frame& frame)
00485 {
00486 _impl->AddFrame(frame);
00487 }
00488
00508 void ID3_Tag::AddFrame(const ID3_Frame* frame)
00509 {
00510 _impl->AddFrame(frame);
00511 }
00512
00527 void ID3_Tag::AttachFrame(ID3_Frame *frame)
00528 {
00529 _impl->AttachFrame(frame);
00530 }
00531
00532
00553 ID3_Frame* ID3_Tag::RemoveFrame(const ID3_Frame *frame)
00554 {
00555 return _impl->RemoveFrame(frame);
00556 }
00557
00558 bool ID3_Tag::Parse(ID3_Reader& reader)
00559 {
00560 return id3::v2::parse(*_impl, reader);
00561 }
00562
00563 size_t ID3_Tag::Parse(const uchar* buffer, size_t bytes)
00564 {
00565 ID3_MemoryReader mr(buffer, bytes);
00566 ID3_Reader::pos_type beg = mr.getCur();
00567 id3::v2::parse(*_impl, mr);
00568 return mr.getEnd() - beg;
00569 }
00570
00610 size_t ID3_Tag::Parse(const uchar header[ID3_TAGHEADERSIZE],
00611 const uchar *buffer)
00612 {
00613 size_t size = ID3_Tag::IsV2Tag(header);
00614 if (0 == size)
00615 {
00616 return 0;
00617 }
00618 BString buf;
00619 buf.reserve(ID3_TagHeader::SIZE + size);
00620 buf.append(reinterpret_cast<const BString::value_type *>(header),
00621 ID3_TagHeader::SIZE);
00622 buf.append(reinterpret_cast<const BString::value_type *>(buffer), size);
00623 return this->Parse(buf.data(), buf.size());
00624 }
00625
00654 size_t ID3_Tag::Render(uchar* buffer, ID3_TagType tt) const
00655 {
00656 ID3_MemoryWriter mw(buffer, -1);
00657 return this->Render(mw, tt);
00658 }
00659
00660 size_t ID3_Tag::Render(ID3_Writer& writer, ID3_TagType tt) const
00661 {
00662 ID3_Writer::pos_type beg = writer.getCur();
00663 if (ID3TT_ID3V2 & tt)
00664 {
00665 id3::v2::render(writer, *this);
00666 }
00667 else if (ID3TT_ID3V1 & tt)
00668 {
00669 id3::v1::render(writer, *this);
00670 }
00671 return writer.getCur() - beg;
00672 }
00673
00674
00711 size_t ID3_Tag::Link(const char *fileInfo, flags_t flags)
00712 {
00713 return _impl->Link(fileInfo, flags);
00714 }
00715
00716 flags_t ID3_Tag::Update(flags_t flags)
00717 {
00718 return _impl->Update(flags);
00719 }
00720
00727 flags_t ID3_Tag::Strip(flags_t flags)
00728 {
00729 return _impl->Strip(flags);
00730 }
00731
00732 size_t ID3_Tag::GetPrependedBytes() const
00733 {
00734 return _impl->GetPrependedBytes();
00735 }
00736
00737 size_t ID3_Tag::GetAppendedBytes() const
00738 {
00739 return _impl->GetAppendedBytes();
00740 }
00741
00742 size_t ID3_Tag::GetFileSize() const
00743 {
00744 return _impl->GetFileSize();
00745 }
00746
00747 const char* ID3_Tag::GetFileName() const
00748 {
00749 return _impl->GetFileName().c_str();
00750 }
00751
00753
00816 ID3_Frame* ID3_Tag::Find(ID3_FrameID id) const
00817 {
00818 return _impl->Find(id);
00819 }
00820
00822 ID3_Frame* ID3_Tag::Find(ID3_FrameID id, ID3_FieldID fld, uint32 data) const
00823 {
00824 return _impl->Find(id, fld, data);
00825 }
00826
00828 ID3_Frame* ID3_Tag::Find(ID3_FrameID id, ID3_FieldID fld, const char* data) const
00829 {
00830 String str(data);
00831 return _impl->Find(id, fld, str);
00832 }
00833
00835 ID3_Frame* ID3_Tag::Find(ID3_FrameID id, ID3_FieldID fld, const unicode_t* data) const
00836 {
00837 WString str = toWString(data, ucslen(data));
00838 return _impl->Find(id, fld, str);
00839 }
00840
00848 size_t ID3_Tag::NumFrames() const
00849 {
00850 return _impl->NumFrames();
00851 }
00852
00867
00868
00869
00870
00871
00872
00873
00874
00875
00876
00877
00878
00879
00880
00881
00882
00883
00884
00885
00886
00887
00888
00889
00890
00891
00900
00901
00902
00903
00904
00905
00906
00907 ID3_Tag& ID3_Tag::operator=( const ID3_Tag &rTag )
00908 {
00909 if (this != &rTag)
00910 {
00911 *_impl = rTag;
00912 }
00913 return *this;
00914 }
00915
00916 bool ID3_Tag::HasTagType(uint16 tt) const
00917 {
00918 return _impl->HasTagType(tt);
00919 }
00920
00921 ID3_V2Spec ID3_Tag::GetSpec() const
00922 {
00923 return _impl->GetSpec();
00924 }
00925
00926 bool ID3_Tag::SetSpec(ID3_V2Spec spec)
00927 {
00928 return _impl->SetSpec(spec);
00929 }
00930
00935 size_t ID3_Tag::IsV2Tag(const uchar* const data)
00936 {
00937 ID3_MemoryReader mr(data, ID3_TagHeader::SIZE);
00938 return ID3_TagImpl::IsV2Tag(mr);
00939 }
00940
00941 size_t ID3_Tag::IsV2Tag(ID3_Reader& reader)
00942 {
00943 return ID3_TagImpl::IsV2Tag(reader);
00944 }
00945
00947 void ID3_Tag::AddNewFrame(ID3_Frame* f)
00948 {
00949 _impl->AttachFrame(f);
00950 }
00951
00968 void ID3_Tag::AddFrames(const ID3_Frame *frames, size_t numFrames)
00969 {
00970 for (index_t i = numFrames - 1; i >= 0; i--)
00971 {
00972 this->AddFrame(frames[i]);
00973 }
00974 }
00975
00976 size_t ID3_Tag::Link(const char *fileInfo, bool parseID3v1, bool parseLyrics3)
00977 {
00978 return _impl->Link(fileInfo, parseID3v1, parseLyrics3);
00979 }
00980
00981 void ID3_Tag::SetCompression(bool b)
00982 {
00983 ;
00984 }
00985
00986 bool ID3_Tag::HasLyrics() const
00987 {
00988 return this->HasTagType(ID3TT_LYRICS);
00989 }
00990 bool ID3_Tag::HasV2Tag() const
00991 {
00992 return this->HasTagType(ID3TT_ID3V2);
00993 }
00994 bool ID3_Tag::HasV1Tag() const
00995 {
00996 return this->HasTagType(ID3TT_ID3V1);
00997 }
00998
01018 ID3_Tag& ID3_Tag::operator<<(const ID3_Frame& frame)
01019 {
01020 this->AddFrame(frame);
01021 return *this;
01022 }
01023
01024
01025 ID3_Tag& ID3_Tag::operator<<(const ID3_Frame* frame)
01026 {
01027 if (frame)
01028 {
01029 this->AddFrame(frame);
01030 }
01031 return *this;
01032 }
01033
01034 int32 ID3_IsTagHeader(const uchar data[ID3_TAGHEADERSIZE])
01035 {
01036 size_t size = ID3_Tag::IsV2Tag(data);
01037
01038 if (!size)
01039 {
01040 return -1;
01041 }
01042
01043 return size - ID3_TagHeader::SIZE;
01044 }
01045
01046
01047 namespace
01048 {
01049 class IteratorImpl : public ID3_Tag::Iterator
01050 {
01051 ID3_TagImpl::iterator _cur;
01052 ID3_TagImpl::iterator _end;
01053 public:
01054 IteratorImpl(ID3_TagImpl& tag)
01055 : _cur(tag.begin()), _end(tag.end())
01056 {
01057 }
01058
01059 ID3_Frame* GetNext()
01060 {
01061 ID3_Frame* next = NULL;
01062 while (next == NULL && _cur != _end)
01063 {
01064 next = *_cur;
01065 ++_cur;
01066 }
01067 return next;
01068 }
01069 };
01070
01071
01072 class ConstIteratorImpl : public ID3_Tag::ConstIterator
01073 {
01074 ID3_TagImpl::const_iterator _cur;
01075 ID3_TagImpl::const_iterator _end;
01076 public:
01077 ConstIteratorImpl(ID3_TagImpl& tag)
01078 : _cur(tag.begin()), _end(tag.end())
01079 {
01080 }
01081 const ID3_Frame* GetNext()
01082 {
01083 ID3_Frame* next = NULL;
01084 while (next == NULL && _cur != _end)
01085 {
01086 next = *_cur;
01087 ++_cur;
01088 }
01089 return next;
01090 }
01091 };
01092 }
01093
01094 ID3_Tag::Iterator*
01095 ID3_Tag::CreateIterator()
01096 {
01097 return new IteratorImpl(*_impl);
01098 }
01099
01100 ID3_Tag::ConstIterator*
01101 ID3_Tag::CreateIterator() const
01102 {
01103 return new ConstIteratorImpl(*_impl);
01104 }