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

version» Context lines:

pike.git/src/modules/_Stdio/buffer.cmod:466:       push_int64( howmuch );    apply_current( f_IOBuffer_range_error_fun_num, 1 );    res = Pike_sp[-1].u.integer;    pop_n_elems( Pike_sp-osp );    if( !res ) io_range_error_throw( io, howmuch );       return res;    }    -  static int io_avail_rewind( IOBuffer *io, ptrdiff_t len ) +  static int io_avail( IOBuffer *io, ptrdiff_t len )    { -  ptrdiff_t left; - #ifdef PIKE_DEBUG -  if (len < 0) Pike_fatal("IOBuffer.io_avail_rewind: len<0.\n"); - #endif -  while( UNLIKELY((left = io->offset - len) < 0) ) -  if( !io_range_error( io, left ) ) +  if( len < 0 || len + io->offset > io->len ) +  { +  if( len < 0 ) +  io_range_error_throw( io, 0 ); +  else if( io_range_error( io, len+io->len-io->offset ) ) +  return io_avail(io,len);    return 0; -  +  }    return 1;    }    -  static int io_avail( IOBuffer *io, ptrdiff_t len ) +  static int io_avail_mul( IOBuffer *io, ptrdiff_t len, ptrdiff_t each )    { -  ptrdiff_t left; - #ifdef PIKE_DEBUG -  if (len < 0) Pike_fatal("IOBuffer.io_avail: len<0.\n"); - #endif -  while( UNLIKELY((left = len - io->len + io->offset) > 0) ) -  if( !io_range_error( io, left ) ) +  /* safely check if len*each is available. */ +  size_t total = io_len(io); +  if( len < 0 || each <= 0 ) +  { +  io_range_error_throw( io, 0 );    return 0; -  return 1; +     }    -  static int io_avail_mul( IOBuffer *io, ptrdiff_t len, ptrdiff_t each ) +  if( (total/(size_t)each) < (size_t)len )    { -  /* safely check if len*each is available. */ -  ptrdiff_t left; - #ifdef PIKE_DEBUG -  if (len < 0 ) Pike_fatal("IOBuffer.io_avail_mul: len<0.\n"); -  if (each <= 0 ) Pike_fatal("IOBuffer.io_avail_mul: each<=0.\n"); - #endif -  while( UNLIKELY((left = len*each -io->len+io->offset) > 0) ) -  if( !io_range_error( io, left ) ) +  if( io_range_error( io, len+io->len-io->offset ) ) +  return io_avail_mul(io,len,each);    return 0; -  +  }    return 1;    }       static void io_append( IOBuffer *io, const void *p, int bytes )    {    memcpy( io_add_space( io, bytes, 0 ), p, bytes );    io->len += bytes;    io_trigger_output( io );    }   
pike.git/src/modules/_Stdio/buffer.cmod:567:    }       static int io_read_byte_uc( IOBuffer *io )    {    return io->buffer[io->offset++];    }       static INT_TYPE io_read_number_uc( IOBuffer *io, size_t len )    {    size_t i; -  LONGEST res; - #ifdef PIKE_DEBUG -  if (len < 1 ) Pike_fatal("IOBuffer.io_read_number_uc: len<1.\n"); - #endif -  res = io_read_byte_uc(io); -  for( i=0; ++i<len; ) +  LONGEST res = 0; +  for( i=0; i<len; i++ )    {    res <<= 8;    res |= io_read_byte_uc(io);    }    return res;    }       static LONGEST io_read_number( IOBuffer *io, size_t len )    {    size_t i;    LONGEST res; - #ifdef PIKE_DEBUG -  if (len < 1 ) Pike_fatal("IOBuffer.io_read_number: len<1.\n"); - #endif -  +  if( !io_avail(io, len) ) +  return -1;    if( len > SIZEOF_INT_TYPE )    {    unsigned int extra = len-SIZEOF_INT_TYPE;    /* ensure only 0:s */    for( i=0; i<extra; i++ )    {    if( io_read_byte_uc(io) )    Pike_error("Integer (%dbit) overflow.\n", SIZEOF_INT_TYPE*8);    }    len=SIZEOF_INT_TYPE;
pike.git/src/modules/_Stdio/buffer.cmod:667:    static size_t io_add_int( IOBuffer *io, ptrdiff_t i, size_t bytes )    {    unsigned char *x = io_add_space(io, bytes, 0);    io_add_int_uc( io, i, bytes );    io_trigger_output( io );    return io_len( io );    }       static size_t io_rewind( IOBuffer *io, INT_TYPE n )    { +  if( n < 0 || (io->offset < (unsigned)n) ) +  { +  if( n < 0 ) +  io_range_error_throw( io, 0 ); +  else if( io_range_error(io,-(long)(n-io->offset)) ) +  return io_rewind( io, n ); +  return -1; +  }    io->offset -= n;    io_trigger_output( io );    return io->offset;    }       static void io_append_byte_uc( IOBuffer *io, unsigned char byte )    {    io->buffer[io->len++] = byte;    }   
pike.git/src/modules/_Stdio/buffer.cmod:1428:    *!    *! Note that pike string can not be longer than 0x7fffffff bytes (~2Gb).    */    PIKEFUN string(0..255) read_hstring( int bytes )    {    LONGEST len;    IOBuffer *io = THIS;    struct pike_string *s;    ONERROR e;    -  Pike_sp--; +  io_rewind_on_error( io, &e ); +  len = io_read_number( io, bytes );    -  if (UNLIKELY(bytes<=0)) { -  if (UNLIKELY(bytes)) -  goto fai2; -  push_empty_string(); +  if (len < 0) { +  /* io_avail() in io_read_number() failed. */ +  CALL_AND_UNSET_ONERROR(e); +  Pike_sp[-1].u.integer = 0;    return;    }    -  io_rewind_on_error( io, &e ); -  -  if ( LIKELY(io_avail(io, bytes)) ) -  len = io_read_number( io, bytes ); -  else -  goto fail; -  +  /* NB: We assume that io_avail() in io_read_string() doesn't throw. */    s = io_read_string( io, len );       if( s ) { -  +     io_unset_rewind_on_error( io, &e ); -  +  Pike_sp--;    push_string(s); -  +     } else { - fail: CALL_AND_UNSET_ONERROR(e); - fai2: push_undefined(); +  CALL_AND_UNSET_ONERROR(e); +  Pike_sp[-1].u.integer = 0;    }    }       /*! @decl string(8bit) read_cstring( )    *!    *! Reads a \0 terminated C-string and returns the    *! string excluding the terminating \0.    *!    *! If there is not enough data available return UNDEFINED.    *!
pike.git/src/modules/_Stdio/buffer.cmod:1786:       /*! @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 )    {    Pike_sp--; -  if( n<0 || !io_avail( THIS, n ) ) +  if( !io_avail( THIS, n ) )    push_int(-1);    else    push_int64( io_consume( THIS, n ) );    }          /*! @decl int(0..)|int(-1..-1) unread( int(0..) n )    *!    *! Rewind the buffer @[n] bytes.    *!
pike.git/src/modules/_Stdio/buffer.cmod:1811:    *!    *! @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 )    { -  IOBuffer *io = THIS; +     Pike_sp--; -  -  if( UNLIKELY(bytes < 0) ) -  io_range_error_throw( io, 0 ); -  -  if( LIKELY(io_avail_rewind( io, bytes )) ) -  push_int64( io_rewind( io, bytes ) ); -  else -  push_int( -1 ); +  push_int64( io_rewind( THIS, bytes ) );    }       /*! @decl string(8bit) read( int n )    *!    *! Read @[bytes] bytes of data from the buffer.    *!    *! If there is not enough data available this returns 0.    */    PIKEFUN string(0..255) read( int bytes )    {
pike.git/src/modules/_Stdio/buffer.cmod:1953:    */    PIKEFUN array(int(0..)) read_ints( int num, int len )    {    IOBuffer *io = THIS;    INT_TYPE i;    struct object *o;    struct array *a;       Pike_sp-=2;    -  if( num<=0 || len<=0 || !io_avail_mul( io, num, len ) ) +  if( !io_avail_mul( io, num, len ) )    {    push_int(0);    return;    }       if( len < SIZEOF_INT_TYPE-1 ) /* will for sure fit. */    {    push_array(a = allocate_array(num));    for( i=0;i<num;i++ )    a->item[i].u.integer = io_read_number_uc( io, len );