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( IOBuffer *io, ptrdiff_t len ) +  static int io_avail_rewind( IOBuffer *io, ptrdiff_t len )    { -  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); +  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 ) )    return 0; -  } +     return 1;    }    -  static int io_avail_mul( IOBuffer *io, ptrdiff_t len, ptrdiff_t each ) +  static int io_avail( IOBuffer *io, ptrdiff_t len )    { -  /* safely check if len*each is available. */ -  size_t total = io_len(io); -  if( len < 0 || each <= 0 ) -  { -  io_range_error_throw( io, 0 ); +  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 ) )    return 0; -  +  return 1;    }    -  if( (total/(size_t)each) < (size_t)len ) +  static int io_avail_mul( IOBuffer *io, ptrdiff_t len, ptrdiff_t each )    { -  if( io_range_error( io, len+io->len-io->offset ) ) -  return io_avail_mul(io,len,each); +  /* 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 ) )    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:561:    }       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 = 0; -  for( i=0; i<len; 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; )    {    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; -  if( !io_avail(io, len) ) -  return -1; + #ifdef PIKE_DEBUG +  if (len < 1 ) Pike_fatal("IOBuffer.io_read_number: len<1.\n"); + #endif +     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:655:    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:1424:    *!    *! 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;    -  io_rewind_on_error( io, &e ); -  len = io_read_number( io, bytes ); +  Pike_sp--;    -  if (len < 0) { -  /* io_avail() in io_read_number() failed. */ -  CALL_AND_UNSET_ONERROR(e); -  Pike_sp[-1].u.integer = 0; +  if (UNLIKELY(bytes<=0)) { +  if (UNLIKELY(bytes)) +  goto fai2; +  push_empty_string();    return;    }    -  /* NB: We assume that io_avail() in io_read_string() doesn't throw. */ +  io_rewind_on_error( io, &e ); +  +  if ( LIKELY(io_avail(io, bytes)) ) +  len = io_read_number( io, bytes ); +  else +  goto fail; +     s = io_read_string( io, len );       if( s ) { -  +     io_unset_rewind_on_error( io, &e ); -  Pike_sp--; +     push_string(s); -  +     } else { -  CALL_AND_UNSET_ONERROR(e); -  Pike_sp[-1].u.integer = 0; + fail: CALL_AND_UNSET_ONERROR(e); + fai2: push_undefined();    }    }       /*! @decl IOBuffer read_hbuffer( int n )    *! @decl IOBuffer read_hbuffer( int n, bool copy )    *!    *! Same as @[read_hstring], but returns the result as an IOBuffer.    *!    *! No data is copied unless @[copy] is specified and true, the new    *! buffer points into the old one.
pike.git/src/modules/_Stdio/buffer.cmod:1739:       /*! @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( !io_avail( THIS, n ) ) +  if( n<0 || !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:1764:    *!    *! @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--; -  push_int64( io_rewind( THIS, bytes ) ); +  +  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 );    }       /*! @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:1898:    */    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( !io_avail_mul( io, num, len ) ) +  if( num<=0 || len<=0 || !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 );