pike.git / src / modules / _Stdio / buffer.cmod

version» Context lines:

pike.git/src/modules/_Stdio/buffer.cmod:880:    }    break;    case PIKE_T_INT:    {    unsigned char a = p->u.integer;    io_append( io, &a, 1 );    }    }    }    -  static Buffer* already_destructed() { -  Pike_error("Stdio.Buffer already destructed.\n"); -  return 0; -  } -  +    #undef THIS   #define THIS (&(((struct Buffer_struct *)Pike_fp->current_storage)->b))    - #define CHECK_DESTRUCTED(io) ((io)->this ? (io) : already_destructed()) +        /* pike functions */       /*! @decl int(-1..) input_from( Stdio.Stream f, int|void nbytes )    *!    *! Read data from @[f] into this buffer. If @[nbytes] is not    *! specified, read until there is no more data to read (currently).    *!    *! Returns the amount of data that was read, or @expr{-1@} on    *! read error.    *!    *! @note    *! Please note that this funcition will read all data from the    *! filedescriptor unless it's set to be non-blocking.    */    PIKEFUN int(-1..) input_from( object f, int|void _nbytes, int|void _once )    { -  Buffer *io = CHECK_DESTRUCTED(THIS); +  Buffer *io = THIS;    size_t sz = io_len( io );    size_t bread = 0, nbytes = (size_t)-1;    struct my_file *fd;    int once = 0;       if( _nbytes ) {    nbytes = _nbytes->u.integer;    if (!nbytes) RETURN 0;    }   
pike.git/src/modules/_Stdio/buffer.cmod:982:    *!    *! @note    *! This is used internally by @[Stdio.File] and @[SSL.File] to    *! handle nonblocking buffered mode, and is not necessarily    *! intended to be used directly by anything but implementations    *! of File or Stream like programs. Do not use this yourself    *! on buffers with Files or Streams in buffer modes.    */    PIKEFUN void __set_on_write( zero|function f )    { -  Buffer *io = CHECK_DESTRUCTED(THIS); +  Buffer *io = THIS;       if (f)    assign_svalue(&io->output, f);    else {    if (io->output.tu.named_type == PIKE_T_FUNCTION)    free_svalue(&io->output);    }    }       /*! @decl int(-1..) output_to( Stdio.Stream|function(string(8bit):int) fun, @
pike.git/src/modules/_Stdio/buffer.cmod:1030:    *! @deprecated    *! This function is going to get deprecated. In case you want to use    *! it against an @[Stdio.File] like object, please consider using    *! the @expr{f->write(buf)@} API. If you want to use it against a custom    *! write function, please consider supporting the @expr{f->write(buf)@}    *! API in it.    */    PIKEFUN int(-1..) output_to( object|function(string(8bit):int) f,    int|void nbytes )    { -  Buffer *io = CHECK_DESTRUCTED(THIS); +  Buffer *io = THIS;    ptrdiff_t written = 0;    ptrdiff_t sz = io_len( io );    int write_fun_num = -1;       if( !sz )    {    io_range_error(io, sz);    sz = io_len(io);    }    if( nbytes )
pike.git/src/modules/_Stdio/buffer.cmod:1118:    /*! @decl int read_sint( int size )    *!    *! Read a network byte order two:s complement signed number of size    *! n*8 bits, then return it.    *!    *! Will return UNDEFINED if there is not enough buffer space    *! available unless error mode is set to throw errors.    */    PIKEFUN int read_sint( int nbytes )    { -  Buffer *io = CHECK_DESTRUCTED(THIS); +  Buffer *io = THIS;    struct pike_string *tmp;    Pike_sp--;    if( !io_avail( io, nbytes ) )    {    push_undefined();    return;    }    if( nbytes <= SIZEOF_INT_TYPE )    {    push_int( io_read_signed_number_uc( io,nbytes ) );
pike.git/src/modules/_Stdio/buffer.cmod:1151:    ref_push_string( tmp );    push_int( 256 );    push_object( clone_object( bignum_program, 2 ) );    if( tmp->str[0]&0x80 )    o_xor();    free_string( tmp );    }       PIKEFUN int(0..) _size_object( )    { -  Buffer *io = CHECK_DESTRUCTED(THIS); +  Buffer *io = THIS;    if (io->malloced)    {    push_ulongest(THIS->allocated);    }    else    {    push_int(0);    }    }       /*! @decl Buffer add_padding( int(0..) nbytes, int(0..255)|void byte )    *!    *! Add @[nbytes] bytes of padding, if @[byte] is not specified the    *! area will be filled with 0's, otherwise the specified byte will    *! be repeated.    */    PIKEFUN Buffer add_padding( int(0..) nbytes, int|void _byte )    { -  Buffer *io = CHECK_DESTRUCTED(THIS); +  Buffer *io = THIS;    int byte = 0;    if( _byte ) byte = _byte->u.integer;       if( nbytes < 0 )    Pike_error("Cannot add negative padding.\n");       memset( io_add_space( io, nbytes,0), byte, nbytes );    io->len += nbytes;    Pike_sp -= args;    io_trigger_output( io );
pike.git/src/modules/_Stdio/buffer.cmod:1217:    *! any one of the types listed here.    *! @endmixed    *!    *! @seealso    *! @[sprintf], @[add_int8], @[add_int16], @[add_int32], @[add_int]    *! and    *! @[add_hstring]    */    PIKEFUN Buffer add( object|string(8bit)|int|array(object|string(8bit)|int) ... argp)    { -  Buffer *io = CHECK_DESTRUCTED(THIS); +     int i; -  +  Buffer *io = THIS;       for(i=0; i<args; i++ )    io_append_svalue( io, argp+i );       pop_stack();    ref_push_object(io->this);    }       /*! @decl Buffer add_int8( int(8bit) )    *! Adds a single byte to the buffer.    */    PIKEFUN Buffer add_int8( int i )    { -  Buffer *io = CHECK_DESTRUCTED(THIS); +  Buffer *io = THIS;    *io_add_space(io,1,0)=i;    io->len++;    Pike_sp--;    io_trigger_output( io );    ref_push_object(Pike_fp->current_object);    }       /*! @decl Buffer add_int8( Gmp.mpz )    *! Adds a single byte to the buffer.    */    PIKEFUN Buffer add_int8( object mpz )    { -  Buffer *io = CHECK_DESTRUCTED(THIS); +     INT64 i = 0; -  +  Buffer *io = THIS;    unsigned char *p = io_add_space(io,1,0);    if (!low_int64_from_bignum(&i, mpz)) {    SIMPLE_ARG_TYPE_ERROR("add_int8", 1, "int|Gmp.mpz");    }    *p = i;    io->len++;    ref_push_object(Pike_fp->current_object);    }       /*! @decl Buffer add_int16( int(16bit) )    *!    *! Add a 16-bit network byte order value to the buffer    */    PIKEFUN Buffer add_int16( int i )    { -  Buffer *io = CHECK_DESTRUCTED(THIS); +  Buffer *io = THIS;    unsigned char *p = io_add_space(io,2,0);    p[0] = i>>8;    p[1] = i;    io->len += 2;    io_trigger_output( io );    ref_push_object(Pike_fp->current_object);    }       /*! @decl Buffer add_int16( Gmp.mpz )    *!    *! Add a 16-bit network byte order value to the buffer    */    PIKEFUN Buffer add_int16( object mpz )    { -  Buffer *io = CHECK_DESTRUCTED(THIS); +     INT64 i = 0; -  +  Buffer *io = THIS;    unsigned char *p = io_add_space(io,2,0);    if (!low_int64_from_bignum(&i, mpz)) {    SIMPLE_ARG_TYPE_ERROR("add_int16", 1, "int|Gmp.mpz");    }    p[0] = i>>8;    p[1] = i;    io->len += 2;    ref_push_object(Pike_fp->current_object);    }       /*! @decl Buffer add_int32( int i )    *! Adds a 32 bit network byte order value to the buffer    */    PIKEFUN Buffer add_int32( int i )    { -  Buffer *io = CHECK_DESTRUCTED(THIS); +  Buffer *io = THIS;    unsigned char *p = io_add_space(io,4,0);    p[0] = i>>24;    p[1] = i>>16;    p[2] = i>>8;    p[3] = i;    io->len += 4;    io_trigger_output( io );    ref_push_object(Pike_fp->current_object);    }       /*! @decl Buffer add_int32( Gmp.mpz i )    *! Adds a 32 bit network byte order value to the buffer    */    PIKEFUN Buffer add_int32( object mpz )    { -  Buffer *io = CHECK_DESTRUCTED(THIS); +     INT64 i = 0; -  +  Buffer *io = THIS;    unsigned char *p = io_add_space(io,4,0);    if (!low_int64_from_bignum(&i, mpz)) {    SIMPLE_ARG_TYPE_ERROR("add_int32", 1, "int|Gmp.mpz");    }    p[0] = i>>24;    p[1] = i>>16;    p[2] = i>>8;    p[3] = i;    io->len += 4;    io_trigger_output( io );
pike.git/src/modules/_Stdio/buffer.cmod:1375:    /* we can not use the actual type here.       the reason is that this class is loaded before the master is, so    we cannot possibly use things that require the master (such as    resolving things.)    */    PIKEFUN Buffer add_hstring(    int|string(8bit)|object|array(int|string(8bit)|Buffer|array) str,    int size_size, void|int offset )    { -  Buffer *io = CHECK_DESTRUCTED(THIS); +  Buffer *io = THIS;    size_t len = io_svalue_len(io, str);       if( offset )    len += offset->u.integer;       if( size_size < (int)sizeof(size_t) &&    len > (((size_t)1)<<(8*size_size))-1 )    Pike_error("Too long string, need larger size field.\n");       io_add_int( io, len, size_size );
pike.git/src/modules/_Stdio/buffer.cmod:1401:    /*! @decl Buffer add_int( int i, int(0..) width )    *!    *! Adds a generic integer to the buffer as an (width*8)bit    *! network byteorder number.    *!    *! @[width] must be less than Int.NATIVE_MAX.    *!    */    PIKEFUN Buffer add_int( object|int i, int width )    { -  Buffer *io = CHECK_DESTRUCTED(THIS); +     pop_stack(); /* width */    if( TYPEOF(*i) == PIKE_T_INT )    { -  io_add_int( io, i->u.integer, width ); +  io_add_int( THIS, i->u.integer, width );    Pike_sp--;    }    else    {    convert_stack_top_to_bignum(); -  io_add_bignum( io, i->u.object, width ); +  io_add_bignum( THIS, i->u.object, width );    pop_stack(); /* o. */    }    ref_push_object(Pike_fp->current_object);    }       /*! @decl Buffer add_hint( int i, int(0..) size_width )    *!    *! First add the size of the integer when encoded to base 256 as a    *! @[size_width] integer, then add the integer to the buffer, both    *! in network byte order.    *!    *! @[size_width] must be less than Int.NATIVE_MAX.    *!    */    PIKEFUN Buffer add_hint( object|int i, int len_width )    { -  Buffer *io = CHECK_DESTRUCTED(THIS); +     int width;    pop_stack(); /* width */    if( TYPEOF(*i) == PIKE_T_INT )    {    INT_TYPE ui = i->u.integer;    if (!ui) { -  io_add_int( io, 0, len_width ); +  io_add_int( THIS, 0, len_width );    } else {    for( width=1; width<SIZEOF_INT_TYPE; width++ )    if( ui < (((INT_TYPE)1)<<(width*8)) &&    ui >= -(((INT_TYPE)1)<<(width*8-1)) )    break; -  io_add_int( io, width, len_width ); -  io_add_int( io, i->u.integer, width ); +  io_add_int( THIS, width, len_width ); +  io_add_int( THIS, i->u.integer, width );    }    Pike_sp--;    }    else    {    convert_stack_top_to_bignum();    width = (mpz_sizeinbase( (void*)i->u.object->storage, 2)+7)/8; -  io_add_int( io, width, len_width ); -  io_add_bignum( io, i->u.object, width ); +  io_add_int( THIS, width, len_width ); +  io_add_bignum( THIS, i->u.object, width );    pop_stack(); /* o. */    }    ref_push_object(Pike_fp->current_object);    }       /*! @decl Buffer add_ints( array(int) integers, int(8bit) len )    *!    *! Add the integers in the specified array, @[len] bytes per int.    *! Equivalent to calling @[add_int] for each integer, but faster,    *! and if an error occurs the buffer will contain no new    *! data. Either all or none of the integers will be added.    *!    *! Errors can occur if one of the elements in @[integers] is not    *! actually an integer, if sizeof(integers)*len is bigger than can    *! be represented in a size_t, or if the buffer cannot grow due to    *! an out of memory condition.    */    PIKEFUN Buffer add_ints( array(int) a, int bpi )    { -  Buffer *io = CHECK_DESTRUCTED(THIS); +     int i,l = a->size;    struct svalue *it = a->item;    unsigned char *ptr;    ptrdiff_t n=0;    ONERROR e; -  +  Buffer *io = THIS;       io_unwrite_on_error(io, &e);       if( bpi < 0 )    Pike_error("Illegal int width.\n");      #if SIZEOF_LONG == 4    if( DO_INT32_MUL_OVERFLOW( l, bpi, &n ) )   #else    if( DO_INT64_MUL_OVERFLOW( l, bpi, &n ) )
pike.git/src/modules/_Stdio/buffer.cmod:1545:    *!    *! Return the character at the specified offset.    *!    *! @returns    *! Returns the character at offset @[off] on success,    *! and @expr{-1@} otherwise.    */    PIKEFUN int(8bit) `[]( int off )    flags ID_PROTECTED;    { -  Buffer *io = CHECK_DESTRUCTED(THIS); +  Buffer *io = THIS;    if( off < 0 )    off = io_len(io)-off;       if( io_avail( io, off ) )    Pike_sp[-1].u.integer = io_read_pointer(io)[off];    else    Pike_sp[-1].u.integer = -1;    }       /*! @decl protected void `[]=(int off, int char)    *!    *! Set the character at the specified offset to @[char].    */    PIKEFUN void `[]=( int off, int val )    flags ID_PROTECTED;    { -  Buffer *io = CHECK_DESTRUCTED(THIS); +  Buffer *io = THIS;       io_ensure_malloced( io, 0 );       if( off < 0 ) off = io_len(io)-off;    again:    if( io_avail( io, off ) )    {    io_read_pointer(io)[off]=(val&0xff);    }    else
pike.git/src/modules/_Stdio/buffer.cmod:1589:    }       /*! @decl int _sizeof()    *!    *! Returns the buffer size, in bytes.    *! This is how much you can read from the buffer until it runs out of data.    */    PIKEFUN int(0..) _sizeof()    flags ID_PROTECTED;    { -  Buffer *io = CHECK_DESTRUCTED(THIS); -  push_ulongest(io_len(io)); +  push_ulongest(io_len(THIS));    }       /*! @decl string(8bit) cast("string")    *!    *! Convert the buffer to a string.    *!    *!@note    *! This only works for buffers whose length is less than 0x7fffffff.    */    PIKEFUN string(8bit) cast(string to)    flags ID_PROTECTED;    { -  Buffer *io = CHECK_DESTRUCTED(THIS); +     if( to != literal_string_string )    {    push_undefined();    return;    } -  if( io_len(io) > 0x7fffffff ) +  if( io_len(THIS) > 0x7fffffff )    Pike_error("This buffer is too large to convert to a string.\n"); -  push_string(make_shared_binary_string((void*)io_read_pointer(io), -  (INT32)io_len(io))); +  push_string(make_shared_binary_string((void*)io_read_pointer(THIS), +  (INT32)io_len(THIS)));    }          /*! @decl Buffer set_error_mode(int m)    *! @decl Buffer set_error_mode(program m)    *!    *! Set the error mode of this buffer to @[m].    *!    *! If true operations that would normally return 0 (like trying to    *! read too much) will instead throw an error. If @[m] is a program
pike.git/src/modules/_Stdio/buffer.cmod:1668:    *! int num_headers = pack->read_int32();    *! for( int i = 0; i<num_headers; i++ )    *! headers[pack->read_hstring(2)] = pack->read_hstring(2);    *! ...    *! }    *! }    *! @endcode    */    PIKEFUN Buffer set_error_mode( int|program m )    { -  Buffer *io = CHECK_DESTRUCTED(THIS); +     if( TYPEOF(*m) == PIKE_T_INT ) -  io_set_error_mode( io, m->u.integer ? buffer_error_program : 0 ); +  io_set_error_mode( THIS, m->u.integer ? buffer_error_program : 0 );    else -  io_set_error_mode( io, program_from_svalue(m)); +  io_set_error_mode( THIS, program_from_svalue(m));       pop_stack();    ref_push_object(Pike_fp->current_object);    }       /*! @decl object lock()    *!    *! Makes this buffer read only until the returned object is released.    *!    *! @note    *! This currently simply returns a 0-length subbuffer.    */    PIKEFUN Buffer lock()    { -  Buffer *io = CHECK_DESTRUCTED(THIS); -  push_object( io_read_buffer( io, 0, 0 ) ); +  push_object( io_read_buffer( THIS, 0, 0 ) );    }       PIKEFUN string(8bit) _sprintf(int o, mapping|void UNUSED)    flags ID_PROTECTED;    { -  Buffer *io = CHECK_DESTRUCTED(THIS); +     size_t bytes;    pop_n_elems(args-1);    Pike_sp--;    switch( o )    {    case 'O':    {    push_static_text("%O(%d bytes, read=[..%d] data=[%d..%d] free=[%d..%d] %s%s)");    ref_push_program(Pike_fp->current_object->prog);    /* io_len [..offset] [offset..len] [..allocated] */ -  push_int(io_len(io)); -  push_int(io->offset-1); -  push_int(io->offset); +  push_int(io_len(THIS)); +  push_int(THIS->offset-1); +  push_int(THIS->offset);    -  push_int(io->len-1); -  push_int(io->len); -  push_int(io->allocated); -  push_static_text( (io->str ? "string" : io->malloced ? "allocated" : "subbuffer" ) ); -  if( io->locked ) +  push_int(THIS->len-1); +  push_int(THIS->len); +  push_int(THIS->allocated); +  push_static_text( (THIS->str ? "string" : THIS->malloced ? "allocated" : "subbuffer" ) ); +  if( THIS->locked )    push_static_text(" (read only)");    else    push_static_text("");    f_sprintf(10);    }    break;       case 's': -  bytes = io_len(io); -  io->locked_move++; -  push_string( io_read_string(io, bytes) ); -  io_rewind(io, bytes); -  io->locked_move--; +  bytes = io_len(THIS); +  THIS->locked_move++; +  push_string( io_read_string(THIS, bytes) ); +  io_rewind(THIS, bytes); +  THIS->locked_move--;    break;       case 'q':    push_static_text("%q"); -  bytes = io_len(io); -  io->locked_move++; -  push_string( io_read_string(io, bytes) ); -  io_rewind(io, bytes); -  io->locked_move--; +  bytes = io_len(THIS); +  THIS->locked_move++; +  push_string( io_read_string(THIS, bytes) ); +  io_rewind(THIS, bytes); +  THIS->locked_move--;    f_sprintf(2);    break;    default:    push_undefined();    }    }       /*! @decl string(8bit) read_hstring( int(0..) n, void|int offset )    *!    *! Identical in functionality to @[read](@[read_number](@[n])) but
pike.git/src/modules/_Stdio/buffer.cmod:1761:    *! @[offset] is substracted from the specified length prior to reading the    *! string. Typical usage involves substracting @[n] to account    *! for the room used by the size.    *!    *! If there is not enough data available return 0.    *!    *! Note that pike string can not be longer than 0x7fffffff bytes (~2Gb).    */    PIKEFUN string(8bit) read_hstring( int bytes, void|int offset )    { -  Buffer *io = CHECK_DESTRUCTED(THIS); +     INT64 len; -  +  Buffer *io = THIS;    struct pike_string *s;    ONERROR e;       io_rewind_on_error( io, &e );    len = io_read_number( io, bytes, 1 );       if (offset)    len -= offset->u.integer;       if (len < 0) {
pike.git/src/modules/_Stdio/buffer.cmod:1819:    *!    *! @note    *! Escape characters (if any) are left untouched in the returned string.    *!    *! @seealso    *! @[_search()]    */    PIKEFUN string(8bit) read_cstring(void|int(8bit) sentinel,    void|int(8bit) escape)    { -  Buffer *io = CHECK_DESTRUCTED(THIS); +  Buffer *io = THIS;    int csentinel = sentinel ? sentinel->u.integer : 0;       if (!escape || (escape->u.integer == csentinel)) {    do {    if ( LIKELY(io_len(io)) )    {    const char * start = (char*)io_read_pointer(io);    const char * end = memchr(start, csentinel, io_len(io));       if ( LIKELY(end) )
pike.git/src/modules/_Stdio/buffer.cmod:1907:    *! on not found. The read position is not advanced.    *!    *! @seealso    *! @[read_cstring()], @[search()], @[lfun::_search()]    */    PIKEFUN int(-1..) _search(int character, int|void start, int|void end)    flags ID_PROTECTED;    rawtype tFunc(tInt8bit tOr(tInt, tVoid) tOr(tIntPos, tVoid),    tOr(tInt_10, tIntPos));    { -  Buffer *io = CHECK_DESTRUCTED(THIS); +  Buffer *io = THIS;    unsigned char *buf = io_read_pointer(io);    unsigned char *buf_end = buf + io_len(io);       if (end) {    INT_TYPE bytes = end->u.integer;       if (bytes < 0) {    push_int(-1);    return;    }
pike.git/src/modules/_Stdio/buffer.cmod:1977:    *! Returns the first found position of @[substring] relative to the    *! current read position of the buffer on success, and @[UNDEFINED]    *! on not found. The read position is not advanced.    *!    *! @seealso    *! @[read_cstring()], @[search()], @[lfun::_search()]    */    PIKEFUN int _search(string(8bit) substring, int|void start, int|void end)    flags ID_PROTECTED;    { -  Buffer *io = CHECK_DESTRUCTED(THIS); +  Buffer *io = THIS;    unsigned char *buf = io_read_pointer(io);    unsigned char *buf_end = buf + io_len(io);    SearchMojt mojt;       if (end) {    INT_TYPE bytes = end->u.integer;       if (bytes < 0) {    push_int(-1);    return;
pike.git/src/modules/_Stdio/buffer.cmod:2052:    *!    *! Usually this is OK, since it often represents something that    *! should be parsed before the next whatever is extracted from    *! the buffer, but do take care.    *!    *! If you need to unlink the new buffer after it has been    *! created, call @[trim] in it.    */    PIKEFUN Buffer read_hbuffer( int bytes, int|void copy )    { -  Buffer *io = CHECK_DESTRUCTED(THIS); +     INT64 len;    int do_copy = 0; -  +  Buffer *io = THIS;    ONERROR e;       io_rewind_on_error( io, &e );       if( copy ) do_copy = copy->u.integer;    Pike_sp-=args;       len = io_read_number( io, bytes, 1 );    if( len >= 0 && io_avail( io, len ) )    {
pike.git/src/modules/_Stdio/buffer.cmod:2090:    *!    *! @note    *! As long as the subbuffer exists no data can be added to the main buffer.    *!    *! Usually this is OK, since it often represents something that    *! should be parsed before the next whatever is extracted from    *! the buffer, but do take care.    */    PIKEFUN Buffer read_buffer( int bytes, int|void copy )    { -  Buffer *io = CHECK_DESTRUCTED(THIS); +     int do_copy = 0;    struct object *o;    if( copy )    do_copy = copy->u.integer;    Pike_sp-=args; -  if( (o = io_read_buffer( io, bytes, do_copy )) ) +  if( (o = io_read_buffer( THIS, bytes, do_copy )) )    push_object(o);    else    push_int(0);    }       /*! @decl Buffer sprintf(strict_sprintf_format format, sprintf_args ... args)    *!    *! Appends the output from @[sprintf] at the end of the buffer.    *!    *! This is somewhat faster than add(sprintf(...)) since no    *! intermediate string is created.    */    PIKEFUN Buffer sprintf(mixed ... ignored)    rawtype tFuncV(tAttr("strict_sprintf_format", tOr(tStr, tObj)),    tAttr("sprintf_args", tMix), tObjIs_BUFFER);    { -  Buffer *io = CHECK_DESTRUCTED(THIS); +     ONERROR _e;    struct string_builder tmp;    init_string_builder(&tmp,0);    SET_ONERROR(_e, free_string_builder, &tmp);    low_f_sprintf(args, &tmp);    if( tmp.s->size_shift )    Pike_error("Buffer only handles 8bit data.\n"); -  io_append( io, tmp.s->str, tmp.s->len ); +  io_append( THIS, tmp.s->str, tmp.s->len );    pop_n_elems(args);    CALL_AND_UNSET_ONERROR(_e);    ref_push_object(Pike_fp->current_object);    }       /*! @decl array sscanf(string(8bit) format)    *!    *! Reads data from the beginning of the buffer to match the    *! specifed format, then return an array with the matches.    *!    *! The non-matching data will be left in the buffer.    *!    *! See @[array_sscanf] for more information.    */    PIKEFUN array sscanf( string(8bit) format )    { -  Buffer *io = CHECK_DESTRUCTED(THIS); +     INT32 i;    ptrdiff_t num_used;    struct svalue *start = Pike_sp;    retry:    i = low_sscanf_pcharp( -  MKPCHARP(io_read_pointer(io), 0), io_len(io), +  MKPCHARP(io_read_pointer(THIS), 0), io_len(THIS),    MKPCHARP(format->str,format->size_shift), format->len,    &num_used);       if( !num_used )    { -  if( io_range_error(io,0) ) +  if( io_range_error(THIS,0) )    goto retry;    pop_n_elems(Pike_sp-start);    push_int(0);    }    else    { -  io_consume( io, num_used ); +  io_consume( THIS, num_used );    f_aggregate(Pike_sp-start);    }    }          /*! @decl mixed read_json(int|void require_whitespace_separator)    *!    *! Read a single JSON expression from the buffer and return it.    *!    *! If @[require_whitespace_separator] is true there must be a whitespace
pike.git/src/modules/_Stdio/buffer.cmod:2185:    *!    *! @note    *! Unless whitespaces are required this function only really work correctly    *! with objects, arrays and strings.    *!    *! There is really no way to see where one value starts and the other ends    *! for most other cases    */    PIKEFUN mixed read_json(int|void require_whitespace)    { -  Buffer *io = CHECK_DESTRUCTED(THIS); +     INT_TYPE whites = 0;    ptrdiff_t stop;    static ptrdiff_t(*parse_json_pcharp)(PCHARP,size_t,int,char**);    char *err = NULL;    if( require_whitespace )    whites = require_whitespace->u.integer;       Pike_sp-=args;    if( !parse_json_pcharp )    parse_json_pcharp = PIKE_MODULE_IMPORT(Standards.JSON, parse_json_pcharp );    retry: -  stop = parse_json_pcharp( MKPCHARP(io_read_pointer(io),0), -  io_len(io), 1|8, &err ); /* json_utf8 */ +  stop = parse_json_pcharp( MKPCHARP(io_read_pointer(THIS),0), +  io_len(THIS), 1|8, &err ); /* json_utf8 */       if( stop < 0 )    { -  if( -stop == (ptrdiff_t)io_len(io) || (err && !strncmp(err,"Unterminated",12))) +  if( -stop == (ptrdiff_t)io_len(THIS) || (err && !strncmp(err,"Unterminated",12)))    { -  if( io_range_error(io,0) ) +  if( io_range_error(THIS,0) )    goto retry;    push_undefined();    }    else    {    /* FIXME: Use real json error? */    if( err )    Pike_error("Syntax error in json at offset %d: %s,\n", -stop, err );    else    Pike_error("Syntax error in json at offset %d.\n", -stop );    }    }    else    {    if( whites && -  (io_is_whitespace(io,stop)<=0 && io_is_whitespace(io,stop-1)<=0)) +  (io_is_whitespace(THIS,stop)<=0 && io_is_whitespace(THIS,stop-1)<=0))    { -  if( stop == (ptrdiff_t)io_len(io) ) +  if( stop == (ptrdiff_t)io_len(THIS) )    { -  if( io_range_error(io,0) ) +  if( io_range_error(THIS,0) )    goto retry;    pop_stack();    push_undefined();    }    else    Pike_error("Missing whitespace between json values at offset %d.\n", stop );    }    else    {    if( whites ) -  while( io_is_whitespace( io, stop ) ) +  while( io_is_whitespace( THIS, stop ) )    stop++; -  io_consume( io, stop ); +  io_consume( THIS, stop );    }    }    }       /*! @decl mixed match(string(8bit) format)    *!    *! Reads data from the beginning of the buffer to match the    *! specifed format, then return the match.    *!    *! The non-matching data will be left in the buffer.
pike.git/src/modules/_Stdio/buffer.cmod:2261:    *! a single value.    *!    *! @example    *! @code    *! // get the next whitespace separated word from the buffer.    *! buffer->match("%*[ \t\r\n]%[^ \t\r\n]");    *! @endcode    */    PIKEFUN string(8bit)|int|float|array match( string(8bit) format )    { -  Buffer *io = CHECK_DESTRUCTED(THIS); +     INT32 i;    ptrdiff_t num_used;    struct svalue *start = Pike_sp;    retry:    i = low_sscanf_pcharp( -  MKPCHARP(io_read_pointer(io), 0), io_len(io), +  MKPCHARP(io_read_pointer(THIS), 0), io_len(THIS),    MKPCHARP(format->str,format->size_shift), format->len,    &num_used);       if( !num_used )    { -  if( io_range_error(io,0) ) +  if( io_range_error(THIS,0) )    goto retry;    pop_n_elems(Pike_sp-start);    push_int(0);    }    else    { -  io_consume( io, num_used ); +  io_consume( THIS, num_used );    if( Pike_sp-start > 1 )    f_add(Pike_sp-start);    }    }       /*! @decl void clear()    *!    *! Clear the buffer.    */    PIKEFUN void clear( )    { -  Buffer *io = CHECK_DESTRUCTED(THIS); +  Buffer *io = THIS;    io->offset = io->len = 0;    }       /*! @decl void set_max_waste(float factor)    *!    *! Configure how much free space should be allowed, at most, as a    *! factor of the current buffer size.    *!    *! The default is 0.5, leaving at most half the buffer as waste.    *!    */    PIKEFUN void set_max_waste(float howmuch)    { -  Buffer *io = CHECK_DESTRUCTED(THIS); +  Buffer *io = THIS;    io->max_waste = howmuch;    io_add_space( io, 0, 1 );    io_trim_waste( io );    }       /*! @decl void trim()    *!    *! Frees unused memory.    *!    *! Note that calling this function excessively will slow things    *! down, since the data often has to be copied.    *!    *! @note    *! This function could possibly throw an out-of-memory error    *! if the realloc fails to find a new (smaller) memory area.    */    PIKEFUN void trim( )    { -  Buffer *io = CHECK_DESTRUCTED(THIS); +  Buffer *io = THIS;       io_add_space( io, 0, 1 );    io_trim(io);    }       /*! @decl void allocate( int(0..) n )    *!    *! Make sure that at least @[n] bytes of space are available in this buffer.    */    PIKEFUN void allocate( int n )    { -  Buffer *io = CHECK_DESTRUCTED(THIS); +  Buffer *io = THIS;    Pike_sp--;    if (!n) return;    if (n < 0)    SIMPLE_BAD_ARG_ERROR("allocate()", 1, "int(0..1)");    io_add_space(io, n, 0);    }       /*! @decl int(0..)|int(-1..-1) consume( int(0..) n )    *!    *! Discard the first @[n] bytes from the buffer    *!    *! Returns -1 on error and the amount of space still left otherwise.    */    PIKEFUN int(-1..) consume( int n )    { -  Buffer *io = CHECK_DESTRUCTED(THIS); +     Pike_sp--; -  if( !io_avail( io, n ) ) +  if( !io_avail( THIS, n ) )    push_int(-1);    else -  push_int64( io_consume( io, n ) ); +  push_int64( io_consume( THIS, n ) );    }       /*! @decl int(0..)|int(-1..-1) truncate( int(0..) n )    *!    *! Truncates the buffer to a length of @[n] bytes.    *!    *! Returns -1 on error and the number of bytes removed otherwise.    */    PIKEFUN int(-1..) truncate( int(0..) n )    { -  Buffer *io = CHECK_DESTRUCTED(THIS); +  Buffer *io = THIS;    ptrdiff_t diff = io_len(io) - n;    Pike_sp--;       if( diff < 0 || io_len(io) < (size_t)diff )    push_int(-1);    else {    io->len -= diff;    push_int64( diff );    }    }
pike.git/src/modules/_Stdio/buffer.cmod:2399:    *!    *! @note    *!    *! Unless you add new data to the buffer using any of the add    *! functions you can always rewind.    *!    *! You can call @[unread(0)] to see how much.    */    PIKEFUN int(-1..) unread( int bytes )    { -  Buffer *io = CHECK_DESTRUCTED(THIS); +     Pike_sp--; -  push_int64( io_rewind( io, bytes ) ); +  push_int64( io_rewind( THIS, bytes ) );    }       /*! @decl string(8bit) read( int n )    *!    *! Read @[n] bytes of data from the buffer.    *!    *! If there is not enough data available this returns 0.    *!    *! @seealso    *! @[try_read()]    */    PIKEFUN string(8bit) read( int bytes )    { -  Buffer *io = CHECK_DESTRUCTED(THIS); +     struct pike_string *s;    Pike_sp--; -  s = io_read_string(io, bytes ); +  s = io_read_string(THIS, bytes );    if( s )    push_string( s );    else    push_undefined();    }       /*! @decl string(8bit) read( )    *!    *! Read all data from the buffer.    *!    *! If there is not enough data available this returns 0.    *!    *! This is basically equivalent to (string)buffer, but it also    *! removes the data from the buffer.    *!    *! @seealso    *! @[try_read()]    */    PIKEFUN string(8bit) read()    { -  Buffer *io = CHECK_DESTRUCTED(THIS); -  push_string( io_read_string(io, io_len(io)) ); +  push_string( io_read_string(THIS, io_len(THIS)) );    }       /*! @decl string(8bit) try_read(int len)    *!    *! Attempt to read some data from the buffer.    *!    *! @param len    *! Read at most @[len] bytes from the buffer.    *!    *! @returns    *! If the buffer contains less than @[len] bytes    *! of data, the entire buffer contents are returned.    *! Otherwise the first @[len] bytes are returned.    *!    *! @seealso    *! @[read()]    */    PIKEFUN string(8bit) try_read( int bytes )    { -  Buffer *io = CHECK_DESTRUCTED(THIS); +  Buffer *this = THIS;    struct pike_string *s;    Pike_sp--;    /* Hm. signed/unsigned comparisons abound. */ -  if( bytes > 0 && (size_t)bytes > io_len(io) ) -  bytes = io_len(io); -  push_string( io_read_string(io, bytes ) ); +  if( bytes > 0 && (size_t)bytes > io_len(this) ) +  bytes = io_len(this); +  push_string( io_read_string(this, bytes ) );    }       /*! @decl int(8bit) read_int8()    */    PIKEFUN int(8bit) read_int8( )    { -  Buffer *io = CHECK_DESTRUCTED(THIS); +  Buffer *io = THIS;    if( LIKELY(io_avail( io, 1 )) )    push_int( io_read_byte_uc(io) );    else    push_int(-1);    }       /*! @decl int(16bit) read_int16()    */    PIKEFUN int(0..65535) read_int16( )    { -  Buffer *io = CHECK_DESTRUCTED(THIS); +  Buffer *io = THIS;    if( LIKELY(io_avail( io, 2 )) )    push_int( io_read_number_uc(io,2) );    else    push_int(-1);    }       /*! @decl int(24bit) read_int24()    */    PIKEFUN int(0..16777215) read_int24( )    { -  Buffer *io = CHECK_DESTRUCTED(THIS); +  Buffer *io = THIS;    if( LIKELY(io_avail( io, 3 )) )    push_int( io_read_number_uc(io,3) );    else    push_int(-1);    }       /*! @decl int(32bit) read_int32()    */    PIKEFUN int(0..4294967295) read_int32( )    { -  Buffer *io = CHECK_DESTRUCTED(THIS); +  Buffer *io = THIS;    if( LIKELY(io_avail( io, 4 )) )    {    push_int( io_read_number_uc(io,4) );   #if SIZEOF_INT_TYPE < 5    if( UNLIKELY(Pike_sp[-1].u.integer < 0) )    {    io_rewind( io, 4 );    pop_stack();    push_object( io_read_bignum(io, 4, 1) );    }
pike.git/src/modules/_Stdio/buffer.cmod:2536:    *! return it.    *!    *! Will return -1 if there is not enough buffer space available    *! unless error mode is set to throw errors.    *!    *! @seealso    *! @[read_le_int]    */    PIKEFUN int(0..) read_int( int len )    { -  Buffer *io = CHECK_DESTRUCTED(THIS); +  Buffer *io = THIS;    struct object *o;       Pike_sp--;       if( len < SIZEOF_INT_TYPE ) /* will for sure fit. */    {    push_int( io_read_number( io, len, 1 ) );    return;    }   
pike.git/src/modules/_Stdio/buffer.cmod:2569:    *! then return it.    *!    *! Will return -1 if there is not enough buffer space available    *! unless error mode is set to throw errors.    *!    *! @seealso    *! @[read_int]    */    PIKEFUN int(0..) read_le_int( int len )    { -  Buffer *io = CHECK_DESTRUCTED(THIS); +  Buffer *io = THIS;    struct object *o;       Pike_sp--;       if( len < SIZEOF_INT_TYPE ) /* will for sure fit. */    {    push_int( io_read_number( io, len, 0 ) );    return;    }   
pike.git/src/modules/_Stdio/buffer.cmod:2600:    *!    *! Read a network byte order unsigned number of size n*8 bits, then    *! read another network byte order number of the size indicated by    *! the first size.    *!    *! Will return -1 if there is not enough buffer space available    *! unless error mode is set to throw errors.    */    PIKEFUN int(0..) read_hint( int size_len )    { -  Buffer *io = CHECK_DESTRUCTED(THIS); +  Buffer *io = THIS;    ONERROR e;    INT_TYPE len;    struct object *o;       io_rewind_on_error( io, &e );       len = io_read_number( io, size_len, 1 );    if( len >= 0 )    {    if( len < SIZEOF_INT_TYPE )
pike.git/src/modules/_Stdio/buffer.cmod:2641:    /*! @decl array(int) read_ints( int n, int width )    *!    *! Read a list of @[n] network byte order unsigned numbers each of    *! size @[width]*8 bits, then return it.    *!    *! Will return 0 if there is not enough buffer space available    *! unless error mode is set to throw errors.    */    PIKEFUN array(int(0..)) read_ints( int num, int len )    { -  Buffer *io = CHECK_DESTRUCTED(THIS); +  Buffer *io = THIS;    INT_TYPE i;    struct object *o;    struct array *a;       Pike_sp-=2;       if( !io_avail_mul( io, num, len ) )    {    push_int(0);    return;
pike.git/src/modules/_Stdio/buffer.cmod:2678:    }      /*! @decl string(8bit) _encode()    *! @decl void _decode(string(8bit) x)    *!    *! Encode and decode Stdio.Buffer objects.    *! Only the buffer data is kept, no other state is saved.    */    PIKEFUN string _encode()    { -  Buffer *io = CHECK_DESTRUCTED(THIS); -  push_string(io_read_string(io, io_len(io))); +  push_string(io_read_string(THIS, io_len(THIS)));    }       PIKEFUN void _decode(string(8bit) x)    { -  Buffer *io = CHECK_DESTRUCTED(THIS); -  if( io->buffer ) +  Buffer *this = THIS; +  if( this->buffer )    Pike_error("Can not initialize twice.\n");    if( x->size_shift )    Pike_error("Can not handle non-8bit data.\n"); -  io->buffer = (unsigned char*)x->str; -  io->len = x->len; -  io->malloced = 0; -  io->str = x; +  this->buffer = (unsigned char*)x->str; +  this->len = x->len; +  this->malloced = 0; +  this->str = x;    add_ref(x);    }       /*! @decl void read_only()    *!    *! Make the buffer permanently read only.    *! @note    *! You can use lock() to do this temporarily.    */    PIKEFUN void read_only()    { -  Buffer *io = CHECK_DESTRUCTED(THIS); -  io_lock( io ); +  io_lock( THIS );    }          static struct object* io_create_rewind_key( Buffer *io, int how );       /*! @decl RewindKey rewind_on_error()    *! @decl RewindKey rewind_key()    *!    *! These functions are very similar. The @[rewind_on_error] variant    *! will create an object that, when it goes out of scope without
pike.git/src/modules/_Stdio/buffer.cmod:2771:    *! Just calling @[rewind_on_error] without assigning the return    *! value to something will not do anything. You need to keep the    *! object around while the rewind-to position is still valid.    *!    *! Keeping the object around forbids the buffer from moving data    *! inside itself, this means that it can only grow. So do not keep    *! the rewind key when it is not needed.    */    PIKEFUN object(Buffer.RewindKey) rewind_on_error()    { -  Buffer *io = CHECK_DESTRUCTED(THIS); -  push_object( io_create_rewind_key( io, 1 ) ); +  push_object( io_create_rewind_key( THIS, 1 ) );    }       PIKEFUN object(Buffer.RewindKey) rewind_key()    { -  Buffer *io = CHECK_DESTRUCTED(THIS); -  push_object( io_create_rewind_key( io, 0 ) ); +  push_object( io_create_rewind_key( THIS, 0 ) );    }       /*! @decl void create( int|void len )    *! @decl void create( string(8bit) contents )    *! @decl void create( System.Memory|String.Buffer contents )    *!    *! If passed an integer or no argument, create a buffer of that    *! size, or if no argument is given, 226 bytes.    *!    *! If @[contents] are specified a new buffer with the contents of
pike.git/src/modules/_Stdio/buffer.cmod:2812:    *! However, as an example, if the buffer is created with a 100Gb    *! @[System.Memory] mmap:ed file as the @[contents] and you later on    *! try to modify the buffer using one of the @[add] functions (or    *! @[sprintf] and similar) the old contents @b{will@} be copied.    *!    *! You can use @[read_only()] to avoid accidents.    */    PIKEFUN void create( int|void|string(8bit)|object|array x )    flags ID_PROTECTED;    { -  Buffer *io = CHECK_DESTRUCTED(THIS); -  if( io->buffer ) +  Buffer *this = THIS; +  if( this->buffer )    Pike_error("Can not initialize twice.\n");    if( !x )    { -  io->buffer = xalloc(256-32); -  io->allocated = 256-32; -  io->malloced = 1; +  this->buffer = xalloc(256-32); +  this->allocated = 256-32; +  this->malloced = 1;    }    else if( TYPEOF(*x) == PIKE_T_INT )    {    INT_TYPE len = x->u.integer;    if( len <= 0 ) -  io->buffer = xalloc(1); +  this->buffer = xalloc(1);    else -  io->buffer = xalloc(len); -  io->allocated = MAXIMUM(len,1); -  io->malloced = 1; +  this->buffer = xalloc(len); +  this->allocated = MAXIMUM(len,1); +  this->malloced = 1;    pop_stack();    }    else    { -  io_append_svalue( io, x ); +  io_append_svalue( THIS, x );    pop_stack();    }    }       INIT { -  Buffer *io = THIS; -  io->max_waste = 0.615; -  io->this = Pike_fp->current_object; +  Buffer *this = THIS; +  this->max_waste = 0.615; +  this->this = Pike_fp->current_object;    }       EXIT { -  Buffer *io = THIS; -  io_unlink_external_storage( io ); -  if( io->error_mode ) -  free_program( io->error_mode ); -  if( io->malloced ) -  free( io->buffer ); +  Buffer *this = THIS; +  io_unlink_external_storage( this ); +  if( this->error_mode ) +  free_program( this->error_mode ); +  if( this->malloced ) +  free( this->buffer );    }         /*! @class RewindKey    *!    *! The return value of @[Buffer.rewind_on_error()] and    *! @[Buffer.rewind_key()]    *!    *! This object will cause the buffer to unwind to the position it was    *! at when the object was created either when it is released (when it