00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #ifndef __PORT_HPP
00014 #define __PORT_HPP
00015 #include <basix/string.hpp>
00016
00018
00019 namespace mmx {
00020 #define mmx_wait mmx::wait
00021
00022 extern bool texmacs_mode;
00023 extern bool math_mode;
00024 extern bool color_mode;
00025
00026 string string_as_mmx (const string& g);
00027 string output_as_mmx (const generic& g);
00028
00029
00030
00031
00032
00033 class port;
00034 class port_rep: public rep_struct {
00035 public:
00036 virtual syntactic expression () const = 0;
00037 virtual bool is_output_port ();
00038 virtual bool is_input_port ();
00039 virtual bool error_flag ();
00040 virtual string error_message ();
00041 virtual bool busy ();
00042 virtual nat can_write ();
00043 virtual nat can_read ();
00044 virtual void write (const char* s, nat n);
00045 virtual void read (char* s, nat n);
00046 virtual void flush ();
00047 virtual bool wait (int msecs);
00048 virtual port accept ();
00049 virtual port component (const string& name);
00050 virtual void format (const print_format& fm);
00051
00052 public:
00053 inline port_rep () {}
00054 inline virtual ~port_rep () {}
00055 };
00056
00057 class port {
00058 INDIRECT_PROTO (port, port_rep)
00059 port ();
00060 };
00061 INDIRECT_IMPL (port, port_rep)
00062
00063 HARD_TO_EXACT_IDENTITY_SUGAR(,port)
00064 HARD_TO_TRUE_IDENTITY_SUGAR(,port)
00065
00066 inline syntactic flatten (const port& p) { return p->expression (); }
00067
00068
00069
00070
00071
00072 extern port mmin;
00073 extern port mmout;
00074 extern port mmerr;
00075
00076 port input_string_port (const string& s);
00077 port output_string_port (string& s);
00078 port input_output_string_port (string& s);
00079 port input_file_port (const string& name);
00080 port output_file_port (const string& name);
00081 port input_output_file_port (const string& name);
00082 port socket_server_port (const string& host, int port);
00083 port socket_client_port (const string& host, int port);
00084 port pipe_port (const string& cmd);
00085 port composite_port (const vector<port>& ps);
00086 port composite_port (const vector<port>& ps, const vector<string>& names);
00087 port formatting_port (const port& p);
00088 port error_port (const string& message);
00089
00090
00091
00092
00093
00094 inline bool is_input_port (const port& p) {
00095 return inside (p)->is_input_port (); }
00096 inline bool is_output_port (const port& p) {
00097 return inside (p)->is_output_port (); }
00098 inline bool error_flag (const port& p) {
00099 return inside (p)->error_flag (); }
00100 string error_message (const port& p);
00101 inline bool busy (const port& p) {
00102 return inside (p)->busy (); }
00103 inline nat can_write (const port& p) {
00104 return inside (p)->can_write (); }
00105 inline nat can_read (const port& p) {
00106 return inside (p)->can_read (); }
00107 inline void write (const port& p, const char* s, nat n) {
00108 inside (p)->write (s, n); }
00109 inline void write (const port& p, const string& s) {
00110 inside (p)->write (inside (s, 0), N(s)); }
00111 inline void read (const port& p, char* s, nat n) {
00112 inside (p)->read (s, n); }
00113 inline string read (const port& p, nat n) {
00114 string r (n); inside (p)->read (inside (r, 0), n); return r; }
00115 inline void flush (const port& p) {
00116 inside (p)->flush (); }
00117 inline bool wait (const port& p, int msec) {
00118 return inside (p)->wait (msec); }
00119 inline port accept (const port& p) {
00120 return inside (p)->accept (); }
00121 port component (const port& p, const string& name);
00122
00123 nat wait_port_event (int msecs);
00124
00125
00126
00127
00128
00129 typedef char* charp;
00130 typedef const char* const_charp;
00131
00132 template<typename C> inline port
00133 operator << (const port& out, const C& x) {
00134 write (out, output_as_mmx (as<generic> (x)));
00135 return out;
00136 }
00137
00138 inline port
00139 operator << (const port& out, const string& s) {
00140 write (out, string_as_mmx (s));
00141 return out;
00142 }
00143
00144 inline port
00145 operator << (const port& out, const charp& s) {
00146 write (out, string_as_mmx (s));
00147 return out;
00148 }
00149
00150 inline port
00151 operator << (const port& out, const const_charp& s) {
00152 write (out, string_as_mmx (s));
00153 return out;
00154 }
00155
00156 inline port
00157 operator << (const port& out, const char& c) {
00158 write (out, string_as_mmx (c));
00159 return out;
00160 }
00161
00162 inline port
00163 operator << (const port& out, const print_format& fm) {
00164 inside (out) -> format (fm);
00165 return out;
00166 }
00167
00168 inline port
00169 operator >> (const port& in, char& c) {
00170 read (in, &c, 1);
00171 return in;
00172 }
00173
00174
00175
00176
00177
00178 template<typename C> generic binary_disassemble (const C& x);
00179 template<typename C> C binary_assemble (const generic& x);
00180 template<typename C> void binary_write (const port& out, const C& x);
00181 template<typename C> C binary_read (const port& in);
00182
00183 template<typename C>
00184 struct void_binary_helper {
00185 static inline string short_type_name () { return "?"; }
00186 static inline generic full_type_name () { return "?"; }
00187 static inline nat size (const C& x) {
00188 return vector_size (disassemble (x)); }
00189 static inline generic access (const C& x, nat i) {
00190 return vector_access (disassemble (x), i); }
00191 static inline generic disassemble (const C& x) {
00192 return as<generic> (x); }
00193 static inline C assemble (const generic& x) {
00194 return as<C> (x); }
00195 static inline void write (const port& out, const C& x) {
00196 generic d= binary_disassemble<C> (x);
00197 ASSERT (is<string> (d) || !is<C> (d), "binary write not implemented");
00198 binary_write<generic> (out, d); }
00199 static inline C read (const port& in) {
00200 return binary_assemble<C> (binary_read<generic> (in)); }
00201 };
00202
00203 template<typename C>
00204 struct binary_helper:
00205 public void_binary_helper<C> {};
00206
00207 template<typename C> nat
00208 binary_size (const C& x) {
00209 return binary_helper<C>::size (x);
00210 }
00211
00212 template<typename C> generic
00213 binary_access (const C& x, nat i) {
00214 return binary_helper<C>::access (x, i);
00215 }
00216
00217 template<typename C> generic
00218 binary_disassemble (const C& x) {
00219 return binary_helper<C>::disassemble (x);
00220 }
00221
00222 template<typename C> C
00223 binary_assemble (const generic& x) {
00224 return binary_helper<C>::assemble (x);
00225 }
00226
00227 template<typename C> void
00228 binary_write (const port& out, const C& x) {
00229 binary_helper<C>::write (out, x);
00230 }
00231
00232 template<typename C> C
00233 binary_read (const port& in) {
00234 return binary_helper<C>::read (in);
00235 }
00236
00237 template<typename C> port
00238 binary_ll (const port& out, const C& x) {
00239 binary_helper<C>::write (out, x);
00240 return out;
00241 }
00242
00243 template<typename C> port
00244 binary_rr (const port& in, C& x) {
00245 x= binary_helper<C>::read (in);
00246 return in;
00247 }
00248
00249 #define Short_type_name(T) binary_helper<T >::short_type_name ()
00250 #define Full_type_name(T) binary_helper<T >::full_type_name ()
00251
00252
00253
00254
00255
00256 typedef generic (*unary_generic) (const generic&);
00257
00258 void attach_generic_binary_assembler (const generic&, unary_generic);
00259 generic binary_type_generic (const generic& g);
00260 generic binary_disassemble_generic (const generic& g);
00261 generic binary_assemble_generic (const generic& tp, const generic& val);
00262
00263 template<typename T> generic
00264 binary_assemble_generic_via (const generic& x) {
00265 return as<generic> (binary_assemble<T> (x));
00266 }
00267
00268 template<typename T> inline void
00269 attach_generic_binary_assembler () {
00270 attach_generic_binary_assembler (binary_helper<T>::full_type_name (),
00271 binary_assemble_generic_via<T>);
00272 }
00273
00274 void attach_generic_binary_reader (const string&, unary_generic);
00275 void binary_write_generic (const port& out, const generic& g);
00276 generic binary_read_generic (const port& in);
00277
00278 template<typename T> generic
00279 binary_read_generic (const generic& in) {
00280 return as<generic> (binary_read<T> (as<port> (in)));
00281 }
00282
00283 template<typename T> inline void
00284 attach_generic_binary_reader () {
00285 attach_generic_binary_reader (binary_helper<T>::short_type_name (),
00286 binary_read_generic<T>);
00287 }
00288
00289 template<>
00290 struct binary_helper<generic> {
00291 static inline string short_type_name () { return "Gen"; }
00292 static inline generic full_type_name () { return "Generic"; }
00293 static inline nat size (const generic& g) { (void) g; return 2; }
00294 static inline generic access (const generic& x, nat i) {
00295 if (i == 0) return binary_type_generic (x);
00296 else if (i == 1) return binary_disassemble_generic (x);
00297 else ERROR ("index out of range"); }
00298 static inline generic disassemble (const generic& x) {
00299 return gen_vec (access (x, 0), access (x, 1)); }
00300 static inline generic assemble (const generic& x) {
00301 return binary_assemble_generic (vector_access (x, 0),
00302 vector_access (x, 1)); }
00303 static inline void write (const port& out, const generic& g) {
00304 binary_write_generic (out, g); }
00305 static generic read (const port& in) {
00306 return binary_read_generic (in); }
00307 };
00308
00309 inline generic generic_disassemble (const generic& x) {
00310 return binary_disassemble<generic> (x); }
00311 inline generic generic_assemble (const generic& x) {
00312 return binary_assemble<generic> (x); }
00313
00314
00315
00316
00317
00318 #define NUMERIC_BINARY_HELPER(TMPL,C,name,fname) \
00319 TMPL \
00320 struct binary_helper< C >: public void_binary_helper< C > { \
00321 static inline string short_type_name () { return name; } \
00322 static inline generic full_type_name () { return fname; } \
00323 static inline generic disassemble (const C& x) { \
00324 return as<generic> (numeric_as_string (x)); } \
00325 static inline C assemble (const generic& x) { \
00326 return string_as_numeric<C> (as<string> (x)); } \
00327 static inline void write (const port& out, const C& x) { \
00328 mmx::write (out, (const char*) ((const void*) (&x)), sizeof (C)); } \
00329 static inline C read (const port& in) { \
00330 C x; mmx::read (in, (char*) ((void*) (&x)), sizeof (C)); return x; } \
00331 };
00332
00333 NUMERIC_BINARY_HELPER(STMPL,char,"C","Char")
00334 NUMERIC_BINARY_HELPER(STMPL,uchar,"Uc","Uchar")
00335 NUMERIC_BINARY_HELPER(STMPL,short,"Sh","Short")
00336 NUMERIC_BINARY_HELPER(STMPL,ushort,"Us","Ushort")
00337 NUMERIC_BINARY_HELPER(STMPL,int,"I","Int")
00338 NUMERIC_BINARY_HELPER(STMPL,nat,"N","Uint")
00339 NUMERIC_BINARY_HELPER(STMPL,long,"Lo","Long")
00340 NUMERIC_BINARY_HELPER(STMPL,ulong,"Ul","Ulong")
00341 NUMERIC_BINARY_HELPER(STMPL,float,"F","Float")
00342 NUMERIC_BINARY_HELPER(STMPL,double,"D","Double")
00343
00344
00345
00346
00347
00348 template<>
00349 struct binary_helper<bool>: public void_binary_helper<bool> {
00350 static inline string short_type_name () { return "B"; }
00351 static inline generic full_type_name () { return "Boolean"; }
00352 static inline generic disassemble (const bool& b) {
00353 return as<generic> (b? string ("true"): string ("false")); }
00354 static inline bool assemble (const generic& x) {
00355 return is<string> (x) && as<string> (x) == "true"; }
00356 static inline void write (const port& out, const bool& b) {
00357 mmx::write (out, b? "t": "f", 1); }
00358 static inline bool read (const port& in) {
00359 char s[1]; mmx::read (in, s, 1); return s[0] == 't'; }
00360 };
00361
00362 template<>
00363 struct binary_helper<string>: public void_binary_helper<string> {
00364 static inline string short_type_name () { return "S"; }
00365 static inline generic full_type_name () { return "String"; }
00366 static inline void write (const port& out, const string& s) {
00367 binary_write<nat> (out, N(s));
00368 mmx::write (out, s); }
00369 static inline string read (const port& in) {
00370 nat n= binary_read<nat> (in);
00371 return mmx::read (in, n); }
00372 };
00373
00374 template<>
00375 struct binary_helper<syntactic>: public void_binary_helper<syntactic> {
00376 static inline string short_type_name () { return "Y"; }
00377 static inline generic full_type_name () { return "Syntactic"; }
00378 static inline generic disassemble (const syntactic& x) {
00379 return *x; }
00380 static inline syntactic assemble (const generic& x) {
00381 return as_syntactic (x); }
00382 static inline void write (const port& out, const syntactic& s) {
00383 binary_write<generic> (out, *s); }
00384 static inline syntactic read (const port& in) {
00385 return as_syntactic (binary_read<generic> (in)); }
00386 };
00387
00388 template<>
00389 struct binary_helper<exception>: public void_binary_helper<exception> {
00390 static inline string short_type_name () { return "Exc"; }
00391 static inline generic full_type_name () { return "Exception"; }
00392 static inline generic disassemble (const exception& x) {
00393 return *x; }
00394 static inline exception assemble (const generic& x) {
00395 return exception (x); }
00396 static inline void write (const port& out, const exception& e) {
00397 binary_write<generic> (out, *e); }
00398 static inline exception read (const port& in) {
00399 return exception (binary_read<generic> (in)); }
00400 };
00401
00402 template<typename FT, typename T>
00403 struct format_binary_helper {
00404 static inline void write (const port& out, const format<T>& fm) {
00405 binary_write<T> (out, get_sample (fm)); }
00406 static inline format<T> read (const port& in) {
00407 return get_format (binary_read<T> (in)); }
00408 };
00409
00410 template<typename T>
00411 struct format_binary_helper<empty_format,T> {
00412 static inline void write (const port&, const format<T>&) {}
00413 static inline format<T> read (const port&) { return format<T> (); }
00414 };
00415
00416 template<typename T>
00417 struct binary_helper<format<T> >: public void_binary_helper<format<T> > {
00418 typedef typename format<T>::FT FT;
00419 static inline string short_type_name () {
00420 return "Fm" * Short_type_name (T); }
00421 static inline generic full_type_name () {
00422 return gen ("Format", Full_type_name (T)); }
00423 static inline generic disassemble (const format<T>& fm) {
00424 return binary_disassemble (get_sample (fm)); }
00425 static inline format<T> assemble (const generic& x) {
00426 return get_format (binary_assemble<T> (x)); }
00427 static inline void write (const port& out, const format<T>& fm) {
00428 format_binary_helper<FT,T>::write (out, fm); }
00429 static inline format<T> read (const port& in) {
00430 return format_binary_helper<FT,T>::read (in); }
00431 };
00432
00433 }
00434 #endif // __PORT_HPP