📄 stream.cxx
字号:
#ifdef CYGSEM_LIBC_STDIO_WANT_BUFFERED_IO
if (flags.buffering) {
// need to flush output if we were writing before
if (!flags.last_buffer_op_was_read) {
Cyg_ErrNo err = flush_output_unlocked();
if (ENOERR != err) {
unlock_me();
return err;
}
}
cyg_uint8 *buff_to_read_from;
cyg_ucount32 bytes_available;
bytes_available = io_buf.get_buffer_addr_to_read(
(cyg_uint8 **)&buff_to_read_from );
cyg_ucount32 count =
(bytes_available < buffer_length) ? bytes_available : buffer_length;
if (count) {
memcpy( user_buffer, buff_to_read_from, count );
io_buf.set_bytes_read( count );
*bytes_read += count;
} // if
} // if
else
#endif
if (flags.readbuf_char_in_use && buffer_length) {
*user_buffer = readbuf_char;
*bytes_read = 1;
flags.readbuf_char_in_use = false;
}
position += *bytes_read;
unlock_me();
return ENOERR;
} // read()
Cyg_ErrNo
Cyg_StdioStream::read_byte( cyg_uint8 *c )
{
Cyg_ErrNo err=ENOERR;
CYG_ASSERTCLASS( this, "Stream object is not a valid stream!" );
if (!lock_me())
return EBADF; // assume file is now invalid
if (!flags.opened_for_read) {
unlock_me();
return EINVAL;
}
# ifdef CYGFUN_LIBC_STDIO_ungetc
if (flags.unread_char_buf_in_use) {
*c = unread_char_buf;
flags.unread_char_buf_in_use = false;
position++;
unlock_me();
return ENOERR;
} // if
# endif // ifdef CYGFUN_LIBC_STDIO_ungetc
#ifdef CYGSEM_LIBC_STDIO_WANT_BUFFERED_IO
if (flags.buffering) {
// need to flush output if we were writing before
if (!flags.last_buffer_op_was_read)
err = flush_output_unlocked();
if (ENOERR != err) {
unlock_me();
return err;
}
cyg_uint8 *buff_to_read_from;
cyg_ucount32 bytes_available;
bytes_available=io_buf.get_buffer_addr_to_read(&buff_to_read_from);
if (bytes_available) {
*c = *buff_to_read_from;
io_buf.set_bytes_read(1);
position++;
}
else
err = EAGAIN;
} // if
else
#endif
if (flags.readbuf_char_in_use) {
*c = readbuf_char;
flags.readbuf_char_in_use = false;
position++;
}
else
err = EAGAIN;
unlock_me();
return err;
} // read_byte()
Cyg_ErrNo
Cyg_StdioStream::peek_byte( cyg_uint8 *c )
{
Cyg_ErrNo err=ENOERR;
CYG_ASSERTCLASS( this, "Stream object is not a valid stream!" );
if (!lock_me())
return EBADF; // assume file is now invalid
if (!flags.opened_for_read) {
unlock_me();
return EINVAL;
}
// this should really only be called after refill_read_buffer, but just
// in case
#ifdef CYGSEM_LIBC_STDIO_WANT_BUFFERED_IO
if (flags.buffering)
err = flush_output_unlocked();
if (err != ENOERR)
return err;
// we're now reading
flags.last_buffer_op_was_read = true;
#endif
# ifdef CYGFUN_LIBC_STDIO_ungetc
if (flags.unread_char_buf_in_use) {
*c = unread_char_buf;
unlock_me();
return ENOERR;
} // if
# endif // ifdef CYGFUN_LIBC_STDIO_ungetc
#ifdef CYGSEM_LIBC_STDIO_WANT_BUFFERED_IO
if (flags.buffering) {
cyg_uint8 *buff_to_read_from;
cyg_ucount32 bytes_available;
bytes_available=io_buf.get_buffer_addr_to_read(&buff_to_read_from);
if (bytes_available) {
*c = *buff_to_read_from;
}
else
err = EAGAIN;
} // if
else
#endif
if (flags.readbuf_char_in_use) {
*c = readbuf_char;
}
else
err = EAGAIN;
unlock_me();
return err;
} // peek_byte()
Cyg_ErrNo
Cyg_StdioStream::flush_output_unlocked( void )
{
#ifdef CYGSEM_LIBC_STDIO_WANT_BUFFERED_IO
Cyg_ErrNo write_err=ENOERR;
cyg_uint8 *buffer;
cyg_uint32 len;
CYG_ASSERTCLASS( this, "Stream object is not a valid stream!" );
if ( flags.last_buffer_op_was_read )
return ENOERR;
// first just check that we _can_ write to the device!
if ( !flags.opened_for_write )
return EINVAL;
// shortcut if nothing to do
if (io_buf.get_buffer_space_used() == 0)
return ENOERR;
len = io_buf.get_buffer_addr_to_read( (cyg_uint8 **)&buffer );
CYG_ASSERT( len > 0,
"There should be data to read but there isn't!");
write_err = cyg_stdio_write(my_device, buffer, &len);
// since we're doing a concerted flush, we tell the I/O layer to
// flush too, otherwise output may just sit there forever
if (!write_err)
cyg_stdio_flush( my_device );
// we've just read it all, so just wipe it out
io_buf.drain_buffer();
return write_err;
#else // ifdef CYGSEM_LIBC_STDIO_WANT_BUFFERED_IO
CYG_ASSERTCLASS( this, "Stream object is not a valid stream!" );
return ENOERR;
#endif // ifdef CYGSEM_LIBC_STDIO_WANT_BUFFERED_IO
} // flush_output_unlocked()
Cyg_ErrNo
Cyg_StdioStream::write( const cyg_uint8 *buffer,
cyg_ucount32 buffer_length,
cyg_ucount32 *bytes_written )
{
Cyg_ErrNo write_err = ENOERR;
CYG_ASSERTCLASS( this, "Stream object is not a valid stream!" );
*bytes_written = 0;
if (!lock_me())
return EBADF; // assume file is now invalid
// first just check that we _can_ write to the device!
if ( !flags.opened_for_write ) {
unlock_me();
return EINVAL;
}
#ifdef CYGSEM_LIBC_STDIO_WANT_BUFFERED_IO
if (flags.last_buffer_op_was_read == true)
io_buf.drain_buffer(); // nuke input bytes to prevent confusion
flags.last_buffer_op_was_read = false;
if (!flags.buffering) {
#endif
cyg_uint32 len = buffer_length;
write_err = cyg_stdio_write(my_device, buffer, &len);
*bytes_written = len;
#ifdef CYGSEM_LIBC_STDIO_WANT_BUFFERED_IO
} // if
else {
cyg_ucount32 bytes_available;
cyg_ucount32 bytes_to_write;
cyg_ucount32 newline_pos;
cyg_uint8 *write_addr;
cyg_bool must_flush = false;
while ( buffer_length > 0 ) {
bytes_available =
io_buf.get_buffer_addr_to_write( &write_addr );
// we need to flush if we've no room or the buffer has an up
// and coming newline
if ( !bytes_available || must_flush ) {
write_err = flush_output_unlocked();
// harmless even if there was an error
bytes_available =
io_buf.get_buffer_addr_to_write( &write_addr );
CYG_ASSERT( bytes_available > 0,
"Help! still no bytes available in "
"write buffer" );
} // if
if (write_err) {
unlock_me();
return write_err;
} // if
// choose the lower of the buffer available and the length
// to write
bytes_to_write=(bytes_available < buffer_length)
? bytes_available
: buffer_length;
// if we're line buffered, we may want want to flush if there's
// a newline character, so lets find out
if (flags.line_buffering) {
for (newline_pos=0;
newline_pos<bytes_to_write;
newline_pos++) {
if (buffer[newline_pos] == '\n') {
break;
} // if
} // for
// if we didn't reach the end
if (newline_pos != bytes_to_write) {
// shrink bytes_to_write down to the bit we need to
// flush including the newline itself
bytes_to_write = newline_pos + 1;
must_flush = true;
} // if
} // if
memcpy( write_addr, buffer, bytes_to_write );
*bytes_written += bytes_to_write;
buffer += bytes_to_write;
buffer_length -= bytes_to_write;
io_buf.set_bytes_written( bytes_to_write );
position += bytes_to_write;
} // while
if ( must_flush ) {
write_err = flush_output_unlocked();
} // if
} // else
#endif // ifdef CYGSEM_LIBC_STDIO_WANT_BUFFERED_IO
unlock_me();
return write_err;
} // write()
// EOF stream.cxx
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -