home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / octa21fs.zip / octave / octave-2.1.23 / src / oct-stream.h < prev    next >
C/C++ Source or Header  |  2000-01-15  |  14KB  |  559 lines

  1. /*
  2.  
  3. Copyright (C) 1996, 1997 John W. Eaton
  4.  
  5. This file is part of Octave.
  6.  
  7. Octave is free software; you can redistribute it and/or modify it
  8. under the terms of the GNU General Public License as published by the
  9. Free Software Foundation; either version 2, or (at your option) any
  10. later version.
  11.  
  12. Octave is distributed in the hope that it will be useful, but WITHOUT
  13. ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  14. FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  15. for more details.
  16.  
  17. You should have received a copy of the GNU General Public License
  18. along with Octave; see the file COPYING.  If not, write to the Free
  19. Software Foundation, 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  20.  
  21. */
  22.  
  23. /* Modified by Klaus Gebhardt, 1999 */
  24.  
  25. #if !defined (octave_octave_stream_h)
  26. #define octave_octave_stream_h 1
  27.  
  28. class Matrix;
  29. class string_vector;
  30. class octave_value;
  31. class octave_value_list;
  32.  
  33. class istream;
  34. class ostream;
  35. class ostrstream;
  36.  
  37. #ifdef __EMX__
  38. #include <iostream.h>
  39. #endif
  40.  
  41. #include <string>
  42.  
  43. #include "Array.h"
  44. #include "data-conv.h"
  45. #include "mach-info.h"
  46.  
  47. struct
  48. scanf_format_elt
  49. {
  50.   scanf_format_elt (const char *txt = 0, int w = 0, bool d = false,
  51.             char typ = '\0', char mod = '\0')
  52.     : text (txt), width (w), discard (d), type (typ), modifier (mod) { }
  53.  
  54.   ~scanf_format_elt (void) { delete text; }
  55.  
  56.   const char *text;
  57.   int width;
  58.   bool discard;
  59.   char type;
  60.   char modifier;
  61. };
  62.  
  63. class
  64. scanf_format_list
  65. {
  66. public:
  67.  
  68.   scanf_format_list (const string& fmt = string ());
  69.  
  70.   ~scanf_format_list (void);
  71.  
  72.   int num_conversions (void) { return nconv; }
  73.  
  74.   // The length can be different than the number of conversions.
  75.   // For example, "x %d y %d z" has 2 conversions but the length of
  76.   // the list is 3 because of the characters that appear after the
  77.   // last conversion.
  78.  
  79.   int length (void) { return list.length (); }
  80.  
  81.   const scanf_format_elt *first (void)
  82.     {
  83.       curr_idx = 0;
  84.       return current ();
  85.     }
  86.  
  87.   const scanf_format_elt *current (void) const
  88.     { return list.length () > 0 ? list.elem (curr_idx) : 0; }
  89.  
  90.   const scanf_format_elt *next (void)
  91.     {
  92.       curr_idx++;
  93.       if (curr_idx >= list.length ())
  94.     curr_idx = 0;
  95.       return current ();
  96.     }
  97.  
  98.   void printme (void) const;
  99.  
  100.   bool ok (void) const { return (nconv >= 0); }
  101.  
  102.   operator bool () const { return ok (); }
  103.  
  104.   bool all_character_conversions (void);
  105.  
  106.   bool all_numeric_conversions (void);
  107.  
  108. private:
  109.  
  110.   // Number of conversions specified by this format string, or -1 if
  111.   // invalid conversions have been found.
  112.   int nconv;
  113.  
  114.   // Index to current element;
  115.   int curr_idx;
  116.  
  117.   // List of format elements.
  118.   Array<scanf_format_elt*> list;
  119.  
  120.   // Temporary buffer.
  121.   ostrstream *buf;
  122.  
  123.   void add_elt_to_list (int width, bool discard, char type, char modifier,
  124.             int& num_elts);
  125.  
  126.   void process_conversion (const string& s, int& i, int n, int& width,
  127.                bool& discard, char& type, char& modifier,
  128.                int& num_elts);
  129.  
  130.   int finish_conversion (const string& s, int& i, int n, int& width,
  131.              bool discard, char& type, char modifier,
  132.              int& num_elts);
  133.   // No copying!
  134.  
  135.   scanf_format_list (const scanf_format_list&);
  136.  
  137.   scanf_format_list& operator = (const scanf_format_list&);
  138. };
  139.  
  140. struct
  141. printf_format_elt
  142. {
  143.   printf_format_elt (const char *txt = 0, int n = 0, char typ = '\0',
  144.              char mod = '\0')
  145.     : text (txt), args (n), type (typ), modifier (mod) { }
  146.  
  147.   ~printf_format_elt (void) { delete text; }
  148.  
  149.   const char *text;
  150.   int args;
  151.   char type;
  152.   char modifier;
  153. };
  154.  
  155. class
  156. printf_format_list
  157. {
  158. public:
  159.  
  160.   printf_format_list (const string& fmt = string ());
  161.  
  162.   ~printf_format_list (void);
  163.  
  164.   int num_conversions (void) { return nconv; }
  165.  
  166.   const printf_format_elt *first (void)
  167.     {
  168.       curr_idx = 0;
  169.       return current ();
  170.     }
  171.  
  172.   const printf_format_elt *current (void) const
  173.     { return list.length () > 0 ? list.elem (curr_idx) : 0; }
  174.  
  175.   const printf_format_elt *next (void)
  176.     {
  177.       curr_idx++;
  178.       if (curr_idx >= list.length ())
  179.     curr_idx = 0;
  180.       return current ();
  181.     }
  182.  
  183.   void printme (void) const;
  184.  
  185.   bool ok (void) const { return (nconv >= 0); }
  186.  
  187.   operator bool () const { return ok (); }
  188.  
  189. private:
  190.  
  191.   // Number of conversions specified by this format string, or -1 if
  192.   // invalid conversions have been found.
  193.   int nconv;
  194.  
  195.   // Index to current element;
  196.   int curr_idx;
  197.  
  198.   // List of format elements.
  199.   Array<printf_format_elt*> list;
  200.  
  201.   // Temporary buffer.
  202.   ostrstream *buf;
  203.  
  204.   void add_elt_to_list (int args, char type, char modifier,
  205.             int& num_elts);
  206.  
  207.   void process_conversion (const string& s, int& i, int n, int& args,
  208.                char& modifier, char& type, int& num_elts);
  209.  
  210.   void finish_conversion (const string& s, int& i, int args,
  211.               char modifier, char& type, int& num_elts);
  212.  
  213.   // No copying!
  214.  
  215.   printf_format_list (const printf_format_list&);
  216.  
  217.   printf_format_list& operator = (const printf_format_list&);
  218. };
  219.  
  220. // Provide an interface for Octave streams.
  221.  
  222. class
  223. octave_base_stream
  224. {
  225. friend class octave_stream;
  226.  
  227. public:
  228.  
  229.   octave_base_stream (ios::openmode arg_md = ios::in|ios::out,
  230.               oct_mach_info::float_format ff = oct_mach_info::native)
  231.     : count (0), md (arg_md), flt_fmt (ff), fail (false), open_state (true)
  232.   { }
  233.  
  234.   virtual ~octave_base_stream (void) { }
  235.  
  236.   // The remaining functions are not specific to input or output only,
  237.   // and must be provided by the derived classes.
  238.  
  239.   // Position a stream at OFFSET relative to ORIGIN.
  240.  
  241.   virtual int seek (streamoff offset, ios::seek_dir origin) = 0;
  242.  
  243.   // Return current stream position.
  244.  
  245.   virtual long tell (void) const = 0;
  246.  
  247.   // Return TRUE if EOF has been reached on this stream.
  248.  
  249.   virtual bool eof (void) const = 0;
  250.  
  251.   // The name of the file.
  252.  
  253.   virtual string name (void) const = 0;
  254.  
  255.   // If the derived class provides this function and it returns a
  256.   // pointer to a valid istream, scanf(), read(), getl(), and gets()
  257.   // will automatically work for this stream.
  258.  
  259.   virtual istream *input_stream (void) { return 0; }
  260.  
  261.   // If the derived class provides this function and it returns a
  262.   // pointer to a valid ostream, flush(), write(), and printf() will
  263.   // automatically work for this stream.
  264.  
  265.   virtual ostream *output_stream (void) { return 0; }
  266.  
  267.   // Return TRUE if this stream is open.
  268.  
  269.   bool is_open (void) const { return open_state; }
  270.  
  271.   void close (void);
  272.  
  273.   int file_number (void);
  274.  
  275.   bool ok (void) const { return ! fail; }
  276.  
  277.   // Return current error message for this stream.
  278.  
  279.   string error (bool clear, int& err_num);
  280.  
  281. protected:
  282.  
  283.   int mode (void) const { return md; }
  284.  
  285.   oct_mach_info::float_format float_format (void) const { return flt_fmt; }
  286.  
  287.   // Set current error state and set fail to TRUE.
  288.  
  289.   void error (const string& msg);
  290.  
  291.   // Clear any error message and set fail to FALSE.
  292.  
  293.   void clear (void);
  294.  
  295. private:
  296.  
  297.   // A reference count.
  298.   int count;
  299.  
  300.   // The permission bits for the file.  Should be some combination of
  301.   // ios::open_mode bits.
  302.   int md;
  303.  
  304.   // Data format.
  305.   oct_mach_info::float_format flt_fmt;
  306.  
  307.   // TRUE if an error has occurred.
  308.   bool fail;
  309.  
  310.   // TRUE if this stream is open.
  311.   bool open_state;
  312.  
  313.   // Should contain error message if fail is TRUE.
  314.   string errmsg;
  315.  
  316.   // Functions that are defined for all input streams (input streams
  317.   // are those that define is).
  318.  
  319.   string do_gets (int max_len, bool& err, bool strip_newline,
  320.           const char *fcn);
  321.  
  322.   string getl (int max_len, bool& err);
  323.   string gets (int max_len, bool& err);
  324.  
  325.   octave_value do_read (int nr, int nc, oct_data_conv::data_type dt,
  326.             int skip, oct_mach_info::float_format flt_fmt,
  327.             int& count);
  328.  
  329.   octave_value read (const Matrix& size, oct_data_conv::data_type dt,
  330.              int skip, oct_mach_info::float_format flt_fmt,
  331.              int& count);
  332.  
  333.   octave_value do_char_scanf (scanf_format_list& fmt_list,
  334.                   int nr, int nc, int& count);
  335.  
  336.   octave_value do_real_scanf (scanf_format_list& fmt_list,
  337.                   int nr, int nc, int& count);
  338.  
  339.   octave_value do_scanf (scanf_format_list& fmt_list, int nr, int nc,
  340.              bool one_elt_size_spec, int& count);
  341.  
  342.   octave_value scanf (const string& fmt, const Matrix& size, int& count);
  343.  
  344.   bool do_oscanf (const scanf_format_elt *elt, octave_value&);
  345.  
  346.   octave_value_list oscanf (const string& fmt);
  347.  
  348.   // Functions that are defined for all output streams (output streams
  349.   // are those that define os).
  350.  
  351.   int flush (void);
  352.  
  353.   int do_write (const Matrix& m, oct_data_conv::data_type dt, int skip,
  354.         oct_mach_info::float_format flt_fmt);
  355.  
  356.   int write (const octave_value& data, oct_data_conv::data_type dt,
  357.          int skip, oct_mach_info::float_format flt_fmt);
  358.  
  359.   int do_printf (printf_format_list& fmt_list, const octave_value_list& args);
  360.  
  361.   int printf (const string& fmt, const octave_value_list& args);
  362.  
  363.   int puts (const string& s);
  364.  
  365.   // We can always do this in terms of seek(), so the derived class
  366.   // only has to provide that.
  367.  
  368.   int rewind (void);
  369.  
  370.   void invalid_operation (const char *op, const char *rw);
  371.  
  372.   // No copying!
  373.  
  374.   octave_base_stream (const octave_base_stream&);
  375.  
  376.   octave_base_stream& operator = (const octave_base_stream&);
  377. };
  378.  
  379. class
  380. octave_stream
  381. {
  382. public:
  383.  
  384.   octave_stream (octave_base_stream *bs = 0);
  385.  
  386.   ~octave_stream (void);
  387.  
  388.   octave_stream (const octave_stream&);
  389.  
  390.   octave_stream& operator = (const octave_stream&);
  391.  
  392.   int flush (void);
  393.  
  394.   string getl (int max_len, bool& err);
  395.   string getl (const octave_value& max_len, bool& err);
  396.  
  397.   string gets (int max_len, bool& err);
  398.   string gets (const octave_value& max_len, bool& err);
  399.  
  400.   int seek (streamoff offset, ios::seek_dir origin);
  401.   int seek (const octave_value& offset, const octave_value& origin);
  402.  
  403.   long tell (void) const;
  404.  
  405.   int rewind (void);
  406.  
  407.   bool is_open (void) const;
  408.  
  409.   void close (void);
  410.  
  411.   octave_value read (const Matrix& size, oct_data_conv::data_type dt,
  412.              int skip, oct_mach_info::float_format flt_fmt,
  413.              int& count);
  414.  
  415.   int write (const octave_value& data, oct_data_conv::data_type dt,
  416.          int skip, oct_mach_info::float_format flt_fmt);
  417.  
  418.   octave_value scanf (const string& fmt, const Matrix& size, int& count);
  419.  
  420.   octave_value_list oscanf (const string& fmt);
  421.  
  422.   int printf (const string& fmt, const octave_value_list& args);
  423.  
  424.   int puts (const string& s);
  425.   int puts (const octave_value& s);
  426.  
  427.   bool eof (void) const;
  428.  
  429.   string error (bool clear, int& err_num);
  430.  
  431.   string error (bool clear = false)
  432.     {
  433.       int err_num;
  434.       return error (clear, err_num);
  435.     }
  436.  
  437.   int file_number (void) { return rep ? rep->file_number () : -1; }
  438.  
  439.   bool is_valid (void) const { return (rep != 0); }
  440.  
  441.   bool ok (void) const { return rep && rep->ok (); }
  442.  
  443.   operator bool () const { return ok (); }
  444.  
  445.   string name (void) const;
  446.  
  447.   int mode (void) const;
  448.  
  449.   oct_mach_info::float_format float_format (void) const;
  450.  
  451.   static string mode_as_string (int mode);
  452.  
  453.   istream *input_stream (void) { return rep ? rep->input_stream () : 0; }
  454.  
  455.   ostream *output_stream (void) { return rep ? rep->output_stream () : 0; }
  456.  
  457. private:
  458.  
  459.   // The actual representation of this stream.
  460.   octave_base_stream *rep;
  461.  
  462.   void invalid_stream_error (const char *op) const;
  463.  
  464.   bool stream_ok (const char *op, bool clear = true) const
  465.     {
  466.       bool retval = true;
  467.  
  468.       if (rep)
  469.     {
  470.       if (clear)
  471.         rep->clear ();
  472.     }
  473.       else
  474.     {
  475.       retval = false;
  476.       invalid_stream_error (op);
  477.     }
  478.  
  479.       return retval;
  480.     }
  481.  
  482.   void error (const string& msg)
  483.     {
  484.       if (rep)
  485.     rep->error (msg);
  486.     }
  487. };
  488.  
  489. class
  490. octave_stream_list
  491. {
  492. protected:
  493.  
  494.   octave_stream_list (void) : list (32), curr_len (0) { }
  495.  
  496. public:
  497.  
  498.   ~octave_stream_list (void) { }
  499.  
  500.   static bool instance_ok (void);
  501.  
  502.   static octave_value insert (const octave_stream& os);
  503.  
  504.   static octave_stream lookup (int fid, const string& who = string ());
  505.   static octave_stream lookup (const octave_value& fid,
  506.                    const string& who = string ());
  507.  
  508.   static int remove (int fid, const string& who = string ());
  509.   static int remove (const octave_value& fid,
  510.              const string& who = string ());
  511.  
  512.   static void clear (void);
  513.  
  514.   static string_vector get_info (int fid);
  515.   static string_vector get_info (const octave_value& fid);
  516.  
  517.   static string list_open_files (void);
  518.  
  519.   static octave_value open_file_numbers (void);
  520.  
  521.   static int get_file_number (const octave_value& fid);
  522.  
  523. private:
  524.  
  525.   Array<octave_stream> list;
  526.  
  527.   int curr_len;
  528.  
  529.   static octave_stream_list *instance;
  530.  
  531.   octave_value do_insert (const octave_stream& os);
  532.  
  533.   octave_stream do_lookup (int fid, const string& who = string ()) const;
  534.   octave_stream do_lookup (const octave_value& fid,
  535.                const string& who = string ()) const;
  536.  
  537.   int do_remove (int fid, const string& who = string ());
  538.   int do_remove (const octave_value& fid, const string& who = string ());
  539.  
  540.   void do_clear (void);
  541.  
  542.   string_vector do_get_info (int fid) const;
  543.   string_vector do_get_info (const octave_value& fid) const;
  544.  
  545.   string do_list_open_files (void) const;
  546.  
  547.   octave_value do_open_file_numbers (void) const;
  548.  
  549.   int do_get_file_number (const octave_value& fid) const;
  550. };
  551.  
  552. #endif
  553.  
  554. /*
  555. ;;; Local Variables: ***
  556. ;;; mode: C++ ***
  557. ;;; End: ***
  558. */
  559.