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 */
47void 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 */
103void 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 */
162enum 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 */
173int 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 */
337id3_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 */
408int 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 */
448int 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
463static
464int 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 */
485int 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 */
510int 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
522static
523int 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 */
544int 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 */
569int 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 */
585int 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 */
626int 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 */
659int 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 */
682int 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 */
705int 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 */
739signed 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 */
756enum id3_field_textencoding
757id3_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 */
771id3_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 */
785id3_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 */
799id3_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 */
813id3_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 */
827unsigned 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 */
841id3_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 */
861char 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 */
875id3_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 : &empty;
890}
891