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