src/utils.cpp

Go to the documentation of this file.
00001 // $Id: utils.cpp,v 1.26 2002/07/02 22:04:36 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 <ctype.h>
00028 
00029 #if (defined(__GNUC__) && __GNUC__ == 2)
00030 #define NOCREATE ios::nocreate
00031 #else
00032 #if defined(macintosh)  //not sure if this is still needed
00033 #define toascii(X) (X)  //not sure if this is still needed
00034 #endif                  //not sure if this is still needed
00035 #define NOCREATE ((std::ios_base::openmode)0)
00036 #endif
00037 
00038 #include "id3/utils.h" // has <config.h> "id3/id3lib_streams.h" "id3/globals.h" "id3/id3lib_strings.h"
00039 
00040 #if defined HAVE_ICONV_H
00041 // check if we have all unicodes
00042 #if (defined(ID3_ICONV_FORMAT_UTF16BE) && defined(ID3_ICONV_FORMAT_UTF16) && defined(ID3_ICONV_FORMAT_UTF8) && defined(ID3_ICONV_FORMAT_ASCII))
00043 # include <iconv.h>
00044 # include <errno.h>
00045 #else
00046 # undef HAVE_ICONV_H
00047 #endif
00048 #endif
00049 
00050   // converts an ASCII string into a Unicode one
00051 dami::String mbstoucs(dami::String data)
00052 {
00053   size_t size = data.size();
00054   dami::String unicode(size * 2, '\0');
00055   for (size_t i = 0; i < size; ++i)
00056   {
00057     unicode[i*2+1] = toascii(data[i]);
00058   }
00059   return unicode;
00060 }
00061 
00062 // converts a Unicode string into ASCII
00063 dami::String ucstombs(dami::String data)
00064 {
00065   size_t size = data.size() / 2;
00066   dami::String ascii(size, '\0');
00067   for (size_t i = 0; i < size; ++i)
00068   {
00069     ascii[i] = toascii(data[i*2+1]);
00070   }
00071   return ascii;
00072 }
00073 
00074 dami::String oldconvert(dami::String data, ID3_TextEnc sourceEnc, ID3_TextEnc targetEnc)
00075 {
00076   dami::String target;
00077 #define ID3_IS_ASCII(enc)      ((enc) == ID3TE_ASCII || (enc) == ID3TE_ISO8859_1 || (enc) == ID3TE_UTF8)
00078 #define ID3_IS_UNICODE(enc)    ((enc) == ID3TE_UNICODE || (enc) == ID3TE_UTF16 || (enc) == ID3TE_UTF16BE)
00079   if (ID3_IS_ASCII(sourceEnc) && ID3_IS_UNICODE(targetEnc))
00080   {
00081     target = mbstoucs(data);
00082   }
00083   else if (ID3_IS_UNICODE(sourceEnc) && ID3_IS_ASCII(targetEnc))
00084   {
00085     target = ucstombs(data);
00086   }
00087   return target;
00088 }
00089 
00090 using namespace dami;
00091 
00092 size_t dami::renderNumber(uchar *buffer, uint32 val, size_t size)
00093 {
00094   uint32 num = val;
00095   for (size_t i = 0; i < size; i++)
00096   {
00097     buffer[size - i - 1] = (uchar)(num & MASK8);
00098     num >>= 8;
00099   }
00100   return size;
00101 }
00102 
00103 String dami::renderNumber(uint32 val, size_t size)
00104 {
00105   String str(size, '\0');
00106   uint32 num = val;
00107   for (size_t i = 0; i < size; i++)
00108   {
00109     str[size - i - 1] = (uchar)(num & MASK8);
00110     num >>= 8;
00111   }
00112   return str;
00113 }
00114 
00115 
00116 #if defined(HAVE_ICONV_H)
00117 
00118 namespace 
00119 {
00120   String convert_i(iconv_t cd, String source)
00121   {
00122     String target;
00123     size_t source_size = source.size();
00124 #if defined(ID3LIB_ICONV_OLDSTYLE)
00125     const char* source_str = source.data();
00126 #else
00127     char *source_str = new char[source.size()+1];
00128     source.copy(source_str, String::npos);
00129     source_str[source.length()] = 0;
00130 #endif
00131 
00132 #define ID3LIB_BUFSIZ 1024
00133     char buf[ID3LIB_BUFSIZ];
00134     char* target_str = buf;
00135     size_t target_size = ID3LIB_BUFSIZ;
00136     
00137     do
00138     {
00139       errno = 0;
00140       size_t nconv = iconv(cd, 
00141                            &source_str, &source_size, 
00142                            &target_str, &target_size);
00143       if (nconv == (size_t) -1 && errno != EINVAL && errno != E2BIG)
00144       {
00145 // errno is probably EILSEQ here, which means either an invalid byte sequence or a valid but unconvertible byte sequence 
00146         return target;
00147       }
00148       target.append(buf, ID3LIB_BUFSIZ - target_size);
00149       target_str = buf;
00150       target_size = ID3LIB_BUFSIZ;
00151     }
00152     while (source_size > 0);
00153     return target;
00154   }
00155 
00156   const char* getFormat(ID3_TextEnc enc)
00157   {
00158     const char* format = NULL;
00159     switch (enc)
00160     {
00161       case ID3TE_ASCII:
00162         format = ID3_ICONV_FORMAT_ASCII;
00163         break;
00164 
00165       case ID3TE_UTF16:
00166         format = ID3_ICONV_FORMAT_UTF16;
00167         break;
00168         
00169       case ID3TE_UTF16BE:
00170         format = ID3_ICONV_FORMAT_UTF16BE;
00171         break;
00172         
00173       case ID3TE_UTF8:
00174         format = ID3_ICONV_FORMAT_UTF8;
00175         break;
00176         
00177       default:
00178         break;
00179     }
00180     return format;
00181   }
00182 }
00183 #endif
00184 
00185 String dami::convert(String data, ID3_TextEnc sourceEnc, ID3_TextEnc targetEnc)
00186 {
00187   String target;
00188   if ((sourceEnc != targetEnc) && (data.size() > 0 ))
00189   {
00190 #if !defined HAVE_ICONV_H
00191     target = oldconvert(data, sourceEnc, targetEnc);
00192 #else
00193     const char* targetFormat = getFormat(targetEnc);
00194     const char* sourceFormat = getFormat(sourceEnc);
00195    
00196     iconv_t cd = iconv_open (targetFormat, sourceFormat);
00197     if (cd != (iconv_t) -1)
00198     {
00199       target = convert_i(cd, data);
00200       if (target.size() == 0)
00201       {
00202         //try it without iconv
00203         target = oldconvert(data, sourceEnc, targetEnc);
00204       }
00205     }
00206     else
00207     {
00208       target = oldconvert(data, sourceEnc, targetEnc);
00209     }
00210     iconv_close (cd);
00211 #endif
00212   }
00213   return target;
00214 }
00215 
00216 size_t dami::ucslen(const unicode_t *unicode)
00217 {
00218   if (NULL != unicode)
00219   {
00220     for (size_t size = 0; true; size++)
00221     {
00222       if (NULL_UNICODE == unicode[size])
00223       {
00224         return size;
00225       }
00226     }
00227   }
00228   return 0;
00229 }
00230 
00231 namespace
00232 {
00233   bool exists(String name)
00234   {
00235     ifstream file(name.c_str(), NOCREATE);
00236     return file.is_open() != 0;
00237   }
00238 };
00239 
00240 ID3_Err dami::createFile(String name, fstream& file)
00241 {
00242   if (file.is_open())
00243   {
00244     file.close();
00245   }
00246     
00247   file.open(name.c_str(), ios::in | ios::out | ios::binary | ios::trunc);
00248   if (!file)
00249   {
00250     return ID3E_ReadOnly;
00251   }
00252     
00253   return ID3E_NoError;
00254 }
00255 
00256 size_t dami::getFileSize(fstream& file)
00257 {
00258   size_t size = 0;
00259   if (file.is_open())
00260   {
00261     streamoff curpos = file.tellg();
00262     file.seekg(0, ios::end);
00263     size = file.tellg();
00264     file.seekg(curpos);
00265   }
00266   return size;
00267 }
00268 
00269 size_t dami::getFileSize(ifstream& file)
00270 {
00271   size_t size = 0;
00272   if (file.is_open())
00273   {
00274     streamoff curpos = file.tellg();
00275     file.seekg(0, ios::end);
00276     size = file.tellg();
00277     file.seekg(curpos);
00278   }
00279   return size;
00280 }
00281 
00282 size_t dami::getFileSize(ofstream& file)
00283 {
00284   size_t size = 0;
00285   if (file.is_open())
00286   {
00287     streamoff curpos = file.tellp();
00288     file.seekp(0, ios::end);
00289     size = file.tellp();
00290     file.seekp(curpos);
00291   }
00292   return size;
00293 }
00294 
00295 ID3_Err dami::openWritableFile(String name, fstream& file)
00296 {
00297   if (!exists(name))
00298   {
00299     return ID3E_NoFile;
00300   }
00301     
00302   if (file.is_open())
00303   {
00304     file.close();
00305   }
00306   file.open(name.c_str(), ios::in | ios::out | ios::binary | NOCREATE);
00307   if (!file)
00308   {
00309     return ID3E_ReadOnly;
00310   }
00311     
00312   return ID3E_NoError;
00313 }
00314 
00315 ID3_Err dami::openWritableFile(String name, ofstream& file)
00316 {
00317   if (!exists(name))
00318   {
00319     return ID3E_NoFile;
00320   }
00321     
00322   if (file.is_open())
00323   {
00324     file.close();
00325   }
00326   file.open(name.c_str(), ios::in | ios::out | ios::binary | NOCREATE);
00327   if (!file)
00328   {
00329     return ID3E_ReadOnly;
00330   }
00331     
00332   return ID3E_NoError;
00333 }
00334 
00335 ID3_Err dami::openReadableFile(String name, fstream& file)
00336 {
00337   if (file.is_open())
00338   {
00339     file.close();
00340   }
00341   file.open(name.c_str(), ios::in | ios::binary | NOCREATE);
00342   if (!file)
00343   {
00344     return ID3E_NoFile;
00345   }
00346     
00347   return ID3E_NoError;
00348 }
00349 
00350 ID3_Err dami::openReadableFile(String name, ifstream& file)
00351 {
00352   if (file.is_open())
00353   {
00354     file.close();
00355   }
00356   file.open(name.c_str(), ios::in | ios::binary | NOCREATE);
00357   if (!file)
00358   {
00359     return ID3E_NoFile;
00360   }
00361     
00362   return ID3E_NoError;
00363 }
00364 
00365 String dami::toString(uint32 val)
00366 {
00367   if (val == 0)
00368   {
00369     return "0";
00370   }
00371   String text;
00372   while (val > 0)
00373   {
00374     String tmp;
00375     char ch = (val % 10) + '0';
00376     tmp += ch;
00377     text = tmp + text;
00378     val /= 10;
00379   }
00380   return text;
00381 }
00382 
00383 WString dami::toWString(const unicode_t buf[], size_t len)
00384 {
00385   WString str;
00386   str.reserve(len);
00387 
00388   for (size_t i = 0; i < len; ++i)
00389   {
00390     str += static_cast<WString::value_type>(buf[i]);
00391   }
00392   return str;
00393 }
00394 

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