Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

  1. /*      Copyright (C) 2004-2008 Garrett A. Kajmowicz
  2.  
  3.         This file is part of the uClibc++ Library.
  4.  
  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.
  9.  
  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.
  14.  
  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
  18. */
  19.  
  20. #include <basic_definitions>
  21.  
  22. #ifndef STD_HEADER_OSTREAM
  23. #define STD_HEADER_OSTREAM 1
  24.  
  25. #include <iosfwd>
  26. #include <streambuf>
  27. #include <cstdio>
  28. #include <ostream_helpers>
  29.  
  30. #pragma GCC visibility push(default)
  31.  
  32. namespace std {
  33.         template <class charT, class traits > class basic_ostream;
  34.         typedef basic_ostream<char> ostream;
  35.  
  36. #ifdef __UCLIBCXX_HAS_WCHAR__
  37.         typedef basic_ostream<wchar_t> wostream;
  38. #endif
  39.  
  40.         template <class charT, class traits> basic_ostream<charT,traits>& endl(basic_ostream<charT,traits>& os);
  41.         template <class charT, class traits> basic_ostream<charT,traits>& ends(basic_ostream<charT,traits>& os);
  42.         template <class charT, class traits> basic_ostream<charT,traits>& flush(basic_ostream<charT,traits>& os);
  43.  
  44.         template <class charT, class traits > class _UCXXEXPORT basic_ostream
  45.                 : virtual public basic_ios<charT,traits>
  46.         {
  47.         public:
  48.  
  49.                 typedef charT char_type;
  50.                 typedef typename traits::int_type int_type;
  51.                 typedef typename traits::pos_type pos_type;
  52.                 typedef typename traits::off_type off_type;
  53.                 typedef traits traits_type;
  54.  
  55.  
  56.                 _UCXXEXPORT basic_ostream(basic_streambuf<charT,traits>* sb)
  57.                         : basic_ios<charT, traits>(sb)
  58.                 {
  59.                         basic_ios<charT,traits>::init(sb);
  60.                 }
  61.                 virtual _UCXXEXPORT ~basic_ostream();
  62.  
  63.                 class sentry;
  64.  
  65.                 _UCXXEXPORT basic_ostream<charT,traits>& operator<<(basic_ostream<charT,traits>& (*pf)(basic_ostream<charT,traits>&)){
  66.                         return pf(*this);
  67.                 }
  68.                 _UCXXEXPORT basic_ostream<charT,traits>& operator<<(basic_ios<charT,traits>& (*pf)(basic_ios<charT,traits>&)){
  69.                         pf(*this);
  70.                         return *this;
  71.                 }
  72.                 _UCXXEXPORT basic_ostream<charT,traits>& operator<<(ios_base& (*pf)(ios_base&)){
  73.                         pf(*this);
  74.                         return *this;
  75.                 }
  76.                 basic_ostream<charT,traits>& operator<<(bool n);
  77.                 basic_ostream<charT,traits>& operator<<(short n);
  78.                 basic_ostream<charT,traits>& operator<<(unsigned short n);
  79.                 basic_ostream<charT,traits>& operator<<(int n);
  80.                 basic_ostream<charT,traits>& operator<<(unsigned int n);
  81.                 basic_ostream<charT,traits>& operator<<(long n);
  82.                 basic_ostream<charT,traits>& operator<<(unsigned long n);
  83.                 basic_ostream<charT,traits>& operator<<(float f);
  84.                 basic_ostream<charT,traits>& operator<<(double f);
  85.                 basic_ostream<charT,traits>& operator<<(long double f);
  86.                 basic_ostream<charT,traits>& operator<<(void* p);
  87.                 basic_ostream<charT,traits>& operator<<(basic_streambuf<char_type,traits>* sb);
  88.  
  89.                 _UCXXEXPORT basic_ostream<charT,traits>& put(char_type c){
  90.                         if(basic_ostream<charT,traits>::traits_type::eq_int_type(
  91.                                 basic_ios<charT, traits>::mstreambuf->sputc(c),
  92.                                 basic_ostream<charT,traits>::traits_type::eof()))
  93.                         {
  94.                                 basic_ios<charT,traits>::setstate(ios_base::eofbit);
  95.                         }
  96.                         return *this;
  97.                 }
  98.                 _UCXXEXPORT basic_ostream<charT,traits>& write(const char_type* s, streamsize n){
  99.                         if(basic_ostream<charT,traits>::traits_type::eq_int_type(
  100.                                 basic_ios<charT, traits>::mstreambuf->sputn(s, n),
  101.                                 basic_ostream<charT,traits>::traits_type::eof())
  102.                         ){
  103.                                 basic_ios<charT,traits>::setstate(ios_base::eofbit);
  104.                         }
  105.                         return *this;
  106.                 }
  107.                 _UCXXEXPORT basic_ostream<charT,traits>& flush(){
  108.                         if(basic_ios<charT, traits>::mstreambuf->pubsync() == -1){
  109.                                 basic_ios<charT,traits>::setstate(ios_base::badbit);
  110.                         }
  111.                         return *this;
  112.                 }
  113.                 _UCXXEXPORT pos_type tellp(){
  114.                         if(basic_ios<charT,traits>::fail() != false){
  115.                                 return pos_type(-1);
  116.                         }
  117.                         return basic_ios<charT,traits>::rdbuf()->pubseekoff(0, ios_base::cur, ios_base::out);
  118.                 }
  119.                 _UCXXEXPORT basic_ostream<charT,traits>& seekp(pos_type pos){
  120.                         if( basic_ios<charT,traits>::fail() != true ){
  121.                                 basic_ios<charT,traits>::rdbuf()->pubseekpos(pos);
  122.                         }
  123.                         return *this;
  124.                 }
  125.                 _UCXXEXPORT basic_ostream<charT,traits>& seekp(off_type off, ios_base::seekdir dir){
  126.                         if( basic_ios<charT,traits>::fail() != true){
  127.                                 basic_ios<charT,traits>::rdbuf()->pubseekoff(off, dir);
  128.                         }
  129.                         return *this;
  130.                 }
  131.  
  132.                 _UCXXEXPORT void printout(const char_type* s, streamsize n){
  133.                         streamsize extra = ios::width() - n;
  134.                         if ((ios::flags()&ios::adjustfield) == ios::right){
  135.                                 while (extra > 0) {
  136.                                         --extra;
  137.                                         put(ios::fill());
  138.                                 }
  139.                         }
  140.                         write(s, n);
  141.                         if ((ios::flags()&ios::adjustfield) == ios::left) {
  142.                                 while (extra > 0) {
  143.                                         --extra;
  144.                                         put(ios::fill());
  145.                                 }
  146.                         }
  147.                         // Width value only applies for the next output operation.  Reset to zero.
  148.                         ios::width(0);
  149.                 }
  150.  
  151.         protected:
  152.                 basic_ostream(const basic_ostream<charT,traits> &){ }
  153.                 basic_ostream<charT,traits> & operator=(const basic_ostream<charT,traits> &){ return *this; }
  154.         };
  155.  
  156.         //Implementations of template functions.  To allow for partial specialization
  157.  
  158.         template <class charT, class traits> _UCXXEXPORT basic_ostream<charT,traits>::~basic_ostream(){ }
  159.        
  160.         template <class charT, class traits> _UCXXEXPORT basic_ostream<charT,traits>& basic_ostream<charT, traits>::operator<<(bool n){
  161.                 sentry s(*this);
  162.                 if( basic_ios<charT,traits>::flags() & ios_base::boolalpha){
  163.                         if(n){
  164.                                 printout("true", 4);
  165.                         }else{
  166.                                 printout("false", 5);
  167.                         }
  168.                 }else{
  169.                         if(n){
  170.                                 printout("1", 1);
  171.                         }else{
  172.                                 printout("0", 1);
  173.                         }
  174.                 }
  175.                 if(basic_ios<charT,traits>::flags() & ios_base::unitbuf){
  176.                         flush();
  177.                 }
  178.                 return *this;
  179.         }
  180.  
  181.         template <class charT, class traits> _UCXXEXPORT basic_ostream<charT,traits>&
  182.                 basic_ostream<charT, traits>::operator<<(unsigned short n){
  183.                 sentry s(*this);
  184.                 __ostream_printout<traits, charT, unsigned long int>::printout(*this, n);
  185.                 return *this;
  186.         }
  187.  
  188.         template <class charT, class traits> _UCXXEXPORT basic_ostream<charT,traits>& basic_ostream<charT, traits>::operator<<(short n){
  189.                 sentry s(*this);
  190.                 __ostream_printout<traits, charT, long int>::printout(*this, n);
  191.                 return *this;
  192.         }
  193.  
  194.         template <class charT, class traits> _UCXXEXPORT basic_ostream<charT,traits>& basic_ostream<charT, traits>::operator<<(int n){
  195.                 sentry s(*this);
  196.                 __ostream_printout<traits, charT, long int>::printout(*this, n);
  197.                 return *this;
  198.         }
  199.  
  200.         template <class charT, class traits> _UCXXEXPORT basic_ostream<charT,traits>& basic_ostream<charT, traits>::operator<<(unsigned int n){
  201.                 sentry s(*this);
  202.                 __ostream_printout<traits, charT, unsigned long int>::printout(*this, n);
  203.                 return *this;
  204.         }
  205.  
  206.         template <class charT, class traits> _UCXXEXPORT basic_ostream<charT,traits>& basic_ostream<charT, traits>::operator<<(long n){
  207.                 sentry s(*this);
  208.                 __ostream_printout<traits, charT, long >::printout(*this, n);
  209.                 return *this;
  210.         }
  211.  
  212.         template <class charT, class traits> _UCXXEXPORT basic_ostream<charT,traits>&
  213.                 basic_ostream<charT, traits>::operator<<(unsigned long n)
  214.         {
  215.                 sentry s(*this);
  216.                 __ostream_printout<traits, charT, unsigned long >::printout(*this, n);
  217.                 return *this;
  218.         }
  219.  
  220.         template <class charT, class traits> _UCXXEXPORT basic_ostream<charT,traits>& basic_ostream<charT, traits>::operator<<(float f){
  221.                 sentry s(*this);
  222.                 __ostream_printout<traits, charT, double >::printout(*this, f);
  223.                 return *this;
  224.         }
  225.  
  226.         template <class charT, class traits> _UCXXEXPORT basic_ostream<charT,traits>& basic_ostream<charT, traits>::operator<<(double f){
  227.                 sentry s(*this);
  228.                 __ostream_printout<traits, charT, double >::printout(*this, f);
  229.                 return *this;
  230.         }
  231.  
  232.         template <class charT, class traits> _UCXXEXPORT basic_ostream<charT,traits>& basic_ostream<charT, traits>::operator<<(long double f){
  233.                 sentry s(*this);
  234.                 __ostream_printout<traits, charT, long double >::printout(*this, f);
  235.                 return *this;
  236.         }
  237.  
  238.         template <class charT, class traits> _UCXXEXPORT basic_ostream<charT,traits>& basic_ostream<charT, traits>::operator<<(void* p){
  239.                 sentry s(*this);
  240.                 char buffer[20];
  241.                 printout(buffer, snprintf(buffer, 20, "%p", p) );
  242.                 if(basic_ios<charT,traits>::flags() & ios_base::unitbuf){
  243.                         flush();
  244.                 }
  245.                 return *this;
  246.         }
  247.  
  248.         template <class charT, class traits> _UCXXEXPORT basic_ostream<charT,traits>&
  249.                 basic_ostream<charT, traits>::operator<<(basic_streambuf<charT,traits>* sb)
  250.         {
  251.                 sentry s(*this);
  252.                 if(sb == 0){
  253.                         basic_ios<charT,traits>::setstate(ios_base::badbit);
  254.                         return *this;
  255.                 }
  256.  
  257.                 typename traits::int_type c;
  258.  
  259.                 while(basic_ios<charT,traits>::good() && (c = sb->sbumpc()) != traits::eof() ){
  260.                         put(c);
  261.                 }
  262.  
  263.                 if(basic_ios<charT,traits>::flags() & ios_base::unitbuf){
  264.                         flush();
  265.                 }
  266.                 return *this;
  267.         }
  268.  
  269.         /*Template Specializations*/
  270.  
  271. #ifdef __UCLIBCXX_EXPAND_OSTREAM_CHAR__
  272. #ifndef __UCLIBCXX_COMPILE_OSTREAM__
  273.  
  274. #ifdef __UCLIBCXX_EXPAND_CONSTRUCTORS_DESTRUCTORS__
  275.  
  276.         template <> _UCXXEXPORT ostream::~basic_ostream();
  277.  
  278. #endif // __UCLIBCXX_EXPAND_CONSTRUCTORS_DESTRUCTORS__
  279.  
  280.         template <> _UCXXEXPORT ostream & ostream::flush();
  281.  
  282.         template <> _UCXXEXPORT ostream & ostream::operator<<(bool n);
  283.         template <> _UCXXEXPORT ostream & ostream::operator<<(short int n);
  284.         template <> _UCXXEXPORT ostream & ostream::operator<<(unsigned short int n);
  285.         template <> _UCXXEXPORT ostream & ostream::operator<<(int n);
  286.         template <> _UCXXEXPORT ostream & ostream::operator<<(unsigned int n);
  287.         template <> _UCXXEXPORT ostream & ostream::operator<<(long n);
  288.         template <> _UCXXEXPORT ostream & ostream::operator<<(unsigned long n);
  289.         template <> _UCXXEXPORT ostream & ostream::operator<<(float f);
  290.         template <> _UCXXEXPORT ostream & ostream::operator<<(double f);
  291.         template <> _UCXXEXPORT ostream & ostream::operator<<(long double f);
  292.         template <> _UCXXEXPORT ostream & ostream::operator<<(void* p);
  293.         template <> _UCXXEXPORT ostream & ostream::operator<<(basic_streambuf<char, char_traits<char> >* sb);
  294. #endif
  295. #endif
  296.  
  297.         template <class charT,class traits = char_traits<charT> >
  298.                 class _UCXXEXPORT basic_ostream<charT,traits>::sentry
  299.         {
  300.                 bool ok;
  301.         public:
  302.                 explicit _UCXXEXPORT sentry(basic_ostream<charT,traits>& os): ok(true){
  303.                         if(os.good() !=0){              //Prepare for output
  304.                         }
  305.  
  306.                         //Flush any tied buffer
  307.                         if(os.tie() !=0 ){
  308.                                 os.tie()->flush();
  309.                         }
  310.                 }
  311.                 _UCXXEXPORT ~sentry() { }
  312.                 _UCXXEXPORT operator bool() {
  313.                         return ok;
  314.                 }
  315.         };
  316.  
  317.  
  318. #ifdef __UCLIBCXX_EXPAND_OSTREAM_CHAR__
  319. #ifndef __UCLIBCXX_COMPILE_OSTREAM__
  320. #ifdef __UCLIBCXX_EXPAND_CONSTRUCTORS_DESTRUCTORS__
  321.  
  322.         template <> _UCXXEXPORT ostream::sentry::sentry(ostream & os);
  323.         template <> _UCXXEXPORT ostream::sentry::~sentry();
  324.  
  325. #endif //__UCLIBCXX_EXPAND_CONSTRUCTORS_DESTRUCTORS__
  326. #endif
  327. #endif
  328.  
  329.  
  330.         //Non - class functions
  331.  
  332.  
  333.         template<class charT, class traits> _UCXXEXPORT basic_ostream<charT,traits>&
  334.                 operator<<(basic_ostream<charT,traits>& out, charT c)
  335.         {
  336.                 typename basic_ostream<charT,traits>::sentry s(out);
  337.                 out.put(c);
  338.                 return out;
  339.         }
  340.        
  341.         template<class charT, class traits> _UCXXEXPORT basic_ostream<charT,traits>&
  342.                 operator<<(basic_ostream<charT,traits>& out, char c)
  343.         {
  344.                 typename basic_ostream<charT,traits>::sentry s(out);
  345.                 out.put(c);
  346.                 return out;
  347.         }
  348.    
  349.         template<class traits> _UCXXEXPORT basic_ostream<char,traits>&
  350.                 operator<<(basic_ostream<char,traits>& out, char c)
  351.         {
  352.                 typename basic_ostream<char,traits>::sentry s(out);
  353.                 out.put(c);
  354.                 return out;
  355.         }
  356.    
  357.     // signed and unsigned
  358.         template<class traits> _UCXXEXPORT basic_ostream<char,traits>&
  359.                 operator<<(basic_ostream<char,traits>& out, signed char c)
  360.         {
  361.                 typename basic_ostream<char,traits>::sentry s(out);
  362.                 out.put(c);
  363.                 return out;
  364.         }
  365.        
  366.         template<class traits> _UCXXEXPORT basic_ostream<char,traits>&
  367.                 operator<<(basic_ostream<char,traits>& out, unsigned char c)
  368.         {
  369.                 typename basic_ostream<char,traits>::sentry s(out);
  370.                 out.put(c);
  371.                 return out;
  372.         }
  373.        
  374.         template<class charT, class traits> _UCXXEXPORT basic_ostream<charT,traits>&
  375.                 operator<<(basic_ostream<charT,traits>& out, const charT* c)
  376.         {
  377.                 typename basic_ostream<charT,traits>::sentry s(out);
  378.                 out.printout(c, traits::length(c) );
  379.                 return out;
  380.         }
  381.        
  382.         template<class charT, class traits> _UCXXEXPORT basic_ostream<charT,traits>&
  383.                 operator<<(basic_ostream<charT,traits>& out, const char* c)
  384.         {
  385.                 typename basic_ostream<charT,traits>::sentry s(out);
  386.                 out.printout(c, char_traits<char>::length(c) );
  387.                 return out;
  388.         }
  389.  
  390.     // partial specializations
  391.         template<class traits> _UCXXEXPORT basic_ostream<char,traits>&
  392.                 operator<<(basic_ostream<char,traits>& out, const char* c)
  393.         {
  394.                 typename basic_ostream<char,traits>::sentry s(out);
  395.                 out.printout(c, traits::length(c));
  396.                 return out;
  397.         }
  398.  
  399. #ifdef __UCLIBCXX_HAS_WCHAR__
  400.         template<class traits> _UCXXEXPORT basic_ostream<wchar_t,traits>&
  401.                 operator<<(basic_ostream<wchar_t,traits>& out, const char* c)
  402.         {
  403.                 typename basic_ostream<wchar_t, traits>::sentry s(out);
  404.                 size_t numChars = char_traits<char>::length(c);
  405.                 wchar_t * temp = new wchar_t[numChars];
  406.  
  407.                 for(size_t i=0; i < numChars; ++i){
  408.                         temp[i] = out.widen(c[i]);
  409.                 }
  410.  
  411.                 out.printout(temp, numChars);
  412.                 return out;
  413.         }
  414. #endif
  415.    
  416.     //  signed and unsigned
  417.         template<class traits> _UCXXEXPORT basic_ostream<char,traits>&
  418.                 operator<<(basic_ostream<char,traits>& out, const signed char* c)
  419.         {
  420.                 typename basic_ostream<char,traits>::sentry s(out);
  421.                 out.printout(reinterpret_cast<const char *>(c), traits::length( reinterpret_cast<const char *>(c)));
  422.                 return out;
  423.         }
  424.        
  425.         template<class traits> _UCXXEXPORT basic_ostream<char,traits>&
  426.                 operator<<(basic_ostream<char,traits>& out, const unsigned char* c)
  427.         {
  428.                 typename basic_ostream<char,traits>::sentry s(out);
  429.                 out.printout(reinterpret_cast<const char *>(c), traits::length( reinterpret_cast<const char *>(c)));
  430.                 return out;
  431.         }
  432.  
  433.         template <class charT, class traits> _UCXXEXPORT basic_ostream<charT,traits>&
  434.                 endl(basic_ostream<charT,traits>& os)
  435.         {
  436.                 typename basic_ostream<charT,traits>::sentry s(os);
  437.                 os.put('\n');
  438.                 os.flush();
  439.                 return os;
  440.         }
  441.  
  442.         template <class charT, class traits> _UCXXEXPORT basic_ostream<charT,traits>&
  443.                 ends(basic_ostream<charT,traits>& os)
  444.         {
  445.                 typename basic_ostream<charT,traits>::sentry s(os);
  446.                 os.put(traits::eos());
  447.                 return os;
  448.         }
  449.  
  450.         template <class charT, class traits> _UCXXEXPORT basic_ostream<charT,traits>& flush(basic_ostream<charT,traits>& os){
  451.                 typename basic_ostream<charT,traits>::sentry s(os);
  452.                 os.flush();
  453.                 return os;
  454.         }
  455.  
  456.  
  457. #ifdef __UCLIBCXX_EXPAND_OSTREAM_CHAR__
  458. #ifndef __UCLIBCXX_COMPILE_OSTREAM__
  459.         template <> _UCXXEXPORT ostream & endl(ostream & os);
  460.         template <> _UCXXEXPORT ostream & flush(ostream & os);
  461.         template <> _UCXXEXPORT ostream & operator<<(ostream & out, char c);
  462.         template <> _UCXXEXPORT ostream & operator<<(ostream & out, const char* c);
  463.         template <> _UCXXEXPORT ostream & operator<<(ostream & out, unsigned char c);
  464.         template <> _UCXXEXPORT ostream & operator<<(ostream & out, unsigned const char* c);
  465.  
  466. #endif
  467. #endif
  468.  
  469.  
  470. #ifndef __STRICT_ANSI__
  471.  
  472. //Support for output of long long data types
  473.  
  474. template<class Ch, class Tr> _UCXXEXPORT basic_ostream<Ch, Tr>&
  475.         operator<<(basic_ostream<Ch, Tr>& os, signed long long int i)
  476. {
  477.         typename basic_ostream<Ch, Tr>::sentry s(os);
  478.         __ostream_printout<Tr, Ch, signed long long int>::printout(os, i);
  479.         return os;
  480. }
  481.  
  482.  
  483. template<class Ch, class Tr> _UCXXEXPORT basic_ostream<Ch, Tr>&
  484.         operator<<(basic_ostream<Ch, Tr>& os, unsigned long long int i)
  485. {
  486.         typename basic_ostream<Ch, Tr>::sentry s(os);
  487.         __ostream_printout<Tr, Ch, unsigned long long int>::printout(os, i);
  488.         return os;
  489. }
  490.  
  491.  
  492. #endif  //__STRICT_ANSI__
  493.  
  494.  
  495.  
  496.  
  497. }
  498.  
  499. #pragma GCC visibility pop
  500.  
  501. #endif
  502.  
  503.