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
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
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