Split archive_{read,write}_finish into separate "close" (finish the archive

and close it) and "finish" (destroy the object) functions.   For backwards
compat and simplicity, have "finish" invoke "close" transparently if needed.
This allows clients to close the archive and check end-of-operation
statistics before destroying the object.
This commit is contained in:
kientzle 2004-08-07 19:22:50 +00:00
parent 42609f208c
commit ce43965b8b
6 changed files with 67 additions and 22 deletions

View File

@ -7,9 +7,10 @@
LIB= archive
SHLIB_MAJOR= 1
VERSION= 1.00.009
ARCHIVE_API_FEATURE= 1
VERSION= 1.01.010
ARCHIVE_API_FEATURE= 2
ARCHIVE_API_VERSION= 1
SHLIB_MAJOR= ${ARCHIVE_API_VERSION}
CFLAGS+= -DPACKAGE_NAME=\"lib${LIB}\"
CFLAGS+= -DPACKAGE_VERSION=\"${VERSION}\"
CFLAGS+= -I${.OBJDIR}
@ -182,7 +183,7 @@ CLEANFILES+= archive.h
# Build archive.h from archive.h.in
archive.h: archive.h.in Makefile
cat ${.CURDIR}/archive.h.in | \
sed 's/@ARCHIVE_API_VERSION@/${SHLIB_MAJOR}/' | \
sed 's/@ARCHIVE_API_VERSION@/${ARCHIVE_API_VERSION}/' | \
sed 's/@ARCHIVE_API_FEATURE@/${ARCHIVE_API_FEATURE}/' | \
cat > archive.h

View File

@ -41,7 +41,8 @@
* the features you're relying on. Specific values of FEATURE are
* documented here:
*
* 1 - Version test is available.
* 1 - Version tests are available.
* 2 - archive_{read,write}_close available separately from _finish.
*/
#define ARCHIVE_API_VERSION @ARCHIVE_API_VERSION@
int archive_api_version(void);
@ -138,7 +139,7 @@ typedef int archive_close_callback(struct archive *, void *_client_data);
* 4) Repeatedly call archive_read_next_header to get information about
* successive archive entries. Call archive_read_data to extract
* data for entries of interest.
* 5) Call archive_read_finish to destroy the object.
* 5) Call archive_read_finish to end processing.
*/
struct archive *archive_read_new(void);
@ -237,7 +238,10 @@ int archive_read_extract(struct archive *, struct archive_entry *,
void archive_read_extract_set_progress_callback(struct archive *,
void (*_progress_func)(void *), void *_user_data);
/* Close the file, release any resources, and destroy the object. */
/* Close the file and release most resources. */
int archive_read_close(struct archive *);
/* Release all resources and destroy the object. */
/* Note that archive_read_finish will call archive_read_close for you. */
void archive_read_finish(struct archive *);
/*-
@ -250,7 +254,8 @@ void archive_read_finish(struct archive *);
* - construct an appropriate struct archive_entry structure
* - archive_write_header to write the header
* - archive_write_data to write the entry data
* 5) archive_write_finish to close the output and cleanup the writer
* 5) archive_write_close to close the output
* 6) archive_write_finish to cleanup the writer and release resources
*/
struct archive *archive_write_new(void);
int archive_write_set_bytes_per_block(struct archive *,
@ -287,6 +292,7 @@ int archive_write_open_file(struct archive *, const char *_file);
int archive_write_header(struct archive *,
struct archive_entry *);
int archive_write_data(struct archive *, const void *, size_t);
int archive_write_close(struct archive *);
void archive_write_finish(struct archive *);
/*

View File

@ -49,6 +49,7 @@
.Nm archive_read_data_into_fd ,
.Nm archive_read_extract ,
.Nm archive_read_extract_set_progress_callback ,
.Nm archive_read_close
.Nm archive_read_finish
.Nd functions for reading tar archives
.Sh SYNOPSIS
@ -95,6 +96,8 @@
.Fn archive_read_extract "struct archive *" "int flags"
.Ft void
.Fn archive_read_extract_set_progress_callback "struct archive *" "void (*func)(void *)" "void *user_data"
.Ft int
.Fn archive_read_close "struct archive *"
.Ft void
.Fn archive_read_finish "struct archive *"
.Sh DESCRIPTION
@ -231,9 +234,12 @@ The progress function will be invoked with the pointer provided to this call.
Generally, the data pointed to should include a reference to the archive
object and the archive_entry object so that various statistics
can be retrieved for the progress display.
.It Fn archive_read_close
Complete the archive and invoke the close callback.
.It Fn archive_read_finish
Complete the archive, invoke the close callback, and release
all resources.
Invokes
.Fn archive_read_close
if it wasn't invoked maually, then release all resources.
.El
.Pp
Note that the library determines most of the relevant information about

View File

@ -441,18 +441,15 @@ archive_read_data_block(struct archive *a,
}
/*
* Cleanup and free the archive object.
* Close the file and release most resources.
*
* Be careful: client might just call read_new and then read_finish.
* Don't assume we actually read anything or performed any non-trivial
* initialization.
*/
void
archive_read_finish(struct archive *a)
int
archive_read_close(struct archive *a)
{
int i;
int slots;
archive_check_magic(a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_ANY);
a->state = ARCHIVE_STATE_CLOSED;
@ -465,6 +462,21 @@ archive_read_finish(struct archive *a)
/* Close the input machinery. */
if (a->compression_finish != NULL)
(a->compression_finish)(a);
return (ARCHIVE_OK);
}
/*
* Release memory and other resources.
*/
void
archive_read_finish(struct archive *a)
{
int i;
int slots;
archive_check_magic(a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_ANY);
if (a->state != ARCHIVE_STATE_CLOSED)
archive_read_close(a);
/* Cleanup format-specific data. */
slots = sizeof(a->formats) / sizeof(a->formats[0]);

View File

@ -45,6 +45,7 @@
.Nm archive_write_prepare ,
.Nm archive_write_header ,
.Nm archive_write_data ,
.Nm archive_write_close ,
.Nm archive_write_finish
.Nd functions for creating archives
.Sh SYNOPSIS
@ -82,6 +83,8 @@
.Ft int
.Fn archive_write_data "struct archive *" "const void *" "size_t"
.Ft int
.Fn archive_write_close "struct archive *"
.Ft void
.Fn archive_write_finish "struct archive *"
.Sh DESCRIPTION
These functions provide a complete API for creating streaming
@ -187,9 +190,12 @@ Build and write a header using the data in the provided
structure.
.It Fn archive_write_data
Write data corresponding to the header just written.
.It Fn archive_write_close
Complete the archive and invoke the close callback.
.It Fn archive_write_finish
Complete the archive, invoke the close callback, and release
all resources.
Invokes
.Fn archive_write_close
if it wasn't invoked manually, then release all resources.
.El
.Pp
The callback functions are defined as follows:
@ -321,7 +327,7 @@ may include
.Fn archive_write_header ,
.Fn archive_write_data ,
or
.Fn archive_write_finish .
.Fn archive_write_close .
In such a case, the
.Fn archive_errno
or

View File

@ -141,14 +141,14 @@ archive_write_open(struct archive *a, void *client_data,
/*
* Cleanup and free the archive object.
* Close out the archive.
*
* Be careful: user might just call write_new and then write_finish.
* Don't assume we actually wrote anything or performed any non-trivial
* initialization.
*/
void
archive_write_finish(struct archive *a)
int
archive_write_close(struct archive *a)
{
archive_check_magic(a, ARCHIVE_WRITE_MAGIC, ARCHIVE_STATE_ANY);
@ -164,6 +164,20 @@ archive_write_finish(struct archive *a)
if (a->compression_finish != NULL)
(a->compression_finish)(a);
a->state = ARCHIVE_STATE_CLOSED;
return (ARCHIVE_OK);
}
/*
* Destroy the archive structure.
*/
void
archive_write_finish(struct archive *a)
{
archive_check_magic(a, ARCHIVE_WRITE_MAGIC, ARCHIVE_STATE_ANY);
if (a->state != ARCHIVE_STATE_CLOSED)
archive_write_close(a);
/* Release various dynamic buffers. */
free((void *)(uintptr_t)(const void *)a->nulls);
archive_string_free(&a->error_string);