OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-2.0/] [packages/] [language/] [c/] [libc/] [stdio/] [v2_0/] [include/] [stream.inl] - Blame information for rev 341

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 27 unneback
#ifndef CYGONCE_LIBC_STDIO_STREAM_INL
2
#define CYGONCE_LIBC_STDIO_STREAM_INL
3
//========================================================================
4
//
5
//      stream.inl
6
//
7
//      Inline functions for internal C library stdio stream interface
8
//
9
//========================================================================
10
//####ECOSGPLCOPYRIGHTBEGIN####
11
// -------------------------------------------
12
// This file is part of eCos, the Embedded Configurable Operating System.
13
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
14
//
15
// eCos is free software; you can redistribute it and/or modify it under
16
// the terms of the GNU General Public License as published by the Free
17
// Software Foundation; either version 2 or (at your option) any later version.
18
//
19
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
20
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
21
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
22
// for more details.
23
//
24
// You should have received a copy of the GNU General Public License along
25
// with eCos; if not, write to the Free Software Foundation, Inc.,
26
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
27
//
28
// As a special exception, if other files instantiate templates or use macros
29
// or inline functions from this file, or you compile this file and link it
30
// with other works to produce a work based on this file, this file does not
31
// by itself cause the resulting work to be covered by the GNU General Public
32
// License. However the source code for this file must still be made available
33
// in accordance with section (3) of the GNU General Public License.
34
//
35
// This exception does not invalidate any other reasons why a work based on
36
// this file might be covered by the GNU General Public License.
37
//
38
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
39
// at http://sources.redhat.com/ecos/ecos-license/
40
// -------------------------------------------
41
//####ECOSGPLCOPYRIGHTEND####
42
//========================================================================
43
//#####DESCRIPTIONBEGIN####
44
//
45
// Author(s):     jlarmour
46
// Contributors:
47
// Date:          2000-04-19
48
// Purpose:
49
// Description:
50
// Usage:         Do not include this file -
51
//                #include  instead.
52
//
53
//####DESCRIPTIONEND####
54
//
55
//========================================================================
56
 
57
// CONFIGURATION
58
 
59
#include     // Configuration header
60
 
61
// INCLUDES
62
 
63
#include     // Common project-wide type definitions
64
#include                 // NULL and size_t from compiler
65
#include                  // Error codes
66
#include  // Just be sure that this really is
67
                                   // included
68
 
69
#include      // I/O system inlines
70
 
71
// FUNCTIONS
72
 
73
#ifdef CYGDBG_USE_ASSERTS
74
inline cyg_bool
75
Cyg_StdioStream::check_this( cyg_assert_class_zeal zeal ) const
76
{
77
    // check that it has the magic word set meaning it is valid.
78
    if ( magic_validity_word != 0x7b4321ce )
79
        return false;
80
    return true;
81
} // check_this()
82
 
83
#endif // ifdef CYGDBG_USE_ASSERTS
84
 
85
 
86
 
87
// LOCKING FUNCTIONS
88
 
89
// returns true on success
90
inline cyg_bool
91
Cyg_StdioStream::lock_me( void )
92
{
93
    CYG_ASSERTCLASS( this, "Stream object is not a valid stream!" );
94
 
95
#ifdef CYGSEM_LIBC_STDIO_THREAD_SAFE_STREAMS
96
    return stream_lock.lock();
97
#else
98
    // otherwise it "worked"
99
    return true;
100
#endif
101
 
102
} // lock_me()
103
 
104
 
105
// returns true on success
106
inline cyg_bool
107
Cyg_StdioStream::trylock_me( void )
108
{
109
    CYG_ASSERTCLASS( this, "Stream object is not a valid stream!" );
110
 
111
#ifdef CYGSEM_LIBC_STDIO_THREAD_SAFE_STREAMS
112
    return stream_lock.trylock();
113
#else
114
    // otherwise it "worked"
115
    return true;
116
#endif
117
 
118
} // lock_me()
119
 
120
 
121
inline void
122
Cyg_StdioStream::unlock_me( void )
123
{
124
    CYG_ASSERTCLASS( this, "Stream object is not a valid stream!" );
125
 
126
#ifdef CYGSEM_LIBC_STDIO_THREAD_SAFE_STREAMS
127
    stream_lock.unlock();
128
#endif
129
} // unlock_me()
130
 
131
 
132
// DESTRUCTOR
133
 
134
inline Cyg_ErrNo
135
Cyg_StdioStream::close()
136
{
137
    Cyg_ErrNo err = ENOERR;
138
 
139
    if (!lock_me())
140
        return EBADF;
141
 
142
    if( my_device != CYG_STDIO_HANDLE_NULL )
143
    {
144
        flush_output_unlocked();
145
 
146
        err = cyg_stdio_close( my_device );
147
 
148
        if( err == ENOERR )
149
            my_device = CYG_STDIO_HANDLE_NULL;
150
    }
151
 
152
    unlock_me();
153
 
154
    return err;
155
} // close()
156
 
157
inline
158
Cyg_StdioStream::~Cyg_StdioStream()
159
{
160
    CYG_ASSERTCLASS( this, "Stream object is not a valid stream!" );
161
 
162
    // Close the device if it has not already been closed.
163
    if( my_device != CYG_STDIO_HANDLE_NULL )
164
        close();
165
 
166
#ifdef CYGDBG_USE_ASSERTS
167
    magic_validity_word = 0xbadbad;
168
#endif
169
} // Cyg_StdioStream destructor
170
 
171
 
172
// MEMBER FUNCTIONS
173
 
174
 
175
// this is currently just a wrapper around write, but having this interface
176
// leaves scope for optimisations in future
177
inline Cyg_ErrNo
178
Cyg_StdioStream::write_byte( cyg_uint8 c )
179
{
180
    cyg_ucount32 dummy_bytes_written;
181
    Cyg_ErrNo err;
182
 
183
    CYG_ASSERTCLASS( this, "Stream object is not a valid stream!" );
184
 
185
    err = write( &c, 1, &dummy_bytes_written );
186
 
187
    CYG_ASSERT( (err!=ENOERR) || (dummy_bytes_written==1),
188
                "Single byte not written, but no error returned!" );
189
 
190
    return err;
191
} // write_byte()
192
 
193
 
194
inline Cyg_ErrNo
195
Cyg_StdioStream::unread_byte( cyg_uint8 c )
196
{
197
    CYG_ASSERTCLASS( this, "Stream object is not a valid stream!" );
198
 
199
#ifdef CYGFUN_LIBC_STDIO_ungetc
200
    if (!lock_me())
201
        return EBADF;  // assume file is now invalid
202
 
203
    if (flags.unread_char_buf_in_use) {
204
        unlock_me();
205
        return ENOMEM;
206
    } // if
207
 
208
    flags.unread_char_buf_in_use = true;
209
    unread_char_buf = c;
210
 
211
    // can't be at EOF any more
212
    flags.at_eof = false;
213
 
214
    if (position)    // position is always 0 for certain devices
215
        --position;
216
 
217
    unlock_me();
218
 
219
    return ENOERR;
220
 
221
#else // ifdef CYGFUN_LIBC_STDIO_ungetc
222
 
223
    return ENOSYS;
224
#endif // ifdef CYGFUN_LIBC_STDIO_ungetc
225
} // unread_byte()
226
 
227
 
228
inline cyg_ucount32
229
Cyg_StdioStream::bytes_available_to_read( void )
230
{
231
    cyg_ucount32 bytes=0;
232
 
233
    CYG_ASSERTCLASS( this, "Stream object is not a valid stream!" );
234
 
235
#ifdef CYGFUN_LIBC_STDIO_ungetc
236
    if (flags.unread_char_buf_in_use)
237
        ++bytes;
238
#endif
239
 
240
#ifdef CYGSEM_LIBC_STDIO_WANT_BUFFERED_IO
241
 
242
    // either the last operation was a read, which attempted to read bytes
243
    // into the buffer, or there are no bytes in the buffer
244
 
245
    if (flags.buffering) {
246
        if (flags.last_buffer_op_was_read == true)
247
            bytes += io_buf.get_buffer_space_used();
248
    }
249
    else
250
 
251
#endif
252
 
253
    if (flags.readbuf_char_in_use)
254
        ++bytes;
255
 
256
    return bytes;
257
} // bytes_available_to_read()
258
 
259
 
260
 
261
inline Cyg_ErrNo
262
Cyg_StdioStream::flush_output( void )
263
{
264
    Cyg_ErrNo err;
265
 
266
    CYG_ASSERTCLASS( this, "Stream object is not a valid stream!" );
267
 
268
    if (!lock_me())
269
        return EBADF;  // assume file is now invalid
270
 
271
    err = flush_output_unlocked();
272
 
273
    unlock_me();
274
 
275
    return err;
276
} // flush_output()
277
 
278
 
279
// get error status for this file
280
inline Cyg_ErrNo
281
Cyg_StdioStream::get_error( void )
282
{
283
    Cyg_ErrNo err_temp;
284
 
285
    CYG_ASSERTCLASS( this, "Stream object is not a valid stream!" );
286
 
287
    if (!lock_me())
288
        return EBADF;     // well, we've certainly got an error now!
289
 
290
    err_temp = error;
291
 
292
    unlock_me();
293
 
294
    return err_temp;
295
} // get_error()
296
 
297
 
298
// set error status for this file
299
inline void
300
Cyg_StdioStream::set_error( Cyg_ErrNo errno_to_set )
301
{
302
    CYG_ASSERTCLASS( this, "Stream object is not a valid stream!" );
303
 
304
    if (!lock_me())
305
    {
306
        errno = EBADF; // best we can do - we can't trust error to be there
307
        return;
308
    } // if
309
 
310
    errno = error = errno_to_set;
311
 
312
    if ( EEOF == error )
313
        flags.at_eof = 1;
314
 
315
    unlock_me();
316
} // set_error()
317
 
318
 
319
// are we at EOF? true means we are, false means no
320
inline cyg_bool
321
Cyg_StdioStream::get_eof_state( void )
322
{
323
    cyg_bool eof_temp;
324
 
325
    CYG_ASSERTCLASS( this, "Stream object is not a valid stream!" );
326
 
327
    if (!lock_me())
328
        return false;     // not much we can do here
329
 
330
    eof_temp = flags.at_eof;
331
 
332
    unlock_me();
333
 
334
    return eof_temp;
335
} // get_eof_state()
336
 
337
 
338
// Set whether we are at EOF.
339
inline void
340
Cyg_StdioStream::set_eof_state( cyg_bool eof_to_set )
341
{
342
    CYG_ASSERTCLASS( this, "Stream object is not a valid stream!" );
343
 
344
    if (!lock_me())
345
        return;     // not much we can do here
346
 
347
    flags.at_eof = eof_to_set;
348
 
349
    unlock_me();
350
} // set_eof_state()
351
 
352
 
353
// retrieve position
354
inline Cyg_ErrNo
355
Cyg_StdioStream::get_position( fpos_t *pos )
356
{
357
    CYG_ASSERTCLASS( this, "Stream object is not a valid stream!" );
358
 
359
    if (!lock_me())
360
        return EBADF; // assume file is now invalid
361
 
362
    *pos = position;
363
 
364
    unlock_me();
365
 
366
    return ENOERR;
367
 
368
} // get_position()
369
 
370
 
371
// set absolute position
372
inline Cyg_ErrNo
373
Cyg_StdioStream::set_position( fpos_t pos, int whence )
374
{
375
    CYG_ASSERTCLASS( this, "Stream object is not a valid stream!" );
376
 
377
#ifndef CYGPKG_LIBC_STDIO_FILEIO
378
    // this is currently a workaround until we have real files
379
    // this will be corrected when we decide the true filesystem interface
380
 
381
    Cyg_ErrNo err;
382
    cyg_uint8 c;
383
 
384
    if ((whence != SEEK_CUR) || pos < 0)
385
        return ENOSYS;
386
 
387
    if (!lock_me())
388
        return EBADF; // assume file is now invalid
389
 
390
    // Drain read buffer
391
 
392
    for ( ; pos > 0 ; pos-- ) {
393
        err = read_byte( &c );
394
        if (err == EAGAIN)
395
            err=refill_read_buffer();
396
 
397
        // if read_byte retured error, or refill_read_buffer returned error
398
        if (err) {
399
            unlock_me();
400
            return err;
401
        } // if
402
    } // for
403
 
404
    unlock_me();
405
 
406
    return ENOERR;
407
 
408
#else
409
 
410
    if (!lock_me())
411
        return EBADF; // assume file is now invalid
412
 
413
    if ( whence != SEEK_END ) {
414
        off_t bytesavail = (off_t)bytes_available_to_read();
415
        off_t abspos = (whence == SEEK_CUR) ? position + pos : pos;
416
        off_t posdiff = abspos - position;
417
 
418
        if ( posdiff >= 0 && bytesavail > posdiff ) {
419
            // can just "seek" within the existing buffer
420
#ifdef CYGFUN_LIBC_STDIO_ungetc
421
            if (posdiff>0 && flags.unread_char_buf_in_use) {
422
                flags.unread_char_buf_in_use = false;
423
                posdiff--;
424
            }
425
#endif
426
#ifdef CYGSEM_LIBC_STDIO_WANT_BUFFERED_IO
427
            if (posdiff>0 && flags.buffering) {
428
                io_buf.set_bytes_read(posdiff);
429
                posdiff=0;
430
            } else
431
#endif
432
            if (posdiff>0 && flags.readbuf_char_in_use) {
433
                flags.readbuf_char_in_use = false;
434
                posdiff--;
435
            }
436
            CYG_ASSERT(posdiff==0, "Failed to seek within buffer correctly");
437
 
438
            position = abspos;
439
            unlock_me();
440
            return ENOERR;
441
        } // endif (bytesavail > posdiff)
442
 
443
        if (whence == SEEK_CUR) {
444
            position += bytesavail;
445
        }
446
    } //endif (whence != SEEK_END)
447
 
448
    Cyg_ErrNo err;
449
    off_t newpos=pos;
450
 
451
    err = cyg_stdio_lseek( my_device, &newpos, whence );
452
 
453
    if( err == ENOERR )
454
    {
455
        // Clean out the buffer. Flush output if any present,
456
        // and clear any input out of input buffer and any ungot
457
        // chars from unread buffer.
458
 
459
        err = flush_output_unlocked();
460
        io_buf.drain_buffer();
461
#ifdef CYGFUN_LIBC_STDIO_ungetc
462
        flags.unread_char_buf_in_use = false;
463
#endif
464
 
465
        // Clear EOF indicator.
466
        flags.at_eof = false;
467
 
468
        // update stream pos
469
        position = newpos;
470
    }
471
 
472
    unlock_me();
473
 
474
    return err;
475
#endif
476
 
477
} // set_position()
478
 
479
 
480
#endif // CYGONCE_LIBC_STDIO_STREAM_INL multiple inclusion protection
481
 
482
// EOF stream.inl

powered by: WebSVN 2.1.0

© copyright 1999-2025 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.