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

version» Context lines:

pike.git/src/modules/_Stdio/buffer.cmod:245:    }    else    push_text("Illegal arguments\n");       ref_push_object( io->this );    push_object(clone_object(io->error_mode, 2));    f_throw(1);    }    }    +  static struct pike_string *io_read_string( IOBuffer *io, size_t len ); +  static size_t io_rewind( IOBuffer *io, INT_TYPE n ); +  +  static void io_trigger_output( IOBuffer *io ) +  { +  if( io->output && !io->output_triggered ) +  { +  struct my_file *fd; +  if( (fd = get_storage( io->output, file_program )) ) +  { +  /* actual fd? Just register the callback. */ +  fd->box.revents &= ~(PIKE_BIT_FD_WRITE|PIKE_BIT_FD_WRITE_OOB); +  if(!SAFE_IS_ZERO(&fd->event_cbs[PIKE_FD_WRITE]) +  && fd->box.backend) +  set_fd_callback_events(&fd->box, fd->box.events|PIKE_BIT_FD_WRITE, 0); +  io->output_triggered = 1; +  } +  else +  { +  size_t bytes = MINIMUM(io_len(io),100); +  INT_TYPE l; +  struct pike_string *s = io_read_string( io,bytes ); +  if( s ) +  { +  /* Call write to triggger. */ +  io->output_triggered = 1; +  push_string( s ); +  apply( io->output, "write", 1 ); +  l = Pike_sp[-1].u.integer; +  pop_stack(); +  if( l < 0 ) +  l = 0; +  if( bytes > (unsigned)l ) +  io_rewind( io, bytes-l ); +  } +  } +  } +  } +     static int io_range_error( IOBuffer *io, int howmuch )    {    int res;    struct svalue *osp = Pike_sp;       push_int( 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 );
pike.git/src/modules/_Stdio/buffer.cmod:276:    return io_avail(io,len);    return 0;    }    return 1;    }       static size_t io_append( IOBuffer *io, void *p, int bytes )    {    memcpy( io_add_space( io, bytes, 0 ), p, bytes );    io->len += bytes; +  io_trigger_output( io );    return io_len(io);    }       static size_t io_read( IOBuffer *io, void *to, size_t len )    {    if( !io_avail(io,len))    return 0;    memcpy( to, io_read_pointer(io), len );    io_consume( io, len );    return len;
pike.git/src/modules/_Stdio/buffer.cmod:394:       static size_t io_add_int( IOBuffer *io, INT_TYPE i, size_t bytes )    {    unsigned char *x = io_add_space(io, bytes, 0);    io->len += bytes;    while(bytes--)    {    x[bytes] = i&255;    i>>=8;    } +  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;    }       static void io_append_short_uc( IOBuffer *io, unsigned short shrt )    {
pike.git/src/modules/_Stdio/buffer.cmod:492:       if( res <= 0 )    break;    nbytes -= res;    io->len += res;    bread += res;    if( res != 4096 )    break;    }    fd->box.revents &= ~(PIKE_BIT_FD_READ|PIKE_BIT_FD_READ_OOB); +  if(!SAFE_IS_ZERO(&fd->event_cbs[PIKE_FD_READ]) +  && fd->box.backend) +  set_fd_callback_events(&fd->box, fd->box.events|PIKE_BIT_FD_READ, 0);    }    else    {    /* some other object. Just call read */    while( nbytes )    {    push_int( MINIMUM(4096,nbytes) );    safe_apply( f, "read", 1 );    if( TYPEOF(Pike_sp[-1]) != PIKE_T_STRING || Pike_sp[-1].u.string->len == 0 )    break;    if( Pike_sp[-1].u.string->size_shift )    Pike_error("Can not handle non-8bit data\n");    io_append( io, Pike_sp[-1].u.string->str, Pike_sp[-1].u.string->len );    nbytes -= Pike_sp[-1].u.string->len;    pop_stack();    }    }    RETURN bread;    }    -  +  /*! @decl int __fd_set_output( object f ) +  *! +  *! This tells the buffer to trigger the write callback for the +  *! specified filedescriptor when data is added to the buffer. +  *! +  *! This is used internally by Stdio.File to handle nonblocking +  *! buffered mode, and is not really intended to be used directly. +  *! +  *! If f is 0 the state is cleared. +  */ +  +  PIKEFUN void __fd_set_output( object f ) +  { +  IOBuffer *io = THIS; +  if( io->output ) free_object(io->output); +  io->output_triggered = 0; +  io->output = f; +  io->output->refs++; +  } +  +  PIKEFUN void __fd_set_output( int(0..0) f ) +  { +  IOBuffer *io = THIS; +  if( io->output ) free_object(io->output); +  io->output = 0; +  io->output_triggered = 0; +  } +     /*! @decl int output_to( Stdio.Stream f, int|void nbytes )    *!    *! Write data from the buffer to the indicated file.    *!    *! Will return the number of bytes that were successfully written.    *!    *! If @[nbytes] is not specified the whole buffer will be written    *! if possible. Otherwise at most @[nbytes] will be written.    */    PIKEFUN int(0..) output_to( object f, int|void _nbytes )
pike.git/src/modules/_Stdio/buffer.cmod:1552:    this->this = Pike_fp->current_object;    }       EXIT {    IOBuffer *this = THIS;    if( this->sub )    {    free_object( this->sub );    io_unlock( get_storage(this->sub,IOBuffer_program ) );    } +  if( this->output ) +  free_object(this->output);    if( this->source )    free_object( this->source );    if( this->str )    free_string( this->str );    if( this->error_mode )    free_program( this->error_mode );    if( this->malloced )    free( this->buffer );    }   }