Rapicorn - Experimental UI Toolkit - Source Code  13.07.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines
aida.hh
Go to the documentation of this file.
00001  // CC0 Public Domain: http://creativecommons.org/publicdomain/zero/1.0/
00002 #ifndef __RAPICORN_AIDA_HH__
00003 #define __RAPICORN_AIDA_HH__
00004 
00005 #include <rcore/cxxaux.hh>
00006 #include <string>
00007 #include <vector>
00008 #include <memory>               // auto_ptr
00009 #include <stdint.h>             // uint32_t
00010 #include <stdarg.h>
00011 #include <type_traits>
00012 #include <memory>
00013 #include <future>
00014 #include <set>
00015 #include <map>
00016 
00017 namespace Rapicorn { namespace Aida {
00018 
00019 // == Auxillary macros ==
00020 #define AIDA_CPP_STRINGIFYi(s)  #s // indirection required to expand __LINE__ etc
00021 #define AIDA_CPP_STRINGIFY(s)   AIDA_CPP_STRINGIFYi (s)
00022 #if     __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 3)
00023 #define AIDA_UNUSED             __attribute__ ((__unused__))
00024 #define AIDA_DEPRECATED         __attribute__ ((__deprecated__))
00025 #define AIDA_NORETURN           __attribute__ ((__noreturn__))
00026 #define AIDA_PRINTF(fix, arx)   __attribute__ ((__format__ (__printf__, fix, arx)))
00027 #define AIDA_BOOLi(expr)        __extension__ ({ bool _plic__bool; if (expr) _plic__bool = 1; else _plic__bool = 0; _plic__bool; })
00028 #define AIDA_ISLIKELY(expr)     __builtin_expect (AIDA_BOOLi (expr), 1)
00029 #define AIDA_UNLIKELY(expr)     __builtin_expect (AIDA_BOOLi (expr), 0)
00030 #define AIDA_ASSERT(expr)       do { if (__builtin_expect (!(expr), 0)) ::Rapicorn::Aida::assertion_error (__FILE__, __LINE__, #expr); } while (0)
00031 #define AIDA_ASSERT_RETURN(expr,...) do { if (__builtin_expect (!!(expr), 1)) break; ::Rapicorn::Aida::assertion_error (__FILE__, __LINE__, #expr); return __VA_ARGS__; } while (0)
00032 #else   // !__GNUC__
00033 #define AIDA_UNUSED
00034 #define AIDA_DEPRECATED
00035 #define AIDA_NORETURN
00036 #define AIDA_PRINTF(fix, arx)
00037 #define AIDA_ISLIKELY(expr)     expr
00038 #define AIDA_UNLIKELY(expr)     expr
00039 #define AIDA_ASSERT(expr)       do { } while (0)
00040 #endif
00041 #define AIDA_LIKELY             AIDA_ISLIKELY
00042 
00043 // == Standard Types ==
00044 using std::vector;
00045 typedef std::string String;
00046 using Rapicorn::int32;
00047 using Rapicorn::uint32;
00048 using Rapicorn::int64;
00049 using Rapicorn::uint64;
00050 
00051 // == Prototypes ==
00052 class SmartHandle;
00053 
00054 // == TypeKind ==
00056 enum TypeKind {
00057   UNTYPED        = 0,   
00058   VOID           = 'v', 
00059   BOOL           = 'b', 
00060   INT32          = 'i', 
00061   INT64          = 'l', 
00062   FLOAT64        = 'd', 
00063   STRING         = 's', 
00064   ENUM           = 'E', 
00065   SEQUENCE       = 'Q', 
00066   RECORD         = 'R', 
00067   INSTANCE       = 'C', 
00068   FUNC           = 'F', 
00069   TYPE_REFERENCE = 'T', 
00070   ANY            = 'Y', 
00071 };
00072 const char* type_kind_name (TypeKind type_kind); 
00073 
00075 struct EnumValue {
00076   int64 value;
00077   const char *ident, *label, *blurb;
00078   constexpr EnumValue (int64 dflt = 0) : value (dflt), ident (0), label (0), blurb (0) {}
00079 };
00080 
00081 // == TypeCode ==
00082 struct TypeCode 
00083 {
00084   /*copy*/              TypeCode        (const TypeCode&);
00085   /*dtor*/             ~TypeCode        ();
00086   bool                  operator!=      (const TypeCode&) const;
00087   bool                  operator==      (const TypeCode&) const;
00088   TypeCode&             operator=       (const TypeCode&);
00089   void                  swap            (TypeCode &other);      
00090   TypeKind              kind            () const;               
00091   std::string           kind_name       () const;               
00092   std::string           name            () const;               
00093   size_t                aux_count       () const;               
00094   std::string           aux_data        (size_t index) const;   
00095   std::string           aux_value       (std::string key) const; 
00096   std::string           hints           () const;               
00097   size_t                prerequisite_count () const;            
00098   std::string           prerequisite    (size_t index) const;   
00099   size_t                field_count     () const;               
00100   TypeCode              field           (size_t index) const;   
00101   std::string           origin          () const;               
00102   TypeCode              resolve         () const;               
00103   bool                  untyped         () const;               
00104   std::string           pretty          (const std::string &indent = "") const; 
00105   bool                  enum_combinable () const;               
00106   size_t                enum_count      () const;               
00107   EnumValue             enum_value      (size_t index) const;   
00108   EnumValue             enum_find       (int64 value) const;    
00109   EnumValue             enum_find       (const String &name) const; 
00110   String                enum_string     (int64 value) const;    
00111   int64                 enum_parse      (const String &value_string, String *error = NULL) const; 
00112   template<class E> static
00113   inline TypeCode       from_enum       ();                     
00114   class InternalType;
00115   class MapHandle;
00116 private: // implementation bits
00117   explicit              TypeCode        (MapHandle*, InternalType*);
00118   static TypeCode       notype          (MapHandle*);
00119   friend class TypeMap;
00120   MapHandle    *handle_;
00121   InternalType *type_;
00122 };
00123 
00124 class TypeMap 
00125 {
00126   TypeCode::MapHandle  *handle_;
00127   friend class TypeCode::MapHandle;
00128   explicit              TypeMap      (TypeCode::MapHandle*);
00129   static TypeMap        builtins     ();
00130   static TypeMap        enlist_map   (size_t length, const char *static_type_map, bool global);
00131 public:
00132   /*copy*/              TypeMap      (const TypeMap&);
00133   TypeMap&              operator=    (const TypeMap&);
00134   /*dtor*/             ~TypeMap      ();
00135   size_t                type_count   () const;                  
00136   const TypeCode        type         (size_t      index) const; 
00137   int                   error_status ();                        
00138   static TypeMap        load         (std::string file_name);   
00139   static TypeCode       lookup       (std::string name);        
00140   static TypeMap        load_local   (std::string file_name);   
00141   TypeCode              lookup_local (std::string name) const;  
00142   static TypeCode       notype       ();
00143   template<ssize_t S>
00144   static void           enlist_map   (const char (&static_type_map)[S]) { enlist_map (S, static_type_map, true); }
00145 };
00146 
00147 // == Type Declarations ==
00148 class ObjectBroker;
00149 class ClientConnection;
00150 class ServerConnection;
00151 union FieldUnion;
00152 class FieldBuffer;
00153 class FieldReader;
00154 typedef FieldBuffer* (*DispatchFunc) (FieldReader&);
00155 class PropertyList;
00156 class Property;
00157 
00158 // == ImplicitBase ==
00159 class ImplicitBase 
00160 {
00161 protected:
00162   virtual                     ~ImplicitBase       () = 0; // abstract class
00163   virtual const PropertyList& __aida_properties__ () = 0; 
00164   Property*                   __aida_lookup__     (const std::string &property_name);
00165   bool                        __aida_setter__     (const std::string &property_name, const std::string &value);
00166   std::string                 __aida_getter__     (const std::string &property_name);
00167 public:
00168   virtual std::string        __aida_type_name__   () const = 0; 
00169 };
00170 
00171 // == Any Type ==
00172 class Any 
00173 {
00175   template<class ANY> struct AnyField : ANY { // We must wrap Any::Field into a template, because "Any" is not yet fully defined.
00176     std::string name;
00177     AnyField () = default;
00178     AnyField (const std::string &_name, const ANY &any) : name (_name) { this->ANY::operator= (any); }
00179     template<class V>
00180     AnyField (const std::string &_name, const V &value) : name (_name) { this->operator<<= (value); }
00181   };
00183 public:
00184 #ifndef DOXYGEN
00185   typedef AnyField<Any> Field;  // See DOXYGEN section for the "unwrapped" definition.
00186 #else // DOXYGEN
00187   struct Field : Any    
00188   {
00189     String name;        
00190     AnyField();         
00191     AnyField (const String &name, const Any &any);                   
00192     template<class V> AnyField (const String &name, const V &value); 
00193   };
00194 #endif // DOXYGEN
00195   typedef std::vector<Field> FieldVector; 
00196   typedef std::vector<Any> AnyVector;     
00197 protected:
00198   bool  plain_zero_type (TypeKind kind);
00199   template<class Rec> static void any_from_record (Any &any, const Rec &record);
00200   template<class Rec> static void any_to_record   (Any &any, Rec &record);
00201 private:
00202   TypeCode type_code_;
00203   union {
00204     uint64 vuint64; int64 vint64; double vdouble; Any *vany; AnyVector *vanys; FieldVector *vfields; SmartHandle *shandle;
00205     String&       vstring() { return *(String*) this; static_assert (sizeof (String) <= sizeof (*this), "union size"); }
00206     const String& vstring() const { return *(const String*) this; }
00207   } u_;
00208   void    ensure  (TypeKind _kind) { if (AIDA_LIKELY (kind() == _kind)) return; rekind (_kind); }
00209   void    rekind  (TypeKind _kind);
00210   void    reset   ();
00211   bool    to_int  (int64 &v, char b) const;
00212   void    to_proto   (const TypeCode type_code, FieldBuffer &fb) const;
00213   void    from_proto (const TypeCode type_code, FieldReader &fbr);
00214 public:
00215   /*dtor*/ ~Any    ();                                   
00216   explicit  Any    ();                                   
00217   explicit  Any    (const TypeCode &tc);                 
00218   /*copy*/  Any    (const Any &clone);                   
00219   template<class V>
00220   explicit  Any    (const V &value);                     
00221   Any& operator=   (const Any &clone);                   
00222   bool operator==  (const Any &clone) const;             
00223   bool operator!=  (const Any &clone) const;             
00224   TypeCode  type   () const { return type_code_; }       
00225   TypeKind  kind   () const { return type_code_.kind(); } 
00226   void      retype (const TypeCode &tc);                 
00227   void      swap   (Any           &other);               
00228   bool operator>>= (bool          &v) const { int64 d; const bool r = to_int (d, 1); v = d; return r; }
00229   bool operator>>= (char          &v) const { int64 d; const bool r = to_int (d, 7); v = d; return r; }
00230   bool operator>>= (unsigned char &v) const { int64 d; const bool r = to_int (d, 8); v = d; return r; }
00231   bool operator>>= (int32         &v) const { int64 d; const bool r = to_int (d, 31); v = d; return r; }
00232   bool operator>>= (uint32        &v) const { int64 d; const bool r = to_int (d, 32); v = d; return r; }
00233   bool operator>>= (LongIffy      &v) const { int64 d; const bool r = to_int (d, 47); v = d; return r; }
00234   bool operator>>= (ULongIffy     &v) const { int64 d; const bool r = to_int (d, 48); v = d; return r; }
00235   bool operator>>= (int64         &v) const { int64 d; const bool r = to_int (d, 63); v = d; return r; }
00236   bool operator>>= (uint64        &v) const { int64 d; const bool r = to_int (d, 64); v = d; return r; }
00237   bool operator>>= (float         &v) const { double d; const bool r = operator>>= (d); v = d; return r; }
00238   bool operator>>= (double        &v) const; 
00239   bool operator>>= (EnumValue          &v) const; 
00240   bool operator>>= (const char        *&v) const { String s; const bool r = operator>>= (s); v = s.c_str(); return r; }
00241   bool operator>>= (std::string        &v) const; 
00242   bool operator>>= (const Any         *&v) const; 
00243   bool operator>>= (const AnyVector   *&v) const; 
00244   bool operator>>= (const FieldVector *&v) const; 
00245   bool operator>>= (SmartHandle        &v);
00246   String     to_string (const String &field_name = "") const; 
00247   const Any& as_any   () const { return kind() == ANY ? *u_.vany : *this; } 
00248   double     as_float () const; 
00249   int64      as_int   () const; 
00250   String     as_string() const; 
00251   void operator<<= (bool           v);
00252   void operator<<= (char           v) { operator<<= (int32 (v)); }
00253   void operator<<= (unsigned char  v) { operator<<= (int32 (v)); }
00254   void operator<<= (int32          v);
00255   void operator<<= (uint32         v) { operator<<= (int64 (v)); }
00256   void operator<<= (LongIffy       v) { operator<<= (CastIffy (v)); }
00257   void operator<<= (ULongIffy      v) { operator<<= (UCastIffy (v)); }
00258   void operator<<= (int64          v); 
00259   void operator<<= (uint64         v); 
00260   void operator<<= (float          v) { operator<<= (double (v)); }
00261   void operator<<= (double         v); 
00262   void operator<<= (const EnumValue   &v); 
00263   void operator<<= (const char        *v) { operator<<= (std::string (v)); }
00264   void operator<<= (char              *v) { operator<<= (std::string (v)); }
00265   void operator<<= (const String      &v); 
00266   void operator<<= (const Any         &v); 
00267   void operator<<= (const AnyVector   &v); 
00268   void operator<<= (const FieldVector &v); 
00269   void operator<<= (const SmartHandle &v);
00270 };
00271 
00272 // === EventFd ===
00273 class EventFd            
00274 {
00275   int      fds[2];
00276   void     operator= (const EventFd&) = delete; // no assignments
00277   explicit EventFd   (const EventFd&) = delete; // no copying
00278 public:
00279   explicit EventFd   ();
00280   int      open      (); 
00281   bool     opened    (); 
00282   void     wakeup    (); 
00283   int      inputfd   (); 
00284   bool     pollin    (); 
00285   void     flush     (); 
00286   /*Des*/ ~EventFd   ();
00287 };
00288 
00289 // == Type Hash ==
00290 struct TypeHash {
00291   uint64 typehi, typelo;
00292   explicit    TypeHash   (uint64 hi, uint64 lo) : typehi (hi), typelo (lo) {}
00293   explicit    TypeHash   () : typehi (0), typelo (0) {}
00294   inline bool operator== (const TypeHash &z) const { return typehi == z.typehi && typelo == z.typelo; }
00295 };
00296 typedef std::vector<TypeHash> TypeHashList;
00297 
00298 // == Utilities ==
00299 void assertion_error (const char *file, uint line, const char *expr) AIDA_NORETURN;
00300 void fatal_error     (const String &msg) AIDA_NORETURN;
00301 void print_warning   (const String &msg);
00302 
00303 // == Type Utilities ==
00304 template<class Y> struct ValueType           { typedef Y T; };
00305 template<class Y> struct ValueType<Y&>       { typedef Y T; };
00306 template<class Y> struct ValueType<const Y&> { typedef Y T; };
00307 
00308 // == Message IDs ==
00309 enum MessageId {
00310   MSGID_NONE           = 0x0000000000000000ULL, 
00311   MSGID_ONEWAY_CALL    = 0x1000000000000000ULL, 
00312   MSGID_DISCONNECT     = 0x2000000000000000ULL, 
00313   MSGID_EMIT_ONEWAY    = 0x3000000000000000ULL, 
00314   MSGID_DROP_REFS      = 0x4000000000000000ULL, 
00315   // unused            = 0x5
00316   // unused            = 0x6
00317   // unused            = 0x7
00318   MSGID_HELLO_REQUEST  = 0x8000000000000000ULL, 
00319   MSGID_TWOWAY_CALL    = 0x9000000000000000ULL, 
00320   MSGID_CONNECT        = 0xa000000000000000ULL, 
00321   MSGID_EMIT_TWOWAY    = 0xb000000000000000ULL, 
00322   MSGID_HELLO_REPLY    = 0xc000000000000000ULL, 
00323   MSGID_CALL_RESULT    = 0xd000000000000000ULL, 
00324   MSGID_CONNECT_RESULT = 0xe000000000000000ULL, 
00325   MSGID_EMIT_RESULT    = 0xf000000000000000ULL, 
00326 };
00327 inline bool      msgid_has_result (MessageId mid) { return (mid & 0xc000000000000000ULL) == 0x8000000000000000ULL; }
00328 inline bool      msgid_is_result  (MessageId mid) { return (mid & 0xc000000000000000ULL) == 0xc000000000000000ULL; }
00329 inline MessageId msgid_as_result  (MessageId mid) { return MessageId (mid | 0x4000000000000000ULL); }
00330 inline uint64    msgid_mask       (uint64    mid) { return  mid & 0xf000000000000000ULL; }
00331 
00332 union IdentifierParts {
00333   uint64 vuint64;
00334   struct { // MessageId bits
00335     uint   sender_connection : 16;
00336     uint   msg_unused : 16;
00337     uint   receiver_connection : 16;
00338     uint   msg_unused2 : 8;
00339     uint   message_id : 8;
00340   };
00341   struct { // OrbID bits
00342     uint   orbid32 : 32;
00343     uint   orbid_connection : 16;
00344     uint   orbid_type_index : 16;
00345   };
00346   constexpr IdentifierParts (uint64 vu64) : vuint64 (vu64) {}
00347   constexpr IdentifierParts (MessageId id, uint sender_con, uint receiver_con) :
00348     sender_connection (sender_con), msg_unused (0), receiver_connection (receiver_con), message_id (IdentifierParts (id).message_id)
00349   {}
00350   struct ORBID {}; // constructor tag
00351   constexpr IdentifierParts (const ORBID&, uint orbid_con, uint orbid_v32, uint type_index) :
00352     orbid32 (orbid_v32), orbid_connection (orbid_con), orbid_type_index (type_index) {}
00353 };
00354 constexpr uint64 CONNECTION_MASK = 0x0000ffff;
00355 
00356 // == OrbObject ==
00358 class OrbObject {
00359   uint64      orbid_;
00360 protected:
00361   explicit      OrbObject       (uint64 orbid);
00362 public:
00363   uint64        orbid           ()            { return orbid_; }
00364 };
00365 
00366 // == SmartHandle ==
00367 class SmartHandle {
00368   OrbObject     *orbo_;
00369   template<class Parent> struct NullSmartHandle : public Parent { TypeHashList __aida_typelist__ () { return TypeHashList(); } };
00370   typedef NullSmartHandle<SmartHandle> NullHandle;
00371   friend  class ObjectBroker;
00372   void    assign (const SmartHandle&);
00373   void    reset ();
00374 protected:
00375   explicit          SmartHandle (OrbObject&);
00376   explicit          SmartHandle ();
00377 public:
00378   uint64            _orbid        () const { return orbo_->orbid(); }
00379   virtual          ~SmartHandle   ();
00380   static NullHandle _null_handle  ()       { return NullHandle(); }
00381   // Determine if this SmartHandle contains an object or null handle.
00382   explicit          operator bool () const noexcept               { return 0 != orbo_->orbid(); }
00383   bool              operator==    (std::nullptr_t) const noexcept { return !static_cast<bool> (*this); }
00384   bool              operator!=    (std::nullptr_t) const noexcept { return static_cast<bool> (*this); }
00385   bool              operator==    (const SmartHandle&) const noexcept;
00386   bool              operator!=    (const SmartHandle&) const noexcept;
00387 };
00388 inline bool operator== (std::nullptr_t, const SmartHandle &shd) noexcept { return !static_cast<bool> (shd); }
00389 inline bool operator!= (std::nullptr_t, const SmartHandle &shd) noexcept { return static_cast<bool> (shd); }
00390 
00391 // == SmartMember ==
00392 template<class SmartHandle>
00393 class SmartMember : public SmartHandle {
00394 public:
00395   inline   SmartMember (const SmartHandle &src) : SmartHandle() { *this = src; }
00396   explicit SmartMember () : SmartHandle() {}
00397   void     operator=   (const SmartHandle &src) { SmartHandle::operator= (src); }
00398 };
00399 
00400 // == Conversion Type Tags ==
00401 constexpr struct _ServantType {} _servant; 
00402 constexpr struct _HandleType  {} _handle;  
00403 
00404 // == ObjectBroker ==
00405 class ObjectBroker {
00406 protected:
00407   static void              tie_handle (SmartHandle&, uint64);
00408 public:
00409   static void              pop_handle (FieldReader&, SmartHandle&);
00410   static void              post_msg   (FieldBuffer*); 
00411   static ServerConnection* new_server_connection (const std::string &feature_keys);
00412   static ClientConnection* new_client_connection (const std::string &feature_keys);
00413   static uint         connection_id_from_signal_handler_id (size_t signal_handler_id);
00414   static inline uint  connection_id_from_orbid  (uint64 orbid)        { return IdentifierParts (orbid).orbid_connection; }
00415   static inline uint  connection_id_from_handle (const SmartHandle &sh) { return connection_id_from_orbid (sh._orbid()); }
00416   static inline uint  connection_id_from_keys   (const vector<std::string> &feature_key_list);
00417   static inline uint  sender_connection_id      (uint64 msgid)        { return IdentifierParts (msgid).sender_connection; }
00418   static inline uint  receiver_connection_id    (uint64 msgid)        { return IdentifierParts (msgid).receiver_connection; }
00419   static FieldBuffer* renew_into_result         (FieldBuffer *fb,  MessageId m, uint rconnection, uint64 h, uint64 l, uint32 n = 1);
00420   static FieldBuffer* renew_into_result         (FieldReader &fbr, MessageId m, uint rconnection, uint64 h, uint64 l, uint32 n = 1);
00421   template<class TargetHandle> static TargetHandle smart_handle_down_cast (SmartHandle smh);
00422 };
00423 
00424 // == FieldBuffer ==
00425 union FieldUnion {
00426   int64        vint64;
00427   double       vdouble;
00428   Any         *vany;
00429   uint64       smem[(sizeof (std::string) + 7) / 8];    // String memory
00430   void        *pmem[2];                 // equate sizeof (FieldBuffer)
00431   uint8        bytes[8];                // FieldBuffer types
00432   struct { uint32 index, capacity; }; // FieldBuffer.buffermem[0]
00433 };
00434 
00435 class FieldBuffer { // buffer for marshalling procedure calls
00436   friend class FieldReader;
00437   void               check_internal ();
00438   inline FieldUnion& upeek (uint32 n) const { return buffermem[offset() + n]; }
00439 protected:
00440   FieldUnion        *buffermem;
00441   inline void        check ()      { if (AIDA_UNLIKELY (size() > capacity())) check_internal(); }
00442   inline uint32      offset () const { const uint32 offs = 1 + (capacity() + 7) / 8; return offs; }
00443   inline TypeKind    type_at  (uint32 n) const { return TypeKind (buffermem[1 + n/8].bytes[n%8]); }
00444   inline void        set_type (TypeKind ft)  { buffermem[1 + size()/8].bytes[size()%8] = ft; }
00445   inline FieldUnion& getu () const           { return buffermem[offset() + size()]; }
00446   inline FieldUnion& addu (TypeKind ft) { set_type (ft); FieldUnion &u = getu(); buffermem[0].index++; check(); return u; }
00447   inline FieldUnion& uat (uint32 n) const { return AIDA_LIKELY (n < size()) ? upeek (n) : *(FieldUnion*) NULL; }
00448   explicit           FieldBuffer (uint32 _ntypes);
00449   explicit           FieldBuffer (uint32, FieldUnion*, uint32);
00450 public:
00451   virtual     ~FieldBuffer();
00452   inline uint32 size     () const          { return buffermem[0].index; }
00453   inline uint32 capacity () const          { return buffermem[0].capacity; }
00454   inline uint64 first_id () const          { return AIDA_LIKELY (buffermem && size() && type_at (0) == INT64) ? upeek (0).vint64 : 0; }
00455   inline void add_bool   (bool    vbool)   { FieldUnion &u = addu (BOOL); u.vint64 = vbool; }
00456   inline void add_int64  (int64 vint64)    { FieldUnion &u = addu (INT64); u.vint64 = vint64; }
00457   inline void add_evalue (int64 vint64)    { FieldUnion &u = addu (ENUM); u.vint64 = vint64; }
00458   inline void add_double (double vdouble)  { FieldUnion &u = addu (FLOAT64); u.vdouble = vdouble; }
00459   inline void add_string (const String &s) { FieldUnion &u = addu (STRING); new (&u) String (s); }
00460   inline void add_object (uint64 objid)    { FieldUnion &u = addu (INSTANCE); u.vint64 = objid; }
00461   inline void add_any    (const Any &vany) { FieldUnion &u = addu (ANY); u.vany = new Any (vany); }
00462   inline void add_header1 (MessageId m, uint c, uint64 h, uint64 l) { add_int64 (IdentifierParts (m, c, 0).vuint64); add_int64 (h); add_int64 (l); }
00463   inline void add_header2 (MessageId m, uint c, uint r, uint64 h, uint64 l) { add_int64 (IdentifierParts (m, c, r).vuint64); add_int64 (h); add_int64 (l); }
00464   inline FieldBuffer& add_rec (uint32 nt) { FieldUnion &u = addu (RECORD); return *new (&u) FieldBuffer (nt); }
00465   inline FieldBuffer& add_seq (uint32 nt) { FieldUnion &u = addu (SEQUENCE); return *new (&u) FieldBuffer (nt); }
00466   inline void         reset();
00467   String              first_id_str() const;
00468   String              to_string() const;
00469   static String       type_name (int field_type);
00470   static FieldBuffer* _new (uint32 _ntypes); // Heap allocated FieldBuffer
00471   // static FieldBuffer* new_error (const String &msg, const String &domain = "");
00472   static FieldBuffer* new_result (MessageId m, uint rconnection, uint64 h, uint64 l, uint32 n = 1);
00473   inline void operator<<= (uint32 v)          { FieldUnion &u = addu (INT64); u.vint64 = v; }
00474   inline void operator<<= (ULongIffy v)       { FieldUnion &u = addu (INT64); u.vint64 = v; }
00475   inline void operator<<= (uint64 v)          { FieldUnion &u = addu (INT64); u.vint64 = v; }
00476   inline void operator<<= (int32 v)           { FieldUnion &u = addu (INT64); u.vint64 = v; }
00477   inline void operator<<= (LongIffy v)        { FieldUnion &u = addu (INT64); u.vint64 = v; }
00478   inline void operator<<= (int64 v)           { FieldUnion &u = addu (INT64); u.vint64 = v; }
00479   inline void operator<<= (bool   v)          { FieldUnion &u = addu (BOOL); u.vint64 = v; }
00480   inline void operator<<= (double v)          { FieldUnion &u = addu (FLOAT64); u.vdouble = v; }
00481   inline void operator<<= (EnumValue e)       { FieldUnion &u = addu (ENUM); u.vint64 = e.value; }
00482   inline void operator<<= (const String &s)   { FieldUnion &u = addu (STRING); new (&u) String (s); }
00483   inline void operator<<= (Any    v)          { FieldUnion &u = addu (ANY); u.vany = new Any (v); }
00484   inline void operator<<= (const TypeHash &h) { *this <<= h.typehi; *this <<= h.typelo; }
00485 };
00486 
00487 class FieldBuffer8 : public FieldBuffer { // Stack contained buffer for up to 8 fields
00488   FieldUnion bmem[1 + 1 + 8];
00489 public:
00490   virtual ~FieldBuffer8 () { reset(); buffermem = NULL; }
00491   inline   FieldBuffer8 (uint32 ntypes = 8) : FieldBuffer (ntypes, bmem, sizeof (bmem)) { AIDA_ASSERT (ntypes <= 8); }
00492 };
00493 
00494 class FieldReader { // read field buffer contents
00495   const FieldBuffer *fb_;
00496   uint32             nth_;
00497   void               check_request (int type);
00498   inline void        request (int t) { if (AIDA_UNLIKELY (nth_ >= n_types() || get_type() != t)) check_request (t); }
00499   inline FieldUnion& fb_getu (int t) { request (t); return fb_->upeek (nth_); }
00500   inline FieldUnion& fb_popu (int t) { request (t); FieldUnion &u = fb_->upeek (nth_++); return u; }
00501 public:
00502   explicit                 FieldReader (const FieldBuffer &fb) : fb_ (&fb), nth_ (0) {}
00503   inline const FieldBuffer* field_buffer() const { return fb_; }
00504   inline void               reset      (const FieldBuffer &fb) { fb_ = &fb; nth_ = 0; }
00505   inline void               reset      () { fb_ = NULL; nth_ = 0; }
00506   inline uint32             remaining  () { return n_types() - nth_; }
00507   inline void               skip       () { if (AIDA_UNLIKELY (nth_ >= n_types())) check_request (0); nth_++; }
00508   inline void               skip_header () { skip(); skip(); skip(); }
00509   inline uint32             n_types    () { return fb_->size(); }
00510   inline TypeKind           get_type   () { return fb_->type_at (nth_); }
00511   inline int64              get_bool   () { FieldUnion &u = fb_getu (BOOL); return u.vint64; }
00512   inline int64              get_int64  () { FieldUnion &u = fb_getu (INT64); return u.vint64; }
00513   inline int64              get_evalue () { FieldUnion &u = fb_getu (ENUM); return u.vint64; }
00514   inline double             get_double () { FieldUnion &u = fb_getu (FLOAT64); return u.vdouble; }
00515   inline const String&      get_string () { FieldUnion &u = fb_getu (STRING); return *(String*) &u; }
00516   inline uint64             get_object () { FieldUnion &u = fb_getu (INSTANCE); return u.vint64; }
00517   inline const Any&         get_any    () { FieldUnion &u = fb_getu (ANY); return *u.vany; }
00518   inline const FieldBuffer& get_rec    () { FieldUnion &u = fb_getu (RECORD); return *(FieldBuffer*) &u; }
00519   inline const FieldBuffer& get_seq    () { FieldUnion &u = fb_getu (SEQUENCE); return *(FieldBuffer*) &u; }
00520   inline int64              pop_bool   () { FieldUnion &u = fb_popu (BOOL); return u.vint64; }
00521   inline int64              pop_int64  () { FieldUnion &u = fb_popu (INT64); return u.vint64; }
00522   inline int64              pop_evalue () { FieldUnion &u = fb_popu (ENUM); return u.vint64; }
00523   inline double             pop_double () { FieldUnion &u = fb_popu (FLOAT64); return u.vdouble; }
00524   inline const String&      pop_string () { FieldUnion &u = fb_popu (STRING); return *(String*) &u; }
00525   inline uint64             pop_object () { FieldUnion &u = fb_popu (INSTANCE); return u.vint64; }
00526   inline const Any&         pop_any    () { FieldUnion &u = fb_popu (ANY); return *u.vany; }
00527   inline const FieldBuffer& pop_rec    () { FieldUnion &u = fb_popu (RECORD); return *(FieldBuffer*) &u; }
00528   inline const FieldBuffer& pop_seq    () { FieldUnion &u = fb_popu (SEQUENCE); return *(FieldBuffer*) &u; }
00529   inline void operator>>= (uint32 &v)          { FieldUnion &u = fb_popu (INT64); v = u.vint64; }
00530   inline void operator>>= (ULongIffy &v)       { FieldUnion &u = fb_popu (INT64); v = u.vint64; }
00531   inline void operator>>= (uint64 &v)          { FieldUnion &u = fb_popu (INT64); v = u.vint64; }
00532   inline void operator>>= (int32 &v)           { FieldUnion &u = fb_popu (INT64); v = u.vint64; }
00533   inline void operator>>= (LongIffy &v)        { FieldUnion &u = fb_popu (INT64); v = u.vint64; }
00534   inline void operator>>= (int64 &v)           { FieldUnion &u = fb_popu (INT64); v = u.vint64; }
00535   inline void operator>>= (bool &v)            { FieldUnion &u = fb_popu (BOOL); v = u.vint64; }
00536   inline void operator>>= (double &v)          { FieldUnion &u = fb_popu (FLOAT64); v = u.vdouble; }
00537   inline void operator>>= (EnumValue &e)       { FieldUnion &u = fb_popu (ENUM); e.value = u.vint64; }
00538   inline void operator>>= (String &s)          { FieldUnion &u = fb_popu (STRING); s = *(String*) &u; }
00539   inline void operator>>= (Any &v)             { FieldUnion &u = fb_popu (ANY); v = *u.vany; }
00540   inline void operator>>= (TypeHash &h)        { *this >>= h.typehi; *this >>= h.typelo; }
00541   inline void operator>>= (std::vector<bool>::reference v) { bool b; *this >>= b; v = b; }
00542 };
00543 
00544 // == Connections ==
00546 class BaseConnection {
00547   uint              index_;
00548   const std::string feature_keys_;
00549   friend  class ObjectBroker;
00550   RAPICORN_CLASS_NON_COPYABLE (BaseConnection);
00551 protected:
00552   void                   register_connection  ();
00553   void                   unregister_connection();
00554   explicit               BaseConnection  (const std::string &feature_keys);
00555   virtual               ~BaseConnection  ();
00556   virtual void           send_msg        (FieldBuffer*) = 0; 
00557   static BaseConnection* connection_from_id (uint id);  
00558 public:
00559   uint                   connection_id  () const;   
00560   virtual int            notify_fd      () = 0;     
00561   virtual bool           pending        () = 0;     
00562   virtual void           dispatch       () = 0;     
00563   virtual void           remote_origin  (ImplicitBase *rorigin);
00564   virtual SmartHandle    remote_origin  (const vector<std::string> &feature_key_list);
00565 };
00566 
00568 typedef FieldBuffer* SignalEmitHandler (const FieldBuffer*, void*);
00569 
00571 class ServerConnection : public BaseConnection {
00572   RAPICORN_CLASS_NON_COPYABLE (ServerConnection);
00573 protected:
00574   /*ctor*/           ServerConnection (const std::string &feature_keys);
00575   virtual           ~ServerConnection ();
00576 public: 
00577   virtual uint64        instance2orbid (ImplicitBase*) = 0;
00578   virtual ImplicitBase* orbid2instance (uint64) = 0;
00579   virtual ImplicitBase* remote_origin  () const = 0;
00580 protected: 
00581   static DispatchFunc find_method (uint64 hi, uint64 lo); 
00582 public:
00583   struct MethodEntry       { uint64 hashhi, hashlo; DispatchFunc dispatcher; };
00584   struct MethodRegistry    
00585   {
00586     template<class T, size_t S> MethodRegistry  (T (&static_const_entries)[S])
00587     { for (size_t i = 0; i < S; i++) register_method (static_const_entries[i]); }
00588   private: static void register_method  (const MethodEntry &mentry);
00589   };
00590   typedef std::function<void (Rapicorn::Aida::FieldReader&)> EmitResultHandler;
00591   virtual void emit_result_handler_add (size_t id, const EmitResultHandler &handler) = 0;
00592 };
00593 
00595 class ClientConnection : public BaseConnection {
00596   RAPICORN_CLASS_NON_COPYABLE (ClientConnection);
00597 protected:
00598   explicit              ClientConnection (const std::string &feature_keys);
00599   virtual              ~ClientConnection ();
00600 public: 
00601   virtual FieldBuffer*  call_remote (FieldBuffer*) = 0; 
00602 public: 
00603   virtual size_t        signal_connect    (uint64 hhi, uint64 hlo, uint64 orbid, SignalEmitHandler seh, void *data) = 0;
00604   virtual bool          signal_disconnect (size_t signal_handler_id) = 0;
00605 public: 
00606   virtual std::string   type_name_from_orbid (uint64 orbid) = 0;
00607 };
00608 
00609 // == inline implementations ==
00610 template<class E> inline TypeCode
00611 TypeCode::from_enum () // fallback for unspecialized types
00612 {
00613   static_assert (0 * sizeof (E), "no EnumInfo specialisation for this type");
00614   return *(TypeCode*) NULL; // silence compiler
00615 }
00616 
00617 template<class V> inline
00618 Any::Any (const V &value) :
00619   type_code_ (TypeMap::notype()), u_ {0}
00620 {
00621   this->operator<<= (value);
00622 }
00623 
00624 template<> inline
00625 Any::Any<Any::Field> (const Any::Field &clone) :
00626   type_code_ (TypeMap::notype()), u_ {0}
00627 {
00628   this->operator= (clone);
00629 }
00630 
00631 inline
00632 Any::Any() :
00633   type_code_ (TypeMap::notype()), u_ {0}
00634 {}
00635 
00636 inline
00637 Any::Any (const TypeCode &tc) :
00638   type_code_ (plain_zero_type (tc.kind()) ? tc : TypeMap::notype()), u_ {0}
00639 {
00640   if (!plain_zero_type (tc.kind()))
00641     retype (tc);        // carry out special initializations
00642 }
00643 
00644 inline bool
00645 Any::plain_zero_type (TypeKind kind)
00646 {
00647   switch (kind)
00648     {
00649     case UNTYPED: case BOOL: case INT32: case INT64: case FLOAT64: case ENUM:
00650       return true;      // simple, properly initialized with u {0}
00651     case STRING: case ANY: case SEQUENCE: case RECORD: case INSTANCE:
00652     default:
00653       return false;     // complex types, needing special initializations
00654     }
00655 }
00656 
00657 inline
00658 Any::Any (const Any &clone) :
00659   type_code_ (TypeMap::notype()), u_ {0}
00660 {
00661   this->operator= (clone);
00662 }
00663 
00664 inline
00665 Any::~Any ()
00666 {
00667   reset();
00668 }
00669 
00670 template<class Rec> inline void
00671 Any::any_from_record (Any &any, const Rec &record)
00672 {
00673   const std::string record_type_name = record.__aida_type_name__();
00674   TypeCode type_code = TypeMap::lookup (record_type_name);
00675   AIDA_ASSERT_RETURN (type_code.kind() == RECORD);
00676   FieldBuffer8 cfb (1);
00677   cfb <<= record;
00678   FieldReader fbr (cfb);
00679   any.from_proto (type_code, fbr);
00680 }
00681 
00682 template<class Rec> inline void
00683 Any::any_to_record (Any &any, Rec &record)
00684 {
00685   const std::string record_type_name = record.__aida_type_name__();
00686   TypeCode type_code = TypeMap::lookup (record_type_name);
00687   AIDA_ASSERT_RETURN (type_code.kind() == RECORD);
00688   AIDA_ASSERT_RETURN (any.kind() == RECORD);
00689   FieldBuffer8 cfb (1);
00690   any.to_proto (type_code, cfb);
00691   FieldReader fbr (cfb);
00692   AIDA_ASSERT_RETURN (fbr.get_type() == RECORD);
00693   fbr >>= record;
00694 }
00695 
00696 template<class TargetHandle> TargetHandle
00697 ObjectBroker::smart_handle_down_cast (SmartHandle smh)
00698 {
00699   TargetHandle target;
00700   target.assign (smh);                        // aka reinterpret_cast
00701   return TargetHandle::down_cast (target);    // aka dynamic_cast (remote)
00702 }
00703 
00704 inline void
00705 FieldBuffer::reset()
00706 {
00707   if (!buffermem)
00708     return;
00709   while (size() > 0)
00710     {
00711       buffermem[0].index--; // causes size()--
00712       switch (type_at (size()))
00713         {
00714         case STRING:    { FieldUnion &u = getu(); ((String*) &u)->~String(); }; break;
00715         case ANY:       { FieldUnion &u = getu(); delete u.vany; }; break;
00716         case SEQUENCE:
00717         case RECORD:    { FieldUnion &u = getu(); ((FieldBuffer*) &u)->~FieldBuffer(); }; break;
00718         default: ;
00719         }
00720     }
00721 }
00722 
00723 } } // Rapicorn::Aida
00724 
00725 // == Signals ==
00726 #include "aidasignal.hh"
00727 
00728 #endif // __RAPICORN_AIDA_HH__
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines