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.         This library is free software; you can redistribute it and/or
  5.         modify it under the terms of the GNU Lesser General Public
  6.         License as published by the Free Software Foundation; either
  7.         version 2.1 of the License, or (at your option) any later version.
  8.  
  9.         This library is distributed in the hope that it will be useful,
  10.         but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.         MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  12.         Lesser General Public License for more details.
  13.  
  14.         You should have received a copy of the GNU Lesser General Public
  15.         License along with this library; if not, write to the Free Software
  16.         Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  17. */
  18.  
  19. #ifndef __STD_HEADER_FSTREAM
  20. #define __STD_HEADER_FSTREAM 1
  21.  
  22.  
  23. #include<basic_definitions>
  24.  
  25. #include <cstdio>
  26. #include <cstdlib>
  27. #include <streambuf>
  28. #include <istream>
  29. #include <ostream>
  30. #include <char_traits>
  31.  
  32. #include <unistd.h>
  33. #include <fcntl.h>
  34. #include <errno.h>
  35.  
  36. #ifdef __UCLIBCXX_HAS_WCHAR__
  37. #include <cwchar>
  38. #include <cwctype>
  39. #endif //__UCLIBCXX_HAS_WCHAR__
  40.  
  41. #pragma GCC visibility push(default)
  42.  
  43. namespace std{
  44.  
  45.         template <class C, class T> class basic_filebuf;
  46.  
  47.         typedef basic_filebuf<char>    filebuf;
  48. #ifdef __UCLIBCXX_HAS_WCHAR__
  49.         typedef basic_filebuf<wchar_t> wfilebuf;
  50. #endif
  51.  
  52.  
  53.         template <class charT, class traits> class _UCXXEXPORT basic_filebuf
  54.                 : public basic_streambuf<charT,traits>
  55.         {
  56. #ifdef __UCLIBCXX_SUPPORT_CDIR__
  57.                 friend ios_base::Init::Init();  //Needed for cout/cin stuff
  58. #endif
  59.         public:
  60.                 // Types (inherited from basic_streambuf:
  61.                 typedef typename basic_streambuf<charT, traits>::char_type      char_type;
  62.                 typedef typename basic_streambuf<charT, traits>::int_type       int_type;
  63.                 typedef typename basic_streambuf<charT, traits>::pos_type       pos_type;
  64.                 typedef typename basic_streambuf<charT, traits>::off_type       off_type;
  65.                 typedef traits                                                  traits_type;
  66.  
  67.                 //Constructors/destructor:
  68.  
  69.                 _UCXXEXPORT basic_filebuf()     : basic_streambuf<charT, traits>(), fp(0), pbuffer(0), gbuffer(0)
  70.                 {
  71.                         append=false;
  72.                         pbuffer = new char_type[__UCLIBCXX_IOSTREAM_BUFSIZE__];
  73.                         gbuffer = new char_type[__UCLIBCXX_IOSTREAM_BUFSIZE__];
  74.  
  75.                         this->setp(pbuffer, pbuffer + __UCLIBCXX_IOSTREAM_BUFSIZE__);
  76.                         //Position get buffer so that there is no data available
  77.                         this->setg(gbuffer, gbuffer + __UCLIBCXX_IOSTREAM_BUFSIZE__,
  78.                                 gbuffer + __UCLIBCXX_IOSTREAM_BUFSIZE__);
  79.                 }
  80.  
  81.  
  82.                 _UCXXEXPORT virtual ~basic_filebuf(){
  83.                         sync();
  84.                         close();
  85.                         delete [] pbuffer;
  86.                         delete [] gbuffer;
  87.                         pbuffer = 0;
  88.                         gbuffer = 0;
  89.                 }
  90.  
  91.  
  92.                 //Members:
  93.  
  94.                 _UCXXEXPORT bool is_open() const{
  95.                         if(fp == 0){
  96.                                 return false;
  97.                         }
  98.                         return true;
  99.                 }
  100.  
  101.                 _UCXXEXPORT basic_filebuf<charT,traits>* open(const char* s, ios_base::openmode mode){
  102.                         bool move_end = (mode & ios_base::ate) != 0;
  103.                         if(is_open() !=false){  //Must call close() first
  104.                                 return 0;
  105.                         }
  106.                         basic_streambuf<charT,traits>::openedFor = mode;
  107.                         mode = mode & ~ios_base::ate;
  108.  
  109.                         if(mode == ios_base::out || mode == (ios_base::out | ios_base::trunc)){
  110.                                 fp = fopen(s, "w" );
  111.                         }else if((mode & ios_base::app) && ! (mode & ios_base::trunc)){
  112.                                 if(mode & ios_base::binary){
  113.                                         if(mode & ios_base::in){
  114.                                                 fp = fopen(s, "a+b");
  115.                                         }else{
  116.                                                 fp = fopen(s, "ab");
  117.                                         }
  118.                                 }else{
  119.                                         if(mode & ios_base::in){
  120.                                                 fp = fopen(s, "a+");
  121.                                         }else{
  122.                                                 fp = fopen(s, "a");
  123.                                         }
  124.                                 }
  125.                         }else if(mode == ios_base::in){
  126.                                 fp = fopen(s, "r");
  127.                         }else if(mode == (ios_base::in | ios_base::out)){
  128.                                 fp = fopen(s, "r+");
  129.                         }else if(mode == (ios_base::in | ios_base::out | ios_base::trunc)){
  130.                                 fp = fopen(s, "w+");
  131.                         }else if(mode == (ios_base::binary | ios_base::out)){
  132.                                 fp = fopen(s, "wb");
  133.                         }else if(mode == (ios_base::in | ios_base::binary)){
  134.                                 fp = fopen(s, "rb");
  135.                         }else if(mode == (ios_base::in | ios_base::binary | ios_base::out)){
  136.                                 fp = fopen(s, "r+b");
  137.                         }else if(mode==(ios_base::binary | ios_base::out | ios_base::trunc)){
  138.                                 fp = fopen(s, "w+b");
  139.                         }else if(mode == (ios_base::in | ios_base::binary | ios_base::out | ios_base::trunc)){
  140.                                 fp = fopen(s, "w+b");
  141.                         }
  142.  
  143.                         if(fp == 0){
  144.                                 return 0;
  145.                         }
  146.                         if(ferror(fp)){
  147.                                 fclose(fp);
  148.                                 fp=0;
  149.                                 return 0;
  150.                         }
  151.                         int retval = 0;
  152.  
  153.                         //Check to make sure the stream is good
  154.                         if(move_end == true){
  155.                                 retval = fseek(fp, 0, SEEK_END);
  156.                         }else{
  157.                                 retval = fseek(fp, 0, SEEK_SET);
  158.                         }
  159.                         if(retval!=0){          //Seek error
  160.                                 fclose(fp);
  161.                                 fp=0;
  162.                                 return 0;
  163.                         }
  164.  
  165.                         basic_streambuf<charT,traits>::mgnext = basic_streambuf<charT,traits>::mgend;
  166.  
  167.                         return this;
  168.                 }
  169.                 _UCXXEXPORT basic_filebuf<charT,traits>* close(){
  170.                         if(fp != 0 && fp != stdin && fp != stdout && fp !=stderr ){
  171.                                 overflow();
  172.                                 sync();
  173.                                 int retval = fclose(fp);
  174.                                 if(retval !=0){         //Error of some sort
  175.                                         return 0;
  176.                                 }
  177.                                 fp=0;
  178.                         }
  179.                         return this;
  180.                 }
  181.         protected:
  182.                 _UCXXEXPORT basic_filebuf(const basic_filebuf<charT,traits> &){ }
  183.                 _UCXXEXPORT basic_filebuf<charT,traits> & operator=(const basic_filebuf<charT,traits> &){ return *this; }
  184.  
  185.                 //Overridden virtual functions:
  186.  
  187.                 virtual _UCXXEXPORT int showmanyc(){
  188.                         return basic_streambuf<charT,traits>::egptr() - basic_streambuf<charT,traits>::gptr();
  189.                 }
  190.                 virtual _UCXXEXPORT int_type underflow(){
  191.                         /* Some variables used internally:
  192.                            Buffer pointers:
  193.                            charT * mgbeg;
  194.                            charT * mgnext;
  195.                            charT * mgend;
  196.  
  197.                            eback() returns mgbeg
  198.                            gptr()  returns mgnext
  199.                            egptr() returns mgend
  200.  
  201.                            gbump(int n) mgnext+=n
  202.  
  203.                         */
  204.  
  205.                         if(!is_open()){
  206.                                 return traits::eof();
  207.                         }
  208.  
  209.                         if(basic_streambuf<charT,traits>::eback() == 0){
  210.                                 //No buffer, so...
  211.                                 charT c;
  212.                                 int retval;
  213.                                 retval = fread(&c, sizeof(charT), 1, fp);
  214.  
  215.                                 if(retval == 0 || feof(fp) || ferror(fp) ){
  216.                                         return traits::eof();
  217.                                 }
  218.                                 return traits::to_int_type(c);
  219.                         }
  220.  
  221.                         if(basic_streambuf<charT,traits>::eback() == basic_streambuf<charT,traits>::gptr()){    //Buffer is full
  222.                                 return traits::to_int_type(*basic_streambuf<charT,traits>::gptr());
  223.                         }
  224.                         //Shift entire buffer back to the begining
  225.                         size_t offset = basic_streambuf<charT,traits>::gptr() - basic_streambuf<charT,traits>::eback();
  226.                         size_t amountData = basic_streambuf<charT,traits>::egptr() - basic_streambuf<charT,traits>::gptr();
  227.  
  228.                         for(charT * i = basic_streambuf<charT,traits>::gptr(); i < basic_streambuf<charT,traits>::egptr(); ++i){
  229.                                 *(i-offset) = *i;
  230.                         }
  231.  
  232.                         size_t retval = 0;
  233.                         //Save operating flags from file descriptor
  234.                         int fcntl_flags = fcntl(fileno(fp), F_GETFL);
  235.                         retval = 0;
  236.  
  237.                         //Set to non_blocking mode
  238.                         fcntl(fileno(fp), F_SETFL, fcntl_flags | O_NONBLOCK);
  239.  
  240.                         //Fill rest of buffer
  241.                         retval = fread(basic_streambuf<charT,traits>::egptr() -
  242.                                 basic_streambuf<charT,traits>::gptr() + basic_streambuf<charT,traits>::eback(),
  243.                                 sizeof(charT),
  244.                                 offset,
  245.                                 fp
  246.                         );
  247.  
  248.                         //Clear problems where we didn't read in enough characters
  249.                         if(EAGAIN == errno){
  250.                                 clearerr(fp);
  251.                         }
  252.  
  253.                         //Restore file descriptor clase
  254.                         fcntl(fileno(fp), F_SETFL, fcntl_flags);
  255.  
  256.                         //Now we are going to make sure that we read in at least one character.  The hard way.
  257.                         if(retval == 0){
  258.                                 fcntl_flags = fcntl(fileno(fp), F_GETFL);
  259.                                 //Set to blocking mode
  260.                                 fcntl(fileno(fp), F_SETFL, fcntl_flags & ~O_NONBLOCK);
  261.  
  262.                                 retval = fread(basic_streambuf<charT,traits>::egptr() -
  263.                                         basic_streambuf<charT,traits>::gptr() + basic_streambuf<charT,traits>::eback(),
  264.                                         sizeof(charT),
  265.                                         1,
  266.                                         fp
  267.                                 );
  268.  
  269.                                 //Restore file descriptor clase
  270.                                 fcntl(fileno(fp), F_SETFL, fcntl_flags);
  271.  
  272.                         }
  273.  
  274.                         if(retval !=offset){ //Slide buffer forward again
  275.                                 for(size_t i = 0; i < amountData + retval; ++i){
  276.                                         *(basic_streambuf<charT,traits>::egptr() - i - 1) =
  277.                                                 *(basic_streambuf<charT,traits>::eback() + amountData + retval - i - 1);
  278.                                 }
  279.                         }
  280.  
  281.                         basic_streambuf<charT,traits>::mgnext -= retval;
  282.  
  283.                         if( (retval <= 0 && feof(fp)) || ferror(fp) ){
  284.                                 return traits::eof();
  285.                         }
  286.  
  287.                         return traits::to_int_type(*basic_streambuf<charT,traits>::gptr());
  288.                 }
  289.                 virtual _UCXXEXPORT int_type uflow(){
  290.                         bool dobump = (basic_streambuf<charT,traits>::gptr() != 0);
  291.                         int_type retval = underflow();
  292.                         if(dobump){
  293.                                 basic_streambuf<charT,traits>::gbump(1);
  294.                         }
  295.                         return retval;
  296.                 }
  297.                 virtual _UCXXEXPORT int_type pbackfail(int_type c = traits::eof()){
  298.                         if(is_open() == false ||
  299.                                 basic_streambuf<charT,traits>::gptr() == basic_streambuf<charT,traits>::eback())
  300.                         {
  301.                                 return traits::eof();
  302.                         }
  303.                         if(traits::eq_int_type(c,traits::eof()) == false){
  304.                                 if(traits::eq(traits::to_char_type(c), basic_streambuf<charT,traits>::gptr()[-1]) == true){
  305.                                         basic_streambuf<charT,traits>::gbump(-1);
  306.                                 }else{
  307.                                         basic_streambuf<charT,traits>::gbump(-1);
  308.                                         basic_streambuf<charT,traits>::gptr()[0] = c;
  309.                                 }
  310.                                 return c;
  311.                         }else{
  312.                                 basic_streambuf<charT,traits>::gbump(-1);
  313.                                 return traits::not_eof(c);
  314.                         }
  315.                 }
  316.  
  317.                 virtual _UCXXEXPORT int_type overflow(int_type c = traits::eof()){
  318.                         if(is_open() == false){
  319.                                 //Can't do much
  320.                                 return traits::eof();
  321.                         }
  322.                         if(basic_streambuf<charT,traits>::pbase() == 0){                //Unbuffered - elliminate dupe code below
  323.                                 if(fputc(c, fp) == EOF){
  324.                                         return traits::eof();
  325.                                 }
  326.                                 return c;
  327.                         }
  328.                         if(basic_streambuf<charT,traits>::pbase() == 0 && traits::eq_int_type(c,traits::eof()) ){
  329.                                 //Nothing to flush
  330.                                 return traits::not_eof(c);
  331.                         }
  332.                         size_t r = basic_streambuf<charT,traits>::pptr() - basic_streambuf<charT,traits>::pbase();
  333.  
  334.                         if( r == 0 && traits::eq_int_type(c,traits::eof()) ){
  335.                                 return traits::not_eof(c);
  336.                         }else if (r == 0 ){
  337.                                 if(fputc(c, fp) == EOF){
  338.                                         return traits::eof();
  339.                                 }
  340.                                 return c;
  341.                         }
  342.  
  343.                         size_t totalChars = r;
  344.  
  345.                         char_type *buffer = 0;
  346.                         if(traits::eq_int_type(c,traits::eof())){
  347.                                 buffer = new char_type[r];
  348.                         }else{
  349.                                 buffer = new char_type[r+1];
  350.                                 buffer[r] = c;
  351.                                 totalChars++;
  352.                         }
  353.  
  354.                         traits::copy(buffer, basic_streambuf<charT,traits>::pbase(), r);
  355. //                      memcpy(buffer, basic_streambuf<charT,traits>::pbase(), r);
  356.  
  357.                         size_t retval = fwrite(buffer, sizeof(charT), totalChars, fp);
  358.                         if(retval !=totalChars){
  359.                                 if(retval == 0){
  360.                                         delete [] buffer;
  361.                                         return traits::eof();
  362.                                 }
  363.                                 basic_streambuf<charT,traits>::pbump(-retval);
  364.                                 fprintf(stderr, "***** Did not write the full buffer out.  Should be: %d, actually: %d\n",
  365.                                          totalChars, retval);
  366.                         }else{
  367.                                 basic_streambuf<charT,traits>::pbump(-r);
  368.                         }
  369.  
  370.                         delete [] buffer;
  371.                         return traits::not_eof(c);
  372.                 }
  373.  
  374.                 virtual _UCXXEXPORT basic_streambuf<charT,traits>* setbuf(char_type* s, streamsize n){
  375.                         if(s == 0 && n == 0){   //Unbuffered
  376.                                 if(pbuffer !=0){
  377.                                         delete [] pbuffer;
  378.                                 }
  379.                                 if(gbuffer !=0){
  380.                                         delete [] gbuffer;
  381.                                 }
  382.                                 pbuffer = 0;
  383.                                 gbuffer = 0;
  384.                         }else if(basic_streambuf<charT,traits>::gptr() !=0 &&
  385.                                 basic_streambuf<charT,traits>::gptr()==basic_streambuf<charT,traits>::egptr())
  386.                         {
  387.                                 delete [] pbuffer;
  388.                                 pbuffer = s;
  389.                         }
  390.                         return this;
  391.                 }
  392.                 virtual _UCXXEXPORT pos_type seekoff(off_type off, ios_base::seekdir way,
  393.                         ios_base::openmode = ios_base::in | ios_base::out)
  394.                 {
  395.                         if(is_open() == false){
  396.                                 return -1;
  397.                         }
  398.                         int whence = SEEK_SET;  // if(way == basic_ios<charT>::beg)
  399.                         off_type position = off;
  400.  
  401.                         if(way == basic_ios<charT>::cur){
  402.                                 whence = SEEK_CUR;
  403.                                 position -= (basic_streambuf<charT,traits>::egptr() - basic_streambuf<charT,traits>::gptr());
  404.                         }else if(way == basic_ios<charT>::end){
  405.                                 whence = SEEK_END;
  406.                         }
  407.  
  408.                         sync();
  409.  
  410.                         int retval = fseek(
  411.                                 fp,
  412.                                 sizeof(charT)*(position),
  413.                                 whence
  414.                         );
  415.  
  416.                         //Invalidate read buffer
  417.                         basic_streambuf<charT,traits>::gbump(
  418.                                 basic_streambuf<charT,traits>::egptr() - basic_streambuf<charT,traits>::gptr()
  419.                         );
  420.  
  421.                         if(-1 != retval){
  422.                                 retval = ftell(fp);
  423.                         }
  424.  
  425.                         return retval;
  426.                 }
  427.                 virtual _UCXXEXPORT pos_type seekpos(pos_type sp, ios_base::openmode = ios_base::in | ios_base::out){
  428.                         if(is_open() == false){
  429.                                 return -1;
  430.                         }
  431.                         sync();
  432.  
  433.                         int retval = fseek(fp,sizeof(charT)* sp, SEEK_SET);
  434.  
  435.                         //Invalidate read buffer
  436.                         basic_streambuf<charT,traits>::gbump(basic_streambuf<charT,traits>::egptr() - basic_streambuf<charT,traits>::gptr());
  437.                         if(retval > -1){
  438.                                 return sp;
  439.                         }
  440.                         return -1;
  441.                 }
  442.                 virtual _UCXXEXPORT int sync(){
  443.                         if(pbuffer !=0){
  444.                                 if(overflow() == traits::eof()){
  445.                                         return -1;
  446.                                 }
  447.                         }
  448.                         if(0 != fp && 0 != fflush(fp)){
  449.                                 return -1;
  450.                         }
  451.                         return 0;
  452.                 }
  453.                 virtual _UCXXEXPORT void imbue(const locale&){
  454.                         return;
  455.                 }
  456.  
  457.  
  458.                 virtual _UCXXEXPORT streamsize xsputn(const char_type* s, streamsize n){
  459.                         if(is_open() == false){
  460.                                 return 0;
  461.                         }
  462.                         //Check to see if buffered
  463.  
  464.                         //Check to see if we can buffer the data
  465.                         streamsize buffer_avail = basic_streambuf<charT,traits>::epptr() - basic_streambuf<charT,traits>::pptr();
  466.  
  467.                         if(n > buffer_avail){           //Flush buffer and write directly
  468.                                 overflow();     //Flush the buffer
  469.                                 return fwrite(s, sizeof(charT), n, fp);
  470.                         }
  471.  
  472.                         //Add to buffer to be written later
  473.  
  474.                         traits::copy(basic_streambuf<charT,traits>::pptr(), s, n);
  475.                         basic_streambuf<charT,traits>::pbump(n);
  476.  
  477.                         return n;
  478.                 }
  479.  
  480.                 FILE * fp;
  481.                 char_type * pbuffer;
  482.                 char_type * gbuffer;
  483.                 bool append;
  484.         };
  485.  
  486.  
  487. #ifdef __UCLIBCXX_HAS_WCHAR__
  488.  
  489. template <> _UCXXEXPORT basic_filebuf<wchar_t, char_traits<wchar_t> >::int_type
  490.         basic_filebuf<wchar_t, char_traits<wchar_t> >::overflow(int_type c);
  491.  
  492. template <> _UCXXEXPORT basic_filebuf<wchar_t, char_traits<wchar_t> >::int_type
  493.         basic_filebuf<wchar_t, char_traits<wchar_t> >::underflow();
  494.  
  495. #endif //__UCLIBCXX_HAS_WCHAR__
  496.  
  497.  
  498.  
  499. #ifdef __UCLIBCXX_EXPAND_FSTREAM_CHAR__
  500. #ifndef __UCLIBCXX_COMPILE_FSTREAM__
  501.  
  502. #ifdef __UCLIBCXX_EXPAND_CONSTRUCTORS_DESTRUCTORS__
  503.  
  504.         template <> _UCXXEXPORT filebuf::basic_filebuf();
  505.         template <> _UCXXEXPORT filebuf::~basic_filebuf();
  506.  
  507. #endif // __UCLIBCXX_EXPAND_CONSTRUCTORS_DESTRUCTORS__
  508.  
  509.         template <> _UCXXEXPORT filebuf::int_type filebuf::pbackfail(filebuf::int_type c);
  510.         template <> _UCXXEXPORT filebuf * filebuf::open(const char* s, ios_base::openmode mode);
  511.         template <> _UCXXEXPORT filebuf * filebuf::close();
  512.         template <> _UCXXEXPORT filebuf::int_type filebuf::overflow(filebuf::int_type c);
  513.         template <> _UCXXEXPORT filebuf::int_type filebuf::underflow ();
  514.  
  515.         template <> _UCXXEXPORT basic_streambuf<char, char_traits<char> > * filebuf::setbuf(char * s, streamsize n);
  516.         template <> _UCXXEXPORT streamsize filebuf::xsputn(const char* s, streamsize n);
  517.  
  518. #endif
  519. #endif
  520.  
  521.  
  522.         template <class charT, class traits> class _UCXXEXPORT basic_ifstream
  523.                 : public basic_istream<charT,traits>
  524.         {
  525.         public:
  526.                 typedef charT char_type;
  527.                 typedef typename traits::int_type int_type;
  528.                 typedef typename traits::pos_type pos_type;
  529.                 typedef typename traits::off_type off_type;
  530.  
  531.                 _UCXXEXPORT basic_ifstream(): basic_ios<charT, traits>(&sb), basic_istream<charT,traits>(&sb){
  532.                         //Passing the address of sb
  533.                 }
  534.                 explicit _UCXXEXPORT basic_ifstream(const char* s, ios_base::openmode mode = ios_base::in)
  535.                         : basic_ios<charT, traits>(&sb), basic_istream<charT,traits>(&sb)
  536.                 {
  537.                         if(sb.open(s, mode) == 0){
  538.                                 basic_ios<charT,traits>::setstate(ios_base::failbit);
  539.                         }
  540.                 }
  541.  
  542.                 virtual _UCXXEXPORT ~basic_ifstream(){
  543.  
  544.                 }
  545.  
  546.                 _UCXXEXPORT basic_filebuf<charT,traits>* rdbuf() const{
  547.                         return (basic_filebuf<charT,traits>*)&sb;
  548.                 }
  549.                 _UCXXEXPORT bool is_open() const{
  550.                         return sb.is_open();
  551.                 }
  552.                 _UCXXEXPORT void open(const char* s, ios_base::openmode mode = ios_base::in){
  553.                         if(sb.open(s, mode) == 0){
  554.                                 basic_ios<charT,traits>::setstate(ios_base::failbit);
  555.                         }
  556.                 }
  557.                 _UCXXEXPORT void close(){
  558.                         sb.close();
  559.                 }
  560.         private:
  561.                 basic_filebuf<charT,traits> sb;
  562.         };
  563.  
  564.  
  565.         template <class charT, class traits> class _UCXXEXPORT basic_ofstream
  566.                 : public basic_ostream<charT,traits>
  567.         {
  568.         public:
  569.                 typedef charT char_type;
  570.                 typedef typename traits::int_type int_type;
  571.                 typedef typename traits::pos_type pos_type;
  572.                 typedef typename traits::off_type off_type;
  573.  
  574.                 _UCXXEXPORT basic_ofstream() : basic_ios<charT, traits>(&sb), basic_ostream<charT,traits>(&sb){
  575.  
  576.                 }
  577.  
  578.                 virtual _UCXXEXPORT ~basic_ofstream();
  579.  
  580.                 explicit _UCXXEXPORT basic_ofstream(const char* s, ios_base::openmode mode = ios_base::out | ios_base::trunc) :
  581.                         basic_ios<charT, traits>(&sb), basic_ostream<charT,traits>(&sb)
  582.                 {
  583.                         if(sb.open(s, mode | ios_base::out ) == 0){
  584.                                 basic_ios<charT,traits>::setstate(ios_base::failbit);
  585.                         }
  586.                 }
  587.  
  588.                 _UCXXEXPORT basic_filebuf<charT,traits>* rdbuf() const{
  589.                         return (basic_filebuf<charT,traits>*)&sb;
  590.                 }
  591.  
  592.                 _UCXXEXPORT bool is_open() const{
  593.                         return sb.is_open();
  594.                 }
  595.                 _UCXXEXPORT void open(const char* s, ios_base::openmode mode = ios_base::out | ios_base::trunc){
  596.                         if(sb.open(s, mode) == 0){
  597.                                 basic_ios<charT,traits>::setstate(ios_base::failbit);
  598.                         }
  599.                 }
  600.                 _UCXXEXPORT void close(){
  601.                         sb.close();
  602.                 }
  603.         private:
  604.                 basic_filebuf<charT,traits> sb;
  605.         };
  606.  
  607.         template <class charT, class traits> _UCXXEXPORT basic_ofstream<charT, traits>::~basic_ofstream(){
  608.                 basic_ostream<charT, traits>::flush();
  609.         }
  610.  
  611.  
  612.         template <class charT, class traits> class _UCXXEXPORT basic_fstream
  613.                 : public basic_iostream<charT,traits>
  614.         {
  615.         public:
  616.                 typedef charT char_type;
  617.                 typedef typename traits::int_type ins_type;
  618.                 typedef typename traits::pos_type pos_type;
  619.                 typedef typename traits::off_type off_type;
  620.  
  621.                 _UCXXEXPORT basic_fstream(): basic_ios<charT, traits>(&sb), basic_iostream<charT,traits>(&sb){ }
  622.  
  623.                 explicit _UCXXEXPORT basic_fstream(const char* s, ios_base::openmode mode = ios_base::in|ios_base::out):
  624.                         basic_ios<charT, traits>(&sb), basic_iostream<charT,traits>(&sb)
  625.                 {
  626.                         if(sb.open(s, mode) == 0){
  627.                                 basic_ios<charT,traits>::setstate(ios_base::failbit);
  628.                         }
  629.                 }
  630.  
  631.                 _UCXXEXPORT basic_filebuf<charT,traits>* rdbuf() const{
  632.                         return (basic_filebuf<charT,traits>*)&sb;
  633.                 }
  634.                 _UCXXEXPORT bool is_open() const{
  635.                         return sb.is_open();
  636.                 }
  637.                 _UCXXEXPORT void open(const char* s, ios_base::openmode mode = ios_base::in|ios_base::out){
  638.                         if(sb.open(s, mode) == 0){
  639.                                 basic_ios<charT,traits>::setstate(ios_base::failbit);
  640.                         }
  641.                 }
  642.                 _UCXXEXPORT void close(){
  643.                         sb.close();
  644.                 }
  645.         private:
  646.                 basic_filebuf<charT,traits> sb;
  647.         };
  648.  
  649.  
  650.  
  651. #ifdef __UCLIBCXX_EXPAND_FSTREAM_CHAR__
  652. #ifndef __UCLIBCXX_COMPILE_FSTREAM__
  653.  
  654. #ifdef __UCLIBCXX_EXPAND_CONSTRUCTORS_DESTRUCTORS__
  655.  
  656.         template <> _UCXXEXPORT basic_ofstream<char, char_traits<char> >::basic_ofstream();
  657.         template <> _UCXXEXPORT basic_ofstream<char, char_traits<char> >::basic_ofstream(const char* s, ios_base::openmode mode);
  658.         template <> _UCXXEXPORT basic_ofstream<char, char_traits<char> >::~basic_ofstream();
  659.  
  660.         template <> _UCXXEXPORT basic_ifstream<char, char_traits<char> >::basic_ifstream();
  661.         template <> _UCXXEXPORT basic_ifstream<char, char_traits<char> >::basic_ifstream(const char* s, ios_base::openmode mode);
  662.         template <> _UCXXEXPORT basic_ifstream<char, char_traits<char> >::~basic_ifstream();
  663.  
  664. #endif // __UCLIBCXX_EXPAND_CONSTRUCTORS_DESTRUCTORS__
  665.  
  666. #endif
  667. #endif
  668.  
  669.  
  670.  
  671. }
  672.  
  673. #pragma GCC visibility pop
  674.  
  675. #endif
  676.  
  677.