00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #if !defined (octave_octave_stream_h)
00024 #define octave_octave_stream_h 1
00025
00026 class Matrix;
00027 class string_vector;
00028 class octave_value;
00029 class octave_value_list;
00030
00031 #include <iosfwd>
00032 #include <sstream>
00033 #include <string>
00034 #include <map>
00035
00036 #include "Array.h"
00037 #include "data-conv.h"
00038 #include "lo-utils.h"
00039 #include "mach-info.h"
00040
00041 class
00042 OCTINTERP_API
00043 scanf_format_elt
00044 {
00045 public:
00046
00047 enum special_conversion
00048 {
00049 whitespace_conversion = 1,
00050 literal_conversion = 2
00051 };
00052
00053 scanf_format_elt (const char *txt = 0, int w = 0, bool d = false,
00054 char typ = '\0', char mod = '\0',
00055 const std::string& ch_class = std::string ())
00056 : text (strsave (txt)), width (w), discard (d), type (typ),
00057 modifier (mod), char_class (ch_class) { }
00058
00059 scanf_format_elt (const scanf_format_elt& e)
00060 : text (strsave (e.text)), width (e.width), discard (e.discard),
00061 type (e.type), modifier (e.modifier), char_class (e.char_class) { }
00062
00063 scanf_format_elt& operator = (const scanf_format_elt& e)
00064 {
00065 if (this != &e)
00066 {
00067 text = strsave (e.text);
00068 width = e.width;
00069 discard = e.discard;
00070 type = e.type;
00071 modifier = e.modifier;
00072 char_class = e.char_class;
00073 }
00074
00075 return *this;
00076 }
00077
00078 ~scanf_format_elt (void) { delete [] text; }
00079
00080
00081 const char *text;
00082
00083
00084 int width;
00085
00086
00087 bool discard;
00088
00089
00090
00091 char type;
00092
00093
00094 char modifier;
00095
00096
00097 std::string char_class;
00098 };
00099
00100 class
00101 OCTINTERP_API
00102 scanf_format_list
00103 {
00104 public:
00105
00106 scanf_format_list (const std::string& fmt = std::string ());
00107
00108 ~scanf_format_list (void);
00109
00110 octave_idx_type num_conversions (void) { return nconv; }
00111
00112
00113
00114
00115
00116
00117 octave_idx_type length (void) { return list.length (); }
00118
00119 const scanf_format_elt *first (void)
00120 {
00121 curr_idx = 0;
00122 return current ();
00123 }
00124
00125 const scanf_format_elt *current (void) const
00126 { return list.length () > 0 ? list.elem (curr_idx) : 0; }
00127
00128 const scanf_format_elt *next (bool cycle = true)
00129 {
00130 curr_idx++;
00131
00132 if (curr_idx >= list.length ())
00133 {
00134 if (cycle)
00135 curr_idx = 0;
00136 else
00137 return 0;
00138 }
00139 return current ();
00140 }
00141
00142 void printme (void) const;
00143
00144 bool ok (void) const { return (nconv >= 0); }
00145
00146 operator bool () const { return ok (); }
00147
00148 bool all_character_conversions (void);
00149
00150 bool all_numeric_conversions (void);
00151
00152 private:
00153
00154
00155
00156 octave_idx_type nconv;
00157
00158
00159 octave_idx_type curr_idx;
00160
00161
00162
00163 Array<scanf_format_elt*> list;
00164
00165
00166 std::ostringstream *buf;
00167
00168 void add_elt_to_list (int width, bool discard, char type, char modifier,
00169 octave_idx_type& num_elts,
00170 const std::string& char_class = std::string ());
00171
00172 void process_conversion (const std::string& s, size_t& i, size_t n,
00173 int& width, bool& discard, char& type,
00174 char& modifier, octave_idx_type& num_elts);
00175
00176 int finish_conversion (const std::string& s, size_t& i, size_t n,
00177 int& width, bool discard, char& type,
00178 char modifier, octave_idx_type& num_elts);
00179
00180
00181 scanf_format_list (const scanf_format_list&);
00182
00183 scanf_format_list& operator = (const scanf_format_list&);
00184 };
00185
00186 class
00187 printf_format_elt
00188 {
00189 public:
00190
00191 printf_format_elt (const char *txt = 0, int n = 0, int w = 0,
00192 int p = 0, const std::string& f = std::string (),
00193 char typ = '\0', char mod = '\0')
00194 : text (strsave (txt)), args (n), fw (w), prec (p), flags (f),
00195 type (typ), modifier (mod) { }
00196
00197 printf_format_elt (const printf_format_elt& e)
00198 : text (strsave (e.text)), args (e.args), fw (e.fw), prec (e.prec),
00199 flags (e.flags), type (e.type), modifier (e.modifier) { }
00200
00201 printf_format_elt& operator = (const printf_format_elt& e)
00202 {
00203 if (this != &e)
00204 {
00205 text = strsave (e.text);
00206 args = e.args;
00207 fw = e.fw;
00208 prec = e.prec;
00209 flags = e.flags;
00210 type = e.type;
00211 modifier = e.modifier;
00212 }
00213
00214 return *this;
00215 }
00216
00217 ~printf_format_elt (void) { delete [] text; }
00218
00219
00220 const char *text;
00221
00222
00223 int args;
00224
00225
00226 int fw;
00227
00228
00229 int prec;
00230
00231
00232 std::string flags;
00233
00234
00235
00236 char type;
00237
00238
00239 char modifier;
00240 };
00241
00242 class
00243 OCTINTERP_API
00244 printf_format_list
00245 {
00246 public:
00247
00248 printf_format_list (const std::string& fmt = std::string ());
00249
00250 ~printf_format_list (void);
00251
00252 octave_idx_type num_conversions (void) { return nconv; }
00253
00254 const printf_format_elt *first (void)
00255 {
00256 curr_idx = 0;
00257 return current ();
00258 }
00259
00260 const printf_format_elt *current (void) const
00261 { return list.length () > 0 ? list.elem (curr_idx) : 0; }
00262
00263 const printf_format_elt *next (bool cycle = true)
00264 {
00265 curr_idx++;
00266
00267 if (curr_idx >= list.length ())
00268 {
00269 if (cycle)
00270 curr_idx = 0;
00271 else
00272 return 0;
00273 }
00274
00275 return current ();
00276 }
00277
00278 bool last_elt_p (void) { return (curr_idx + 1 == list.length ()); }
00279
00280 void printme (void) const;
00281
00282 bool ok (void) const { return (nconv >= 0); }
00283
00284 operator bool () const { return ok (); }
00285
00286 private:
00287
00288
00289
00290 octave_idx_type nconv;
00291
00292
00293 octave_idx_type curr_idx;
00294
00295
00296
00297 Array<printf_format_elt*> list;
00298
00299
00300 std::ostringstream *buf;
00301
00302 void add_elt_to_list (int args, const std::string& flags, int fw,
00303 int prec, char type, char modifier,
00304 octave_idx_type& num_elts);
00305
00306 void process_conversion (const std::string& s, size_t& i, size_t n,
00307 int& args, std::string& flags, int& fw,
00308 int& prec, char& modifier, char& type,
00309 octave_idx_type& num_elts);
00310
00311 void finish_conversion (const std::string& s, size_t& i, int args,
00312 const std::string& flags, int fw, int prec,
00313 char modifier, char& type,
00314 octave_idx_type& num_elts);
00315
00316
00317
00318 printf_format_list (const printf_format_list&);
00319
00320 printf_format_list& operator = (const printf_format_list&);
00321 };
00322
00323
00324
00325 class
00326 OCTINTERP_API
00327 octave_base_stream
00328 {
00329 friend class octave_stream;
00330
00331 public:
00332
00333 octave_base_stream (std::ios::openmode arg_md = std::ios::in|std::ios::out,
00334 oct_mach_info::float_format ff
00335 = oct_mach_info::native_float_format ())
00336 : count (0), md (arg_md), flt_fmt (ff), fail (false), open_state (true),
00337 errmsg ()
00338 { }
00339
00340 virtual ~octave_base_stream (void) { }
00341
00342
00343
00344
00345
00346
00347 virtual int seek (long offset, int origin) = 0;
00348
00349
00350
00351 virtual long tell (void) = 0;
00352
00353
00354
00355 virtual bool eof (void) const = 0;
00356
00357
00358
00359 virtual std::string name (void) const = 0;
00360
00361
00362
00363
00364
00365 virtual std::istream *input_stream (void) { return 0; }
00366
00367
00368
00369
00370
00371 virtual std::ostream *output_stream (void) { return 0; }
00372
00373
00374
00375 bool is_open (void) const { return open_state; }
00376
00377 virtual void do_close (void) { }
00378
00379 void close (void)
00380 {
00381 if (is_open ())
00382 {
00383 open_state = false;
00384 do_close ();
00385 }
00386 }
00387
00388 virtual int file_number (void) const
00389 {
00390
00391
00392 if (name () == "stdin")
00393 return 0;
00394 else if (name () == "stdout")
00395 return 1;
00396 else if (name () == "stderr")
00397 return 2;
00398 else
00399 return -1;
00400 }
00401
00402 bool ok (void) const { return ! fail; }
00403
00404
00405
00406 std::string error (bool clear, int& err_num);
00407
00408 protected:
00409
00410 int mode (void) const { return md; }
00411
00412 oct_mach_info::float_format float_format (void) const { return flt_fmt; }
00413
00414
00415
00416 void error (const std::string& msg);
00417 void error (const std::string& who, const std::string& msg);
00418
00419
00420
00421 void clear (void);
00422
00423
00424
00425 void clearerr (void);
00426
00427 private:
00428
00429
00430 octave_idx_type count;
00431
00432
00433
00434 int md;
00435
00436
00437 oct_mach_info::float_format flt_fmt;
00438
00439
00440 bool fail;
00441
00442
00443 bool open_state;
00444
00445
00446 std::string errmsg;
00447
00448
00449
00450
00451 std::string do_gets (octave_idx_type max_len, bool& err, bool strip_newline,
00452 const std::string& who );
00453
00454 std::string getl (octave_idx_type max_len, bool& err, const std::string& who );
00455 std::string gets (octave_idx_type max_len, bool& err, const std::string& who );
00456 long skipl (long count, bool& err, const std::string& who );
00457
00458 octave_value do_scanf (scanf_format_list& fmt_list, octave_idx_type nr, octave_idx_type nc,
00459 bool one_elt_size_spec, octave_idx_type& count,
00460 const std::string& who );
00461
00462 octave_value scanf (const std::string& fmt, const Array<double>& size,
00463 octave_idx_type& count, const std::string& who );
00464
00465 bool do_oscanf (const scanf_format_elt *elt, octave_value&,
00466 const std::string& who );
00467
00468 octave_value_list oscanf (const std::string& fmt,
00469 const std::string& who );
00470
00471
00472
00473
00474 int flush (void);
00475
00476 int do_printf (printf_format_list& fmt_list, const octave_value_list& args,
00477 const std::string& who );
00478
00479 int printf (const std::string& fmt, const octave_value_list& args,
00480 const std::string& who );
00481
00482 int puts (const std::string& s, const std::string& who );
00483
00484
00485
00486
00487 void invalid_operation (const std::string& who, const char *rw);
00488
00489
00490
00491 octave_base_stream (const octave_base_stream&);
00492
00493 octave_base_stream& operator = (const octave_base_stream&);
00494 };
00495
00496 class
00497 OCTINTERP_API
00498 octave_stream
00499 {
00500 public:
00501
00502 octave_stream (octave_base_stream *bs = 0);
00503
00504 ~octave_stream (void);
00505
00506 octave_stream (const octave_stream&);
00507
00508 octave_stream& operator = (const octave_stream&);
00509
00510 int flush (void);
00511
00512 std::string getl (octave_idx_type max_len, bool& err, const std::string& who );
00513 std::string getl (const octave_value& max_len, bool& err,
00514 const std::string& who );
00515
00516 std::string gets (octave_idx_type max_len, bool& err, const std::string& who );
00517 std::string gets (const octave_value& max_len, bool& err,
00518 const std::string& who );
00519
00520 long skipl (long count, bool& err, const std::string& who );
00521 long skipl (const octave_value& count, bool& err, const std::string& who );
00522
00523 int seek (long offset, int origin);
00524 int seek (const octave_value& offset, const octave_value& origin);
00525
00526 long tell (void);
00527
00528 int rewind (void);
00529
00530 bool is_open (void) const;
00531
00532 void close (void);
00533
00534 octave_value read (const Array<double>& size, octave_idx_type block_size,
00535 oct_data_conv::data_type input_type,
00536 oct_data_conv::data_type output_type,
00537 octave_idx_type skip, oct_mach_info::float_format flt_fmt,
00538 octave_idx_type& count);
00539
00540 octave_idx_type write (const octave_value& data, octave_idx_type block_size,
00541 oct_data_conv::data_type output_type,
00542 octave_idx_type skip, oct_mach_info::float_format flt_fmt);
00543
00544 template <class T>
00545 octave_idx_type write (const Array<T>&, octave_idx_type block_size,
00546 oct_data_conv::data_type output_type,
00547 octave_idx_type skip, oct_mach_info::float_format flt_fmt);
00548
00549 octave_value scanf (const std::string& fmt, const Array<double>& size,
00550 octave_idx_type& count, const std::string& who );
00551
00552 octave_value scanf (const octave_value& fmt, const Array<double>& size,
00553 octave_idx_type& count, const std::string& who );
00554
00555 octave_value_list oscanf (const std::string& fmt,
00556 const std::string& who );
00557
00558 octave_value_list oscanf (const octave_value& fmt,
00559 const std::string& who );
00560
00561 int printf (const std::string& fmt, const octave_value_list& args,
00562 const std::string& who );
00563
00564 int printf (const octave_value& fmt, const octave_value_list& args,
00565 const std::string& who );
00566
00567 int puts (const std::string& s, const std::string& who );
00568 int puts (const octave_value& s, const std::string& who );
00569
00570 bool eof (void) const;
00571
00572 std::string error (bool clear, int& err_num);
00573
00574 std::string error (bool clear = false)
00575 {
00576 int err_num;
00577 return error (clear, err_num);
00578 }
00579
00580
00581
00582 void error (const std::string& msg)
00583 {
00584 if (rep)
00585 rep->error (msg);
00586 }
00587
00588 void error (const char *msg) { error (std::string (msg)); }
00589
00590 int file_number (void) { return rep ? rep->file_number () : -1; }
00591
00592 bool is_valid (void) const { return (rep != 0); }
00593
00594 bool ok (void) const { return rep && rep->ok (); }
00595
00596 operator bool () const { return ok (); }
00597
00598 std::string name (void) const;
00599
00600 int mode (void) const;
00601
00602 oct_mach_info::float_format float_format (void) const;
00603
00604 static std::string mode_as_string (int mode);
00605
00606 std::istream *input_stream (void)
00607 {
00608 return rep ? rep->input_stream () : 0;
00609 }
00610
00611 std::ostream *output_stream (void)
00612 {
00613 return rep ? rep->output_stream () : 0;
00614 }
00615
00616 void clearerr (void) { if (rep) rep->clearerr (); }
00617
00618 private:
00619
00620
00621 octave_base_stream *rep;
00622
00623 bool stream_ok (bool clear = true) const
00624 {
00625 bool retval = true;
00626
00627 if (rep)
00628 {
00629 if (clear)
00630 rep->clear ();
00631 }
00632 else
00633 retval = false;
00634
00635 return retval;
00636 }
00637
00638 void invalid_operation (const std::string& who, const char *rw)
00639 {
00640 if (rep)
00641 rep->invalid_operation (who, rw);
00642 }
00643 };
00644
00645 class
00646 OCTINTERP_API
00647 octave_stream_list
00648 {
00649 protected:
00650
00651 octave_stream_list (void) : list (), lookup_cache (list.end ()) { }
00652
00653 public:
00654
00655 ~octave_stream_list (void) { }
00656
00657 static bool instance_ok (void);
00658
00659 static int insert (octave_stream& os);
00660
00661 static octave_stream
00662 lookup (int fid, const std::string& who = std::string ());
00663
00664 static octave_stream
00665 lookup (const octave_value& fid, const std::string& who = std::string ());
00666
00667 static int remove (int fid, const std::string& who = std::string ());
00668 static int remove (const octave_value& fid,
00669 const std::string& who = std::string ());
00670
00671 static void clear (bool flush = true);
00672
00673 static string_vector get_info (int fid);
00674 static string_vector get_info (const octave_value& fid);
00675
00676 static std::string list_open_files (void);
00677
00678 static octave_value open_file_numbers (void);
00679
00680 static int get_file_number (const octave_value& fid);
00681
00682 private:
00683
00684 typedef std::map<int, octave_stream> ostrl_map;
00685
00686 ostrl_map list;
00687
00688 mutable ostrl_map::const_iterator lookup_cache;
00689
00690 static octave_stream_list *instance;
00691
00692 int do_insert (octave_stream& os);
00693
00694 octave_stream do_lookup (int fid, const std::string& who = std::string ()) const;
00695 octave_stream do_lookup (const octave_value& fid,
00696 const std::string& who = std::string ()) const;
00697
00698 int do_remove (int fid, const std::string& who = std::string ());
00699 int do_remove (const octave_value& fid, const std::string& who = std::string ());
00700
00701 void do_clear (bool flush = true);
00702
00703 string_vector do_get_info (int fid) const;
00704 string_vector do_get_info (const octave_value& fid) const;
00705
00706 std::string do_list_open_files (void) const;
00707
00708 octave_value do_open_file_numbers (void) const;
00709
00710 int do_get_file_number (const octave_value& fid) const;
00711 };
00712
00713 #endif