add streamo_steal
and start converting some old dbuf code
This commit is contained in:
parent
c7f622d646
commit
a129cef9dd
@ -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
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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 *) "<", 4 ) )
|
||||
if( vips_streamo_writes( streamo, "<" ) )
|
||||
return( -1 );
|
||||
}
|
||||
else if( *p == '>' ) {
|
||||
if( !vips_streamo_write( streamo,
|
||||
(guchar *) ">", 4 ) )
|
||||
if( vips_streamo_writes( streamo, ">" ) )
|
||||
return( -1 );
|
||||
}
|
||||
else if( *p == '&' ) {
|
||||
if( !vips_streamo_write( streamo,
|
||||
(guchar *) "&", 5 ) )
|
||||
if( vips_streamo_writes( streamo, "&" ) )
|
||||
return( -1 );
|
||||
}
|
||||
else {
|
||||
if( !vips_streamo_putc( streamo, *p ) )
|
||||
if( VIPS_STREAMO_PUTC( streamo, *p ) )
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
|
@ -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.
|
||||
|
Loading…
Reference in New Issue
Block a user