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 <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"
00039
00040 #if defined HAVE_ICONV_H
00041
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
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
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
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
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