blob: 19b791570ba014bec885f1a439344b08b8f786cd [file] [log] [blame]
Marcoen Hirschberg2175d1e2007-06-16 18:19:51 +00001/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2005 Dave Chapman
11 *
Daniel Stenberg2acc0ac2008-06-28 18:10:04 +000012 * 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.
Marcoen Hirschberg2175d1e2007-06-16 18:19:51 +000016 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21#include <stdio.h>
22#include <string.h>
23#include <stdlib.h>
24#include <ctype.h>
25#include <inttypes.h>
26
27#include "system.h"
28#include "id3.h"
29#include "metadata_common.h"
30#include "metadata_parsers.h"
31#include "structec.h"
32#include "logf.h"
33
34/* Read the items in a Vorbis comment packet. Returns true the items were
35 * fully read, false otherwise.
36 */
37bool read_vorbis_tags(int fd, struct mp3entry *id3,
38 long tag_remaining)
39{
40 char *buf = id3->id3v2buf;
41 int32_t comment_count;
42 int32_t len;
43 int buf_remaining = sizeof(id3->id3v2buf) + sizeof(id3->id3v1buf);
44 int i;
45
46 if (ecread(fd, &len, 1, "l", IS_BIG_ENDIAN) < (long) sizeof(len))
47 {
48 return false;
49 }
50
51 if ((lseek(fd, len, SEEK_CUR) < 0)
52 || (ecread(fd, &comment_count, 1, "l", IS_BIG_ENDIAN)
53 < (long) sizeof(comment_count)))
54 {
55 return false;
56 }
57
58 tag_remaining -= len + sizeof(len) + sizeof(comment_count);
59
60 if (tag_remaining <= 0)
61 {
62 return true;
63 }
64
65 for (i = 0; i < comment_count; i++)
66 {
67 char name[TAG_NAME_LENGTH];
68 char value[TAG_VALUE_LENGTH];
69 int32_t read_len;
70
71 if (tag_remaining < 4)
72 {
73 break;
74 }
75
76 if (ecread(fd, &len, 1, "l", IS_BIG_ENDIAN) < (long) sizeof(len))
77 {
78 return false;
79 }
80
81 tag_remaining -= 4;
82
83 /* Quit if we've passed the end of the page */
84 if (tag_remaining < len)
85 {
86 break;
87 }
88
89 tag_remaining -= len;
90 read_len = read_string(fd, name, sizeof(name), '=', len);
91
92 if (read_len < 0)
93 {
94 return false;
95 }
96
97 len -= read_len;
98
99 if (read_string(fd, value, sizeof(value), -1, len) < 0)
100 {
101 return false;
102 }
103
104 len = parse_tag(name, value, id3, buf, buf_remaining,
105 TAGTYPE_VORBIS);
106 buf += len;
107 buf_remaining -= len;
108 }
109
110 /* Skip to the end of the block */
111 if (tag_remaining)
112 {
113 if (lseek(fd, tag_remaining, SEEK_CUR) < 0)
114 {
115 return false;
116 }
117 }
118
119 return true;
120}