1/* C code produced by gperf version 3.0.3 */
2/* Command-line: gperf -tCcTonD -K id -N id3_compat_lookup -s -3 -k '*' compat.gperf  */
3
4#if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \
5      && ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \
6      && (')' == 41) && ('*' == 42) && ('+' == 43) && (',' == 44) \
7      && ('-' == 45) && ('.' == 46) && ('/' == 47) && ('0' == 48) \
8      && ('1' == 49) && ('2' == 50) && ('3' == 51) && ('4' == 52) \
9      && ('5' == 53) && ('6' == 54) && ('7' == 55) && ('8' == 56) \
10      && ('9' == 57) && (':' == 58) && (';' == 59) && ('<' == 60) \
11      && ('=' == 61) && ('>' == 62) && ('?' == 63) && ('A' == 65) \
12      && ('B' == 66) && ('C' == 67) && ('D' == 68) && ('E' == 69) \
13      && ('F' == 70) && ('G' == 71) && ('H' == 72) && ('I' == 73) \
14      && ('J' == 74) && ('K' == 75) && ('L' == 76) && ('M' == 77) \
15      && ('N' == 78) && ('O' == 79) && ('P' == 80) && ('Q' == 81) \
16      && ('R' == 82) && ('S' == 83) && ('T' == 84) && ('U' == 85) \
17      && ('V' == 86) && ('W' == 87) && ('X' == 88) && ('Y' == 89) \
18      && ('Z' == 90) && ('[' == 91) && ('\\' == 92) && (']' == 93) \
19      && ('^' == 94) && ('_' == 95) && ('a' == 97) && ('b' == 98) \
20      && ('c' == 99) && ('d' == 100) && ('e' == 101) && ('f' == 102) \
21      && ('g' == 103) && ('h' == 104) && ('i' == 105) && ('j' == 106) \
22      && ('k' == 107) && ('l' == 108) && ('m' == 109) && ('n' == 110) \
23      && ('o' == 111) && ('p' == 112) && ('q' == 113) && ('r' == 114) \
24      && ('s' == 115) && ('t' == 116) && ('u' == 117) && ('v' == 118) \
25      && ('w' == 119) && ('x' == 120) && ('y' == 121) && ('z' == 122) \
26      && ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126))
27/* The character set is not based on ISO-646.  */
28error "gperf generated tables don't work with this execution character set. Please report a bug to <bug-gnu-gperf@gnu.org>."
29#endif
30
31#line 1 "compat.gperf"
32
33/*
34 * libid3tag - ID3 tag manipulation library
35 * Copyright (C) 2000-2003 Underbit Technologies, Inc.
36 *
37 * This program is free software; you can redistribute it and/or modify
38 * it under the terms of the GNU General Public License as published by
39 * the Free Software Foundation; either version 2 of the License, or
40 * (at your option) any later version.
41 *
42 * This program is distributed in the hope that it will be useful,
43 * but WITHOUT ANY WARRANTY; without even the implied warranty of
44 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
45 * GNU General Public License for more details.
46 *
47 * You should have received a copy of the GNU General Public License
48 * along with this program; if not, write to the Free Software
49 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
50 *
51 * Id: compat.gperf,v 1.10 2003/04/19 00:14:33 rob Exp
52 */
53
54# ifdef HAVE_CONFIG_H
55#  include "config.h"
56# endif
57
58# include "global.h"
59
60# include <stdlib.h>
61# include <string.h>
62
63# ifdef HAVE_ASSERT_H
64#  include <assert.h>
65# endif
66
67# include "id3tag.h"
68# include "compat.h"
69# include "frame.h"
70# include "field.h"
71# include "parse.h"
72# include "ucs4.h"
73
74# define EQ(id)    #id, 0
75# define OBSOLETE    0, 0
76# define TX(id)    #id, translate_##id
77
78static id3_compat_func_t translate_TCON;
79
80#define TOTAL_KEYWORDS 73
81#define MIN_WORD_LENGTH 3
82#define MAX_WORD_LENGTH 4
83#define MIN_HASH_VALUE 6
84#define MAX_HASH_VALUE 127
85/* maximum key range = 122, duplicates = 0 */
86
87#ifdef __GNUC__
88__inline
89#else
90#ifdef __cplusplus
91inline
92#endif
93#endif
94static unsigned int
95hash (str, len)
96     register const char *str;
97     register unsigned int len;
98{
99  static const unsigned char asso_values[] =
100    {
101      128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
102      128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
103      128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
104      128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
105      128, 128, 128, 128, 128, 128, 128, 128, 128,  64,
106       58,  20,  15, 128, 128, 128, 128, 128, 128, 128,
107      128, 128, 128, 128, 128,  10,  18,   3,   6,   1,
108       47,   0, 128,  42,  62,  30,  31,   0,  19,  52,
109       10,  24,   8,  30,   5,   3,  30,   8,  25,  47,
110        3, 128, 128, 128, 128, 128, 128, 128, 128, 128,
111      128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
112      128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
113      128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
114      128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
115      128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
116      128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
117      128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
118      128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
119      128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
120      128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
121      128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
122      128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
123      128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
124      128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
125      128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
126      128, 128, 128, 128, 128, 128, 128
127    };
128  register int hval = 0;
129
130  switch (len)
131    {
132      default:
133        hval += asso_values[(unsigned char)str[3]];
134      /*FALLTHROUGH*/
135      case 3:
136        hval += asso_values[(unsigned char)str[2]];
137      /*FALLTHROUGH*/
138      case 2:
139        hval += asso_values[(unsigned char)str[1]+1];
140      /*FALLTHROUGH*/
141      case 1:
142        hval += asso_values[(unsigned char)str[0]];
143        break;
144    }
145  return hval;
146}
147
148#ifdef __GNUC__
149__inline
150#ifdef __GNUC_STDC_INLINE__
151__attribute__ ((__gnu_inline__))
152#endif
153#endif
154const struct id3_compat *
155id3_compat_lookup (str, len)
156     register const char *str;
157     register unsigned int len;
158{
159  static const struct id3_compat wordlist[] =
160    {
161#line 97 "compat.gperf"
162      {"TLE",  EQ(TLEN)  /* Length */},
163#line 68 "compat.gperf"
164      {"ETC",  EQ(ETCO)  /* Event timing codes */},
165#line 126 "compat.gperf"
166      {"ULT",  EQ(USLT)  /* Unsynchronised lyric/text transcription */},
167#line 123 "compat.gperf"
168      {"TYE",  OBSOLETE  /* Year [obsolete] */},
169#line 92 "compat.gperf"
170      {"TFT",  EQ(TFLT)  /* File type */},
171#line 84 "compat.gperf"
172      {"TCM",  EQ(TCOM)  /* Composer */},
173#line 66 "compat.gperf"
174      {"EQU",  OBSOLETE  /* Equalization [obsolete] */},
175#line 63 "compat.gperf"
176      {"COM",  EQ(COMM)  /* Comments */},
177#line 130 "compat.gperf"
178      {"WCM",  EQ(WCOM)  /* Commercial information */},
179#line 96 "compat.gperf"
180      {"TLA",  EQ(TLAN)  /* Language(s) */},
181#line 88 "compat.gperf"
182      {"TDA",  OBSOLETE  /* Date [obsolete] */},
183#line 124 "compat.gperf"
184      {"TYER", OBSOLETE  /* Year [obsolete] */},
185#line 83 "compat.gperf"
186      {"TBP",  EQ(TBPM)  /* BPM (beats per minute) */},
187#line 87 "compat.gperf"
188      {"TCR",  EQ(TCOP)  /* Copyright message */},
189#line 104 "compat.gperf"
190      {"TOT",  EQ(TOAL)  /* Original album/movie/show title */},
191#line 89 "compat.gperf"
192      {"TDAT", OBSOLETE  /* Date [obsolete] */},
193#line 67 "compat.gperf"
194      {"EQUA", OBSOLETE  /* Equalization [obsolete] */},
195#line 102 "compat.gperf"
196      {"TOR",  EQ(TDOR)  /* Original release year [obsolete] */},
197#line 131 "compat.gperf"
198      {"WCP",  EQ(WCOP)  /* Copyright/legal information */},
199#line 99 "compat.gperf"
200      {"TOA",  EQ(TOPE)  /* Original artist(s)/performer(s) */},
201#line 78 "compat.gperf"
202      {"RVA",  OBSOLETE  /* Relative volume adjustment [obsolete] */},
203#line 120 "compat.gperf"
204      {"TT3",  EQ(TIT3)  /* Subtitle/description refinement */},
205#line 98 "compat.gperf"
206      {"TMT",  EQ(TMED)  /* Media type */},
207#line 76 "compat.gperf"
208      {"POP",  EQ(POPM)  /* Popularimeter */},
209#line 74 "compat.gperf"
210      {"MLL",  EQ(MLLT)  /* MPEG location lookup table */},
211#line 79 "compat.gperf"
212      {"RVAD", OBSOLETE  /* Relative volume adjustment [obsolete] */},
213#line 65 "compat.gperf"
214      {"CRM",  OBSOLETE  /* Encrypted meta frame [obsolete] */},
215#line 128 "compat.gperf"
216      {"WAR",  EQ(WOAR)  /* Official artist/performer webpage */},
217#line 80 "compat.gperf"
218      {"SLT",  EQ(SYLT)  /* Synchronised lyric/text */},
219#line 81 "compat.gperf"
220      {"STC",  EQ(SYTC)  /* Synchronised tempo codes */},
221#line 95 "compat.gperf"
222      {"TKE",  EQ(TKEY)  /* Initial key */},
223#line 111 "compat.gperf"
224      {"TRC",  EQ(TSRC)  /* ISRC (international standard recording code) */},
225#line 109 "compat.gperf"
226      {"TPA",  EQ(TPOS)  /* Part of a set */},
227#line 117 "compat.gperf"
228      {"TSS",  EQ(TSSE)  /* Software/hardware and settings used for encoding */},
229#line 112 "compat.gperf"
230      {"TRD",  OBSOLETE  /* Recording dates [obsolete] */},
231#line 64 "compat.gperf"
232      {"CRA",  EQ(AENC)  /* Audio encryption */},
233#line 108 "compat.gperf"
234      {"TP4",  EQ(TPE4)  /* Interpreted, remixed, or otherwise modified by */},
235#line 125 "compat.gperf"
236      {"UFI",  EQ(UFID)  /* Unique file identifier */},
237#line 101 "compat.gperf"
238      {"TOL",  EQ(TOLY)  /* Original lyricist(s)/text writer(s) */},
239#line 110 "compat.gperf"
240      {"TPB",  EQ(TPUB)  /* Publisher */},
241#line 73 "compat.gperf"
242      {"MCI",  EQ(MCDI)  /* Music CD identifier */},
243#line 107 "compat.gperf"
244      {"TP3",  EQ(TPE3)  /* Conductor/performer refinement */},
245#line 132 "compat.gperf"
246      {"WPB",  EQ(WPUB)  /* Publishers official webpage */},
247#line 113 "compat.gperf"
248      {"TRDA", OBSOLETE  /* Recording dates [obsolete] */},
249#line 115 "compat.gperf"
250      {"TSI",  OBSOLETE  /* Size [obsolete] */},
251#line 90 "compat.gperf"
252      {"TDY",  EQ(TDLY)  /* Playlist delay */},
253#line 82 "compat.gperf"
254      {"TAL",  EQ(TALB)  /* Album/movie/show title */},
255#line 116 "compat.gperf"
256      {"TSIZ", OBSOLETE  /* Size [obsolete] */},
257#line 129 "compat.gperf"
258      {"WAS",  EQ(WOAS)  /* Official audio source webpage */},
259#line 121 "compat.gperf"
260      {"TXT",  EQ(TEXT)  /* Lyricist/text writer */},
261#line 62 "compat.gperf"
262      {"CNT",  EQ(PCNT)  /* Play counter */},
263#line 100 "compat.gperf"
264      {"TOF",  EQ(TOFN)  /* Original filename */},
265#line 85 "compat.gperf"
266      {"TCO",  TX(TCON)  /* Content type */},
267#line 114 "compat.gperf"
268      {"TRK",  EQ(TRCK)  /* Track number/position in set */},
269#line 119 "compat.gperf"
270      {"TT2",  EQ(TIT2)  /* Title/songname/content description */},
271#line 93 "compat.gperf"
272      {"TIM",  OBSOLETE  /* Time [obsolete] */},
273#line 94 "compat.gperf"
274      {"TIME", OBSOLETE  /* Time [obsolete] */},
275#line 103 "compat.gperf"
276      {"TORY", EQ(TDOR)  /* Original release year [obsolete] */},
277#line 91 "compat.gperf"
278      {"TEN",  EQ(TENC)  /* Encoded by */},
279#line 118 "compat.gperf"
280      {"TT1",  EQ(TIT1)  /* Content group description */},
281#line 127 "compat.gperf"
282      {"WAF",  EQ(WOAF)  /* Official audio file webpage */},
283#line 75 "compat.gperf"
284      {"PIC",  EQ(APIC)  /* Attached picture */},
285#line 122 "compat.gperf"
286      {"TXX",  EQ(TXXX)  /* User defined text information frame */},
287#line 133 "compat.gperf"
288      {"WXX",  EQ(WXXX)  /* User defined URL link frame */},
289#line 86 "compat.gperf"
290      {"TCON", TX(TCON)  /* Content type */},
291#line 77 "compat.gperf"
292      {"REV",  EQ(RVRB)  /* Reverb */},
293#line 106 "compat.gperf"
294      {"TP2",  EQ(TPE2)  /* Band/orchestra/accompaniment */},
295#line 105 "compat.gperf"
296      {"TP1",  EQ(TPE1)  /* Lead performer(s)/soloist(s) */},
297#line 61 "compat.gperf"
298      {"BUF",  EQ(RBUF)  /* Recommended buffer size */},
299#line 70 "compat.gperf"
300      {"IPL",  EQ(TIPL)  /* Involved people list */},
301#line 69 "compat.gperf"
302      {"GEO",  EQ(GEOB)  /* General encapsulated object */},
303#line 72 "compat.gperf"
304      {"LNK",  EQ(LINK)  /* Linked information */},
305#line 71 "compat.gperf"
306      {"IPLS", EQ(TIPL)  /* Involved people list */}
307    };
308
309  static const short lookup[] =
310    {
311      -1, -1, -1, -1, -1, -1,  0,  1,  2,  3,  4,  5,  6,  7,
312       8,  9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, -1,
313      21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34,
314      -1, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
315      48, 49, -1, -1, 50, -1, 51, 52, -1, 53, 54, 55, 56, -1,
316      57, 58, 59, 60, -1, 61, -1, 62, -1, -1, 63, -1, 64, -1,
317      -1, 65, -1, 66, -1, -1, -1, -1, -1, 67, -1, 68, -1, 69,
318      -1, 70, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
319      -1, 71, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
320      -1, 72
321    };
322
323  if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH)
324    {
325      register int key = hash (str, len);
326
327      if (key <= MAX_HASH_VALUE && key >= 0)
328        {
329          register int index = lookup[key];
330
331          if (index >= 0)
332            {
333              register const char *s = wordlist[index].id;
334
335              if (*str == *s && !strncmp (str + 1, s + 1, len - 1) && s[len] == '\0')
336                return &wordlist[index];
337            }
338        }
339    }
340  return 0;
341}
342#line 134 "compat.gperf"
343
344
345static
346int translate_TCON(struct id3_frame *frame, char const *oldid,
347		   id3_byte_t const *data, id3_length_t length)
348{
349  id3_byte_t const *end;
350  enum id3_field_textencoding encoding;
351  id3_ucs4_t *string = 0, *ptr, *endptr;
352  int result = 0;
353
354  /* translate old TCON syntax into multiple strings */
355
356  assert(frame->nfields == 2);
357
358  encoding = ID3_FIELD_TEXTENCODING_ISO_8859_1;
359
360  end = data + length;
361
362  if (id3_field_parse(&frame->fields[0], &data, end - data, &encoding) == -1)
363    goto fail;
364
365  string = id3_parse_string(&data, end - data, encoding, 0);
366  if (string == 0)
367    goto fail;
368
369  ptr = string;
370  while (*ptr == '(') {
371    if (*++ptr == '(')
372      break;
373
374    endptr = ptr;
375    while (*endptr && *endptr != ')')
376      ++endptr;
377
378    if (*endptr)
379      *endptr++ = 0;
380
381    if (id3_field_addstring(&frame->fields[1], ptr) == -1)
382      goto fail;
383
384    ptr = endptr;
385  }
386
387  if (*ptr && id3_field_addstring(&frame->fields[1], ptr) == -1)
388    goto fail;
389
390  if (0) {
391  fail:
392    result = -1;
393  }
394
395  if (string)
396    free(string);
397
398  return result;
399}
400
401/*
402 * NAME:	compat->fixup()
403 * DESCRIPTION:	finish compatibility translations
404 */
405int id3_compat_fixup(struct id3_tag *tag)
406{
407  struct id3_frame *frame;
408  unsigned int index;
409  id3_ucs4_t timestamp[17] = { 0 };
410  int result = 0;
411
412  /* create a TDRC frame from obsolete TYER/TDAT/TIME frames */
413
414  /*
415   * TYE/TYER: YYYY
416   * TDA/TDAT: DDMM
417   * TIM/TIME: HHMM
418   *
419   * TDRC: yyyy-MM-ddTHH:mm
420   */
421
422  index = 0;
423  while ((frame = id3_tag_findframe(tag, ID3_FRAME_OBSOLETE, index++))) {
424    char const *id;
425    id3_byte_t const *data, *end;
426    id3_length_t length;
427    enum id3_field_textencoding encoding;
428    id3_ucs4_t *string;
429
430    id = id3_field_getframeid(&frame->fields[0]);
431    assert(id);
432
433    if (strcmp(id, "TYER") != 0 && strcmp(id, "YTYE") != 0 &&
434	strcmp(id, "TDAT") != 0 && strcmp(id, "YTDA") != 0 &&
435	strcmp(id, "TIME") != 0 && strcmp(id, "YTIM") != 0)
436      continue;
437
438    data = id3_field_getbinarydata(&frame->fields[1], &length);
439    assert(data);
440
441    if (length < 1)
442      continue;
443
444    end = data + length;
445
446    encoding = id3_parse_uint(&data, 1);
447    string   = id3_parse_string(&data, end - data, encoding, 0);
448
449    if (id3_ucs4_length(string) < 4) {
450      free(string);
451      continue;
452    }
453
454    if (strcmp(id, "TYER") == 0 ||
455	strcmp(id, "YTYE") == 0) {
456      timestamp[0] = string[0];
457      timestamp[1] = string[1];
458      timestamp[2] = string[2];
459      timestamp[3] = string[3];
460    }
461    else if (strcmp(id, "TDAT") == 0 ||
462	     strcmp(id, "YTDA") == 0) {
463      timestamp[4] = '-';
464      timestamp[5] = string[2];
465      timestamp[6] = string[3];
466      timestamp[7] = '-';
467      timestamp[8] = string[0];
468      timestamp[9] = string[1];
469    }
470    else {  /* TIME or YTIM */
471      timestamp[10] = 'T';
472      timestamp[11] = string[0];
473      timestamp[12] = string[1];
474      timestamp[13] = ':';
475      timestamp[14] = string[2];
476      timestamp[15] = string[3];
477    }
478
479    free(string);
480  }
481
482  if (timestamp[0]) {
483    id3_ucs4_t *strings;
484
485    frame = id3_frame_new("TDRC");
486    if (frame == 0)
487      goto fail;
488
489    strings = timestamp;
490
491    if (id3_field_settextencoding(&frame->fields[0],
492				  ID3_FIELD_TEXTENCODING_ISO_8859_1) == -1 ||
493	id3_field_setstrings(&frame->fields[1], 1, &strings) == -1 ||
494	id3_tag_attachframe(tag, frame) == -1) {
495      id3_frame_delete(frame);
496      goto fail;
497    }
498  }
499
500  if (0) {
501  fail:
502    result = -1;
503  }
504
505  return result;
506}
507