rename bufis as well

This commit is contained in:
John Cupitt 2019-12-30 16:57:19 +00:00
parent 96cdc5ef01
commit 3847f71c54
5 changed files with 245 additions and 230 deletions

View File

@ -91,7 +91,7 @@ typedef struct _VipsForeignLoadPpm {
/* The source we load from, and the buffered wrapper for it.
*/
VipsSource *source;
VipsBufis *bufis;
VipsSbuf *sbuf;
/* Properties of this ppm, from the header.
*/
@ -150,12 +150,12 @@ vips_foreign_load_ppm_is_a_source( VipsSource *source )
}
static int
get_int( VipsBufis *bufis, int *i )
get_int( VipsSbuf *sbuf, int *i )
{
const char *txt;
if( vips_bufis_skip_whitespace( bufis ) ||
!(txt = vips_bufis_get_non_whitespace( bufis )) )
if( vips_sbuf_skip_whitespace( sbuf ) ||
!(txt = vips_sbuf_get_non_whitespace( sbuf )) )
return( -1 );
*i = atoi( txt );
@ -164,12 +164,12 @@ get_int( VipsBufis *bufis, int *i )
}
static int
get_float( VipsBufis *bufis, float *f )
get_float( VipsSbuf *sbuf, float *f )
{
const char *txt;
if( vips_bufis_skip_whitespace( bufis ) ||
!(txt = vips_bufis_get_non_whitespace( bufis )) )
if( vips_sbuf_skip_whitespace( sbuf ) ||
!(txt = vips_sbuf_get_non_whitespace( sbuf )) )
return( -1 );
/* We don't want the locale str -> float conversion.
@ -184,7 +184,7 @@ vips_foreign_load_ppm_dispose( GObject *gobject )
{
VipsForeignLoadPpm *ppm = (VipsForeignLoadPpm *) gobject;
VIPS_UNREF( ppm->bufis );
VIPS_UNREF( ppm->sbuf );
VIPS_UNREF( ppm->source );
G_OBJECT_CLASS( vips_foreign_load_ppm_parent_class )->
@ -218,8 +218,8 @@ vips_foreign_load_ppm_parse_header( VipsForeignLoadPpm *ppm )
/* Read in the magic number.
*/
buf[0] = VIPS_BUFIS_GETC( ppm->bufis );
buf[1] = VIPS_BUFIS_GETC( ppm->bufis );
buf[0] = VIPS_SBUF_GETC( ppm->sbuf );
buf[1] = VIPS_SBUF_GETC( ppm->sbuf );
for( i = 0; i < VIPS_NUMBER( magic_names ); i++ )
if( vips_isprefix( magic_names[i], buf ) )
@ -239,8 +239,8 @@ vips_foreign_load_ppm_parse_header( VipsForeignLoadPpm *ppm )
/* Read in size.
*/
if( get_int( ppm->bufis, &ppm->width ) ||
get_int( ppm->bufis, &ppm->height ) )
if( get_int( ppm->sbuf, &ppm->width ) ||
get_int( ppm->sbuf, &ppm->height ) )
return( -1 );
/* Read in max value / scale for >1 bit images.
@ -248,7 +248,7 @@ vips_foreign_load_ppm_parse_header( VipsForeignLoadPpm *ppm )
if( ppm->bits > 1 ) {
if( ppm->index == 6 ||
ppm->index == 7 ) {
if( get_float( ppm->bufis, &ppm->scale ) )
if( get_float( ppm->sbuf, &ppm->scale ) )
return( -1 );
/* Scale > 0 means big-endian.
@ -256,7 +256,7 @@ vips_foreign_load_ppm_parse_header( VipsForeignLoadPpm *ppm )
ppm->msb_first = ppm->scale > 0;
}
else {
if( get_int( ppm->bufis, &ppm->max_value ) )
if( get_int( ppm->sbuf, &ppm->max_value ) )
return( -1 );
if( ppm->max_value > 255 )
@ -270,7 +270,7 @@ vips_foreign_load_ppm_parse_header( VipsForeignLoadPpm *ppm )
* character before the data starts.
*/
if( !ppm->ascii &&
!isspace( VIPS_BUFIS_GETC( ppm->bufis ) ) ) {
!isspace( VIPS_SBUF_GETC( ppm->sbuf ) ) ) {
vips_error( class->nickname, "%s",
_( "no whitespace before start of binary data" ) );
return( -1 );
@ -366,7 +366,7 @@ vips_foreign_load_ppm_set_image( VipsForeignLoadPpm *ppm, VipsImage *image )
"ppm-max-value", VIPS_ABS( ppm->max_value ) );
VIPS_SETSTR( image->filename,
vips_connection_filename( VIPS_CONNECTION( ppm->bufis->source ) ) );
vips_connection_filename( VIPS_CONNECTION( ppm->sbuf->source ) ) );
}
static int
@ -397,7 +397,7 @@ vips_foreign_load_ppm_map( VipsForeignLoadPpm *ppm, VipsImage *image )
size_t length;
const void *data;
vips_bufis_unbuffer( ppm->bufis );
vips_sbuf_unbuffer( ppm->sbuf );
header_offset = vips_source_seek( ppm->source, 0, SEEK_CUR );
data = vips_source_map( ppm->source, &length );
if( header_offset < 0 ||
@ -462,7 +462,7 @@ vips_foreign_load_ppm_generate_1bit_ascii( VipsRegion *or,
for( x = 0; x < image->Xsize; x++ ) {
int val;
if( get_int( ppm->bufis, &val ) )
if( get_int( ppm->sbuf, &val ) )
return( -1 );
if( val )
@ -486,7 +486,7 @@ vips_foreign_load_ppm_generate_1bit_binary( VipsRegion *or,
int x, y;
int bits;
bits = VIPS_BUFIS_GETC( ppm->bufis );
bits = VIPS_SBUF_GETC( ppm->sbuf );
for( y = 0; y < r->height; y++ ) {
VipsPel *q = VIPS_REGION_ADDR( or, 0, r->top + y );
@ -494,13 +494,13 @@ vips_foreign_load_ppm_generate_1bit_binary( VipsRegion *or,
q[x] = (bits & 128) ? 0 : 255;
bits = VIPS_LSHIFT_INT( bits, 1 );
if( (x & 7) == 7 )
bits = VIPS_BUFIS_GETC( ppm->bufis );
bits = VIPS_SBUF_GETC( ppm->sbuf );
}
/* Skip any unaligned bits at end of line.
*/
if( (x & 7) != 0 )
bits = VIPS_BUFIS_GETC( ppm->bufis );
bits = VIPS_SBUF_GETC( ppm->sbuf );
}
return( 0 );
@ -523,7 +523,7 @@ vips_foreign_load_ppm_generate_ascii_int( VipsRegion *or,
for( i = 0; i < n_elements; i++ ) {
int val;
if( get_int( ppm->bufis, &val ) )
if( get_int( ppm->sbuf, &val ) )
return( -1 );
switch( image->BandFmt ) {
@ -581,7 +581,7 @@ vips_foreign_load_ppm_load( VipsForeignLoad *load )
/* The binary loader does not use the buffered IO
* object.
*/
vips_bufis_unbuffer( ppm->bufis );
vips_sbuf_unbuffer( ppm->sbuf );
}
else if( !ppm->ascii && ppm->bits == 1 )
generate = vips_foreign_load_ppm_generate_1bit_binary;
@ -674,7 +674,7 @@ vips_foreign_load_ppm_file_build( VipsObject *object )
if( !(ppm->source =
vips_source_new_from_file( file->filename )) )
return( -1 );
ppm->bufis = vips_bufis_new_from_source( ppm->source );
ppm->sbuf = vips_sbuf_new_from_source( ppm->source );
}
if( VIPS_OBJECT_CLASS( vips_foreign_load_ppm_file_parent_class )->

View File

@ -500,7 +500,7 @@ formatval( /* get format value (return true if format) */
static int
getheader( /* get header from file */
VipsBufis *bufis,
VipsSbuf *sbuf,
gethfunc *f,
void *p
)
@ -508,7 +508,7 @@ getheader( /* get header from file */
for(;;) {
const char *line;
if( !(line = vips_bufis_get_line( bufis )) )
if( !(line = vips_sbuf_get_line( sbuf )) )
return( -1 );
if( strcmp( line, "" ) == 0 )
/* Blank line. We've parsed the header successfully.
@ -526,20 +526,20 @@ getheader( /* get header from file */
/* Read a single scanline, encoded in the old style.
*/
static int
scanline_read_old( VipsBufis *bufis, COLR *scanline, int width )
scanline_read_old( VipsSbuf *sbuf, COLR *scanline, int width )
{
int rshift;
rshift = 0;
while( width > 0 ) {
if( VIPS_BUFIS_REQUIRE( bufis, 4 ) )
if( VIPS_SBUF_REQUIRE( sbuf, 4 ) )
return( -1 );
scanline[0][RED] = VIPS_BUFIS_FETCH( bufis );
scanline[0][GRN] = VIPS_BUFIS_FETCH( bufis );
scanline[0][BLU] = VIPS_BUFIS_FETCH( bufis );
scanline[0][EXP] = VIPS_BUFIS_FETCH( bufis );
scanline[0][RED] = VIPS_SBUF_FETCH( sbuf );
scanline[0][GRN] = VIPS_SBUF_FETCH( sbuf );
scanline[0][BLU] = VIPS_SBUF_FETCH( sbuf );
scanline[0][EXP] = VIPS_SBUF_FETCH( sbuf );
if( scanline[0][RED] == 1 &&
scanline[0][GRN] == 1 &&
@ -568,7 +568,7 @@ scanline_read_old( VipsBufis *bufis, COLR *scanline, int width )
/* Read a single encoded scanline.
*/
static int
scanline_read( VipsBufis *bufis, COLR *scanline, int width )
scanline_read( VipsSbuf *sbuf, COLR *scanline, int width )
{
int i, j;
@ -576,21 +576,21 @@ scanline_read( VipsBufis *bufis, COLR *scanline, int width )
*/
if( width < MINELEN ||
width > MAXELEN )
return( scanline_read_old( bufis, scanline, width ) );
return( scanline_read_old( sbuf, scanline, width ) );
if( VIPS_BUFIS_REQUIRE( bufis, 4 ) )
if( VIPS_SBUF_REQUIRE( sbuf, 4 ) )
return( -1 );
if( VIPS_BUFIS_PEEK( bufis )[0] != 2 )
return( scanline_read_old( bufis, scanline, width ) );
if( VIPS_SBUF_PEEK( sbuf )[0] != 2 )
return( scanline_read_old( sbuf, scanline, width ) );
scanline[0][RED] = VIPS_BUFIS_FETCH( bufis );
scanline[0][GRN] = VIPS_BUFIS_FETCH( bufis );
scanline[0][BLU] = VIPS_BUFIS_FETCH( bufis );
scanline[0][EXP] = VIPS_BUFIS_FETCH( bufis );
scanline[0][RED] = VIPS_SBUF_FETCH( sbuf );
scanline[0][GRN] = VIPS_SBUF_FETCH( sbuf );
scanline[0][BLU] = VIPS_SBUF_FETCH( sbuf );
scanline[0][EXP] = VIPS_SBUF_FETCH( sbuf );
if( scanline[0][GRN] != 2 ||
scanline[0][BLU] & 128 )
return( scanline_read_old( bufis,
return( scanline_read_old( sbuf,
scanline + 1, width - 1 ) );
if( ((scanline[0][BLU] << 8) | scanline[0][EXP]) != width ) {
@ -603,10 +603,10 @@ scanline_read( VipsBufis *bufis, COLR *scanline, int width )
int code, len;
gboolean run;
if( VIPS_BUFIS_REQUIRE( bufis, 2 ) )
if( VIPS_SBUF_REQUIRE( sbuf, 2 ) )
return( -1 );
code = VIPS_BUFIS_FETCH( bufis );
code = VIPS_SBUF_FETCH( sbuf );
run = code > 128;
len = run ? code & 127 : code;
@ -618,16 +618,16 @@ scanline_read( VipsBufis *bufis, COLR *scanline, int width )
if( run ) {
int val;
val = VIPS_BUFIS_FETCH( bufis );
val = VIPS_SBUF_FETCH( sbuf );
while( len-- )
scanline[j++][i] = val;
}
else {
if( VIPS_BUFIS_REQUIRE( bufis, len ) )
if( VIPS_SBUF_REQUIRE( sbuf, len ) )
return( -1 );
while( len-- )
scanline[j++][i] =
VIPS_BUFIS_FETCH( bufis );
VIPS_SBUF_FETCH( sbuf );
}
}
@ -710,7 +710,7 @@ rle_scanline_write( COLR *scanline, int width,
/* What we track during radiance file read.
*/
typedef struct {
VipsBufis *bufis;
VipsSbuf *sbuf;
VipsImage *out;
char format[256];
@ -724,16 +724,16 @@ typedef struct {
int
vips__rad_israd( VipsSource *source )
{
VipsBufis *bufis;
VipsSbuf *sbuf;
const char *line;
int result;
/* Just test that the first line is the magic string.
*/
bufis = vips_bufis_new_from_source( source );
result = (line = vips_bufis_get_line( bufis )) &&
sbuf = vips_sbuf_new_from_source( source );
result = (line = vips_sbuf_get_line( sbuf )) &&
strcmp( line, "#?RADIANCE" ) == 0;
VIPS_UNREF( bufis );
VIPS_UNREF( sbuf );
return( result );
}
@ -741,14 +741,14 @@ vips__rad_israd( VipsSource *source )
static void
read_destroy( VipsObject *object, Read *read )
{
VIPS_UNREF( read->bufis );
VIPS_UNREF( read->sbuf );
}
static void
read_minimise_cb( VipsObject *object, Read *read )
{
if( read->bufis )
vips_source_minimise( read->bufis->source );
if( read->sbuf )
vips_source_minimise( read->sbuf->source );
}
static Read *
@ -763,7 +763,7 @@ read_new( VipsSource *source, VipsImage *out )
if( !(read = VIPS_NEW( out, Read )) )
return( NULL );
read->bufis = vips_bufis_new_from_source( source );
read->sbuf = vips_sbuf_new_from_source( source );
read->out = out;
strcpy( read->format, COLRFMT );
read->expos = 1.0;
@ -837,9 +837,9 @@ rad2vips_get_header( Read *read, VipsImage *out )
int height;
int i, j;
if( getheader( read->bufis,
if( getheader( read->sbuf,
(gethfunc *) rad2vips_process_line, read ) ||
!(line = vips_bufis_get_line( read->bufis )) ||
!(line = vips_sbuf_get_line( read->sbuf )) ||
!str2resolu( &read->rs, (char *) line ) ) {
vips_error( "rad2vips", "%s",
_( "error reading radiance header" ) );
@ -870,7 +870,7 @@ rad2vips_get_header( Read *read, VipsImage *out )
VIPS_SETSTR( out->filename,
vips_connection_filename(
VIPS_CONNECTION( read->bufis->source ) ) );
VIPS_CONNECTION( read->sbuf->source ) ) );
vips_image_pipelinev( out, VIPS_DEMAND_STYLE_THINSTRIP, NULL );
@ -926,7 +926,7 @@ rad2vips_generate( VipsRegion *or,
COLR *buf = (COLR *)
VIPS_REGION_ADDR( or, 0, r->top + y );
if( scanline_read( read->bufis, buf, or->im->Xsize ) ) {
if( scanline_read( read->sbuf, buf, or->im->Xsize ) ) {
vips_error( "rad2vips",
_( "read error line %d" ), r->top + y );
VIPS_GATE_STOP( "rad2vips_generate: work" );

View File

@ -30,29 +30,29 @@
*/
#ifndef VIPS_BUFIS_H
#define VIPS_BUFIS_H
#ifndef VIPS_SBUF_H
#define VIPS_SBUF_H
#ifdef __cplusplus
extern "C" {
#endif /*__cplusplus*/
#define VIPS_TYPE_BUFIS (vips_bufis_get_type())
#define VIPS_BUFIS( obj ) \
#define VIPS_TYPE_SBUF (vips_sbuf_get_type())
#define VIPS_SBUF( obj ) \
(G_TYPE_CHECK_INSTANCE_CAST( (obj), \
VIPS_TYPE_BUFIS, VipsBufis ))
#define VIPS_BUFIS_CLASS( klass ) \
VIPS_TYPE_SBUF, VipsSbuf ))
#define VIPS_SBUF_CLASS( klass ) \
(G_TYPE_CHECK_CLASS_CAST( (klass), \
VIPS_TYPE_BUFIS, VipsBufisClass))
#define VIPS_IS_BUFIS( obj ) \
(G_TYPE_CHECK_INSTANCE_TYPE( (obj), VIPS_TYPE_BUFIS ))
#define VIPS_IS_BUFIS_CLASS( klass ) \
(G_TYPE_CHECK_CLASS_TYPE( (klass), VIPS_TYPE_BUFIS ))
#define VIPS_BUFIS_GET_CLASS( obj ) \
VIPS_TYPE_SBUF, VipsSbufClass))
#define VIPS_IS_SBUF( obj ) \
(G_TYPE_CHECK_INSTANCE_TYPE( (obj), VIPS_TYPE_SBUF ))
#define VIPS_IS_SBUF_CLASS( klass ) \
(G_TYPE_CHECK_CLASS_TYPE( (klass), VIPS_TYPE_SBUF ))
#define VIPS_SBUF_GET_CLASS( obj ) \
(G_TYPE_INSTANCE_GET_CLASS( (obj), \
VIPS_TYPE_BUFIS, VipsBufisClass ))
VIPS_TYPE_SBUF, VipsSbufClass ))
#define VIPS_BUFIS_BUFFER_SIZE (4096)
#define VIPS_SBUF_BUFFER_SIZE (4096)
/* Layer over source: read with an input buffer.
*
@ -60,7 +60,7 @@ extern "C" {
* others, like radiance, need to parse the input into lines. A buffered read
* class is very convenient.
*/
typedef struct _VipsBufis {
typedef struct _VipsSbuf {
VipsObject parent_object;
/*< private >*/
@ -76,55 +76,55 @@ typedef struct _VipsBufis {
* chars_in_buffer is how many chars we have in input_buffer,
* read_point is the current read position in that buffer.
*/
unsigned char input_buffer[VIPS_BUFIS_BUFFER_SIZE + 1];
unsigned char input_buffer[VIPS_SBUF_BUFFER_SIZE + 1];
int chars_in_buffer;
int read_point;
/* Build lines of text here.
*/
unsigned char line[VIPS_BUFIS_BUFFER_SIZE + 1];
unsigned char line[VIPS_SBUF_BUFFER_SIZE + 1];
} VipsBufis;
} VipsSbuf;
typedef struct _VipsBufisClass {
typedef struct _VipsSbufClass {
VipsObjectClass parent_class;
} VipsBufisClass;
} VipsSbufClass;
GType vips_bufis_get_type( void );
GType vips_sbuf_get_type( void );
VipsBufis *vips_bufis_new_from_source( VipsSource *source );
VipsSbuf *vips_sbuf_new_from_source( VipsSource *source );
void vips_bufis_unbuffer( VipsBufis *sourceb );
void vips_sbuf_unbuffer( VipsSbuf *sbuf );
int vips_bufis_getc( VipsBufis *sourceb );
#define VIPS_BUFIS_GETC( S ) ( \
int vips_sbuf_getc( VipsSbuf *sbuf );
#define VIPS_SBUF_GETC( S ) ( \
(S)->read_point < (S)->chars_in_buffer ? \
(S)->input_buffer[(S)->read_point++] : \
vips_bufis_getc( S ) \
vips_sbuf_getc( S ) \
)
void vips_bufis_ungetc( VipsBufis *sourceb );
#define VIPS_BUFIS_UNGETC( S ) { \
void vips_sbuf_ungetc( VipsSbuf *sbuf );
#define VIPS_SBUF_UNGETC( S ) { \
if( (S)->read_point > 0 ) \
(S)->read_point -= 1; \
}
int vips_bufis_require( VipsBufis *sourceb, int require );
#define VIPS_BUFIS_REQUIRE( S, R ) ( \
int vips_sbuf_require( VipsSbuf *sbuf, int require );
#define VIPS_SBUF_REQUIRE( S, R ) ( \
(S)->read_point + (R) <= (S)->chars_in_buffer ? \
0 : \
vips_bufis_require( (S), (R) ) \
vips_sbuf_require( (S), (R) ) \
)
#define VIPS_BUFIS_PEEK( S ) ((S)->input_buffer + (S)->read_point)
#define VIPS_BUFIS_FETCH( S ) ((S)->input_buffer[(S)->read_point++])
#define VIPS_SBUF_PEEK( S ) ((S)->input_buffer + (S)->read_point)
#define VIPS_SBUF_FETCH( S ) ((S)->input_buffer[(S)->read_point++])
const char *vips_bufis_get_line( VipsBufis *sourceb );
char *vips_bufis_get_line_copy( VipsBufis *sourceb );
const char *vips_bufis_get_non_whitespace( VipsBufis *sourceb );
int vips_bufis_skip_whitespace( VipsBufis *sourceb );
const char *vips_sbuf_get_line( VipsSbuf *sbuf );
char *vips_sbuf_get_line_copy( VipsSbuf *sbuf );
const char *vips_sbuf_get_non_whitespace( VipsSbuf *sbuf );
int vips_sbuf_skip_whitespace( VipsSbuf *sbuf );
#ifdef __cplusplus
}
#endif /*__cplusplus*/
#endif /*VIPS_BUFIS_H*/
#endif /*VIPS_SBUF_H*/

View File

@ -6,7 +6,7 @@ libiofuncs_la_SOURCES = \
sourcecustom.c \
target.c \
targetcustom.c \
bufis.c \
sbuf.c \
dbuf.c \
reorder.c \
vipsmarshal.h \

View File

@ -56,10 +56,25 @@
#include <vips/internal.h>
#include <vips/debug.h>
G_DEFINE_TYPE( VipsBufis, vips_bufis, VIPS_TYPE_OBJECT );
/**
* SECTION: sbuf
* @short_description: buffered read from a source
* @stability: Stable
* @see_also: <link linkend="libvips-foreign">foreign</link>
* @include: vips/vips.h
* @title: VipsSbuf
*
* #VipsSbuf wraps up a #VipsSource and provides a set of calls for
* text-oriented buffered reading. You can fetch lines of text, skip
* whitespace, and so on.
*
* It is useful for implementing things like CSV readers, for example.
*/
G_DEFINE_TYPE( VipsSbuf, vips_sbuf, VIPS_TYPE_OBJECT );
static void
vips_bufis_class_init( VipsBufisClass *class )
vips_sbuf_class_init( VipsSbufClass *class )
{
VipsObjectClass *object_class = VIPS_OBJECT_CLASS( class );
GObjectClass *gobject_class = G_OBJECT_CLASS( class );
@ -67,160 +82,160 @@ vips_bufis_class_init( VipsBufisClass *class )
gobject_class->set_property = vips_object_set_property;
gobject_class->get_property = vips_object_get_property;
object_class->nickname = "bufis";
object_class->nickname = "sbuf";
object_class->description = _( "buffered source" );
VIPS_ARG_OBJECT( class, "input", 1,
_( "Input" ),
_( "Source to load from" ),
VIPS_ARGUMENT_REQUIRED_INPUT,
G_STRUCT_OFFSET( VipsBufis, source ),
G_STRUCT_OFFSET( VipsSbuf, source ),
VIPS_TYPE_SOURCE );
}
static void
vips_bufis_init( VipsBufis *bufis )
vips_sbuf_init( VipsSbuf *sbuf )
{
bufis->read_point = 0;
bufis->chars_in_buffer = 0;
bufis->input_buffer[0] = '\0';
sbuf->read_point = 0;
sbuf->chars_in_buffer = 0;
sbuf->input_buffer[0] = '\0';
}
/**
* vips_bufis_new_from_source:
* vips_sbuf_new_from_source:
* @source: source to operate on
*
* Create a bufis wrapping a source.
* Create a VipsSbuf wrapping a source.
*
* Returns: a new #VipsBufis
* Returns: a new #VipsSbuf
*/
VipsBufis *
vips_bufis_new_from_source( VipsSource *source )
VipsSbuf *
vips_sbuf_new_from_source( VipsSource *source )
{
VipsBufis *bufis;
VipsSbuf *sbuf;
bufis = VIPS_BUFIS( g_object_new( VIPS_TYPE_BUFIS,
sbuf = VIPS_SBUF( g_object_new( VIPS_TYPE_SBUF,
"input", source,
NULL ) );
if( vips_object_build( VIPS_OBJECT( bufis ) ) ) {
VIPS_UNREF( bufis );
if( vips_object_build( VIPS_OBJECT( sbuf ) ) ) {
VIPS_UNREF( sbuf );
return( NULL );
}
return( bufis );
return( sbuf );
}
/**
* vips_bufis_unbuffer:
* @bufis: source to operate on
* vips_sbuf_unbuffer:
* @sbuf: source to operate on
*
* Discard the input buffer and reset the read point. You must call this
* before using read or seek on the underlying #VipsSource class.
*/
void
vips_bufis_unbuffer( VipsBufis *bufis )
vips_sbuf_unbuffer( VipsSbuf *sbuf )
{
/* We'd read ahead a little way -- seek backwards by that amount.
*/
vips_source_seek( bufis->source,
bufis->read_point - bufis->chars_in_buffer, SEEK_CUR );
bufis->read_point = 0;
bufis->chars_in_buffer = 0;
vips_source_seek( sbuf->source,
sbuf->read_point - sbuf->chars_in_buffer, SEEK_CUR );
sbuf->read_point = 0;
sbuf->chars_in_buffer = 0;
}
/* Returns -1 on error, 0 on EOF, otherwise bytes read.
*/
static gint64
vips_bufis_refill( VipsBufis *bufis )
vips_sbuf_refill( VipsSbuf *sbuf )
{
gint64 bytes_read;
VIPS_DEBUG_MSG( "vips_bufis_refill:\n" );
VIPS_DEBUG_MSG( "vips_sbuf_refill:\n" );
/* We should not discard any unread bytes.
*/
g_assert( bufis->read_point == bufis->chars_in_buffer );
g_assert( sbuf->read_point == sbuf->chars_in_buffer );
bytes_read = vips_source_read( bufis->source,
bufis->input_buffer, VIPS_BUFIS_BUFFER_SIZE );
bytes_read = vips_source_read( sbuf->source,
sbuf->input_buffer, VIPS_SBUF_BUFFER_SIZE );
if( bytes_read == -1 )
return( -1 );
bufis->read_point = 0;
bufis->chars_in_buffer = bytes_read;
sbuf->read_point = 0;
sbuf->chars_in_buffer = bytes_read;
/* Always add a null byte so we can use strchr() etc. on lines. This is
* safe because input_buffer is VIPS_BUFIS_BUFFER_SIZE + 1 bytes.
* safe because input_buffer is VIPS_SBUF_BUFFER_SIZE + 1 bytes.
*/
bufis->input_buffer[bytes_read] = '\0';
sbuf->input_buffer[bytes_read] = '\0';
return( bytes_read );
}
/**
* vips_bufis_getc:
* @bufis: source to operate on
* vips_sbuf_getc:
* @sbuf: source to operate on
*
* Fetch the next character from the source.
*
* If you can, use the macro VIPS_BUFIS_GETC() instead for speed.
* If you can, use the macro VIPS_SBUF_GETC() instead for speed.
*
* Returns: the next char from @bufis, -1 on read error or EOF.
* Returns: the next char from @sbuf, -1 on read error or EOF.
*/
int
vips_bufis_getc( VipsBufis *bufis )
vips_sbuf_getc( VipsSbuf *sbuf )
{
if( bufis->read_point == bufis->chars_in_buffer &&
vips_bufis_refill( bufis ) <= 0 )
if( sbuf->read_point == sbuf->chars_in_buffer &&
vips_sbuf_refill( sbuf ) <= 0 )
return( -1 );
g_assert( bufis->read_point < bufis->chars_in_buffer );
g_assert( sbuf->read_point < sbuf->chars_in_buffer );
return( bufis->input_buffer[bufis->read_point++] );
return( sbuf->input_buffer[sbuf->read_point++] );
}
/**
* VIPS_BUFIS_GETC:
* @bufis: source to operate on
* VIPS_SBUF_GETC:
* @sbuf: source to operate on
*
* Fetch the next character from the source.
*
* Returns: the next char from @bufis, -1 on read error or EOF.
* Returns: the next char from @sbuf, -1 on read error or EOF.
*/
/**
* vips_bufis_ungetc:
* @bufis: source to operate on
* vips_sbuf_ungetc:
* @sbuf: source to operate on
*
* The opposite of vips_bufis_getc(): undo the previous getc.
* The opposite of vips_sbuf_getc(): undo the previous getc.
*
* unget more than one character is undefined. Unget at the start of the file
* does nothing.
*
* If you can, use the macro VIPS_BUFIS_UNGETC() instead for speed.
* If you can, use the macro VIPS_SBUF_UNGETC() instead for speed.
*/
void
vips_bufis_ungetc( VipsBufis *bufis )
vips_sbuf_ungetc( VipsSbuf *sbuf )
{
if( bufis->read_point > 0 )
bufis->read_point -= 1;
if( sbuf->read_point > 0 )
sbuf->read_point -= 1;
}
/**
* VIPS_BUFIS_UNGETC:
* @bufis: source to operate on
* VIPS_SBUF_UNGETC:
* @sbuf: source to operate on
*
* The opposite of vips_bufis_getc(): undo the previous getc.
* The opposite of vips_sbuf_getc(): undo the previous getc.
*
* unget more than one character is undefined. Unget at the start of the file
* does nothing.
*/
/**
* vips_bufis_require:
* @bufis: source to operate on
* vips_sbuf_require:
* @sbuf: source to operate on
* @require: make sure we have at least this many chars available
*
* Make sure there are at least @require bytes of readahead available.
@ -228,46 +243,46 @@ vips_bufis_ungetc( VipsBufis *bufis )
* Returns: 0 on success, -1 on error or EOF.
*/
int
vips_bufis_require( VipsBufis *bufis, int require )
vips_sbuf_require( VipsSbuf *sbuf, int require )
{
g_assert( require < VIPS_BUFIS_BUFFER_SIZE );
g_assert( bufis->chars_in_buffer >= 0 );
g_assert( bufis->chars_in_buffer <= VIPS_BUFIS_BUFFER_SIZE );
g_assert( bufis->read_point >= 0 );
g_assert( bufis->read_point <= bufis->chars_in_buffer );
g_assert( require < VIPS_SBUF_BUFFER_SIZE );
g_assert( sbuf->chars_in_buffer >= 0 );
g_assert( sbuf->chars_in_buffer <= VIPS_SBUF_BUFFER_SIZE );
g_assert( sbuf->read_point >= 0 );
g_assert( sbuf->read_point <= sbuf->chars_in_buffer );
VIPS_DEBUG_MSG( "vips_bufis_require: %d\n", require );
VIPS_DEBUG_MSG( "vips_sbuf_require: %d\n", require );
if( bufis->read_point + require > bufis->chars_in_buffer ) {
if( sbuf->read_point + require > sbuf->chars_in_buffer ) {
/* Areas can overlap, so we must memmove().
*/
memmove( bufis->input_buffer,
bufis->input_buffer + bufis->read_point,
bufis->chars_in_buffer - bufis->read_point );
bufis->chars_in_buffer -= bufis->read_point;
bufis->read_point = 0;
memmove( sbuf->input_buffer,
sbuf->input_buffer + sbuf->read_point,
sbuf->chars_in_buffer - sbuf->read_point );
sbuf->chars_in_buffer -= sbuf->read_point;
sbuf->read_point = 0;
while( require > bufis->chars_in_buffer ) {
unsigned char *to = bufis->input_buffer +
bufis->chars_in_buffer;
while( require > sbuf->chars_in_buffer ) {
unsigned char *to = sbuf->input_buffer +
sbuf->chars_in_buffer;
int space_available =
VIPS_BUFIS_BUFFER_SIZE -
bufis->chars_in_buffer;
VIPS_SBUF_BUFFER_SIZE -
sbuf->chars_in_buffer;
size_t bytes_read;
if( (bytes_read = vips_source_read( bufis->source,
if( (bytes_read = vips_source_read( sbuf->source,
to, space_available )) == -1 )
return( -1 );
if( bytes_read == 0 ) {
vips_error(
vips_connection_nick( VIPS_CONNECTION(
bufis->source ) ),
sbuf->source ) ),
"%s", _( "end of file" ) );
return( -1 );
}
to[bytes_read] = '\0';
bufis->chars_in_buffer += bytes_read;
sbuf->chars_in_buffer += bytes_read;
}
}
@ -275,41 +290,41 @@ vips_bufis_require( VipsBufis *bufis, int require )
}
/**
* VIPS_BUFIS_REQUIRE:
* @bufis: source to operate on
* VIPS_SBUF_REQUIRE:
* @sbuf: source to operate on
* @require: need this many characters
*
* Make sure at least @require characters are available for
* VIPS_BUFIS_PEEK() and VIPS_BUFIS_FETCH().
* VIPS_SBUF_PEEK() and VIPS_SBUF_FETCH().
*
* Returns: 0 on success, -1 on read error or EOF.
*/
/**
* VIPS_BUFIS_PEEK:
* @bufis: source to operate on
* VIPS_SBUF_PEEK:
* @sbuf: source to operate on
*
* After a successful VIPS_BUFIS_REQUIRE(), you can index this to get
* After a successful VIPS_SBUF_REQUIRE(), you can index this to get
* require characters of input.
*
* Returns: a pointer to the next requre characters of input.
*/
/**
* VIPS_BUFIS_FETCH:
* @bufis: source to operate on
* VIPS_SBUF_FETCH:
* @sbuf: source to operate on
*
* After a successful VIPS_BUFIS_REQUIRE(), you can use this require times
* After a successful VIPS_SBUF_REQUIRE(), you can use this require times
* to fetch characters of input.
*
* Returns: the next input character.
*/
/**
* vips_bufis_get_line:
* @bufis: source to operate on
* vips_sbuf_get_line:
* @sbuf: source to operate on
*
* Fetch the next line of text from @bufis and return it. The end of
* Fetch the next line of text from @sbuf and return it. The end of
* line character (or characters, for DOS files) are removed, and the string
* is terminated with a null (`\0` character).
*
@ -317,33 +332,33 @@ vips_bufis_require( VipsBufis *bufis, int require )
*
* If the line is longer than some arbitrary (but large) limit, it is
* truncated. If you need to be able to read very long lines, use the
* slower vips_bufis_get_line_copy().
* slower vips_sbuf_get_line_copy().
*
* The return value is owned by @bufis and must not be freed. It
* is valid until the next get call to @bufis.
* The return value is owned by @sbuf and must not be freed. It
* is valid until the next get call to @sbuf.
*
* Returns: the next line of text, or NULL on EOF or read error.
*/
const char *
vips_bufis_get_line( VipsBufis *bufis )
vips_sbuf_get_line( VipsSbuf *sbuf )
{
int write_point;
int space_remaining;
int ch;
VIPS_DEBUG_MSG( "vips_bufis_get_line:\n" );
VIPS_DEBUG_MSG( "vips_sbuf_get_line:\n" );
write_point = 0;
space_remaining = VIPS_BUFIS_BUFFER_SIZE;
space_remaining = VIPS_SBUF_BUFFER_SIZE;
while( (ch = VIPS_BUFIS_GETC( bufis )) != -1 &&
while( (ch = VIPS_SBUF_GETC( sbuf )) != -1 &&
ch != '\n' &&
space_remaining > 0 ) {
bufis->line[write_point] = ch;
sbuf->line[write_point] = ch;
write_point += 1;
space_remaining -= 1;
}
bufis->line[write_point] = '\0';
sbuf->line[write_point] = '\0';
/* If we hit EOF immediately, return EOF.
*/
@ -358,45 +373,45 @@ vips_bufis_get_line( VipsBufis *bufis )
* lines, but ignore this.
*/
if( write_point > 0 &&
bufis->line[write_point - 1] == '\r' )
bufis->line[write_point - 1] = '\0';
sbuf->line[write_point - 1] == '\r' )
sbuf->line[write_point - 1] = '\0';
/* If we filled the output line without seeing \n, keep going to the
* next \n.
*/
if( ch != '\n' &&
space_remaining == 0 ) {
while( (ch = VIPS_BUFIS_GETC( bufis )) != -1 &&
while( (ch = VIPS_SBUF_GETC( sbuf )) != -1 &&
ch != '\n' )
;
}
VIPS_DEBUG_MSG( " %s\n", bufis->line );
VIPS_DEBUG_MSG( " %s\n", sbuf->line );
return( (const char *) bufis->line );
return( (const char *) sbuf->line );
}
/**
* vips_bufis_get_line_copy:
* @bufis: source to operate on
* vips_sbuf_get_line_copy:
* @sbuf: source to operate on
*
* Fetch the next line of text from @bufis and return it. The end of
* Fetch the next line of text from @sbuf and return it. The end of
* line character (or characters, for DOS files) are removed, and the string
* is terminated with a null (`\0` character).
*
* The return result must be freed with g_free().
*
* This is slower than vips_bufis_get_line(), but can work with lines of
* This is slower than vips_sbuf_get_line(), but can work with lines of
* any length.
*
* Returns: the next line of text, or NULL on EOF or read error.
*/
char *
vips_bufis_get_line_copy( VipsBufis *bufis )
vips_sbuf_get_line_copy( VipsSbuf *sbuf )
{
static const unsigned char null = '\0';
VIPS_DEBUG_MSG( "vips_bufis_get_line_copy:\n" );
VIPS_DEBUG_MSG( "vips_sbuf_get_line_copy:\n" );
GByteArray *buffer;
int ch;
@ -404,7 +419,7 @@ vips_bufis_get_line_copy( VipsBufis *bufis )
buffer = g_byte_array_new();
while( (ch = VIPS_BUFIS_GETC( bufis )) != -1 &&
while( (ch = VIPS_SBUF_GETC( sbuf )) != -1 &&
ch != '\n' ) {
unsigned char c = ch;
@ -437,8 +452,8 @@ vips_bufis_get_line_copy( VipsBufis *bufis )
}
/**
* vips_bufis_get_non_whitespace:
* @bufis: source to operate on
* vips_sbuf_get_non_whitespace:
* @sbuf: source to operate on
*
* Fetch the next chunk of non-whitespace text from the source, and
* null-terminate it.
@ -452,28 +467,28 @@ vips_bufis_get_line_copy( VipsBufis *bufis )
* If the item is longer than some arbitrary (but large) limit, it is
* truncated.
*
* The return value is owned by @bufis and must not be freed. It
* is valid until the next get call to @bufis.
* The return value is owned by @sbuf and must not be freed. It
* is valid until the next get call to @sbuf.
*
* Returns: the next block of non-whitespace, or NULL on EOF or read error.
*/
const char *
vips_bufis_get_non_whitespace( VipsBufis *bufis )
vips_sbuf_get_non_whitespace( VipsSbuf *sbuf )
{
int ch;
int i;
for( i = 0; i < VIPS_BUFIS_BUFFER_SIZE &&
!isspace( ch = VIPS_BUFIS_GETC( bufis ) ) &&
for( i = 0; i < VIPS_SBUF_BUFFER_SIZE &&
!isspace( ch = VIPS_SBUF_GETC( sbuf ) ) &&
ch != EOF; i++ )
bufis->line[i] = ch;
bufis->line[i] = '\0';
sbuf->line[i] = ch;
sbuf->line[i] = '\0';
/* If we stopped before seeing any whitespace, skip to the end of the
* block of non-whitespace.
*/
if( !isspace( ch ) )
while( !isspace( ch = VIPS_BUFIS_GETC( bufis ) ) &&
while( !isspace( ch = VIPS_SBUF_GETC( sbuf ) ) &&
ch != EOF )
;
@ -481,14 +496,14 @@ vips_bufis_get_non_whitespace( VipsBufis *bufis )
* will be whitespace (or EOF).
*/
if( isspace( ch ) )
VIPS_BUFIS_UNGETC( bufis );
VIPS_SBUF_UNGETC( sbuf );
return( (const char *) bufis->line );
return( (const char *) sbuf->line );
}
/**
* vips_bufis_skip_whitespace:
* @bufis: source to operate on
* vips_sbuf_skip_whitespace:
* @sbuf: source to operate on
*
* After this, the next getc will be the first char of the next block of
* non-whitespace (or EOF).
@ -498,25 +513,25 @@ vips_bufis_get_non_whitespace( VipsBufis *bufis )
* Returns: 0 on success, or -1 on EOF.
*/
int
vips_bufis_skip_whitespace( VipsBufis *bufis )
vips_sbuf_skip_whitespace( VipsSbuf *sbuf )
{
int ch;
do {
ch = VIPS_BUFIS_GETC( bufis );
ch = VIPS_SBUF_GETC( sbuf );
/* # skip comments too.
*/
if( ch == '#' ) {
/* Probably EOF.
*/
if( !vips_bufis_get_line( bufis ) )
if( !vips_sbuf_get_line( sbuf ) )
return( -1 );
ch = VIPS_BUFIS_GETC( bufis );
ch = VIPS_SBUF_GETC( sbuf );
}
} while( isspace( ch ) );
VIPS_BUFIS_UNGETC( bufis );
VIPS_SBUF_UNGETC( sbuf );
return( 0 );
}