src/field_string_ascii.cpp

Go to the documentation of this file.
00001 // $Id: field_string_ascii.cpp,v 1.29 2003/03/02 14:23:58 t1mpy Exp $
00002 
00003 // id3lib: a C++ library for creating and manipulating id3v1/v2 tags
00004 // Copyright 1999, 2000  Scott Thomas Haug
00005 
00006 // This library is free software; you can redistribute it and/or modify it
00007 // under the terms of the GNU Library General Public License as published by
00008 // the Free Software Foundation; either version 2 of the License, or (at your
00009 // option) any later version.
00010 //
00011 // This library is distributed in the hope that it will be useful, but WITHOUT
00012 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00013 // FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
00014 // License for more details.
00015 //
00016 // You should have received a copy of the GNU Library General Public License
00017 // along with this library; if not, write to the Free Software Foundation,
00018 // Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00019 
00020 // The id3lib authors encourage improvements and optimisations to be sent to
00021 // the id3lib coordinator.  Please see the README file for details on where to
00022 // send such submissions.  See the AUTHORS file for a list of people who have
00023 // contributed to id3lib.  See the ChangeLog file for a list of changes to
00024 // id3lib.  These files are distributed with id3lib at
00025 // http://download.sourceforge.net/id3lib/
00026 
00027 #include "field_impl.h"
00028 #include "id3/utils.h" // has <config.h> "id3/id3lib_streams.h" "id3/globals.h" "id3/id3lib_strings.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 // the ::Get() function for ASCII
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;  // how much of str we copied into this field (max is strLen)
00216   ID3D_NOTICE ("ID3_FieldImpl::AddText_i: Adding \"" << data << "\"" );
00217   if (this->GetNumTextItems() == 0)
00218   {
00219     // there aren't any text items in the field so just assign the string to
00220     // the field
00221     len = this->SetText_i(data);
00222   }
00223   else
00224   {
00225 
00226     // ASSERT(_fixed_size == 0)
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     // The string is of fixed length
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     // lists are always the last field in a frame.  parse all remaining
00348     // characters in the reader
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     // not null terminated.
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 

Generated on Mon Aug 20 17:48:46 2007 for id3lib by  doxygen 1.5.2