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