Go to the documentation of this file.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