basix_doc 0.1
/Users/mourrain/Devel/mmx/basix/src/file_port.cpp
Go to the documentation of this file.
00001 
00002 /******************************************************************************
00003 * MODULE     : file_port.cpp
00004 * DESCRIPTION: Ports from file descriptors
00005 * COPYRIGHT  : (C) 2010  Joris van der Hoeven
00006 *******************************************************************************
00007 * This software falls under the GNU general public license and comes WITHOUT
00008 * ANY WARRANTY WHATSOEVER. See the file $TEXMACS_PATH/LICENSE for more details.
00009 * If you don't have this file, write to the Free Software Foundation, Inc.,
00010 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00011 ******************************************************************************/
00012 
00013 #include <basix/posix_port.hpp>
00014 #include <basix/system.hpp>
00015 
00017 
00018 namespace mmx {
00019 
00020 /******************************************************************************
00021 * File ports
00022 ******************************************************************************/
00023 
00024 class file_port_rep: public posix_port_rep {
00025   FILE*  f;
00026   bool   cf;
00027   string name;
00028   int    next;
00029 
00030 public:
00031   syntactic expression () const {
00032     if (this->kind == 1) return syn ("output_file_port", syntactic (name));
00033     if (this->kind == 2) return syn ("input_file_port", syntactic (name));
00034     return syn ("input_output_file_port", syntactic (name));
00035   }
00036 
00037   bool busy () {
00038     if (this->kind == 2) return can_read () > 0;
00039     return true;
00040   }
00041   nat can_write () {
00042     if (this->kind == 2) return 0;
00043     return (nat) (-1);
00044   }
00045   nat can_read () {
00046     if (next != -1) return 1;
00047     if (this->kind == 1 || feof (f) != 0) return 0;
00048     next= fgetc (f);
00049     if (next != -1) return 1;
00050     return 0;
00051   }
00052 
00053   void write (const char* s, nat n) {
00054     for (nat i=0; i<n; i++) fputc (s[i], f); }
00055   void read (char* s, nat n) {
00056     if (next != -1 && n > 0) { s[0]= next; s++; n--; next= -1; }
00057     for (nat i=0; i<n; i++) s[i]= fgetc (f); }
00058 
00059   void flush () { fflush (f); }
00060 
00061 public:
00062   inline file_port_rep (int kind, FILE* f2, bool cf2, const string& name2):
00063     posix_port_rep (kind, fileno (f2)),
00064     f (f2), cf (cf2), name (name2), next (-1) {}
00065   inline ~file_port_rep () {
00066     if (cf) fclose (f); }
00067 };
00068 
00069 port
00070 output_file_port (FILE* f, bool close_flag, const string& name) {
00071   return (port_rep*) new file_port_rep (1, f, close_flag, name);
00072 }
00073 
00074 port
00075 input_file_port (FILE* f, bool close_flag, const string& name) {
00076   return (port_rep*) new file_port_rep (2, f, close_flag, name);
00077 }
00078 
00079 port
00080 input_output_file_port (FILE* f, bool close_flag, const string& name) {
00081   return (port_rep*) new file_port_rep (3, f, close_flag, name);
00082 }
00083 
00084 /******************************************************************************
00085 * Standard constructors
00086 ******************************************************************************/
00087 
00088 table<int,int> out_count (0);
00089 table<int,int> in_count  (0);
00090 
00091 port mmin = input_file_port (stdin , false, "mmin");
00092 port mmout= formatting_port (output_file_port (stdout, false, "mmout"));
00093 port mmerr= formatting_port (output_file_port (stderr, false, "mmerr"));
00094 
00095 port
00096 output_file_port (const string& name) {
00097   string name_s= decode_name (name);
00098   char* temp= as_charp (name_s);
00099   FILE* f= fopen (temp, "w");
00100   free_charp (temp);
00101   if (f == NULL) return error_port ("file '" * name * "' not writable");
00102   return output_file_port (f, true, name);
00103 }
00104 
00105 port
00106 input_file_port (const string& name) {
00107   string name_s= decode_name (name);
00108   char* temp= as_charp (name_s);
00109   FILE* f= fopen (temp, "r");
00110   free_charp (temp);
00111   if (f == NULL) return error_port ("file '" * name * "' not found");
00112   return input_file_port (f, true, name);
00113 }
00114 
00115 port
00116 input_output_file_port (const string& name) {
00117   string name_s= decode_name (name);
00118   char* temp= as_charp (name_s);
00119   FILE* f= fopen (temp, "w+");
00120   free_charp (temp);
00121   if (f == NULL) return error_port ("file '" * name * "' did not open");
00122   return input_output_file_port (f, true, name);
00123 }
00124 
00125 } // namespace mmx
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines