rename VipsStreamib as VipsBufis
The VipsStreamib (stream input buffered) was misleading -- it was implemented on top of VipsStreami, but was not a subclass. Rename as VipsBufis (buffered input stream). It's a silly name, but easy to remember and reflects the purpose better,
This commit is contained in:
parent
6b5035c160
commit
09325600ee
@ -147,7 +147,6 @@ extern const char *vips__ppm_suffs[];
|
||||
|
||||
int vips__ppm_save_stream( VipsImage *in, VipsStreamo *streamo,
|
||||
gboolean ascii, gboolean squash );
|
||||
|
||||
int vips__rad_israd( VipsStreami *streami );
|
||||
int vips__rad_header( VipsStreami *streami, VipsImage *out );
|
||||
int vips__rad_load( VipsStreami *streami, VipsImage *out );
|
||||
|
@ -88,10 +88,10 @@
|
||||
typedef struct _VipsForeignLoadPpm {
|
||||
VipsForeignLoad parent_object;
|
||||
|
||||
/* The stream we load from, and the buffered wrapper.
|
||||
/* The stream we load from, and the buffered wrapper for it.
|
||||
*/
|
||||
VipsStreami *streami;
|
||||
VipsStreamib *streamib;
|
||||
VipsBufis *bufis;
|
||||
|
||||
/* Properties of this ppm, from the header.
|
||||
*/
|
||||
@ -103,7 +103,7 @@ typedef struct _VipsForeignLoadPpm {
|
||||
float scale;
|
||||
int max_value;
|
||||
int index; /* ppm type .. index in magic_names[] */
|
||||
int bits; /* 1, 8 or 32 */
|
||||
int bits; /* 1, 8, 16 or 32 */
|
||||
gboolean ascii; /* TRUE for ascii encoding */
|
||||
gboolean msb_first; /* TRUE if most sig byte is first */
|
||||
|
||||
@ -150,12 +150,12 @@ vips_foreign_load_ppm_is_a_stream( VipsStreami *streami )
|
||||
}
|
||||
|
||||
static int
|
||||
get_int( VipsStreamib *streamib, int *i )
|
||||
get_int( VipsBufis *bufis, int *i )
|
||||
{
|
||||
const char *txt;
|
||||
|
||||
if( vips_streamib_skip_whitespace( streamib ) ||
|
||||
!(txt = vips_streamib_get_non_whitespace( streamib )) )
|
||||
if( vips_bufis_skip_whitespace( bufis ) ||
|
||||
!(txt = vips_bufis_get_non_whitespace( bufis )) )
|
||||
return( -1 );
|
||||
|
||||
*i = atoi( txt );
|
||||
@ -164,12 +164,12 @@ get_int( VipsStreamib *streamib, int *i )
|
||||
}
|
||||
|
||||
static int
|
||||
get_float( VipsStreamib *streamib, float *f )
|
||||
get_float( VipsBufis *bufis, float *f )
|
||||
{
|
||||
const char *txt;
|
||||
|
||||
if( vips_streamib_skip_whitespace( streamib ) ||
|
||||
!(txt = vips_streamib_get_non_whitespace( streamib )) )
|
||||
if( vips_bufis_skip_whitespace( bufis ) ||
|
||||
!(txt = vips_bufis_get_non_whitespace( bufis )) )
|
||||
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->streamib );
|
||||
VIPS_UNREF( ppm->bufis );
|
||||
VIPS_UNREF( ppm->streami );
|
||||
|
||||
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_STREAMIB_GETC( ppm->streamib );
|
||||
buf[1] = VIPS_STREAMIB_GETC( ppm->streamib );
|
||||
buf[0] = VIPS_BUFIS_GETC( ppm->bufis );
|
||||
buf[1] = VIPS_BUFIS_GETC( ppm->bufis );
|
||||
|
||||
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->streamib, &ppm->width ) ||
|
||||
get_int( ppm->streamib, &ppm->height ) )
|
||||
if( get_int( ppm->bufis, &ppm->width ) ||
|
||||
get_int( ppm->bufis, &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->streamib, &ppm->scale ) )
|
||||
if( get_float( ppm->bufis, &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->streamib, &ppm->max_value ) )
|
||||
if( get_int( ppm->bufis, &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_STREAMIB_GETC( ppm->streamib ) ) ) {
|
||||
!isspace( VIPS_BUFIS_GETC( ppm->bufis ) ) ) {
|
||||
vips_error( class->nickname, "%s",
|
||||
_( "no whitespace before start of binary data" ) );
|
||||
return( -1 );
|
||||
@ -368,7 +368,7 @@ vips_foreign_load_ppm_set_image( VipsForeignLoadPpm *ppm, VipsImage *image )
|
||||
"ppm-max-value", VIPS_FABS( ppm->max_value ) );
|
||||
|
||||
VIPS_SETSTR( image->filename,
|
||||
vips_stream_filename( VIPS_STREAM( ppm->streamib->streami ) ) );
|
||||
vips_stream_filename( VIPS_STREAM( ppm->bufis->streami ) ) );
|
||||
}
|
||||
|
||||
static int
|
||||
@ -399,7 +399,7 @@ vips_foreign_load_ppm_map( VipsForeignLoadPpm *ppm, VipsImage *image )
|
||||
size_t length;
|
||||
const void *data;
|
||||
|
||||
vips_streamib_unbuffer( ppm->streamib );
|
||||
vips_bufis_unbuffer( ppm->bufis );
|
||||
header_offset = vips_streami_seek( ppm->streami, 0, SEEK_CUR );
|
||||
data = vips_streami_map( ppm->streami, &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->streamib, &val ) )
|
||||
if( get_int( ppm->bufis, &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_STREAMIB_GETC( ppm->streamib );
|
||||
bits = VIPS_BUFIS_GETC( ppm->bufis );
|
||||
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_STREAMIB_GETC( ppm->streamib );
|
||||
bits = VIPS_BUFIS_GETC( ppm->bufis );
|
||||
}
|
||||
|
||||
/* Skip any unaligned bits at end of line.
|
||||
*/
|
||||
if( (x & 7) != 0 )
|
||||
bits = VIPS_STREAMIB_GETC( ppm->streamib );
|
||||
bits = VIPS_BUFIS_GETC( ppm->bufis );
|
||||
}
|
||||
|
||||
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->streamib, &val ) )
|
||||
if( get_int( ppm->bufis, &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_streamib_unbuffer( ppm->streamib );
|
||||
vips_bufis_unbuffer( ppm->bufis );
|
||||
}
|
||||
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->streami =
|
||||
vips_streami_new_from_filename( file->filename )) )
|
||||
return( -1 );
|
||||
ppm->streamib = vips_streamib_new( ppm->streami );
|
||||
ppm->bufis = vips_bufis_new_from_streami( ppm->streami );
|
||||
}
|
||||
|
||||
if( VIPS_OBJECT_CLASS( vips_foreign_load_ppm_file_parent_class )->
|
||||
|
@ -4,7 +4,6 @@
|
||||
* - wrap a class around the ppm writer
|
||||
* 13/11/19
|
||||
* - redone with streams
|
||||
* - faster plus lower memory use
|
||||
*/
|
||||
|
||||
/*
|
||||
|
@ -500,7 +500,7 @@ formatval( /* get format value (return true if format) */
|
||||
|
||||
static int
|
||||
getheader( /* get header from file */
|
||||
VipsStreamib *streamib,
|
||||
VipsBufis *bufis,
|
||||
gethfunc *f,
|
||||
void *p
|
||||
)
|
||||
@ -508,7 +508,7 @@ getheader( /* get header from file */
|
||||
for(;;) {
|
||||
const char *line;
|
||||
|
||||
if( !(line = vips_streamib_get_line( streamib )) )
|
||||
if( !(line = vips_bufis_get_line( bufis )) )
|
||||
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( VipsStreamib *streamib, COLR *scanline, int width )
|
||||
scanline_read_old( VipsBufis *bufis, COLR *scanline, int width )
|
||||
{
|
||||
int rshift;
|
||||
|
||||
rshift = 0;
|
||||
|
||||
while( width > 0 ) {
|
||||
if( VIPS_STREAMIB_REQUIRE( streamib, 4 ) )
|
||||
if( VIPS_BUFIS_REQUIRE( bufis, 4 ) )
|
||||
return( -1 );
|
||||
|
||||
scanline[0][RED] = VIPS_STREAMIB_FETCH( streamib );
|
||||
scanline[0][GRN] = VIPS_STREAMIB_FETCH( streamib );
|
||||
scanline[0][BLU] = VIPS_STREAMIB_FETCH( streamib );
|
||||
scanline[0][EXP] = VIPS_STREAMIB_FETCH( streamib );
|
||||
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 );
|
||||
|
||||
if( scanline[0][RED] == 1 &&
|
||||
scanline[0][GRN] == 1 &&
|
||||
@ -568,7 +568,7 @@ scanline_read_old( VipsStreamib *streamib, COLR *scanline, int width )
|
||||
/* Read a single encoded scanline.
|
||||
*/
|
||||
static int
|
||||
scanline_read( VipsStreamib *streamib, COLR *scanline, int width )
|
||||
scanline_read( VipsBufis *bufis, COLR *scanline, int width )
|
||||
{
|
||||
int i, j;
|
||||
|
||||
@ -576,21 +576,21 @@ scanline_read( VipsStreamib *streamib, COLR *scanline, int width )
|
||||
*/
|
||||
if( width < MINELEN ||
|
||||
width > MAXELEN )
|
||||
return( scanline_read_old( streamib, scanline, width ) );
|
||||
return( scanline_read_old( bufis, scanline, width ) );
|
||||
|
||||
if( VIPS_STREAMIB_REQUIRE( streamib, 4 ) )
|
||||
if( VIPS_BUFIS_REQUIRE( bufis, 4 ) )
|
||||
return( -1 );
|
||||
|
||||
if( VIPS_STREAMIB_PEEK( streamib )[0] != 2 )
|
||||
return( scanline_read_old( streamib, scanline, width ) );
|
||||
if( VIPS_BUFIS_PEEK( bufis )[0] != 2 )
|
||||
return( scanline_read_old( bufis, scanline, width ) );
|
||||
|
||||
scanline[0][RED] = VIPS_STREAMIB_FETCH( streamib );
|
||||
scanline[0][GRN] = VIPS_STREAMIB_FETCH( streamib );
|
||||
scanline[0][BLU] = VIPS_STREAMIB_FETCH( streamib );
|
||||
scanline[0][EXP] = VIPS_STREAMIB_FETCH( streamib );
|
||||
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 );
|
||||
if( scanline[0][GRN] != 2 ||
|
||||
scanline[0][BLU] & 128 )
|
||||
return( scanline_read_old( streamib,
|
||||
return( scanline_read_old( bufis,
|
||||
scanline + 1, width - 1 ) );
|
||||
|
||||
if( ((scanline[0][BLU] << 8) | scanline[0][EXP]) != width ) {
|
||||
@ -603,10 +603,10 @@ scanline_read( VipsStreamib *streamib, COLR *scanline, int width )
|
||||
int code, len;
|
||||
gboolean run;
|
||||
|
||||
if( VIPS_STREAMIB_REQUIRE( streamib, 2 ) )
|
||||
if( VIPS_BUFIS_REQUIRE( bufis, 2 ) )
|
||||
return( -1 );
|
||||
|
||||
code = VIPS_STREAMIB_FETCH( streamib );
|
||||
code = VIPS_BUFIS_FETCH( bufis );
|
||||
run = code > 128;
|
||||
len = run ? code & 127 : code;
|
||||
|
||||
@ -618,16 +618,16 @@ scanline_read( VipsStreamib *streamib, COLR *scanline, int width )
|
||||
if( run ) {
|
||||
int val;
|
||||
|
||||
val = VIPS_STREAMIB_FETCH( streamib );
|
||||
val = VIPS_BUFIS_FETCH( bufis );
|
||||
while( len-- )
|
||||
scanline[j++][i] = val;
|
||||
}
|
||||
else {
|
||||
if( VIPS_STREAMIB_REQUIRE( streamib, len ) )
|
||||
if( VIPS_BUFIS_REQUIRE( bufis, len ) )
|
||||
return( -1 );
|
||||
while( len-- )
|
||||
scanline[j++][i] =
|
||||
VIPS_STREAMIB_FETCH( streamib );
|
||||
VIPS_BUFIS_FETCH( bufis );
|
||||
}
|
||||
}
|
||||
|
||||
@ -710,7 +710,7 @@ rle_scanline_write( COLR *scanline, int width,
|
||||
/* What we track during radiance file read.
|
||||
*/
|
||||
typedef struct {
|
||||
VipsStreamib *streamib;
|
||||
VipsBufis *bufis;
|
||||
VipsImage *out;
|
||||
|
||||
char format[256];
|
||||
@ -724,16 +724,16 @@ typedef struct {
|
||||
int
|
||||
vips__rad_israd( VipsStreami *streami )
|
||||
{
|
||||
VipsStreamib *streamib;
|
||||
VipsBufis *bufis;
|
||||
const char *line;
|
||||
int result;
|
||||
|
||||
/* Just test that the first line is the magic string.
|
||||
*/
|
||||
streamib = vips_streamib_new( streami );
|
||||
result = (line = vips_streamib_get_line( streamib )) &&
|
||||
bufis = vips_bufis_new_from_streami( streami );
|
||||
result = (line = vips_bufis_get_line( bufis )) &&
|
||||
strcmp( line, "#?RADIANCE" ) == 0;
|
||||
VIPS_UNREF( streamib );
|
||||
VIPS_UNREF( bufis );
|
||||
|
||||
return( result );
|
||||
}
|
||||
@ -741,14 +741,14 @@ vips__rad_israd( VipsStreami *streami )
|
||||
static void
|
||||
read_destroy( VipsObject *object, Read *read )
|
||||
{
|
||||
VIPS_UNREF( read->streamib );
|
||||
VIPS_UNREF( read->bufis );
|
||||
}
|
||||
|
||||
static void
|
||||
read_minimise_cb( VipsObject *object, Read *read )
|
||||
{
|
||||
if( read->streamib )
|
||||
vips_streami_minimise( read->streamib->streami );
|
||||
if( read->bufis )
|
||||
vips_streami_minimise( read->bufis->streami );
|
||||
}
|
||||
|
||||
static Read *
|
||||
@ -763,7 +763,7 @@ read_new( VipsStreami *streami, VipsImage *out )
|
||||
if( !(read = VIPS_NEW( out, Read )) )
|
||||
return( NULL );
|
||||
|
||||
read->streamib = vips_streamib_new( streami );
|
||||
read->bufis = vips_bufis_new_from_streami( streami );
|
||||
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->streamib,
|
||||
if( getheader( read->bufis,
|
||||
(gethfunc *) rad2vips_process_line, read ) ||
|
||||
!(line = vips_streamib_get_line( read->streamib )) ||
|
||||
!(line = vips_bufis_get_line( read->bufis )) ||
|
||||
!str2resolu( &read->rs, 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_stream_filename(
|
||||
VIPS_STREAM( read->streamib->streami ) ) );
|
||||
VIPS_STREAM( read->bufis->streami ) ) );
|
||||
|
||||
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->streamib, buf, or->im->Xsize ) ) {
|
||||
if( scanline_read( read->bufis, buf, or->im->Xsize ) ) {
|
||||
vips_error( "rad2vips",
|
||||
_( "read error line %d" ), r->top + y );
|
||||
VIPS_GATE_STOP( "rad2vips_generate: work" );
|
||||
|
@ -1,5 +1,6 @@
|
||||
pkginclude_HEADERS = \
|
||||
stream.h \
|
||||
bufis.h \
|
||||
basic.h \
|
||||
type.h \
|
||||
gate.h \
|
||||
|
130
libvips/include/vips/bufis.h
Normal file
130
libvips/include/vips/bufis.h
Normal file
@ -0,0 +1,130 @@
|
||||
/* Buffered inputput from a VipsStreami
|
||||
*
|
||||
* J.Cupitt, 18/11/19
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
This file is part of VIPS.
|
||||
|
||||
VIPS is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
These files are distributed with VIPS - http://www.vips.ecs.soton.ac.uk
|
||||
|
||||
*/
|
||||
|
||||
#ifndef VIPS_BUFIS_H
|
||||
#define VIPS_BUFIS_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /*__cplusplus*/
|
||||
|
||||
#define VIPS_TYPE_BUFIS (vips_bufis_get_type())
|
||||
#define VIPS_BUFIS( obj ) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST( (obj), \
|
||||
VIPS_TYPE_BUFIS, VipsBufis ))
|
||||
#define VIPS_BUFIS_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 ) \
|
||||
(G_TYPE_INSTANCE_GET_CLASS( (obj), \
|
||||
VIPS_TYPE_BUFIS, VipsBufisClass ))
|
||||
|
||||
#define VIPS_BUFIS_BUFFER_SIZE (4096)
|
||||
|
||||
/* Layer over streami: read with an input buffer.
|
||||
*
|
||||
* Libraries like libjpeg do their own input buffering and need raw IO, but
|
||||
* others, like radiance, need to parse the input into lines. A buffered read
|
||||
* class is very convenient.
|
||||
*/
|
||||
typedef struct _VipsBufis {
|
||||
VipsObject parent_object;
|
||||
|
||||
/*< private >*/
|
||||
|
||||
/* The VipsStreami we wrap.
|
||||
*/
|
||||
VipsStreami *streami;
|
||||
|
||||
/* The +1 means there's always a \0 byte at the end.
|
||||
*
|
||||
* Unsigned char, since we don't want >127 to be -ve.
|
||||
*
|
||||
* 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];
|
||||
int chars_in_buffer;
|
||||
int read_point;
|
||||
|
||||
/* Build lines of text here.
|
||||
*/
|
||||
unsigned char line[VIPS_BUFIS_BUFFER_SIZE + 1];
|
||||
|
||||
} VipsBufis;
|
||||
|
||||
typedef struct _VipsBufisClass {
|
||||
VipsObjectClass parent_class;
|
||||
|
||||
} VipsBufisClass;
|
||||
|
||||
GType vips_bufis_get_type( void );
|
||||
|
||||
VipsBufis *vips_bufis_new_from_streami( VipsStreami *streami );
|
||||
|
||||
void vips_bufis_unbuffer( VipsBufis *streamib );
|
||||
|
||||
int vips_bufis_getc( VipsBufis *streamib );
|
||||
#define VIPS_BUFIS_GETC( S ) ( \
|
||||
(S)->read_point < (S)->chars_in_buffer ? \
|
||||
(S)->input_buffer[(S)->read_point++] : \
|
||||
vips_bufis_getc( S ) \
|
||||
)
|
||||
void vips_bufis_ungetc( VipsBufis *streamib );
|
||||
#define VIPS_BUFIS_UNGETC( S ) { \
|
||||
if( (S)->read_point > 0 ) \
|
||||
(S)->read_point -= 1; \
|
||||
}
|
||||
|
||||
int vips_bufis_require( VipsBufis *streamib, int require );
|
||||
#define VIPS_BUFIS_REQUIRE( S, R ) ( \
|
||||
(S)->read_point + (R) <= (S)->chars_in_buffer ? \
|
||||
0 : \
|
||||
vips_bufis_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++])
|
||||
|
||||
const char *vips_bufis_get_line( VipsBufis *streamib );
|
||||
char *vips_bufis_get_line_copy( VipsBufis *streamib );
|
||||
const char *vips_bufis_get_non_whitespace( VipsBufis *streamib );
|
||||
int vips_bufis_skip_whitespace( VipsBufis *streamib );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /*__cplusplus*/
|
||||
|
||||
#endif /*VIPS_BUFIS_H*/
|
@ -217,92 +217,6 @@ size_t vips_streami_sniff_at_most( VipsStreami *streami,
|
||||
unsigned char *vips_streami_sniff( VipsStreami *streami, size_t length );
|
||||
gint64 vips_streami_size( VipsStreami *streami );
|
||||
|
||||
#define VIPS_TYPE_STREAMIB (vips_streamib_get_type())
|
||||
#define VIPS_STREAMIB( obj ) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST( (obj), \
|
||||
VIPS_TYPE_STREAMIB, VipsStreamib ))
|
||||
#define VIPS_STREAMIB_CLASS( klass ) \
|
||||
(G_TYPE_CHECK_CLASS_CAST( (klass), \
|
||||
VIPS_TYPE_STREAMIB, VipsStreamibClass))
|
||||
#define VIPS_IS_STREAMIB( obj ) \
|
||||
(G_TYPE_CHECK_INSTANCE_TYPE( (obj), VIPS_TYPE_STREAMIB ))
|
||||
#define VIPS_IS_STREAMIB_CLASS( klass ) \
|
||||
(G_TYPE_CHECK_CLASS_TYPE( (klass), VIPS_TYPE_STREAMIB ))
|
||||
#define VIPS_STREAMIB_GET_CLASS( obj ) \
|
||||
(G_TYPE_INSTANCE_GET_CLASS( (obj), \
|
||||
VIPS_TYPE_STREAMIB, VipsStreamibClass ))
|
||||
|
||||
#define VIPS_STREAMIB_BUFFER_SIZE (4096)
|
||||
|
||||
/* Layer over streami: read with an input buffer.
|
||||
*
|
||||
* Libraries like libjpeg do their own input buffering and need raw IO, but
|
||||
* others, like radiance, need to parse the input into lines. A buffered read
|
||||
* class is very convenient.
|
||||
*/
|
||||
typedef struct _VipsStreamib {
|
||||
VipsObject parent_object;
|
||||
|
||||
/*< private >*/
|
||||
|
||||
/* The VipsStreami we wrap.
|
||||
*/
|
||||
VipsStreami *streami;
|
||||
|
||||
/* The +1 means there's always a \0 byte at the end.
|
||||
*
|
||||
* Unsigned char, since we don't want >127 to be -ve.
|
||||
*
|
||||
* 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_STREAMIB_BUFFER_SIZE + 1];
|
||||
int chars_in_buffer;
|
||||
int read_point;
|
||||
|
||||
/* Build lines of text here.
|
||||
*/
|
||||
unsigned char line[VIPS_STREAMIB_BUFFER_SIZE + 1];
|
||||
|
||||
} VipsStreamib;
|
||||
|
||||
typedef struct _VipsStreamibClass {
|
||||
VipsObjectClass parent_class;
|
||||
|
||||
} VipsStreamibClass;
|
||||
|
||||
GType vips_streamib_get_type( void );
|
||||
|
||||
VipsStreamib *vips_streamib_new( VipsStreami *streami );
|
||||
|
||||
void vips_streamib_unbuffer( VipsStreamib *streamib );
|
||||
|
||||
int vips_streamib_getc( VipsStreamib *streamib );
|
||||
#define VIPS_STREAMIB_GETC( S ) ( \
|
||||
(S)->read_point < (S)->chars_in_buffer ? \
|
||||
(S)->input_buffer[(S)->read_point++] : \
|
||||
vips_streamib_getc( S ) \
|
||||
)
|
||||
void vips_streamib_ungetc( VipsStreamib *streamib );
|
||||
#define VIPS_STREAMIB_UNGETC( S ) { \
|
||||
if( (S)->read_point > 0 ) \
|
||||
(S)->read_point -= 1; \
|
||||
}
|
||||
|
||||
int vips_streamib_require( VipsStreamib *streamib, int require );
|
||||
#define VIPS_STREAMIB_REQUIRE( S, R ) ( \
|
||||
(S)->read_point + (R) <= (S)->chars_in_buffer ? \
|
||||
0 : \
|
||||
vips_streamib_require( (S), (R) ) \
|
||||
)
|
||||
#define VIPS_STREAMIB_PEEK( S ) ((S)->input_buffer + (S)->read_point)
|
||||
#define VIPS_STREAMIB_FETCH( S ) ((S)->input_buffer[(S)->read_point++])
|
||||
|
||||
const char *vips_streamib_get_line( VipsStreamib *streamib );
|
||||
char *vips_streamib_get_line_copy( VipsStreamib *streamib );
|
||||
const char *vips_streamib_get_non_whitespace( VipsStreamib *streamib );
|
||||
int vips_streamib_skip_whitespace( VipsStreamib *streamib );
|
||||
|
||||
#define VIPS_TYPE_STREAMIW (vips_streamiw_get_type())
|
||||
#define VIPS_STREAMIW( obj ) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST( (obj), \
|
||||
|
@ -115,6 +115,7 @@ extern "C" {
|
||||
#include <vips/type.h>
|
||||
#include <vips/gate.h>
|
||||
#include <vips/stream.h>
|
||||
#include <vips/bufis.h>
|
||||
|
||||
#include <vips/version.h>
|
||||
#include <vips/rect.h>
|
||||
|
@ -3,9 +3,9 @@ noinst_LTLIBRARIES = libiofuncs.la
|
||||
libiofuncs_la_SOURCES = \
|
||||
stream.c \
|
||||
streami.c \
|
||||
streamib.c \
|
||||
streamiw.c \
|
||||
streamo.c \
|
||||
bufis.c \
|
||||
dbuf.c \
|
||||
reorder.c \
|
||||
vipsmarshal.h \
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* A layer over streami to provide buffered and line-based input.
|
||||
*
|
||||
* J.Cupitt, 19/6/14
|
||||
/* Buffered input from a stream.
|
||||
*
|
||||
* J.Cupitt, 18/11/19
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -30,13 +30,6 @@
|
||||
|
||||
*/
|
||||
|
||||
/* TODO
|
||||
*
|
||||
* - can we map and then close the fd? how about on Windows?
|
||||
* - make a subclass that lets you set vfuncs as params, inc. close(),
|
||||
* is_pipe etc.
|
||||
*/
|
||||
|
||||
/*
|
||||
#define VIPS_DEBUG
|
||||
*/
|
||||
@ -63,10 +56,10 @@
|
||||
#include <vips/internal.h>
|
||||
#include <vips/debug.h>
|
||||
|
||||
G_DEFINE_TYPE( VipsStreamib, vips_streamib, VIPS_TYPE_OBJECT );
|
||||
G_DEFINE_TYPE( VipsBufis, vips_bufis, VIPS_TYPE_OBJECT );
|
||||
|
||||
static void
|
||||
vips_streamib_class_init( VipsStreamibClass *class )
|
||||
vips_bufis_class_init( VipsBufisClass *class )
|
||||
{
|
||||
VipsObjectClass *object_class = VIPS_OBJECT_CLASS( class );
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS( class );
|
||||
@ -74,160 +67,160 @@ vips_streamib_class_init( VipsStreamibClass *class )
|
||||
gobject_class->set_property = vips_object_set_property;
|
||||
gobject_class->get_property = vips_object_get_property;
|
||||
|
||||
object_class->nickname = "streamib";
|
||||
object_class->nickname = "bufis";
|
||||
object_class->description = _( "buffered input stream" );
|
||||
|
||||
VIPS_ARG_OBJECT( class, "input", 1,
|
||||
_( "Input" ),
|
||||
_( "Stream to load from" ),
|
||||
VIPS_ARGUMENT_REQUIRED_INPUT,
|
||||
G_STRUCT_OFFSET( VipsStreamib, streami ),
|
||||
G_STRUCT_OFFSET( VipsBufis, streami ),
|
||||
VIPS_TYPE_STREAMI );
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
vips_streamib_init( VipsStreamib *streamib )
|
||||
vips_bufis_init( VipsBufis *bufis )
|
||||
{
|
||||
streamib->read_point = 0;
|
||||
streamib->chars_in_buffer = 0;
|
||||
streamib->input_buffer[0] = '\0';
|
||||
bufis->read_point = 0;
|
||||
bufis->chars_in_buffer = 0;
|
||||
bufis->input_buffer[0] = '\0';
|
||||
}
|
||||
|
||||
/**
|
||||
* vips_streamib_new:
|
||||
* vips_bufis_new_from_streami:
|
||||
* @streami: stream to operate on
|
||||
*
|
||||
* Create a streamib wrapping a streami.
|
||||
* Create a bufis wrapping a streami.
|
||||
*
|
||||
* Returns: a new #VipsStreamib
|
||||
* Returns: a new #VipsBufis
|
||||
*/
|
||||
VipsStreamib *
|
||||
vips_streamib_new( VipsStreami *streami )
|
||||
VipsBufis *
|
||||
vips_bufis_new_from_streami( VipsStreami *streami )
|
||||
{
|
||||
VipsStreamib *streamib;
|
||||
VipsBufis *bufis;
|
||||
|
||||
streamib = VIPS_STREAMIB( g_object_new( VIPS_TYPE_STREAMIB,
|
||||
bufis = VIPS_BUFIS( g_object_new( VIPS_TYPE_BUFIS,
|
||||
"input", streami,
|
||||
NULL ) );
|
||||
|
||||
if( vips_object_build( VIPS_OBJECT( streamib ) ) ) {
|
||||
VIPS_UNREF( streamib );
|
||||
if( vips_object_build( VIPS_OBJECT( bufis ) ) ) {
|
||||
VIPS_UNREF( bufis );
|
||||
return( NULL );
|
||||
}
|
||||
|
||||
return( streamib );
|
||||
return( bufis );
|
||||
}
|
||||
|
||||
/**
|
||||
* vips_streamib_unbuffer:
|
||||
* @streamib: stream to operate on
|
||||
* vips_bufis_unbuffer:
|
||||
* @bufis: stream to operate on
|
||||
*
|
||||
* Discard the input buffer and reset the read point. You must call this
|
||||
* before using read or seek on the underlying #VipsStreami class.
|
||||
*/
|
||||
void
|
||||
vips_streamib_unbuffer( VipsStreamib *streamib )
|
||||
vips_bufis_unbuffer( VipsBufis *bufis )
|
||||
{
|
||||
/* We'd read ahead a little way -- seek backwards by that amount.
|
||||
*/
|
||||
vips_streami_seek( streamib->streami,
|
||||
streamib->read_point - streamib->chars_in_buffer, SEEK_CUR );
|
||||
streamib->read_point = 0;
|
||||
streamib->chars_in_buffer = 0;
|
||||
vips_streami_seek( bufis->streami,
|
||||
bufis->read_point - bufis->chars_in_buffer, SEEK_CUR );
|
||||
bufis->read_point = 0;
|
||||
bufis->chars_in_buffer = 0;
|
||||
}
|
||||
|
||||
/* Returns -1 on error, 0 on EOF, otherwise bytes read.
|
||||
*/
|
||||
static ssize_t
|
||||
vips_streamib_refill( VipsStreamib *streamib )
|
||||
vips_bufis_refill( VipsBufis *bufis )
|
||||
{
|
||||
ssize_t bytes_read;
|
||||
|
||||
VIPS_DEBUG_MSG( "vips_streamib_refill:\n" );
|
||||
VIPS_DEBUG_MSG( "vips_bufis_refill:\n" );
|
||||
|
||||
/* We should not discard any unread bytes.
|
||||
*/
|
||||
g_assert( streamib->read_point == streamib->chars_in_buffer );
|
||||
g_assert( bufis->read_point == bufis->chars_in_buffer );
|
||||
|
||||
bytes_read = vips_streami_read( streamib->streami,
|
||||
streamib->input_buffer, VIPS_STREAMIB_BUFFER_SIZE );
|
||||
bytes_read = vips_streami_read( bufis->streami,
|
||||
bufis->input_buffer, VIPS_BUFIS_BUFFER_SIZE );
|
||||
if( bytes_read == -1 )
|
||||
return( -1 );
|
||||
|
||||
streamib->read_point = 0;
|
||||
streamib->chars_in_buffer = bytes_read;
|
||||
bufis->read_point = 0;
|
||||
bufis->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_STREAMIB_BUFFER_SIZE + 1 bytes.
|
||||
* safe because input_buffer is VIPS_BUFIS_BUFFER_SIZE + 1 bytes.
|
||||
*/
|
||||
streamib->input_buffer[bytes_read] = '\0';
|
||||
bufis->input_buffer[bytes_read] = '\0';
|
||||
|
||||
return( bytes_read );
|
||||
}
|
||||
|
||||
/**
|
||||
* vips_streamib_getc:
|
||||
* @streamib: stream to operate on
|
||||
* vips_bufis_getc:
|
||||
* @bufis: stream to operate on
|
||||
*
|
||||
* Fetch the next character from the stream.
|
||||
*
|
||||
* If you can, use the macro VIPS_STREAMIB_GETC() instead for speed.
|
||||
* If you can, use the macro VIPS_BUFIS_GETC() instead for speed.
|
||||
*
|
||||
* Returns: the next char from @streamib, -1 on read error or EOF.
|
||||
* Returns: the next char from @bufis, -1 on read error or EOF.
|
||||
*/
|
||||
int
|
||||
vips_streamib_getc( VipsStreamib *streamib )
|
||||
vips_bufis_getc( VipsBufis *bufis )
|
||||
{
|
||||
if( streamib->read_point == streamib->chars_in_buffer &&
|
||||
vips_streamib_refill( streamib ) <= 0 )
|
||||
if( bufis->read_point == bufis->chars_in_buffer &&
|
||||
vips_bufis_refill( bufis ) <= 0 )
|
||||
return( -1 );
|
||||
|
||||
g_assert( streamib->read_point < streamib->chars_in_buffer );
|
||||
g_assert( bufis->read_point < bufis->chars_in_buffer );
|
||||
|
||||
return( streamib->input_buffer[streamib->read_point++] );
|
||||
return( bufis->input_buffer[bufis->read_point++] );
|
||||
}
|
||||
|
||||
/**
|
||||
* VIPS_STREAMIB_GETC:
|
||||
* @streamib: stream to operate on
|
||||
* VIPS_BUFIS_GETC:
|
||||
* @bufis: stream to operate on
|
||||
*
|
||||
* Fetch the next character from the stream.
|
||||
*
|
||||
* Returns: the next char from @streamib, -1 on read error or EOF.
|
||||
* Returns: the next char from @bufis, -1 on read error or EOF.
|
||||
*/
|
||||
|
||||
/**
|
||||
* vips_streamib_ungetc:
|
||||
* @streamib: stream to operate on
|
||||
* vips_bufis_ungetc:
|
||||
* @bufis: stream to operate on
|
||||
*
|
||||
* The opposite of vips_streamib_getc(): undo the previous getc.
|
||||
* The opposite of vips_bufis_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_STREAMIB_UNGETC() instead for speed.
|
||||
* If you can, use the macro VIPS_BUFIS_UNGETC() instead for speed.
|
||||
*/
|
||||
void
|
||||
vips_streamib_ungetc( VipsStreamib *streamib )
|
||||
vips_bufis_ungetc( VipsBufis *bufis )
|
||||
{
|
||||
if( streamib->read_point > 0 )
|
||||
streamib->read_point -= 1;
|
||||
if( bufis->read_point > 0 )
|
||||
bufis->read_point -= 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* VIPS_STREAMIB_UNGETC:
|
||||
* @streamib: stream to operate on
|
||||
* VIPS_BUFIS_UNGETC:
|
||||
* @bufis: stream to operate on
|
||||
*
|
||||
* The opposite of vips_streamib_getc(): undo the previous getc.
|
||||
* The opposite of vips_bufis_getc(): undo the previous getc.
|
||||
*
|
||||
* unget more than one character is undefined. Unget at the start of the file
|
||||
* does nothing.
|
||||
*/
|
||||
|
||||
/**
|
||||
* vips_streamib_require:
|
||||
* @streamib: stream to operate on
|
||||
* vips_bufis_require:
|
||||
* @bufis: stream 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.
|
||||
@ -235,46 +228,46 @@ vips_streamib_ungetc( VipsStreamib *streamib )
|
||||
* Returns: 0 on success, -1 on error or EOF.
|
||||
*/
|
||||
int
|
||||
vips_streamib_require( VipsStreamib *streamib, int require )
|
||||
vips_bufis_require( VipsBufis *bufis, int require )
|
||||
{
|
||||
g_assert( require < VIPS_STREAMIB_BUFFER_SIZE );
|
||||
g_assert( streamib->chars_in_buffer >= 0 );
|
||||
g_assert( streamib->chars_in_buffer <= VIPS_STREAMIB_BUFFER_SIZE );
|
||||
g_assert( streamib->read_point >= 0 );
|
||||
g_assert( streamib->read_point <= streamib->chars_in_buffer );
|
||||
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 );
|
||||
|
||||
VIPS_DEBUG_MSG( "vips_streamib_require: %d\n", require );
|
||||
VIPS_DEBUG_MSG( "vips_bufis_require: %d\n", require );
|
||||
|
||||
if( streamib->read_point + require > streamib->chars_in_buffer ) {
|
||||
if( bufis->read_point + require > bufis->chars_in_buffer ) {
|
||||
/* Areas can overlap, so we must memmove().
|
||||
*/
|
||||
memmove( streamib->input_buffer,
|
||||
streamib->input_buffer + streamib->read_point,
|
||||
streamib->chars_in_buffer - streamib->read_point );
|
||||
streamib->chars_in_buffer -= streamib->read_point;
|
||||
streamib->read_point = 0;
|
||||
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;
|
||||
|
||||
while( require > streamib->chars_in_buffer ) {
|
||||
unsigned char *to = streamib->input_buffer +
|
||||
streamib->chars_in_buffer;
|
||||
while( require > bufis->chars_in_buffer ) {
|
||||
unsigned char *to = bufis->input_buffer +
|
||||
bufis->chars_in_buffer;
|
||||
int space_available =
|
||||
VIPS_STREAMIB_BUFFER_SIZE -
|
||||
streamib->chars_in_buffer;
|
||||
VIPS_BUFIS_BUFFER_SIZE -
|
||||
bufis->chars_in_buffer;
|
||||
size_t bytes_read;
|
||||
|
||||
if( (bytes_read = vips_streami_read( streamib->streami,
|
||||
if( (bytes_read = vips_streami_read( bufis->streami,
|
||||
to, space_available )) == -1 )
|
||||
return( -1 );
|
||||
if( bytes_read == 0 ) {
|
||||
vips_error(
|
||||
vips_stream_nick( VIPS_STREAM(
|
||||
streamib->streami ) ),
|
||||
bufis->streami ) ),
|
||||
"%s", _( "end of file" ) );
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
to[bytes_read] = '\0';
|
||||
streamib->chars_in_buffer += bytes_read;
|
||||
bufis->chars_in_buffer += bytes_read;
|
||||
}
|
||||
}
|
||||
|
||||
@ -282,41 +275,41 @@ vips_streamib_require( VipsStreamib *streamib, int require )
|
||||
}
|
||||
|
||||
/**
|
||||
* VIPS_STREAMIB_REQUIRE:
|
||||
* @streamib: stream to operate on
|
||||
* VIPS_BUFIS_REQUIRE:
|
||||
* @bufis: stream to operate on
|
||||
* @require: need this many characters
|
||||
*
|
||||
* Make sure at least @require characters are available for
|
||||
* VIPS_STREAMIB_PEEK() and VIPS_STREAMIB_FETCH().
|
||||
* VIPS_BUFIS_PEEK() and VIPS_BUFIS_FETCH().
|
||||
*
|
||||
* Returns: 0 on success, -1 on read error or EOF.
|
||||
*/
|
||||
|
||||
/**
|
||||
* VIPS_STREAMIB_PEEK:
|
||||
* @streamib: stream to operate on
|
||||
* VIPS_BUFIS_PEEK:
|
||||
* @bufis: stream to operate on
|
||||
*
|
||||
* After a successful VIPS_STREAMIB_REQUIRE(), you can index this to get
|
||||
* After a successful VIPS_BUFIS_REQUIRE(), you can index this to get
|
||||
* require characters of input.
|
||||
*
|
||||
* Returns: a pointer to the next requre characters of input.
|
||||
*/
|
||||
|
||||
/**
|
||||
* VIPS_STREAMIB_FETCH:
|
||||
* @streamib: stream to operate on
|
||||
* VIPS_BUFIS_FETCH:
|
||||
* @bufis: stream to operate on
|
||||
*
|
||||
* After a successful VIPS_STREAMIB_REQUIRE(), you can use this require times
|
||||
* After a successful VIPS_BUFIS_REQUIRE(), you can use this require times
|
||||
* to fetch characters of input.
|
||||
*
|
||||
* Returns: the next input character.
|
||||
*/
|
||||
|
||||
/**
|
||||
* vips_streamib_get_line:
|
||||
* @streamib: stream to operate on
|
||||
* vips_bufis_get_line:
|
||||
* @bufis: stream to operate on
|
||||
*
|
||||
* Fetch the next line of text from @streamib and return it. The end of
|
||||
* Fetch the next line of text from @bufis 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).
|
||||
*
|
||||
@ -324,33 +317,33 @@ vips_streamib_require( VipsStreamib *streamib, int require )
|
||||
*
|
||||
* If the line is longer than some arbitrary (but large) limit, is is
|
||||
* truncated. If you need to be able to read very long lines, use the
|
||||
* slower vips_streamib_get_line_copy().
|
||||
* slower vips_bufis_get_line_copy().
|
||||
*
|
||||
* The return value is owned by @streamib and must not be freed. It
|
||||
* is valid until the next get call @streamib.
|
||||
* The return value is owned by @bufis and must not be freed. It
|
||||
* is valid until the next get call @bufis.
|
||||
*
|
||||
* Returns: the next line of text, or NULL on EOF or read error.
|
||||
*/
|
||||
const char *
|
||||
vips_streamib_get_line( VipsStreamib *streamib )
|
||||
vips_bufis_get_line( VipsBufis *bufis )
|
||||
{
|
||||
int write_point;
|
||||
int space_remaining;
|
||||
int ch;
|
||||
|
||||
VIPS_DEBUG_MSG( "vips_streamib_get_line:\n" );
|
||||
VIPS_DEBUG_MSG( "vips_bufis_get_line:\n" );
|
||||
|
||||
write_point = 0;
|
||||
space_remaining = VIPS_STREAMIB_BUFFER_SIZE;
|
||||
space_remaining = VIPS_BUFIS_BUFFER_SIZE;
|
||||
|
||||
while( (ch = VIPS_STREAMIB_GETC( streamib )) != -1 &&
|
||||
while( (ch = VIPS_BUFIS_GETC( bufis )) != -1 &&
|
||||
ch != '\n' &&
|
||||
space_remaining > 0 ) {
|
||||
streamib->line[write_point] = ch;
|
||||
bufis->line[write_point] = ch;
|
||||
write_point += 1;
|
||||
space_remaining -= 1;
|
||||
}
|
||||
streamib->line[write_point] = '\0';
|
||||
bufis->line[write_point] = '\0';
|
||||
|
||||
/* If we hit EOF immediately, return EOF.
|
||||
*/
|
||||
@ -365,27 +358,27 @@ vips_streamib_get_line( VipsStreamib *streamib )
|
||||
* lines, but ignore this.
|
||||
*/
|
||||
if( write_point > 0 &&
|
||||
streamib->line[write_point - 1] == '\r' )
|
||||
streamib->line[write_point - 1] = '\0';
|
||||
bufis->line[write_point - 1] == '\r' )
|
||||
bufis->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_STREAMIB_GETC( streamib )) != -1 &&
|
||||
while( (ch = VIPS_BUFIS_GETC( bufis )) != -1 &&
|
||||
ch != '\n' )
|
||||
;
|
||||
}
|
||||
|
||||
VIPS_DEBUG_MSG( " %s\n", streamib->line );
|
||||
VIPS_DEBUG_MSG( " %s\n", bufis->line );
|
||||
|
||||
return( (const char *) streamib->line );
|
||||
return( (const char *) bufis->line );
|
||||
}
|
||||
|
||||
/**
|
||||
* vips_streamib_get_line_copy:
|
||||
* @streamib: stream to operate on
|
||||
* vips_bufis_get_line_copy:
|
||||
* @bufis: stream to operate on
|
||||
*
|
||||
* Return the next line of text from the stream. The newline character (or
|
||||
* characters) are removed, and and the string is terminated with a null
|
||||
@ -393,17 +386,17 @@ vips_streamib_get_line( VipsStreamib *streamib )
|
||||
*
|
||||
* The return result must be freed with g_free().
|
||||
*
|
||||
* This is slower than vips_streamib_get_line(), but can work with lines of
|
||||
* This is slower than vips_bufis_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_streamib_get_line_copy( VipsStreamib *streamib )
|
||||
vips_bufis_get_line_copy( VipsBufis *bufis )
|
||||
{
|
||||
static const unsigned char null = '\0';
|
||||
|
||||
VIPS_DEBUG_MSG( "vips_streamib_get_line_copy:\n" );
|
||||
VIPS_DEBUG_MSG( "vips_bufis_get_line_copy:\n" );
|
||||
|
||||
GByteArray *buffer;
|
||||
int ch;
|
||||
@ -411,7 +404,7 @@ vips_streamib_get_line_copy( VipsStreamib *streamib )
|
||||
|
||||
buffer = g_byte_array_new();
|
||||
|
||||
while( (ch = VIPS_STREAMIB_GETC( streamib )) != -1 &&
|
||||
while( (ch = VIPS_BUFIS_GETC( bufis )) != -1 &&
|
||||
ch != '\n' ) {
|
||||
unsigned char c = ch;
|
||||
|
||||
@ -444,8 +437,8 @@ vips_streamib_get_line_copy( VipsStreamib *streamib )
|
||||
}
|
||||
|
||||
/**
|
||||
* vips_streamib_get_non_whitespace:
|
||||
* @streamib: stream to operate on
|
||||
* vips_bufis_get_non_whitespace:
|
||||
* @bufis: stream to operate on
|
||||
*
|
||||
* Fetch the next chunk of non-whitespace text from the stream, and
|
||||
* null-terminate it.
|
||||
@ -459,28 +452,28 @@ vips_streamib_get_line_copy( VipsStreamib *streamib )
|
||||
* If the item is longer than some arbitrary (but large) limit, it is
|
||||
* truncated.
|
||||
*
|
||||
* The return value is owned by @streamib and must not be freed. It
|
||||
* is valid until the next get call @streamib.
|
||||
* The return value is owned by @bufis and must not be freed. It
|
||||
* is valid until the next get call @bufis.
|
||||
*
|
||||
* Returns: the next block of non-whitespace, or NULL on EOF or read error.
|
||||
*/
|
||||
const char *
|
||||
vips_streamib_get_non_whitespace( VipsStreamib *streamib )
|
||||
vips_bufis_get_non_whitespace( VipsBufis *bufis )
|
||||
{
|
||||
int ch;
|
||||
int i;
|
||||
|
||||
for( i = 0; i < VIPS_STREAMIB_BUFFER_SIZE &&
|
||||
!isspace( ch = VIPS_STREAMIB_GETC( streamib ) ) &&
|
||||
for( i = 0; i < VIPS_BUFIS_BUFFER_SIZE &&
|
||||
!isspace( ch = VIPS_BUFIS_GETC( bufis ) ) &&
|
||||
ch != EOF; i++ )
|
||||
streamib->line[i] = ch;
|
||||
streamib->line[i] = '\0';
|
||||
bufis->line[i] = ch;
|
||||
bufis->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_STREAMIB_GETC( streamib ) ) &&
|
||||
while( !isspace( ch = VIPS_BUFIS_GETC( bufis ) ) &&
|
||||
ch != EOF )
|
||||
;
|
||||
|
||||
@ -488,14 +481,14 @@ vips_streamib_get_non_whitespace( VipsStreamib *streamib )
|
||||
* will be whitespace (or EOF).
|
||||
*/
|
||||
if( isspace( ch ) )
|
||||
VIPS_STREAMIB_UNGETC( streamib );
|
||||
VIPS_BUFIS_UNGETC( bufis );
|
||||
|
||||
return( (const char *) streamib->line );
|
||||
return( (const char *) bufis->line );
|
||||
}
|
||||
|
||||
/**
|
||||
* vips_streamib_skip_whitespace:
|
||||
* @streamib: stream to operate on
|
||||
* vips_bufis_skip_whitespace:
|
||||
* @bufis: stream to operate on
|
||||
*
|
||||
* After this, the next getc will be the first char of the next block of
|
||||
* non-whitespace (or EOF).
|
||||
@ -503,19 +496,19 @@ vips_streamib_get_non_whitespace( VipsStreamib *streamib )
|
||||
* Returns: 0 on success, -1 on error.
|
||||
*/
|
||||
int
|
||||
vips_streamib_skip_whitespace( VipsStreamib *streamib )
|
||||
vips_bufis_skip_whitespace( VipsBufis *bufis )
|
||||
{
|
||||
int ch;
|
||||
|
||||
while( isspace( ch = VIPS_STREAMIB_GETC( streamib ) ) )
|
||||
while( isspace( ch = VIPS_BUFIS_GETC( bufis ) ) )
|
||||
;
|
||||
VIPS_STREAMIB_UNGETC( streamib );
|
||||
VIPS_BUFIS_UNGETC( bufis );
|
||||
|
||||
/* # skip comments too.
|
||||
*/
|
||||
if( ch == '#' &&
|
||||
(!vips_streamib_get_line( streamib ) ||
|
||||
vips_streamib_skip_whitespace( streamib )) )
|
||||
(!vips_bufis_get_line( bufis ) ||
|
||||
vips_bufis_skip_whitespace( bufis )) )
|
||||
return( -1 );
|
||||
|
||||
return( 0 );
|
Loading…
Reference in New Issue
Block a user