cannam@85
|
1 /*
|
cannam@85
|
2 * libid3tag - ID3 tag manipulation library
|
cannam@85
|
3 * Copyright (C) 2000-2004 Underbit Technologies, Inc.
|
cannam@85
|
4 *
|
cannam@85
|
5 * This program is free software; you can redistribute it and/or modify
|
cannam@85
|
6 * it under the terms of the GNU General Public License as published by
|
cannam@85
|
7 * the Free Software Foundation; either version 2 of the License, or
|
cannam@85
|
8 * (at your option) any later version.
|
cannam@85
|
9 *
|
cannam@85
|
10 * This program is distributed in the hope that it will be useful,
|
cannam@85
|
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
cannam@85
|
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
cannam@85
|
13 * GNU General Public License for more details.
|
cannam@85
|
14 *
|
cannam@85
|
15 * You should have received a copy of the GNU General Public License
|
cannam@85
|
16 * along with this program; if not, write to the Free Software
|
cannam@85
|
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
cannam@85
|
18 *
|
cannam@85
|
19 * $Id: render.c,v 1.11 2004/01/23 09:41:32 rob Exp $
|
cannam@85
|
20 */
|
cannam@85
|
21
|
cannam@85
|
22 # ifdef HAVE_CONFIG_H
|
cannam@85
|
23 # include "config.h"
|
cannam@85
|
24 # endif
|
cannam@85
|
25
|
cannam@85
|
26 # include "global.h"
|
cannam@85
|
27
|
cannam@85
|
28 # include <string.h>
|
cannam@85
|
29 # include <stdlib.h>
|
cannam@85
|
30
|
cannam@85
|
31 # ifdef HAVE_ASSERT_H
|
cannam@85
|
32 # include <assert.h>
|
cannam@85
|
33 # endif
|
cannam@85
|
34
|
cannam@85
|
35 # include "id3tag.h"
|
cannam@85
|
36 # include "render.h"
|
cannam@85
|
37 # include "ucs4.h"
|
cannam@85
|
38 # include "latin1.h"
|
cannam@85
|
39 # include "utf16.h"
|
cannam@85
|
40 # include "utf8.h"
|
cannam@85
|
41
|
cannam@85
|
42 id3_length_t id3_render_immediate(id3_byte_t **ptr,
|
cannam@85
|
43 char const *value, unsigned int bytes)
|
cannam@85
|
44 {
|
cannam@85
|
45 assert(value);
|
cannam@85
|
46 assert(bytes == 8 || bytes == 4 || bytes == 3);
|
cannam@85
|
47
|
cannam@85
|
48 if (ptr) {
|
cannam@85
|
49 switch (bytes) {
|
cannam@85
|
50 case 8: *(*ptr)++ = *value++;
|
cannam@85
|
51 *(*ptr)++ = *value++;
|
cannam@85
|
52 *(*ptr)++ = *value++;
|
cannam@85
|
53 *(*ptr)++ = *value++;
|
cannam@85
|
54 case 4: *(*ptr)++ = *value++;
|
cannam@85
|
55 case 3: *(*ptr)++ = *value++;
|
cannam@85
|
56 *(*ptr)++ = *value++;
|
cannam@85
|
57 *(*ptr)++ = *value++;
|
cannam@85
|
58 }
|
cannam@85
|
59 }
|
cannam@85
|
60
|
cannam@85
|
61 return bytes;
|
cannam@85
|
62 }
|
cannam@85
|
63
|
cannam@85
|
64 id3_length_t id3_render_syncsafe(id3_byte_t **ptr,
|
cannam@85
|
65 unsigned long num, unsigned int bytes)
|
cannam@85
|
66 {
|
cannam@85
|
67 assert(bytes == 4 || bytes == 5);
|
cannam@85
|
68
|
cannam@85
|
69 if (ptr) {
|
cannam@85
|
70 switch (bytes) {
|
cannam@85
|
71 case 5: *(*ptr)++ = (num >> 28) & 0x0f;
|
cannam@85
|
72 case 4: *(*ptr)++ = (num >> 21) & 0x7f;
|
cannam@85
|
73 *(*ptr)++ = (num >> 14) & 0x7f;
|
cannam@85
|
74 *(*ptr)++ = (num >> 7) & 0x7f;
|
cannam@85
|
75 *(*ptr)++ = (num >> 0) & 0x7f;
|
cannam@85
|
76 }
|
cannam@85
|
77 }
|
cannam@85
|
78
|
cannam@85
|
79 return bytes;
|
cannam@85
|
80 }
|
cannam@85
|
81
|
cannam@85
|
82 id3_length_t id3_render_int(id3_byte_t **ptr,
|
cannam@85
|
83 signed long num, unsigned int bytes)
|
cannam@85
|
84 {
|
cannam@85
|
85 assert(bytes >= 1 && bytes <= 4);
|
cannam@85
|
86
|
cannam@85
|
87 if (ptr) {
|
cannam@85
|
88 switch (bytes) {
|
cannam@85
|
89 case 4: *(*ptr)++ = num >> 24;
|
cannam@85
|
90 case 3: *(*ptr)++ = num >> 16;
|
cannam@85
|
91 case 2: *(*ptr)++ = num >> 8;
|
cannam@85
|
92 case 1: *(*ptr)++ = num >> 0;
|
cannam@85
|
93 }
|
cannam@85
|
94 }
|
cannam@85
|
95
|
cannam@85
|
96 return bytes;
|
cannam@85
|
97 }
|
cannam@85
|
98
|
cannam@85
|
99 id3_length_t id3_render_binary(id3_byte_t **ptr,
|
cannam@85
|
100 id3_byte_t const *data, id3_length_t length)
|
cannam@85
|
101 {
|
cannam@85
|
102 if (data == 0)
|
cannam@85
|
103 return 0;
|
cannam@85
|
104
|
cannam@85
|
105 if (ptr) {
|
cannam@85
|
106 memcpy(*ptr, data, length);
|
cannam@85
|
107 *ptr += length;
|
cannam@85
|
108 }
|
cannam@85
|
109
|
cannam@85
|
110 return length;
|
cannam@85
|
111 }
|
cannam@85
|
112
|
cannam@85
|
113 id3_length_t id3_render_latin1(id3_byte_t **ptr,
|
cannam@85
|
114 id3_latin1_t const *latin1, int terminate)
|
cannam@85
|
115 {
|
cannam@85
|
116 id3_length_t size;
|
cannam@85
|
117
|
cannam@85
|
118 if (latin1 == 0)
|
cannam@85
|
119 latin1 = "";
|
cannam@85
|
120
|
cannam@85
|
121 size = id3_latin1_size(latin1);
|
cannam@85
|
122 if (!terminate)
|
cannam@85
|
123 --size;
|
cannam@85
|
124
|
cannam@85
|
125 if (ptr) {
|
cannam@85
|
126 memcpy(*ptr, latin1, size);
|
cannam@85
|
127 *ptr += size;
|
cannam@85
|
128 }
|
cannam@85
|
129
|
cannam@85
|
130 return size;
|
cannam@85
|
131 }
|
cannam@85
|
132
|
cannam@85
|
133 id3_length_t id3_render_string(id3_byte_t **ptr, id3_ucs4_t const *ucs4,
|
cannam@85
|
134 enum id3_field_textencoding encoding,
|
cannam@85
|
135 int terminate)
|
cannam@85
|
136 {
|
cannam@85
|
137 enum id3_utf16_byteorder byteorder = ID3_UTF16_BYTEORDER_ANY;
|
cannam@85
|
138
|
cannam@85
|
139 if (ucs4 == 0)
|
cannam@85
|
140 ucs4 = id3_ucs4_empty;
|
cannam@85
|
141
|
cannam@85
|
142 switch (encoding) {
|
cannam@85
|
143 case ID3_FIELD_TEXTENCODING_ISO_8859_1:
|
cannam@85
|
144 return id3_latin1_serialize(ptr, ucs4, terminate);
|
cannam@85
|
145
|
cannam@85
|
146 case ID3_FIELD_TEXTENCODING_UTF_16BE:
|
cannam@85
|
147 byteorder = ID3_UTF16_BYTEORDER_BE;
|
cannam@85
|
148 case ID3_FIELD_TEXTENCODING_UTF_16:
|
cannam@85
|
149 return id3_utf16_serialize(ptr, ucs4, byteorder, terminate);
|
cannam@85
|
150
|
cannam@85
|
151 case ID3_FIELD_TEXTENCODING_UTF_8:
|
cannam@85
|
152 return id3_utf8_serialize(ptr, ucs4, terminate);
|
cannam@85
|
153 }
|
cannam@85
|
154
|
cannam@85
|
155 return 0;
|
cannam@85
|
156 }
|
cannam@85
|
157
|
cannam@85
|
158 id3_length_t id3_render_padding(id3_byte_t **ptr, id3_byte_t value,
|
cannam@85
|
159 id3_length_t length)
|
cannam@85
|
160 {
|
cannam@85
|
161 if (ptr) {
|
cannam@85
|
162 memset(*ptr, value, length);
|
cannam@85
|
163 *ptr += length;
|
cannam@85
|
164 }
|
cannam@85
|
165
|
cannam@85
|
166 return length;
|
cannam@85
|
167 }
|
cannam@85
|
168
|
cannam@85
|
169 /*
|
cannam@85
|
170 * NAME: render->paddedstring()
|
cannam@85
|
171 * DESCRIPTION: render a space-padded string using latin1 encoding
|
cannam@85
|
172 */
|
cannam@85
|
173 id3_length_t id3_render_paddedstring(id3_byte_t **ptr, id3_ucs4_t const *ucs4,
|
cannam@85
|
174 id3_length_t length)
|
cannam@85
|
175 {
|
cannam@85
|
176 id3_ucs4_t padded[31], *data, *end;
|
cannam@85
|
177
|
cannam@85
|
178 /* latin1 encoding only (this is used for ID3v1 fields) */
|
cannam@85
|
179
|
cannam@85
|
180 assert(length <= 30);
|
cannam@85
|
181
|
cannam@85
|
182 data = padded;
|
cannam@85
|
183 end = data + length;
|
cannam@85
|
184
|
cannam@85
|
185 if (ucs4) {
|
cannam@85
|
186 while (*ucs4 && end - data > 0) {
|
cannam@85
|
187 *data++ = *ucs4++;
|
cannam@85
|
188
|
cannam@85
|
189 if (data[-1] == '\n')
|
cannam@85
|
190 data[-1] = ' ';
|
cannam@85
|
191 }
|
cannam@85
|
192 }
|
cannam@85
|
193
|
cannam@85
|
194 while (end - data > 0)
|
cannam@85
|
195 *data++ = ' ';
|
cannam@85
|
196
|
cannam@85
|
197 *data = 0;
|
cannam@85
|
198
|
cannam@85
|
199 return id3_latin1_serialize(ptr, padded, 0);
|
cannam@85
|
200 }
|