Annotation of /trunk/beep-media-player/patches/beep-media-player-0.9.7-unicode.patch
Parent Directory | Revision Log
Revision 144 -
(hide annotations)
(download)
Tue May 8 20:06:05 2007 UTC (17 years, 4 months ago) by niro
File size: 16841 byte(s)
Tue May 8 20:06:05 2007 UTC (17 years, 4 months ago) by niro
File size: 16841 byte(s)
-import
1 | niro | 144 | diff -r -U3 bmp-0.9.7.orig/Input/mpg123/id3_frame_content.c bmp-0.9.7/Input/mpg123/id3_frame_content.c |
2 | --- bmp-0.9.7.orig/Input/mpg123/id3_frame_content.c 2005-02-25 21:45:03.000000000 -0500 | ||
3 | +++ bmp-0.9.7/Input/mpg123/id3_frame_content.c 2005-02-25 21:56:14.000000000 -0500 | ||
4 | @@ -44,9 +44,7 @@ | ||
5 | char * | ||
6 | id3_get_content(struct id3_frame *frame) | ||
7 | { | ||
8 | - char *text, *text_beg, *ptr; | ||
9 | - char buffer[256]; | ||
10 | - int spc = sizeof(buffer) - 1; | ||
11 | + gchar *text, *text_it; | ||
12 | |||
13 | /* Type check */ | ||
14 | if (frame->fr_desc->fd_id != ID3_TCON) | ||
15 | @@ -56,83 +54,82 @@ | ||
16 | if (id3_decompress_frame(frame) == -1) | ||
17 | return NULL; | ||
18 | |||
19 | - if (*(guint8 *) frame->fr_data == ID3_ENCODING_ISO_8859_1) | ||
20 | - text_beg = text = g_strdup((char *) frame->fr_data + 1); | ||
21 | - else | ||
22 | - text_beg = text = id3_utf16_to_ascii((char *) frame->fr_data + 1); | ||
23 | - | ||
24 | - /* | ||
25 | - * If content is just plain text, return it. | ||
26 | - */ | ||
27 | - if (text[0] != '(') { | ||
28 | - return text; | ||
29 | - } | ||
30 | - | ||
31 | + ID3_FRAME_DEFINE_CURSOR(frame); | ||
32 | + | ||
33 | + guint8 encoding; | ||
34 | + ID3_FRAME_READ_OR_RETVAL(encoding, NULL); | ||
35 | + | ||
36 | + text = text_it = id3_string_decode(encoding, cursor, length); | ||
37 | + | ||
38 | + if (text == NULL) | ||
39 | + return NULL; | ||
40 | + | ||
41 | /* | ||
42 | * Expand ID3v1 genre numbers. | ||
43 | */ | ||
44 | - ptr = buffer; | ||
45 | - while (text[0] == '(' && text[1] != '(' && spc > 0) { | ||
46 | - const char *genre; | ||
47 | - int num = 0; | ||
48 | - | ||
49 | - if (text[1] == 'R' && text[2] == 'X') { | ||
50 | - text += 4; | ||
51 | - genre = _(" (Remix)"); | ||
52 | - if (ptr == buffer) | ||
53 | - genre++; | ||
54 | - | ||
55 | + while ((text_it = strstr(text_it, "(")) != NULL) | ||
56 | + { | ||
57 | + gchar* replace = NULL; | ||
58 | + gchar* ref_start = text_it + 1; | ||
59 | + | ||
60 | + if (*ref_start == ')') | ||
61 | + { | ||
62 | + /* False alarm */ | ||
63 | + ++text_it; | ||
64 | + continue; | ||
65 | } | ||
66 | - else if (text[1] == 'C' && text[2] == 'R') { | ||
67 | - text += 4; | ||
68 | - genre = _(" (Cover)"); | ||
69 | - if (ptr == buffer) | ||
70 | - genre++; | ||
71 | - | ||
72 | + | ||
73 | + gsize ref_size = strstr(ref_start, ")") - ref_start; | ||
74 | + | ||
75 | + if (strncmp(ref_start, "RX", ref_size) == 0) | ||
76 | + { | ||
77 | + replace = _("Remix"); | ||
78 | } | ||
79 | - else { | ||
80 | - /* Get ID3v1 genre number */ | ||
81 | - text++; | ||
82 | - while (*text != ')') { | ||
83 | - num *= 10; | ||
84 | - num += *text++ - '0'; | ||
85 | + else if (strncmp(ref_start, "CR", ref_size) == 0) | ||
86 | + { | ||
87 | + replace = _("Cover"); | ||
88 | + } | ||
89 | + else | ||
90 | + { | ||
91 | + /* Maybe an ID3v1 genre? */ | ||
92 | + int genre_number; | ||
93 | + gchar* genre_number_str = g_strndup(ref_start, ref_size); | ||
94 | + if (sscanf(genre_number_str, "%d", &genre_number) > 0) | ||
95 | + { | ||
96 | + /* Boundary check */ | ||
97 | + if (genre_number >= sizeof(mpg123_id3_genres) / sizeof(char *)) | ||
98 | + continue; | ||
99 | + replace = gettext(mpg123_id3_genres[genre_number]); | ||
100 | } | ||
101 | - text++; | ||
102 | - | ||
103 | - /* Boundary check */ | ||
104 | - if (num >= sizeof(mpg123_id3_genres) / sizeof(char *)) | ||
105 | - continue; | ||
106 | - | ||
107 | - genre = gettext(mpg123_id3_genres[num]); | ||
108 | - | ||
109 | - if (ptr != buffer && spc-- > 0) | ||
110 | - *ptr++ = '/'; | ||
111 | } | ||
112 | |||
113 | - /* Expand string into buffer */ | ||
114 | - while (*genre != '\0' && spc > 0) { | ||
115 | - *ptr++ = *genre++; | ||
116 | - spc--; | ||
117 | + if (replace != NULL) | ||
118 | + { | ||
119 | + /* Amazingly hairy code to replace a part of the original genre string | ||
120 | + with 'replace'. */ | ||
121 | + gchar* copy = g_malloc(strlen(text) - ref_size + strlen(replace) + 1); | ||
122 | + gsize pos = 0; | ||
123 | + gsize copy_size; | ||
124 | + | ||
125 | + /* Copy the part before the replaced part */ | ||
126 | + copy_size = ref_start - text; | ||
127 | + memcpy(copy + pos, text, copy_size); | ||
128 | + pos += copy_size; | ||
129 | + /* Copy the replacement instead of the original reference */ | ||
130 | + copy_size = strlen(replace); | ||
131 | + memcpy(copy + pos, replace, copy_size); | ||
132 | + pos += copy_size; | ||
133 | + /* Copy the rest, including the null */ | ||
134 | + memcpy(copy + pos, ref_start + ref_size, strlen(ref_start + ref_size)+1); | ||
135 | + | ||
136 | + /* Put into original variables */ | ||
137 | + gsize offset = text_it - text; | ||
138 | + g_free(text); | ||
139 | + text = copy; | ||
140 | + text_it = text + offset; | ||
141 | } | ||
142 | + | ||
143 | + ++text_it; | ||
144 | } | ||
145 | - | ||
146 | - /* | ||
147 | - * Add plaintext refinement. | ||
148 | - */ | ||
149 | - if (*text == '(') | ||
150 | - text++; | ||
151 | - if (*text != '\0' && ptr != buffer && spc-- > 0) | ||
152 | - *ptr++ = ' '; | ||
153 | - while (*text != '\0' && spc > 0) { | ||
154 | - *ptr++ = *text++; | ||
155 | - spc--; | ||
156 | - } | ||
157 | - *ptr = '\0'; | ||
158 | - | ||
159 | - g_free(text_beg); | ||
160 | - | ||
161 | - /* | ||
162 | - * Return the expanded content string. | ||
163 | - */ | ||
164 | - return g_strdup(buffer); | ||
165 | + return text; | ||
166 | } | ||
167 | diff -r -U3 bmp-0.9.7.orig/Input/mpg123/id3_frame_text.c bmp-0.9.7/Input/mpg123/id3_frame_text.c | ||
168 | --- bmp-0.9.7.orig/Input/mpg123/id3_frame_text.c 2005-02-25 21:45:03.000000000 -0500 | ||
169 | +++ bmp-0.9.7/Input/mpg123/id3_frame_text.c 2005-02-26 01:25:45.613011872 -0500 | ||
170 | @@ -35,21 +35,6 @@ | ||
171 | #include "id3_header.h" | ||
172 | |||
173 | |||
174 | -char * | ||
175 | -id3_utf16_to_ascii(void *utf16) | ||
176 | -{ | ||
177 | - char ascii[256]; | ||
178 | - char *uc = (char *) utf16 + 2; | ||
179 | - int i; | ||
180 | - | ||
181 | - for (i = 0; *uc != 0 && i < sizeof(ascii); i++, uc += 2) | ||
182 | - ascii[i] = *uc; | ||
183 | - | ||
184 | - ascii[i] = 0; | ||
185 | - return g_strdup(ascii); | ||
186 | -} | ||
187 | - | ||
188 | - | ||
189 | /* | ||
190 | * Function id3_get_encoding (frame) | ||
191 | * | ||
192 | @@ -78,7 +63,12 @@ | ||
193 | if (id3_decompress_frame(frame) == -1) | ||
194 | return -1; | ||
195 | |||
196 | - return *(gint8 *) frame->fr_data; | ||
197 | + ID3_FRAME_DEFINE_CURSOR(frame); | ||
198 | + | ||
199 | + guint8 encoding; | ||
200 | + ID3_FRAME_READ_OR_RETVAL(encoding, -1); | ||
201 | + | ||
202 | + return encoding; | ||
203 | } | ||
204 | |||
205 | |||
206 | @@ -119,6 +109,108 @@ | ||
207 | return 0; | ||
208 | } | ||
209 | |||
210 | +/* Get size of string in bytes including null. */ | ||
211 | +gsize id3_string_size(guint8 encoding, const void* text, gsize max_size) | ||
212 | +{ | ||
213 | + switch ( encoding ) { | ||
214 | + case ID3_ENCODING_ISO_8859_1: | ||
215 | + case ID3_ENCODING_UTF8: | ||
216 | + { | ||
217 | + const guint8* text8 = text; | ||
218 | + while ( (max_size >= sizeof(*text8)) && (*text8 != 0) ) | ||
219 | + { | ||
220 | + ++text8; | ||
221 | + max_size -= sizeof(*text8); | ||
222 | + } | ||
223 | + | ||
224 | + if (max_size >= sizeof(*text8)) | ||
225 | + { | ||
226 | + ++text8; | ||
227 | + max_size -= sizeof(*text8); | ||
228 | + } | ||
229 | + | ||
230 | + return text8 - (guint8*)text; | ||
231 | + } | ||
232 | + case ID3_ENCODING_UTF16: | ||
233 | + case ID3_ENCODING_UTF16BE: | ||
234 | + { | ||
235 | + const guint16* text16 = (guint16*)text; | ||
236 | + while ( (max_size > 0) && (*text16 != 0) ) | ||
237 | + { | ||
238 | + ++text16; | ||
239 | + max_size -= sizeof(*text16); | ||
240 | + } | ||
241 | + | ||
242 | + if (max_size > 0) | ||
243 | + { | ||
244 | + ++text16; | ||
245 | + max_size -= sizeof(*text16); | ||
246 | + } | ||
247 | + | ||
248 | + return (guint8*)text16 - (guint8*)text; | ||
249 | + } | ||
250 | + default: | ||
251 | + return 0; | ||
252 | + } | ||
253 | +} | ||
254 | + | ||
255 | +/* | ||
256 | + * Returns a newly-allocated UTF-8 string in the locale's encoding. | ||
257 | + * max_size specifies the maximum size of 'text', including terminating nulls. | ||
258 | + */ | ||
259 | +gchar* id3_string_decode(guint8 encoding, const void* text, gsize max_size) | ||
260 | +{ | ||
261 | + /* Otherwise, we'll end up passing -1 to functions, eliminating safety benefits. */ | ||
262 | + if (max_size <= 0) | ||
263 | + return NULL; | ||
264 | + | ||
265 | + switch( encoding ) | ||
266 | + { | ||
267 | + case ID3_ENCODING_ISO_8859_1: | ||
268 | + { | ||
269 | + return g_locale_to_utf8((const gchar*)text, max_size, NULL, NULL, NULL); | ||
270 | + } | ||
271 | + case ID3_ENCODING_UTF8: | ||
272 | + { | ||
273 | + gchar* end_text = (gchar*)text; | ||
274 | + if (g_utf8_validate((const gchar*)text, max_size, &end_text)) | ||
275 | + return g_strndup((const gchar*)text, max_size); | ||
276 | + else | ||
277 | + { | ||
278 | + /* g_utf8_validate() with second argument positive | ||
279 | + will return 0 if the string contains nulls. Frequently | ||
280 | + someone will pass us a valid null-terminated utf8 | ||
281 | + string, with max_size overestimated a bit; so we need | ||
282 | + to run another test to truly check validity */ | ||
283 | + if((end_text != text) && (*end_text == NULL) && | ||
284 | + g_utf8_validate((const gchar*)text, NULL, NULL)) | ||
285 | + return g_strndup((const gchar*)text, max_size); | ||
286 | + | ||
287 | + return NULL; | ||
288 | + } | ||
289 | + } | ||
290 | + case ID3_ENCODING_UTF16: | ||
291 | + { | ||
292 | + gsize size_bytes = id3_string_size(encoding, text, max_size); | ||
293 | + gchar* utf8 = g_convert((const gchar*)text, size_bytes, "UTF-8", "UTF-16", NULL, NULL, NULL); | ||
294 | + /* If conversion passes on the BOM as-is, we strip it. */ | ||
295 | + if (g_utf8_get_char(utf8) == 0xfeff) | ||
296 | + { | ||
297 | + gchar* new_utf8 = g_strdup(utf8+3); | ||
298 | + g_free(utf8); | ||
299 | + utf8 = new_utf8; | ||
300 | + } | ||
301 | + return utf8; | ||
302 | + } | ||
303 | + case ID3_ENCODING_UTF16BE: | ||
304 | + { | ||
305 | + gsize size_bytes = id3_string_size(encoding, text, max_size); | ||
306 | + return g_convert((const gchar*)text, size_bytes, "UTF-8", "UTF-16BE", NULL, NULL, NULL); | ||
307 | + } | ||
308 | + default: | ||
309 | + return NULL; | ||
310 | + } | ||
311 | +} | ||
312 | |||
313 | /* | ||
314 | * Function id3_get_text (frame) | ||
315 | @@ -137,38 +229,21 @@ | ||
316 | if (id3_decompress_frame(frame) == -1) | ||
317 | return NULL; | ||
318 | |||
319 | + ID3_FRAME_DEFINE_CURSOR(frame); | ||
320 | + | ||
321 | + guint8 encoding; | ||
322 | + ID3_FRAME_READ_OR_RETVAL(encoding, NULL); | ||
323 | + | ||
324 | if (frame->fr_desc->fd_id == ID3_TXXX || frame->fr_desc->fd_id == ID3_COMM) { | ||
325 | /* | ||
326 | * This is a user defined text frame. Skip the description. | ||
327 | */ | ||
328 | - switch (*(guint8 *) frame->fr_data) { | ||
329 | - case ID3_ENCODING_ISO_8859_1: | ||
330 | - { | ||
331 | - char *text = (char *) frame->fr_data + 1; | ||
332 | - | ||
333 | - while (*text != 0) | ||
334 | - text++; | ||
335 | - | ||
336 | - return g_strdup(++text); | ||
337 | - } | ||
338 | - case ID3_ENCODING_UTF16: | ||
339 | - { | ||
340 | - char *text16 = (char *) frame->fr_data + 1; | ||
341 | - | ||
342 | - while (*text16 != 0 || *(text16 + 1) != 0) | ||
343 | - text16 += 2; | ||
344 | - | ||
345 | - return id3_utf16_to_ascii(text16 + 2); | ||
346 | - } | ||
347 | - default: | ||
348 | - return NULL; | ||
349 | - } | ||
350 | + gsize bytes = id3_string_size(encoding, cursor, length); | ||
351 | + cursor += bytes; | ||
352 | + length -= bytes; | ||
353 | } | ||
354 | |||
355 | - if (*(guint8 *) frame->fr_data == ID3_ENCODING_ISO_8859_1) | ||
356 | - return g_strdup((char *) frame->fr_data + 1); | ||
357 | - else | ||
358 | - return id3_utf16_to_ascii(((char *) frame->fr_data + 1)); | ||
359 | + return id3_string_decode(encoding, cursor, length); | ||
360 | } | ||
361 | |||
362 | |||
363 | @@ -193,10 +268,12 @@ | ||
364 | if (id3_decompress_frame(frame) == -1) | ||
365 | return NULL; | ||
366 | |||
367 | - if (*(guint8 *) frame->fr_data == ID3_ENCODING_ISO_8859_1) | ||
368 | - return g_strdup((char *) frame->fr_data + 1); | ||
369 | - else | ||
370 | - return id3_utf16_to_ascii((char *) frame->fr_data + 1); | ||
371 | + ID3_FRAME_DEFINE_CURSOR(frame); | ||
372 | + | ||
373 | + guint8 encoding; | ||
374 | + ID3_FRAME_READ_OR_RETVAL(encoding, NULL); | ||
375 | + | ||
376 | + return id3_string_decode(encoding, cursor, length); | ||
377 | } | ||
378 | |||
379 | |||
380 | @@ -216,41 +293,19 @@ | ||
381 | if (id3_decompress_frame(frame) == -1) | ||
382 | return -1; | ||
383 | |||
384 | - /* | ||
385 | - * Generate integer according to encoding. | ||
386 | - */ | ||
387 | - switch (*(guint8 *) frame->fr_data) { | ||
388 | - case ID3_ENCODING_ISO_8859_1: | ||
389 | - { | ||
390 | - char *text = ((char *) frame->fr_data) + 1; | ||
391 | - | ||
392 | - while (*text >= '0' && *text <= '9') { | ||
393 | - number *= 10; | ||
394 | - number += *text - '0'; | ||
395 | - text++; | ||
396 | - } | ||
397 | - | ||
398 | - return number; | ||
399 | - } | ||
400 | - case ID3_ENCODING_UTF16: | ||
401 | - { | ||
402 | - char *text = ((char *) frame->fr_data) + 3; | ||
403 | - | ||
404 | -/* if (*(gint16 *) frame->fr_data == 0xfeff) */ | ||
405 | -/* text++; */ | ||
406 | - | ||
407 | - while (*text >= '0' && *text <= '9') { | ||
408 | - number *= 10; | ||
409 | - number += *text - '0'; | ||
410 | - text++; | ||
411 | - } | ||
412 | - | ||
413 | - return number; | ||
414 | - } | ||
415 | - | ||
416 | - default: | ||
417 | - return -1; | ||
418 | - } | ||
419 | + ID3_FRAME_DEFINE_CURSOR(frame); | ||
420 | + | ||
421 | + guint8 encoding; | ||
422 | + ID3_FRAME_READ_OR_RETVAL(encoding, number); | ||
423 | + | ||
424 | + gchar* number_str = id3_string_decode(encoding, cursor, length); | ||
425 | + if (number_str != NULL) | ||
426 | + { | ||
427 | + sscanf(number_str, "%d", &number); | ||
428 | + g_free(number_str); | ||
429 | + } | ||
430 | + | ||
431 | + return number; | ||
432 | } | ||
433 | |||
434 | |||
435 | @@ -306,7 +361,6 @@ | ||
436 | id3_set_text_number(struct id3_frame *frame, int number) | ||
437 | { | ||
438 | char buf[64]; | ||
439 | - int pos; | ||
440 | char *text; | ||
441 | |||
442 | /* Type check */ | ||
443 | @@ -321,20 +375,12 @@ | ||
444 | /* | ||
445 | * Create a string with a reversed number. | ||
446 | */ | ||
447 | - pos = 0; | ||
448 | - while (number > 0 && pos < 64) { | ||
449 | - buf[pos++] = (number % 10) + '0'; | ||
450 | - number /= 10; | ||
451 | - } | ||
452 | - if (pos == 64) | ||
453 | - return -1; | ||
454 | - if (pos == 0) | ||
455 | - buf[pos++] = '0'; | ||
456 | + snprintf(buf, sizeof(buf), "%d", number); | ||
457 | |||
458 | /* | ||
459 | * Allocate memory for new data. | ||
460 | */ | ||
461 | - frame->fr_raw_size = pos + 1; | ||
462 | + frame->fr_raw_size = strlen(buf) + 1; | ||
463 | frame->fr_raw_data = g_malloc(frame->fr_raw_size + 1); | ||
464 | |||
465 | /* | ||
466 | @@ -342,9 +388,7 @@ | ||
467 | */ | ||
468 | *(gint8 *) frame->fr_raw_data = ID3_ENCODING_ISO_8859_1; | ||
469 | text = (char *) frame->fr_raw_data + 1; | ||
470 | - while (--pos >= 0) | ||
471 | - *text++ = buf[pos]; | ||
472 | - *text = '\0'; | ||
473 | + strcpy(text, buf); | ||
474 | |||
475 | frame->fr_altered = 1; | ||
476 | frame->fr_owner->id3_altered = 1; | ||
477 | diff -r -U3 bmp-0.9.7.orig/Input/mpg123/id3_frame_url.c bmp-0.9.7/Input/mpg123/id3_frame_url.c | ||
478 | --- bmp-0.9.7.orig/Input/mpg123/id3_frame_url.c 2005-02-25 21:45:03.000000000 -0500 | ||
479 | +++ bmp-0.9.7/Input/mpg123/id3_frame_url.c 2005-02-25 22:15:28.000000000 -0500 | ||
480 | @@ -48,36 +48,26 @@ | ||
481 | /* Check if frame is compressed */ | ||
482 | if (id3_decompress_frame(frame) == -1) | ||
483 | return NULL; | ||
484 | - | ||
485 | - if (frame->fr_desc->fd_id == ID3_WXXX) { | ||
486 | + | ||
487 | + ID3_FRAME_DEFINE_CURSOR(frame); | ||
488 | + | ||
489 | + if ( frame->fr_desc->fd_id == ID3_WXXX ) { | ||
490 | /* | ||
491 | * This is a user defined link frame. Skip the description. | ||
492 | */ | ||
493 | - switch (*(guint8 *) frame->fr_data) { | ||
494 | - case ID3_ENCODING_ISO_8859_1: | ||
495 | - { | ||
496 | - char *text = (char *) frame->fr_data + 1; | ||
497 | - | ||
498 | - while (*text != 0) | ||
499 | - text++; | ||
500 | - | ||
501 | - return g_strdup(++text); | ||
502 | - } | ||
503 | - case ID3_ENCODING_UTF16: | ||
504 | - { | ||
505 | - gint16 *text16 = (gint16 *) ((glong) frame->fr_data + 1); | ||
506 | - | ||
507 | - while (*text16 != 0) | ||
508 | - text16++; | ||
509 | - | ||
510 | - return g_strdup((char *) (++text16)); | ||
511 | - } | ||
512 | - default: | ||
513 | + guint8 encoding; | ||
514 | + gsize description_size; | ||
515 | + | ||
516 | + ID3_FRAME_READ_OR_RETVAL(encoding, NULL); | ||
517 | + | ||
518 | + description_size = id3_string_size(encoding, cursor, length); | ||
519 | + if (description_size == 0) | ||
520 | return NULL; | ||
521 | - } | ||
522 | + cursor += description_size; | ||
523 | + length -= description_size; | ||
524 | } | ||
525 | |||
526 | - return g_strdup((char *) frame->fr_data); | ||
527 | + return id3_string_decode(ID3_ENCODING_ISO_8859_1, cursor, length); | ||
528 | } | ||
529 | |||
530 | |||
531 | @@ -102,8 +92,10 @@ | ||
532 | if (id3_decompress_frame(frame) == -1) | ||
533 | return NULL; | ||
534 | |||
535 | - if (*(guint8 *) frame->fr_data == ID3_ENCODING_ISO_8859_1) | ||
536 | - return g_strdup((char *) frame->fr_data + 1); | ||
537 | - else | ||
538 | - return id3_utf16_to_ascii((gint16 *) ((glong) frame->fr_data + 1)); | ||
539 | + ID3_FRAME_DEFINE_CURSOR(frame); | ||
540 | + | ||
541 | + guint8 encoding; | ||
542 | + ID3_FRAME_READ_OR_RETVAL(encoding, NULL); | ||
543 | + | ||
544 | + return id3_string_decode(encoding, cursor, length); | ||
545 | } | ||
546 | diff -r -U3 bmp-0.9.7.orig/Input/mpg123/xmms-id3.h bmp-0.9.7/Input/mpg123/xmms-id3.h | ||
547 | --- bmp-0.9.7.orig/Input/mpg123/xmms-id3.h 2005-02-25 21:45:03.000000000 -0500 | ||
548 | +++ bmp-0.9.7/Input/mpg123/xmms-id3.h 2005-02-25 21:49:22.000000000 -0500 | ||
549 | @@ -29,6 +29,7 @@ | ||
550 | #define ID3_H | ||
551 | |||
552 | #include <glib.h> | ||
553 | +#include <string.h> | ||
554 | #include <libbeep/vfs.h> | ||
555 | |||
556 | /* | ||
557 | @@ -318,6 +319,21 @@ | ||
558 | #define ID3_WPB ID3_FRAME_ID_22('W', 'P', 'B') | ||
559 | #define ID3_WXX ID3_FRAME_ID_22('W', 'X', 'X') | ||
560 | |||
561 | +/* | ||
562 | + * Handy macros which help us writing more secure length-aware code | ||
563 | + * which involves reading the frame's data buffer. | ||
564 | + */ | ||
565 | + | ||
566 | +#define ID3_FRAME_DEFINE_CURSOR(frame) \ | ||
567 | + gsize length = frame->fr_size; \ | ||
568 | + guint8* cursor = frame->fr_data; | ||
569 | + | ||
570 | +#define ID3_FRAME_READ_OR_RETVAL(variable, retval) \ | ||
571 | + if (length < sizeof(variable)) \ | ||
572 | + return retval; \ | ||
573 | + memcpy((void*)&variable, (void*)cursor, sizeof(variable)); \ | ||
574 | + cursor += sizeof(variable); \ | ||
575 | + length -= sizeof(variable); | ||
576 | |||
577 | /* | ||
578 | * Prototypes. | ||
579 | @@ -343,7 +359,8 @@ | ||
580 | void id3_frame_clear_data(struct id3_frame *frame); | ||
581 | |||
582 | /* From id3_frame_text.c */ | ||
583 | -char *id3_utf16_to_ascii(void *); | ||
584 | +gsize id3_string_size(guint8 encoding, const void* text, gsize max_size); | ||
585 | +gchar* id3_string_decode(guint8 encoding, const void* text, gsize max_size); | ||
586 | gint8 id3_get_encoding(struct id3_frame *); | ||
587 | int id3_set_encoding(struct id3_frame *, gint8); | ||
588 | char *id3_get_text(struct id3_frame *); |