Chris@1
|
1 /* test_libFLAC - Unit tester for libFLAC
|
Chris@1
|
2 * Copyright (C) 2002,2003,2004,2005,2006,2007 Josh Coalson
|
Chris@1
|
3 *
|
Chris@1
|
4 * This program is free software; you can redistribute it and/or
|
Chris@1
|
5 * modify it under the terms of the GNU General Public License
|
Chris@1
|
6 * as published by the Free Software Foundation; either version 2
|
Chris@1
|
7 * of the License, or (at your option) any later version.
|
Chris@1
|
8 *
|
Chris@1
|
9 * This program is distributed in the hope that it will be useful,
|
Chris@1
|
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
Chris@1
|
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
Chris@1
|
12 * GNU General Public License for more details.
|
Chris@1
|
13 *
|
Chris@1
|
14 * You should have received a copy of the GNU General Public License
|
Chris@1
|
15 * along with this program; if not, write to the Free Software
|
Chris@1
|
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
Chris@1
|
17 */
|
Chris@1
|
18
|
Chris@1
|
19 #if HAVE_CONFIG_H
|
Chris@1
|
20 # include <config.h>
|
Chris@1
|
21 #endif
|
Chris@1
|
22
|
Chris@1
|
23 #include <stdio.h>
|
Chris@1
|
24 #include <stdlib.h> /* for malloc() */
|
Chris@1
|
25 #include <string.h> /* for memcpy()/memset() */
|
Chris@1
|
26 #if defined _MSC_VER || defined __MINGW32__
|
Chris@1
|
27 #include <sys/utime.h> /* for utime() */
|
Chris@1
|
28 #include <io.h> /* for chmod() */
|
Chris@1
|
29 #if _MSC_VER <= 1600 /* @@@ [2G limit] */
|
Chris@1
|
30 #define fseeko fseek
|
Chris@1
|
31 #define ftello ftell
|
Chris@1
|
32 #endif
|
Chris@1
|
33 #else
|
Chris@1
|
34 #include <sys/types.h> /* some flavors of BSD (like OS X) require this to get time_t */
|
Chris@1
|
35 #include <utime.h> /* for utime() */
|
Chris@1
|
36 #include <unistd.h> /* for chown(), unlink() */
|
Chris@1
|
37 #endif
|
Chris@1
|
38 #include <sys/stat.h> /* for stat(), maybe chmod() */
|
Chris@1
|
39 #include "FLAC/assert.h"
|
Chris@1
|
40 #include "FLAC/stream_decoder.h"
|
Chris@1
|
41 #include "FLAC/metadata.h"
|
Chris@1
|
42 #include "share/grabbag.h"
|
Chris@1
|
43 #include "test_libs_common/file_utils_flac.h"
|
Chris@1
|
44 #include "test_libs_common/metadata_utils.h"
|
Chris@1
|
45 #include "metadata.h"
|
Chris@1
|
46
|
Chris@1
|
47
|
Chris@1
|
48 /******************************************************************************
|
Chris@1
|
49 The general strategy of these tests (for interface levels 1 and 2) is
|
Chris@1
|
50 to create a dummy FLAC file with a known set of initial metadata
|
Chris@1
|
51 blocks, then keep a mirror locally of what we expect the metadata to be
|
Chris@1
|
52 after each operation. Then testing becomes a simple matter of running
|
Chris@1
|
53 a FLAC__StreamDecoder over the dummy file after each operation, comparing
|
Chris@1
|
54 the decoded metadata to what's in our local copy. If there are any
|
Chris@1
|
55 differences in the metadata, or the actual audio data is corrupted, we
|
Chris@1
|
56 will catch it while decoding.
|
Chris@1
|
57 ******************************************************************************/
|
Chris@1
|
58
|
Chris@1
|
59 typedef struct {
|
Chris@1
|
60 FLAC__bool error_occurred;
|
Chris@1
|
61 } decoder_client_struct;
|
Chris@1
|
62
|
Chris@1
|
63 typedef struct {
|
Chris@1
|
64 FLAC__StreamMetadata *blocks[64];
|
Chris@1
|
65 unsigned num_blocks;
|
Chris@1
|
66 } our_metadata_struct;
|
Chris@1
|
67
|
Chris@1
|
68 /* our copy of the metadata in flacfilename() */
|
Chris@1
|
69 static our_metadata_struct our_metadata_;
|
Chris@1
|
70
|
Chris@1
|
71 /* the current block number that corresponds to the position of the iterator we are testing */
|
Chris@1
|
72 static unsigned mc_our_block_number_ = 0;
|
Chris@1
|
73
|
Chris@1
|
74 static const char *flacfilename(FLAC__bool is_ogg)
|
Chris@1
|
75 {
|
Chris@1
|
76 return is_ogg? "metadata.oga" : "metadata.flac";
|
Chris@1
|
77 }
|
Chris@1
|
78
|
Chris@1
|
79 static FLAC__bool die_(const char *msg)
|
Chris@1
|
80 {
|
Chris@1
|
81 printf("ERROR: %s\n", msg);
|
Chris@1
|
82 return false;
|
Chris@1
|
83 }
|
Chris@1
|
84
|
Chris@1
|
85 static FLAC__bool die_c_(const char *msg, FLAC__Metadata_ChainStatus status)
|
Chris@1
|
86 {
|
Chris@1
|
87 printf("ERROR: %s\n", msg);
|
Chris@1
|
88 printf(" status=%s\n", FLAC__Metadata_ChainStatusString[status]);
|
Chris@1
|
89 return false;
|
Chris@1
|
90 }
|
Chris@1
|
91
|
Chris@1
|
92 static FLAC__bool die_ss_(const char *msg, FLAC__Metadata_SimpleIterator *iterator)
|
Chris@1
|
93 {
|
Chris@1
|
94 printf("ERROR: %s\n", msg);
|
Chris@1
|
95 printf(" status=%s\n", FLAC__Metadata_SimpleIteratorStatusString[FLAC__metadata_simple_iterator_status(iterator)]);
|
Chris@1
|
96 return false;
|
Chris@1
|
97 }
|
Chris@1
|
98
|
Chris@1
|
99 static void *malloc_or_die_(size_t size)
|
Chris@1
|
100 {
|
Chris@1
|
101 void *x = malloc(size);
|
Chris@1
|
102 if(0 == x) {
|
Chris@1
|
103 fprintf(stderr, "ERROR: out of memory allocating %u bytes\n", (unsigned)size);
|
Chris@1
|
104 exit(1);
|
Chris@1
|
105 }
|
Chris@1
|
106 return x;
|
Chris@1
|
107 }
|
Chris@1
|
108
|
Chris@1
|
109 static char *strdup_or_die_(const char *s)
|
Chris@1
|
110 {
|
Chris@1
|
111 char *x = strdup(s);
|
Chris@1
|
112 if(0 == x) {
|
Chris@1
|
113 fprintf(stderr, "ERROR: out of memory copying string \"%s\"\n", s);
|
Chris@1
|
114 exit(1);
|
Chris@1
|
115 }
|
Chris@1
|
116 return x;
|
Chris@1
|
117 }
|
Chris@1
|
118
|
Chris@1
|
119 /* functions for working with our metadata copy */
|
Chris@1
|
120
|
Chris@1
|
121 static FLAC__bool replace_in_our_metadata_(FLAC__StreamMetadata *block, unsigned position, FLAC__bool copy)
|
Chris@1
|
122 {
|
Chris@1
|
123 unsigned i;
|
Chris@1
|
124 FLAC__StreamMetadata *obj = block;
|
Chris@1
|
125 FLAC__ASSERT(position < our_metadata_.num_blocks);
|
Chris@1
|
126 if(copy) {
|
Chris@1
|
127 if(0 == (obj = FLAC__metadata_object_clone(block)))
|
Chris@1
|
128 return die_("during FLAC__metadata_object_clone()");
|
Chris@1
|
129 }
|
Chris@1
|
130 FLAC__metadata_object_delete(our_metadata_.blocks[position]);
|
Chris@1
|
131 our_metadata_.blocks[position] = obj;
|
Chris@1
|
132
|
Chris@1
|
133 /* set the is_last flags */
|
Chris@1
|
134 for(i = 0; i < our_metadata_.num_blocks - 1; i++)
|
Chris@1
|
135 our_metadata_.blocks[i]->is_last = false;
|
Chris@1
|
136 our_metadata_.blocks[i]->is_last = true;
|
Chris@1
|
137
|
Chris@1
|
138 return true;
|
Chris@1
|
139 }
|
Chris@1
|
140
|
Chris@1
|
141 static FLAC__bool insert_to_our_metadata_(FLAC__StreamMetadata *block, unsigned position, FLAC__bool copy)
|
Chris@1
|
142 {
|
Chris@1
|
143 unsigned i;
|
Chris@1
|
144 FLAC__StreamMetadata *obj = block;
|
Chris@1
|
145 if(copy) {
|
Chris@1
|
146 if(0 == (obj = FLAC__metadata_object_clone(block)))
|
Chris@1
|
147 return die_("during FLAC__metadata_object_clone()");
|
Chris@1
|
148 }
|
Chris@1
|
149 if(position > our_metadata_.num_blocks) {
|
Chris@1
|
150 position = our_metadata_.num_blocks;
|
Chris@1
|
151 }
|
Chris@1
|
152 else {
|
Chris@1
|
153 for(i = our_metadata_.num_blocks; i > position; i--)
|
Chris@1
|
154 our_metadata_.blocks[i] = our_metadata_.blocks[i-1];
|
Chris@1
|
155 }
|
Chris@1
|
156 our_metadata_.blocks[position] = obj;
|
Chris@1
|
157 our_metadata_.num_blocks++;
|
Chris@1
|
158
|
Chris@1
|
159 /* set the is_last flags */
|
Chris@1
|
160 for(i = 0; i < our_metadata_.num_blocks - 1; i++)
|
Chris@1
|
161 our_metadata_.blocks[i]->is_last = false;
|
Chris@1
|
162 our_metadata_.blocks[i]->is_last = true;
|
Chris@1
|
163
|
Chris@1
|
164 return true;
|
Chris@1
|
165 }
|
Chris@1
|
166
|
Chris@1
|
167 static void delete_from_our_metadata_(unsigned position)
|
Chris@1
|
168 {
|
Chris@1
|
169 unsigned i;
|
Chris@1
|
170 FLAC__ASSERT(position < our_metadata_.num_blocks);
|
Chris@1
|
171 FLAC__metadata_object_delete(our_metadata_.blocks[position]);
|
Chris@1
|
172 for(i = position; i < our_metadata_.num_blocks - 1; i++)
|
Chris@1
|
173 our_metadata_.blocks[i] = our_metadata_.blocks[i+1];
|
Chris@1
|
174 our_metadata_.num_blocks--;
|
Chris@1
|
175
|
Chris@1
|
176 /* set the is_last flags */
|
Chris@1
|
177 if(our_metadata_.num_blocks > 0) {
|
Chris@1
|
178 for(i = 0; i < our_metadata_.num_blocks - 1; i++)
|
Chris@1
|
179 our_metadata_.blocks[i]->is_last = false;
|
Chris@1
|
180 our_metadata_.blocks[i]->is_last = true;
|
Chris@1
|
181 }
|
Chris@1
|
182 }
|
Chris@1
|
183
|
Chris@1
|
184 /*
|
Chris@1
|
185 * This wad of functions supports filename- and callback-based chain reading/writing.
|
Chris@1
|
186 * Everything up to set_file_stats_() is copied from libFLAC/metadata_iterators.c
|
Chris@1
|
187 */
|
Chris@1
|
188 static FLAC__bool open_tempfile_(const char *filename, FILE **tempfile, char **tempfilename)
|
Chris@1
|
189 {
|
Chris@1
|
190 static const char *tempfile_suffix = ".metadata_edit";
|
Chris@1
|
191
|
Chris@1
|
192 if(0 == (*tempfilename = (char*)malloc(strlen(filename) + strlen(tempfile_suffix) + 1)))
|
Chris@1
|
193 return false;
|
Chris@1
|
194 strcpy(*tempfilename, filename);
|
Chris@1
|
195 strcat(*tempfilename, tempfile_suffix);
|
Chris@1
|
196
|
Chris@1
|
197 if(0 == (*tempfile = fopen(*tempfilename, "wb")))
|
Chris@1
|
198 return false;
|
Chris@1
|
199
|
Chris@1
|
200 return true;
|
Chris@1
|
201 }
|
Chris@1
|
202
|
Chris@1
|
203 static void cleanup_tempfile_(FILE **tempfile, char **tempfilename)
|
Chris@1
|
204 {
|
Chris@1
|
205 if(0 != *tempfile) {
|
Chris@1
|
206 (void)fclose(*tempfile);
|
Chris@1
|
207 *tempfile = 0;
|
Chris@1
|
208 }
|
Chris@1
|
209
|
Chris@1
|
210 if(0 != *tempfilename) {
|
Chris@1
|
211 (void)unlink(*tempfilename);
|
Chris@1
|
212 free(*tempfilename);
|
Chris@1
|
213 *tempfilename = 0;
|
Chris@1
|
214 }
|
Chris@1
|
215 }
|
Chris@1
|
216
|
Chris@1
|
217 static FLAC__bool transport_tempfile_(const char *filename, FILE **tempfile, char **tempfilename)
|
Chris@1
|
218 {
|
Chris@1
|
219 FLAC__ASSERT(0 != filename);
|
Chris@1
|
220 FLAC__ASSERT(0 != tempfile);
|
Chris@1
|
221 FLAC__ASSERT(0 != tempfilename);
|
Chris@1
|
222 FLAC__ASSERT(0 != *tempfilename);
|
Chris@1
|
223
|
Chris@1
|
224 if(0 != *tempfile) {
|
Chris@1
|
225 (void)fclose(*tempfile);
|
Chris@1
|
226 *tempfile = 0;
|
Chris@1
|
227 }
|
Chris@1
|
228
|
Chris@1
|
229 #if defined _MSC_VER || defined __MINGW32__ || defined __EMX__
|
Chris@1
|
230 /* on some flavors of windows, rename() will fail if the destination already exists */
|
Chris@1
|
231 if(unlink(filename) < 0) {
|
Chris@1
|
232 cleanup_tempfile_(tempfile, tempfilename);
|
Chris@1
|
233 return false;
|
Chris@1
|
234 }
|
Chris@1
|
235 #endif
|
Chris@1
|
236
|
Chris@1
|
237 if(0 != rename(*tempfilename, filename)) {
|
Chris@1
|
238 cleanup_tempfile_(tempfile, tempfilename);
|
Chris@1
|
239 return false;
|
Chris@1
|
240 }
|
Chris@1
|
241
|
Chris@1
|
242 cleanup_tempfile_(tempfile, tempfilename);
|
Chris@1
|
243
|
Chris@1
|
244 return true;
|
Chris@1
|
245 }
|
Chris@1
|
246
|
Chris@1
|
247 static FLAC__bool get_file_stats_(const char *filename, struct stat *stats)
|
Chris@1
|
248 {
|
Chris@1
|
249 FLAC__ASSERT(0 != filename);
|
Chris@1
|
250 FLAC__ASSERT(0 != stats);
|
Chris@1
|
251 return (0 == stat(filename, stats));
|
Chris@1
|
252 }
|
Chris@1
|
253
|
Chris@1
|
254 static void set_file_stats_(const char *filename, struct stat *stats)
|
Chris@1
|
255 {
|
Chris@1
|
256 struct utimbuf srctime;
|
Chris@1
|
257
|
Chris@1
|
258 FLAC__ASSERT(0 != filename);
|
Chris@1
|
259 FLAC__ASSERT(0 != stats);
|
Chris@1
|
260
|
Chris@1
|
261 srctime.actime = stats->st_atime;
|
Chris@1
|
262 srctime.modtime = stats->st_mtime;
|
Chris@1
|
263 (void)chmod(filename, stats->st_mode);
|
Chris@1
|
264 (void)utime(filename, &srctime);
|
Chris@1
|
265 #if !defined _MSC_VER && !defined __MINGW32__ && !defined __EMX__
|
Chris@1
|
266 (void)chown(filename, stats->st_uid, -1);
|
Chris@1
|
267 (void)chown(filename, -1, stats->st_gid);
|
Chris@1
|
268 #endif
|
Chris@1
|
269 }
|
Chris@1
|
270
|
Chris@1
|
271 #ifdef FLAC__VALGRIND_TESTING
|
Chris@1
|
272 static size_t chain_write_cb_(const void *ptr, size_t size, size_t nmemb, FLAC__IOHandle handle)
|
Chris@1
|
273 {
|
Chris@1
|
274 FILE *stream = (FILE*)handle;
|
Chris@1
|
275 size_t ret = fwrite(ptr, size, nmemb, stream);
|
Chris@1
|
276 if(!ferror(stream))
|
Chris@1
|
277 fflush(stream);
|
Chris@1
|
278 return ret;
|
Chris@1
|
279 }
|
Chris@1
|
280 #endif
|
Chris@1
|
281
|
Chris@1
|
282 static int chain_seek_cb_(FLAC__IOHandle handle, FLAC__int64 offset, int whence)
|
Chris@1
|
283 {
|
Chris@1
|
284 off_t o = (off_t)offset;
|
Chris@1
|
285 FLAC__ASSERT(offset == o);
|
Chris@1
|
286 return fseeko((FILE*)handle, o, whence);
|
Chris@1
|
287 }
|
Chris@1
|
288
|
Chris@1
|
289 static FLAC__int64 chain_tell_cb_(FLAC__IOHandle handle)
|
Chris@1
|
290 {
|
Chris@1
|
291 return ftello((FILE*)handle);
|
Chris@1
|
292 }
|
Chris@1
|
293
|
Chris@1
|
294 static int chain_eof_cb_(FLAC__IOHandle handle)
|
Chris@1
|
295 {
|
Chris@1
|
296 return feof((FILE*)handle);
|
Chris@1
|
297 }
|
Chris@1
|
298
|
Chris@1
|
299 static FLAC__bool write_chain_(FLAC__Metadata_Chain *chain, FLAC__bool use_padding, FLAC__bool preserve_file_stats, FLAC__bool filename_based, const char *filename)
|
Chris@1
|
300 {
|
Chris@1
|
301 if(filename_based)
|
Chris@1
|
302 return FLAC__metadata_chain_write(chain, use_padding, preserve_file_stats);
|
Chris@1
|
303 else {
|
Chris@1
|
304 FLAC__IOCallbacks callbacks;
|
Chris@1
|
305
|
Chris@1
|
306 memset(&callbacks, 0, sizeof(callbacks));
|
Chris@1
|
307 callbacks.read = (FLAC__IOCallback_Read)fread;
|
Chris@1
|
308 #ifdef FLAC__VALGRIND_TESTING
|
Chris@1
|
309 callbacks.write = chain_write_cb_;
|
Chris@1
|
310 #else
|
Chris@1
|
311 callbacks.write = (FLAC__IOCallback_Write)fwrite;
|
Chris@1
|
312 #endif
|
Chris@1
|
313 callbacks.seek = chain_seek_cb_;
|
Chris@1
|
314 callbacks.eof = chain_eof_cb_;
|
Chris@1
|
315
|
Chris@1
|
316 if(FLAC__metadata_chain_check_if_tempfile_needed(chain, use_padding)) {
|
Chris@1
|
317 struct stat stats;
|
Chris@1
|
318 FILE *file, *tempfile = 0;
|
Chris@1
|
319 char *tempfilename;
|
Chris@1
|
320 if(preserve_file_stats) {
|
Chris@1
|
321 if(!get_file_stats_(filename, &stats))
|
Chris@1
|
322 return false;
|
Chris@1
|
323 }
|
Chris@1
|
324 if(0 == (file = fopen(filename, "rb")))
|
Chris@1
|
325 return false; /*@@@@ chain status still says OK though */
|
Chris@1
|
326 if(!open_tempfile_(filename, &tempfile, &tempfilename)) {
|
Chris@1
|
327 fclose(file);
|
Chris@1
|
328 cleanup_tempfile_(&tempfile, &tempfilename);
|
Chris@1
|
329 return false; /*@@@@ chain status still says OK though */
|
Chris@1
|
330 }
|
Chris@1
|
331 if(!FLAC__metadata_chain_write_with_callbacks_and_tempfile(chain, use_padding, (FLAC__IOHandle)file, callbacks, (FLAC__IOHandle)tempfile, callbacks)) {
|
Chris@1
|
332 fclose(file);
|
Chris@1
|
333 fclose(tempfile);
|
Chris@1
|
334 return false;
|
Chris@1
|
335 }
|
Chris@1
|
336 fclose(file);
|
Chris@1
|
337 fclose(tempfile);
|
Chris@1
|
338 file = tempfile = 0;
|
Chris@1
|
339 if(!transport_tempfile_(filename, &tempfile, &tempfilename))
|
Chris@1
|
340 return false;
|
Chris@1
|
341 if(preserve_file_stats)
|
Chris@1
|
342 set_file_stats_(filename, &stats);
|
Chris@1
|
343 }
|
Chris@1
|
344 else {
|
Chris@1
|
345 FILE *file = fopen(filename, "r+b");
|
Chris@1
|
346 if(0 == file)
|
Chris@1
|
347 return false; /*@@@@ chain status still says OK though */
|
Chris@1
|
348 if(!FLAC__metadata_chain_write_with_callbacks(chain, use_padding, (FLAC__IOHandle)file, callbacks))
|
Chris@1
|
349 return false;
|
Chris@1
|
350 fclose(file);
|
Chris@1
|
351 }
|
Chris@1
|
352 }
|
Chris@1
|
353
|
Chris@1
|
354 return true;
|
Chris@1
|
355 }
|
Chris@1
|
356
|
Chris@1
|
357 static FLAC__bool read_chain_(FLAC__Metadata_Chain *chain, const char *filename, FLAC__bool filename_based, FLAC__bool is_ogg)
|
Chris@1
|
358 {
|
Chris@1
|
359 if(filename_based)
|
Chris@1
|
360 return is_ogg?
|
Chris@1
|
361 FLAC__metadata_chain_read_ogg(chain, flacfilename(is_ogg)) :
|
Chris@1
|
362 FLAC__metadata_chain_read(chain, flacfilename(is_ogg))
|
Chris@1
|
363 ;
|
Chris@1
|
364 else {
|
Chris@1
|
365 FLAC__IOCallbacks callbacks;
|
Chris@1
|
366
|
Chris@1
|
367 memset(&callbacks, 0, sizeof(callbacks));
|
Chris@1
|
368 callbacks.read = (FLAC__IOCallback_Read)fread;
|
Chris@1
|
369 callbacks.seek = chain_seek_cb_;
|
Chris@1
|
370 callbacks.tell = chain_tell_cb_;
|
Chris@1
|
371
|
Chris@1
|
372 {
|
Chris@1
|
373 FLAC__bool ret;
|
Chris@1
|
374 FILE *file = fopen(filename, "rb");
|
Chris@1
|
375 if(0 == file)
|
Chris@1
|
376 return false; /*@@@@ chain status still says OK though */
|
Chris@1
|
377 ret = is_ogg?
|
Chris@1
|
378 FLAC__metadata_chain_read_ogg_with_callbacks(chain, (FLAC__IOHandle)file, callbacks) :
|
Chris@1
|
379 FLAC__metadata_chain_read_with_callbacks(chain, (FLAC__IOHandle)file, callbacks)
|
Chris@1
|
380 ;
|
Chris@1
|
381 fclose(file);
|
Chris@1
|
382 return ret;
|
Chris@1
|
383 }
|
Chris@1
|
384 }
|
Chris@1
|
385 }
|
Chris@1
|
386
|
Chris@1
|
387 /* function for comparing our metadata to a FLAC__Metadata_Chain */
|
Chris@1
|
388
|
Chris@1
|
389 static FLAC__bool compare_chain_(FLAC__Metadata_Chain *chain, unsigned current_position, FLAC__StreamMetadata *current_block)
|
Chris@1
|
390 {
|
Chris@1
|
391 unsigned i;
|
Chris@1
|
392 FLAC__Metadata_Iterator *iterator;
|
Chris@1
|
393 FLAC__StreamMetadata *block;
|
Chris@1
|
394 FLAC__bool next_ok = true;
|
Chris@1
|
395
|
Chris@1
|
396 FLAC__ASSERT(0 != chain);
|
Chris@1
|
397
|
Chris@1
|
398 printf("\tcomparing chain... ");
|
Chris@1
|
399 fflush(stdout);
|
Chris@1
|
400
|
Chris@1
|
401 if(0 == (iterator = FLAC__metadata_iterator_new()))
|
Chris@1
|
402 return die_("allocating memory for iterator");
|
Chris@1
|
403
|
Chris@1
|
404 FLAC__metadata_iterator_init(iterator, chain);
|
Chris@1
|
405
|
Chris@1
|
406 i = 0;
|
Chris@1
|
407 do {
|
Chris@1
|
408 printf("%u... ", i);
|
Chris@1
|
409 fflush(stdout);
|
Chris@1
|
410
|
Chris@1
|
411 if(0 == (block = FLAC__metadata_iterator_get_block(iterator))) {
|
Chris@1
|
412 FLAC__metadata_iterator_delete(iterator);
|
Chris@1
|
413 return die_("getting block from iterator");
|
Chris@1
|
414 }
|
Chris@1
|
415
|
Chris@1
|
416 if(!mutils__compare_block(our_metadata_.blocks[i], block)) {
|
Chris@1
|
417 FLAC__metadata_iterator_delete(iterator);
|
Chris@1
|
418 return die_("metadata block mismatch");
|
Chris@1
|
419 }
|
Chris@1
|
420
|
Chris@1
|
421 i++;
|
Chris@1
|
422 next_ok = FLAC__metadata_iterator_next(iterator);
|
Chris@1
|
423 } while(i < our_metadata_.num_blocks && next_ok);
|
Chris@1
|
424
|
Chris@1
|
425 FLAC__metadata_iterator_delete(iterator);
|
Chris@1
|
426
|
Chris@1
|
427 if(next_ok)
|
Chris@1
|
428 return die_("chain has more blocks than expected");
|
Chris@1
|
429
|
Chris@1
|
430 if(i < our_metadata_.num_blocks)
|
Chris@1
|
431 return die_("short block count in chain");
|
Chris@1
|
432
|
Chris@1
|
433 if(0 != current_block) {
|
Chris@1
|
434 printf("CURRENT_POSITION... ");
|
Chris@1
|
435 fflush(stdout);
|
Chris@1
|
436
|
Chris@1
|
437 if(!mutils__compare_block(our_metadata_.blocks[current_position], current_block))
|
Chris@1
|
438 return die_("metadata block mismatch");
|
Chris@1
|
439 }
|
Chris@1
|
440
|
Chris@1
|
441 printf("PASSED\n");
|
Chris@1
|
442
|
Chris@1
|
443 return true;
|
Chris@1
|
444 }
|
Chris@1
|
445
|
Chris@1
|
446 /* decoder callbacks for checking the file */
|
Chris@1
|
447
|
Chris@1
|
448 static FLAC__StreamDecoderWriteStatus decoder_write_callback_(const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data)
|
Chris@1
|
449 {
|
Chris@1
|
450 (void)decoder, (void)buffer, (void)client_data;
|
Chris@1
|
451
|
Chris@1
|
452 if(
|
Chris@1
|
453 (frame->header.number_type == FLAC__FRAME_NUMBER_TYPE_FRAME_NUMBER && frame->header.number.frame_number == 0) ||
|
Chris@1
|
454 (frame->header.number_type == FLAC__FRAME_NUMBER_TYPE_SAMPLE_NUMBER && frame->header.number.sample_number == 0)
|
Chris@1
|
455 ) {
|
Chris@1
|
456 printf("content... ");
|
Chris@1
|
457 fflush(stdout);
|
Chris@1
|
458 }
|
Chris@1
|
459
|
Chris@1
|
460 return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
|
Chris@1
|
461 }
|
Chris@1
|
462
|
Chris@1
|
463 /* this version pays no attention to the metadata */
|
Chris@1
|
464 static void decoder_metadata_callback_null_(const FLAC__StreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data)
|
Chris@1
|
465 {
|
Chris@1
|
466 (void)decoder, (void)metadata, (void)client_data;
|
Chris@1
|
467
|
Chris@1
|
468 printf("%d... ", mc_our_block_number_);
|
Chris@1
|
469 fflush(stdout);
|
Chris@1
|
470
|
Chris@1
|
471 mc_our_block_number_++;
|
Chris@1
|
472 }
|
Chris@1
|
473
|
Chris@1
|
474 /* this version is used when we want to compare to our metadata copy */
|
Chris@1
|
475 static void decoder_metadata_callback_compare_(const FLAC__StreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data)
|
Chris@1
|
476 {
|
Chris@1
|
477 decoder_client_struct *dcd = (decoder_client_struct*)client_data;
|
Chris@1
|
478
|
Chris@1
|
479 (void)decoder;
|
Chris@1
|
480
|
Chris@1
|
481 /* don't bother checking if we've already hit an error */
|
Chris@1
|
482 if(dcd->error_occurred)
|
Chris@1
|
483 return;
|
Chris@1
|
484
|
Chris@1
|
485 printf("%d... ", mc_our_block_number_);
|
Chris@1
|
486 fflush(stdout);
|
Chris@1
|
487
|
Chris@1
|
488 if(mc_our_block_number_ >= our_metadata_.num_blocks) {
|
Chris@1
|
489 (void)die_("got more metadata blocks than expected");
|
Chris@1
|
490 dcd->error_occurred = true;
|
Chris@1
|
491 }
|
Chris@1
|
492 else {
|
Chris@1
|
493 if(!mutils__compare_block(our_metadata_.blocks[mc_our_block_number_], metadata)) {
|
Chris@1
|
494 (void)die_("metadata block mismatch");
|
Chris@1
|
495 dcd->error_occurred = true;
|
Chris@1
|
496 }
|
Chris@1
|
497 }
|
Chris@1
|
498 mc_our_block_number_++;
|
Chris@1
|
499 }
|
Chris@1
|
500
|
Chris@1
|
501 static void decoder_error_callback_(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data)
|
Chris@1
|
502 {
|
Chris@1
|
503 decoder_client_struct *dcd = (decoder_client_struct*)client_data;
|
Chris@1
|
504 (void)decoder;
|
Chris@1
|
505
|
Chris@1
|
506 dcd->error_occurred = true;
|
Chris@1
|
507 printf("ERROR: got error callback, status = %s (%u)\n", FLAC__StreamDecoderErrorStatusString[status], (unsigned)status);
|
Chris@1
|
508 }
|
Chris@1
|
509
|
Chris@1
|
510 static FLAC__bool generate_file_(FLAC__bool include_extras, FLAC__bool is_ogg)
|
Chris@1
|
511 {
|
Chris@1
|
512 FLAC__StreamMetadata streaminfo, vorbiscomment, *cuesheet, picture, padding;
|
Chris@1
|
513 FLAC__StreamMetadata *metadata[4];
|
Chris@1
|
514 unsigned i = 0, n = 0;
|
Chris@1
|
515
|
Chris@1
|
516 printf("generating %sFLAC file for test\n", is_ogg? "Ogg " : "");
|
Chris@1
|
517
|
Chris@1
|
518 while(our_metadata_.num_blocks > 0)
|
Chris@1
|
519 delete_from_our_metadata_(0);
|
Chris@1
|
520
|
Chris@1
|
521 streaminfo.is_last = false;
|
Chris@1
|
522 streaminfo.type = FLAC__METADATA_TYPE_STREAMINFO;
|
Chris@1
|
523 streaminfo.length = FLAC__STREAM_METADATA_STREAMINFO_LENGTH;
|
Chris@1
|
524 streaminfo.data.stream_info.min_blocksize = 576;
|
Chris@1
|
525 streaminfo.data.stream_info.max_blocksize = 576;
|
Chris@1
|
526 streaminfo.data.stream_info.min_framesize = 0;
|
Chris@1
|
527 streaminfo.data.stream_info.max_framesize = 0;
|
Chris@1
|
528 streaminfo.data.stream_info.sample_rate = 44100;
|
Chris@1
|
529 streaminfo.data.stream_info.channels = 1;
|
Chris@1
|
530 streaminfo.data.stream_info.bits_per_sample = 8;
|
Chris@1
|
531 streaminfo.data.stream_info.total_samples = 0;
|
Chris@1
|
532 memset(streaminfo.data.stream_info.md5sum, 0, 16);
|
Chris@1
|
533
|
Chris@1
|
534 {
|
Chris@1
|
535 const unsigned vendor_string_length = (unsigned)strlen(FLAC__VENDOR_STRING);
|
Chris@1
|
536 vorbiscomment.is_last = false;
|
Chris@1
|
537 vorbiscomment.type = FLAC__METADATA_TYPE_VORBIS_COMMENT;
|
Chris@1
|
538 vorbiscomment.length = (4 + vendor_string_length) + 4;
|
Chris@1
|
539 vorbiscomment.data.vorbis_comment.vendor_string.length = vendor_string_length;
|
Chris@1
|
540 vorbiscomment.data.vorbis_comment.vendor_string.entry = malloc_or_die_(vendor_string_length+1);
|
Chris@1
|
541 memcpy(vorbiscomment.data.vorbis_comment.vendor_string.entry, FLAC__VENDOR_STRING, vendor_string_length+1);
|
Chris@1
|
542 vorbiscomment.data.vorbis_comment.num_comments = 0;
|
Chris@1
|
543 vorbiscomment.data.vorbis_comment.comments = 0;
|
Chris@1
|
544 }
|
Chris@1
|
545
|
Chris@1
|
546 {
|
Chris@1
|
547 if (0 == (cuesheet = FLAC__metadata_object_new(FLAC__METADATA_TYPE_CUESHEET)))
|
Chris@1
|
548 return die_("priming our metadata");
|
Chris@1
|
549 cuesheet->is_last = false;
|
Chris@1
|
550 strcpy(cuesheet->data.cue_sheet.media_catalog_number, "bogo-MCN");
|
Chris@1
|
551 cuesheet->data.cue_sheet.lead_in = 123;
|
Chris@1
|
552 cuesheet->data.cue_sheet.is_cd = false;
|
Chris@1
|
553 if (!FLAC__metadata_object_cuesheet_insert_blank_track(cuesheet, 0))
|
Chris@1
|
554 return die_("priming our metadata");
|
Chris@1
|
555 cuesheet->data.cue_sheet.tracks[0].number = 1;
|
Chris@1
|
556 if (!FLAC__metadata_object_cuesheet_track_insert_blank_index(cuesheet, 0, 0))
|
Chris@1
|
557 return die_("priming our metadata");
|
Chris@1
|
558 }
|
Chris@1
|
559
|
Chris@1
|
560 {
|
Chris@1
|
561 picture.is_last = false;
|
Chris@1
|
562 picture.type = FLAC__METADATA_TYPE_PICTURE;
|
Chris@1
|
563 picture.length =
|
Chris@1
|
564 (
|
Chris@1
|
565 FLAC__STREAM_METADATA_PICTURE_TYPE_LEN +
|
Chris@1
|
566 FLAC__STREAM_METADATA_PICTURE_MIME_TYPE_LENGTH_LEN + /* will add the length for the string later */
|
Chris@1
|
567 FLAC__STREAM_METADATA_PICTURE_DESCRIPTION_LENGTH_LEN + /* will add the length for the string later */
|
Chris@1
|
568 FLAC__STREAM_METADATA_PICTURE_WIDTH_LEN +
|
Chris@1
|
569 FLAC__STREAM_METADATA_PICTURE_HEIGHT_LEN +
|
Chris@1
|
570 FLAC__STREAM_METADATA_PICTURE_DEPTH_LEN +
|
Chris@1
|
571 FLAC__STREAM_METADATA_PICTURE_COLORS_LEN +
|
Chris@1
|
572 FLAC__STREAM_METADATA_PICTURE_DATA_LENGTH_LEN /* will add the length for the data later */
|
Chris@1
|
573 ) / 8
|
Chris@1
|
574 ;
|
Chris@1
|
575 picture.data.picture.type = FLAC__STREAM_METADATA_PICTURE_TYPE_FRONT_COVER;
|
Chris@1
|
576 picture.data.picture.mime_type = strdup_or_die_("image/jpeg");
|
Chris@1
|
577 picture.length += strlen(picture.data.picture.mime_type);
|
Chris@1
|
578 picture.data.picture.description = (FLAC__byte*)strdup_or_die_("desc");
|
Chris@1
|
579 picture.length += strlen((const char *)picture.data.picture.description);
|
Chris@1
|
580 picture.data.picture.width = 300;
|
Chris@1
|
581 picture.data.picture.height = 300;
|
Chris@1
|
582 picture.data.picture.depth = 24;
|
Chris@1
|
583 picture.data.picture.colors = 0;
|
Chris@1
|
584 picture.data.picture.data = (FLAC__byte*)strdup_or_die_("SOMEJPEGDATA");
|
Chris@1
|
585 picture.data.picture.data_length = strlen((const char *)picture.data.picture.data);
|
Chris@1
|
586 picture.length += picture.data.picture.data_length;
|
Chris@1
|
587 }
|
Chris@1
|
588
|
Chris@1
|
589 padding.is_last = true;
|
Chris@1
|
590 padding.type = FLAC__METADATA_TYPE_PADDING;
|
Chris@1
|
591 padding.length = 1234;
|
Chris@1
|
592
|
Chris@1
|
593 metadata[n++] = &vorbiscomment;
|
Chris@1
|
594 if(include_extras) {
|
Chris@1
|
595 metadata[n++] = cuesheet;
|
Chris@1
|
596 metadata[n++] = &picture;
|
Chris@1
|
597 }
|
Chris@1
|
598 metadata[n++] = &padding;
|
Chris@1
|
599
|
Chris@1
|
600 if(
|
Chris@1
|
601 !insert_to_our_metadata_(&streaminfo, i++, /*copy=*/true) ||
|
Chris@1
|
602 !insert_to_our_metadata_(&vorbiscomment, i++, /*copy=*/true) ||
|
Chris@1
|
603 (include_extras && !insert_to_our_metadata_(cuesheet, i++, /*copy=*/false)) ||
|
Chris@1
|
604 (include_extras && !insert_to_our_metadata_(&picture, i++, /*copy=*/true)) ||
|
Chris@1
|
605 !insert_to_our_metadata_(&padding, i++, /*copy=*/true)
|
Chris@1
|
606 )
|
Chris@1
|
607 return die_("priming our metadata");
|
Chris@1
|
608
|
Chris@1
|
609 if(!file_utils__generate_flacfile(is_ogg, flacfilename(is_ogg), 0, 512 * 1024, &streaminfo, metadata, n))
|
Chris@1
|
610 return die_("creating the encoded file");
|
Chris@1
|
611
|
Chris@1
|
612 free(vorbiscomment.data.vorbis_comment.vendor_string.entry);
|
Chris@1
|
613 free(picture.data.picture.mime_type);
|
Chris@1
|
614 free(picture.data.picture.description);
|
Chris@1
|
615 free(picture.data.picture.data);
|
Chris@1
|
616 if(!include_extras)
|
Chris@1
|
617 FLAC__metadata_object_delete(cuesheet);
|
Chris@1
|
618
|
Chris@1
|
619 return true;
|
Chris@1
|
620 }
|
Chris@1
|
621
|
Chris@1
|
622 static FLAC__bool test_file_(FLAC__bool is_ogg, FLAC__StreamDecoderMetadataCallback metadata_callback)
|
Chris@1
|
623 {
|
Chris@1
|
624 const char *filename = flacfilename(is_ogg);
|
Chris@1
|
625 FLAC__StreamDecoder *decoder;
|
Chris@1
|
626 decoder_client_struct decoder_client_data;
|
Chris@1
|
627
|
Chris@1
|
628 FLAC__ASSERT(0 != metadata_callback);
|
Chris@1
|
629
|
Chris@1
|
630 mc_our_block_number_ = 0;
|
Chris@1
|
631 decoder_client_data.error_occurred = false;
|
Chris@1
|
632
|
Chris@1
|
633 printf("\ttesting '%s'... ", filename);
|
Chris@1
|
634 fflush(stdout);
|
Chris@1
|
635
|
Chris@1
|
636 if(0 == (decoder = FLAC__stream_decoder_new()))
|
Chris@1
|
637 return die_("couldn't allocate decoder instance");
|
Chris@1
|
638
|
Chris@1
|
639 FLAC__stream_decoder_set_md5_checking(decoder, true);
|
Chris@1
|
640 FLAC__stream_decoder_set_metadata_respond_all(decoder);
|
Chris@1
|
641 if(
|
Chris@1
|
642 (is_ogg?
|
Chris@1
|
643 FLAC__stream_decoder_init_ogg_file(decoder, filename, decoder_write_callback_, metadata_callback, decoder_error_callback_, &decoder_client_data) :
|
Chris@1
|
644 FLAC__stream_decoder_init_file(decoder, filename, decoder_write_callback_, metadata_callback, decoder_error_callback_, &decoder_client_data)
|
Chris@1
|
645 ) != FLAC__STREAM_DECODER_INIT_STATUS_OK
|
Chris@1
|
646 ) {
|
Chris@1
|
647 (void)FLAC__stream_decoder_finish(decoder);
|
Chris@1
|
648 FLAC__stream_decoder_delete(decoder);
|
Chris@1
|
649 return die_("initializing decoder\n");
|
Chris@1
|
650 }
|
Chris@1
|
651 if(!FLAC__stream_decoder_process_until_end_of_stream(decoder)) {
|
Chris@1
|
652 (void)FLAC__stream_decoder_finish(decoder);
|
Chris@1
|
653 FLAC__stream_decoder_delete(decoder);
|
Chris@1
|
654 return die_("decoding file\n");
|
Chris@1
|
655 }
|
Chris@1
|
656
|
Chris@1
|
657 (void)FLAC__stream_decoder_finish(decoder);
|
Chris@1
|
658 FLAC__stream_decoder_delete(decoder);
|
Chris@1
|
659
|
Chris@1
|
660 if(decoder_client_data.error_occurred)
|
Chris@1
|
661 return false;
|
Chris@1
|
662
|
Chris@1
|
663 if(mc_our_block_number_ != our_metadata_.num_blocks)
|
Chris@1
|
664 return die_("short metadata block count");
|
Chris@1
|
665
|
Chris@1
|
666 printf("PASSED\n");
|
Chris@1
|
667 return true;
|
Chris@1
|
668 }
|
Chris@1
|
669
|
Chris@1
|
670 static FLAC__bool change_stats_(const char *filename, FLAC__bool read_only)
|
Chris@1
|
671 {
|
Chris@1
|
672 if(!grabbag__file_change_stats(filename, read_only))
|
Chris@1
|
673 return die_("during grabbag__file_change_stats()");
|
Chris@1
|
674
|
Chris@1
|
675 return true;
|
Chris@1
|
676 }
|
Chris@1
|
677
|
Chris@1
|
678 static FLAC__bool remove_file_(const char *filename)
|
Chris@1
|
679 {
|
Chris@1
|
680 while(our_metadata_.num_blocks > 0)
|
Chris@1
|
681 delete_from_our_metadata_(0);
|
Chris@1
|
682
|
Chris@1
|
683 if(!grabbag__file_remove_file(filename))
|
Chris@1
|
684 return die_("removing file");
|
Chris@1
|
685
|
Chris@1
|
686 return true;
|
Chris@1
|
687 }
|
Chris@1
|
688
|
Chris@1
|
689 static FLAC__bool test_level_0_(void)
|
Chris@1
|
690 {
|
Chris@1
|
691 FLAC__StreamMetadata streaminfo;
|
Chris@1
|
692 FLAC__StreamMetadata *tags = 0;
|
Chris@1
|
693 FLAC__StreamMetadata *cuesheet = 0;
|
Chris@1
|
694 FLAC__StreamMetadata *picture = 0;
|
Chris@1
|
695
|
Chris@1
|
696 printf("\n\n++++++ testing level 0 interface\n");
|
Chris@1
|
697
|
Chris@1
|
698 if(!generate_file_(/*include_extras=*/true, /*is_ogg=*/false))
|
Chris@1
|
699 return false;
|
Chris@1
|
700
|
Chris@1
|
701 if(!test_file_(/*is_ogg=*/false, decoder_metadata_callback_null_))
|
Chris@1
|
702 return false;
|
Chris@1
|
703
|
Chris@1
|
704 printf("testing FLAC__metadata_get_streaminfo()... ");
|
Chris@1
|
705
|
Chris@1
|
706 if(!FLAC__metadata_get_streaminfo(flacfilename(/*is_ogg=*/false), &streaminfo))
|
Chris@1
|
707 return die_("during FLAC__metadata_get_streaminfo()");
|
Chris@1
|
708
|
Chris@1
|
709 /* check to see if some basic data matches (c.f. generate_file_()) */
|
Chris@1
|
710 if(streaminfo.data.stream_info.channels != 1)
|
Chris@1
|
711 return die_("mismatch in streaminfo.data.stream_info.channels");
|
Chris@1
|
712 if(streaminfo.data.stream_info.bits_per_sample != 8)
|
Chris@1
|
713 return die_("mismatch in streaminfo.data.stream_info.bits_per_sample");
|
Chris@1
|
714 if(streaminfo.data.stream_info.sample_rate != 44100)
|
Chris@1
|
715 return die_("mismatch in streaminfo.data.stream_info.sample_rate");
|
Chris@1
|
716 if(streaminfo.data.stream_info.min_blocksize != 576)
|
Chris@1
|
717 return die_("mismatch in streaminfo.data.stream_info.min_blocksize");
|
Chris@1
|
718 if(streaminfo.data.stream_info.max_blocksize != 576)
|
Chris@1
|
719 return die_("mismatch in streaminfo.data.stream_info.max_blocksize");
|
Chris@1
|
720
|
Chris@1
|
721 printf("OK\n");
|
Chris@1
|
722
|
Chris@1
|
723 printf("testing FLAC__metadata_get_tags()... ");
|
Chris@1
|
724
|
Chris@1
|
725 if(!FLAC__metadata_get_tags(flacfilename(/*is_ogg=*/false), &tags))
|
Chris@1
|
726 return die_("during FLAC__metadata_get_tags()");
|
Chris@1
|
727
|
Chris@1
|
728 /* check to see if some basic data matches (c.f. generate_file_()) */
|
Chris@1
|
729 if(tags->data.vorbis_comment.num_comments != 0)
|
Chris@1
|
730 return die_("mismatch in tags->data.vorbis_comment.num_comments");
|
Chris@1
|
731
|
Chris@1
|
732 printf("OK\n");
|
Chris@1
|
733
|
Chris@1
|
734 FLAC__metadata_object_delete(tags);
|
Chris@1
|
735
|
Chris@1
|
736 printf("testing FLAC__metadata_get_cuesheet()... ");
|
Chris@1
|
737
|
Chris@1
|
738 if(!FLAC__metadata_get_cuesheet(flacfilename(/*is_ogg=*/false), &cuesheet))
|
Chris@1
|
739 return die_("during FLAC__metadata_get_cuesheet()");
|
Chris@1
|
740
|
Chris@1
|
741 /* check to see if some basic data matches (c.f. generate_file_()) */
|
Chris@1
|
742 if(cuesheet->data.cue_sheet.lead_in != 123)
|
Chris@1
|
743 return die_("mismatch in cuesheet->data.cue_sheet.lead_in");
|
Chris@1
|
744
|
Chris@1
|
745 printf("OK\n");
|
Chris@1
|
746
|
Chris@1
|
747 FLAC__metadata_object_delete(cuesheet);
|
Chris@1
|
748
|
Chris@1
|
749 printf("testing FLAC__metadata_get_picture()... ");
|
Chris@1
|
750
|
Chris@1
|
751 if(!FLAC__metadata_get_picture(flacfilename(/*is_ogg=*/false), &picture, /*type=*/(FLAC__StreamMetadata_Picture_Type)(-1), /*mime_type=*/0, /*description=*/0, /*max_width=*/(unsigned)(-1), /*max_height=*/(unsigned)(-1), /*max_depth=*/(unsigned)(-1), /*max_colors=*/(unsigned)(-1)))
|
Chris@1
|
752 return die_("during FLAC__metadata_get_picture()");
|
Chris@1
|
753
|
Chris@1
|
754 /* check to see if some basic data matches (c.f. generate_file_()) */
|
Chris@1
|
755 if(picture->data.picture.type != FLAC__STREAM_METADATA_PICTURE_TYPE_FRONT_COVER)
|
Chris@1
|
756 return die_("mismatch in picture->data.picture.type");
|
Chris@1
|
757
|
Chris@1
|
758 printf("OK\n");
|
Chris@1
|
759
|
Chris@1
|
760 FLAC__metadata_object_delete(picture);
|
Chris@1
|
761
|
Chris@1
|
762 if(!remove_file_(flacfilename(/*is_ogg=*/false)))
|
Chris@1
|
763 return false;
|
Chris@1
|
764
|
Chris@1
|
765 return true;
|
Chris@1
|
766 }
|
Chris@1
|
767
|
Chris@1
|
768 static FLAC__bool test_level_1_(void)
|
Chris@1
|
769 {
|
Chris@1
|
770 FLAC__Metadata_SimpleIterator *iterator;
|
Chris@1
|
771 FLAC__StreamMetadata *block, *app, *padding;
|
Chris@1
|
772 FLAC__byte data[1000];
|
Chris@1
|
773 unsigned our_current_position = 0;
|
Chris@1
|
774
|
Chris@1
|
775 /* initialize 'data' to avoid Valgrind errors */
|
Chris@1
|
776 memset(data, 0, sizeof(data));
|
Chris@1
|
777
|
Chris@1
|
778 printf("\n\n++++++ testing level 1 interface\n");
|
Chris@1
|
779
|
Chris@1
|
780 /************************************************************/
|
Chris@1
|
781
|
Chris@1
|
782 printf("simple iterator on read-only file\n");
|
Chris@1
|
783
|
Chris@1
|
784 if(!generate_file_(/*include_extras=*/false, /*is_ogg=*/false))
|
Chris@1
|
785 return false;
|
Chris@1
|
786
|
Chris@1
|
787 if(!change_stats_(flacfilename(/*is_ogg=*/false), /*read_only=*/true))
|
Chris@1
|
788 return false;
|
Chris@1
|
789
|
Chris@1
|
790 if(!test_file_(/*is_ogg=*/false, decoder_metadata_callback_null_))
|
Chris@1
|
791 return false;
|
Chris@1
|
792
|
Chris@1
|
793 if(0 == (iterator = FLAC__metadata_simple_iterator_new()))
|
Chris@1
|
794 return die_("FLAC__metadata_simple_iterator_new()");
|
Chris@1
|
795
|
Chris@1
|
796 if(!FLAC__metadata_simple_iterator_init(iterator, flacfilename(/*is_ogg=*/false), /*read_only=*/false, /*preserve_file_stats=*/false))
|
Chris@1
|
797 return die_("FLAC__metadata_simple_iterator_init() returned false");
|
Chris@1
|
798
|
Chris@1
|
799 printf("is writable = %u\n", (unsigned)FLAC__metadata_simple_iterator_is_writable(iterator));
|
Chris@1
|
800 if(FLAC__metadata_simple_iterator_is_writable(iterator))
|
Chris@1
|
801 return die_("iterator claims file is writable when tester thinks it should not be; are you running as root?\n");
|
Chris@1
|
802
|
Chris@1
|
803 printf("iterate forwards\n");
|
Chris@1
|
804
|
Chris@1
|
805 if(FLAC__metadata_simple_iterator_get_block_type(iterator) != FLAC__METADATA_TYPE_STREAMINFO)
|
Chris@1
|
806 return die_("expected STREAMINFO type from FLAC__metadata_simple_iterator_get_block_type()");
|
Chris@1
|
807 if(0 == (block = FLAC__metadata_simple_iterator_get_block(iterator)))
|
Chris@1
|
808 return die_("getting block 0");
|
Chris@1
|
809 if(block->type != FLAC__METADATA_TYPE_STREAMINFO)
|
Chris@1
|
810 return die_("expected STREAMINFO type");
|
Chris@1
|
811 if(block->is_last)
|
Chris@1
|
812 return die_("expected is_last to be false");
|
Chris@1
|
813 if(block->length != FLAC__STREAM_METADATA_STREAMINFO_LENGTH)
|
Chris@1
|
814 return die_("bad STREAMINFO length");
|
Chris@1
|
815 /* check to see if some basic data matches (c.f. generate_file_()) */
|
Chris@1
|
816 if(block->data.stream_info.channels != 1)
|
Chris@1
|
817 return die_("mismatch in channels");
|
Chris@1
|
818 if(block->data.stream_info.bits_per_sample != 8)
|
Chris@1
|
819 return die_("mismatch in bits_per_sample");
|
Chris@1
|
820 if(block->data.stream_info.sample_rate != 44100)
|
Chris@1
|
821 return die_("mismatch in sample_rate");
|
Chris@1
|
822 if(block->data.stream_info.min_blocksize != 576)
|
Chris@1
|
823 return die_("mismatch in min_blocksize");
|
Chris@1
|
824 if(block->data.stream_info.max_blocksize != 576)
|
Chris@1
|
825 return die_("mismatch in max_blocksize");
|
Chris@1
|
826 FLAC__metadata_object_delete(block);
|
Chris@1
|
827
|
Chris@1
|
828 if(!FLAC__metadata_simple_iterator_next(iterator))
|
Chris@1
|
829 return die_("forward iterator ended early");
|
Chris@1
|
830 our_current_position++;
|
Chris@1
|
831
|
Chris@1
|
832 if(!FLAC__metadata_simple_iterator_next(iterator))
|
Chris@1
|
833 return die_("forward iterator ended early");
|
Chris@1
|
834 our_current_position++;
|
Chris@1
|
835
|
Chris@1
|
836 if(FLAC__metadata_simple_iterator_get_block_type(iterator) != FLAC__METADATA_TYPE_PADDING)
|
Chris@1
|
837 return die_("expected PADDING type from FLAC__metadata_simple_iterator_get_block_type()");
|
Chris@1
|
838 if(0 == (block = FLAC__metadata_simple_iterator_get_block(iterator)))
|
Chris@1
|
839 return die_("getting block 2");
|
Chris@1
|
840 if(block->type != FLAC__METADATA_TYPE_PADDING)
|
Chris@1
|
841 return die_("expected PADDING type");
|
Chris@1
|
842 if(!block->is_last)
|
Chris@1
|
843 return die_("expected is_last to be true");
|
Chris@1
|
844 /* check to see if some basic data matches (c.f. generate_file_()) */
|
Chris@1
|
845 if(block->length != 1234)
|
Chris@1
|
846 return die_("bad PADDING length");
|
Chris@1
|
847 FLAC__metadata_object_delete(block);
|
Chris@1
|
848
|
Chris@1
|
849 if(FLAC__metadata_simple_iterator_next(iterator))
|
Chris@1
|
850 return die_("forward iterator returned true but should have returned false");
|
Chris@1
|
851
|
Chris@1
|
852 printf("iterate backwards\n");
|
Chris@1
|
853 if(!FLAC__metadata_simple_iterator_prev(iterator))
|
Chris@1
|
854 return die_("reverse iterator ended early");
|
Chris@1
|
855 if(!FLAC__metadata_simple_iterator_prev(iterator))
|
Chris@1
|
856 return die_("reverse iterator ended early");
|
Chris@1
|
857 if(FLAC__metadata_simple_iterator_prev(iterator))
|
Chris@1
|
858 return die_("reverse iterator returned true but should have returned false");
|
Chris@1
|
859
|
Chris@1
|
860 printf("testing FLAC__metadata_simple_iterator_set_block() on read-only file...\n");
|
Chris@1
|
861
|
Chris@1
|
862 if(!FLAC__metadata_simple_iterator_set_block(iterator, (FLAC__StreamMetadata*)99, false))
|
Chris@1
|
863 printf("OK: FLAC__metadata_simple_iterator_set_block() returned false like it should\n");
|
Chris@1
|
864 else
|
Chris@1
|
865 return die_("FLAC__metadata_simple_iterator_set_block() returned true but shouldn't have");
|
Chris@1
|
866
|
Chris@1
|
867 FLAC__metadata_simple_iterator_delete(iterator);
|
Chris@1
|
868
|
Chris@1
|
869 /************************************************************/
|
Chris@1
|
870
|
Chris@1
|
871 printf("simple iterator on writable file\n");
|
Chris@1
|
872
|
Chris@1
|
873 if(!change_stats_(flacfilename(/*is_ogg=*/false), /*read-only=*/false))
|
Chris@1
|
874 return false;
|
Chris@1
|
875
|
Chris@1
|
876 printf("creating APPLICATION block\n");
|
Chris@1
|
877
|
Chris@1
|
878 if(0 == (app = FLAC__metadata_object_new(FLAC__METADATA_TYPE_APPLICATION)))
|
Chris@1
|
879 return die_("FLAC__metadata_object_new(FLAC__METADATA_TYPE_APPLICATION)");
|
Chris@1
|
880 memcpy(app->data.application.id, "duh", (FLAC__STREAM_METADATA_APPLICATION_ID_LEN/8));
|
Chris@1
|
881
|
Chris@1
|
882 printf("creating PADDING block\n");
|
Chris@1
|
883
|
Chris@1
|
884 if(0 == (padding = FLAC__metadata_object_new(FLAC__METADATA_TYPE_PADDING)))
|
Chris@1
|
885 return die_("FLAC__metadata_object_new(FLAC__METADATA_TYPE_PADDING)");
|
Chris@1
|
886 padding->length = 20;
|
Chris@1
|
887
|
Chris@1
|
888 if(0 == (iterator = FLAC__metadata_simple_iterator_new()))
|
Chris@1
|
889 return die_("FLAC__metadata_simple_iterator_new()");
|
Chris@1
|
890
|
Chris@1
|
891 if(!FLAC__metadata_simple_iterator_init(iterator, flacfilename(/*is_ogg=*/false), /*read_only=*/false, /*preserve_file_stats=*/false))
|
Chris@1
|
892 return die_("FLAC__metadata_simple_iterator_init() returned false");
|
Chris@1
|
893 our_current_position = 0;
|
Chris@1
|
894
|
Chris@1
|
895 printf("is writable = %u\n", (unsigned)FLAC__metadata_simple_iterator_is_writable(iterator));
|
Chris@1
|
896
|
Chris@1
|
897 printf("[S]VP\ttry to write over STREAMINFO block...\n");
|
Chris@1
|
898 if(!FLAC__metadata_simple_iterator_set_block(iterator, app, false))
|
Chris@1
|
899 printf("\tFLAC__metadata_simple_iterator_set_block() returned false like it should\n");
|
Chris@1
|
900 else
|
Chris@1
|
901 return die_("FLAC__metadata_simple_iterator_set_block() returned true but shouldn't have");
|
Chris@1
|
902
|
Chris@1
|
903 printf("[S]VP\tnext\n");
|
Chris@1
|
904 if(!FLAC__metadata_simple_iterator_next(iterator))
|
Chris@1
|
905 return die_("iterator ended early\n");
|
Chris@1
|
906 our_current_position++;
|
Chris@1
|
907
|
Chris@1
|
908 printf("S[V]P\tnext\n");
|
Chris@1
|
909 if(!FLAC__metadata_simple_iterator_next(iterator))
|
Chris@1
|
910 return die_("iterator ended early\n");
|
Chris@1
|
911 our_current_position++;
|
Chris@1
|
912
|
Chris@1
|
913 printf("SV[P]\tinsert PADDING after, don't expand into padding\n");
|
Chris@1
|
914 padding->length = 25;
|
Chris@1
|
915 if(!FLAC__metadata_simple_iterator_insert_block_after(iterator, padding, false))
|
Chris@1
|
916 return die_ss_("FLAC__metadata_simple_iterator_insert_block_after(iterator, padding, false)", iterator);
|
Chris@1
|
917 if(!insert_to_our_metadata_(padding, ++our_current_position, /*copy=*/true))
|
Chris@1
|
918 return false;
|
Chris@1
|
919
|
Chris@1
|
920 printf("SVP[P]\tprev\n");
|
Chris@1
|
921 if(!FLAC__metadata_simple_iterator_prev(iterator))
|
Chris@1
|
922 return die_("iterator ended early\n");
|
Chris@1
|
923 our_current_position--;
|
Chris@1
|
924
|
Chris@1
|
925 printf("SV[P]P\tprev\n");
|
Chris@1
|
926 if(!FLAC__metadata_simple_iterator_prev(iterator))
|
Chris@1
|
927 return die_("iterator ended early\n");
|
Chris@1
|
928 our_current_position--;
|
Chris@1
|
929
|
Chris@1
|
930 printf("S[V]PP\tinsert PADDING after, don't expand into padding\n");
|
Chris@1
|
931 padding->length = 30;
|
Chris@1
|
932 if(!FLAC__metadata_simple_iterator_insert_block_after(iterator, padding, false))
|
Chris@1
|
933 return die_ss_("FLAC__metadata_simple_iterator_insert_block_after(iterator, padding, false)", iterator);
|
Chris@1
|
934 if(!insert_to_our_metadata_(padding, ++our_current_position, /*copy=*/true))
|
Chris@1
|
935 return false;
|
Chris@1
|
936
|
Chris@1
|
937 if(!test_file_(/*is_ogg=*/false, decoder_metadata_callback_compare_))
|
Chris@1
|
938 return false;
|
Chris@1
|
939
|
Chris@1
|
940 printf("SV[P]PP\tprev\n");
|
Chris@1
|
941 if(!FLAC__metadata_simple_iterator_prev(iterator))
|
Chris@1
|
942 return die_("iterator ended early\n");
|
Chris@1
|
943 our_current_position--;
|
Chris@1
|
944
|
Chris@1
|
945 printf("S[V]PPP\tprev\n");
|
Chris@1
|
946 if(!FLAC__metadata_simple_iterator_prev(iterator))
|
Chris@1
|
947 return die_("iterator ended early\n");
|
Chris@1
|
948 our_current_position--;
|
Chris@1
|
949
|
Chris@1
|
950 printf("[S]VPPP\tdelete (STREAMINFO block), must fail\n");
|
Chris@1
|
951 if(FLAC__metadata_simple_iterator_delete_block(iterator, false))
|
Chris@1
|
952 return die_ss_("FLAC__metadata_simple_iterator_delete_block(iterator, false) should have returned false", iterator);
|
Chris@1
|
953
|
Chris@1
|
954 if(!test_file_(/*is_ogg=*/false, decoder_metadata_callback_compare_))
|
Chris@1
|
955 return false;
|
Chris@1
|
956
|
Chris@1
|
957 printf("[S]VPPP\tnext\n");
|
Chris@1
|
958 if(!FLAC__metadata_simple_iterator_next(iterator))
|
Chris@1
|
959 return die_("iterator ended early\n");
|
Chris@1
|
960 our_current_position++;
|
Chris@1
|
961
|
Chris@1
|
962 printf("S[V]PPP\tnext\n");
|
Chris@1
|
963 if(!FLAC__metadata_simple_iterator_next(iterator))
|
Chris@1
|
964 return die_("iterator ended early\n");
|
Chris@1
|
965 our_current_position++;
|
Chris@1
|
966
|
Chris@1
|
967 printf("SV[P]PP\tdelete (middle block), replace with padding\n");
|
Chris@1
|
968 if(!FLAC__metadata_simple_iterator_delete_block(iterator, true))
|
Chris@1
|
969 return die_ss_("FLAC__metadata_simple_iterator_delete_block(iterator, true)", iterator);
|
Chris@1
|
970 our_current_position--;
|
Chris@1
|
971
|
Chris@1
|
972 printf("S[V]PPP\tnext\n");
|
Chris@1
|
973 if(!FLAC__metadata_simple_iterator_next(iterator))
|
Chris@1
|
974 return die_("iterator ended early\n");
|
Chris@1
|
975 our_current_position++;
|
Chris@1
|
976
|
Chris@1
|
977 printf("SV[P]PP\tdelete (middle block), don't replace with padding\n");
|
Chris@1
|
978 if(!FLAC__metadata_simple_iterator_delete_block(iterator, false))
|
Chris@1
|
979 return die_ss_("FLAC__metadata_simple_iterator_delete_block(iterator, false)", iterator);
|
Chris@1
|
980 delete_from_our_metadata_(our_current_position--);
|
Chris@1
|
981
|
Chris@1
|
982 if(!test_file_(/*is_ogg=*/false, decoder_metadata_callback_compare_))
|
Chris@1
|
983 return false;
|
Chris@1
|
984
|
Chris@1
|
985 printf("S[V]PP\tnext\n");
|
Chris@1
|
986 if(!FLAC__metadata_simple_iterator_next(iterator))
|
Chris@1
|
987 return die_("iterator ended early\n");
|
Chris@1
|
988 our_current_position++;
|
Chris@1
|
989
|
Chris@1
|
990 printf("SV[P]P\tnext\n");
|
Chris@1
|
991 if(!FLAC__metadata_simple_iterator_next(iterator))
|
Chris@1
|
992 return die_("iterator ended early\n");
|
Chris@1
|
993 our_current_position++;
|
Chris@1
|
994
|
Chris@1
|
995 printf("SVP[P]\tdelete (last block), replace with padding\n");
|
Chris@1
|
996 if(!FLAC__metadata_simple_iterator_delete_block(iterator, true))
|
Chris@1
|
997 return die_ss_("FLAC__metadata_simple_iterator_delete_block(iterator, false)", iterator);
|
Chris@1
|
998 our_current_position--;
|
Chris@1
|
999
|
Chris@1
|
1000 if(!test_file_(/*is_ogg=*/false, decoder_metadata_callback_compare_))
|
Chris@1
|
1001 return false;
|
Chris@1
|
1002
|
Chris@1
|
1003 printf("SV[P]P\tnext\n");
|
Chris@1
|
1004 if(!FLAC__metadata_simple_iterator_next(iterator))
|
Chris@1
|
1005 return die_("iterator ended early\n");
|
Chris@1
|
1006 our_current_position++;
|
Chris@1
|
1007
|
Chris@1
|
1008 printf("SVP[P]\tdelete (last block), don't replace with padding\n");
|
Chris@1
|
1009 if(!FLAC__metadata_simple_iterator_delete_block(iterator, false))
|
Chris@1
|
1010 return die_ss_("FLAC__metadata_simple_iterator_delete_block(iterator, false)", iterator);
|
Chris@1
|
1011 delete_from_our_metadata_(our_current_position--);
|
Chris@1
|
1012
|
Chris@1
|
1013 if(!test_file_(/*is_ogg=*/false, decoder_metadata_callback_compare_))
|
Chris@1
|
1014 return false;
|
Chris@1
|
1015
|
Chris@1
|
1016 printf("SV[P]\tprev\n");
|
Chris@1
|
1017 if(!FLAC__metadata_simple_iterator_prev(iterator))
|
Chris@1
|
1018 return die_("iterator ended early\n");
|
Chris@1
|
1019 our_current_position--;
|
Chris@1
|
1020
|
Chris@1
|
1021 printf("S[V]P\tprev\n");
|
Chris@1
|
1022 if(!FLAC__metadata_simple_iterator_prev(iterator))
|
Chris@1
|
1023 return die_("iterator ended early\n");
|
Chris@1
|
1024 our_current_position--;
|
Chris@1
|
1025
|
Chris@1
|
1026 printf("[S]VP\tset STREAMINFO (change sample rate)\n");
|
Chris@1
|
1027 FLAC__ASSERT(our_current_position == 0);
|
Chris@1
|
1028 block = FLAC__metadata_simple_iterator_get_block(iterator);
|
Chris@1
|
1029 block->data.stream_info.sample_rate = 32000;
|
Chris@1
|
1030 if(!replace_in_our_metadata_(block, our_current_position, /*copy=*/true))
|
Chris@1
|
1031 return die_("copying object");
|
Chris@1
|
1032 if(!FLAC__metadata_simple_iterator_set_block(iterator, block, false))
|
Chris@1
|
1033 return die_ss_("FLAC__metadata_simple_iterator_set_block(iterator, block, false)", iterator);
|
Chris@1
|
1034 FLAC__metadata_object_delete(block);
|
Chris@1
|
1035
|
Chris@1
|
1036 if(!test_file_(/*is_ogg=*/false, decoder_metadata_callback_compare_))
|
Chris@1
|
1037 return false;
|
Chris@1
|
1038
|
Chris@1
|
1039 printf("[S]VP\tnext\n");
|
Chris@1
|
1040 if(!FLAC__metadata_simple_iterator_next(iterator))
|
Chris@1
|
1041 return die_("iterator ended early\n");
|
Chris@1
|
1042 our_current_position++;
|
Chris@1
|
1043
|
Chris@1
|
1044 printf("S[V]P\tinsert APPLICATION after, expand into padding of exceeding size\n");
|
Chris@1
|
1045 app->data.application.id[0] = 'e'; /* twiddle the id so that our comparison doesn't miss transposition */
|
Chris@1
|
1046 if(!FLAC__metadata_simple_iterator_insert_block_after(iterator, app, true))
|
Chris@1
|
1047 return die_ss_("FLAC__metadata_simple_iterator_insert_block_after(iterator, app, true)", iterator);
|
Chris@1
|
1048 if(!insert_to_our_metadata_(app, ++our_current_position, /*copy=*/true))
|
Chris@1
|
1049 return false;
|
Chris@1
|
1050 our_metadata_.blocks[our_current_position+1]->length -= (FLAC__STREAM_METADATA_APPLICATION_ID_LEN/8) + app->length;
|
Chris@1
|
1051
|
Chris@1
|
1052 if(!test_file_(/*is_ogg=*/false, decoder_metadata_callback_compare_))
|
Chris@1
|
1053 return false;
|
Chris@1
|
1054
|
Chris@1
|
1055 printf("SV[A]P\tnext\n");
|
Chris@1
|
1056 if(!FLAC__metadata_simple_iterator_next(iterator))
|
Chris@1
|
1057 return die_("iterator ended early\n");
|
Chris@1
|
1058 our_current_position++;
|
Chris@1
|
1059
|
Chris@1
|
1060 printf("SVA[P]\tset APPLICATION, expand into padding of exceeding size\n");
|
Chris@1
|
1061 app->data.application.id[0] = 'f'; /* twiddle the id */
|
Chris@1
|
1062 if(!FLAC__metadata_simple_iterator_set_block(iterator, app, true))
|
Chris@1
|
1063 return die_ss_("FLAC__metadata_simple_iterator_set_block(iterator, app, true)", iterator);
|
Chris@1
|
1064 if(!insert_to_our_metadata_(app, our_current_position, /*copy=*/true))
|
Chris@1
|
1065 return false;
|
Chris@1
|
1066 our_metadata_.blocks[our_current_position+1]->length -= (FLAC__STREAM_METADATA_APPLICATION_ID_LEN/8) + app->length;
|
Chris@1
|
1067
|
Chris@1
|
1068 if(!test_file_(/*is_ogg=*/false, decoder_metadata_callback_compare_))
|
Chris@1
|
1069 return false;
|
Chris@1
|
1070
|
Chris@1
|
1071 printf("SVA[A]P\tset APPLICATION (grow), don't expand into padding\n");
|
Chris@1
|
1072 app->data.application.id[0] = 'g'; /* twiddle the id */
|
Chris@1
|
1073 if(!FLAC__metadata_object_application_set_data(app, data, sizeof(data), true))
|
Chris@1
|
1074 return die_("setting APPLICATION data");
|
Chris@1
|
1075 if(!replace_in_our_metadata_(app, our_current_position, /*copy=*/true))
|
Chris@1
|
1076 return die_("copying object");
|
Chris@1
|
1077 if(!FLAC__metadata_simple_iterator_set_block(iterator, app, false))
|
Chris@1
|
1078 return die_ss_("FLAC__metadata_simple_iterator_set_block(iterator, app, false)", iterator);
|
Chris@1
|
1079
|
Chris@1
|
1080 if(!test_file_(/*is_ogg=*/false, decoder_metadata_callback_compare_))
|
Chris@1
|
1081 return false;
|
Chris@1
|
1082
|
Chris@1
|
1083 printf("SVA[A]P\tset APPLICATION (shrink), don't fill in with padding\n");
|
Chris@1
|
1084 app->data.application.id[0] = 'h'; /* twiddle the id */
|
Chris@1
|
1085 if(!FLAC__metadata_object_application_set_data(app, data, 12, true))
|
Chris@1
|
1086 return die_("setting APPLICATION data");
|
Chris@1
|
1087 if(!replace_in_our_metadata_(app, our_current_position, /*copy=*/true))
|
Chris@1
|
1088 return die_("copying object");
|
Chris@1
|
1089 if(!FLAC__metadata_simple_iterator_set_block(iterator, app, false))
|
Chris@1
|
1090 return die_ss_("FLAC__metadata_simple_iterator_set_block(iterator, app, false)", iterator);
|
Chris@1
|
1091
|
Chris@1
|
1092 if(!test_file_(/*is_ogg=*/false, decoder_metadata_callback_compare_))
|
Chris@1
|
1093 return false;
|
Chris@1
|
1094
|
Chris@1
|
1095 printf("SVA[A]P\tset APPLICATION (grow), expand into padding of exceeding size\n");
|
Chris@1
|
1096 app->data.application.id[0] = 'i'; /* twiddle the id */
|
Chris@1
|
1097 if(!FLAC__metadata_object_application_set_data(app, data, sizeof(data), true))
|
Chris@1
|
1098 return die_("setting APPLICATION data");
|
Chris@1
|
1099 if(!replace_in_our_metadata_(app, our_current_position, /*copy=*/true))
|
Chris@1
|
1100 return die_("copying object");
|
Chris@1
|
1101 our_metadata_.blocks[our_current_position+1]->length -= (sizeof(data) - 12);
|
Chris@1
|
1102 if(!FLAC__metadata_simple_iterator_set_block(iterator, app, true))
|
Chris@1
|
1103 return die_ss_("FLAC__metadata_simple_iterator_set_block(iterator, app, true)", iterator);
|
Chris@1
|
1104
|
Chris@1
|
1105 if(!test_file_(/*is_ogg=*/false, decoder_metadata_callback_compare_))
|
Chris@1
|
1106 return false;
|
Chris@1
|
1107
|
Chris@1
|
1108 printf("SVA[A]P\tset APPLICATION (shrink), fill in with padding\n");
|
Chris@1
|
1109 app->data.application.id[0] = 'j'; /* twiddle the id */
|
Chris@1
|
1110 if(!FLAC__metadata_object_application_set_data(app, data, 23, true))
|
Chris@1
|
1111 return die_("setting APPLICATION data");
|
Chris@1
|
1112 if(!replace_in_our_metadata_(app, our_current_position, /*copy=*/true))
|
Chris@1
|
1113 return die_("copying object");
|
Chris@1
|
1114 if(!insert_to_our_metadata_(padding, our_current_position+1, /*copy=*/true))
|
Chris@1
|
1115 return die_("copying object");
|
Chris@1
|
1116 our_metadata_.blocks[our_current_position+1]->length = sizeof(data) - 23 - FLAC__STREAM_METADATA_HEADER_LENGTH;
|
Chris@1
|
1117 if(!FLAC__metadata_simple_iterator_set_block(iterator, app, true))
|
Chris@1
|
1118 return die_ss_("FLAC__metadata_simple_iterator_set_block(iterator, app, true)", iterator);
|
Chris@1
|
1119
|
Chris@1
|
1120 if(!test_file_(/*is_ogg=*/false, decoder_metadata_callback_compare_))
|
Chris@1
|
1121 return false;
|
Chris@1
|
1122
|
Chris@1
|
1123 printf("SVA[A]PP\tnext\n");
|
Chris@1
|
1124 if(!FLAC__metadata_simple_iterator_next(iterator))
|
Chris@1
|
1125 return die_("iterator ended early\n");
|
Chris@1
|
1126 our_current_position++;
|
Chris@1
|
1127
|
Chris@1
|
1128 printf("SVAA[P]P\tnext\n");
|
Chris@1
|
1129 if(!FLAC__metadata_simple_iterator_next(iterator))
|
Chris@1
|
1130 return die_("iterator ended early\n");
|
Chris@1
|
1131 our_current_position++;
|
Chris@1
|
1132
|
Chris@1
|
1133 printf("SVAAP[P]\tset PADDING (shrink), don't fill in with padding\n");
|
Chris@1
|
1134 padding->length = 5;
|
Chris@1
|
1135 if(!replace_in_our_metadata_(padding, our_current_position, /*copy=*/true))
|
Chris@1
|
1136 return die_("copying object");
|
Chris@1
|
1137 if(!FLAC__metadata_simple_iterator_set_block(iterator, padding, false))
|
Chris@1
|
1138 return die_ss_("FLAC__metadata_simple_iterator_set_block(iterator, padding, false)", iterator);
|
Chris@1
|
1139
|
Chris@1
|
1140 if(!test_file_(/*is_ogg=*/false, decoder_metadata_callback_compare_))
|
Chris@1
|
1141 return false;
|
Chris@1
|
1142
|
Chris@1
|
1143 printf("SVAAP[P]\tset APPLICATION (grow)\n");
|
Chris@1
|
1144 app->data.application.id[0] = 'k'; /* twiddle the id */
|
Chris@1
|
1145 if(!replace_in_our_metadata_(app, our_current_position, /*copy=*/true))
|
Chris@1
|
1146 return die_("copying object");
|
Chris@1
|
1147 if(!FLAC__metadata_simple_iterator_set_block(iterator, app, false))
|
Chris@1
|
1148 return die_ss_("FLAC__metadata_simple_iterator_set_block(iterator, app, false)", iterator);
|
Chris@1
|
1149
|
Chris@1
|
1150 if(!test_file_(/*is_ogg=*/false, decoder_metadata_callback_compare_))
|
Chris@1
|
1151 return false;
|
Chris@1
|
1152
|
Chris@1
|
1153 printf("SVAAP[A]\tset PADDING (equal)\n");
|
Chris@1
|
1154 padding->length = 27;
|
Chris@1
|
1155 if(!replace_in_our_metadata_(padding, our_current_position, /*copy=*/true))
|
Chris@1
|
1156 return die_("copying object");
|
Chris@1
|
1157 if(!FLAC__metadata_simple_iterator_set_block(iterator, padding, false))
|
Chris@1
|
1158 return die_ss_("FLAC__metadata_simple_iterator_set_block(iterator, padding, false)", iterator);
|
Chris@1
|
1159
|
Chris@1
|
1160 if(!test_file_(/*is_ogg=*/false, decoder_metadata_callback_compare_))
|
Chris@1
|
1161 return false;
|
Chris@1
|
1162
|
Chris@1
|
1163 printf("SVAAP[P]\tprev\n");
|
Chris@1
|
1164 if(!FLAC__metadata_simple_iterator_prev(iterator))
|
Chris@1
|
1165 return die_("iterator ended early\n");
|
Chris@1
|
1166 our_current_position--;
|
Chris@1
|
1167
|
Chris@1
|
1168 printf("SVAA[P]P\tdelete (middle block), don't replace with padding\n");
|
Chris@1
|
1169 if(!FLAC__metadata_simple_iterator_delete_block(iterator, false))
|
Chris@1
|
1170 return die_ss_("FLAC__metadata_simple_iterator_delete_block(iterator, false)", iterator);
|
Chris@1
|
1171 delete_from_our_metadata_(our_current_position--);
|
Chris@1
|
1172
|
Chris@1
|
1173 if(!test_file_(/*is_ogg=*/false, decoder_metadata_callback_compare_))
|
Chris@1
|
1174 return false;
|
Chris@1
|
1175
|
Chris@1
|
1176 printf("SVA[A]P\tdelete (middle block), don't replace with padding\n");
|
Chris@1
|
1177 if(!FLAC__metadata_simple_iterator_delete_block(iterator, false))
|
Chris@1
|
1178 return die_ss_("FLAC__metadata_simple_iterator_delete_block(iterator, false)", iterator);
|
Chris@1
|
1179 delete_from_our_metadata_(our_current_position--);
|
Chris@1
|
1180
|
Chris@1
|
1181 if(!test_file_(/*is_ogg=*/false, decoder_metadata_callback_compare_))
|
Chris@1
|
1182 return false;
|
Chris@1
|
1183
|
Chris@1
|
1184 printf("SV[A]P\tnext\n");
|
Chris@1
|
1185 if(!FLAC__metadata_simple_iterator_next(iterator))
|
Chris@1
|
1186 return die_("iterator ended early\n");
|
Chris@1
|
1187 our_current_position++;
|
Chris@1
|
1188
|
Chris@1
|
1189 printf("SVA[P]\tinsert PADDING after\n");
|
Chris@1
|
1190 padding->length = 5;
|
Chris@1
|
1191 if(!FLAC__metadata_simple_iterator_insert_block_after(iterator, padding, false))
|
Chris@1
|
1192 return die_ss_("FLAC__metadata_simple_iterator_insert_block_after(iterator, padding, false)", iterator);
|
Chris@1
|
1193 if(!insert_to_our_metadata_(padding, ++our_current_position, /*copy=*/true))
|
Chris@1
|
1194 return false;
|
Chris@1
|
1195
|
Chris@1
|
1196 if(!test_file_(/*is_ogg=*/false, decoder_metadata_callback_compare_))
|
Chris@1
|
1197 return false;
|
Chris@1
|
1198
|
Chris@1
|
1199 printf("SVAP[P]\tprev\n");
|
Chris@1
|
1200 if(!FLAC__metadata_simple_iterator_prev(iterator))
|
Chris@1
|
1201 return die_("iterator ended early\n");
|
Chris@1
|
1202 our_current_position--;
|
Chris@1
|
1203
|
Chris@1
|
1204 printf("SVA[P]P\tprev\n");
|
Chris@1
|
1205 if(!FLAC__metadata_simple_iterator_prev(iterator))
|
Chris@1
|
1206 return die_("iterator ended early\n");
|
Chris@1
|
1207 our_current_position--;
|
Chris@1
|
1208
|
Chris@1
|
1209 printf("SV[A]PP\tset APPLICATION (grow), try to expand into padding which is too small\n");
|
Chris@1
|
1210 if(!FLAC__metadata_object_application_set_data(app, data, 32, true))
|
Chris@1
|
1211 return die_("setting APPLICATION data");
|
Chris@1
|
1212 if(!replace_in_our_metadata_(app, our_current_position, /*copy=*/true))
|
Chris@1
|
1213 return die_("copying object");
|
Chris@1
|
1214 if(!FLAC__metadata_simple_iterator_set_block(iterator, app, true))
|
Chris@1
|
1215 return die_ss_("FLAC__metadata_simple_iterator_set_block(iterator, app, true)", iterator);
|
Chris@1
|
1216
|
Chris@1
|
1217 if(!test_file_(/*is_ogg=*/false, decoder_metadata_callback_compare_))
|
Chris@1
|
1218 return false;
|
Chris@1
|
1219
|
Chris@1
|
1220 printf("SV[A]PP\tset APPLICATION (grow), try to expand into padding which is 'close' but still too small\n");
|
Chris@1
|
1221 if(!FLAC__metadata_object_application_set_data(app, data, 60, true))
|
Chris@1
|
1222 return die_("setting APPLICATION data");
|
Chris@1
|
1223 if(!replace_in_our_metadata_(app, our_current_position, /*copy=*/true))
|
Chris@1
|
1224 return die_("copying object");
|
Chris@1
|
1225 if(!FLAC__metadata_simple_iterator_set_block(iterator, app, true))
|
Chris@1
|
1226 return die_ss_("FLAC__metadata_simple_iterator_set_block(iterator, app, true)", iterator);
|
Chris@1
|
1227
|
Chris@1
|
1228 if(!test_file_(/*is_ogg=*/false, decoder_metadata_callback_compare_))
|
Chris@1
|
1229 return false;
|
Chris@1
|
1230
|
Chris@1
|
1231 printf("SV[A]PP\tset APPLICATION (grow), expand into padding which will leave 0-length pad\n");
|
Chris@1
|
1232 if(!FLAC__metadata_object_application_set_data(app, data, 87, true))
|
Chris@1
|
1233 return die_("setting APPLICATION data");
|
Chris@1
|
1234 if(!replace_in_our_metadata_(app, our_current_position, /*copy=*/true))
|
Chris@1
|
1235 return die_("copying object");
|
Chris@1
|
1236 our_metadata_.blocks[our_current_position+1]->length = 0;
|
Chris@1
|
1237 if(!FLAC__metadata_simple_iterator_set_block(iterator, app, true))
|
Chris@1
|
1238 return die_ss_("FLAC__metadata_simple_iterator_set_block(iterator, app, true)", iterator);
|
Chris@1
|
1239
|
Chris@1
|
1240 if(!test_file_(/*is_ogg=*/false, decoder_metadata_callback_compare_))
|
Chris@1
|
1241 return false;
|
Chris@1
|
1242
|
Chris@1
|
1243 printf("SV[A]PP\tset APPLICATION (grow), expand into padding which is exactly consumed\n");
|
Chris@1
|
1244 if(!FLAC__metadata_object_application_set_data(app, data, 91, true))
|
Chris@1
|
1245 return die_("setting APPLICATION data");
|
Chris@1
|
1246 if(!replace_in_our_metadata_(app, our_current_position, /*copy=*/true))
|
Chris@1
|
1247 return die_("copying object");
|
Chris@1
|
1248 delete_from_our_metadata_(our_current_position+1);
|
Chris@1
|
1249 if(!FLAC__metadata_simple_iterator_set_block(iterator, app, true))
|
Chris@1
|
1250 return die_ss_("FLAC__metadata_simple_iterator_set_block(iterator, app, true)", iterator);
|
Chris@1
|
1251
|
Chris@1
|
1252 if(!test_file_(/*is_ogg=*/false, decoder_metadata_callback_compare_))
|
Chris@1
|
1253 return false;
|
Chris@1
|
1254
|
Chris@1
|
1255 printf("SV[A]P\tset APPLICATION (grow), expand into padding which is exactly consumed\n");
|
Chris@1
|
1256 if(!FLAC__metadata_object_application_set_data(app, data, 100, true))
|
Chris@1
|
1257 return die_("setting APPLICATION data");
|
Chris@1
|
1258 if(!replace_in_our_metadata_(app, our_current_position, /*copy=*/true))
|
Chris@1
|
1259 return die_("copying object");
|
Chris@1
|
1260 delete_from_our_metadata_(our_current_position+1);
|
Chris@1
|
1261 our_metadata_.blocks[our_current_position]->is_last = true;
|
Chris@1
|
1262 if(!FLAC__metadata_simple_iterator_set_block(iterator, app, true))
|
Chris@1
|
1263 return die_ss_("FLAC__metadata_simple_iterator_set_block(iterator, app, true)", iterator);
|
Chris@1
|
1264
|
Chris@1
|
1265 if(!test_file_(/*is_ogg=*/false, decoder_metadata_callback_compare_))
|
Chris@1
|
1266 return false;
|
Chris@1
|
1267
|
Chris@1
|
1268 printf("SV[A]\tset PADDING (equal size)\n");
|
Chris@1
|
1269 padding->length = app->length;
|
Chris@1
|
1270 if(!replace_in_our_metadata_(padding, our_current_position, /*copy=*/true))
|
Chris@1
|
1271 return die_("copying object");
|
Chris@1
|
1272 if(!FLAC__metadata_simple_iterator_set_block(iterator, padding, true))
|
Chris@1
|
1273 return die_ss_("FLAC__metadata_simple_iterator_set_block(iterator, padding, true)", iterator);
|
Chris@1
|
1274
|
Chris@1
|
1275 if(!test_file_(/*is_ogg=*/false, decoder_metadata_callback_compare_))
|
Chris@1
|
1276 return false;
|
Chris@1
|
1277
|
Chris@1
|
1278 printf("SV[P]\tinsert PADDING after\n");
|
Chris@1
|
1279 if(!FLAC__metadata_simple_iterator_insert_block_after(iterator, padding, false))
|
Chris@1
|
1280 return die_ss_("FLAC__metadata_simple_iterator_insert_block_after(iterator, padding, false)", iterator);
|
Chris@1
|
1281 if(!insert_to_our_metadata_(padding, ++our_current_position, /*copy=*/true))
|
Chris@1
|
1282 return false;
|
Chris@1
|
1283
|
Chris@1
|
1284 if(!test_file_(/*is_ogg=*/false, decoder_metadata_callback_compare_))
|
Chris@1
|
1285 return false;
|
Chris@1
|
1286
|
Chris@1
|
1287 printf("SVP[P]\tinsert PADDING after\n");
|
Chris@1
|
1288 padding->length = 5;
|
Chris@1
|
1289 if(!FLAC__metadata_simple_iterator_insert_block_after(iterator, padding, false))
|
Chris@1
|
1290 return die_ss_("FLAC__metadata_simple_iterator_insert_block_after(iterator, padding, false)", iterator);
|
Chris@1
|
1291 if(!insert_to_our_metadata_(padding, ++our_current_position, /*copy=*/true))
|
Chris@1
|
1292 return false;
|
Chris@1
|
1293
|
Chris@1
|
1294 if(!test_file_(/*is_ogg=*/false, decoder_metadata_callback_compare_))
|
Chris@1
|
1295 return false;
|
Chris@1
|
1296
|
Chris@1
|
1297 printf("SVPP[P]\tprev\n");
|
Chris@1
|
1298 if(!FLAC__metadata_simple_iterator_prev(iterator))
|
Chris@1
|
1299 return die_("iterator ended early\n");
|
Chris@1
|
1300 our_current_position--;
|
Chris@1
|
1301
|
Chris@1
|
1302 printf("SVP[P]P\tprev\n");
|
Chris@1
|
1303 if(!FLAC__metadata_simple_iterator_prev(iterator))
|
Chris@1
|
1304 return die_("iterator ended early\n");
|
Chris@1
|
1305 our_current_position--;
|
Chris@1
|
1306
|
Chris@1
|
1307 printf("SV[P]PP\tprev\n");
|
Chris@1
|
1308 if(!FLAC__metadata_simple_iterator_prev(iterator))
|
Chris@1
|
1309 return die_("iterator ended early\n");
|
Chris@1
|
1310 our_current_position--;
|
Chris@1
|
1311
|
Chris@1
|
1312 printf("S[V]PPP\tinsert APPLICATION after, try to expand into padding which is too small\n");
|
Chris@1
|
1313 if(!FLAC__metadata_object_application_set_data(app, data, 101, true))
|
Chris@1
|
1314 return die_("setting APPLICATION data");
|
Chris@1
|
1315 if(!insert_to_our_metadata_(app, ++our_current_position, /*copy=*/true))
|
Chris@1
|
1316 return die_("copying object");
|
Chris@1
|
1317 if(!FLAC__metadata_simple_iterator_insert_block_after(iterator, app, true))
|
Chris@1
|
1318 return die_ss_("FLAC__metadata_simple_iterator_insert_block_after(iterator, app, true)", iterator);
|
Chris@1
|
1319
|
Chris@1
|
1320 if(!test_file_(/*is_ogg=*/false, decoder_metadata_callback_compare_))
|
Chris@1
|
1321 return false;
|
Chris@1
|
1322
|
Chris@1
|
1323 printf("SV[A]PPP\tdelete (middle block), don't replace with padding\n");
|
Chris@1
|
1324 if(!FLAC__metadata_simple_iterator_delete_block(iterator, false))
|
Chris@1
|
1325 return die_ss_("FLAC__metadata_simple_iterator_delete_block(iterator, false)", iterator);
|
Chris@1
|
1326 delete_from_our_metadata_(our_current_position--);
|
Chris@1
|
1327
|
Chris@1
|
1328 if(!test_file_(/*is_ogg=*/false, decoder_metadata_callback_compare_))
|
Chris@1
|
1329 return false;
|
Chris@1
|
1330
|
Chris@1
|
1331 printf("S[V]PPP\tinsert APPLICATION after, try to expand into padding which is 'close' but still too small\n");
|
Chris@1
|
1332 if(!FLAC__metadata_object_application_set_data(app, data, 97, true))
|
Chris@1
|
1333 return die_("setting APPLICATION data");
|
Chris@1
|
1334 if(!insert_to_our_metadata_(app, ++our_current_position, /*copy=*/true))
|
Chris@1
|
1335 return die_("copying object");
|
Chris@1
|
1336 if(!FLAC__metadata_simple_iterator_insert_block_after(iterator, app, true))
|
Chris@1
|
1337 return die_ss_("FLAC__metadata_simple_iterator_insert_block_after(iterator, app, true)", iterator);
|
Chris@1
|
1338
|
Chris@1
|
1339 if(!test_file_(/*is_ogg=*/false, decoder_metadata_callback_compare_))
|
Chris@1
|
1340 return false;
|
Chris@1
|
1341
|
Chris@1
|
1342 printf("SV[A]PPP\tdelete (middle block), don't replace with padding\n");
|
Chris@1
|
1343 if(!FLAC__metadata_simple_iterator_delete_block(iterator, false))
|
Chris@1
|
1344 return die_ss_("FLAC__metadata_simple_iterator_delete_block(iterator, false)", iterator);
|
Chris@1
|
1345 delete_from_our_metadata_(our_current_position--);
|
Chris@1
|
1346
|
Chris@1
|
1347 if(!test_file_(/*is_ogg=*/false, decoder_metadata_callback_compare_))
|
Chris@1
|
1348 return false;
|
Chris@1
|
1349
|
Chris@1
|
1350 printf("S[V]PPP\tinsert APPLICATION after, expand into padding which is exactly consumed\n");
|
Chris@1
|
1351 if(!FLAC__metadata_object_application_set_data(app, data, 100, true))
|
Chris@1
|
1352 return die_("setting APPLICATION data");
|
Chris@1
|
1353 if(!insert_to_our_metadata_(app, ++our_current_position, /*copy=*/true))
|
Chris@1
|
1354 return die_("copying object");
|
Chris@1
|
1355 delete_from_our_metadata_(our_current_position+1);
|
Chris@1
|
1356 if(!FLAC__metadata_simple_iterator_insert_block_after(iterator, app, true))
|
Chris@1
|
1357 return die_ss_("FLAC__metadata_simple_iterator_insert_block_after(iterator, app, true)", iterator);
|
Chris@1
|
1358
|
Chris@1
|
1359 if(!test_file_(/*is_ogg=*/false, decoder_metadata_callback_compare_))
|
Chris@1
|
1360 return false;
|
Chris@1
|
1361
|
Chris@1
|
1362 printf("SV[A]PP\tdelete (middle block), don't replace with padding\n");
|
Chris@1
|
1363 if(!FLAC__metadata_simple_iterator_delete_block(iterator, false))
|
Chris@1
|
1364 return die_ss_("FLAC__metadata_simple_iterator_delete_block(iterator, false)", iterator);
|
Chris@1
|
1365 delete_from_our_metadata_(our_current_position--);
|
Chris@1
|
1366
|
Chris@1
|
1367 if(!test_file_(/*is_ogg=*/false, decoder_metadata_callback_compare_))
|
Chris@1
|
1368 return false;
|
Chris@1
|
1369
|
Chris@1
|
1370 printf("S[V]PP\tinsert APPLICATION after, expand into padding which will leave 0-length pad\n");
|
Chris@1
|
1371 if(!FLAC__metadata_object_application_set_data(app, data, 96, true))
|
Chris@1
|
1372 return die_("setting APPLICATION data");
|
Chris@1
|
1373 if(!insert_to_our_metadata_(app, ++our_current_position, /*copy=*/true))
|
Chris@1
|
1374 return die_("copying object");
|
Chris@1
|
1375 our_metadata_.blocks[our_current_position+1]->length = 0;
|
Chris@1
|
1376 if(!FLAC__metadata_simple_iterator_insert_block_after(iterator, app, true))
|
Chris@1
|
1377 return die_ss_("FLAC__metadata_simple_iterator_insert_block_after(iterator, app, true)", iterator);
|
Chris@1
|
1378
|
Chris@1
|
1379 if(!test_file_(/*is_ogg=*/false, decoder_metadata_callback_compare_))
|
Chris@1
|
1380 return false;
|
Chris@1
|
1381
|
Chris@1
|
1382 printf("SV[A]PP\tdelete (middle block), don't replace with padding\n");
|
Chris@1
|
1383 if(!FLAC__metadata_simple_iterator_delete_block(iterator, false))
|
Chris@1
|
1384 return die_ss_("FLAC__metadata_simple_iterator_delete_block(iterator, false)", iterator);
|
Chris@1
|
1385 delete_from_our_metadata_(our_current_position--);
|
Chris@1
|
1386
|
Chris@1
|
1387 if(!test_file_(/*is_ogg=*/false, decoder_metadata_callback_compare_))
|
Chris@1
|
1388 return false;
|
Chris@1
|
1389
|
Chris@1
|
1390 printf("S[V]PP\tnext\n");
|
Chris@1
|
1391 if(!FLAC__metadata_simple_iterator_next(iterator))
|
Chris@1
|
1392 return die_("iterator ended early\n");
|
Chris@1
|
1393 our_current_position++;
|
Chris@1
|
1394
|
Chris@1
|
1395 printf("SV[P]P\tdelete (middle block), don't replace with padding\n");
|
Chris@1
|
1396 if(!FLAC__metadata_simple_iterator_delete_block(iterator, false))
|
Chris@1
|
1397 return die_ss_("FLAC__metadata_simple_iterator_delete_block(iterator, false)", iterator);
|
Chris@1
|
1398 delete_from_our_metadata_(our_current_position--);
|
Chris@1
|
1399
|
Chris@1
|
1400 if(!test_file_(/*is_ogg=*/false, decoder_metadata_callback_compare_))
|
Chris@1
|
1401 return false;
|
Chris@1
|
1402
|
Chris@1
|
1403 printf("S[V]P\tinsert APPLICATION after, expand into padding which is exactly consumed\n");
|
Chris@1
|
1404 if(!FLAC__metadata_object_application_set_data(app, data, 1, true))
|
Chris@1
|
1405 return die_("setting APPLICATION data");
|
Chris@1
|
1406 if(!insert_to_our_metadata_(app, ++our_current_position, /*copy=*/true))
|
Chris@1
|
1407 return die_("copying object");
|
Chris@1
|
1408 delete_from_our_metadata_(our_current_position+1);
|
Chris@1
|
1409 if(!FLAC__metadata_simple_iterator_insert_block_after(iterator, app, true))
|
Chris@1
|
1410 return die_ss_("FLAC__metadata_simple_iterator_insert_block_after(iterator, app, true)", iterator);
|
Chris@1
|
1411
|
Chris@1
|
1412 if(!test_file_(/*is_ogg=*/false, decoder_metadata_callback_compare_))
|
Chris@1
|
1413 return false;
|
Chris@1
|
1414
|
Chris@1
|
1415 printf("delete simple iterator\n");
|
Chris@1
|
1416
|
Chris@1
|
1417 FLAC__metadata_simple_iterator_delete(iterator);
|
Chris@1
|
1418
|
Chris@1
|
1419 FLAC__metadata_object_delete(app);
|
Chris@1
|
1420 FLAC__metadata_object_delete(padding);
|
Chris@1
|
1421
|
Chris@1
|
1422 if(!remove_file_(flacfilename(/*is_ogg=*/false)))
|
Chris@1
|
1423 return false;
|
Chris@1
|
1424
|
Chris@1
|
1425 return true;
|
Chris@1
|
1426 }
|
Chris@1
|
1427
|
Chris@1
|
1428 static FLAC__bool test_level_2_(FLAC__bool filename_based, FLAC__bool is_ogg)
|
Chris@1
|
1429 {
|
Chris@1
|
1430 FLAC__Metadata_Iterator *iterator;
|
Chris@1
|
1431 FLAC__Metadata_Chain *chain;
|
Chris@1
|
1432 FLAC__StreamMetadata *block, *app, *padding;
|
Chris@1
|
1433 FLAC__byte data[2000];
|
Chris@1
|
1434 unsigned our_current_position;
|
Chris@1
|
1435
|
Chris@1
|
1436 /* initialize 'data' to avoid Valgrind errors */
|
Chris@1
|
1437 memset(data, 0, sizeof(data));
|
Chris@1
|
1438
|
Chris@1
|
1439 printf("\n\n++++++ testing level 2 interface (%s-based, %s FLAC)\n", filename_based? "filename":"callback", is_ogg? "Ogg":"native");
|
Chris@1
|
1440
|
Chris@1
|
1441 printf("generate read-only file\n");
|
Chris@1
|
1442
|
Chris@1
|
1443 if(!generate_file_(/*include_extras=*/false, is_ogg))
|
Chris@1
|
1444 return false;
|
Chris@1
|
1445
|
Chris@1
|
1446 if(!change_stats_(flacfilename(is_ogg), /*read_only=*/true))
|
Chris@1
|
1447 return false;
|
Chris@1
|
1448
|
Chris@1
|
1449 printf("create chain\n");
|
Chris@1
|
1450
|
Chris@1
|
1451 if(0 == (chain = FLAC__metadata_chain_new()))
|
Chris@1
|
1452 return die_("allocating chain");
|
Chris@1
|
1453
|
Chris@1
|
1454 printf("read chain\n");
|
Chris@1
|
1455
|
Chris@1
|
1456 if(!read_chain_(chain, flacfilename(is_ogg), filename_based, is_ogg))
|
Chris@1
|
1457 return die_c_("reading chain", FLAC__metadata_chain_status(chain));
|
Chris@1
|
1458
|
Chris@1
|
1459 printf("[S]VP\ttest initial metadata\n");
|
Chris@1
|
1460
|
Chris@1
|
1461 if(!compare_chain_(chain, 0, 0))
|
Chris@1
|
1462 return false;
|
Chris@1
|
1463 if(!test_file_(is_ogg, decoder_metadata_callback_compare_))
|
Chris@1
|
1464 return false;
|
Chris@1
|
1465
|
Chris@1
|
1466 if(is_ogg)
|
Chris@1
|
1467 goto end;
|
Chris@1
|
1468
|
Chris@1
|
1469 printf("switch file to read-write\n");
|
Chris@1
|
1470
|
Chris@1
|
1471 if(!change_stats_(flacfilename(is_ogg), /*read-only=*/false))
|
Chris@1
|
1472 return false;
|
Chris@1
|
1473
|
Chris@1
|
1474 printf("create iterator\n");
|
Chris@1
|
1475 if(0 == (iterator = FLAC__metadata_iterator_new()))
|
Chris@1
|
1476 return die_("allocating memory for iterator");
|
Chris@1
|
1477
|
Chris@1
|
1478 our_current_position = 0;
|
Chris@1
|
1479
|
Chris@1
|
1480 FLAC__metadata_iterator_init(iterator, chain);
|
Chris@1
|
1481
|
Chris@1
|
1482 if(0 == (block = FLAC__metadata_iterator_get_block(iterator)))
|
Chris@1
|
1483 return die_("getting block from iterator");
|
Chris@1
|
1484
|
Chris@1
|
1485 FLAC__ASSERT(block->type == FLAC__METADATA_TYPE_STREAMINFO);
|
Chris@1
|
1486
|
Chris@1
|
1487 printf("[S]VP\tmodify STREAMINFO, write\n");
|
Chris@1
|
1488
|
Chris@1
|
1489 block->data.stream_info.sample_rate = 32000;
|
Chris@1
|
1490 if(!replace_in_our_metadata_(block, our_current_position, /*copy=*/true))
|
Chris@1
|
1491 return die_("copying object");
|
Chris@1
|
1492
|
Chris@1
|
1493 if(!write_chain_(chain, /*use_padding=*/false, /*preserve_file_stats=*/true, filename_based, flacfilename(is_ogg)))
|
Chris@1
|
1494 return die_c_("during FLAC__metadata_chain_write(chain, false, true)", FLAC__metadata_chain_status(chain));
|
Chris@1
|
1495 if(!compare_chain_(chain, our_current_position, FLAC__metadata_iterator_get_block(iterator)))
|
Chris@1
|
1496 return false;
|
Chris@1
|
1497 if(!test_file_(is_ogg, decoder_metadata_callback_compare_))
|
Chris@1
|
1498 return false;
|
Chris@1
|
1499
|
Chris@1
|
1500 printf("[S]VP\tnext\n");
|
Chris@1
|
1501 if(!FLAC__metadata_iterator_next(iterator))
|
Chris@1
|
1502 return die_("iterator ended early\n");
|
Chris@1
|
1503 our_current_position++;
|
Chris@1
|
1504
|
Chris@1
|
1505 printf("S[V]P\tnext\n");
|
Chris@1
|
1506 if(!FLAC__metadata_iterator_next(iterator))
|
Chris@1
|
1507 return die_("iterator ended early\n");
|
Chris@1
|
1508 our_current_position++;
|
Chris@1
|
1509
|
Chris@1
|
1510 printf("SV[P]\treplace PADDING with identical-size APPLICATION\n");
|
Chris@1
|
1511 if(0 == (block = FLAC__metadata_iterator_get_block(iterator)))
|
Chris@1
|
1512 return die_("getting block from iterator");
|
Chris@1
|
1513 if(0 == (app = FLAC__metadata_object_new(FLAC__METADATA_TYPE_APPLICATION)))
|
Chris@1
|
1514 return die_("FLAC__metadata_object_new(FLAC__METADATA_TYPE_APPLICATION)");
|
Chris@1
|
1515 memcpy(app->data.application.id, "duh", (FLAC__STREAM_METADATA_APPLICATION_ID_LEN/8));
|
Chris@1
|
1516 if(!FLAC__metadata_object_application_set_data(app, data, block->length-(FLAC__STREAM_METADATA_APPLICATION_ID_LEN/8), true))
|
Chris@1
|
1517 return die_("setting APPLICATION data");
|
Chris@1
|
1518 if(!replace_in_our_metadata_(app, our_current_position, /*copy=*/true))
|
Chris@1
|
1519 return die_("copying object");
|
Chris@1
|
1520 if(!FLAC__metadata_iterator_set_block(iterator, app))
|
Chris@1
|
1521 return die_c_("FLAC__metadata_iterator_set_block(iterator, app)", FLAC__metadata_chain_status(chain));
|
Chris@1
|
1522
|
Chris@1
|
1523 if(!write_chain_(chain, /*use_padding=*/false, /*preserve_file_stats=*/false, filename_based, flacfilename(is_ogg)))
|
Chris@1
|
1524 return die_c_("during FLAC__metadata_chain_write(chain, false, false)", FLAC__metadata_chain_status(chain));
|
Chris@1
|
1525 if(!compare_chain_(chain, our_current_position, FLAC__metadata_iterator_get_block(iterator)))
|
Chris@1
|
1526 return false;
|
Chris@1
|
1527 if(!test_file_(is_ogg, decoder_metadata_callback_compare_))
|
Chris@1
|
1528 return false;
|
Chris@1
|
1529
|
Chris@1
|
1530 printf("SV[A]\tshrink APPLICATION, don't use padding\n");
|
Chris@1
|
1531 if(0 == (app = FLAC__metadata_object_clone(our_metadata_.blocks[our_current_position])))
|
Chris@1
|
1532 return die_("copying object");
|
Chris@1
|
1533 if(!FLAC__metadata_object_application_set_data(app, data, 26, true))
|
Chris@1
|
1534 return die_("setting APPLICATION data");
|
Chris@1
|
1535 if(!replace_in_our_metadata_(app, our_current_position, /*copy=*/true))
|
Chris@1
|
1536 return die_("copying object");
|
Chris@1
|
1537 if(!FLAC__metadata_iterator_set_block(iterator, app))
|
Chris@1
|
1538 return die_c_("FLAC__metadata_iterator_set_block(iterator, app)", FLAC__metadata_chain_status(chain));
|
Chris@1
|
1539
|
Chris@1
|
1540 if(!write_chain_(chain, /*use_padding=*/false, /*preserve_file_stats=*/false, filename_based, flacfilename(is_ogg)))
|
Chris@1
|
1541 return die_c_("during FLAC__metadata_chain_write(chain, false, false)", FLAC__metadata_chain_status(chain));
|
Chris@1
|
1542 if(!compare_chain_(chain, our_current_position, FLAC__metadata_iterator_get_block(iterator)))
|
Chris@1
|
1543 return false;
|
Chris@1
|
1544 if(!test_file_(is_ogg, decoder_metadata_callback_compare_))
|
Chris@1
|
1545 return false;
|
Chris@1
|
1546
|
Chris@1
|
1547 printf("SV[A]\tgrow APPLICATION, don't use padding\n");
|
Chris@1
|
1548 if(0 == (app = FLAC__metadata_object_clone(our_metadata_.blocks[our_current_position])))
|
Chris@1
|
1549 return die_("copying object");
|
Chris@1
|
1550 if(!FLAC__metadata_object_application_set_data(app, data, 28, true))
|
Chris@1
|
1551 return die_("setting APPLICATION data");
|
Chris@1
|
1552 if(!replace_in_our_metadata_(app, our_current_position, /*copy=*/true))
|
Chris@1
|
1553 return die_("copying object");
|
Chris@1
|
1554 if(!FLAC__metadata_iterator_set_block(iterator, app))
|
Chris@1
|
1555 return die_c_("FLAC__metadata_iterator_set_block(iterator, app)", FLAC__metadata_chain_status(chain));
|
Chris@1
|
1556
|
Chris@1
|
1557 if(!write_chain_(chain, /*use_padding=*/false, /*preserve_file_stats=*/false, filename_based, flacfilename(is_ogg)))
|
Chris@1
|
1558 return die_c_("during FLAC__metadata_chain_write(chain, false, false)", FLAC__metadata_chain_status(chain));
|
Chris@1
|
1559 if(!compare_chain_(chain, our_current_position, FLAC__metadata_iterator_get_block(iterator)))
|
Chris@1
|
1560 return false;
|
Chris@1
|
1561 if(!test_file_(is_ogg, decoder_metadata_callback_compare_))
|
Chris@1
|
1562 return false;
|
Chris@1
|
1563
|
Chris@1
|
1564 printf("SV[A]\tgrow APPLICATION, use padding, but last block is not padding\n");
|
Chris@1
|
1565 if(0 == (app = FLAC__metadata_object_clone(our_metadata_.blocks[our_current_position])))
|
Chris@1
|
1566 return die_("copying object");
|
Chris@1
|
1567 if(!FLAC__metadata_object_application_set_data(app, data, 36, true))
|
Chris@1
|
1568 return die_("setting APPLICATION data");
|
Chris@1
|
1569 if(!replace_in_our_metadata_(app, our_current_position, /*copy=*/true))
|
Chris@1
|
1570 return die_("copying object");
|
Chris@1
|
1571 if(!FLAC__metadata_iterator_set_block(iterator, app))
|
Chris@1
|
1572 return die_c_("FLAC__metadata_iterator_set_block(iterator, app)", FLAC__metadata_chain_status(chain));
|
Chris@1
|
1573
|
Chris@1
|
1574 if(!write_chain_(chain, /*use_padding=*/false, /*preserve_file_stats=*/false, filename_based, flacfilename(is_ogg)))
|
Chris@1
|
1575 return die_c_("during FLAC__metadata_chain_write(chain, false, false)", FLAC__metadata_chain_status(chain));
|
Chris@1
|
1576 if(!compare_chain_(chain, our_current_position, FLAC__metadata_iterator_get_block(iterator)))
|
Chris@1
|
1577 return false;
|
Chris@1
|
1578 if(!test_file_(is_ogg, decoder_metadata_callback_compare_))
|
Chris@1
|
1579 return false;
|
Chris@1
|
1580
|
Chris@1
|
1581 printf("SV[A]\tshrink APPLICATION, use padding, last block is not padding, but delta is too small for new PADDING block\n");
|
Chris@1
|
1582 if(0 == (app = FLAC__metadata_object_clone(our_metadata_.blocks[our_current_position])))
|
Chris@1
|
1583 return die_("copying object");
|
Chris@1
|
1584 if(!FLAC__metadata_object_application_set_data(app, data, 33, true))
|
Chris@1
|
1585 return die_("setting APPLICATION data");
|
Chris@1
|
1586 if(!replace_in_our_metadata_(app, our_current_position, /*copy=*/true))
|
Chris@1
|
1587 return die_("copying object");
|
Chris@1
|
1588 if(!FLAC__metadata_iterator_set_block(iterator, app))
|
Chris@1
|
1589 return die_c_("FLAC__metadata_iterator_set_block(iterator, app)", FLAC__metadata_chain_status(chain));
|
Chris@1
|
1590
|
Chris@1
|
1591 if(!write_chain_(chain, /*use_padding=*/true, /*preserve_file_stats=*/false, filename_based, flacfilename(is_ogg)))
|
Chris@1
|
1592 return die_c_("during FLAC__metadata_chain_write(chain, true, false)", FLAC__metadata_chain_status(chain));
|
Chris@1
|
1593 if(!compare_chain_(chain, our_current_position, FLAC__metadata_iterator_get_block(iterator)))
|
Chris@1
|
1594 return false;
|
Chris@1
|
1595 if(!test_file_(is_ogg, decoder_metadata_callback_compare_))
|
Chris@1
|
1596 return false;
|
Chris@1
|
1597
|
Chris@1
|
1598 printf("SV[A]\tshrink APPLICATION, use padding, last block is not padding, delta is enough for new PADDING block\n");
|
Chris@1
|
1599 if(0 == (padding = FLAC__metadata_object_new(FLAC__METADATA_TYPE_PADDING)))
|
Chris@1
|
1600 return die_("creating PADDING block");
|
Chris@1
|
1601 if(0 == (app = FLAC__metadata_object_clone(our_metadata_.blocks[our_current_position])))
|
Chris@1
|
1602 return die_("copying object");
|
Chris@1
|
1603 if(!FLAC__metadata_object_application_set_data(app, data, 29, true))
|
Chris@1
|
1604 return die_("setting APPLICATION data");
|
Chris@1
|
1605 if(!replace_in_our_metadata_(app, our_current_position, /*copy=*/true))
|
Chris@1
|
1606 return die_("copying object");
|
Chris@1
|
1607 padding->length = 0;
|
Chris@1
|
1608 if(!insert_to_our_metadata_(padding, our_current_position+1, /*copy=*/false))
|
Chris@1
|
1609 return die_("internal error");
|
Chris@1
|
1610 if(!FLAC__metadata_iterator_set_block(iterator, app))
|
Chris@1
|
1611 return die_c_("FLAC__metadata_iterator_set_block(iterator, app)", FLAC__metadata_chain_status(chain));
|
Chris@1
|
1612
|
Chris@1
|
1613 if(!write_chain_(chain, /*use_padding=*/true, /*preserve_file_stats=*/false, filename_based, flacfilename(is_ogg)))
|
Chris@1
|
1614 return die_c_("during FLAC__metadata_chain_write(chain, true, false)", FLAC__metadata_chain_status(chain));
|
Chris@1
|
1615 if(!compare_chain_(chain, our_current_position, FLAC__metadata_iterator_get_block(iterator)))
|
Chris@1
|
1616 return false;
|
Chris@1
|
1617 if(!test_file_(is_ogg, decoder_metadata_callback_compare_))
|
Chris@1
|
1618 return false;
|
Chris@1
|
1619
|
Chris@1
|
1620 printf("SV[A]P\tshrink APPLICATION, use padding, last block is padding\n");
|
Chris@1
|
1621 if(0 == (app = FLAC__metadata_object_clone(our_metadata_.blocks[our_current_position])))
|
Chris@1
|
1622 return die_("copying object");
|
Chris@1
|
1623 if(!FLAC__metadata_object_application_set_data(app, data, 16, true))
|
Chris@1
|
1624 return die_("setting APPLICATION data");
|
Chris@1
|
1625 if(!replace_in_our_metadata_(app, our_current_position, /*copy=*/true))
|
Chris@1
|
1626 return die_("copying object");
|
Chris@1
|
1627 our_metadata_.blocks[our_current_position+1]->length = 13;
|
Chris@1
|
1628 if(!FLAC__metadata_iterator_set_block(iterator, app))
|
Chris@1
|
1629 return die_c_("FLAC__metadata_iterator_set_block(iterator, app)", FLAC__metadata_chain_status(chain));
|
Chris@1
|
1630
|
Chris@1
|
1631 if(!write_chain_(chain, /*use_padding=*/true, /*preserve_file_stats=*/false, filename_based, flacfilename(is_ogg)))
|
Chris@1
|
1632 return die_c_("during FLAC__metadata_chain_write(chain, true, false)", FLAC__metadata_chain_status(chain));
|
Chris@1
|
1633 if(!compare_chain_(chain, our_current_position, FLAC__metadata_iterator_get_block(iterator)))
|
Chris@1
|
1634 return false;
|
Chris@1
|
1635 if(!test_file_(is_ogg, decoder_metadata_callback_compare_))
|
Chris@1
|
1636 return false;
|
Chris@1
|
1637
|
Chris@1
|
1638 printf("SV[A]P\tgrow APPLICATION, use padding, last block is padding, but delta is too small\n");
|
Chris@1
|
1639 if(0 == (app = FLAC__metadata_object_clone(our_metadata_.blocks[our_current_position])))
|
Chris@1
|
1640 return die_("copying object");
|
Chris@1
|
1641 if(!FLAC__metadata_object_application_set_data(app, data, 50, true))
|
Chris@1
|
1642 return die_("setting APPLICATION data");
|
Chris@1
|
1643 if(!replace_in_our_metadata_(app, our_current_position, /*copy=*/true))
|
Chris@1
|
1644 return die_("copying object");
|
Chris@1
|
1645 if(!FLAC__metadata_iterator_set_block(iterator, app))
|
Chris@1
|
1646 return die_c_("FLAC__metadata_iterator_set_block(iterator, app)", FLAC__metadata_chain_status(chain));
|
Chris@1
|
1647
|
Chris@1
|
1648 if(!write_chain_(chain, /*use_padding=*/true, /*preserve_file_stats=*/false, filename_based, flacfilename(is_ogg)))
|
Chris@1
|
1649 return die_c_("during FLAC__metadata_chain_write(chain, true, false)", FLAC__metadata_chain_status(chain));
|
Chris@1
|
1650 if(!compare_chain_(chain, our_current_position, FLAC__metadata_iterator_get_block(iterator)))
|
Chris@1
|
1651 return false;
|
Chris@1
|
1652 if(!test_file_(is_ogg, decoder_metadata_callback_compare_))
|
Chris@1
|
1653 return false;
|
Chris@1
|
1654
|
Chris@1
|
1655 printf("SV[A]P\tgrow APPLICATION, use padding, last block is padding of exceeding size\n");
|
Chris@1
|
1656 if(0 == (app = FLAC__metadata_object_clone(our_metadata_.blocks[our_current_position])))
|
Chris@1
|
1657 return die_("copying object");
|
Chris@1
|
1658 if(!FLAC__metadata_object_application_set_data(app, data, 56, true))
|
Chris@1
|
1659 return die_("setting APPLICATION data");
|
Chris@1
|
1660 if(!replace_in_our_metadata_(app, our_current_position, /*copy=*/true))
|
Chris@1
|
1661 return die_("copying object");
|
Chris@1
|
1662 our_metadata_.blocks[our_current_position+1]->length -= (56 - 50);
|
Chris@1
|
1663 if(!FLAC__metadata_iterator_set_block(iterator, app))
|
Chris@1
|
1664 return die_c_("FLAC__metadata_iterator_set_block(iterator, app)", FLAC__metadata_chain_status(chain));
|
Chris@1
|
1665
|
Chris@1
|
1666 if(!write_chain_(chain, /*use_padding=*/true, /*preserve_file_stats=*/false, filename_based, flacfilename(is_ogg)))
|
Chris@1
|
1667 return die_c_("during FLAC__metadata_chain_write(chain, true, false)", FLAC__metadata_chain_status(chain));
|
Chris@1
|
1668 if(!compare_chain_(chain, our_current_position, FLAC__metadata_iterator_get_block(iterator)))
|
Chris@1
|
1669 return false;
|
Chris@1
|
1670 if(!test_file_(is_ogg, decoder_metadata_callback_compare_))
|
Chris@1
|
1671 return false;
|
Chris@1
|
1672
|
Chris@1
|
1673 printf("SV[A]P\tgrow APPLICATION, use padding, last block is padding of exact size\n");
|
Chris@1
|
1674 if(0 == (app = FLAC__metadata_object_clone(our_metadata_.blocks[our_current_position])))
|
Chris@1
|
1675 return die_("copying object");
|
Chris@1
|
1676 if(!FLAC__metadata_object_application_set_data(app, data, 67, true))
|
Chris@1
|
1677 return die_("setting APPLICATION data");
|
Chris@1
|
1678 if(!replace_in_our_metadata_(app, our_current_position, /*copy=*/true))
|
Chris@1
|
1679 return die_("copying object");
|
Chris@1
|
1680 delete_from_our_metadata_(our_current_position+1);
|
Chris@1
|
1681 if(!FLAC__metadata_iterator_set_block(iterator, app))
|
Chris@1
|
1682 return die_c_("FLAC__metadata_iterator_set_block(iterator, app)", FLAC__metadata_chain_status(chain));
|
Chris@1
|
1683
|
Chris@1
|
1684 if(!write_chain_(chain, /*use_padding=*/true, /*preserve_file_stats=*/false, filename_based, flacfilename(is_ogg)))
|
Chris@1
|
1685 return die_c_("during FLAC__metadata_chain_write(chain, true, false)", FLAC__metadata_chain_status(chain));
|
Chris@1
|
1686 if(!compare_chain_(chain, our_current_position, FLAC__metadata_iterator_get_block(iterator)))
|
Chris@1
|
1687 return false;
|
Chris@1
|
1688 if(!test_file_(is_ogg, decoder_metadata_callback_compare_))
|
Chris@1
|
1689 return false;
|
Chris@1
|
1690
|
Chris@1
|
1691 printf("SV[A]\tprev\n");
|
Chris@1
|
1692 if(!FLAC__metadata_iterator_prev(iterator))
|
Chris@1
|
1693 return die_("iterator ended early\n");
|
Chris@1
|
1694 our_current_position--;
|
Chris@1
|
1695
|
Chris@1
|
1696 printf("S[V]A\tprev\n");
|
Chris@1
|
1697 if(!FLAC__metadata_iterator_prev(iterator))
|
Chris@1
|
1698 return die_("iterator ended early\n");
|
Chris@1
|
1699 our_current_position--;
|
Chris@1
|
1700
|
Chris@1
|
1701 printf("[S]VA\tinsert PADDING before STREAMINFO (should fail)\n");
|
Chris@1
|
1702 if(0 == (padding = FLAC__metadata_object_new(FLAC__METADATA_TYPE_PADDING)))
|
Chris@1
|
1703 return die_("creating PADDING block");
|
Chris@1
|
1704 padding->length = 30;
|
Chris@1
|
1705 if(!FLAC__metadata_iterator_insert_block_before(iterator, padding))
|
Chris@1
|
1706 printf("\tFLAC__metadata_iterator_insert_block_before() returned false like it should\n");
|
Chris@1
|
1707 else
|
Chris@1
|
1708 return die_("FLAC__metadata_iterator_insert_block_before() should have returned false");
|
Chris@1
|
1709
|
Chris@1
|
1710 printf("[S]VP\tnext\n");
|
Chris@1
|
1711 if(!FLAC__metadata_iterator_next(iterator))
|
Chris@1
|
1712 return die_("iterator ended early\n");
|
Chris@1
|
1713 our_current_position++;
|
Chris@1
|
1714
|
Chris@1
|
1715 printf("S[V]A\tinsert PADDING after\n");
|
Chris@1
|
1716 if(!insert_to_our_metadata_(padding, ++our_current_position, /*copy=*/true))
|
Chris@1
|
1717 return die_("copying metadata");
|
Chris@1
|
1718 if(!FLAC__metadata_iterator_insert_block_after(iterator, padding))
|
Chris@1
|
1719 return die_("FLAC__metadata_iterator_insert_block_after(iterator, padding)");
|
Chris@1
|
1720
|
Chris@1
|
1721 if(!compare_chain_(chain, our_current_position, FLAC__metadata_iterator_get_block(iterator)))
|
Chris@1
|
1722 return false;
|
Chris@1
|
1723
|
Chris@1
|
1724 printf("SV[P]A\tinsert PADDING before\n");
|
Chris@1
|
1725 if(0 == (padding = FLAC__metadata_object_clone(our_metadata_.blocks[our_current_position])))
|
Chris@1
|
1726 return die_("creating PADDING block");
|
Chris@1
|
1727 padding->length = 17;
|
Chris@1
|
1728 if(!insert_to_our_metadata_(padding, our_current_position, /*copy=*/true))
|
Chris@1
|
1729 return die_("copying metadata");
|
Chris@1
|
1730 if(!FLAC__metadata_iterator_insert_block_before(iterator, padding))
|
Chris@1
|
1731 return die_("FLAC__metadata_iterator_insert_block_before(iterator, padding)");
|
Chris@1
|
1732
|
Chris@1
|
1733 if(!compare_chain_(chain, our_current_position, FLAC__metadata_iterator_get_block(iterator)))
|
Chris@1
|
1734 return false;
|
Chris@1
|
1735
|
Chris@1
|
1736 printf("SV[P]PA\tinsert PADDING before\n");
|
Chris@1
|
1737 if(0 == (padding = FLAC__metadata_object_clone(our_metadata_.blocks[our_current_position])))
|
Chris@1
|
1738 return die_("creating PADDING block");
|
Chris@1
|
1739 padding->length = 0;
|
Chris@1
|
1740 if(!insert_to_our_metadata_(padding, our_current_position, /*copy=*/true))
|
Chris@1
|
1741 return die_("copying metadata");
|
Chris@1
|
1742 if(!FLAC__metadata_iterator_insert_block_before(iterator, padding))
|
Chris@1
|
1743 return die_("FLAC__metadata_iterator_insert_block_before(iterator, padding)");
|
Chris@1
|
1744
|
Chris@1
|
1745 if(!compare_chain_(chain, our_current_position, FLAC__metadata_iterator_get_block(iterator)))
|
Chris@1
|
1746 return false;
|
Chris@1
|
1747
|
Chris@1
|
1748 printf("SV[P]PPA\tnext\n");
|
Chris@1
|
1749 if(!FLAC__metadata_iterator_next(iterator))
|
Chris@1
|
1750 return die_("iterator ended early\n");
|
Chris@1
|
1751 our_current_position++;
|
Chris@1
|
1752
|
Chris@1
|
1753 printf("SVP[P]PA\tnext\n");
|
Chris@1
|
1754 if(!FLAC__metadata_iterator_next(iterator))
|
Chris@1
|
1755 return die_("iterator ended early\n");
|
Chris@1
|
1756 our_current_position++;
|
Chris@1
|
1757
|
Chris@1
|
1758 printf("SVPP[P]A\tnext\n");
|
Chris@1
|
1759 if(!FLAC__metadata_iterator_next(iterator))
|
Chris@1
|
1760 return die_("iterator ended early\n");
|
Chris@1
|
1761 our_current_position++;
|
Chris@1
|
1762
|
Chris@1
|
1763 printf("SVPPP[A]\tinsert PADDING after\n");
|
Chris@1
|
1764 if(0 == (padding = FLAC__metadata_object_clone(our_metadata_.blocks[2])))
|
Chris@1
|
1765 return die_("creating PADDING block");
|
Chris@1
|
1766 padding->length = 57;
|
Chris@1
|
1767 if(!insert_to_our_metadata_(padding, ++our_current_position, /*copy=*/true))
|
Chris@1
|
1768 return die_("copying metadata");
|
Chris@1
|
1769 if(!FLAC__metadata_iterator_insert_block_after(iterator, padding))
|
Chris@1
|
1770 return die_("FLAC__metadata_iterator_insert_block_after(iterator, padding)");
|
Chris@1
|
1771
|
Chris@1
|
1772 if(!compare_chain_(chain, our_current_position, FLAC__metadata_iterator_get_block(iterator)))
|
Chris@1
|
1773 return false;
|
Chris@1
|
1774
|
Chris@1
|
1775 printf("SVPPPA[P]\tinsert PADDING before\n");
|
Chris@1
|
1776 if(0 == (padding = FLAC__metadata_object_clone(our_metadata_.blocks[2])))
|
Chris@1
|
1777 return die_("creating PADDING block");
|
Chris@1
|
1778 padding->length = 99;
|
Chris@1
|
1779 if(!insert_to_our_metadata_(padding, our_current_position, /*copy=*/true))
|
Chris@1
|
1780 return die_("copying metadata");
|
Chris@1
|
1781 if(!FLAC__metadata_iterator_insert_block_before(iterator, padding))
|
Chris@1
|
1782 return die_("FLAC__metadata_iterator_insert_block_before(iterator, padding)");
|
Chris@1
|
1783
|
Chris@1
|
1784 if(!compare_chain_(chain, our_current_position, FLAC__metadata_iterator_get_block(iterator)))
|
Chris@1
|
1785 return false;
|
Chris@1
|
1786
|
Chris@1
|
1787 printf("delete iterator\n");
|
Chris@1
|
1788 FLAC__metadata_iterator_delete(iterator);
|
Chris@1
|
1789 our_current_position = 0;
|
Chris@1
|
1790
|
Chris@1
|
1791 printf("SVPPPAPP\tmerge padding\n");
|
Chris@1
|
1792 FLAC__metadata_chain_merge_padding(chain);
|
Chris@1
|
1793 our_metadata_.blocks[2]->length += (FLAC__STREAM_METADATA_HEADER_LENGTH + our_metadata_.blocks[3]->length);
|
Chris@1
|
1794 our_metadata_.blocks[2]->length += (FLAC__STREAM_METADATA_HEADER_LENGTH + our_metadata_.blocks[4]->length);
|
Chris@1
|
1795 our_metadata_.blocks[6]->length += (FLAC__STREAM_METADATA_HEADER_LENGTH + our_metadata_.blocks[7]->length);
|
Chris@1
|
1796 delete_from_our_metadata_(7);
|
Chris@1
|
1797 delete_from_our_metadata_(4);
|
Chris@1
|
1798 delete_from_our_metadata_(3);
|
Chris@1
|
1799
|
Chris@1
|
1800 if(!write_chain_(chain, /*use_padding=*/true, /*preserve_file_stats=*/false, filename_based, flacfilename(is_ogg)))
|
Chris@1
|
1801 return die_c_("during FLAC__metadata_chain_write(chain, true, false)", FLAC__metadata_chain_status(chain));
|
Chris@1
|
1802 if(!compare_chain_(chain, 0, 0))
|
Chris@1
|
1803 return false;
|
Chris@1
|
1804 if(!test_file_(is_ogg, decoder_metadata_callback_compare_))
|
Chris@1
|
1805 return false;
|
Chris@1
|
1806
|
Chris@1
|
1807 printf("SVPAP\tsort padding\n");
|
Chris@1
|
1808 FLAC__metadata_chain_sort_padding(chain);
|
Chris@1
|
1809 our_metadata_.blocks[4]->length += (FLAC__STREAM_METADATA_HEADER_LENGTH + our_metadata_.blocks[2]->length);
|
Chris@1
|
1810 delete_from_our_metadata_(2);
|
Chris@1
|
1811
|
Chris@1
|
1812 if(!write_chain_(chain, /*use_padding=*/true, /*preserve_file_stats=*/false, filename_based, flacfilename(is_ogg)))
|
Chris@1
|
1813 return die_c_("during FLAC__metadata_chain_write(chain, true, false)", FLAC__metadata_chain_status(chain));
|
Chris@1
|
1814 if(!compare_chain_(chain, 0, 0))
|
Chris@1
|
1815 return false;
|
Chris@1
|
1816 if(!test_file_(is_ogg, decoder_metadata_callback_compare_))
|
Chris@1
|
1817 return false;
|
Chris@1
|
1818
|
Chris@1
|
1819 printf("create iterator\n");
|
Chris@1
|
1820 if(0 == (iterator = FLAC__metadata_iterator_new()))
|
Chris@1
|
1821 return die_("allocating memory for iterator");
|
Chris@1
|
1822
|
Chris@1
|
1823 our_current_position = 0;
|
Chris@1
|
1824
|
Chris@1
|
1825 FLAC__metadata_iterator_init(iterator, chain);
|
Chris@1
|
1826
|
Chris@1
|
1827 printf("[S]VAP\tnext\n");
|
Chris@1
|
1828 if(!FLAC__metadata_iterator_next(iterator))
|
Chris@1
|
1829 return die_("iterator ended early\n");
|
Chris@1
|
1830 our_current_position++;
|
Chris@1
|
1831
|
Chris@1
|
1832 printf("S[V]AP\tnext\n");
|
Chris@1
|
1833 if(!FLAC__metadata_iterator_next(iterator))
|
Chris@1
|
1834 return die_("iterator ended early\n");
|
Chris@1
|
1835 our_current_position++;
|
Chris@1
|
1836
|
Chris@1
|
1837 printf("SV[A]P\tdelete middle block, replace with padding\n");
|
Chris@1
|
1838 if(0 == (padding = FLAC__metadata_object_new(FLAC__METADATA_TYPE_PADDING)))
|
Chris@1
|
1839 return die_("creating PADDING block");
|
Chris@1
|
1840 padding->length = 71;
|
Chris@1
|
1841 if(!replace_in_our_metadata_(padding, our_current_position--, /*copy=*/false))
|
Chris@1
|
1842 return die_("copying object");
|
Chris@1
|
1843 if(!FLAC__metadata_iterator_delete_block(iterator, /*replace_with_padding=*/true))
|
Chris@1
|
1844 return die_c_("FLAC__metadata_iterator_delete_block(iterator, true)", FLAC__metadata_chain_status(chain));
|
Chris@1
|
1845
|
Chris@1
|
1846 if(!compare_chain_(chain, our_current_position, FLAC__metadata_iterator_get_block(iterator)))
|
Chris@1
|
1847 return false;
|
Chris@1
|
1848
|
Chris@1
|
1849 printf("S[V]PP\tnext\n");
|
Chris@1
|
1850 if(!FLAC__metadata_iterator_next(iterator))
|
Chris@1
|
1851 return die_("iterator ended early\n");
|
Chris@1
|
1852 our_current_position++;
|
Chris@1
|
1853
|
Chris@1
|
1854 printf("SV[P]P\tdelete middle block, don't replace with padding\n");
|
Chris@1
|
1855 delete_from_our_metadata_(our_current_position--);
|
Chris@1
|
1856 if(!FLAC__metadata_iterator_delete_block(iterator, /*replace_with_padding=*/false))
|
Chris@1
|
1857 return die_c_("FLAC__metadata_iterator_delete_block(iterator, false)", FLAC__metadata_chain_status(chain));
|
Chris@1
|
1858
|
Chris@1
|
1859 if(!compare_chain_(chain, our_current_position, FLAC__metadata_iterator_get_block(iterator)))
|
Chris@1
|
1860 return false;
|
Chris@1
|
1861
|
Chris@1
|
1862 printf("S[V]P\tnext\n");
|
Chris@1
|
1863 if(!FLAC__metadata_iterator_next(iterator))
|
Chris@1
|
1864 return die_("iterator ended early\n");
|
Chris@1
|
1865 our_current_position++;
|
Chris@1
|
1866
|
Chris@1
|
1867 printf("SV[P]\tdelete last block, replace with padding\n");
|
Chris@1
|
1868 if(0 == (padding = FLAC__metadata_object_new(FLAC__METADATA_TYPE_PADDING)))
|
Chris@1
|
1869 return die_("creating PADDING block");
|
Chris@1
|
1870 padding->length = 219;
|
Chris@1
|
1871 if(!replace_in_our_metadata_(padding, our_current_position--, /*copy=*/false))
|
Chris@1
|
1872 return die_("copying object");
|
Chris@1
|
1873 if(!FLAC__metadata_iterator_delete_block(iterator, /*replace_with_padding=*/true))
|
Chris@1
|
1874 return die_c_("FLAC__metadata_iterator_delete_block(iterator, true)", FLAC__metadata_chain_status(chain));
|
Chris@1
|
1875
|
Chris@1
|
1876 if(!compare_chain_(chain, our_current_position, FLAC__metadata_iterator_get_block(iterator)))
|
Chris@1
|
1877 return false;
|
Chris@1
|
1878
|
Chris@1
|
1879 printf("S[V]P\tnext\n");
|
Chris@1
|
1880 if(!FLAC__metadata_iterator_next(iterator))
|
Chris@1
|
1881 return die_("iterator ended early\n");
|
Chris@1
|
1882 our_current_position++;
|
Chris@1
|
1883
|
Chris@1
|
1884 printf("SV[P]\tdelete last block, don't replace with padding\n");
|
Chris@1
|
1885 delete_from_our_metadata_(our_current_position--);
|
Chris@1
|
1886 if(!FLAC__metadata_iterator_delete_block(iterator, /*replace_with_padding=*/false))
|
Chris@1
|
1887 return die_c_("FLAC__metadata_iterator_delete_block(iterator, false)", FLAC__metadata_chain_status(chain));
|
Chris@1
|
1888
|
Chris@1
|
1889 if(!compare_chain_(chain, our_current_position, FLAC__metadata_iterator_get_block(iterator)))
|
Chris@1
|
1890 return false;
|
Chris@1
|
1891
|
Chris@1
|
1892 printf("S[V]\tprev\n");
|
Chris@1
|
1893 if(!FLAC__metadata_iterator_prev(iterator))
|
Chris@1
|
1894 return die_("iterator ended early\n");
|
Chris@1
|
1895 our_current_position--;
|
Chris@1
|
1896
|
Chris@1
|
1897 printf("[S]V\tdelete STREAMINFO block, should fail\n");
|
Chris@1
|
1898 if(FLAC__metadata_iterator_delete_block(iterator, /*replace_with_padding=*/false))
|
Chris@1
|
1899 return die_("FLAC__metadata_iterator_delete_block() on STREAMINFO should have failed but didn't");
|
Chris@1
|
1900
|
Chris@1
|
1901 if(!compare_chain_(chain, our_current_position, FLAC__metadata_iterator_get_block(iterator)))
|
Chris@1
|
1902 return false;
|
Chris@1
|
1903
|
Chris@1
|
1904 printf("delete iterator\n");
|
Chris@1
|
1905 FLAC__metadata_iterator_delete(iterator);
|
Chris@1
|
1906 our_current_position = 0;
|
Chris@1
|
1907
|
Chris@1
|
1908 printf("SV\tmerge padding\n");
|
Chris@1
|
1909 FLAC__metadata_chain_merge_padding(chain);
|
Chris@1
|
1910
|
Chris@1
|
1911 if(!write_chain_(chain, /*use_padding=*/false, /*preserve_file_stats=*/false, filename_based, flacfilename(is_ogg)))
|
Chris@1
|
1912 return die_c_("during FLAC__metadata_chain_write(chain, false, false)", FLAC__metadata_chain_status(chain));
|
Chris@1
|
1913 if(!compare_chain_(chain, 0, 0))
|
Chris@1
|
1914 return false;
|
Chris@1
|
1915 if(!test_file_(is_ogg, decoder_metadata_callback_compare_))
|
Chris@1
|
1916 return false;
|
Chris@1
|
1917
|
Chris@1
|
1918 printf("SV\tsort padding\n");
|
Chris@1
|
1919 FLAC__metadata_chain_sort_padding(chain);
|
Chris@1
|
1920
|
Chris@1
|
1921 if(!write_chain_(chain, /*use_padding=*/false, /*preserve_file_stats=*/false, filename_based, flacfilename(is_ogg)))
|
Chris@1
|
1922 return die_c_("during FLAC__metadata_chain_write(chain, false, false)", FLAC__metadata_chain_status(chain));
|
Chris@1
|
1923 if(!compare_chain_(chain, 0, 0))
|
Chris@1
|
1924 return false;
|
Chris@1
|
1925 if(!test_file_(is_ogg, decoder_metadata_callback_compare_))
|
Chris@1
|
1926 return false;
|
Chris@1
|
1927
|
Chris@1
|
1928 end:
|
Chris@1
|
1929 printf("delete chain\n");
|
Chris@1
|
1930
|
Chris@1
|
1931 FLAC__metadata_chain_delete(chain);
|
Chris@1
|
1932
|
Chris@1
|
1933 if(!remove_file_(flacfilename(is_ogg)))
|
Chris@1
|
1934 return false;
|
Chris@1
|
1935
|
Chris@1
|
1936 return true;
|
Chris@1
|
1937 }
|
Chris@1
|
1938
|
Chris@1
|
1939 static FLAC__bool test_level_2_misc_(FLAC__bool is_ogg)
|
Chris@1
|
1940 {
|
Chris@1
|
1941 FLAC__Metadata_Iterator *iterator;
|
Chris@1
|
1942 FLAC__Metadata_Chain *chain;
|
Chris@1
|
1943 FLAC__IOCallbacks callbacks;
|
Chris@1
|
1944
|
Chris@1
|
1945 memset(&callbacks, 0, sizeof(callbacks));
|
Chris@1
|
1946 callbacks.read = (FLAC__IOCallback_Read)fread;
|
Chris@1
|
1947 #ifdef FLAC__VALGRIND_TESTING
|
Chris@1
|
1948 callbacks.write = chain_write_cb_;
|
Chris@1
|
1949 #else
|
Chris@1
|
1950 callbacks.write = (FLAC__IOCallback_Write)fwrite;
|
Chris@1
|
1951 #endif
|
Chris@1
|
1952 callbacks.seek = chain_seek_cb_;
|
Chris@1
|
1953 callbacks.tell = chain_tell_cb_;
|
Chris@1
|
1954 callbacks.eof = chain_eof_cb_;
|
Chris@1
|
1955
|
Chris@1
|
1956 printf("\n\n++++++ testing level 2 interface (mismatched read/write protections)\n");
|
Chris@1
|
1957
|
Chris@1
|
1958 printf("generate file\n");
|
Chris@1
|
1959
|
Chris@1
|
1960 if(!generate_file_(/*include_extras=*/false, is_ogg))
|
Chris@1
|
1961 return false;
|
Chris@1
|
1962
|
Chris@1
|
1963 printf("create chain\n");
|
Chris@1
|
1964
|
Chris@1
|
1965 if(0 == (chain = FLAC__metadata_chain_new()))
|
Chris@1
|
1966 return die_("allocating chain");
|
Chris@1
|
1967
|
Chris@1
|
1968 printf("read chain (filename-based)\n");
|
Chris@1
|
1969
|
Chris@1
|
1970 if(!FLAC__metadata_chain_read(chain, flacfilename(is_ogg)))
|
Chris@1
|
1971 return die_c_("reading chain", FLAC__metadata_chain_status(chain));
|
Chris@1
|
1972
|
Chris@1
|
1973 printf("write chain with wrong method FLAC__metadata_chain_write_with_callbacks()\n");
|
Chris@1
|
1974 {
|
Chris@1
|
1975 if(FLAC__metadata_chain_write_with_callbacks(chain, /*use_padding=*/false, 0, callbacks))
|
Chris@1
|
1976 return die_c_("mismatched write should have failed", FLAC__metadata_chain_status(chain));
|
Chris@1
|
1977 if(FLAC__metadata_chain_status(chain) != FLAC__METADATA_CHAIN_STATUS_READ_WRITE_MISMATCH)
|
Chris@1
|
1978 return die_c_("expected FLAC__METADATA_CHAIN_STATUS_READ_WRITE_MISMATCH", FLAC__metadata_chain_status(chain));
|
Chris@1
|
1979 printf(" OK: FLAC__metadata_chain_write_with_callbacks() returned false,FLAC__METADATA_CHAIN_STATUS_READ_WRITE_MISMATCH like it should\n");
|
Chris@1
|
1980 }
|
Chris@1
|
1981
|
Chris@1
|
1982 printf("read chain (filename-based)\n");
|
Chris@1
|
1983
|
Chris@1
|
1984 if(!FLAC__metadata_chain_read(chain, flacfilename(is_ogg)))
|
Chris@1
|
1985 return die_c_("reading chain", FLAC__metadata_chain_status(chain));
|
Chris@1
|
1986
|
Chris@1
|
1987 printf("write chain with wrong method FLAC__metadata_chain_write_with_callbacks_and_tempfile()\n");
|
Chris@1
|
1988 {
|
Chris@1
|
1989 if(FLAC__metadata_chain_write_with_callbacks_and_tempfile(chain, /*use_padding=*/false, 0, callbacks, 0, callbacks))
|
Chris@1
|
1990 return die_c_("mismatched write should have failed", FLAC__metadata_chain_status(chain));
|
Chris@1
|
1991 if(FLAC__metadata_chain_status(chain) != FLAC__METADATA_CHAIN_STATUS_READ_WRITE_MISMATCH)
|
Chris@1
|
1992 return die_c_("expected FLAC__METADATA_CHAIN_STATUS_READ_WRITE_MISMATCH", FLAC__metadata_chain_status(chain));
|
Chris@1
|
1993 printf(" OK: FLAC__metadata_chain_write_with_callbacks_and_tempfile() returned false,FLAC__METADATA_CHAIN_STATUS_READ_WRITE_MISMATCH like it should\n");
|
Chris@1
|
1994 }
|
Chris@1
|
1995
|
Chris@1
|
1996 printf("read chain (callback-based)\n");
|
Chris@1
|
1997 {
|
Chris@1
|
1998 FILE *file = fopen(flacfilename(is_ogg), "rb");
|
Chris@1
|
1999 if(0 == file)
|
Chris@1
|
2000 return die_("opening file");
|
Chris@1
|
2001 if(!FLAC__metadata_chain_read_with_callbacks(chain, (FLAC__IOHandle)file, callbacks)) {
|
Chris@1
|
2002 fclose(file);
|
Chris@1
|
2003 return die_c_("reading chain", FLAC__metadata_chain_status(chain));
|
Chris@1
|
2004 }
|
Chris@1
|
2005 fclose(file);
|
Chris@1
|
2006 }
|
Chris@1
|
2007
|
Chris@1
|
2008 printf("write chain with wrong method FLAC__metadata_chain_write()\n");
|
Chris@1
|
2009 {
|
Chris@1
|
2010 if(FLAC__metadata_chain_write(chain, /*use_padding=*/false, /*preserve_file_stats=*/false))
|
Chris@1
|
2011 return die_c_("mismatched write should have failed", FLAC__metadata_chain_status(chain));
|
Chris@1
|
2012 if(FLAC__metadata_chain_status(chain) != FLAC__METADATA_CHAIN_STATUS_READ_WRITE_MISMATCH)
|
Chris@1
|
2013 return die_c_("expected FLAC__METADATA_CHAIN_STATUS_READ_WRITE_MISMATCH", FLAC__metadata_chain_status(chain));
|
Chris@1
|
2014 printf(" OK: FLAC__metadata_chain_write() returned false,FLAC__METADATA_CHAIN_STATUS_READ_WRITE_MISMATCH like it should\n");
|
Chris@1
|
2015 }
|
Chris@1
|
2016
|
Chris@1
|
2017 printf("read chain (callback-based)\n");
|
Chris@1
|
2018 {
|
Chris@1
|
2019 FILE *file = fopen(flacfilename(is_ogg), "rb");
|
Chris@1
|
2020 if(0 == file)
|
Chris@1
|
2021 return die_("opening file");
|
Chris@1
|
2022 if(!FLAC__metadata_chain_read_with_callbacks(chain, (FLAC__IOHandle)file, callbacks)) {
|
Chris@1
|
2023 fclose(file);
|
Chris@1
|
2024 return die_c_("reading chain", FLAC__metadata_chain_status(chain));
|
Chris@1
|
2025 }
|
Chris@1
|
2026 fclose(file);
|
Chris@1
|
2027 }
|
Chris@1
|
2028
|
Chris@1
|
2029 printf("testing FLAC__metadata_chain_check_if_tempfile_needed()... ");
|
Chris@1
|
2030
|
Chris@1
|
2031 if(!FLAC__metadata_chain_check_if_tempfile_needed(chain, /*use_padding=*/false))
|
Chris@1
|
2032 printf("OK: FLAC__metadata_chain_check_if_tempfile_needed() returned false like it should\n");
|
Chris@1
|
2033 else
|
Chris@1
|
2034 return die_("FLAC__metadata_chain_check_if_tempfile_needed() returned true but shouldn't have");
|
Chris@1
|
2035
|
Chris@1
|
2036 printf("write chain with wrong method FLAC__metadata_chain_write_with_callbacks_and_tempfile()\n");
|
Chris@1
|
2037 {
|
Chris@1
|
2038 if(FLAC__metadata_chain_write_with_callbacks_and_tempfile(chain, /*use_padding=*/false, 0, callbacks, 0, callbacks))
|
Chris@1
|
2039 return die_c_("mismatched write should have failed", FLAC__metadata_chain_status(chain));
|
Chris@1
|
2040 if(FLAC__metadata_chain_status(chain) != FLAC__METADATA_CHAIN_STATUS_WRONG_WRITE_CALL)
|
Chris@1
|
2041 return die_c_("expected FLAC__METADATA_CHAIN_STATUS_WRONG_WRITE_CALL", FLAC__metadata_chain_status(chain));
|
Chris@1
|
2042 printf(" OK: FLAC__metadata_chain_write_with_callbacks_and_tempfile() returned false,FLAC__METADATA_CHAIN_STATUS_WRONG_WRITE_CALL like it should\n");
|
Chris@1
|
2043 }
|
Chris@1
|
2044
|
Chris@1
|
2045 printf("read chain (callback-based)\n");
|
Chris@1
|
2046 {
|
Chris@1
|
2047 FILE *file = fopen(flacfilename(is_ogg), "rb");
|
Chris@1
|
2048 if(0 == file)
|
Chris@1
|
2049 return die_("opening file");
|
Chris@1
|
2050 if(!FLAC__metadata_chain_read_with_callbacks(chain, (FLAC__IOHandle)file, callbacks)) {
|
Chris@1
|
2051 fclose(file);
|
Chris@1
|
2052 return die_c_("reading chain", FLAC__metadata_chain_status(chain));
|
Chris@1
|
2053 }
|
Chris@1
|
2054 fclose(file);
|
Chris@1
|
2055 }
|
Chris@1
|
2056
|
Chris@1
|
2057 printf("create iterator\n");
|
Chris@1
|
2058 if(0 == (iterator = FLAC__metadata_iterator_new()))
|
Chris@1
|
2059 return die_("allocating memory for iterator");
|
Chris@1
|
2060
|
Chris@1
|
2061 FLAC__metadata_iterator_init(iterator, chain);
|
Chris@1
|
2062
|
Chris@1
|
2063 printf("[S]VP\tnext\n");
|
Chris@1
|
2064 if(!FLAC__metadata_iterator_next(iterator))
|
Chris@1
|
2065 return die_("iterator ended early\n");
|
Chris@1
|
2066
|
Chris@1
|
2067 printf("S[V]P\tdelete VORBIS_COMMENT, write\n");
|
Chris@1
|
2068 if(!FLAC__metadata_iterator_delete_block(iterator, /*replace_with_padding=*/false))
|
Chris@1
|
2069 return die_c_("block delete failed\n", FLAC__metadata_chain_status(chain));
|
Chris@1
|
2070
|
Chris@1
|
2071 printf("testing FLAC__metadata_chain_check_if_tempfile_needed()... ");
|
Chris@1
|
2072
|
Chris@1
|
2073 if(FLAC__metadata_chain_check_if_tempfile_needed(chain, /*use_padding=*/false))
|
Chris@1
|
2074 printf("OK: FLAC__metadata_chain_check_if_tempfile_needed() returned true like it should\n");
|
Chris@1
|
2075 else
|
Chris@1
|
2076 return die_("FLAC__metadata_chain_check_if_tempfile_needed() returned false but shouldn't have");
|
Chris@1
|
2077
|
Chris@1
|
2078 printf("write chain with wrong method FLAC__metadata_chain_write_with_callbacks()\n");
|
Chris@1
|
2079 {
|
Chris@1
|
2080 if(FLAC__metadata_chain_write_with_callbacks(chain, /*use_padding=*/false, 0, callbacks))
|
Chris@1
|
2081 return die_c_("mismatched write should have failed", FLAC__metadata_chain_status(chain));
|
Chris@1
|
2082 if(FLAC__metadata_chain_status(chain) != FLAC__METADATA_CHAIN_STATUS_WRONG_WRITE_CALL)
|
Chris@1
|
2083 return die_c_("expected FLAC__METADATA_CHAIN_STATUS_WRONG_WRITE_CALL", FLAC__metadata_chain_status(chain));
|
Chris@1
|
2084 printf(" OK: FLAC__metadata_chain_write_with_callbacks() returned false,FLAC__METADATA_CHAIN_STATUS_WRONG_WRITE_CALL like it should\n");
|
Chris@1
|
2085 }
|
Chris@1
|
2086
|
Chris@1
|
2087 printf("delete iterator\n");
|
Chris@1
|
2088
|
Chris@1
|
2089 FLAC__metadata_iterator_delete(iterator);
|
Chris@1
|
2090
|
Chris@1
|
2091 printf("delete chain\n");
|
Chris@1
|
2092
|
Chris@1
|
2093 FLAC__metadata_chain_delete(chain);
|
Chris@1
|
2094
|
Chris@1
|
2095 if(!remove_file_(flacfilename(is_ogg)))
|
Chris@1
|
2096 return false;
|
Chris@1
|
2097
|
Chris@1
|
2098 return true;
|
Chris@1
|
2099 }
|
Chris@1
|
2100
|
Chris@1
|
2101 FLAC__bool test_metadata_file_manipulation(void)
|
Chris@1
|
2102 {
|
Chris@1
|
2103 printf("\n+++ libFLAC unit test: metadata manipulation\n\n");
|
Chris@1
|
2104
|
Chris@1
|
2105 our_metadata_.num_blocks = 0;
|
Chris@1
|
2106
|
Chris@1
|
2107 if(!test_level_0_())
|
Chris@1
|
2108 return false;
|
Chris@1
|
2109
|
Chris@1
|
2110 if(!test_level_1_())
|
Chris@1
|
2111 return false;
|
Chris@1
|
2112
|
Chris@1
|
2113 if(!test_level_2_(/*filename_based=*/true, /*is_ogg=*/false)) /* filename-based */
|
Chris@1
|
2114 return false;
|
Chris@1
|
2115 if(!test_level_2_(/*filename_based=*/false, /*is_ogg=*/false)) /* callback-based */
|
Chris@1
|
2116 return false;
|
Chris@1
|
2117 if(!test_level_2_misc_(/*is_ogg=*/false))
|
Chris@1
|
2118 return false;
|
Chris@1
|
2119
|
Chris@1
|
2120 if(FLAC_API_SUPPORTS_OGG_FLAC) {
|
Chris@1
|
2121 if(!test_level_2_(/*filename_based=*/true, /*is_ogg=*/true)) /* filename-based */
|
Chris@1
|
2122 return false;
|
Chris@1
|
2123 if(!test_level_2_(/*filename_based=*/false, /*is_ogg=*/true)) /* callback-based */
|
Chris@1
|
2124 return false;
|
Chris@1
|
2125 #if 0
|
Chris@1
|
2126 /* when ogg flac write is supported, will have to add this: */
|
Chris@1
|
2127 if(!test_level_2_misc_(/*is_ogg=*/true))
|
Chris@1
|
2128 return false;
|
Chris@1
|
2129 #endif
|
Chris@1
|
2130 }
|
Chris@1
|
2131
|
Chris@1
|
2132 return true;
|
Chris@1
|
2133 }
|