add streamo_steal

and start converting some old dbuf code
This commit is contained in:
John Cupitt 2019-11-19 06:47:24 +00:00
parent c7f622d646
commit a129cef9dd
4 changed files with 111 additions and 36 deletions

View File

@ -268,8 +268,7 @@ vips_g_input_stream_skip( GInputStream *stream, gsize count,
GCancellable *cancellable, GError **error )
{
VipsStreami *streami;
goffset start;
goffset end;
gssize position;
streami = VIPS_G_INPUT_STREAM( stream )->streami;
@ -278,8 +277,8 @@ vips_g_input_stream_skip( GInputStream *stream, gsize count,
if( g_cancellable_set_error_if_cancelled( cancellable, error ) )
return( -1 );
start = vips_streami_seek( streami, count, SEEK_CUR );
if( start == -1 ) {
position = vips_streami_seek( streami, count, SEEK_CUR );
if( position == -1 ) {
g_set_error( error, G_IO_ERROR,
G_IO_ERROR_FAILED,
_( "Error while seeking: %s" ),
@ -287,7 +286,7 @@ vips_g_input_stream_skip( GInputStream *stream, gsize count,
return( -1 );
}
return( count );
return( position );
}
static gboolean

View File

@ -241,6 +241,10 @@ typedef struct _VipsStreamo {
/*< private >*/
/* The stream has been finished and can no longer be written.
*/
gboolean finished;
/* Write memory output here.
*/
GByteArray *memory;
@ -278,16 +282,19 @@ VipsStreamo *vips_streamo_new_to_filename( const char *filename );
VipsStreamo *vips_streamo_new_to_memory( void );
int vips_streamo_write( VipsStreamo *streamo, const void *data, size_t length );
void vips_streamo_finish( VipsStreamo *streamo );
unsigned char *vips_streamo_steal( VipsStreamo *streamo, size_t *length );
char *vips_streamo_steal_text( VipsStreamo *streamo );
int vips_streamo_putc( VipsStreamo *streamo, int ch );
#define VIPS_STREAMO_PUTC( S, C ) ( \
(S)->write_point <= VIPS_STREAMO_BUFFER_SIZE ? \
(S)->write_point < VIPS_STREAMO_BUFFER_SIZE ? \
((S)->output_buffer[(S)->write_point++] = (C), 0) : \
vips_streamo_putc( (S), (C) ) \
)
int vips_streamo_writes( VipsStreamo *streamo, const char *str );
int vips_streamo_writef( VipsStreamo *streamo, const char *fmt, ... )
__attribute__((format(printf, 2, 3)));
int vips_streamo_write_amp( VipsStreamo *streamo, const char *str );
#ifdef __cplusplus
}

View File

@ -293,6 +293,9 @@ vips_streamo_write_unbuffered( VipsStreamo *streamo,
{
VipsStreamoClass *class = VIPS_STREAMO_GET_CLASS( streamo );
if( streamo->finished )
return( 0 );
if( streamo->memory )
g_byte_array_append( streamo->memory, data, length );
else
@ -375,7 +378,10 @@ vips_streamo_write( VipsStreamo *streamo, const void *buffer, size_t length )
* @buffer: bytes to write
* @length: length of @buffer in bytes
*
* Call this at the end of write to make the stream do any cleaning up.
* Call this at the end of write to make the stream do any cleaning up. You
* can call it many times.
*
* After a streamo has been finished, further writes will do nothing.
*/
void
vips_streamo_finish( VipsStreamo *streamo )
@ -384,6 +390,9 @@ vips_streamo_finish( VipsStreamo *streamo )
VIPS_DEBUG_MSG( "vips_streamo_finish:\n" );
if( streamo->finished )
return;
(void) vips_streamo_flush( streamo );
/* Move the stream buffer into the blob so it can be read out.
@ -400,6 +409,69 @@ vips_streamo_finish( VipsStreamo *streamo )
}
else
class->finish( streamo );
streamo->finished = TRUE;
}
/**
* vips_streamo_steal:
* @streamo: output stream to operate on
* @length: return number of bytes of data
*
* Memory streams only (see vips_streamo_new_to_memory()). Steal all data
* written to the stream so far, and finish it.
*
* You must free the returned pointer with g_free().
*
* The data is NOT automatically null-terminated. vips_streamo_putc() a '\0'
* before calling this to get a null-terminated string.
*
* Returns: (array length=length) (element-type guint8) (transfer full): the
* data
*/
unsigned char *
vips_streamo_steal( VipsStreamo *streamo, size_t *length )
{
unsigned char *data;
(void) vips_streamo_flush( streamo );
if( !streamo->memory ||
streamo->finished ) {
if( length )
*length = streamo->memory->len;
return( NULL );
}
if( length )
*length = streamo->memory->len;
data = g_byte_array_free( streamo->memory, FALSE );
streamo->memory = NULL;
/* We must have a valid byte array or finish will fail.
*/
streamo->memory = g_byte_array_new();
vips_streamo_finish( streamo );
return( data );
}
/**
* vips_streamo_steal_text:
* @streamo: output stream to operate on
*
* As vips_streamo_steal_text(), but return a null-terminated string.
*
* Returns: (transfer full): stream contents as a null-terminated string.
*/
char *
vips_streamo_steal_text( VipsStreamo *streamo )
{
vips_streamo_putc( streamo, '\0' );
return( (char *) vips_streamo_steal( streamo, NULL ) );
}
/**
@ -417,7 +489,7 @@ vips_streamo_putc( VipsStreamo *streamo, int ch )
{
VIPS_DEBUG_MSG( "vips_streamo_putc: %d\n", ch );
if( streamo->write_point > VIPS_STREAMO_BUFFER_SIZE &&
if( streamo->write_point >= VIPS_STREAMO_BUFFER_SIZE &&
vips_streamo_flush( streamo ) )
return( -1 );
@ -504,27 +576,24 @@ vips_streamo_write_amp( VipsStreamo *streamo, const char *str )
* control characters, so we can use them -- thanks
* electroly.
*/
if( !vips_streamo_writef( streamo,
if( vips_streamo_writef( streamo,
"&#x%04x;", 0x2400 + *p ) )
return( -1 );
}
else if( *p == '<' ) {
if( !vips_streamo_write( streamo,
(guchar *) "&lt;", 4 ) )
if( vips_streamo_writes( streamo, "&lt;" ) )
return( -1 );
}
else if( *p == '>' ) {
if( !vips_streamo_write( streamo,
(guchar *) "&gt;", 4 ) )
if( vips_streamo_writes( streamo, "&gt;" ) )
return( -1 );
}
else if( *p == '&' ) {
if( !vips_streamo_write( streamo,
(guchar *) "&amp;", 5 ) )
if( vips_streamo_writes( streamo, "&amp;" ) )
return( -1 );
}
else {
if( !vips_streamo_putc( streamo, *p ) )
if( VIPS_STREAMO_PUTC( streamo, *p ) )
return( -1 );
}

View File

@ -912,7 +912,7 @@ static void *
vips__xml_properties_meta( VipsImage *image,
const char *field, GValue *value, void *a )
{
VipsDbuf *dbuf = (VipsDbuf *) a;
VipsStreamo *streamo = (VipsStreamo *) a;
GType type = G_VALUE_TYPE( value );
const char *str;
@ -928,19 +928,19 @@ vips__xml_properties_meta( VipsImage *image,
if( !g_value_transform( value, &save_value ) ) {
vips_error( "VipsImage", "%s",
_( "error transforming to save format" ) );
return( dbuf );
return( streamo );
}
str = vips_value_get_save_string( &save_value );
vips_dbuf_writef( dbuf, " <property>\n" );
vips_dbuf_writef( dbuf, " <name>" );
vips_dbuf_write_amp( dbuf, field );
vips_dbuf_writef( dbuf, "</name>\n" );
vips_dbuf_writef( dbuf, " <value type=\"%s\">",
vips_streamo_writef( streamo, " <property>\n" );
vips_streamo_writef( streamo, " <name>" );
vips_streamo_write_amp( streamo, field );
vips_streamo_writef( streamo, "</name>\n" );
vips_streamo_writef( streamo, " <value type=\"%s\">",
g_type_name( type ) );
vips_dbuf_write_amp( dbuf, str );
vips_dbuf_writef( dbuf, "</value>\n" );
vips_dbuf_writef( dbuf, " </property>\n" );
vips_streamo_write_amp( streamo, str );
vips_streamo_writef( streamo, "</value>\n" );
vips_streamo_writef( streamo, " </property>\n" );
g_value_unset( &save_value );
}
@ -954,31 +954,31 @@ vips__xml_properties_meta( VipsImage *image,
char *
vips__xml_properties( VipsImage *image )
{
VipsDbuf dbuf;
VipsStreamo *streamo;
char *date;
date = vips__get_iso8601();
vips_dbuf_init( &dbuf );
vips_dbuf_writef( &dbuf, "<?xml version=\"1.0\"?>\n" );
vips_dbuf_writef( &dbuf, "<image xmlns=\"%s/dzsave\" "
streamo = vips_streamo_new_to_memory();
vips_streamo_writef( streamo, "<?xml version=\"1.0\"?>\n" );
vips_streamo_writef( streamo, "<image xmlns=\"%s/dzsave\" "
"date=\"%s\" version=\"%d.%d.%d\">\n",
NAMESPACE_URI,
date,
VIPS_MAJOR_VERSION, VIPS_MINOR_VERSION, VIPS_MICRO_VERSION );
vips_dbuf_writef( &dbuf, " <properties>\n" );
vips_streamo_writef( streamo, " <properties>\n" );
g_free( date );
if( vips_image_map( image, vips__xml_properties_meta, &dbuf ) ) {
vips_dbuf_destroy( &dbuf );
if( vips_image_map( image, vips__xml_properties_meta, streamo ) ) {
VIPS_UNREF( streamo );
return( NULL );
}
vips_dbuf_writef( &dbuf, " </properties>\n" );
vips_dbuf_writef( &dbuf, "</image>\n" );
vips_streamo_writef( streamo, " </properties>\n" );
vips_streamo_writef( streamo, "</image>\n" );
return( (char *) vips_dbuf_steal( &dbuf, NULL ) );
return( vips_streamo_steal_text( streamo ) );
}
/* Append XML to output fd.