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
#if defined HAVE_SYS_PARAM_H
00029
#include <sys/param.h>
00030
#endif
00031
00032
#include "tag_impl.h"
00033
00034
#include "io_strings.h"
00035
00036
using namespace dami;
00037
00038 size_t
ID3_TagImpl::IsV2Tag(
ID3_Reader& reader)
00039 {
00040
io::ExitTrigger et(reader);
00041 size_t tagSize = 0;
00042 String
id = io::readText(reader, ID3_TagHeader::ID_SIZE);
00043 String ver = io::readText(reader, 2);
00044
char flags = reader.
readChar();
00045 String size = io::readText(reader, 4);
00046
00047
if (
id == ID3_TagHeader::ID &&
00048 (
uchar) ver [0] < 0xFF && (
uchar) ver [1] < 0xFF &&
00049 (
uchar) size[0] < 0x80 && (
uchar) size[1] < 0x80 &&
00050 (
uchar) size[2] < 0x80 && (
uchar) size[3] < 0x80)
00051 {
00052
io::StringReader sr(size);
00053 tagSize = io::readUInt28(sr) + ID3_TagHeader::SIZE;
00054 }
00055
else if (
id != ID3_TagHeader::ID)
00056 {
00057
00058 }
00059
else if ((
uchar)ver[0] >= 0xFF)
00060 {
00061
00062 }
00063
else if ((
uchar)ver[1] >= 0xFF)
00064 {
00065
00066 }
00067
else if ((
uchar)size[0] >= 0x80)
00068 {
00069
00070 }
00071
else if ((
uchar)size[1] >= 0x80)
00072 {
00073
00074 }
00075
else if ((
uchar)size[2] >= 0x80)
00076 {
00077
00078 }
00079
else if ((
uchar)size[3] >= 0x80)
00080 {
00081
00082 }
00083
else
00084 {
00085
00086 }
00087
00088
return tagSize;
00089 }
00090
00091 ID3_TagImpl::ID3_TagImpl(
const char *name)
00092 : _frames(),
00093 _cursor(_frames.begin()),
00094 _file_name(),
00095 _file_size(0),
00096 _prepended_bytes(0),
00097 _appended_bytes(0),
00098 _is_file_writable(false),
00099 _mp3_info(
NULL)
00100 {
00101 this->
Clear();
00102
if (name)
00103 {
00104 this->
Link(name);
00105 }
00106 }
00107
00108 ID3_TagImpl::ID3_TagImpl(
const ID3_Tag &tag)
00109 : _frames(),
00110 _cursor(_frames.begin()),
00111 _file_name(),
00112 _file_size(0),
00113 _prepended_bytes(0),
00114 _appended_bytes(0),
00115 _is_file_writable(false),
00116 _mp3_info(
NULL)
00117 {
00118 *
this = tag;
00119 }
00120
00121 ID3_TagImpl::~ID3_TagImpl()
00122 {
00123 this->
Clear();
00124 }
00125
00126 void ID3_TagImpl::Clear()
00127 {
00128
for (
iterator cur = _frames.begin(); cur != _frames.end(); ++cur)
00129 {
00130
if (*cur)
00131 {
00132
delete *cur;
00133 *cur =
NULL;
00134 }
00135 }
00136 _frames.clear();
00137 _cursor = _frames.begin();
00138 _is_padded =
true;
00139
00140 _hdr.
Clear();
00141 _hdr.
SetSpec(
ID3V2_LATEST);
00142
00143 _tags_to_parse.
clear();
00144
if (_mp3_info)
00145
delete _mp3_info;
00146
00147 _mp3_info =
NULL;
00148
00149 _changed =
true;
00150 }
00151
00152
00153 void ID3_TagImpl::AddFrame(
const ID3_Frame& frame)
00154 {
00155 this->
AddFrame(&frame);
00156 }
00157
00158 void ID3_TagImpl::AddFrame(
const ID3_Frame* frame)
00159 {
00160
if (frame)
00161 {
00162
ID3_Frame* frm =
new ID3_Frame(*frame);
00163 this->
AttachFrame(frm);
00164 }
00165 }
00166
00167 bool ID3_TagImpl::AttachFrame(
ID3_Frame *frame)
00168 {
00169
00170
if (
NULL == frame)
00171 {
00172
00173
return false;
00174
00175 }
00176
00177 _frames.push_back(frame);
00178 _cursor = _frames.begin();
00179
00180 _changed =
true;
00181
return true;
00182 }
00183
00184
00185 ID3_Frame*
ID3_TagImpl::RemoveFrame(
const ID3_Frame *frame)
00186 {
00187
ID3_Frame *frm =
NULL;
00188
00189
iterator fi =
Find(frame);
00190
if (fi != _frames.end())
00191 {
00192 frm = *fi;
00193 _frames.erase(fi);
00194 _cursor = _frames.begin();
00195 _changed =
true;
00196 }
00197
00198
return frm;
00199 }
00200
00201
00202 bool ID3_TagImpl::HasChanged()
const
00203
{
00204
bool changed = _changed;
00205
00206
if (! changed)
00207 {
00208
for (
const_iterator fi = _frames.begin(); fi != _frames.end(); ++fi)
00209 {
00210
if (*fi)
00211 {
00212 changed = (*fi)->HasChanged();
00213 }
00214
00215
if (changed)
00216 {
00217
break;
00218 }
00219 }
00220 }
00221
00222
return changed;
00223 }
00224
00225 bool ID3_TagImpl::SetSpec(ID3_V2Spec spec)
00226 {
00227
bool changed = _hdr.
SetSpec(spec);
00228 _changed = _changed || changed;
00229
return changed;
00230 }
00231
00232 ID3_V2Spec ID3_TagImpl::GetSpec()
const
00233
{
00234
return _hdr.
GetSpec();
00235 }
00236
00237 bool ID3_TagImpl::SetUnsync(
bool b)
00238 {
00239
bool changed = _hdr.
SetUnsync(b);
00240 _changed = changed || _changed;
00241
return changed;
00242 }
00243
00244 bool ID3_TagImpl::SetExtended(
bool ext)
00245 {
00246
bool changed = _hdr.
SetExtended(ext);
00247 _changed = changed || _changed;
00248
return changed;
00249 }
00250
00251 bool ID3_TagImpl::SetExperimental(
bool exp)
00252 {
00253
bool changed = _hdr.
SetExperimental(exp);
00254 _changed = changed || _changed;
00255
return changed;
00256 }
00257
00258 bool ID3_TagImpl::GetUnsync()
const
00259
{
00260
return _hdr.
GetUnsync();
00261 }
00262
00263 bool ID3_TagImpl::GetExtended()
const
00264
{
00265
return _hdr.
GetExtended();
00266 }
00267
00268 bool ID3_TagImpl::GetExperimental()
const
00269
{
00270
return _hdr.
GetExperimental();
00271 }
00272
00273 bool ID3_TagImpl::GetFooter()
const
00274
{
00275
return _hdr.
GetFooter();
00276 }
00277
00278 size_t
ID3_TagImpl::GetExtendedBytes()
const
00279
{
00280
if (this->
GetExtended())
00281
if (this->
GetSpec() ==
ID3V2_4_0)
00282
return 6;
00283
else if (this->
GetSpec() ==
ID3V2_3_0)
00284
return 10;
00285
else
00286
return 0;
00287
else
00288
return 0;;
00289 }
00290
00291 bool ID3_TagImpl::SetPadding(
bool pad)
00292 {
00293
bool changed = (_is_padded != pad);
00294 _changed = changed || _changed;
00295
if (changed)
00296 {
00297 _is_padded = pad;
00298 }
00299
00300
return changed;
00301 }
00302
00303
00304
ID3_TagImpl &
00305 ID3_TagImpl::operator=(
const ID3_Tag &rTag )
00306 {
00307 this->
Clear();
00308
00309 this->
SetUnsync(rTag.
GetUnsync());
00310 this->
SetExtended(rTag.
GetExtendedHeader());
00311 this->
SetExperimental(rTag.
GetExperimental());
00312
00313
ID3_Tag::ConstIterator* iter = rTag.
CreateIterator();
00314
const ID3_Frame* frame =
NULL;
00315
while (
NULL != (frame = iter->
GetNext()))
00316 {
00317 this->
AttachFrame(
new ID3_Frame(*frame));
00318 }
00319
delete iter;
00320
return *
this;
00321 }
00322
00323 size_t
ID3_GetDataSize(
const ID3_TagImpl& tag)
00324 {
00325
return tag.
GetFileSize() - tag.
GetPrependedBytes() - tag.
GetAppendedBytes();
00326 }
00327