Mercurial > audlegacy
comparison src/libid3tag/field.c @ 2503:10692383c103 trunk
[svn] first try for libid3tag integration. this improved libid3tag supports vfs operations and is capable of adding id3v2 tag to files which doesn't have id3v2 tag ever.
author | yaz |
---|---|
date | Sun, 11 Feb 2007 05:19:07 -0800 |
parents | |
children | 28814e6846e5 |
comparison
equal
deleted
inserted
replaced
2502:b7be0af74307 | 2503:10692383c103 |
---|---|
1 /* | |
2 * libid3tag - ID3 tag manipulation library | |
3 * Copyright (C) 2000-2004 Underbit Technologies, Inc. | |
4 * | |
5 * This program is free software; you can redistribute it and/or modify | |
6 * it under the terms of the GNU General Public License as published by | |
7 * the Free Software Foundation; either version 2 of the License, or | |
8 * (at your option) any later version. | |
9 * | |
10 * This program is distributed in the hope that it will be useful, | |
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
13 * GNU General Public License for more details. | |
14 * | |
15 * You should have received a copy of the GNU General Public License | |
16 * along with this program; if not, write to the Free Software | |
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
18 * | |
19 * $Id: field.c,v 1.16 2004/01/23 09:41:32 rob Exp $ | |
20 */ | |
21 | |
22 # ifdef HAVE_CONFIG_H | |
23 # include "config.h" | |
24 # endif | |
25 | |
26 # include "global.h" | |
27 | |
28 # include <stdlib.h> | |
29 # include <string.h> | |
30 | |
31 # ifdef HAVE_ASSERT_H | |
32 # include <assert.h> | |
33 # endif | |
34 | |
35 # include "id3tag.h" | |
36 # include "field.h" | |
37 # include "frame.h" | |
38 # include "render.h" | |
39 # include "ucs4.h" | |
40 # include "latin1.h" | |
41 # include "parse.h" | |
42 | |
43 /* | |
44 * NAME: field->init() | |
45 * DESCRIPTION: initialize a field to a default value for the given type | |
46 */ | |
47 void id3_field_init(union id3_field *field, enum id3_field_type type) | |
48 { | |
49 assert(field); | |
50 | |
51 switch (field->type = type) { | |
52 case ID3_FIELD_TYPE_TEXTENCODING: | |
53 case ID3_FIELD_TYPE_INT8: | |
54 case ID3_FIELD_TYPE_INT16: | |
55 case ID3_FIELD_TYPE_INT24: | |
56 case ID3_FIELD_TYPE_INT32: | |
57 field->number.value = 0; | |
58 break; | |
59 | |
60 case ID3_FIELD_TYPE_LATIN1: | |
61 case ID3_FIELD_TYPE_LATIN1FULL: | |
62 field->latin1.ptr = 0; | |
63 break; | |
64 | |
65 case ID3_FIELD_TYPE_LATIN1LIST: | |
66 field->latin1list.nstrings = 0; | |
67 field->latin1list.strings = 0; | |
68 | |
69 case ID3_FIELD_TYPE_STRING: | |
70 case ID3_FIELD_TYPE_STRINGFULL: | |
71 field->string.ptr = 0; | |
72 break; | |
73 | |
74 case ID3_FIELD_TYPE_STRINGLIST: | |
75 field->stringlist.nstrings = 0; | |
76 field->stringlist.strings = 0; | |
77 break; | |
78 | |
79 case ID3_FIELD_TYPE_LANGUAGE: | |
80 strcpy(field->immediate.value, "XXX"); | |
81 break; | |
82 | |
83 case ID3_FIELD_TYPE_FRAMEID: | |
84 strcpy(field->immediate.value, "XXXX"); | |
85 break; | |
86 | |
87 case ID3_FIELD_TYPE_DATE: | |
88 memset(field->immediate.value, 0, sizeof(field->immediate.value)); | |
89 break; | |
90 | |
91 case ID3_FIELD_TYPE_INT32PLUS: | |
92 case ID3_FIELD_TYPE_BINARYDATA: | |
93 field->binary.data = 0; | |
94 field->binary.length = 0; | |
95 break; | |
96 } | |
97 } | |
98 | |
99 /* | |
100 * NAME: field->finish() | |
101 * DESCRIPTION: reset a field, deallocating memory if necessary | |
102 */ | |
103 void id3_field_finish(union id3_field *field) | |
104 { | |
105 unsigned int i; | |
106 | |
107 assert(field); | |
108 | |
109 switch (field->type) { | |
110 case ID3_FIELD_TYPE_TEXTENCODING: | |
111 case ID3_FIELD_TYPE_INT8: | |
112 case ID3_FIELD_TYPE_INT16: | |
113 case ID3_FIELD_TYPE_INT24: | |
114 case ID3_FIELD_TYPE_INT32: | |
115 case ID3_FIELD_TYPE_LANGUAGE: | |
116 case ID3_FIELD_TYPE_FRAMEID: | |
117 case ID3_FIELD_TYPE_DATE: | |
118 break; | |
119 | |
120 case ID3_FIELD_TYPE_LATIN1: | |
121 case ID3_FIELD_TYPE_LATIN1FULL: | |
122 if (field->latin1.ptr) | |
123 free(field->latin1.ptr); | |
124 break; | |
125 | |
126 case ID3_FIELD_TYPE_LATIN1LIST: | |
127 for (i = 0; i < field->latin1list.nstrings; ++i) | |
128 free(field->latin1list.strings[i]); | |
129 | |
130 if (field->latin1list.strings) | |
131 free(field->latin1list.strings); | |
132 break; | |
133 | |
134 case ID3_FIELD_TYPE_STRING: | |
135 case ID3_FIELD_TYPE_STRINGFULL: | |
136 if (field->string.ptr) | |
137 free(field->string.ptr); | |
138 break; | |
139 | |
140 case ID3_FIELD_TYPE_STRINGLIST: | |
141 for (i = 0; i < field->stringlist.nstrings; ++i) | |
142 free(field->stringlist.strings[i]); | |
143 | |
144 if (field->stringlist.strings) | |
145 free(field->stringlist.strings); | |
146 break; | |
147 | |
148 case ID3_FIELD_TYPE_INT32PLUS: | |
149 case ID3_FIELD_TYPE_BINARYDATA: | |
150 if (field->binary.data) | |
151 free(field->binary.data); | |
152 break; | |
153 } | |
154 | |
155 id3_field_init(field, field->type); | |
156 } | |
157 | |
158 /* | |
159 * NAME: field->type() | |
160 * DESCRIPTION: return the value type of a field | |
161 */ | |
162 enum id3_field_type id3_field_type(union id3_field const *field) | |
163 { | |
164 assert(field); | |
165 | |
166 return field->type; | |
167 } | |
168 | |
169 /* | |
170 * NAME: field->parse() | |
171 * DESCRIPTION: parse a field value | |
172 */ | |
173 int id3_field_parse(union id3_field *field, id3_byte_t const **ptr, | |
174 id3_length_t length, enum id3_field_textencoding *encoding) | |
175 { | |
176 assert(field); | |
177 | |
178 id3_field_finish(field); | |
179 | |
180 switch (field->type) { | |
181 case ID3_FIELD_TYPE_INT32: | |
182 if (length < 4) | |
183 goto fail; | |
184 | |
185 field->number.value = id3_parse_uint(ptr, 4); | |
186 break; | |
187 | |
188 case ID3_FIELD_TYPE_INT24: | |
189 if (length < 3) | |
190 goto fail; | |
191 | |
192 field->number.value = id3_parse_uint(ptr, 3); | |
193 break; | |
194 | |
195 case ID3_FIELD_TYPE_INT16: | |
196 if (length < 2) | |
197 goto fail; | |
198 | |
199 field->number.value = id3_parse_uint(ptr, 2); | |
200 break; | |
201 | |
202 case ID3_FIELD_TYPE_INT8: | |
203 case ID3_FIELD_TYPE_TEXTENCODING: | |
204 if (length < 1) | |
205 goto fail; | |
206 | |
207 field->number.value = id3_parse_uint(ptr, 1); | |
208 | |
209 if (field->type == ID3_FIELD_TYPE_TEXTENCODING) | |
210 *encoding = field->number.value; | |
211 break; | |
212 | |
213 case ID3_FIELD_TYPE_LANGUAGE: | |
214 if (length < 3) | |
215 goto fail; | |
216 | |
217 id3_parse_immediate(ptr, 3, field->immediate.value); | |
218 break; | |
219 | |
220 case ID3_FIELD_TYPE_FRAMEID: | |
221 if (length < 4) | |
222 goto fail; | |
223 | |
224 id3_parse_immediate(ptr, 4, field->immediate.value); | |
225 break; | |
226 | |
227 case ID3_FIELD_TYPE_DATE: | |
228 if (length < 8) | |
229 goto fail; | |
230 | |
231 id3_parse_immediate(ptr, 8, field->immediate.value); | |
232 break; | |
233 | |
234 case ID3_FIELD_TYPE_LATIN1: | |
235 case ID3_FIELD_TYPE_LATIN1FULL: | |
236 { | |
237 id3_latin1_t *latin1; | |
238 | |
239 latin1 = id3_parse_latin1(ptr, length, | |
240 field->type == ID3_FIELD_TYPE_LATIN1FULL); | |
241 if (latin1 == 0) | |
242 goto fail; | |
243 | |
244 field->latin1.ptr = latin1; | |
245 } | |
246 break; | |
247 | |
248 case ID3_FIELD_TYPE_LATIN1LIST: | |
249 { | |
250 id3_byte_t const *end; | |
251 id3_latin1_t *latin1, **strings; | |
252 | |
253 end = *ptr + length; | |
254 | |
255 while (end - *ptr > 0) { | |
256 latin1 = id3_parse_latin1(ptr, end - *ptr, 0); | |
257 if (latin1 == 0) | |
258 goto fail; | |
259 | |
260 strings = realloc(field->latin1list.strings, | |
261 (field->latin1list.nstrings + 1) * sizeof(*strings)); | |
262 if (strings == 0) { | |
263 free(latin1); | |
264 goto fail; | |
265 } | |
266 | |
267 field->latin1list.strings = strings; | |
268 field->latin1list.strings[field->latin1list.nstrings++] = latin1; | |
269 } | |
270 } | |
271 break; | |
272 | |
273 case ID3_FIELD_TYPE_STRING: | |
274 case ID3_FIELD_TYPE_STRINGFULL: | |
275 { | |
276 id3_ucs4_t *ucs4; | |
277 | |
278 ucs4 = id3_parse_string(ptr, length, *encoding, | |
279 field->type == ID3_FIELD_TYPE_STRINGFULL); | |
280 if (ucs4 == 0) | |
281 goto fail; | |
282 | |
283 field->string.ptr = ucs4; | |
284 } | |
285 break; | |
286 | |
287 case ID3_FIELD_TYPE_STRINGLIST: | |
288 { | |
289 id3_byte_t const *end; | |
290 id3_ucs4_t *ucs4, **strings; | |
291 | |
292 end = *ptr + length; | |
293 | |
294 while (end - *ptr > 0) { | |
295 ucs4 = id3_parse_string(ptr, end - *ptr, *encoding, 0); | |
296 if (ucs4 == 0) | |
297 goto fail; | |
298 | |
299 strings = realloc(field->stringlist.strings, | |
300 (field->stringlist.nstrings + 1) * sizeof(*strings)); | |
301 if (strings == 0) { | |
302 free(ucs4); | |
303 goto fail; | |
304 } | |
305 | |
306 field->stringlist.strings = strings; | |
307 field->stringlist.strings[field->stringlist.nstrings++] = ucs4; | |
308 } | |
309 } | |
310 break; | |
311 | |
312 case ID3_FIELD_TYPE_INT32PLUS: | |
313 case ID3_FIELD_TYPE_BINARYDATA: | |
314 { | |
315 id3_byte_t *data; | |
316 | |
317 data = id3_parse_binary(ptr, length); | |
318 if (data == 0) | |
319 goto fail; | |
320 | |
321 field->binary.data = data; | |
322 field->binary.length = length; | |
323 } | |
324 break; | |
325 } | |
326 | |
327 return 0; | |
328 | |
329 fail: | |
330 return -1; | |
331 } | |
332 | |
333 /* | |
334 * NAME: field->render() | |
335 * DESCRIPTION: render a field value | |
336 */ | |
337 id3_length_t id3_field_render(union id3_field const *field, id3_byte_t **ptr, | |
338 enum id3_field_textencoding *encoding, | |
339 int terminate) | |
340 { | |
341 id3_length_t size; | |
342 unsigned int i; | |
343 | |
344 assert(field && encoding); | |
345 | |
346 switch (field->type) { | |
347 case ID3_FIELD_TYPE_INT32: | |
348 return id3_render_int(ptr, field->number.value, 4); | |
349 | |
350 case ID3_FIELD_TYPE_INT24: | |
351 return id3_render_int(ptr, field->number.value, 3); | |
352 | |
353 case ID3_FIELD_TYPE_INT16: | |
354 return id3_render_int(ptr, field->number.value, 2); | |
355 | |
356 case ID3_FIELD_TYPE_TEXTENCODING: | |
357 *encoding = field->number.value; | |
358 case ID3_FIELD_TYPE_INT8: | |
359 return id3_render_int(ptr, field->number.value, 1); | |
360 | |
361 case ID3_FIELD_TYPE_LATIN1: | |
362 case ID3_FIELD_TYPE_LATIN1FULL: | |
363 return id3_render_latin1(ptr, field->latin1.ptr, terminate); | |
364 | |
365 case ID3_FIELD_TYPE_LATIN1LIST: | |
366 size = 0; | |
367 for (i = 0; i < field->latin1list.nstrings; ++i) { | |
368 size += id3_render_latin1(ptr, field->latin1list.strings[i], | |
369 (i < field->latin1list.nstrings - 1) || | |
370 terminate); | |
371 } | |
372 return size; | |
373 | |
374 case ID3_FIELD_TYPE_STRING: | |
375 case ID3_FIELD_TYPE_STRINGFULL: // here !! --yaz | |
376 return id3_render_string(ptr, field->string.ptr, *encoding, terminate); | |
377 | |
378 case ID3_FIELD_TYPE_STRINGLIST: | |
379 size = 0; | |
380 for (i = 0; i < field->stringlist.nstrings; ++i) { | |
381 size += id3_render_string(ptr, field->stringlist.strings[i], *encoding, | |
382 (i < field->stringlist.nstrings - 1) || | |
383 terminate); | |
384 } | |
385 return size; | |
386 | |
387 case ID3_FIELD_TYPE_LANGUAGE: | |
388 return id3_render_immediate(ptr, field->immediate.value, 3); | |
389 | |
390 case ID3_FIELD_TYPE_FRAMEID: | |
391 return id3_render_immediate(ptr, field->immediate.value, 4); | |
392 | |
393 case ID3_FIELD_TYPE_DATE: | |
394 return id3_render_immediate(ptr, field->immediate.value, 8); | |
395 | |
396 case ID3_FIELD_TYPE_INT32PLUS: | |
397 case ID3_FIELD_TYPE_BINARYDATA: | |
398 return id3_render_binary(ptr, field->binary.data, field->binary.length); | |
399 } | |
400 | |
401 return 0; | |
402 } | |
403 | |
404 /* | |
405 * NAME: field->setint() | |
406 * DESCRIPTION: set the value of an int field | |
407 */ | |
408 int id3_field_setint(union id3_field *field, signed long number) | |
409 { | |
410 assert(field); | |
411 | |
412 switch (field->type) { | |
413 case ID3_FIELD_TYPE_INT8: | |
414 if (number > 0x7f || number < -0x80) | |
415 return -1; | |
416 break; | |
417 | |
418 case ID3_FIELD_TYPE_INT16: | |
419 if (number > 0x7fff || number < -0x8000) | |
420 return -1; | |
421 break; | |
422 | |
423 case ID3_FIELD_TYPE_INT24: | |
424 if (number > 0x7fffffL || number < -0x800000L) | |
425 return -1; | |
426 break; | |
427 | |
428 case ID3_FIELD_TYPE_INT32: | |
429 if (number > 0x7fffffffL || number < -0x80000000L) | |
430 return -1; | |
431 break; | |
432 | |
433 default: | |
434 return -1; | |
435 } | |
436 | |
437 id3_field_finish(field); | |
438 | |
439 field->number.value = number; | |
440 | |
441 return 0; | |
442 } | |
443 | |
444 /* | |
445 * NAME: field->settextencoding() | |
446 * DESCRIPTION: set the value of a textencoding field | |
447 */ | |
448 int id3_field_settextencoding(union id3_field *field, | |
449 enum id3_field_textencoding encoding) | |
450 { | |
451 assert(field); | |
452 | |
453 printf("field type=%d ", field->type); | |
454 if (field->type != ID3_FIELD_TYPE_TEXTENCODING) { | |
455 printf("not textencoding\n"); | |
456 return -1; | |
457 } | |
458 | |
459 id3_field_finish(field); | |
460 | |
461 field->number.value = encoding; | |
462 | |
463 return 0; | |
464 } | |
465 | |
466 static | |
467 int set_latin1(union id3_field *field, id3_latin1_t const *latin1) | |
468 { | |
469 id3_latin1_t *data; | |
470 | |
471 if (latin1 == 0 || *latin1 == 0) | |
472 data = 0; | |
473 else { | |
474 data = id3_latin1_duplicate(latin1); | |
475 if (data == 0) | |
476 return -1; | |
477 } | |
478 | |
479 field->latin1.ptr = data; | |
480 | |
481 return 0; | |
482 } | |
483 | |
484 /* | |
485 * NAME: field->setlatin1() | |
486 * DESCRIPTION: set the value of a latin1 field | |
487 */ | |
488 int id3_field_setlatin1(union id3_field *field, id3_latin1_t const *latin1) | |
489 { | |
490 assert(field); | |
491 | |
492 if (field->type != ID3_FIELD_TYPE_LATIN1) | |
493 return -1; | |
494 | |
495 id3_field_finish(field); | |
496 | |
497 if (latin1) { | |
498 id3_latin1_t const *ptr; | |
499 | |
500 for (ptr = latin1; *ptr; ++ptr) { | |
501 if (*ptr == '\n') | |
502 return -1; | |
503 } | |
504 } | |
505 | |
506 return set_latin1(field, latin1); | |
507 } | |
508 | |
509 /* | |
510 * NAME: field->setfulllatin1() | |
511 * DESCRIPTION: set the value of a full latin1 field | |
512 */ | |
513 int id3_field_setfulllatin1(union id3_field *field, id3_latin1_t const *latin1) | |
514 { | |
515 assert(field); | |
516 | |
517 if (field->type != ID3_FIELD_TYPE_LATIN1FULL) | |
518 return -1; | |
519 | |
520 id3_field_finish(field); | |
521 | |
522 return set_latin1(field, latin1); | |
523 } | |
524 | |
525 static | |
526 int set_string(union id3_field *field, id3_ucs4_t const *string) | |
527 { | |
528 id3_ucs4_t *data; | |
529 | |
530 if (string == 0 || *string == 0) | |
531 data = 0; | |
532 else { | |
533 data = id3_ucs4_duplicate(string); | |
534 if (data == 0) | |
535 return -1; | |
536 } | |
537 | |
538 field->string.ptr = data; | |
539 | |
540 return 0; | |
541 } | |
542 | |
543 /* | |
544 * NAME: field->setstring() | |
545 * DESCRIPTION: set the value of a string field | |
546 */ | |
547 int id3_field_setstring(union id3_field *field, id3_ucs4_t const *string) | |
548 { | |
549 assert(field); | |
550 | |
551 if (field->type != ID3_FIELD_TYPE_STRING) | |
552 return -1; | |
553 | |
554 id3_field_finish(field); | |
555 | |
556 if (string) { | |
557 id3_ucs4_t const *ptr; | |
558 | |
559 for (ptr = string; *ptr; ++ptr) { | |
560 if (*ptr == '\n') | |
561 return -1; | |
562 } | |
563 } | |
564 | |
565 return set_string(field, string); | |
566 } | |
567 | |
568 /* | |
569 * NAME: field->setfullstring() | |
570 * DESCRIPTION: set the value of a full string field | |
571 */ | |
572 int id3_field_setfullstring(union id3_field *field, id3_ucs4_t const *string) | |
573 { | |
574 assert(field); | |
575 | |
576 if (field->type != ID3_FIELD_TYPE_STRINGFULL) | |
577 return -1; | |
578 | |
579 id3_field_finish(field); | |
580 | |
581 return set_string(field, string); | |
582 } | |
583 | |
584 /* | |
585 * NAME: field->setstrings() | |
586 * DESCRIPTION: set the value of a stringlist field | |
587 */ | |
588 int id3_field_setstrings(union id3_field *field, | |
589 unsigned int length, id3_ucs4_t **ptrs) | |
590 { | |
591 id3_ucs4_t **strings; | |
592 unsigned int i; | |
593 | |
594 assert(field); | |
595 | |
596 if (field->type != ID3_FIELD_TYPE_STRINGLIST) | |
597 return -1; | |
598 | |
599 id3_field_finish(field); | |
600 | |
601 if (length == 0) | |
602 return 0; | |
603 | |
604 strings = malloc(length * sizeof(*strings)); | |
605 if (strings == 0) | |
606 return -1; | |
607 | |
608 for (i = 0; i < length; ++i) { | |
609 strings[i] = id3_ucs4_duplicate(ptrs[i]); | |
610 if (strings[i] == 0) { | |
611 while (i--) | |
612 free(strings[i]); | |
613 | |
614 free(strings); | |
615 return -1; | |
616 } | |
617 } | |
618 | |
619 field->stringlist.strings = strings; | |
620 field->stringlist.nstrings = length; | |
621 | |
622 return 0; | |
623 } | |
624 | |
625 /* | |
626 * NAME: field->addstring() | |
627 * DESCRIPTION: add a string to a stringlist field | |
628 */ | |
629 int id3_field_addstring(union id3_field *field, id3_ucs4_t const *string) | |
630 { | |
631 id3_ucs4_t *new, **strings; | |
632 | |
633 assert(field); | |
634 | |
635 if (field->type != ID3_FIELD_TYPE_STRINGLIST) | |
636 return -1; | |
637 | |
638 if (string == 0) | |
639 string = id3_ucs4_empty; | |
640 | |
641 new = id3_ucs4_duplicate(string); | |
642 if (new == 0) | |
643 return -1; | |
644 | |
645 strings = realloc(field->stringlist.strings, | |
646 (field->stringlist.nstrings + 1) * sizeof(*strings)); | |
647 if (strings == 0) { | |
648 free(new); | |
649 return -1; | |
650 } | |
651 | |
652 field->stringlist.strings = strings; | |
653 field->stringlist.strings[field->stringlist.nstrings++] = new; | |
654 | |
655 return 0; | |
656 } | |
657 | |
658 /* | |
659 * NAME: field->setlanguage() | |
660 * DESCRIPTION: set the value of a language field | |
661 */ | |
662 int id3_field_setlanguage(union id3_field *field, char const *language) | |
663 { | |
664 assert(field); | |
665 | |
666 if (field->type != ID3_FIELD_TYPE_LANGUAGE) | |
667 return -1; | |
668 | |
669 id3_field_finish(field); | |
670 | |
671 if (language) { | |
672 if (strlen(language) != 3) | |
673 return -1; | |
674 | |
675 strcpy(field->immediate.value, language); | |
676 } | |
677 | |
678 return 0; | |
679 } | |
680 | |
681 /* | |
682 * NAME: field->setframeid() | |
683 * DESCRIPTION: set the value of a frameid field | |
684 */ | |
685 int id3_field_setframeid(union id3_field *field, char const *id) | |
686 { | |
687 assert(field); | |
688 | |
689 if (field->type != ID3_FIELD_TYPE_FRAMEID || | |
690 !id3_frame_validid(id)) | |
691 return -1; | |
692 | |
693 id3_field_finish(field); | |
694 | |
695 field->immediate.value[0] = id[0]; | |
696 field->immediate.value[1] = id[1]; | |
697 field->immediate.value[2] = id[2]; | |
698 field->immediate.value[3] = id[3]; | |
699 field->immediate.value[4] = 0; | |
700 | |
701 return 0; | |
702 } | |
703 | |
704 /* | |
705 * NAME: field->setbinarydata() | |
706 * DESCRIPTION: set the value of a binarydata field | |
707 */ | |
708 int id3_field_setbinarydata(union id3_field *field, | |
709 id3_byte_t const *data, id3_length_t length) | |
710 { | |
711 id3_byte_t *mem; | |
712 | |
713 assert(field); | |
714 | |
715 if (field->type != ID3_FIELD_TYPE_BINARYDATA) | |
716 return -1; | |
717 | |
718 id3_field_finish(field); | |
719 | |
720 if (length == 0) | |
721 mem = 0; | |
722 else { | |
723 mem = malloc(length); | |
724 if (mem == 0) | |
725 return -1; | |
726 | |
727 assert(data); | |
728 | |
729 memcpy(mem, data, length); | |
730 } | |
731 | |
732 field->binary.data = mem; | |
733 field->binary.length = length; | |
734 | |
735 return 0; | |
736 } | |
737 | |
738 /* | |
739 * NAME: field->getint() | |
740 * DESCRIPTION: return the value of an integer field | |
741 */ | |
742 signed long id3_field_getint(union id3_field const *field) | |
743 { | |
744 assert(field); | |
745 | |
746 if (field->type != ID3_FIELD_TYPE_INT8 && | |
747 field->type != ID3_FIELD_TYPE_INT16 && | |
748 field->type != ID3_FIELD_TYPE_INT24 && | |
749 field->type != ID3_FIELD_TYPE_INT32) | |
750 return -1; | |
751 | |
752 return field->number.value; | |
753 } | |
754 | |
755 /* | |
756 * NAME: field->gettextencoding() | |
757 * DESCRIPTION: return the value of a text encoding field | |
758 */ | |
759 enum id3_field_textencoding | |
760 id3_field_gettextencoding(union id3_field const *field) | |
761 { | |
762 assert(field); | |
763 | |
764 if (field->type != ID3_FIELD_TYPE_TEXTENCODING) | |
765 return -1; | |
766 | |
767 return field->number.value; | |
768 } | |
769 | |
770 /* | |
771 * NAME: field->getlatin1() | |
772 * DESCRIPTION: return the value of a latin1 field | |
773 */ | |
774 id3_latin1_t const *id3_field_getlatin1(union id3_field const *field) | |
775 { | |
776 assert(field); | |
777 | |
778 if (field->type != ID3_FIELD_TYPE_LATIN1) | |
779 return 0; | |
780 | |
781 return field->latin1.ptr ? field->latin1.ptr : (id3_latin1_t const *) ""; | |
782 } | |
783 | |
784 /* | |
785 * NAME: field->getfulllatin1() | |
786 * DESCRIPTION: return the value of a full latin1 field | |
787 */ | |
788 id3_latin1_t const *id3_field_getfulllatin1(union id3_field const *field) | |
789 { | |
790 assert(field); | |
791 | |
792 if (field->type != ID3_FIELD_TYPE_LATIN1FULL) | |
793 return 0; | |
794 | |
795 return field->latin1.ptr ? field->latin1.ptr : (id3_latin1_t const *) ""; | |
796 } | |
797 | |
798 /* | |
799 * NAME: field->getstring() | |
800 * DESCRIPTION: return the value of a string field | |
801 */ | |
802 id3_ucs4_t const *id3_field_getstring(union id3_field const *field) | |
803 { | |
804 assert(field); | |
805 | |
806 if (field->type != ID3_FIELD_TYPE_STRING) | |
807 return 0; | |
808 | |
809 return field->string.ptr ? field->string.ptr : id3_ucs4_empty; | |
810 } | |
811 | |
812 /* | |
813 * NAME: field->getfullstring() | |
814 * DESCRIPTION: return the value of a fullstring field | |
815 */ | |
816 id3_ucs4_t const *id3_field_getfullstring(union id3_field const *field) | |
817 { | |
818 assert(field); | |
819 | |
820 if (field->type != ID3_FIELD_TYPE_STRINGFULL) { | |
821 printf("not stringfull\n"); | |
822 return 0; | |
823 } | |
824 | |
825 return field->string.ptr ? field->string.ptr : id3_ucs4_empty; | |
826 } | |
827 | |
828 /* | |
829 * NAME: field->getnstrings() | |
830 * DESCRIPTION: return the number of strings in a stringlist field | |
831 */ | |
832 unsigned int id3_field_getnstrings(union id3_field const *field) | |
833 { | |
834 assert(field); | |
835 | |
836 if (field->type != ID3_FIELD_TYPE_STRINGLIST) | |
837 return 0; | |
838 | |
839 return field->stringlist.nstrings; | |
840 } | |
841 | |
842 /* | |
843 * NAME: field->getstrings() | |
844 * DESCRIPTION: return one value of a stringlist field | |
845 */ | |
846 id3_ucs4_t const *id3_field_getstrings(union id3_field const *field, | |
847 unsigned int index) | |
848 { | |
849 id3_ucs4_t const *string; | |
850 | |
851 assert(field); | |
852 | |
853 if (field->type != ID3_FIELD_TYPE_STRINGLIST || | |
854 index >= field->stringlist.nstrings) | |
855 return 0; | |
856 | |
857 string = field->stringlist.strings[index]; | |
858 | |
859 return string ? string : id3_ucs4_empty; | |
860 } | |
861 | |
862 /* | |
863 * NAME: field->getframeid() | |
864 * DESCRIPTION: return the value of a frameid field | |
865 */ | |
866 char const *id3_field_getframeid(union id3_field const *field) | |
867 { | |
868 assert(field); | |
869 | |
870 if (field->type != ID3_FIELD_TYPE_FRAMEID) | |
871 return 0; | |
872 | |
873 return field->immediate.value; | |
874 } | |
875 | |
876 /* | |
877 * NAME: field->getbinarydata() | |
878 * DESCRIPTION: return the value of a binarydata field | |
879 */ | |
880 id3_byte_t const *id3_field_getbinarydata(union id3_field const *field, | |
881 id3_length_t *length) | |
882 { | |
883 static id3_byte_t const empty; | |
884 | |
885 assert(field && length); | |
886 | |
887 if (field->type != ID3_FIELD_TYPE_BINARYDATA) | |
888 return 0; | |
889 | |
890 assert(field->binary.length == 0 || field->binary.data); | |
891 | |
892 *length = field->binary.length; | |
893 | |
894 return field->binary.data ? field->binary.data : ∅ | |
895 } |