Mercurial > hg > sv-dependency-builds
comparison src/libid3tag-0.15.1b/field.c @ 0:c7265573341e
Import initial set of sources
author | Chris Cannam |
---|---|
date | Mon, 18 Mar 2013 14:12:14 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:c7265573341e |
---|---|
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: | |
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 if (field->type != ID3_FIELD_TYPE_TEXTENCODING) | |
454 return -1; | |
455 | |
456 id3_field_finish(field); | |
457 | |
458 field->number.value = encoding; | |
459 | |
460 return 0; | |
461 } | |
462 | |
463 static | |
464 int set_latin1(union id3_field *field, id3_latin1_t const *latin1) | |
465 { | |
466 id3_latin1_t *data; | |
467 | |
468 if (latin1 == 0 || *latin1 == 0) | |
469 data = 0; | |
470 else { | |
471 data = id3_latin1_duplicate(latin1); | |
472 if (data == 0) | |
473 return -1; | |
474 } | |
475 | |
476 field->latin1.ptr = data; | |
477 | |
478 return 0; | |
479 } | |
480 | |
481 /* | |
482 * NAME: field->setlatin1() | |
483 * DESCRIPTION: set the value of a latin1 field | |
484 */ | |
485 int id3_field_setlatin1(union id3_field *field, id3_latin1_t const *latin1) | |
486 { | |
487 assert(field); | |
488 | |
489 if (field->type != ID3_FIELD_TYPE_LATIN1) | |
490 return -1; | |
491 | |
492 id3_field_finish(field); | |
493 | |
494 if (latin1) { | |
495 id3_latin1_t const *ptr; | |
496 | |
497 for (ptr = latin1; *ptr; ++ptr) { | |
498 if (*ptr == '\n') | |
499 return -1; | |
500 } | |
501 } | |
502 | |
503 return set_latin1(field, latin1); | |
504 } | |
505 | |
506 /* | |
507 * NAME: field->setfulllatin1() | |
508 * DESCRIPTION: set the value of a full latin1 field | |
509 */ | |
510 int id3_field_setfulllatin1(union id3_field *field, id3_latin1_t const *latin1) | |
511 { | |
512 assert(field); | |
513 | |
514 if (field->type != ID3_FIELD_TYPE_LATIN1FULL) | |
515 return -1; | |
516 | |
517 id3_field_finish(field); | |
518 | |
519 return set_latin1(field, latin1); | |
520 } | |
521 | |
522 static | |
523 int set_string(union id3_field *field, id3_ucs4_t const *string) | |
524 { | |
525 id3_ucs4_t *data; | |
526 | |
527 if (string == 0 || *string == 0) | |
528 data = 0; | |
529 else { | |
530 data = id3_ucs4_duplicate(string); | |
531 if (data == 0) | |
532 return -1; | |
533 } | |
534 | |
535 field->string.ptr = data; | |
536 | |
537 return 0; | |
538 } | |
539 | |
540 /* | |
541 * NAME: field->setstring() | |
542 * DESCRIPTION: set the value of a string field | |
543 */ | |
544 int id3_field_setstring(union id3_field *field, id3_ucs4_t const *string) | |
545 { | |
546 assert(field); | |
547 | |
548 if (field->type != ID3_FIELD_TYPE_STRING) | |
549 return -1; | |
550 | |
551 id3_field_finish(field); | |
552 | |
553 if (string) { | |
554 id3_ucs4_t const *ptr; | |
555 | |
556 for (ptr = string; *ptr; ++ptr) { | |
557 if (*ptr == '\n') | |
558 return -1; | |
559 } | |
560 } | |
561 | |
562 return set_string(field, string); | |
563 } | |
564 | |
565 /* | |
566 * NAME: field->setfullstring() | |
567 * DESCRIPTION: set the value of a full string field | |
568 */ | |
569 int id3_field_setfullstring(union id3_field *field, id3_ucs4_t const *string) | |
570 { | |
571 assert(field); | |
572 | |
573 if (field->type != ID3_FIELD_TYPE_STRINGFULL) | |
574 return -1; | |
575 | |
576 id3_field_finish(field); | |
577 | |
578 return set_string(field, string); | |
579 } | |
580 | |
581 /* | |
582 * NAME: field->setstrings() | |
583 * DESCRIPTION: set the value of a stringlist field | |
584 */ | |
585 int id3_field_setstrings(union id3_field *field, | |
586 unsigned int length, id3_ucs4_t **ptrs) | |
587 { | |
588 id3_ucs4_t **strings; | |
589 unsigned int i; | |
590 | |
591 assert(field); | |
592 | |
593 if (field->type != ID3_FIELD_TYPE_STRINGLIST) | |
594 return -1; | |
595 | |
596 id3_field_finish(field); | |
597 | |
598 if (length == 0) | |
599 return 0; | |
600 | |
601 strings = malloc(length * sizeof(*strings)); | |
602 if (strings == 0) | |
603 return -1; | |
604 | |
605 for (i = 0; i < length; ++i) { | |
606 strings[i] = id3_ucs4_duplicate(ptrs[i]); | |
607 if (strings[i] == 0) { | |
608 while (i--) | |
609 free(strings[i]); | |
610 | |
611 free(strings); | |
612 return -1; | |
613 } | |
614 } | |
615 | |
616 field->stringlist.strings = strings; | |
617 field->stringlist.nstrings = length; | |
618 | |
619 return 0; | |
620 } | |
621 | |
622 /* | |
623 * NAME: field->addstring() | |
624 * DESCRIPTION: add a string to a stringlist field | |
625 */ | |
626 int id3_field_addstring(union id3_field *field, id3_ucs4_t const *string) | |
627 { | |
628 id3_ucs4_t *new, **strings; | |
629 | |
630 assert(field); | |
631 | |
632 if (field->type != ID3_FIELD_TYPE_STRINGLIST) | |
633 return -1; | |
634 | |
635 if (string == 0) | |
636 string = id3_ucs4_empty; | |
637 | |
638 new = id3_ucs4_duplicate(string); | |
639 if (new == 0) | |
640 return -1; | |
641 | |
642 strings = realloc(field->stringlist.strings, | |
643 (field->stringlist.nstrings + 1) * sizeof(*strings)); | |
644 if (strings == 0) { | |
645 free(new); | |
646 return -1; | |
647 } | |
648 | |
649 field->stringlist.strings = strings; | |
650 field->stringlist.strings[field->stringlist.nstrings++] = new; | |
651 | |
652 return 0; | |
653 } | |
654 | |
655 /* | |
656 * NAME: field->setlanguage() | |
657 * DESCRIPTION: set the value of a language field | |
658 */ | |
659 int id3_field_setlanguage(union id3_field *field, char const *language) | |
660 { | |
661 assert(field); | |
662 | |
663 if (field->type != ID3_FIELD_TYPE_LANGUAGE) | |
664 return -1; | |
665 | |
666 id3_field_finish(field); | |
667 | |
668 if (language) { | |
669 if (strlen(language) != 3) | |
670 return -1; | |
671 | |
672 strcpy(field->immediate.value, language); | |
673 } | |
674 | |
675 return 0; | |
676 } | |
677 | |
678 /* | |
679 * NAME: field->setframeid() | |
680 * DESCRIPTION: set the value of a frameid field | |
681 */ | |
682 int id3_field_setframeid(union id3_field *field, char const *id) | |
683 { | |
684 assert(field); | |
685 | |
686 if (field->type != ID3_FIELD_TYPE_FRAMEID || | |
687 !id3_frame_validid(id)) | |
688 return -1; | |
689 | |
690 id3_field_finish(field); | |
691 | |
692 field->immediate.value[0] = id[0]; | |
693 field->immediate.value[1] = id[1]; | |
694 field->immediate.value[2] = id[2]; | |
695 field->immediate.value[3] = id[3]; | |
696 field->immediate.value[4] = 0; | |
697 | |
698 return 0; | |
699 } | |
700 | |
701 /* | |
702 * NAME: field->setbinarydata() | |
703 * DESCRIPTION: set the value of a binarydata field | |
704 */ | |
705 int id3_field_setbinarydata(union id3_field *field, | |
706 id3_byte_t const *data, id3_length_t length) | |
707 { | |
708 id3_byte_t *mem; | |
709 | |
710 assert(field); | |
711 | |
712 if (field->type != ID3_FIELD_TYPE_BINARYDATA) | |
713 return -1; | |
714 | |
715 id3_field_finish(field); | |
716 | |
717 if (length == 0) | |
718 mem = 0; | |
719 else { | |
720 mem = malloc(length); | |
721 if (mem == 0) | |
722 return -1; | |
723 | |
724 assert(data); | |
725 | |
726 memcpy(mem, data, length); | |
727 } | |
728 | |
729 field->binary.data = mem; | |
730 field->binary.length = length; | |
731 | |
732 return 0; | |
733 } | |
734 | |
735 /* | |
736 * NAME: field->getint() | |
737 * DESCRIPTION: return the value of an integer field | |
738 */ | |
739 signed long id3_field_getint(union id3_field const *field) | |
740 { | |
741 assert(field); | |
742 | |
743 if (field->type != ID3_FIELD_TYPE_INT8 && | |
744 field->type != ID3_FIELD_TYPE_INT16 && | |
745 field->type != ID3_FIELD_TYPE_INT24 && | |
746 field->type != ID3_FIELD_TYPE_INT32) | |
747 return -1; | |
748 | |
749 return field->number.value; | |
750 } | |
751 | |
752 /* | |
753 * NAME: field->gettextencoding() | |
754 * DESCRIPTION: return the value of a text encoding field | |
755 */ | |
756 enum id3_field_textencoding | |
757 id3_field_gettextencoding(union id3_field const *field) | |
758 { | |
759 assert(field); | |
760 | |
761 if (field->type != ID3_FIELD_TYPE_TEXTENCODING) | |
762 return -1; | |
763 | |
764 return field->number.value; | |
765 } | |
766 | |
767 /* | |
768 * NAME: field->getlatin1() | |
769 * DESCRIPTION: return the value of a latin1 field | |
770 */ | |
771 id3_latin1_t const *id3_field_getlatin1(union id3_field const *field) | |
772 { | |
773 assert(field); | |
774 | |
775 if (field->type != ID3_FIELD_TYPE_LATIN1) | |
776 return 0; | |
777 | |
778 return field->latin1.ptr ? field->latin1.ptr : (id3_latin1_t const *) ""; | |
779 } | |
780 | |
781 /* | |
782 * NAME: field->getfulllatin1() | |
783 * DESCRIPTION: return the value of a full latin1 field | |
784 */ | |
785 id3_latin1_t const *id3_field_getfulllatin1(union id3_field const *field) | |
786 { | |
787 assert(field); | |
788 | |
789 if (field->type != ID3_FIELD_TYPE_LATIN1FULL) | |
790 return 0; | |
791 | |
792 return field->latin1.ptr ? field->latin1.ptr : (id3_latin1_t const *) ""; | |
793 } | |
794 | |
795 /* | |
796 * NAME: field->getstring() | |
797 * DESCRIPTION: return the value of a string field | |
798 */ | |
799 id3_ucs4_t const *id3_field_getstring(union id3_field const *field) | |
800 { | |
801 assert(field); | |
802 | |
803 if (field->type != ID3_FIELD_TYPE_STRING) | |
804 return 0; | |
805 | |
806 return field->string.ptr ? field->string.ptr : id3_ucs4_empty; | |
807 } | |
808 | |
809 /* | |
810 * NAME: field->getfullstring() | |
811 * DESCRIPTION: return the value of a fullstring field | |
812 */ | |
813 id3_ucs4_t const *id3_field_getfullstring(union id3_field const *field) | |
814 { | |
815 assert(field); | |
816 | |
817 if (field->type != ID3_FIELD_TYPE_STRINGFULL) | |
818 return 0; | |
819 | |
820 return field->string.ptr ? field->string.ptr : id3_ucs4_empty; | |
821 } | |
822 | |
823 /* | |
824 * NAME: field->getnstrings() | |
825 * DESCRIPTION: return the number of strings in a stringlist field | |
826 */ | |
827 unsigned int id3_field_getnstrings(union id3_field const *field) | |
828 { | |
829 assert(field); | |
830 | |
831 if (field->type != ID3_FIELD_TYPE_STRINGLIST) | |
832 return 0; | |
833 | |
834 return field->stringlist.nstrings; | |
835 } | |
836 | |
837 /* | |
838 * NAME: field->getstrings() | |
839 * DESCRIPTION: return one value of a stringlist field | |
840 */ | |
841 id3_ucs4_t const *id3_field_getstrings(union id3_field const *field, | |
842 unsigned int index) | |
843 { | |
844 id3_ucs4_t const *string; | |
845 | |
846 assert(field); | |
847 | |
848 if (field->type != ID3_FIELD_TYPE_STRINGLIST || | |
849 index >= field->stringlist.nstrings) | |
850 return 0; | |
851 | |
852 string = field->stringlist.strings[index]; | |
853 | |
854 return string ? string : id3_ucs4_empty; | |
855 } | |
856 | |
857 /* | |
858 * NAME: field->getframeid() | |
859 * DESCRIPTION: return the value of a frameid field | |
860 */ | |
861 char const *id3_field_getframeid(union id3_field const *field) | |
862 { | |
863 assert(field); | |
864 | |
865 if (field->type != ID3_FIELD_TYPE_FRAMEID) | |
866 return 0; | |
867 | |
868 return field->immediate.value; | |
869 } | |
870 | |
871 /* | |
872 * NAME: field->getbinarydata() | |
873 * DESCRIPTION: return the value of a binarydata field | |
874 */ | |
875 id3_byte_t const *id3_field_getbinarydata(union id3_field const *field, | |
876 id3_length_t *length) | |
877 { | |
878 static id3_byte_t const empty; | |
879 | |
880 assert(field && length); | |
881 | |
882 if (field->type != ID3_FIELD_TYPE_BINARYDATA) | |
883 return 0; | |
884 | |
885 assert(field->binary.length == 0 || field->binary.data); | |
886 | |
887 *length = field->binary.length; | |
888 | |
889 return field->binary.data ? field->binary.data : ∅ | |
890 } |