Rapicorn - Experimental UI Toolkit - Source Code
13.07.0
|
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__