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