basix_doc 0.1
/Users/mourrain/Devel/mmx/basix/src/composite_port.cpp
Go to the documentation of this file.
00001 
00002 /******************************************************************************
00003 * MODULE     : composite_port.cpp
00004 * DESCRIPTION: Aggregation of several 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 #include <basix/port.hpp>
00014 #include <basix/string.hpp>
00015 #include <basix/vector.hpp>
00016 #include <basix/identifiers.hpp>
00017 
00019 
00020 namespace mmx {
00021 
00022 /******************************************************************************
00023 * Composite ports
00024 ******************************************************************************/
00025 
00026 class composite_port_rep: public port_rep {
00027   vector<port>   ps;
00028   vector<string> names;
00029 
00030 public:
00031   syntactic expression () const {
00032     vector<syntactic> v;
00033     for (nat i=0; i<N(ps); i++)
00034       v << syn (GEN_TYPE, syntactic (names[i]), flatten (ps[i]));
00035     return syn ("composite_port", v);
00036   }
00037 
00038   bool is_output_port () {
00039     for (nat i=0; i<N(ps); i++)
00040       if (mmx::is_output_port (ps[i]))
00041         return true;
00042     return false;
00043   }
00044   bool is_input_port () {
00045     for (nat i=0; i<N(ps); i++)
00046       if (mmx::is_input_port (ps[i]))
00047         return true;
00048     return false;
00049   }
00050   bool error_flag () {
00051     for (nat i=0; i<N(ps); i++)
00052       if (mmx::error_flag (ps[i]))
00053         return true;
00054     return false;
00055   }
00056   string error_message () {
00057     for (nat i=0; i<N(ps); i++)
00058       if (mmx::error_flag (ps[i]))
00059         return mmx::error_message (ps[i]);
00060     return "";
00061   }
00062   bool busy () {
00063     for (nat i=0; i<N(ps); i++)
00064       if (mmx::busy (ps[i]))
00065         return true;
00066     return false;
00067   }
00068   nat can_write () {
00069     nat r= (nat) (-1);
00070     for (nat i=0; i<N(ps); i++)
00071       if (mmx::is_output_port (ps[i]))
00072         r= min (r, mmx::can_write (ps[i]));
00073     return r;
00074   }
00075   nat can_read () {
00076     nat r= 0;
00077     for (nat i=0; i<N(ps); i++)
00078       if (mmx::is_input_port (ps[i]))
00079         r += mmx::can_read (ps[i]);
00080     return r;
00081   }
00082   void write (const char* s, nat n) {
00083     for (nat i=0; i<N(ps); i++)
00084       if (mmx::is_output_port (ps[i]))
00085         mmx::write (ps[i], s, n);
00086   }
00087   void read (char* s, nat n) {
00088     while (n > 0)
00089       for (nat i=0; i<N(ps); i++)
00090         if (n > 0 && mmx::is_input_port (ps[i])) {
00091           nat k= min (n, mmx::can_read (ps[i]));
00092           if (k > 0) mmx::read (ps[i], s, k);
00093           s += k;
00094           n -= k;
00095         }
00096     ASSERT (n == 0, "read failed");
00097   }
00098   void flush () {
00099     for (nat i=0; i<N(ps); i++)
00100       if (mmx::is_output_port (ps[i]))
00101         mmx::flush (ps[i]);
00102   }
00103   bool wait (int msecs) {
00104     for (nat i=0; i<N(ps); i++)
00105       if (mmx::is_input_port (ps[i])) {
00106         nat delay= min (msecs, 1);
00107         if (mmx::wait (ps[i], delay)) return true;
00108         msecs -= delay;
00109       }
00110     return false;
00111   }
00112   port component (const string& name) {
00113     for (nat i=0; i<N(ps); i++)
00114       if (name == names[i])
00115         return ps[i];
00116     ERROR ("port not found");
00117   }
00118 
00119 public:
00120   inline composite_port_rep (const vector<port>& p2, const vector<string>& n2):
00121     ps (p2), names (n2) {}
00122 };
00123 
00124 /******************************************************************************
00125 * Composite ports
00126 ******************************************************************************/
00127 
00128 port
00129 composite_port (const vector<port>& ps, const vector<string>& names) {
00130   ASSERT (N(ps) == N(names), "lengths do not match");
00131   return (port_rep*) new composite_port_rep (ps, names);
00132 }
00133 
00134 port
00135 composite_port (const vector<port>& ps) {
00136   nat i, n= N(ps);
00137   vector<string> names= fill<string> (n);
00138   for (i=0; i<n; i++) names[i]= as_string (i);
00139   return composite_port (ps, names);
00140 }
00141 
00142 } // namespace mmx
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines