Mercurial > nand-ecoscentric
diff packages/language/c/libc/current/src/clibincl/stream.inl @ 0:3111d98ba7b3 ecos-v1_1-release
Initial commit of eCos version 1.1
| author | jlarmour |
|---|---|
| date | Tue, 11 May 1999 11:16:07 +0000 |
| parents | |
| children | 443894e2e912 |
line wrap: on
line diff
new file mode 100644 --- /dev/null +++ b/packages/language/c/libc/current/src/clibincl/stream.inl @@ -0,0 +1,381 @@ +#ifndef CYGONCE_LIBC_CLIBINCL_STREAM_INL +#define CYGONCE_LIBC_CLIBINCL_STREAM_INL +//======================================================================== +// +// stream.inl +// +// Inline functions for internal C library stdio stream interface +// +//======================================================================== +//####COPYRIGHTBEGIN#### +// +// ------------------------------------------- +// The contents of this file are subject to the Cygnus eCos Public License +// Version 1.0 (the "License"); you may not use this file except in +// compliance with the License. You may obtain a copy of the License at +// http://sourceware.cygnus.com/ecos +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +// License for the specific language governing rights and limitations under +// the License. +// +// The Original Code is eCos - Embedded Cygnus Operating System, released +// September 30, 1998. +// +// The Initial Developer of the Original Code is Cygnus. Portions created +// by Cygnus are Copyright (C) 1998 Cygnus Solutions. All Rights Reserved. +// ------------------------------------------- +// +//####COPYRIGHTEND#### +//======================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): jlarmour +// Contributors: jlarmour@cygnus.co.uk +// Date: 1998-02-13 +// Purpose: +// Description: +// Usage: Do not include this file - +// #include "clibincl/stream.hxx" instead. +// +//####DESCRIPTIONEND#### +// +//======================================================================== + +// CONFIGURATION + +#include <pkgconf/libc.h> // Configuration header + +// Include the C library? And do we want the stdio stuff? +#if defined(CYGPKG_LIBC) && defined(CYGPKG_LIBC_STDIO) + +// INCLUDES + +#include <cyg/infra/cyg_type.h> // Common project-wide type definitions +#include <stddef.h> // NULL and size_t from compiler +#include <errno.h> // Error codes +#include "clibincl/stream.hxx" // Just be sure that this really is + // included + +// FUNCTIONS + +#ifdef CYGDBG_USE_ASSERTS +inline bool +Cyg_StdioStream::check_this( cyg_assert_class_zeal zeal ) +{ + // check that it has the magic word set meaning it is valid. + if ( magic_validity_word != 0x7b4321ce ) + return false; + return true; +} // check_this() + +#endif // ifdef CYGDBG_USE_ASSERTS + + + +// LOCKING FUNCTIONS + +// returns true on success +inline cyg_bool +Cyg_StdioStream::lock_me( void ) +{ + CYG_ASSERTCLASS( this, "Stream object is not a valid stream!" ); + +#ifdef CYGSEM_LIBC_STDIO_THREAD_SAFE_STREAMS + return stream_lock.lock(); +#else + // otherwise it "worked" + return true; +#endif + +} // lock_me() + + +// returns true on success +inline cyg_bool +Cyg_StdioStream::trylock_me( void ) +{ + CYG_ASSERTCLASS( this, "Stream object is not a valid stream!" ); + +#ifdef CYGSEM_LIBC_STDIO_THREAD_SAFE_STREAMS + return stream_lock.trylock(); +#else + // otherwise it "worked" + return true; +#endif + +} // lock_me() + + +inline void +Cyg_StdioStream::unlock_me( void ) +{ + CYG_ASSERTCLASS( this, "Stream object is not a valid stream!" ); + +#ifdef CYGSEM_LIBC_STDIO_THREAD_SAFE_STREAMS + stream_lock.unlock(); +#endif +} // unlock_me() + + +// DESTRUCTOR + +inline +Cyg_StdioStream::~Cyg_StdioStream() +{ + CYG_ASSERTCLASS( this, "Stream object is not a valid stream!" ); + + if (!lock_me()) + return; + + flush_output_unlocked(); + + if (my_device->close) { + (*my_device->close)( my_device->cookie ); // @@@ discard error? + } // if + + unlock_me(); + +#ifdef CYGDBG_USE_ASSERTS + magic_validity_word = 0xbadbad; +#endif +} // Cyg_StdioStream destructor + + +// MEMBER FUNCTIONS + + +// this is currently just a wrapper around write, but having this interface +// leaves scope for optimisations in future +inline Cyg_ErrNo +Cyg_StdioStream::write_byte( cyg_uint8 c ) +{ + cyg_ucount32 dummy_bytes_written; + Cyg_ErrNo err; + + CYG_ASSERTCLASS( this, "Stream object is not a valid stream!" ); + + err = write( &c, 1, &dummy_bytes_written ); + + CYG_ASSERT( (err!=ENOERR) || (dummy_bytes_written==1), + "Single byte not written, but no error returned!" ); + + return err; +} // write_byte() + + +inline Cyg_ErrNo +Cyg_StdioStream::unread_byte( cyg_uint8 c ) +{ + CYG_ASSERTCLASS( this, "Stream object is not a valid stream!" ); + +#ifdef CYGFUN_LIBC_STDIO_ungetc + if (!lock_me()) + return EBADF; // assume file is now invalid + + if (flags.unread_char_buf_in_use) { + unlock_me(); + return ENOMEM; + } // if + + flags.unread_char_buf_in_use = true; + unread_char_buf = c; + + // can't be at EOF any more + flags.at_eof = false; + + if (position) // position is always 0 for certain devices + --position; + + unlock_me(); + + return ENOERR; + +#else // ifdef CYGFUN_LIBC_STDIO_ungetc + + return ENOSYS; +#endif // ifdef CYGFUN_LIBC_STDIO_ungetc +} // unread_byte() + + +inline cyg_ucount32 +Cyg_StdioStream::bytes_available_to_read( void ) +{ + cyg_ucount32 bytes=0; + + CYG_ASSERTCLASS( this, "Stream object is not a valid stream!" ); + +#ifdef CYGFUN_LIBC_STDIO_ungetc + if (flags.unread_char_buf_in_use) + ++bytes; +#endif + +#ifdef CYGSEM_LIBC_STDIO_WANT_BUFFERED_IO + + // either the last operation was a read, which attempted to read bytes + // into the buffer, or there are no bytes in the buffer + + if (flags.buffering) { + if (flags.last_buffer_op_was_read == true) + bytes += io_buf.get_buffer_space_used(); + } + else + +#endif + + if (flags.readbuf_char_in_use) + ++bytes; + + return bytes; +} // bytes_available_to_read() + + + +inline Cyg_ErrNo +Cyg_StdioStream::flush_output( void ) +{ + Cyg_ErrNo err; + + CYG_ASSERTCLASS( this, "Stream object is not a valid stream!" ); + + if (!lock_me()) + return EBADF; // assume file is now invalid + + err = flush_output_unlocked(); + + unlock_me(); + + return err; +} // flush_output() + + +// get error status for this file +inline Cyg_ErrNo +Cyg_StdioStream::get_error( void ) +{ + Cyg_ErrNo err_temp; + + CYG_ASSERTCLASS( this, "Stream object is not a valid stream!" ); + + if (!lock_me()) + return EBADF; // well, we've certainly got an error now! + + err_temp = error; + + unlock_me(); + + return err_temp; +} // get_error() + + +// set error status for this file +inline void +Cyg_StdioStream::set_error( Cyg_ErrNo errno_to_set ) +{ + CYG_ASSERTCLASS( this, "Stream object is not a valid stream!" ); + + if (!lock_me()) + { + errno = EBADF; // best we can do - we can't trust error to be there + return; + } // if + + errno = error = errno_to_set; +} // set_error() + + +// are we at EOF? true means we are, false means no +inline cyg_bool +Cyg_StdioStream::get_eof_state( void ) +{ + cyg_bool eof_temp; + + CYG_ASSERTCLASS( this, "Stream object is not a valid stream!" ); + + if (!lock_me()) + return false; // not much we can do here + + eof_temp = flags.at_eof; + + unlock_me(); + + return eof_temp; +} // get_eof_state() + + +// Set whether we are at EOF. +inline void +Cyg_StdioStream::set_eof_state( cyg_bool eof_to_set ) +{ + CYG_ASSERTCLASS( this, "Stream object is not a valid stream!" ); + + if (!lock_me()) + return; // not much we can do here + + flags.at_eof = eof_to_set; + + unlock_me(); +} // set_eof_state() + + +// retrieve position +inline Cyg_ErrNo +Cyg_StdioStream::get_position( fpos_t *pos ) +{ + CYG_ASSERTCLASS( this, "Stream object is not a valid stream!" ); + + if (!lock_me()) + return EBADF; // assume file is now invalid + + *pos = position; + + unlock_me(); + + return ENOERR; +} // get_position() + + +// set absolute position +inline Cyg_ErrNo +Cyg_StdioStream::set_position( fpos_t pos, int whence ) +{ + // this is currently a workaround until we have real files + // this will be corrected when we decide the true filesystem interface + + Cyg_ErrNo err; + cyg_uint8 c; + + CYG_ASSERTCLASS( this, "Stream object is not a valid stream!" ); + + if ((whence != SEEK_CUR) || pos < 0) + return ENOSYS; + + if (!lock_me()) + return EBADF; // assume file is now invalid + + // Drain read buffer + + for ( ; whence > 0 ; whence-- ) { + err = read_byte( &c ); + if (err == EAGAIN) + err=refill_read_buffer(); + + // if read_byte retured error, or refill_read_buffer returned error + if (err) { + unlock_me(); + return err; + } // if + } // for + + unlock_me(); + + return ENOERR; +} // set_position() + + +#endif // if defined(CYGPKG_LIBC) && defined(CYGPKG_LIBC_STDIO) + +#endif CYGONCE_LIBC_CLIBINCL_STREAM_INL multiple inclusion protection + +// EOF stream.inl
