comparison src/libid3tag/parse.c @ 2503:10692383c103 trunk

[svn] first try for libid3tag integration. this improved libid3tag supports vfs operations and is capable of adding id3v2 tag to files which doesn't have id3v2 tag ever.
author yaz
date Sun, 11 Feb 2007 05:19:07 -0800
parents
children
comparison
equal deleted inserted replaced
2502:b7be0af74307 2503:10692383c103
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: parse.c,v 1.9 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 # ifdef HAVE_ASSERT_H
29 # include <assert.h>
30 # endif
31
32 # include <stdlib.h>
33 # include <string.h>
34
35 # include "id3tag.h"
36 # include "parse.h"
37 # include "latin1.h"
38 # include "utf16.h"
39 # include "utf8.h"
40
41 signed long id3_parse_int(id3_byte_t const **ptr, unsigned int bytes)
42 {
43 signed long value = 0;
44
45 assert(bytes >= 1 && bytes <= 4);
46
47 if (**ptr & 0x80)
48 value = ~0;
49
50 switch (bytes) {
51 case 4: value = (value << 8) | *(*ptr)++;
52 case 3: value = (value << 8) | *(*ptr)++;
53 case 2: value = (value << 8) | *(*ptr)++;
54 case 1: value = (value << 8) | *(*ptr)++;
55 }
56
57 return value;
58 }
59
60 unsigned long id3_parse_uint(id3_byte_t const **ptr, unsigned int bytes)
61 {
62 unsigned long value = 0;
63
64 assert(bytes >= 1 && bytes <= 4);
65
66 switch (bytes) {
67 case 4: value = (value << 8) | *(*ptr)++;
68 case 3: value = (value << 8) | *(*ptr)++;
69 case 2: value = (value << 8) | *(*ptr)++;
70 case 1: value = (value << 8) | *(*ptr)++;
71 }
72
73 return value;
74 }
75
76 unsigned long id3_parse_syncsafe(id3_byte_t const **ptr, unsigned int bytes)
77 {
78 unsigned long value = 0;
79
80 assert(bytes == 4 || bytes == 5);
81
82 switch (bytes) {
83 case 5: value = (value << 4) | (*(*ptr)++ & 0x0f);
84 case 4: value = (value << 7) | (*(*ptr)++ & 0x7f);
85 value = (value << 7) | (*(*ptr)++ & 0x7f);
86 value = (value << 7) | (*(*ptr)++ & 0x7f);
87 value = (value << 7) | (*(*ptr)++ & 0x7f);
88 }
89
90 return value;
91 }
92
93 void id3_parse_immediate(id3_byte_t const **ptr, unsigned int bytes,
94 char *value)
95 {
96 assert(value);
97 assert(bytes == 8 || bytes == 4 || bytes == 3);
98
99 switch (bytes) {
100 case 8: *value++ = *(*ptr)++;
101 *value++ = *(*ptr)++;
102 *value++ = *(*ptr)++;
103 *value++ = *(*ptr)++;
104 case 4: *value++ = *(*ptr)++;
105 case 3: *value++ = *(*ptr)++;
106 *value++ = *(*ptr)++;
107 *value++ = *(*ptr)++;
108 }
109
110 *value = 0;
111 }
112
113 id3_latin1_t *id3_parse_latin1(id3_byte_t const **ptr, id3_length_t length,
114 int full)
115 {
116 id3_byte_t const *end;
117 int terminated = 0;
118 id3_latin1_t *latin1;
119
120 end = memchr(*ptr, 0, length);
121 if (end == 0)
122 end = *ptr + length;
123 else {
124 length = end - *ptr;
125 terminated = 1;
126 }
127
128 latin1 = malloc(length + 1);
129 if (latin1) {
130 memcpy(latin1, *ptr, length);
131 latin1[length] = 0;
132
133 if (!full) {
134 id3_latin1_t *check;
135
136 for (check = latin1; *check; ++check) {
137 if (*check == '\n')
138 *check = ' ';
139 }
140 }
141 }
142
143 *ptr += length + terminated;
144
145 return latin1;
146 }
147
148 id3_ucs4_t *id3_parse_string(id3_byte_t const **ptr, id3_length_t length,
149 enum id3_field_textencoding encoding, int full)
150 {
151 id3_ucs4_t *ucs4 = 0;
152 enum id3_utf16_byteorder byteorder = ID3_UTF16_BYTEORDER_ANY;
153
154 switch (encoding) {
155 case ID3_FIELD_TEXTENCODING_ISO_8859_1:
156 ucs4 = id3_latin1_deserialize(ptr, length);
157 break;
158
159 case ID3_FIELD_TEXTENCODING_UTF_16BE:
160 byteorder = ID3_UTF16_BYTEORDER_BE;
161 case ID3_FIELD_TEXTENCODING_UTF_16:
162 ucs4 = id3_utf16_deserialize(ptr, length, byteorder);
163 break;
164
165 case ID3_FIELD_TEXTENCODING_UTF_8:
166 ucs4 = id3_utf8_deserialize(ptr, length);
167 break;
168 }
169
170 if (ucs4 && !full) {
171 id3_ucs4_t *check;
172
173 for (check = ucs4; *check; ++check) {
174 if (*check == '\n')
175 *check = ' ';
176 }
177 }
178
179 return ucs4;
180 }
181
182 id3_byte_t *id3_parse_binary(id3_byte_t const **ptr, id3_length_t length)
183 {
184 id3_byte_t *data;
185
186 if (length == 0)
187 return malloc(1);
188
189 data = malloc(length);
190 if (data)
191 memcpy(data, *ptr, length);
192
193 *ptr += length;
194
195 return data;
196 }