Mercurial > audlegacy-plugins
annotate src/demac/apev2.c @ 2494:862477de235b
Automated merge with ssh://hg.atheme.org//hg/audacious-plugins
author | William Pitcock <nenolod@atheme.org> |
---|---|
date | Mon, 31 Mar 2008 04:45:30 -0500 |
parents | d10f13536b94 |
children | ed6c81bd9016 |
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> |
2182
cc5e9ec110a4
Added initial version of Monkey's Audio plugin
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
29 #include <audacious/vfs.h> |
cc5e9ec110a4
Added initial version of Monkey's Audio plugin
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
30 #include <audacious/plugin.h> |
cc5e9ec110a4
Added initial version of Monkey's Audio plugin
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
31 |
2193
80d7ab8f2ec5
removed some duplicated code
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2188
diff
changeset
|
32 #include "ape.h" |
2182
cc5e9ec110a4
Added initial version of Monkey's Audio plugin
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
33 #include "apev2.h" |
cc5e9ec110a4
Added initial version of Monkey's Audio plugin
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
34 |
cc5e9ec110a4
Added initial version of Monkey's Audio plugin
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
35 #define TMP_BUFSIZE 256 |
cc5e9ec110a4
Added initial version of Monkey's Audio plugin
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
36 #ifndef MIN |
cc5e9ec110a4
Added initial version of Monkey's Audio plugin
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
37 #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
|
38 #endif |
cc5e9ec110a4
Added initial version of Monkey's Audio plugin
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
39 |
2199
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
40 #define FLAGS_HEADER_EXISTS (1 << 31) |
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
41 #define FLAGS_HEADER (1 << 29) |
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
42 #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
|
43 |
2200
d10f13536b94
removed ugly callback
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2199
diff
changeset
|
44 /*typedef struct { |
2199
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
45 int tag_items; |
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
46 int tag_size; |
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
47 VFSFile *vfd; |
2200
d10f13536b94
removed ugly callback
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2199
diff
changeset
|
48 } iterator_pvt_t;*/ |
2199
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
49 |
2196
dfa3c3aa2dc7
switched to mowgli_dictionary from GHashTable
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2193
diff
changeset
|
50 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
|
51 unsigned char tmp[TMP_BUFSIZE+1]; |
cc5e9ec110a4
Added initial version of Monkey's Audio plugin
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
52 unsigned char tmp2[TMP_BUFSIZE+1]; |
2193
80d7ab8f2ec5
removed some duplicated code
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2188
diff
changeset
|
53 guint64 signature; |
2197
c8d558dab2a7
debugging stuff added...
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2196
diff
changeset
|
54 int tag_version; |
c8d558dab2a7
debugging stuff added...
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2196
diff
changeset
|
55 long tag_size, item_size; |
c8d558dab2a7
debugging stuff added...
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2196
diff
changeset
|
56 int item_flags; |
c8d558dab2a7
debugging stuff added...
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2196
diff
changeset
|
57 int tag_items; |
2199
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
58 unsigned int tag_flags; |
2196
dfa3c3aa2dc7
switched to mowgli_dictionary from GHashTable
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2193
diff
changeset
|
59 mowgli_dictionary_t *dict; |
2182
cc5e9ec110a4
Added initial version of Monkey's Audio plugin
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
60 |
cc5e9ec110a4
Added initial version of Monkey's Audio plugin
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
61 aud_vfs_fseek(vfd, -32, SEEK_END); |
2193
80d7ab8f2ec5
removed some duplicated code
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2188
diff
changeset
|
62 signature = get_le64(vfd); |
2199
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
63 if (signature != APE_SIGNATURE) { |
2182
cc5e9ec110a4
Added initial version of Monkey's Audio plugin
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
64 #ifdef DEBUG |
cc5e9ec110a4
Added initial version of Monkey's Audio plugin
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
65 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
|
66 #endif |
cc5e9ec110a4
Added initial version of Monkey's Audio plugin
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
67 return NULL; |
cc5e9ec110a4
Added initial version of Monkey's Audio plugin
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
68 } |
cc5e9ec110a4
Added initial version of Monkey's Audio plugin
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
69 |
2193
80d7ab8f2ec5
removed some duplicated code
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2188
diff
changeset
|
70 tag_version = get_le32(vfd); |
80d7ab8f2ec5
removed some duplicated code
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2188
diff
changeset
|
71 tag_size = get_le32(vfd); |
80d7ab8f2ec5
removed some duplicated code
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2188
diff
changeset
|
72 tag_items = get_le32(vfd); |
80d7ab8f2ec5
removed some duplicated code
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2188
diff
changeset
|
73 tag_flags = get_le32(vfd); |
2182
cc5e9ec110a4
Added initial version of Monkey's Audio plugin
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
74 #ifdef DEBUG |
2197
c8d558dab2a7
debugging stuff added...
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2196
diff
changeset
|
75 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
|
76 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
|
77 #endif |
cc5e9ec110a4
Added initial version of Monkey's Audio plugin
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
78 if(tag_items == 0) { |
cc5e9ec110a4
Added initial version of Monkey's Audio plugin
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
79 #ifdef DEBUG |
cc5e9ec110a4
Added initial version of Monkey's Audio plugin
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
80 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
|
81 #endif |
cc5e9ec110a4
Added initial version of Monkey's Audio plugin
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
82 return NULL; |
cc5e9ec110a4
Added initial version of Monkey's Audio plugin
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
83 } |
cc5e9ec110a4
Added initial version of Monkey's Audio plugin
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
84 |
2196
dfa3c3aa2dc7
switched to mowgli_dictionary from GHashTable
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2193
diff
changeset
|
85 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
|
86 |
cc5e9ec110a4
Added initial version of Monkey's Audio plugin
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
87 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
|
88 int i; |
cc5e9ec110a4
Added initial version of Monkey's Audio plugin
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
89 unsigned char *p; |
cc5e9ec110a4
Added initial version of Monkey's Audio plugin
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
90 for(i=0; i<tag_items; i++) { |
2193
80d7ab8f2ec5
removed some duplicated code
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2188
diff
changeset
|
91 item_size = get_le32(vfd); |
80d7ab8f2ec5
removed some duplicated code
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2188
diff
changeset
|
92 item_flags = get_le32(vfd); |
2197
c8d558dab2a7
debugging stuff added...
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2196
diff
changeset
|
93 #ifdef DEBUG |
c8d558dab2a7
debugging stuff added...
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2196
diff
changeset
|
94 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
|
95 #endif |
2182
cc5e9ec110a4
Added initial version of Monkey's Audio plugin
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
96 |
cc5e9ec110a4
Added initial version of Monkey's Audio plugin
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
97 /* read key */ |
2199
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
98 if (item_size > 0 && item_size < tag_size) { /* be bulletproof */ |
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
99 for(p = tmp; p <= tmp+TMP_BUFSIZE; p++) { |
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
100 aud_vfs_fread(p, 1, 1, vfd); |
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
101 if(*p == '\0') break; |
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
102 } |
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
103 *(p+1) = '\0'; |
2182
cc5e9ec110a4
Added initial version of Monkey's Audio plugin
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
104 |
2199
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
105 /* read item */ |
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
106 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
|
107 tmp2[item_size] = '\0'; |
2182
cc5e9ec110a4
Added initial version of Monkey's Audio plugin
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
108 #ifdef DEBUG |
2199
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
109 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
|
110 #endif |
2199
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
111 /* APEv2 stores all items in utf-8 */ |
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
112 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
|
113 |
2199
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
114 mowgli_dictionary_add(dict, (char*)tmp, item); |
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
115 } |
2182
cc5e9ec110a4
Added initial version of Monkey's Audio plugin
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
116 } |
2199
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
117 |
2196
dfa3c3aa2dc7
switched to mowgli_dictionary from GHashTable
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2193
diff
changeset
|
118 return dict; |
2182
cc5e9ec110a4
Added initial version of Monkey's Audio plugin
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
diff
changeset
|
119 } |
2199
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
120 |
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
121 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
|
122 guint64 filling = 0; |
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
123 |
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
124 aud_vfs_fwrite("APETAGEX", 1, 8, vfd); |
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
125 put_le32(version, vfd); |
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
126 put_le32(size, vfd); |
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
127 put_le32(items, vfd); |
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
128 put_le32(flags, vfd); |
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
129 aud_vfs_fwrite(&filling, 1, 8, vfd); |
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 |
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
132 gboolean write_apev2_tag(VFSFile *vfd, mowgli_dictionary_t *tag) { |
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
133 guint64 signature; |
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
134 guint32 tag_version; |
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
135 guint32 tag_size, tag_items = 0, tag_flags; |
2200
d10f13536b94
removed ugly callback
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2199
diff
changeset
|
136 guint32 item_size, item_flags=0; |
2199
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
137 long file_size; |
2200
d10f13536b94
removed ugly callback
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2199
diff
changeset
|
138 void *current_field; |
2199
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
139 |
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
140 if (vfd == NULL || tag == NULL) return FALSE; |
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
141 |
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
142 aud_vfs_fseek(vfd, -32, SEEK_END); |
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
143 signature = get_le64(vfd); |
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
144 |
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
145 /* strip existing tag */ |
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
146 if (signature == APE_SIGNATURE) { |
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
147 tag_version = get_le32(vfd); |
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
148 tag_size = get_le32(vfd); |
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
149 tag_items = get_le32(vfd); |
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
150 tag_flags = get_le32(vfd); |
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
151 aud_vfs_fseek(vfd, 0, SEEK_END); |
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
152 file_size = aud_vfs_ftell(vfd); |
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
153 file_size -= (long)tag_size; |
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
154 |
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
155 /* also strip header */ |
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
156 if((tag_version >= 2000) && (tag_flags | FLAGS_HEADER_EXISTS)) { |
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
157 aud_vfs_fseek(vfd, -((long)tag_size)-32, SEEK_END); |
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
158 signature = get_le64(vfd); /* be bulletproof: check header also */ |
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
159 if (signature == APE_SIGNATURE) { |
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
160 #ifdef DEBUG |
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
161 fprintf(stderr, "stripping also header\n"); |
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
162 #endif |
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
163 file_size -= 32; |
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 } |
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
166 #ifdef DEBUG |
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
167 fprintf(stderr, "stripping existing tag\n"); |
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
168 #endif |
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
169 if(aud_vfs_truncate(vfd, file_size) < 0) return FALSE; |
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
170 } |
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
171 aud_vfs_fseek(vfd, 0, SEEK_END); |
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
172 |
2200
d10f13536b94
removed ugly callback
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2199
diff
changeset
|
173 mowgli_dictionary_iteration_state_t state; |
2199
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
174 |
2200
d10f13536b94
removed ugly callback
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2199
diff
changeset
|
175 tag_size = 32; /* footer size */ |
d10f13536b94
removed ugly callback
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2199
diff
changeset
|
176 /* let's count tag size */ |
d10f13536b94
removed ugly callback
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2199
diff
changeset
|
177 tag_items = 0; |
d10f13536b94
removed ugly callback
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2199
diff
changeset
|
178 MOWGLI_DICTIONARY_FOREACH(current_field, &state, tag) { |
d10f13536b94
removed ugly callback
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2199
diff
changeset
|
179 if(strlen((char*)current_field) != 0) { |
d10f13536b94
removed ugly callback
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2199
diff
changeset
|
180 tag_items++; |
d10f13536b94
removed ugly callback
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2199
diff
changeset
|
181 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
|
182 } |
d10f13536b94
removed ugly callback
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2199
diff
changeset
|
183 } |
2199
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
184 |
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
185 if(tag_items == 0) { |
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
186 #ifdef DEBUG |
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
187 fprintf(stderr, "tag stripped, all done\n"); |
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
188 #endif |
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
189 return TRUE; /* old tag is stripped, new one is empty */ |
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 |
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
192 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
|
193 MOWGLI_DICTIONARY_FOREACH(current_field, &state, tag) { |
d10f13536b94
removed ugly callback
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2199
diff
changeset
|
194 if( (item_size = strlen((char*)current_field)) != 0 ) { |
d10f13536b94
removed ugly callback
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2199
diff
changeset
|
195 #ifdef DEBUG |
d10f13536b94
removed ugly callback
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2199
diff
changeset
|
196 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
|
197 #endif |
d10f13536b94
removed ugly callback
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2199
diff
changeset
|
198 put_le32(item_size, vfd); |
d10f13536b94
removed ugly callback
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2199
diff
changeset
|
199 put_le32(item_flags, vfd); /* all set to zero */ |
d10f13536b94
removed ugly callback
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2199
diff
changeset
|
200 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
|
201 aud_vfs_fwrite(current_field, 1, item_size, vfd); |
d10f13536b94
removed ugly callback
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2199
diff
changeset
|
202 } |
d10f13536b94
removed ugly callback
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2199
diff
changeset
|
203 } |
2199
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
204 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
|
205 |
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
206 return TRUE; |
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
207 } |
8b3c2fe608c9
APEv2 writing implemented
Eugene Zagidullin <e.asphyx@gmail.com>
parents:
2198
diff
changeset
|
208 |