Mercurial > audlegacy-plugins
annotate src/demac/apev2.c @ 3047:4434b4c4a715
ported EsounD plugin
author | Andrew O. Shadoura <bugzilla@tut.by> |
---|---|
date | Fri, 17 Apr 2009 16:17:10 +0300 |
parents | 3134a0987162 |
children |
rev | line source |
---|---|
2182
cc5e9ec110a4
Added initial version of Monkey's Audio plugin
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
1 /* |
cc5e9ec110a4
Added initial version of Monkey's Audio plugin
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
2 * Audacious Monkey's Audio plugin, an APE tag reading stuff |
cc5e9ec110a4
Added initial version of Monkey's Audio plugin
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
3 * |
cc5e9ec110a4
Added initial version of Monkey's Audio plugin
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
4 * Copyright (C) Eugene Zagidullin 2007 |
cc5e9ec110a4
Added initial version of Monkey's Audio plugin
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
5 * |
cc5e9ec110a4
Added initial version of Monkey's Audio plugin
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
6 * This program is free software; you can redistribute it and/or modify |
cc5e9ec110a4
Added initial version of Monkey's Audio plugin
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
7 * it under the terms of the GNU General Public License as published by |
cc5e9ec110a4
Added initial version of Monkey's Audio plugin
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
8 * the Free Software Foundation; either version 2 of the License, or |
cc5e9ec110a4
Added initial version of Monkey's Audio plugin
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
9 * (at your option) any later version. |
cc5e9ec110a4
Added initial version of Monkey's Audio plugin
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
10 * |
cc5e9ec110a4
Added initial version of Monkey's Audio plugin
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
11 * This program is distributed in the hope that it will be useful, |
cc5e9ec110a4
Added initial version of Monkey's Audio plugin
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
cc5e9ec110a4
Added initial version of Monkey's Audio plugin
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
cc5e9ec110a4
Added initial version of Monkey's Audio plugin
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
14 * GNU General Public License for more details. |
cc5e9ec110a4
Added initial version of Monkey's Audio plugin
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
15 * |
cc5e9ec110a4
Added initial version of Monkey's Audio plugin
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
16 * You should have received a copy of the GNU General Public License |
cc5e9ec110a4
Added initial version of Monkey's Audio plugin
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
17 * along with this program; if not, write to the Free Software |
cc5e9ec110a4
Added initial version of Monkey's Audio plugin
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA |
cc5e9ec110a4
Added initial version of Monkey's Audio plugin
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
19 * |
cc5e9ec110a4
Added initial version of Monkey's Audio plugin
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
20 */ |
cc5e9ec110a4
Added initial version of Monkey's Audio plugin
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
21 |
cc5e9ec110a4
Added initial version of Monkey's Audio plugin
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
22 #include <stdio.h> |
cc5e9ec110a4
Added initial version of Monkey's Audio plugin
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
23 #include <stdlib.h> |
cc5e9ec110a4
Added initial version of Monkey's Audio plugin
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
24 #include <errno.h> |
cc5e9ec110a4
Added initial version of Monkey's Audio plugin
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
25 #include <string.h> |
cc5e9ec110a4
Added initial version of Monkey's Audio plugin
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
26 |
cc5e9ec110a4
Added initial version of Monkey's Audio plugin
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
27 #include <glib.h> |
2196
dfa3c3aa2dc7
switched to mowgli_dictionary from GHashTable
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2193
diff
changeset
|
28 #include <mowgli.h> |
2971
3134a0987162
- changed include path from audacious to audlegacy.
Yoshiki Yazawa <yaz@honeyplanet.jp>
parents:
2497
diff
changeset
|
29 #include <audlegacy/plugin.h> |
2182
cc5e9ec110a4
Added initial version of Monkey's Audio plugin
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
30 |
2193
80d7ab8f2ec5
removed some duplicated code
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2188
diff
changeset
|
31 #include "ape.h" |
2182
cc5e9ec110a4
Added initial version of Monkey's Audio plugin
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
32 #include "apev2.h" |
cc5e9ec110a4
Added initial version of Monkey's Audio plugin
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
33 |
cc5e9ec110a4
Added initial version of Monkey's Audio plugin
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
34 #define TMP_BUFSIZE 256 |
cc5e9ec110a4
Added initial version of Monkey's Audio plugin
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
35 #ifndef MIN |
cc5e9ec110a4
Added initial version of Monkey's Audio plugin
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
36 #define MIN(a,b) ((a) < (b) ? (a) : (b)) |
cc5e9ec110a4
Added initial version of Monkey's Audio plugin
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
37 #endif |
cc5e9ec110a4
Added initial version of Monkey's Audio plugin
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
38 |
2199
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
39 #define FLAGS_HEADER_EXISTS (1 << 31) |
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
40 #define FLAGS_HEADER (1 << 29) |
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
41 #define APE_SIGNATURE MKTAG64('A', 'P', 'E', 'T', 'A', 'G', 'E', 'X') |
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
42 |
2200
d10f13536b94
removed ugly callback
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2199
diff
changeset
|
43 /*typedef struct { |
2199
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
44 int tag_items; |
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
45 int tag_size; |
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
46 VFSFile *vfd; |
2200
d10f13536b94
removed ugly callback
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2199
diff
changeset
|
47 } iterator_pvt_t;*/ |
2199
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
48 |
2196
dfa3c3aa2dc7
switched to mowgli_dictionary from GHashTable
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2193
diff
changeset
|
49 mowgli_dictionary_t* parse_apev2_tag(VFSFile *vfd) { |
2182
cc5e9ec110a4
Added initial version of Monkey's Audio plugin
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
50 unsigned char tmp[TMP_BUFSIZE+1]; |
cc5e9ec110a4
Added initial version of Monkey's Audio plugin
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
51 unsigned char tmp2[TMP_BUFSIZE+1]; |
2193
80d7ab8f2ec5
removed some duplicated code
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2188
diff
changeset
|
52 guint64 signature; |
2197
c8d558dab2a7
debugging stuff added...
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2196
diff
changeset
|
53 int tag_version; |
c8d558dab2a7
debugging stuff added...
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2196
diff
changeset
|
54 long tag_size, item_size; |
c8d558dab2a7
debugging stuff added...
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2196
diff
changeset
|
55 int item_flags; |
c8d558dab2a7
debugging stuff added...
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2196
diff
changeset
|
56 int tag_items; |
2199
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
57 unsigned int tag_flags; |
2196
dfa3c3aa2dc7
switched to mowgli_dictionary from GHashTable
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2193
diff
changeset
|
58 mowgli_dictionary_t *dict; |
2182
cc5e9ec110a4
Added initial version of Monkey's Audio plugin
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
59 |
cc5e9ec110a4
Added initial version of Monkey's Audio plugin
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
60 aud_vfs_fseek(vfd, -32, SEEK_END); |
2193
80d7ab8f2ec5
removed some duplicated code
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2188
diff
changeset
|
61 signature = get_le64(vfd); |
2199
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
62 if (signature != APE_SIGNATURE) { |
2182
cc5e9ec110a4
Added initial version of Monkey's Audio plugin
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
63 #ifdef DEBUG |
cc5e9ec110a4
Added initial version of Monkey's Audio plugin
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
64 fprintf(stderr, "** demac: apev2.c: APE tag not found\n"); |
cc5e9ec110a4
Added initial version of Monkey's Audio plugin
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
65 #endif |
cc5e9ec110a4
Added initial version of Monkey's Audio plugin
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
66 return NULL; |
cc5e9ec110a4
Added initial version of Monkey's Audio plugin
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
67 } |
cc5e9ec110a4
Added initial version of Monkey's Audio plugin
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
68 |
2193
80d7ab8f2ec5
removed some duplicated code
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2188
diff
changeset
|
69 tag_version = get_le32(vfd); |
80d7ab8f2ec5
removed some duplicated code
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2188
diff
changeset
|
70 tag_size = get_le32(vfd); |
80d7ab8f2ec5
removed some duplicated code
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2188
diff
changeset
|
71 tag_items = get_le32(vfd); |
80d7ab8f2ec5
removed some duplicated code
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2188
diff
changeset
|
72 tag_flags = get_le32(vfd); |
2182
cc5e9ec110a4
Added initial version of Monkey's Audio plugin
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
73 #ifdef DEBUG |
2197
c8d558dab2a7
debugging stuff added...
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2196
diff
changeset
|
74 fprintf(stderr, "** demac: apev2.c: found APE tag version %d, size %ld, contains %d items, flags %08x\n", |
c8d558dab2a7
debugging stuff added...
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2196
diff
changeset
|
75 tag_version, tag_size, tag_items, tag_flags); |
2182
cc5e9ec110a4
Added initial version of Monkey's Audio plugin
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
76 #endif |
cc5e9ec110a4
Added initial version of Monkey's Audio plugin
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
77 if(tag_items == 0) { |
cc5e9ec110a4
Added initial version of Monkey's Audio plugin
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
78 #ifdef DEBUG |
cc5e9ec110a4
Added initial version of Monkey's Audio plugin
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
79 fprintf(stderr, "** demac: apev2.c: found empty tag\n"); |
cc5e9ec110a4
Added initial version of Monkey's Audio plugin
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
80 #endif |
cc5e9ec110a4
Added initial version of Monkey's Audio plugin
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
81 return NULL; |
cc5e9ec110a4
Added initial version of Monkey's Audio plugin
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
82 } |
cc5e9ec110a4
Added initial version of Monkey's Audio plugin
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
83 |
2196
dfa3c3aa2dc7
switched to mowgli_dictionary from GHashTable
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2193
diff
changeset
|
84 dict = mowgli_dictionary_create(g_ascii_strcasecmp); |
2182
cc5e9ec110a4
Added initial version of Monkey's Audio plugin
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
85 |
cc5e9ec110a4
Added initial version of Monkey's Audio plugin
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
86 aud_vfs_fseek(vfd, -tag_size, SEEK_END); |
cc5e9ec110a4
Added initial version of Monkey's Audio plugin
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
87 int i; |
cc5e9ec110a4
Added initial version of Monkey's Audio plugin
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
88 unsigned char *p; |
cc5e9ec110a4
Added initial version of Monkey's Audio plugin
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
89 for(i=0; i<tag_items; i++) { |
2193
80d7ab8f2ec5
removed some duplicated code
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2188
diff
changeset
|
90 item_size = get_le32(vfd); |
80d7ab8f2ec5
removed some duplicated code
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2188
diff
changeset
|
91 item_flags = get_le32(vfd); |
2197
c8d558dab2a7
debugging stuff added...
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2196
diff
changeset
|
92 #ifdef DEBUG |
c8d558dab2a7
debugging stuff added...
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2196
diff
changeset
|
93 fprintf(stderr, "** demac: apev2.c: item %d, size %ld, flags %d\n", i, item_size, item_flags); |
c8d558dab2a7
debugging stuff added...
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2196
diff
changeset
|
94 #endif |
2182
cc5e9ec110a4
Added initial version of Monkey's Audio plugin
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
95 |
cc5e9ec110a4
Added initial version of Monkey's Audio plugin
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
96 /* read key */ |
2199
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
97 if (item_size > 0 && item_size < tag_size) { /* be bulletproof */ |
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
98 for(p = tmp; p <= tmp+TMP_BUFSIZE; p++) { |
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
99 aud_vfs_fread(p, 1, 1, vfd); |
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
100 if(*p == '\0') break; |
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
101 } |
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
102 *(p+1) = '\0'; |
2182
cc5e9ec110a4
Added initial version of Monkey's Audio plugin
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
103 |
2199
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
104 /* read item */ |
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
105 aud_vfs_fread(tmp2, 1, MIN(item_size, TMP_BUFSIZE), vfd); |
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
106 tmp2[item_size] = '\0'; |
2182
cc5e9ec110a4
Added initial version of Monkey's Audio plugin
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
107 #ifdef DEBUG |
2199
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
108 fprintf(stderr, "%s: \"%s\", f:%08x\n", tmp, tmp2, item_flags); |
2182
cc5e9ec110a4
Added initial version of Monkey's Audio plugin
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
109 #endif |
2199
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
110 /* APEv2 stores all items in utf-8 */ |
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
111 gchar *item = ((tag_version == 1000 ) ? aud_str_to_utf8((gchar*)tmp2) : g_strdup((gchar*)tmp2)); |
2182
cc5e9ec110a4
Added initial version of Monkey's Audio plugin
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
112 |
2199
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
113 mowgli_dictionary_add(dict, (char*)tmp, item); |
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
114 } |
2182
cc5e9ec110a4
Added initial version of Monkey's Audio plugin
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
115 } |
2199
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
116 |
2196
dfa3c3aa2dc7
switched to mowgli_dictionary from GHashTable
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2193
diff
changeset
|
117 return dict; |
2182
cc5e9ec110a4
Added initial version of Monkey's Audio plugin
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
118 } |
2199
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
119 |
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
120 static void write_header_or_footer(guint32 version, guint32 size, guint32 items, guint32 flags, VFSFile *vfd) { |
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
121 guint64 filling = 0; |
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
122 |
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
123 aud_vfs_fwrite("APETAGEX", 1, 8, vfd); |
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
124 put_le32(version, vfd); |
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
125 put_le32(size, vfd); |
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
126 put_le32(items, vfd); |
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
127 put_le32(flags, vfd); |
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
128 aud_vfs_fwrite(&filling, 1, 8, vfd); |
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
129 } |
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
130 |
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
131 gboolean write_apev2_tag(VFSFile *vfd, mowgli_dictionary_t *tag) { |
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
132 guint64 signature; |
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
133 guint32 tag_version; |
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
134 guint32 tag_size, tag_items = 0, tag_flags; |
2200
d10f13536b94
removed ugly callback
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2199
diff
changeset
|
135 guint32 item_size, item_flags=0; |
2199
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
136 long file_size; |
2200
d10f13536b94
removed ugly callback
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2199
diff
changeset
|
137 void *current_field; |
2199
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
138 |
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
139 if (vfd == NULL || tag == NULL) return FALSE; |
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
140 |
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
141 aud_vfs_fseek(vfd, -32, SEEK_END); |
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
142 signature = get_le64(vfd); |
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
143 |
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
144 /* strip existing tag */ |
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
145 if (signature == APE_SIGNATURE) { |
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
146 tag_version = get_le32(vfd); |
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
147 tag_size = get_le32(vfd); |
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
148 tag_items = get_le32(vfd); |
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
149 tag_flags = get_le32(vfd); |
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
150 aud_vfs_fseek(vfd, 0, SEEK_END); |
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
151 file_size = aud_vfs_ftell(vfd); |
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
152 file_size -= (long)tag_size; |
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
153 |
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
154 /* also strip header */ |
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
155 if((tag_version >= 2000) && (tag_flags | FLAGS_HEADER_EXISTS)) { |
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
156 aud_vfs_fseek(vfd, -((long)tag_size)-32, SEEK_END); |
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
157 signature = get_le64(vfd); /* be bulletproof: check header also */ |
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
158 if (signature == APE_SIGNATURE) { |
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
159 #ifdef DEBUG |
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
160 fprintf(stderr, "stripping also header\n"); |
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
161 #endif |
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
162 file_size -= 32; |
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
163 } |
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
164 } |
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
165 #ifdef DEBUG |
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
166 fprintf(stderr, "stripping existing tag\n"); |
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
167 #endif |
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
168 if(aud_vfs_truncate(vfd, file_size) < 0) return FALSE; |
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
169 } |
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
170 aud_vfs_fseek(vfd, 0, SEEK_END); |
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
171 |
2200
d10f13536b94
removed ugly callback
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2199
diff
changeset
|
172 mowgli_dictionary_iteration_state_t state; |
2199
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
173 |
2200
d10f13536b94
removed ugly callback
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2199
diff
changeset
|
174 tag_size = 32; /* footer size */ |
d10f13536b94
removed ugly callback
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2199
diff
changeset
|
175 /* let's count tag size */ |
d10f13536b94
removed ugly callback
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2199
diff
changeset
|
176 tag_items = 0; |
d10f13536b94
removed ugly callback
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2199
diff
changeset
|
177 MOWGLI_DICTIONARY_FOREACH(current_field, &state, tag) { |
d10f13536b94
removed ugly callback
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2199
diff
changeset
|
178 if(strlen((char*)current_field) != 0) { |
d10f13536b94
removed ugly callback
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2199
diff
changeset
|
179 tag_items++; |
d10f13536b94
removed ugly callback
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2199
diff
changeset
|
180 tag_size += strlen((char*)state.cur->key) + strlen((char*)current_field) + 9; /* length in bytes not symbols */ |
d10f13536b94
removed ugly callback
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2199
diff
changeset
|
181 } |
d10f13536b94
removed ugly callback
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2199
diff
changeset
|
182 } |
2199
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
183 |
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
184 if(tag_items == 0) { |
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
185 #ifdef DEBUG |
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
186 fprintf(stderr, "tag stripped, all done\n"); |
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
187 #endif |
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
188 return TRUE; /* old tag is stripped, new one is empty */ |
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
189 } |
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
190 |
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
191 write_header_or_footer(2000, tag_size, tag_items, FLAGS_HEADER | FLAGS_HEADER_EXISTS, vfd); /* header */ |
2200
d10f13536b94
removed ugly callback
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2199
diff
changeset
|
192 MOWGLI_DICTIONARY_FOREACH(current_field, &state, tag) { |
d10f13536b94
removed ugly callback
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2199
diff
changeset
|
193 if( (item_size = strlen((char*)current_field)) != 0 ) { |
d10f13536b94
removed ugly callback
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2199
diff
changeset
|
194 #ifdef DEBUG |
d10f13536b94
removed ugly callback
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2199
diff
changeset
|
195 fprintf(stderr, "Writing field %s = %s\n", (char*)state.cur->key, (char*)current_field); |
d10f13536b94
removed ugly callback
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2199
diff
changeset
|
196 #endif |
d10f13536b94
removed ugly callback
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2199
diff
changeset
|
197 put_le32(item_size, vfd); |
d10f13536b94
removed ugly callback
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2199
diff
changeset
|
198 put_le32(item_flags, vfd); /* all set to zero */ |
d10f13536b94
removed ugly callback
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2199
diff
changeset
|
199 aud_vfs_fwrite(state.cur->key, 1, strlen((char*)state.cur->key) + 1, vfd); /* null-terminated */ |
d10f13536b94
removed ugly callback
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2199
diff
changeset
|
200 aud_vfs_fwrite(current_field, 1, item_size, vfd); |
d10f13536b94
removed ugly callback
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2199
diff
changeset
|
201 } |
d10f13536b94
removed ugly callback
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2199
diff
changeset
|
202 } |
2199
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
203 write_header_or_footer(2000, tag_size, tag_items, FLAGS_HEADER_EXISTS, vfd); /* footer */ |
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
204 |
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
205 return TRUE; |
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
206 } |
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
207 |