Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Stefan Strogin
flac
Commits
deab4627
Commit
deab4627
authored
Jul 15, 2004
by
Josh Coalson
Browse files
add libFLAC++ equivalent callback-based chain reading/writing and tests
parent
967360b9
Changes
3
Hide whitespace changes
Inline
Side-by-side
include/FLAC++/metadata.h
View file @
deab4627
...
...
@@ -908,7 +908,13 @@ namespace FLAC {
Status
status
();
bool
read
(
const
char
*
filename
);
bool
read
(
FLAC__IOHandle
handle
,
FLAC__IOCallbacks
callbacks
);
bool
check_if_tempfile_needed
(
bool
use_padding
);
bool
write
(
bool
use_padding
=
true
,
bool
preserve_file_stats
=
false
);
bool
write
(
bool
use_padding
,
::
FLAC__IOHandle
handle
,
::
FLAC__IOCallbacks
callbacks
);
bool
write
(
bool
use_padding
,
::
FLAC__IOHandle
handle
,
::
FLAC__IOCallbacks
callbacks
,
::
FLAC__IOHandle
temp_handle
,
::
FLAC__IOCallbacks
temp_callbacks
);
void
merge_padding
();
void
sort_padding
();
...
...
src/libFLAC++/metadata.cpp
View file @
deab4627
...
...
@@ -1122,12 +1122,36 @@ namespace FLAC {
return
(
bool
)
::
FLAC__metadata_chain_read
(
chain_
,
filename
);
}
bool
Chain
::
read
(
FLAC__IOHandle
handle
,
::
FLAC__IOCallbacks
callbacks
)
{
FLAC__ASSERT
(
is_valid
());
return
(
bool
)
::
FLAC__metadata_chain_read_with_callbacks
(
chain_
,
handle
,
callbacks
);
}
bool
Chain
::
check_if_tempfile_needed
(
bool
use_padding
)
{
FLAC__ASSERT
(
is_valid
());
return
(
bool
)
::
FLAC__metadata_chain_check_if_tempfile_needed
(
chain_
,
use_padding
);
}
bool
Chain
::
write
(
bool
use_padding
,
bool
preserve_file_stats
)
{
FLAC__ASSERT
(
is_valid
());
return
(
bool
)
::
FLAC__metadata_chain_write
(
chain_
,
use_padding
,
preserve_file_stats
);
}
bool
Chain
::
write
(
bool
use_padding
,
::
FLAC__IOHandle
handle
,
::
FLAC__IOCallbacks
callbacks
)
{
FLAC__ASSERT
(
is_valid
());
return
(
bool
)
::
FLAC__metadata_chain_write_with_callbacks
(
chain_
,
use_padding
,
handle
,
callbacks
);
}
bool
Chain
::
write
(
bool
use_padding
,
::
FLAC__IOHandle
handle
,
::
FLAC__IOCallbacks
callbacks
,
::
FLAC__IOHandle
temp_handle
,
::
FLAC__IOCallbacks
temp_callbacks
)
{
FLAC__ASSERT
(
is_valid
());
return
(
bool
)
::
FLAC__metadata_chain_write_with_callbacks_and_tempfile
(
chain_
,
use_padding
,
handle
,
callbacks
,
temp_handle
,
temp_callbacks
);
}
void
Chain
::
merge_padding
()
{
FLAC__ASSERT
(
is_valid
());
...
...
src/test_libFLAC++/metadata_manip.cpp
View file @
deab4627
...
...
@@ -27,6 +27,16 @@ extern "C" {
#include <stdlib.h>
/* for malloc() */
#include <string.h>
/* for memcpy()/memset() */
#if defined _MSC_VER || defined __MINGW32__
#include <sys/utime.h>
/* for utime() */
#include <io.h>
/* for chmod() */
#else
#include <sys/types.h>
/* some flavors of BSD (like OS X) require this to get time_t */
#include <utime.h>
/* for utime() */
#include <unistd.h>
/* for chown(), unlink() */
#endif
#include <sys/stat.h>
/* for stat(), maybe chmod() */
/******************************************************************************
The general strategy of these tests (for interface levels 1 and 2) is
to create a dummy FLAC file with a known set of initial metadata
...
...
@@ -166,6 +176,202 @@ void add_to_padding_length_(unsigned index, int delta)
padding
->
set_length
((
unsigned
)((
int
)
padding
->
get_length
()
+
delta
));
}
/*
* This wad of functions supports filename- and callback-based chain reading/writing.
* Everything up to set_file_stats_() is copied from libFLAC/metadata_iterators.c
*/
bool
open_tempfile_
(
const
char
*
filename
,
FILE
**
tempfile
,
char
**
tempfilename
)
{
static
const
char
*
tempfile_suffix
=
".metadata_edit"
;
if
(
0
==
(
*
tempfilename
=
(
char
*
)
malloc
(
strlen
(
filename
)
+
strlen
(
tempfile_suffix
)
+
1
)))
return
false
;
strcpy
(
*
tempfilename
,
filename
);
strcat
(
*
tempfilename
,
tempfile_suffix
);
if
(
0
==
(
*
tempfile
=
fopen
(
*
tempfilename
,
"w+b"
)))
return
false
;
return
true
;
}
void
cleanup_tempfile_
(
FILE
**
tempfile
,
char
**
tempfilename
)
{
if
(
0
!=
*
tempfile
)
{
(
void
)
fclose
(
*
tempfile
);
*
tempfile
=
0
;
}
if
(
0
!=
*
tempfilename
)
{
(
void
)
unlink
(
*
tempfilename
);
free
(
*
tempfilename
);
*
tempfilename
=
0
;
}
}
bool
transport_tempfile_
(
const
char
*
filename
,
FILE
**
tempfile
,
char
**
tempfilename
)
{
FLAC__ASSERT
(
0
!=
filename
);
FLAC__ASSERT
(
0
!=
tempfile
);
FLAC__ASSERT
(
0
!=
tempfilename
);
FLAC__ASSERT
(
0
!=
*
tempfilename
);
if
(
0
!=
*
tempfile
)
{
(
void
)
fclose
(
*
tempfile
);
*
tempfile
=
0
;
}
#if defined _MSC_VER || defined __MINGW32__
if
(
unlink
(
filename
)
<
0
)
{
cleanup_tempfile_
(
tempfile
,
tempfilename
);
return
false
;
}
#endif
if
(
0
!=
rename
(
*
tempfilename
,
filename
))
{
cleanup_tempfile_
(
tempfile
,
tempfilename
);
return
false
;
}
cleanup_tempfile_
(
tempfile
,
tempfilename
);
return
true
;
}
bool
get_file_stats_
(
const
char
*
filename
,
struct
stat
*
stats
)
{
FLAC__ASSERT
(
0
!=
filename
);
FLAC__ASSERT
(
0
!=
stats
);
return
(
0
==
stat
(
filename
,
stats
));
}
void
set_file_stats_
(
const
char
*
filename
,
struct
stat
*
stats
)
{
struct
utimbuf
srctime
;
FLAC__ASSERT
(
0
!=
filename
);
FLAC__ASSERT
(
0
!=
stats
);
srctime
.
actime
=
stats
->
st_atime
;
srctime
.
modtime
=
stats
->
st_mtime
;
(
void
)
chmod
(
filename
,
stats
->
st_mode
);
(
void
)
utime
(
filename
,
&
srctime
);
#if !defined _MSC_VER && !defined __MINGW32__
(
void
)
chown
(
filename
,
stats
->
st_uid
,
(
gid_t
)(
-
1
));
(
void
)
chown
(
filename
,
(
uid_t
)(
-
1
),
stats
->
st_gid
);
#endif
}
#ifdef FLAC__VALGRIND_TESTING
static
size_t
chain_write_cb_
(
const
void
*
ptr
,
size_t
size
,
size_t
nmemb
,
::
FLAC__IOHandle
handle
)
{
FILE
*
stream
=
(
FILE
*
)
handle
;
size_t
ret
=
fwrite
(
ptr
,
size
,
nmemb
,
stream
);
if
(
!
ferror
(
stream
))
fflush
(
stream
);
return
ret
;
}
#endif
static
int
chain_seek_cb_
(
::
FLAC__IOHandle
handle
,
FLAC__int64
offset
,
int
whence
)
{
long
o
=
(
long
)
offset
;
FLAC__ASSERT
(
offset
==
o
);
return
fseek
((
FILE
*
)
handle
,
o
,
whence
);
}
static
FLAC__int64
chain_tell_cb_
(
::
FLAC__IOHandle
handle
)
{
return
ftell
((
FILE
*
)
handle
);
}
static
int
chain_eof_cb_
(
::
FLAC__IOHandle
handle
)
{
return
feof
((
FILE
*
)
handle
);
}
static
bool
write_chain_
(
FLAC
::
Metadata
::
Chain
&
chain
,
bool
use_padding
,
bool
preserve_file_stats
,
bool
filename_based
,
const
char
*
filename
)
{
if
(
filename_based
)
return
chain
.
write
(
use_padding
,
preserve_file_stats
);
else
{
::
FLAC__IOCallbacks
callbacks
;
memset
(
&
callbacks
,
0
,
sizeof
(
callbacks
));
callbacks
.
read
=
(
::
FLAC__IOCallback_Read
)
fread
;
#ifdef FLAC__VALGRIND_TESTING
callbacks
.
write
=
chain_write_cb_
;
#else
callbacks
.
write
=
(
::
FLAC__IOCallback_Write
)
fwrite
;
#endif
callbacks
.
seek
=
chain_seek_cb_
;
callbacks
.
eof
=
chain_eof_cb_
;
if
(
chain
.
check_if_tempfile_needed
(
use_padding
))
{
struct
stat
stats
;
FILE
*
file
,
*
tempfile
;
char
*
tempfilename
;
if
(
preserve_file_stats
)
{
if
(
!
get_file_stats_
(
filename
,
&
stats
))
return
false
;
}
if
(
0
==
(
file
=
fopen
(
filename
,
"rb"
)))
return
false
;
/*@@@ chain status still says OK though */
if
(
!
open_tempfile_
(
filename
,
&
tempfile
,
&
tempfilename
))
{
fclose
(
file
);
cleanup_tempfile_
(
&
tempfile
,
&
tempfilename
);
return
false
;
/*@@@ chain status still says OK though */
}
if
(
!
chain
.
write
(
use_padding
,
(
::
FLAC__IOHandle
)
file
,
callbacks
,
(
::
FLAC__IOHandle
)
tempfile
,
callbacks
))
{
fclose
(
file
);
fclose
(
tempfile
);
return
false
;
}
fclose
(
file
);
fclose
(
tempfile
);
file
=
tempfile
=
0
;
if
(
!
transport_tempfile_
(
filename
,
&
tempfile
,
&
tempfilename
))
return
false
;
if
(
preserve_file_stats
)
set_file_stats_
(
filename
,
&
stats
);
}
else
{
FILE
*
file
=
fopen
(
filename
,
"r+b"
);
if
(
0
==
file
)
return
false
;
/*@@@ chain status still says OK though */
if
(
!
chain
.
write
(
use_padding
,
(
::
FLAC__IOHandle
)
file
,
callbacks
))
return
false
;
fclose
(
file
);
}
}
return
true
;
}
static
bool
read_chain_
(
FLAC
::
Metadata
::
Chain
&
chain
,
const
char
*
filename
,
bool
filename_based
)
{
if
(
filename_based
)
return
chain
.
read
(
filename
);
else
{
::
FLAC__IOCallbacks
callbacks
;
memset
(
&
callbacks
,
0
,
sizeof
(
callbacks
));
callbacks
.
read
=
(
::
FLAC__IOCallback_Read
)
fread
;
callbacks
.
seek
=
chain_seek_cb_
;
callbacks
.
tell
=
chain_tell_cb_
;
{
bool
ret
;
FILE
*
file
=
fopen
(
filename
,
"rb"
);
if
(
0
==
file
)
return
false
;
/*@@@ chain status still says OK though */
ret
=
chain
.
read
((
::
FLAC__IOHandle
)
file
,
callbacks
);
fclose
(
file
);
return
ret
;
}
}
}
/* function for comparing our metadata to a FLAC::Metadata::Chain */
static
bool
compare_chain_
(
FLAC
::
Metadata
::
Chain
&
chain
,
unsigned
current_position
,
FLAC
::
Metadata
::
Prototype
*
current_block
)
...
...
@@ -1082,7 +1288,7 @@ static bool test_level_1_()
return
true
;
}
static
bool
test_level_2_
()
static
bool
test_level_2_
(
bool
filename_based
)
{
FLAC
::
Metadata
::
Prototype
*
block
;
FLAC
::
Metadata
::
StreamInfo
*
streaminfo
;
...
...
@@ -1094,7 +1300,7 @@ static bool test_level_2_()
// initialize 'data' to avoid Valgrind errors
memset
(
data
,
0
,
sizeof
(
data
));
printf
(
"
\n\n
++++++ testing level 2 interface
\n
"
);
printf
(
"
\n\n
++++++ testing level 2 interface
(%s-based)
\n
"
,
filename_based
?
"filename"
:
"callback
"
);
printf
(
"generate read-only file
\n
"
);
...
...
@@ -1111,7 +1317,7 @@ static bool test_level_2_()
printf
(
"read chain
\n
"
);
if
(
!
chain
.
read
(
flacfile_
))
if
(
!
read_chain_
(
chain
,
flacfile_
,
filename_based
))
return
die_c_
(
"reading chain"
,
chain
.
status
());
printf
(
"[S]VP
\t
test initial metadata
\n
"
);
...
...
@@ -1150,7 +1356,7 @@ static bool test_level_2_()
return
die_
(
"copying object"
);
delete
block
;
if
(
!
chain
.
write
(
/*use_padding=*/
false
,
/*preserve_file_stats=*/
true
))
if
(
!
write_chain_
(
chain
,
/*use_padding=*/
false
,
/*preserve_file_stats=*/
true
,
filename_based
,
flacfile_
))
return
die_c_
(
"during chain.write(false, true)"
,
chain
.
status
());
block
=
iterator
.
get_block
();
if
(
!
compare_chain_
(
chain
,
our_current_position
,
block
))
...
...
@@ -1183,7 +1389,7 @@ static bool test_level_2_()
if
(
!
iterator
.
set_block
(
app
))
return
die_c_
(
"iterator.set_block(app)"
,
chain
.
status
());
if
(
!
chain
.
write
(
/*use_padding=*/
false
,
/*preserve_file_stats=*/
false
))
if
(
!
write_chain_
(
chain
,
/*use_padding=*/
false
,
/*preserve_file_stats=*/
false
,
filename_based
,
flacfile_
))
return
die_c_
(
"during chain.write(false, false)"
,
chain
.
status
());
block
=
iterator
.
get_block
();
if
(
!
compare_chain_
(
chain
,
our_current_position
,
block
))
...
...
@@ -1202,7 +1408,7 @@ static bool test_level_2_()
if
(
!
iterator
.
set_block
(
app
))
return
die_c_
(
"iterator.set_block(app)"
,
chain
.
status
());
if
(
!
chain
.
write
(
/*use_padding=*/
false
,
/*preserve_file_stats=*/
false
))
if
(
!
write_chain_
(
chain
,
/*use_padding=*/
false
,
/*preserve_file_stats=*/
false
,
filename_based
,
flacfile_
))
return
die_c_
(
"during chain.write(false, false)"
,
chain
.
status
());
block
=
iterator
.
get_block
();
if
(
!
compare_chain_
(
chain
,
our_current_position
,
block
))
...
...
@@ -1221,7 +1427,7 @@ static bool test_level_2_()
if
(
!
iterator
.
set_block
(
app
))
return
die_c_
(
"iterator.set_block(app)"
,
chain
.
status
());
if
(
!
chain
.
write
(
/*use_padding=*/
false
,
/*preserve_file_stats=*/
false
))
if
(
!
write_chain_
(
chain
,
/*use_padding=*/
false
,
/*preserve_file_stats=*/
false
,
filename_based
,
flacfile_
))
return
die_c_
(
"during chain.write(false, false)"
,
chain
.
status
());
block
=
iterator
.
get_block
();
if
(
!
compare_chain_
(
chain
,
our_current_position
,
block
))
...
...
@@ -1240,7 +1446,7 @@ static bool test_level_2_()
if
(
!
iterator
.
set_block
(
app
))
return
die_c_
(
"iterator.set_block(app)"
,
chain
.
status
());
if
(
!
chain
.
write
(
/*use_padding=*/
false
,
/*preserve_file_stats=*/
false
))
if
(
!
write_chain_
(
chain
,
/*use_padding=*/
false
,
/*preserve_file_stats=*/
false
,
filename_based
,
flacfile_
))
return
die_c_
(
"during chain.write(false, false)"
,
chain
.
status
());
block
=
iterator
.
get_block
();
if
(
!
compare_chain_
(
chain
,
our_current_position
,
block
))
...
...
@@ -1259,7 +1465,7 @@ static bool test_level_2_()
if
(
!
iterator
.
set_block
(
app
))
return
die_c_
(
"iterator.set_block(app)"
,
chain
.
status
());
if
(
!
chain
.
write
(
/*use_padding=*/
true
,
/*preserve_file_stats=*/
false
))
if
(
!
write_chain_
(
chain
,
/*use_padding=*/
true
,
/*preserve_file_stats=*/
false
,
filename_based
,
flacfile_
))
return
die_c_
(
"during chain.write(true, false)"
,
chain
.
status
());
block
=
iterator
.
get_block
();
if
(
!
compare_chain_
(
chain
,
our_current_position
,
block
))
...
...
@@ -1283,7 +1489,7 @@ static bool test_level_2_()
if
(
!
iterator
.
set_block
(
app
))
return
die_c_
(
"iterator.set_block(app)"
,
chain
.
status
());
if
(
!
chain
.
write
(
/*use_padding=*/
true
,
/*preserve_file_stats=*/
false
))
if
(
!
write_chain_
(
chain
,
/*use_padding=*/
true
,
/*preserve_file_stats=*/
false
,
filename_based
,
flacfile_
))
return
die_c_
(
"during chain.write(true, false)"
,
chain
.
status
());
block
=
iterator
.
get_block
();
if
(
!
compare_chain_
(
chain
,
our_current_position
,
block
))
...
...
@@ -1303,7 +1509,7 @@ static bool test_level_2_()
if
(
!
iterator
.
set_block
(
app
))
return
die_c_
(
"iterator.set_block(app)"
,
chain
.
status
());
if
(
!
chain
.
write
(
/*use_padding=*/
true
,
/*preserve_file_stats=*/
false
))
if
(
!
write_chain_
(
chain
,
/*use_padding=*/
true
,
/*preserve_file_stats=*/
false
,
filename_based
,
flacfile_
))
return
die_c_
(
"during chain.write(true, false)"
,
chain
.
status
());
block
=
iterator
.
get_block
();
if
(
!
compare_chain_
(
chain
,
our_current_position
,
block
))
...
...
@@ -1322,7 +1528,7 @@ static bool test_level_2_()
if
(
!
iterator
.
set_block
(
app
))
return
die_c_
(
"iterator.set_block(app)"
,
chain
.
status
());
if
(
!
chain
.
write
(
/*use_padding=*/
true
,
/*preserve_file_stats=*/
false
))
if
(
!
write_chain_
(
chain
,
/*use_padding=*/
true
,
/*preserve_file_stats=*/
false
,
filename_based
,
flacfile_
))
return
die_c_
(
"during chain.write(true, false)"
,
chain
.
status
());
block
=
iterator
.
get_block
();
if
(
!
compare_chain_
(
chain
,
our_current_position
,
block
))
...
...
@@ -1342,7 +1548,7 @@ static bool test_level_2_()
if
(
!
iterator
.
set_block
(
app
))
return
die_c_
(
"iterator.set_block(app)"
,
chain
.
status
());
if
(
!
chain
.
write
(
/*use_padding=*/
true
,
/*preserve_file_stats=*/
false
))
if
(
!
write_chain_
(
chain
,
/*use_padding=*/
true
,
/*preserve_file_stats=*/
false
,
filename_based
,
flacfile_
))
return
die_c_
(
"during chain.write(true, false)"
,
chain
.
status
());
block
=
iterator
.
get_block
();
if
(
!
compare_chain_
(
chain
,
our_current_position
,
block
))
...
...
@@ -1362,7 +1568,7 @@ static bool test_level_2_()
if
(
!
iterator
.
set_block
(
app
))
return
die_c_
(
"iterator.set_block(app)"
,
chain
.
status
());
if
(
!
chain
.
write
(
/*use_padding=*/
true
,
/*preserve_file_stats=*/
false
))
if
(
!
write_chain_
(
chain
,
/*use_padding=*/
true
,
/*preserve_file_stats=*/
false
,
filename_based
,
flacfile_
))
return
die_c_
(
"during chain.write(true, false)"
,
chain
.
status
());
block
=
iterator
.
get_block
();
if
(
!
compare_chain_
(
chain
,
our_current_position
,
block
))
...
...
@@ -1489,7 +1695,7 @@ static bool test_level_2_()
delete_from_our_metadata_
(
4
);
delete_from_our_metadata_
(
3
);
if
(
!
chain
.
write
(
/*use_padding=*/
true
,
/*preserve_file_stats=*/
false
))
if
(
!
write_chain_
(
chain
,
/*use_padding=*/
true
,
/*preserve_file_stats=*/
false
,
filename_based
,
flacfile_
))
return
die_c_
(
"during chain.write(true, false)"
,
chain
.
status
());
if
(
!
compare_chain_
(
chain
,
0
,
0
))
return
false
;
...
...
@@ -1501,7 +1707,7 @@ static bool test_level_2_()
add_to_padding_length_
(
4
,
FLAC__STREAM_METADATA_HEADER_LENGTH
+
our_metadata_
.
blocks
[
2
]
->
get_length
());
delete_from_our_metadata_
(
2
);
if
(
!
chain
.
write
(
/*use_padding=*/
true
,
/*preserve_file_stats=*/
false
))
if
(
!
write_chain_
(
chain
,
/*use_padding=*/
true
,
/*preserve_file_stats=*/
false
,
filename_based
,
flacfile_
))
return
die_c_
(
"during chain.write(true, false)"
,
chain
.
status
());
if
(
!
compare_chain_
(
chain
,
0
,
0
))
return
false
;
...
...
@@ -1605,13 +1811,13 @@ static bool test_level_2_()
return
false
;
delete
block
;
}
}
// delete iterator
our_current_position
=
0
;
printf
(
"SV
\t
merge padding
\n
"
);
chain
.
merge_padding
();
if
(
!
chain
.
write
(
/*use_padding=*/
false
,
/*preserve_file_stats=*/
false
))
if
(
!
write_chain_
(
chain
,
/*use_padding=*/
false
,
/*preserve_file_stats=*/
false
,
filename_based
,
flacfile_
))
return
die_c_
(
"during chain.write(false, false)"
,
chain
.
status
());
if
(
!
compare_chain_
(
chain
,
0
,
0
))
return
false
;
...
...
@@ -1621,7 +1827,7 @@ static bool test_level_2_()
printf
(
"SV
\t
sort padding
\n
"
);
chain
.
sort_padding
();
if
(
!
chain
.
write
(
/*use_padding=*/
false
,
/*preserve_file_stats=*/
false
))
if
(
!
write_chain_
(
chain
,
/*use_padding=*/
false
,
/*preserve_file_stats=*/
false
,
filename_based
,
flacfile_
))
return
die_c_
(
"during chain.write(false, false)"
,
chain
.
status
());
if
(
!
compare_chain_
(
chain
,
0
,
0
))
return
false
;
...
...
@@ -1634,6 +1840,162 @@ static bool test_level_2_()
return
true
;
}
static
bool
test_level_2_misc_
()
{
::
FLAC__IOCallbacks
callbacks
;
memset
(
&
callbacks
,
0
,
sizeof
(
callbacks
));
callbacks
.
read
=
(
::
FLAC__IOCallback_Read
)
fread
;
#ifdef FLAC__VALGRIND_TESTING
callbacks
.
write
=
chain_write_cb_
;
#else
callbacks
.
write
=
(
::
FLAC__IOCallback_Write
)
fwrite
;
#endif
callbacks
.
seek
=
chain_seek_cb_
;
callbacks
.
tell
=
chain_tell_cb_
;
callbacks
.
eof
=
chain_eof_cb_
;
printf
(
"
\n\n
++++++ testing level 2 interface (mismatched read/write protections)
\n
"
);
printf
(
"generate file
\n
"
);
if
(
!
generate_file_
())
return
false
;
printf
(
"create chain
\n
"
);
FLAC
::
Metadata
::
Chain
chain
;
if
(
!
chain
.
is_valid
())
return
die_
(
"allocating chain"
);
printf
(
"read chain (filename-based)
\n
"
);
if
(
!
chain
.
read
(
flacfile_
))
return
die_c_
(
"reading chain"
,
chain
.
status
());
printf
(
"write chain with wrong method Chain::write(with callbacks)
\n
"
);
{
if
(
chain
.
write
(
/*use_padding=*/
false
,
0
,
callbacks
))
return
die_c_
(
"mismatched write should have failed"
,
chain
.
status
());
if
(
chain
.
status
()
!=
::
FLAC__METADATA_CHAIN_STATUS_READ_WRITE_MISMATCH
)
return
die_c_
(
"expected FLAC__METADATA_CHAIN_STATUS_READ_WRITE_MISMATCH"
,
chain
.
status
());
printf
(
" OK: Chain::write(with callbacks) returned false,FLAC__METADATA_CHAIN_STATUS_READ_WRITE_MISMATCH like it should
\n
"
);
}
printf
(
"read chain (filename-based)
\n
"
);
if
(
!
chain
.
read
(
flacfile_
))
return
die_c_
(
"reading chain"
,
chain
.
status
());
printf
(
"write chain with wrong method Chain::write(with callbacks and tempfile)
\n
"
);
{
if
(
chain
.
write
(
/*use_padding=*/
false
,
0
,
callbacks
,
0
,
callbacks
))
return
die_c_
(
"mismatched write should have failed"
,
chain
.
status
());
if
(
chain
.
status
()
!=
::
FLAC__METADATA_CHAIN_STATUS_READ_WRITE_MISMATCH
)
return
die_c_
(
"expected FLAC__METADATA_CHAIN_STATUS_READ_WRITE_MISMATCH"
,
chain
.
status
());
printf
(
" OK: Chain::write(with callbacks and tempfile) returned false,FLAC__METADATA_CHAIN_STATUS_READ_WRITE_MISMATCH like it should
\n
"
);
}
printf
(
"read chain (callback-based)
\n
"
);
{
FILE
*
file
=
fopen
(
flacfile_
,
"rb"
);
if
(
0
==
file
)
return
die_
(
"opening file"
);
if
(
!
chain
.
read
((
::
FLAC__IOHandle
)
file
,
callbacks
))
{
fclose
(
file
);
return
die_c_
(
"reading chain"
,
chain
.
status
());
}
fclose
(
file
);
}
printf
(
"write chain with wrong method write()
\n
"
);
{
if
(
chain
.
write
(
/*use_padding=*/
false
,
/*preserve_file_stats=*/
false
))
return
die_c_
(
"mismatched write should have failed"
,
chain
.
status
());
if
(
chain
.
status
()
!=
::
FLAC__METADATA_CHAIN_STATUS_READ_WRITE_MISMATCH
)
return
die_c_
(
"expected FLAC__METADATA_CHAIN_STATUS_READ_WRITE_MISMATCH"
,
chain
.
status
());
printf
(
" OK: write() returned false,FLAC__METADATA_CHAIN_STATUS_READ_WRITE_MISMATCH like it should
\n
"
);
}
printf
(
"read chain (callback-based)
\n
"
);
{
FILE
*
file
=
fopen
(
flacfile_
,
"rb"
);
if
(
0
==
file
)
return
die_
(
"opening file"
);
if
(
!
chain
.
read
((
::
FLAC__IOHandle
)
file
,
callbacks
))
{
fclose
(
file
);
return
die_c_
(
"reading chain"
,
chain
.
status
());
}
fclose
(
file
);
}
printf
(
"testing Chain::check_if_tempfile_needed()... "
);
if
(
!
chain
.
check_if_tempfile_needed
(
/*use_padding=*/
false
))
printf
(
"OK: Chain::check_if_tempfile_needed() returned false like it should
\n
"
);
else
return
die_
(
"Chain::check_if_tempfile_needed() returned true but shouldn't have"
);
printf
(
"write chain with wrong method Chain::write(with callbacks and tempfile)
\n
"
);
{
if
(
chain
.
write
(
/*use_padding=*/
false
,
0
,
callbacks
,
0
,
callbacks
))
return
die_c_
(
"mismatched write should have failed"
,
chain
.
status
());
if
(
chain
.
status
()
!=
::
FLAC__METADATA_CHAIN_STATUS_WRONG_WRITE_CALL
)
return
die_c_
(
"expected FLAC__METADATA_CHAIN_STATUS_WRONG_WRITE_CALL"
,
chain
.
status
());
printf
(
" OK: Chain::write(with callbacks and tempfile) returned false,FLAC__METADATA_CHAIN_STATUS_WRONG_WRITE_CALL like it should
\n
"
);
}
printf
(
"read chain (callback-based)
\n
"
);
{
FILE
*
file
=
fopen
(
flacfile_
,
"rb"
);
if
(
0
==
file
)
return
die_
(
"opening file"
);
if
(
!
chain
.
read
((
::
FLAC__IOHandle
)
file
,
callbacks
))
{
fclose
(
file
);
return
die_c_
(
"reading chain"
,
chain
.
status
());
}
fclose
(
file
);
}
printf
(
"create iterator
\n
"
);
{
FLAC
::
Metadata
::
Iterator
iterator
;
if
(
!
iterator
.
is_valid
())
return
die_
(
"allocating memory for iterator"
);
iterator
.
init
(
chain
);
printf
(
"[S]VP
\t
next
\n
"
);
if
(
!
iterator
.
next
())
return
die_
(
"iterator ended early
\n
"
);
printf
(
"S[V]P
\t
delete VORBIS_COMMENT, write
\n
"
);
if
(
!
iterator
.
delete_block
(
/*replace_with_padding=*/
false
))
return
die_c_
(
"block delete failed
\n
"
,
chain
.
status
());
printf
(
"testing Chain::check_if_tempfile_needed()... "
);
if
(
chain
.
check_if_tempfile_needed
(
/*use_padding=*/
false
))
printf
(
"OK: Chain::check_if_tempfile_needed() returned true like it should
\n
"
);
else
return
die_
(
"Chain::check_if_tempfile_needed() returned false but shouldn't have"
);
printf
(
"write chain with wrong method Chain::write(with callbacks)
\n
"
);
{
if
(
chain
.
write
(
/*use_padding=*/
false
,
0
,
callbacks
))
return
die_c_
(
"mismatched write should have failed"
,
chain
.
status
());
if
(
chain
.
status
()
!=
::
FLAC__METADATA_CHAIN_STATUS_WRONG_WRITE_CALL
)
return
die_c_
(
"expected FLAC__METADATA_CHAIN_STATUS_WRONG_WRITE_CALL"
,
chain
.
status
());
printf
(
" OK: Chain::write(with callbacks) returned false,FLAC__METADATA_CHAIN_STATUS_WRONG_WRITE_CALL like it should
\n
"
);
}
}
// delete iterator
if
(
!
remove_file_
(
flacfile_
))
return
false
;
return
true
;
}