OSDN Git Service

* config/os/irix/irix6.5/os_defines.h (_GLIBCXX_FIONREAD_TAKES_OFF_T):
[pf3gnuchains/gcc-fork.git] / libstdc++-v3 / config / io / basic_file_stdio.cc
index e03e869..8cba0db 100644 (file)
@@ -1,6 +1,6 @@
 // Wrapper of C-language FILE struct -*- C++ -*-
 
-// Copyright (C) 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+// Copyright (C) 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
 //
 // This file is part of the GNU ISO C++ Library.  This library is free
 // software; you can redistribute it and/or modify it under the
 
 #include <limits> // For <off_t>::max() and min()
 
+namespace __gnu_internal
+{
+  // Map ios_base::openmode flags to a string for use in fopen().
+  // Table of valid combinations as given in [lib.filebuf.members]/2.
+  static const char*
+  fopen_mode(std::ios_base::openmode mode)
+  {
+    enum 
+      {
+       in     = std::ios_base::in,
+       out    = std::ios_base::out,
+       trunc  = std::ios_base::trunc,
+       app    = std::ios_base::app,
+       binary = std::ios_base::binary
+      };
+    
+    switch (mode & (in|out|trunc|app|binary))
+      {
+      case (   out                 ): return "w";  
+      case (   out      |app       ): return "a";  
+      case (   out|trunc           ): return "w";  
+      case (in                     ): return "r";  
+      case (in|out                 ): return "r+"; 
+      case (in|out|trunc           ): return "w+"; 
+       
+      case (   out          |binary): return "wb"; 
+      case (   out      |app|binary): return "ab"; 
+      case (   out|trunc    |binary): return "wb"; 
+      case (in              |binary): return "rb"; 
+      case (in|out          |binary): return "r+b";
+      case (in|out|trunc    |binary): return "w+b";
+       
+      default: return 0; // invalid
+      }
+  }
+} // namespace __gnu_internal
+
 namespace std 
 {
   // Definitions for __basic_file<char>.
@@ -79,53 +116,6 @@ namespace std
   __basic_file<char>::~__basic_file()
   { this->close(); }
       
-  void 
-  __basic_file<char>::_M_open_mode(ios_base::openmode __mode, int& __p_mode, 
-                                  int&, char* __c_mode)
-  {  
-    bool __testb = __mode & ios_base::binary;
-    bool __testi = __mode & ios_base::in;
-    bool __testo = __mode & ios_base::out;
-    bool __testt = __mode & ios_base::trunc;
-    bool __testa = __mode & ios_base::app;
-      
-    // Set __c_mode for use in fopen.
-    // Set __p_mode for use in open.
-    if (!__testi && __testo && !__testt && !__testa)
-      {
-       strcpy(__c_mode, "w");
-       __p_mode = O_WRONLY | O_CREAT;
-      }
-    if (!__testi && __testo && !__testt && __testa)
-      {
-       strcpy(__c_mode, "a");
-       __p_mode = O_WRONLY | O_CREAT | O_APPEND;
-      }
-    if (!__testi && __testo && __testt && !__testa)
-      {
-       strcpy(__c_mode, "w");
-       __p_mode = O_WRONLY | O_CREAT | O_TRUNC;
-      }
-
-    if (__testi && !__testo && !__testt && !__testa)
-      {
-       strcpy(__c_mode, "r");
-       __p_mode = O_RDONLY;
-      }
-    if (__testi && __testo && !__testt && !__testa)
-      {
-       strcpy(__c_mode, "r+");
-       __p_mode = O_RDWR | O_CREAT;
-      }
-    if (__testi && __testo && __testt && !__testa)
-      {
-       strcpy(__c_mode, "w+");
-       __p_mode = O_RDWR | O_CREAT | O_TRUNC;
-      }
-    if (__testb)
-      strcat(__c_mode, "b");
-  }
-  
   __basic_file<char>*
   __basic_file<char>::sys_open(__c_file* __file, ios_base::openmode) 
   {
@@ -134,6 +124,7 @@ namespace std
       {
        _M_cfile = __file;
        _M_cfile_created = false;
+       this->sync();
        __ret = this;
       }
     return __ret;
@@ -143,12 +134,9 @@ namespace std
   __basic_file<char>::sys_open(int __fd, ios_base::openmode __mode)
   {
     __basic_file* __ret = NULL;
-    int __p_mode = 0;
-    int __rw_mode = 0;
-    char __c_mode[4];
-    
-    _M_open_mode(__mode, __p_mode, __rw_mode, __c_mode);
-    if (!this->is_open() && (_M_cfile = fdopen(__fd, __c_mode)))
+    const char* __c_mode = __gnu_internal::fopen_mode(__mode);
+    if (__c_mode && !this->is_open() 
+       && (_M_cfile = fdopen(__fd, __c_mode)))
       {
        _M_cfile_created = true;
        if (__fd == 0)
@@ -163,13 +151,8 @@ namespace std
                           int /*__prot*/)
   {
     __basic_file* __ret = NULL;
-    int __p_mode = 0;
-    int __rw_mode = 0;
-    char __c_mode[4];
-      
-    _M_open_mode(__mode, __p_mode, __rw_mode, __c_mode);
-
-    if (!this->is_open())
+    const char* __c_mode = __gnu_internal::fopen_mode(__mode);
+    if (__c_mode && !this->is_open())
       {
 #ifdef _GLIBCXX_USE_LFS
        if ((_M_cfile = fopen64(__name, __c_mode)))
@@ -201,7 +184,7 @@ namespace std
        if (_M_cfile_created)
          fclose(_M_cfile);
        else
-         fflush(_M_cfile);
+         this->sync();
        _M_cfile = 0;
        __ret = this;
       }
@@ -284,7 +267,11 @@ namespace std
   {
 #ifdef FIONREAD
     // Pipes and sockets.    
+#ifdef _GLIBCXX_FIONREAD_TAKES_OFF_T
+    off_t __num = 0;
+#else
     int __num = 0;
+#endif
     int __r = ioctl(this->fd(), FIONREAD, &__num);
     if (!__r && __num >= 0)
       return __num; 
@@ -308,5 +295,4 @@ namespace std
 #endif
     return 0;
   }
-
 }  // namespace std