id3lib 3.8.3
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
51dami::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
63dami::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
74dami::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
90using namespace dami;
91
92size_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
103String 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
118namespace
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
185String 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
216size_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
231namespace
232{
233 bool exists(String name)
234 {
235 ifstream file(name.c_str(), NOCREATE);
236 return file.is_open() != 0;
237 }
238};
239
240ID3_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
256size_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
269size_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
282size_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
295ID3_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
315ID3_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
335ID3_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
350ID3_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
365String 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
383WString 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
#define MASK8
Definition globals.h:705
#define NULL
Definition globals.h:743
ID3_Err
Predefined id3lib error types.
Definition globals.h:364
@ ID3E_ReadOnly
Attempting to write to a read-only file.
Definition globals.h:377
@ ID3E_NoError
No error reported.
Definition globals.h:365
@ ID3E_NoFile
No file to parse.
Definition globals.h:376
ID3_TextEnc
Enumeration of the types of text encodings: ascii or unicode.
Definition globals.h:138
@ ID3TE_UTF16BE
Definition globals.h:142
@ ID3TE_UTF16
Definition globals.h:141
@ ID3TE_ASCII
Definition globals.h:145
@ ID3TE_UTF8
Definition globals.h:143
unsigned char uchar
Definition globals.h:114
uint16 unicode_t
Definition globals.h:117
#define NULL_UNICODE
Definition globals.h:120
dami::String ucstombs(dami::String data)
Definition utils.cpp:63
dami::String mbstoucs(dami::String data)
Definition utils.cpp:51
#define ID3_IS_ASCII(enc)
dami::String oldconvert(dami::String data, ID3_TextEnc sourceEnc, ID3_TextEnc targetEnc)
Definition utils.cpp:74
#define ID3_IS_UNICODE(enc)
#define NOCREATE
Definition utils.cpp:35

Generated for id3lib by doxygen 1.10.0