1
 
/*      Copyright (C) 2004-2008 Garrett A. Kajmowicz
 
3
 
        This file is part of the uClibc++ Library.
 
5
 
        This library is free software; you can redistribute it and/or
 
6
 
        modify it under the terms of the GNU Lesser General Public
 
7
 
        License as published by the Free Software Foundation; either
 
8
 
        version 2.1 of the License, or (at your option) any later version.
 
10
 
        This library is distributed in the hope that it will be useful,
 
11
 
        but WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
 
        MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
13
 
        Lesser General Public License for more details.
 
15
 
        You should have received a copy of the GNU Lesser General Public
 
16
 
        License along with this library; if not, write to the Free Software
 
17
 
        Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
20
 
#include <basic_definitions>
 
22
 
#ifndef STD_HEADER_OSTREAM
 
23
 
#define STD_HEADER_OSTREAM 1
 
28
 
#include <ostream_helpers>
 
30
 
#if defined( __AVR__ )
 
31
 
#include <avr/pgmspace.h>
 
32
 
class __FlashStringHelper;
 
35
 
#pragma GCC visibility push(default)
 
38
 
        template <class charT, class traits > class basic_ostream;
 
39
 
        typedef basic_ostream<char> ostream;
 
41
 
#ifdef __UCLIBCXX_HAS_WCHAR__
 
42
 
        typedef basic_ostream<wchar_t> wostream;
 
45
 
        template <class charT, class traits> basic_ostream<charT,traits>& endl(basic_ostream<charT,traits>& os);
 
46
 
        template <class charT, class traits> basic_ostream<charT,traits>& ends(basic_ostream<charT,traits>& os);
 
47
 
        template <class charT, class traits> basic_ostream<charT,traits>& flush(basic_ostream<charT,traits>& os);
 
49
 
        template <class charT, class traits > class _UCXXEXPORT basic_ostream
 
50
 
                : virtual public basic_ios<charT,traits>
 
54
 
                typedef charT char_type;
 
55
 
                typedef typename traits::int_type int_type;
 
56
 
                typedef typename traits::pos_type pos_type;
 
57
 
                typedef typename traits::off_type off_type;
 
58
 
                typedef traits traits_type;
 
61
 
                _UCXXEXPORT basic_ostream(basic_streambuf<charT,traits>* sb)
 
62
 
                        : basic_ios<charT, traits>(sb)
 
64
 
                        basic_ios<charT,traits>::init(sb);
 
66
 
                virtual _UCXXEXPORT ~basic_ostream();
 
70
 
                _UCXXEXPORT basic_ostream<charT,traits>& operator<<(basic_ostream<charT,traits>& (*pf)(basic_ostream<charT,traits>&)){
 
73
 
                _UCXXEXPORT basic_ostream<charT,traits>& operator<<(basic_ios<charT,traits>& (*pf)(basic_ios<charT,traits>&)){
 
77
 
                _UCXXEXPORT basic_ostream<charT,traits>& operator<<(ios_base& (*pf)(ios_base&)){
 
81
 
                basic_ostream<charT,traits>& operator<<(bool n);
 
82
 
                basic_ostream<charT,traits>& operator<<(short n);
 
83
 
                basic_ostream<charT,traits>& operator<<(unsigned short n);
 
84
 
                basic_ostream<charT,traits>& operator<<(int n);
 
85
 
                basic_ostream<charT,traits>& operator<<(unsigned int n);
 
86
 
                basic_ostream<charT,traits>& operator<<(long n);
 
87
 
                basic_ostream<charT,traits>& operator<<(unsigned long n);
 
88
 
                basic_ostream<charT,traits>& operator<<(float f);
 
89
 
                basic_ostream<charT,traits>& operator<<(double f);
 
90
 
                basic_ostream<charT,traits>& operator<<(long double f);
 
91
 
                basic_ostream<charT,traits>& operator<<(void* p);
 
92
 
                basic_ostream<charT,traits>& operator<<(basic_streambuf<char_type,traits>* sb);
 
93
 
#if defined( __AVR__ )
 
94
 
                basic_ostream<charT,traits>& operator<<(const __FlashStringHelper* p);
 
97
 
                _UCXXEXPORT basic_ostream<charT,traits>& put(char_type c){
 
98
 
                        if(basic_ostream<charT,traits>::traits_type::eq_int_type(
 
99
 
                                basic_ios<charT, traits>::mstreambuf->sputc(c),
 
100
 
                                basic_ostream<charT,traits>::traits_type::eof()))
 
102
 
                                basic_ios<charT,traits>::setstate(ios_base::eofbit);
 
106
 
                _UCXXEXPORT basic_ostream<charT,traits>& write(const char_type* s, streamsize n){
 
107
 
                        if(basic_ostream<charT,traits>::traits_type::eq_int_type(
 
108
 
                                basic_ios<charT, traits>::mstreambuf->sputn(s, n), 
 
109
 
                                basic_ostream<charT,traits>::traits_type::eof())
 
111
 
                                basic_ios<charT,traits>::setstate(ios_base::eofbit);
 
115
 
                _UCXXEXPORT basic_ostream<charT,traits>& flush(){
 
116
 
                        if(basic_ios<charT, traits>::mstreambuf->pubsync() == -1){
 
117
 
                                basic_ios<charT,traits>::setstate(ios_base::badbit);
 
121
 
                _UCXXEXPORT pos_type tellp(){
 
122
 
                        if(basic_ios<charT,traits>::fail() != false){
 
125
 
                        return basic_ios<charT,traits>::rdbuf()->pubseekoff(0, ios_base::cur, ios_base::out);
 
127
 
                _UCXXEXPORT basic_ostream<charT,traits>& seekp(pos_type pos){
 
128
 
                        if( basic_ios<charT,traits>::fail() != true ){
 
129
 
                                basic_ios<charT,traits>::rdbuf()->pubseekpos(pos);
 
133
 
                _UCXXEXPORT basic_ostream<charT,traits>& seekp(off_type off, ios_base::seekdir dir){
 
134
 
                        if( basic_ios<charT,traits>::fail() != true){
 
135
 
                                basic_ios<charT,traits>::rdbuf()->pubseekoff(off, dir);
 
140
 
                _UCXXEXPORT void printout(const char_type* s, streamsize n){
 
141
 
                        streamsize extra = ios::width() - n;
 
142
 
                        if ((ios::flags()&ios::adjustfield) == ios::right){
 
149
 
                        if ((ios::flags()&ios::adjustfield) == ios::left) {
 
155
 
                        // Width value only applies for the next output operation.  Reset to zero.
 
160
 
                basic_ostream(const basic_ostream<charT,traits> &){ }
 
161
 
                basic_ostream<charT,traits> & operator=(const basic_ostream<charT,traits> &){ return *this; }
 
164
 
        //Implementations of template functions.  To allow for partial specialization
 
166
 
        template <class charT, class traits> _UCXXEXPORT basic_ostream<charT,traits>::~basic_ostream(){ }
 
168
 
        template <class charT, class traits> _UCXXEXPORT basic_ostream<charT,traits>& basic_ostream<charT, traits>::operator<<(bool n){
 
170
 
                if( basic_ios<charT,traits>::flags() & ios_base::boolalpha){
 
174
 
                                printout("false", 5);
 
183
 
                if(basic_ios<charT,traits>::flags() & ios_base::unitbuf){
 
189
 
        template <class charT, class traits> _UCXXEXPORT basic_ostream<charT,traits>& 
 
190
 
                basic_ostream<charT, traits>::operator<<(unsigned short n){
 
192
 
                __ostream_printout<traits, charT, unsigned long int>::printout(*this, n);
 
196
 
        template <class charT, class traits> _UCXXEXPORT basic_ostream<charT,traits>& basic_ostream<charT, traits>::operator<<(short n){
 
198
 
                __ostream_printout<traits, charT, long int>::printout(*this, n);
 
202
 
        template <class charT, class traits> _UCXXEXPORT basic_ostream<charT,traits>& basic_ostream<charT, traits>::operator<<(int n){
 
204
 
                __ostream_printout<traits, charT, long int>::printout(*this, n);
 
208
 
        template <class charT, class traits> _UCXXEXPORT basic_ostream<charT,traits>& basic_ostream<charT, traits>::operator<<(unsigned int n){
 
210
 
                __ostream_printout<traits, charT, unsigned long int>::printout(*this, n);
 
214
 
        template <class charT, class traits> _UCXXEXPORT basic_ostream<charT,traits>& basic_ostream<charT, traits>::operator<<(long n){
 
216
 
                __ostream_printout<traits, charT, long >::printout(*this, n);
 
220
 
        template <class charT, class traits> _UCXXEXPORT basic_ostream<charT,traits>& 
 
221
 
                basic_ostream<charT, traits>::operator<<(unsigned long n)
 
224
 
                __ostream_printout<traits, charT, unsigned long >::printout(*this, n);
 
228
 
        template <class charT, class traits> _UCXXEXPORT basic_ostream<charT,traits>& basic_ostream<charT, traits>::operator<<(float f){
 
230
 
                __ostream_printout<traits, charT, double >::printout(*this, f);
 
234
 
        template <class charT, class traits> _UCXXEXPORT basic_ostream<charT,traits>& basic_ostream<charT, traits>::operator<<(double f){
 
236
 
                __ostream_printout<traits, charT, double >::printout(*this, f);
 
240
 
        template <class charT, class traits> _UCXXEXPORT basic_ostream<charT,traits>& basic_ostream<charT, traits>::operator<<(long double f){
 
242
 
                __ostream_printout<traits, charT, long double >::printout(*this, f);
 
246
 
        template <class charT, class traits> _UCXXEXPORT basic_ostream<charT,traits>& basic_ostream<charT, traits>::operator<<(void* p){
 
249
 
                printout(buffer, snprintf(buffer, 20, "%p", p) );
 
250
 
                if(basic_ios<charT,traits>::flags() & ios_base::unitbuf){
 
255
 
        template <class charT, class traits> _UCXXEXPORT basic_ostream<charT,traits>& 
 
256
 
                basic_ostream<charT, traits>::operator<<(basic_streambuf<charT,traits>* sb)
 
260
 
                        basic_ios<charT,traits>::setstate(ios_base::badbit);
 
264
 
                typename traits::int_type c;
 
266
 
                while(basic_ios<charT,traits>::good() && (c = sb->sbumpc()) != traits::eof() ){
 
270
 
                if(basic_ios<charT,traits>::flags() & ios_base::unitbuf){
 
275
 
#if defined( __AVR__ )
 
276
 
        template <class charT, class traits> _UCXXEXPORT basic_ostream<charT,traits>& basic_ostream<charT, traits>::operator<<(const __FlashStringHelper* p ){
 
279
 
                size_t p_len = strlcpy_P(buffer,reinterpret_cast<const char*>(p),sizeof(buffer));
 
280
 
                printout(buffer, (p_len>=sizeof(buffer)) ? sizeof(buffer) - 1 : p_len ); 
 
281
 
                if(basic_ios<charT,traits>::flags() & ios_base::unitbuf){
 
289
 
        /*Template Specializations*/
 
291
 
#ifdef __UCLIBCXX_EXPAND_OSTREAM_CHAR__
 
292
 
#ifndef __UCLIBCXX_COMPILE_OSTREAM__
 
294
 
#ifdef __UCLIBCXX_EXPAND_CONSTRUCTORS_DESTRUCTORS__
 
296
 
        template <> _UCXXEXPORT ostream::~basic_ostream();
 
298
 
#endif // __UCLIBCXX_EXPAND_CONSTRUCTORS_DESTRUCTORS__
 
300
 
        template <> _UCXXEXPORT ostream & ostream::flush();
 
302
 
        template <> _UCXXEXPORT ostream & ostream::operator<<(bool n);
 
303
 
        template <> _UCXXEXPORT ostream & ostream::operator<<(short int n);
 
304
 
        template <> _UCXXEXPORT ostream & ostream::operator<<(unsigned short int n);
 
305
 
        template <> _UCXXEXPORT ostream & ostream::operator<<(int n);
 
306
 
        template <> _UCXXEXPORT ostream & ostream::operator<<(unsigned int n);
 
307
 
        template <> _UCXXEXPORT ostream & ostream::operator<<(long n);
 
308
 
        template <> _UCXXEXPORT ostream & ostream::operator<<(unsigned long n);
 
309
 
        template <> _UCXXEXPORT ostream & ostream::operator<<(float f);
 
310
 
        template <> _UCXXEXPORT ostream & ostream::operator<<(double f);
 
311
 
        template <> _UCXXEXPORT ostream & ostream::operator<<(long double f);
 
312
 
        template <> _UCXXEXPORT ostream & ostream::operator<<(void* p);
 
313
 
        template <> _UCXXEXPORT ostream & ostream::operator<<(basic_streambuf<char, char_traits<char> >* sb);
 
317
 
        template <class charT,class traits = char_traits<charT> >
 
318
 
                class _UCXXEXPORT basic_ostream<charT,traits>::sentry
 
322
 
                explicit _UCXXEXPORT sentry(basic_ostream<charT,traits>& os): ok(true){
 
323
 
                        if(os.good() !=0){              //Prepare for output
 
326
 
                        //Flush any tied buffer
 
331
 
                _UCXXEXPORT ~sentry() { }
 
332
 
                _UCXXEXPORT operator bool() {
 
338
 
#ifdef __UCLIBCXX_EXPAND_OSTREAM_CHAR__
 
339
 
#ifndef __UCLIBCXX_COMPILE_OSTREAM__
 
340
 
#ifdef __UCLIBCXX_EXPAND_CONSTRUCTORS_DESTRUCTORS__
 
342
 
        template <> _UCXXEXPORT ostream::sentry::sentry(ostream & os);
 
343
 
        template <> _UCXXEXPORT ostream::sentry::~sentry();
 
345
 
#endif //__UCLIBCXX_EXPAND_CONSTRUCTORS_DESTRUCTORS__
 
350
 
        //Non - class functions
 
353
 
        template<class charT, class traits> _UCXXEXPORT basic_ostream<charT,traits>&
 
354
 
                operator<<(basic_ostream<charT,traits>& out, charT c)
 
356
 
                typename basic_ostream<charT,traits>::sentry s(out);
 
361
 
        template<class charT, class traits> _UCXXEXPORT basic_ostream<charT,traits>&
 
362
 
                operator<<(basic_ostream<charT,traits>& out, char c)
 
364
 
                typename basic_ostream<charT,traits>::sentry s(out);
 
369
 
        template<class traits> _UCXXEXPORT basic_ostream<char,traits>&
 
370
 
                operator<<(basic_ostream<char,traits>& out, char c)
 
372
 
                typename basic_ostream<char,traits>::sentry s(out);
 
377
 
    // signed and unsigned
 
378
 
        template<class traits> _UCXXEXPORT basic_ostream<char,traits>&
 
379
 
                operator<<(basic_ostream<char,traits>& out, signed char c)
 
381
 
                typename basic_ostream<char,traits>::sentry s(out);
 
386
 
        template<class traits> _UCXXEXPORT basic_ostream<char,traits>&
 
387
 
                operator<<(basic_ostream<char,traits>& out, unsigned char c)
 
389
 
                typename basic_ostream<char,traits>::sentry s(out);
 
394
 
        template<class charT, class traits> _UCXXEXPORT basic_ostream<charT,traits>&
 
395
 
                operator<<(basic_ostream<charT,traits>& out, const charT* c)
 
397
 
                typename basic_ostream<charT,traits>::sentry s(out);
 
398
 
                out.printout(c, traits::length(c) );
 
402
 
        template<class charT, class traits> _UCXXEXPORT basic_ostream<charT,traits>&
 
403
 
                operator<<(basic_ostream<charT,traits>& out, const char* c)
 
405
 
                typename basic_ostream<charT,traits>::sentry s(out);
 
406
 
                out.printout(c, char_traits<char>::length(c) );
 
410
 
    // partial specializations
 
411
 
        template<class traits> _UCXXEXPORT basic_ostream<char,traits>&
 
412
 
                operator<<(basic_ostream<char,traits>& out, const char* c)
 
414
 
                typename basic_ostream<char,traits>::sentry s(out);
 
415
 
                out.printout(c, traits::length(c));
 
419
 
#ifdef __UCLIBCXX_HAS_WCHAR__
 
420
 
        template<class traits> _UCXXEXPORT basic_ostream<wchar_t,traits>&
 
421
 
                operator<<(basic_ostream<wchar_t,traits>& out, const char* c)
 
423
 
                typename basic_ostream<wchar_t, traits>::sentry s(out);
 
424
 
                size_t numChars = char_traits<char>::length(c);
 
425
 
                wchar_t * temp = new wchar_t[numChars];
 
427
 
                for(size_t i=0; i < numChars; ++i){
 
428
 
                        temp[i] = out.widen(c[i]);
 
431
 
                out.printout(temp, numChars);
 
436
 
    //  signed and unsigned
 
437
 
        template<class traits> _UCXXEXPORT basic_ostream<char,traits>&
 
438
 
                operator<<(basic_ostream<char,traits>& out, const signed char* c)
 
440
 
                typename basic_ostream<char,traits>::sentry s(out);
 
441
 
                out.printout(reinterpret_cast<const char *>(c), traits::length( reinterpret_cast<const char *>(c)));
 
445
 
        template<class traits> _UCXXEXPORT basic_ostream<char,traits>&
 
446
 
                operator<<(basic_ostream<char,traits>& out, const unsigned char* c)
 
448
 
                typename basic_ostream<char,traits>::sentry s(out);
 
449
 
                out.printout(reinterpret_cast<const char *>(c), traits::length( reinterpret_cast<const char *>(c)));
 
453
 
        template <class charT, class traits> _UCXXEXPORT basic_ostream<charT,traits>&
 
454
 
                endl(basic_ostream<charT,traits>& os)
 
456
 
                typename basic_ostream<charT,traits>::sentry s(os);
 
462
 
        template <class charT, class traits> _UCXXEXPORT basic_ostream<charT,traits>&
 
463
 
                ends(basic_ostream<charT,traits>& os)
 
465
 
                typename basic_ostream<charT,traits>::sentry s(os);
 
466
 
                os.put(traits::eos());
 
470
 
        template <class charT, class traits> _UCXXEXPORT basic_ostream<charT,traits>& flush(basic_ostream<charT,traits>& os){
 
471
 
                typename basic_ostream<charT,traits>::sentry s(os);
 
477
 
#ifdef __UCLIBCXX_EXPAND_OSTREAM_CHAR__
 
478
 
#ifndef __UCLIBCXX_COMPILE_OSTREAM__
 
479
 
        template <> _UCXXEXPORT ostream & endl(ostream & os);
 
480
 
        template <> _UCXXEXPORT ostream & flush(ostream & os);
 
481
 
        template <> _UCXXEXPORT ostream & operator<<(ostream & out, char c);
 
482
 
        template <> _UCXXEXPORT ostream & operator<<(ostream & out, const char* c);
 
483
 
        template <> _UCXXEXPORT ostream & operator<<(ostream & out, unsigned char c);
 
484
 
        template <> _UCXXEXPORT ostream & operator<<(ostream & out, unsigned const char* c);
 
490
 
#ifndef __STRICT_ANSI__
 
492
 
//Support for output of long long data types
 
494
 
template<class Ch, class Tr> _UCXXEXPORT basic_ostream<Ch, Tr>& 
 
495
 
        operator<<(basic_ostream<Ch, Tr>& os, signed long long int i)
 
497
 
        typename basic_ostream<Ch, Tr>::sentry s(os);
 
498
 
        __ostream_printout<Tr, Ch, signed long long int>::printout(os, i);
 
503
 
template<class Ch, class Tr> _UCXXEXPORT basic_ostream<Ch, Tr>& 
 
504
 
        operator<<(basic_ostream<Ch, Tr>& os, unsigned long long int i)
 
506
 
        typename basic_ostream<Ch, Tr>::sentry s(os);
 
507
 
        __ostream_printout<Tr, Ch, unsigned long long int>::printout(os, i);
 
512
 
#endif  //__STRICT_ANSI__
 
519
 
#pragma GCC visibility pop