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