1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2008 Dominik Wenger
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
29 #include "metadata_common.h"
30 #include "metadata_parsers.h"
31 #include "rbunicode.h"
36 static bool parse_dec(int *retval
, const char *p
, int minval
, int maxval
)
41 if (c
>= '0' && c
<= '9')
47 } while (*++p
!= '\0');
54 static bool parse_text(char *retval
, const char *p
)
60 if (p
[0] == '<' && p
[1] == '?' && p
[2] == '>' && p
[3] == '"')
74 static int ASAP_ParseDuration(const char *s
)
77 if (*s
< '0' || *s
> '9')
80 if (*s
>= '0' && *s
<= '9')
81 r
= 10 * r
+ *s
++ - '0';
84 if (*s
< '0' || *s
> '5')
86 r
= 60 * r
+ (*s
++ - '0') * 10;
87 if (*s
< '0' || *s
> '9')
95 if (*s
< '0' || *s
> '9')
97 r
+= 100 * (*s
++ - '0');
98 if (*s
< '0' || *s
> '9')
100 r
+= 10 * (*s
++ - '0');
101 if (*s
< '0' || *s
> '9')
107 static bool read_asap_string(char* source
, char** buf
, char** buffer_end
, char** dest
)
109 if(parse_text(*buf
,source
) == false)
112 /* set dest pointer */
116 *buf
+= strlen(*buf
)+1;
119 if(*buf
>= *buffer_end
)
121 DEBUGF("Buffer full\n");
127 static bool parse_sap_header(int fd
, struct mp3entry
* id3
, int file_len
)
129 int module_index
= 0;
130 int sap_signature
= -1;
131 int duration_index
= 0;
132 unsigned char cur_char
= 0;
138 int durations
[MAX_SONGS
];
139 for (i
= 0; i
< MAX_SONGS
; i
++)
142 /* use id3v2 buffer for our strings */
143 char* buffer
= id3
->id3v2buf
;
144 char* buffer_end
= id3
->id3v2buf
+ ID3V2_BUF_SIZE
;
152 if (module_index
+ 8 >= file_len
)
155 read(fd
,&cur_char
,1);
157 if (cur_char
== 0xff)
161 while (cur_char
!= 0x0d)
163 line
[i
++] = cur_char
;
165 if (module_index
>= file_len
|| (unsigned)i
>= sizeof(line
) - 1)
168 read(fd
,&cur_char
,1);
170 if (++module_index
>= file_len
)
173 read(fd
,&cur_char
,1);
174 if ( cur_char
!= 0x0a)
178 for (p
= line
; *p
!= '\0'; p
++) {
186 if(strcmp(line
, "SAP") == 0)
188 if (sap_signature
== -1)
190 if (strcmp(line
, "AUTHOR") == 0)
192 if(read_asap_string(p
, &buffer
, &buffer_end
, &id3
->artist
) == false)
195 else if(strcmp(line
, "NAME") == 0)
197 if(read_asap_string(p
, &buffer
, &buffer_end
, &id3
->title
) == false)
200 else if(strcmp(line
, "DATE") == 0)
202 if(read_asap_string(p
, &buffer
, &buffer_end
, &id3
->year_string
) == false)
205 else if (strcmp(line
, "SONGS") == 0)
207 if (parse_dec(&numSongs
, p
, 1, MAX_SONGS
) == false )
210 else if (strcmp(line
, "DEFSONG") == 0)
212 if (parse_dec(&defSong
, p
, 0, MAX_SONGS
) == false)
215 else if (strcmp(line
, "TIME") == 0)
217 int durationTemp
= ASAP_ParseDuration(p
);
218 if (durationTemp
< 0 || duration_index
>= MAX_SONGS
)
220 durations
[duration_index
++] = durationTemp
;
225 int length
= durations
[defSong
];
228 id3
->length
= length
;
230 lseek(fd
, 0, SEEK_SET
);
235 bool get_asap_metadata(int fd
, struct mp3entry
* id3
)
238 int filelength
= filesize(fd
);
240 if(parse_sap_header(fd
, id3
, filelength
) == false)
242 DEBUGF("parse sap header failed.\n");
247 id3
->frequency
= 44100;
250 id3
->filesize
= filelength
;