⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 stream.cxx

📁 开放源码实时操作系统源码.
💻 CXX
📖 第 1 页 / 共 2 页
字号:
        } // 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;
    }


    // if we are unbuffered, we read as much as we can directly from the 
    // file system at this point.
    //
    // unless we do this, we could end up reading byte-by-byte from the filing system
    // due to the readbuf_char scheme.
    if (
#ifdef CYGSEM_LIBC_STDIO_WANT_BUFFERED_IO
        !flags.buffering &&
#endif
        (*bytes_read<buffer_length)) {
        cyg_uint32 len;
        len=buffer_length-*bytes_read;
        read_err = cyg_stdio_read(my_device, user_buffer + *bytes_read, &len);      
        *bytes_read+=len;
    }
    
    position += *bytes_read;
    
    unlock_me();

    return read_err;
} // 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) {
#ifdef CYGPKG_LIBC_STDIO_FILEIO
        if ( 0 != io_buf.get_buffer_space_used() )
        {
            off_t newpos = position;
            io_buf.drain_buffer();  // nuke input bytes to prevent confusion
            Cyg_ErrNo err = cyg_stdio_lseek( my_device, &newpos, SEEK_SET );
            if (err) {
                unlock_me();
                return err;
            }
        }
#else
        io_buf.drain_buffer();  // nuke input bytes to prevent confusion
#endif
    }

    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()

//
// class Cyg_OutputStream
//

Cyg_ErrNo
Cyg_OutputStream::write( const cyg_uint8 *buffer, cyg_ucount32 buffer_length,
    cyg_ucount32 *bytes_written )
{
    CYG_FAIL("Cyg_OutputStream::write(): pure virtual called");
    return ENOSYS;
}

Cyg_ErrNo
Cyg_OutputStream::get_error( void )
{
    CYG_FAIL("Cyg_OutputStream::get_error(): pure virtual called");
    return ENOSYS;
}



// EOF stream.cxx

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -