Subversion Repositories Kolibri OS

Rev

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

  1. /*      Copyright (C) 2004 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. #include <cstddef>
  22. #include <ios>
  23. #include <cctype>
  24. #include <string>
  25.  
  26. #ifndef __STD_HEADER_OSTREAM_HELPERS
  27. #define __STD_HEADER_OSTREAM_HELPERS 1
  28.  
  29. #pragma GCC visibility push(default)
  30.  
  31. namespace std{
  32.  
  33.         /* We are making the following template class for serveral reasons.  Firstly,
  34.          * we want to keep the main ostream code neat and tidy.  Secondly, we want it
  35.          * to be easy to do partial specialization of the ostream code so that it can
  36.          * be expanded and put into the library.  This will allow us to make application
  37.          * code smaller at the expense of increased library size.  This is a fair
  38.          * trade-off when there are multiple applications being compiled.  Also, this
  39.          * feature will be used optionally via configuration options.  It will also
  40.          * allow us to keep the code bases in sync, dramatically simplifying the
  41.          * maintenance required.  We specialized for char because wchar and others
  42.          * require different scanf functions
  43.          */
  44.  
  45.  
  46.  
  47.         template <class traits, class charT, class dataType> class _UCXXEXPORT __ostream_printout{
  48.         public:
  49.                 static void printout(basic_ostream<charT,traits>& stream, const dataType n);
  50.         };
  51.  
  52.         template <class traits> class _UCXXEXPORT __ostream_printout<traits, char, signed long int>{
  53.         public:
  54.                 static void printout(basic_ostream<char, traits >& stream, const signed long int n)
  55.                 {
  56.                         char buffer[20];
  57.                         const char * c_ld = "%ld";
  58.                         const char * c_lo = "%lo";
  59.                         const char * c_lX = "%lX";
  60.                         const char * c_lx = "%lx";
  61.                         const char * c_hashlo = "%#lo";
  62.                         const char * c_hashlX = "%#lX";
  63.                         const char * c_hashlx = "%#lx";
  64.  
  65.                         const char * formatString=0;
  66.  
  67.                         if( stream.flags() & ios_base::dec){
  68.                                 formatString = c_ld;
  69.                         }else if( stream.flags() & ios_base::oct){
  70.                                 if( stream.flags() & ios_base::showbase){
  71.                                         formatString = c_hashlo;
  72.                                 }else{
  73.                                         formatString = c_lo;
  74.                                 }
  75.                         }else if (stream.flags() & ios_base::hex){
  76.                                 if(stream.flags() & ios_base::showbase){
  77.                                         if(stream.flags() & ios_base::uppercase){
  78.                                                 formatString = c_hashlX;
  79.                                         }else{
  80.                                                 formatString = c_hashlx;
  81.                                         }
  82.                                 }else{
  83.                                         if(stream.flags() & ios_base::uppercase){
  84.                                                 formatString = c_lX;
  85.                                         }else{
  86.                                                 formatString = c_lx;
  87.                                         }
  88.                                 }
  89.                         }
  90.  
  91.                         stream.printout(buffer, snprintf(buffer, 20, formatString, n) );
  92.  
  93.                         if(stream.flags() & ios_base::unitbuf){
  94.                                 stream.flush();
  95.                         }
  96.  
  97.                 }
  98.         };
  99.  
  100.         template <class traits> class _UCXXEXPORT __ostream_printout<traits, char, unsigned long int>{
  101.         public:
  102.                 static void printout(basic_ostream<char, traits >& stream, const unsigned long int n)
  103.                 {
  104.                         char buffer[20];
  105.                         const char * c_lo = "%lo";
  106.                         const char * c_lu = "%lu";
  107.                         const char * c_lX = "%lX";
  108.                         const char * c_lx = "%lx";
  109.                         const char * c_hashlo = "%#lo";
  110.                         const char * c_hashlX = "%#lX";
  111.                         const char * c_hashlx = "%#lx";
  112.                         const char * formatString=0;
  113.  
  114.                         if( stream.flags() & ios_base::dec){
  115.                                 formatString = c_lu;
  116.                         }else if( stream.flags() & ios_base::oct){
  117.                                 if( stream.flags() & ios_base::showbase){
  118.                                         formatString = c_hashlo;
  119.                                 }else{
  120.                                         formatString = c_lo;
  121.                                 }
  122.                         }else if (stream.flags() & ios_base::hex){
  123.                                 if(stream.flags() & ios_base::showbase){
  124.                                         if(stream.flags() & ios_base::uppercase){
  125.                                                 formatString = c_hashlX;
  126.                                         }else{
  127.                                                 formatString = c_hashlx;
  128.                                         }
  129.                                 }else{
  130.                                         if(stream.flags() & ios_base::uppercase){
  131.                                                 formatString = c_lX;
  132.                                         }else{
  133.                                                 formatString = c_lx;
  134.                                         }
  135.                                 }
  136.                         }
  137.  
  138.                         stream.printout(buffer, snprintf(buffer, 20, formatString, n));
  139.                         if(stream.flags() & ios_base::unitbuf){
  140.                                 stream.flush();
  141.                         }
  142.                 }
  143.         };
  144.  
  145. #ifndef __STRICT_ANSI__
  146.  
  147.         template <class traits> class _UCXXEXPORT __ostream_printout<traits, char, signed long long int>{
  148.         public:
  149.                 static void printout(basic_ostream<char, traits >& stream, const signed long long int n)
  150.                 {
  151.                         char buffer[28];
  152.                         const char * lld = "%lld";
  153.                         const char * llo = "%llo";
  154.                         const char * llX = "%llX";
  155.                         const char * llx = "%llx";
  156.                         const char * hashllo = "%#llo";
  157.                         const char * hashllX = "%#llX";
  158.                         const char * hashllx = "%#llx";
  159.                         const char * formatString=0;
  160.  
  161.                         if( stream.flags() & ios_base::dec){
  162.                                 formatString = lld;
  163.                         }else if( stream.flags() & ios_base::oct){
  164.                                 if( stream.flags() & ios_base::showbase){
  165.                                         formatString = hashllo;
  166.                                 }else{
  167.                                         formatString = llo;
  168.                                 }
  169.                         }else if (stream.flags() & ios_base::hex){
  170.                                 if(stream.flags() & ios_base::showbase){
  171.                                         if(stream.flags() & ios_base::uppercase){
  172.                                                 formatString = hashllX;
  173.                                         }else{
  174.                                                 formatString = hashllx;
  175.                                         }
  176.                                 }else{
  177.                                         if(stream.flags() & ios_base::uppercase){
  178.                                                 formatString = llX;
  179.                                         }else{
  180.                                                 formatString = llx;
  181.                                         }
  182.                                 }
  183.                         }
  184.  
  185.                         stream.printout(buffer, snprintf(buffer, 27, formatString, n) );
  186.  
  187.                         if(stream.flags() & ios_base::unitbuf){
  188.                                 stream.flush();
  189.                         }
  190.                 }
  191.         };
  192.  
  193.         template <class traits> class _UCXXEXPORT __ostream_printout<traits, char, unsigned long long int>{
  194.         public:
  195.                 static void printout(basic_ostream<char, traits >& stream, const unsigned long long int n)
  196.                 {
  197.                         char buffer[28];
  198.                         const char * llo = "%llo";
  199.                         const char * llu = "%llu";
  200.                         const char * llX = "%llX";
  201.                         const char * llx = "%llx";
  202.                         const char * hashllo = "%#llo";
  203.                         const char * hashllX = "%#llX";
  204.                         const char * hashllx = "%#llx";
  205.                         const char * formatString=0;
  206.  
  207.                         if( stream.flags() & ios_base::dec){
  208.                                 formatString = llu;
  209.                         }else if( stream.flags() & ios_base::oct){
  210.                                 if( stream.flags() & ios_base::showbase){
  211.                                         formatString = hashllo;
  212.                                 }else{
  213.                                         formatString = llo;
  214.                                 }
  215.                         }else if (stream.flags() & ios_base::hex){
  216.                                 if(stream.flags() & ios_base::showbase){
  217.                                         if(stream.flags() & ios_base::uppercase){
  218.                                                 formatString = hashllX;
  219.                                         }else{
  220.                                                 formatString = hashllx;
  221.                                         }
  222.                                 }else{
  223.                                         if(stream.flags() & ios_base::uppercase){
  224.                                                 formatString = llX;
  225.                                         }else{
  226.                                                 formatString = llx;
  227.                                         }
  228.                                 }
  229.                         }
  230.  
  231.                         stream.printout(buffer, snprintf(buffer, 27, formatString, n) );
  232.  
  233.                         if(stream.flags() & ios_base::unitbuf){
  234.                                 stream.flush();
  235.                         }
  236.                 }
  237.         };
  238.  
  239.  
  240. #endif  //__STRICT_ANSI__
  241.  
  242.         template <class traits> class _UCXXEXPORT __ostream_printout<traits, char, double>{
  243.         public:
  244.                 static void printout(basic_ostream<char, traits >& stream, const double f)
  245.                 {
  246.                         char buffer[32];
  247.                         int length;
  248.                         if(stream.flags() & ios_base::scientific){
  249.                                 if(stream.flags() & ios_base::uppercase){
  250.                                         length = snprintf(buffer, 32, "%*.*E", static_cast<int>(stream.width()),static_cast<int>(stream.precision()), f);
  251.                                 }else{
  252.                                         length = snprintf(buffer, 32, "%*.*e", static_cast<int>(stream.width()),static_cast<int>(stream.precision()), f);
  253.                                 }
  254.                         } else if(stream.flags() & ios_base::fixed){
  255.                                 length = snprintf(buffer, 32, "%*.*f",static_cast<int>(stream.width()),static_cast<int>(stream.precision()), f);
  256.                         } else {
  257.                                 length = snprintf(buffer, 32, "%*.*g",static_cast<int>(stream.width()),static_cast<int>(stream.precision()), f);
  258.                         }
  259.                         stream.printout(buffer, length);
  260.                         if(stream.flags() & ios_base::unitbuf){
  261.                                 stream.flush();
  262.                         }
  263.                 }
  264.         };
  265.  
  266.         template <class traits> class _UCXXEXPORT __ostream_printout<traits, char, long double>{
  267.         public:
  268.                 static void printout(basic_ostream<char, traits >& stream, const long double f)
  269.                 {
  270.                         char buffer[32];
  271.                         int length;
  272.                         if(stream.flags() & ios_base::scientific){
  273.                                 if(stream.flags() & ios_base::uppercase){
  274.                                         length = snprintf(buffer, 32, "%*.*LE", static_cast<int>(stream.width()), static_cast<int>(stream.precision()), f);
  275.                                 }else{
  276.                                         length = snprintf(buffer, 32, "%*.*Le", static_cast<int>(stream.width()), static_cast<int>(stream.precision()), f);
  277.                                 }
  278.                         } else if(stream.flags() & ios_base::fixed){
  279.                                 length = snprintf(buffer, 32, "%*.*Lf", static_cast<int>(stream.width()), static_cast<int>(stream.precision()), f);
  280.                         } else {
  281.                                 length = snprintf(buffer, 32, "%*.*Lg", static_cast<int>(stream.width()), static_cast<int>(stream.precision()), f);
  282.                         }
  283.                         stream.printout(buffer, length);
  284.                         if(stream.flags() & ios_base::unitbuf){
  285.                                 stream.flush();
  286.                         }
  287.  
  288.                 }
  289.         };
  290.  
  291. #ifdef __UCLIBCXX_HAS_WCHAR__
  292.         template <class traits> class _UCXXEXPORT __ostream_printout<traits, wchar_t, signed long int>{
  293.         public:
  294.                 static void printout(basic_ostream<wchar_t, traits >& stream, const signed long int n)
  295.                 {
  296.                         wchar_t buffer[20];
  297.                         if( stream.flags() & ios_base::dec){
  298.                                 stream.printout(buffer, swprintf(buffer, 20, L"%ld", n));
  299.                         }else if( stream.flags() & ios_base::oct){
  300.                                 if( stream.flags() & ios_base::showbase){
  301.                                         stream.printout(buffer, swprintf(buffer, 20, L"%#lo", n));
  302.                                 }else{
  303.                                         stream.printout(buffer, swprintf(buffer, 20, L"%lo", n) );
  304.                                 }
  305.                         }else if (stream.flags() & ios_base::hex){
  306.                                 if(stream.flags() & ios_base::showbase){
  307.                                         if(stream.flags() & ios_base::uppercase){
  308.                                                 stream.printout(buffer, swprintf(buffer, 20, L"%#lX", n) );
  309.                                         }else{
  310.                                                 stream.printout(buffer, swprintf(buffer, 20, L"%#lx", n) );
  311.                                         }
  312.                                 }else{
  313.                                         if(stream.flags() & ios_base::uppercase){
  314.                                                 stream.printout(buffer, swprintf(buffer, 20, L"%lX", n) );
  315.                                         }else{
  316.                                                 stream.printout(buffer, swprintf(buffer, 20, L"%lx", n) );
  317.                                         }
  318.                                 }
  319.                         }
  320.                         if(stream.flags() & ios_base::unitbuf){
  321.                                 stream.flush();
  322.                         }
  323.                 }
  324.         };
  325.  
  326.         template <class traits> class _UCXXEXPORT __ostream_printout<traits, wchar_t, unsigned long int>{
  327.         public:
  328.                 static void printout(basic_ostream<wchar_t, traits >& stream, const unsigned long int n)
  329.                 {
  330.                         wchar_t buffer[20];
  331.                         if( stream.flags() & ios_base::dec){
  332.                                 stream.printout(buffer, swprintf(buffer, 20, L"%lu", n));
  333.                         }else if( stream.flags() & ios_base::oct){
  334.                                 if( stream.flags() & ios_base::showbase){
  335.                                         stream.printout(buffer, swprintf(buffer, 20, L"%#lo", n));
  336.                                 }else{
  337.                                         stream.printout(buffer, swprintf(buffer, 20, L"%lo", n) );
  338.                                 }
  339.                         }else if (stream.flags() & ios_base::hex){
  340.                                 if(stream.flags() & ios_base::showbase){
  341.                                         if(stream.flags() & ios_base::uppercase){
  342.                                                 stream.printout(buffer, swprintf(buffer, 20, L"%#lX", n) );
  343.                                         }else{
  344.                                                 stream.printout(buffer, swprintf(buffer, 20, L"%#lx", n) );
  345.                                         }
  346.                                 }else{
  347.                                         if(stream.flags() & ios_base::uppercase){
  348.                                                 stream.printout(buffer, swprintf(buffer, 20, L"%lX", n) );
  349.                                         }else{
  350.                                                 stream.printout(buffer, swprintf(buffer, 20, L"%lx", n) );
  351.                                         }
  352.                                 }
  353.                         }
  354.                         if(stream.flags() & ios_base::unitbuf){
  355.                                 stream.flush();
  356.                         }
  357.                 }
  358.         };
  359.  
  360. #ifndef __STRICT_ANSI__
  361.  
  362.         template <class traits> class _UCXXEXPORT __ostream_printout<traits, wchar_t, signed long long int>{
  363.         public:
  364.                 static void printout(basic_ostream<wchar_t, traits >& stream, const signed long long int n)
  365.                 {
  366.                         wchar_t buffer[28];
  367.                         if( stream.flags() & ios_base::dec){
  368.                                 stream.printout(buffer, swprintf(buffer, 27, L"%lld", n));
  369.                         }else if( stream.flags() & ios_base::oct){
  370.                                 if( stream.flags() & ios_base::showbase){
  371.                                         stream.printout(buffer, swprintf(buffer, 27, L"%#llo", n));
  372.                                 }else{
  373.                                         stream.printout(buffer, swprintf(buffer, 27, L"%llo", n) );
  374.                                 }
  375.                         }else if (stream.flags() & ios_base::hex){
  376.                                 if(stream.flags() & ios_base::showbase){
  377.                                         if(stream.flags() & ios_base::uppercase){
  378.                                                 stream.printout(buffer, swprintf(buffer, 27, L"%#llX", n) );
  379.                                         }else{
  380.                                                 stream.printout(buffer, swprintf(buffer, 27, L"%#llx", n) );
  381.                                         }
  382.                                 }else{
  383.                                         if(stream.flags() & ios_base::uppercase){
  384.                                                 stream.printout(buffer, swprintf(buffer, 27, L"%llX", n) );
  385.                                         }else{
  386.                                                 stream.printout(buffer, swprintf(buffer, 27, L"%llx", n) );
  387.                                         }
  388.                                 }
  389.                         }
  390.                         if(stream.flags() & ios_base::unitbuf){
  391.                                 stream.flush();
  392.                         }
  393.                 }
  394.         };
  395.  
  396.         template <class traits> class _UCXXEXPORT __ostream_printout<traits, wchar_t, unsigned long long int>{
  397.         public:
  398.                 static void printout(basic_ostream<wchar_t, traits >& stream, const unsigned long long int n)
  399.                 {
  400.                         wchar_t buffer[28];
  401.                         if( stream.flags() & ios_base::dec){
  402.                                 stream.printout(buffer, swprintf(buffer, 27, L"%llu", n));
  403.                         }else if( stream.flags() & ios_base::oct){
  404.                                 if( stream.flags() & ios_base::showbase){
  405.                                         stream.printout(buffer, swprintf(buffer, 27, L"%#llo", n));
  406.                                 }else{
  407.                                         stream.printout(buffer, swprintf(buffer, 27, L"%llo", n) );
  408.                                 }
  409.                         }else if (stream.flags() & ios_base::hex){
  410.                                 if(stream.flags() & ios_base::showbase){
  411.                                         if(stream.flags() & ios_base::uppercase){
  412.                                                 stream.printout(buffer, swprintf(buffer, 27, L"%#llX", n) );
  413.                                         }else{
  414.                                                 stream.printout(buffer, swprintf(buffer, 27, L"%#llx", n) );
  415.                                         }
  416.                                 }else{
  417.                                         if(stream.flags() & ios_base::uppercase){
  418.                                                 stream.printout(buffer, swprintf(buffer, 27, L"%llX", n) );
  419.                                         }else{
  420.                                                 stream.printout(buffer, swprintf(buffer, 27, L"%llx", n) );
  421.                                         }
  422.                                 }
  423.                         }
  424.                         if(stream.flags() & ios_base::unitbuf){
  425.                                 stream.flush();
  426.                         }
  427.                 }
  428.         };
  429.  
  430.  
  431. #endif  //__STRICT_ANSI__
  432.  
  433.         template <class traits> class _UCXXEXPORT __ostream_printout<traits, wchar_t, double>{
  434.         public:
  435.                 static void printout(basic_ostream<wchar_t, traits >& stream, const double f)
  436.                 {
  437.                         wchar_t buffer[32];
  438.                         wchar_t format_string[32];
  439.                         if(stream.flags() & ios_base::scientific){
  440.                                 if(stream.flags() & ios_base::uppercase){
  441.                                         swprintf(format_string, 32, L"%%%u.%uE", static_cast<int>(stream.width()), static_cast<unsigned int>(stream.precision()));
  442.                                 }else{
  443.                                         swprintf(format_string, 32, L"%%%u.%ue", static_cast<int>(stream.width()), static_cast<unsigned int>(stream.precision()));
  444.                                 }
  445.                         } else if(stream.flags() & ios_base::fixed){
  446.                                 swprintf(format_string, 32, L"%%%u.%uf", static_cast<int>(stream.width()), static_cast<unsigned int>(stream.precision()));
  447.                         } else {
  448.                                 swprintf(format_string, 32, L"%%%u.%ug", static_cast<int>(stream.width()), static_cast<unsigned int>(stream.precision()));
  449.                         }
  450.                         stream.printout(buffer, swprintf(buffer, 32, format_string, f) );
  451.                         if(stream.flags() & ios_base::unitbuf){
  452.                                 stream.flush();
  453.                         }
  454.                 }
  455.         };
  456.  
  457.         template <class traits> class _UCXXEXPORT __ostream_printout<traits, wchar_t, long double>{
  458.         public:
  459.                 static void printout(basic_ostream<wchar_t, traits >& stream, const long double f)
  460.                 {
  461.                         wchar_t buffer[32];
  462.                         wchar_t format_string[32];
  463.                         if(stream.flags() & ios_base::scientific){
  464.                                 if(stream.flags() & ios_base::uppercase){
  465.                                         swprintf(format_string, 32, L"%%%u.%uLE", static_cast<unsigned int>(stream.width()), static_cast<unsigned int>(stream.precision()));
  466.                                 }else{
  467.                                         swprintf(format_string, 32, L"%%%u.%uLe", static_cast<unsigned int>(stream.width()), static_cast<unsigned int>(stream.precision()));
  468.                                 }
  469.                         } else if(stream.flags() & ios_base::fixed){
  470.                                 swprintf(format_string, 32, L"%%%u.%uLf", static_cast<unsigned int>(stream.width()), static_cast<unsigned int>(stream.precision()));
  471.                         } else {
  472.                                 swprintf(format_string, 32, L"%%%u.%uLg", static_cast<unsigned int>(stream.width()), static_cast<unsigned int>(stream.precision()));
  473.                         }
  474.                         stream.printout(buffer, swprintf(buffer, 32, format_string, f) );
  475.                         if(stream.flags() & ios_base::unitbuf){
  476.                                 stream.flush();
  477.                         }
  478.                 }
  479.         };
  480.  
  481. #endif //__UCLIBCXX_HAS_WCHAR__
  482.  
  483. }
  484.  
  485. #pragma GCC visibility pop
  486.  
  487. #endif
  488.  
  489.  
  490.  
  491.