id3lib 3.8.3

- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

utils.cpp
Go to the documentation of this file.
1 // $Id: utils.cpp,v 1.26 2002/07/02 22:04:36 t1mpy Exp $
2
3 // id3lib: a C++ library for creating and manipulating id3v1/v2 tags
4 // Copyright 1999, 2000 Scott Thomas Haug
5
6 // This library is free software; you can redistribute it and/or modify it
7 // under the terms of the GNU Library General Public License as published by
8 // the Free Software Foundation; either version 2 of the License, or (at your
9 // option) any later version.
10 //
11 // This library is distributed in the hope that it will be useful, but WITHOUT
12 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
14 // License for more details.
15 //
16 // You should have received a copy of the GNU Library General Public License
17 // along with this library; if not, write to the Free Software Foundation,
18 // Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19
20 // The id3lib authors encourage improvements and optimisations to be sent to
21 // the id3lib coordinator. Please see the README file for details on where to
22 // send such submissions. See the AUTHORS file for a list of people who have
23 // contributed to id3lib. See the ChangeLog file for a list of changes to
24 // id3lib. These files are distributed with id3lib at
25 // http://download.sourceforge.net/id3lib/
26
27 #include <ctype.h>
28
29 #if (defined(__GNUC__) && __GNUC__ == 2)
30 #define NOCREATE ios::nocreate
31 #else
32 #if defined(macintosh) //not sure if this is still needed
33 #define toascii(X) (X) //not sure if this is still needed
34 #endif //not sure if this is still needed
35 #define NOCREATE ((std::ios_base::openmode)0)
36 #endif
37
38 #include "id3/utils.h" // has <config.h> "id3/id3lib_streams.h" "id3/globals.h" "id3/id3lib_strings.h"
39
40 #if defined HAVE_ICONV_H
41 // check if we have all unicodes
42 #if (defined(ID3_ICONV_FORMAT_UTF16BE) && defined(ID3_ICONV_FORMAT_UTF16) && defined(ID3_ICONV_FORMAT_UTF8) && defined(ID3_ICONV_FORMAT_ASCII))
43 # include <iconv.h>
44 # include <errno.h>
45 #else
46 # undef HAVE_ICONV_H
47 #endif
48 #endif
49
50 // converts an ASCII string into a Unicode one
51 dami::String mbstoucs(dami::String data)
52 {
53 size_t size = data.size();
54 dami::String unicode(size * 2, '\0');
55 for (size_t i = 0; i < size; ++i)
56 {
57 unicode[i*2+1] = toascii(data[i]);
58 }
59 return unicode;
60 }
61
62 // converts a Unicode string into ASCII
63 dami::String ucstombs(dami::String data)
64 {
65 size_t size = data.size() / 2;
66 dami::String ascii(size, '\0');
67 for (size_t i = 0; i < size; ++i)
68 {
69 ascii[i] = toascii(data[i*2+1]);
70 }
71 return ascii;
72 }
73
74 dami::String oldconvert(dami::String data, ID3_TextEnc sourceEnc, ID3_TextEnc targetEnc)
75 {
76 dami::String target;
77 #define ID3_IS_ASCII(enc) ((enc) == ID3TE_ASCII || (enc) == ID3TE_ISO8859_1 || (enc) == ID3TE_UTF8)
78 #define ID3_IS_UNICODE(enc) ((enc) == ID3TE_UNICODE || (enc) == ID3TE_UTF16 || (enc) == ID3TE_UTF16BE)
79 if (ID3_IS_ASCII(sourceEnc) && ID3_IS_UNICODE(targetEnc))
80 {
81 target = mbstoucs(data);
82 }
83 else if (ID3_IS_UNICODE(sourceEnc) && ID3_IS_ASCII(targetEnc))
84 {
85 target = ucstombs(data);
86 }
87 return target;
88 }
89
90 using namespace dami;
91
92 size_t dami::renderNumber(uchar *buffer, uint32 val, size_t size)
93 {
94 uint32 num = val;
95 for (size_t i = 0; i < size; i++)
96 {
97 buffer[size - i - 1] = (uchar)(num & MASK8);
98 num >>= 8;
99 }
100 return size;
101 }
102
103 String dami::renderNumber(uint32 val, size_t size)
104 {
105 String str(size, '\0');
106 uint32 num = val;
107 for (size_t i = 0; i < size; i++)
108 {
109 str[size - i - 1] = (uchar)(num & MASK8);
110 num >>= 8;
111 }
112 return str;
113 }
114
115
116 #if defined(HAVE_ICONV_H)
117
118 namespace
119 {
120 String convert_i(iconv_t cd, String source)
121 {
122 String target;
123 size_t source_size = source.size();
124 #if defined(ID3LIB_ICONV_OLDSTYLE)
125 const char* source_str = source.data();
126 #else
127 char *source_str = new char[source.size()+1];
128 source.copy(source_str, String::npos);
129 source_str[source.length()] = 0;
130 #endif
131
132 #define ID3LIB_BUFSIZ 1024
133 char buf[ID3LIB_BUFSIZ];
134 char* target_str = buf;
135 size_t target_size = ID3LIB_BUFSIZ;
136
137 do
138 {
139 errno = 0;
140 size_t nconv = iconv(cd,
141 &source_str, &source_size,
142 &target_str, &target_size);
143 if (nconv == (size_t) -1 && errno != EINVAL && errno != E2BIG)
144 {
145 // errno is probably EILSEQ here, which means either an invalid byte sequence or a valid but unconvertible byte sequence
146 return target;
147 }
148 target.append(buf, ID3LIB_BUFSIZ - target_size);
149 target_str = buf;
150 target_size = ID3LIB_BUFSIZ;
151 }
152 while (source_size > 0);
153 return target;
154 }
155
156 const char* getFormat(ID3_TextEnc enc)
157 {
158 const char* format = NULL;
159 switch (enc)
160 {
161 case ID3TE_ASCII:
162 format = ID3_ICONV_FORMAT_ASCII;
163 break;
164
165 case ID3TE_UTF16:
166 format = ID3_ICONV_FORMAT_UTF16;
167 break;
168
169 case ID3TE_UTF16BE:
170 format = ID3_ICONV_FORMAT_UTF16BE;
171 break;
172
173 case ID3TE_UTF8:
174 format = ID3_ICONV_FORMAT_UTF8;
175 break;
176
177 default:
178 break;
179 }
180 return format;
181 }
182 }
183 #endif
184
185 String dami::convert(String data, ID3_TextEnc sourceEnc, ID3_TextEnc targetEnc)
186 {
187 String target;
188 if ((sourceEnc != targetEnc) && (data.size() > 0 ))
189 {
190 #if !defined HAVE_ICONV_H
191 target = oldconvert(data, sourceEnc, targetEnc);
192 #else
193 const char* targetFormat = getFormat(targetEnc);
194 const char* sourceFormat = getFormat(sourceEnc);
195
196 iconv_t cd = iconv_open (targetFormat, sourceFormat);
197 if (cd != (iconv_t) -1)
198 {
199 target = convert_i(cd, data);
200 if (target.size() == 0)
201 {
202 //try it without iconv
203 target = oldconvert(data, sourceEnc, targetEnc);
204 }
205 }
206 else
207 {
208 target = oldconvert(data, sourceEnc, targetEnc);
209 }
210 iconv_close (cd);
211 #endif
212 }
213 return target;
214 }
215
216 size_t dami::ucslen(const unicode_t *unicode)
217 {
218 if (NULL != unicode)
219 {
220 for (size_t size = 0; true; size++)
221 {
222 if (NULL_UNICODE == unicode[size])
223 {
224 return size;
225 }
226 }
227 }
228 return 0;
229 }
230
231 namespace
232 {
233 bool exists(String name)
234 {
235 ifstream file(name.c_str(), NOCREATE);
236 return file.is_open() != 0;
237 }
238 };
239
240 ID3_Err dami::createFile(String name, fstream& file)
241 {
242 if (file.is_open())
243 {
244 file.close();
245 }
246
247 file.open(name.c_str(), ios::in | ios::out | ios::binary | ios::trunc);
248 if (!file)
249 {
250 return ID3E_ReadOnly;
251 }
252
253 return ID3E_NoError;
254 }
255
256 size_t dami::getFileSize(fstream& file)
257 {
258 size_t size = 0;
259 if (file.is_open())
260 {
261 streamoff curpos = file.tellg();
262 file.seekg(0, ios::end);
263 size = file.tellg();
264 file.seekg(curpos);
265 }
266 return size;
267 }
268
269 size_t dami::getFileSize(ifstream& file)
270 {
271 size_t size = 0;
272 if (file.is_open())
273 {
274 streamoff curpos = file.tellg();
275 file.seekg(0, ios::end);
276 size = file.tellg();
277 file.seekg(curpos);
278 }
279 return size;
280 }
281
282 size_t dami::getFileSize(ofstream& file)
283 {
284 size_t size = 0;
285 if (file.is_open())
286 {
287 streamoff curpos = file.tellp();
288 file.seekp(0, ios::end);
289 size = file.tellp();
290 file.seekp(curpos);
291 }
292 return size;
293 }
294
295 ID3_Err dami::openWritableFile(String name, fstream& file)
296 {
297 if (!exists(name))
298 {
299 return ID3E_NoFile;
300 }
301
302 if (file.is_open())
303 {
304 file.close();
305 }
306 file.open(name.c_str(), ios::in | ios::out | ios::binary | NOCREATE);
307 if (!file)
308 {
309 return ID3E_ReadOnly;
310 }
311
312 return ID3E_NoError;
313 }
314
315 ID3_Err dami::openWritableFile(String name, ofstream& file)
316 {
317 if (!exists(name))
318 {
319 return ID3E_NoFile;
320 }
321
322 if (file.is_open())
323 {
324 file.close();
325 }
326 file.open(name.c_str(), ios::in | ios::out | ios::binary | NOCREATE);
327 if (!file)
328 {
329 return ID3E_ReadOnly;
330 }
331
332 return ID3E_NoError;
333 }
334
335 ID3_Err dami::openReadableFile(String name, fstream& file)
336 {
337 if (file.is_open())
338 {
339 file.close();
340 }
341 file.open(name.c_str(), ios::in | ios::binary | NOCREATE);
342 if (!file)
343 {
344 return ID3E_NoFile;
345 }
346
347 return ID3E_NoError;
348 }
349
350 ID3_Err dami::openReadableFile(String name, ifstream& file)
351 {
352 if (file.is_open())
353 {
354 file.close();
355 }
356 file.open(name.c_str(), ios::in | ios::binary | NOCREATE);
357 if (!file)
358 {
359 return ID3E_NoFile;
360 }
361
362 return ID3E_NoError;
363 }
364
365 String dami::toString(uint32 val)
366 {
367 if (val == 0)
368 {
369 return "0";
370 }
371 String text;
372 while (val > 0)
373 {
374 String tmp;
375 char ch = (val % 10) + '0';
376 tmp += ch;
377 text = tmp + text;
378 val /= 10;
379 }
380 return text;
381 }
382
383 WString dami::toWString(const unicode_t buf[], size_t len)
384 {
385 WString str;
386 str.reserve(len);
387
388 for (size_t i = 0; i < len; ++i)
389 {
390 str += static_cast<WString::value_type>(buf[i]);
391 }
392 return str;
393 }
394
mbstoucs
dami::String mbstoucs(dami::String data)
Definition: utils.cpp:51
dami::String
std::basic_string< char > String
Definition: id3lib_strings.h:198
ID3E_NoError
No error reported.
Definition: globals.h:365
dami::getFileSize
size_t ID3_C_EXPORT getFileSize(fstream &)
Definition: utils.cpp:256
ID3_IS_UNICODE
#define ID3_IS_UNICODE(enc)
ID3TE_ASCII
Definition: globals.h:145
dami::renderNumber
size_t ID3_C_EXPORT renderNumber(uchar *buffer, uint32 val, size_t size=sizeof(uint32))
Definition: utils.cpp:92
ID3TE_UTF16BE
Definition: globals.h:142
uchar
unsigned char uchar
Definition: globals.h:114
ID3TE_UTF16
Definition: globals.h:141
utils.h
dami::convert
String ID3_C_EXPORT convert(String data, ID3_TextEnc, ID3_TextEnc)
Definition: utils.cpp:185
MASK8
#define MASK8
Definition: globals.h:705
NULL_UNICODE
#define NULL_UNICODE
Definition: globals.h:120
ID3_IS_ASCII
#define ID3_IS_ASCII(enc)
ID3E_NoFile
No file to parse.
Definition: globals.h:376
dami::ucslen
size_t ID3_C_EXPORT ucslen(const unicode_t *unicode)
Definition: utils.cpp:216
ID3_TextEnc
ID3_TextEnc
Enumeration of the types of text encodings: ascii or unicode.
Definition: globals.h:137
dami::openReadableFile
ID3_Err ID3_C_EXPORT openReadableFile(String, fstream &)
Definition: utils.cpp:335
ID3_Err
ID3_Err
Predefined id3lib error types.
Definition: globals.h:363
ID3TE_UTF8
Definition: globals.h:143
dami::WString
std::basic_string< wchar_t > WString
Definition: id3lib_strings.h:200
dami::toString
String ID3_C_EXPORT toString(uint32 val)
Definition: utils.cpp:365
NOCREATE
#define NOCREATE
Definition: utils.cpp:35
ucstombs
dami::String ucstombs(dami::String data)
Definition: utils.cpp:63
NULL
#define NULL
Definition: globals.h:743
dami::openWritableFile
ID3_Err ID3_C_EXPORT openWritableFile(String, fstream &)
Definition: utils.cpp:295
dami::toWString
WString ID3_C_EXPORT toWString(const unicode_t[], size_t)
Definition: utils.cpp:383
unicode_t
uint16 unicode_t
Definition: globals.h:117
oldconvert
dami::String oldconvert(dami::String data, ID3_TextEnc sourceEnc, ID3_TextEnc targetEnc)
Definition: utils.cpp:74
ID3E_ReadOnly
Attempting to write to a read-only file.
Definition: globals.h:377
dami::createFile
ID3_Err ID3_C_EXPORT createFile(String, fstream &)
Definition: utils.cpp:240