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
#include "field_impl.h"
00028
#include "id3/utils.h"
00029
#include "io_helpers.h"
00030
00031
using namespace dami;
00032
00045 size_t
ID3_FieldImpl::Set(
const char* data)
00046 {
00047 size_t len = 0;
00048
if ((this->
GetType() ==
ID3FTY_TEXTSTRING) && data)
00049 {
00050 String str(data);
00051 len = this->SetText_i(str);
00052 }
00053
return len;
00054 }
00055
00056
00057
00087 size_t
ID3_FieldImpl::Get(
char* buffer, size_t maxLength)
const
00088
{
00089 size_t size = 0;
00090
if (this->
GetType() ==
ID3FTY_TEXTSTRING &&
00091 this->
GetEncoding() ==
ID3TE_ASCII &&
00092 buffer !=
NULL && maxLength > 0)
00093 {
00094 String data = this->
GetText();
00095 size =
dami::min(maxLength, data.size());
00096 ::memcpy(buffer, data.data(), size);
00097
if (size < maxLength)
00098 {
00099 buffer[size] =
'\0';
00100 }
00101 }
00102
00103
return size;
00104 }
00105
00106 size_t
ID3_FieldImpl::Get(
char* buf, size_t maxLen, size_t index)
const
00107
{
00108 size_t size = 0;
00109
if (this->
GetType() ==
ID3FTY_TEXTSTRING &&
00110 this->
GetEncoding() ==
ID3TE_ASCII &&
00111 buf !=
NULL && maxLen > 0)
00112 {
00113 String data = this->
GetTextItem(index);
00114 size =
dami::min(maxLen, data.size());
00115 ::memcpy(buf, data.data(), size);
00116
if (size < maxLen)
00117 {
00118 buf[size] =
'\0';
00119 }
00120 }
00121
return size;
00122 }
00123
00124 String
ID3_FieldImpl::GetText()
const
00125
{
00126 String data;
00127
if (this->
GetType() ==
ID3FTY_TEXTSTRING)
00128 {
00129 data = _text;
00130 }
00131
return data;
00132 }
00133
00134 String
ID3_FieldImpl::GetTextItem(size_t index)
const
00135
{
00136 String data;
00137
if (this->
GetType() ==
ID3FTY_TEXTSTRING &&
00138 this->
GetEncoding() ==
ID3TE_ASCII)
00139 {
00140
const char* raw = this->
GetRawTextItem(index);
00141
if (raw !=
NULL)
00142 {
00143 data = raw;
00144 }
00145 }
00146
return data;
00147 }
00148
00149
namespace
00150
{
00151 String getFixed(String data, size_t size)
00152 {
00153 String text(data, 0, size);
00154
if (text.size() < size)
00155 {
00156 text.append(size - text.size(),
'\0');
00157 }
00158
return text;
00159 }
00160 }
00161
00162
00163 size_t ID3_FieldImpl::SetText_i(String data)
00164 {
00165 this->
Clear();
00166
if (_fixed_size > 0)
00167 {
00168 _text = getFixed(data, _fixed_size);
00169 }
00170
else
00171 {
00172 _text = data;
00173 }
00174 ID3D_NOTICE(
"SetText_i: text = \"" << _text <<
"\"" );
00175 _changed =
true;
00176
00177
if (_text.size() == 0)
00178 {
00179 _num_items = 0;
00180 }
00181
else
00182 {
00183 _num_items = 1;
00184 }
00185
00186
return _text.size();
00187 }
00188
00189 size_t
ID3_FieldImpl::SetText(String data)
00190 {
00191 size_t len = 0;
00192
if (this->
GetType() ==
ID3FTY_TEXTSTRING)
00193 {
00194 len = this->SetText_i(data);
00195 }
00196
return len;
00197 }
00198
00199
00213 size_t ID3_FieldImpl::AddText_i(String data)
00214 {
00215 size_t len = 0;
00216 ID3D_NOTICE (
"ID3_FieldImpl::AddText_i: Adding \"" << data <<
"\"" );
00217
if (this->
GetNumTextItems() == 0)
00218 {
00219
00220
00221 len = this->SetText_i(data);
00222 }
00223
else
00224 {
00225
00226
00227 _text +=
'\0';
00228
if (this->
GetEncoding() ==
ID3TE_UNICODE)
00229 {
00230 _text +=
'\0';
00231 }
00232 _text.append(data);
00233 len = data.size();
00234 _num_items++;
00235 }
00236
00237
return len;
00238 }
00239
00240 size_t
ID3_FieldImpl::AddText(String data)
00241 {
00242 size_t len = 0;
00243
if (this->
GetType() ==
ID3FTY_TEXTSTRING)
00244 {
00245 len = this->AddText_i(data);
00246 }
00247
return len;
00248 }
00249
00250 size_t
ID3_FieldImpl::Add(
const char* data)
00251 {
00252 size_t len = 0;
00253
if (this->
GetType() ==
ID3FTY_TEXTSTRING)
00254 {
00255 String str(data);
00256 len = this->AddText_i(str);
00257 }
00258
return len;
00259 }
00260
00261 const char*
ID3_FieldImpl::GetRawText()
const
00262
{
00263
const char* text =
NULL;
00264
if (this->
GetType() ==
ID3FTY_TEXTSTRING &&
00265 this->
GetEncoding() ==
ID3TE_ASCII)
00266 {
00267 text = _text.c_str();
00268 }
00269
return text;
00270 }
00271
00272 const char*
ID3_FieldImpl::GetRawTextItem(size_t index)
const
00273
{
00274
const char* text =
NULL;
00275
if (this->
GetType() ==
ID3FTY_TEXTSTRING &&
00276 this->
GetEncoding() ==
ID3TE_ASCII &&
00277 index < this->
GetNumTextItems())
00278 {
00279 text = _text.c_str();
00280
for (size_t i = 0; i < index; ++i)
00281 {
00282 text += strlen(text) + 1;
00283 }
00284 }
00285
return text;
00286 }
00287
00288
namespace
00289
{
00290 String readEncodedText(
ID3_Reader& reader, size_t len, ID3_TextEnc enc)
00291 {
00292
if (enc ==
ID3TE_ASCII)
00293 {
00294
return io::readText(reader, len);
00295 }
00296
return io::readUnicodeText(reader, len);
00297 }
00298
00299 String readEncodedString(
ID3_Reader& reader, ID3_TextEnc enc)
00300 {
00301
if (enc ==
ID3TE_ASCII)
00302 {
00303
return io::readString(reader);
00304 }
00305
return io::readUnicodeString(reader);
00306 }
00307
00308 size_t writeEncodedText(
ID3_Writer& writer, String data, ID3_TextEnc enc)
00309 {
00310
if (enc ==
ID3TE_ASCII)
00311 {
00312
return io::writeText(writer, data);
00313 }
00314
return io::writeUnicodeText(writer, data);
00315 }
00316
00317 size_t writeEncodedString(
ID3_Writer& writer, String data, ID3_TextEnc enc)
00318 {
00319
if (enc ==
ID3TE_ASCII)
00320 {
00321
return io::writeString(writer, data);
00322 }
00323
return io::writeUnicodeString(writer, data);
00324 }
00325 }
00326
00327 bool ID3_FieldImpl::ParseText(
ID3_Reader& reader)
00328 {
00329 ID3D_NOTICE(
"ID3_Field::ParseText(): reader.getBeg() = " << reader.
getBeg() );
00330 ID3D_NOTICE(
"ID3_Field::ParseText(): reader.getCur() = " << reader.
getCur() );
00331 ID3D_NOTICE(
"ID3_Field::ParseText(): reader.getEnd() = " << reader.
getEnd() );
00332 this->
Clear();
00333
00334
ID3_TextEnc enc = this->
GetEncoding();
00335 size_t fixed_size = this->
Size();
00336
if (fixed_size)
00337 {
00338 ID3D_NOTICE(
"ID3_Field::ParseText(): fixed size string" );
00339
00340 String text = readEncodedText(reader, fixed_size, enc);
00341 this->
SetText(text);
00342 ID3D_NOTICE(
"ID3_Field::ParseText(): fixed size string = " << text );
00343 }
00344
else if (_flags &
ID3FF_LIST)
00345 {
00346 ID3D_NOTICE(
"ID3_Field::ParseText(): text list" );
00347
00348
00349
while (!reader.
atEnd())
00350 {
00351 String text = readEncodedString(reader, enc);
00352 this->
AddText(text);
00353 ID3D_NOTICE(
"ID3_Field::ParseText(): adding string = " << text );
00354 }
00355 }
00356
else if (_flags &
ID3FF_CSTR)
00357 {
00358 ID3D_NOTICE(
"ID3_Field::ParseText(): null terminated string" );
00359 String text = readEncodedString(reader, enc);
00360 this->
SetText(text);
00361 ID3D_NOTICE(
"ID3_Field::ParseText(): null terminated string = " << text );
00362 }
00363
else
00364 {
00365 ID3D_NOTICE(
"ID3_Field::ParseText(): last field string" );
00366 String text = readEncodedText(reader, reader.
remainingBytes(), enc);
00367
00368 this->
AddText(text);
00369 ID3D_NOTICE(
"ID3_Field::ParseText(): last field string = " << text );
00370 }
00371
00372 _changed =
false;
00373
return true;
00374 }
00375
00376 void ID3_FieldImpl::RenderText(
ID3_Writer& writer)
const
00377
{
00378
ID3_TextEnc enc = this->
GetEncoding();
00379
00380
if (_flags &
ID3FF_CSTR)
00381 {
00382 writeEncodedString(writer, _text, enc);
00383 }
00384
else
00385 {
00386 writeEncodedText(writer, _text, enc);
00387 }
00388 _changed =
false;
00389 };
00390
00399 size_t
ID3_FieldImpl::GetNumTextItems()
const
00400
{
00401
return _num_items;
00402 }
00403