Mercurial > audlegacy-plugins
annotate src/demac/apev2.c @ 2284:d19b53359b24
cleaned up the sndfile wav plugin, currently limiting it ONLY TO WAV
PLAYBACK. if somebody is more experienced with it and wants to restore
the other formats, go ahead (maybe change the name of the plugin too?).
author | mf0102 <0102@gmx.at> |
---|---|
date | Wed, 09 Jan 2008 15:41:22 +0100 |
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 |