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