|
Urbi SDK Remote for C++
2.7.3
|
00001 /* 00002 * Copyright (C) 2004, 2006-2011, Gostai S.A.S. 00003 * 00004 * This software is provided "as is" without warranty of any kind, 00005 * either expressed or implied, including but not limited to the 00006 * implied warranties of fitness for a particular purpose. 00007 * 00008 * See the LICENSE file for more information. 00009 */ 00010 00013 00014 #ifndef URBI_UABSTRACTCLIENT_HH 00015 # define URBI_UABSTRACTCLIENT_HH 00016 00017 # include <libport/cstdio> 00018 # include <libport/sys/types.h> 00019 # include <libport/cstring> 00020 # include <libport/cstdlib> 00021 # include <cstdarg> 00022 00023 # include <list> 00024 # include <iostream> 00025 # include <string> 00026 00027 # include <libport/compiler.hh> 00028 # include <libport/fwd.hh> 00029 # include <libport/lockable.hh> 00030 # include <libport/traits.hh> 00031 00032 # include <urbi/fwd.hh> 00033 # include <urbi/export.hh> 00034 # include <urbi/ubinary.hh> 00035 # include <urbi/umessage.hh> 00036 00046 namespace urbi 00047 { 00049 00055 enum UCallbackAction 00056 { 00057 URBI_CONTINUE=0, 00058 URBI_REMOVE 00059 }; 00060 00062 enum { URBI_MAX_TAG_LENGTH = 64 }; 00063 00064 typedef unsigned int UCallbackID; 00065 00066 # define UINVALIDCALLBACKID 0 00067 00069 typedef UCallbackAction (*UCallback) (const UMessage&msg); 00070 00071 typedef UCallbackAction (*UCustomCallback) (void * callbackData, 00072 const UMessage&msg); 00073 00074 00075 //used internaly 00076 class UCallbackInfo 00077 { 00078 public: 00079 UCallbackInfo(UCallbackWrapper &w); 00080 bool operator==(UCallbackID id) const; 00081 00082 char tag[URBI_MAX_TAG_LENGTH]; 00083 UCallbackWrapper& callback; 00084 UCallbackID id; 00085 }; 00086 00087 //used internaly 00088 class UClientStreambuf; 00089 00090 00091 class LockableOstream: public std::ostream 00092 { 00093 public: 00094 LockableOstream(std::streambuf* sb) 00095 : std::ostream(sb) 00096 { 00097 } 00098 mutable libport::Lockable sendBufferLock; 00099 }; 00100 00101 00103 00120 class URBI_SDK_API UAbstractClient : public LockableOstream 00121 { 00122 public: 00124 enum { URBI_BUFLEN = 128000 }; 00126 enum { URBI_PORT = 54000 } ; 00128 static const char* default_host(); 00129 00133 typedef int error_type; 00134 00136 00143 UAbstractClient(const std::string& host = default_host(), 00144 unsigned port = URBI_PORT, 00145 size_t buflen = URBI_BUFLEN, 00146 bool server = false); 00147 00148 virtual ~UAbstractClient(); 00149 00150 bool init() const; 00152 error_type error() const; 00153 00154 /*----------. 00155 | Sending. | 00156 `----------*/ 00165 00166 00170 ATTRIBUTE_PRINTF(2, 3) 00171 error_type send(const char* format, ...); 00172 00174 error_type send(const std::string& s); 00175 00177 error_type send(const urbi::UValue& v); 00178 00180 error_type send(std::istream& is); 00181 00183 error_type sendBinary(const void* data, size_t len, 00184 const std::string& header); 00185 00187 error_type sendBin(const void*, size_t len); 00188 00190 ATTRIBUTE_PRINTF(4, 5) 00191 error_type sendBin(const void*, size_t len, const char* header, ...); 00192 00195 error_type startPack(); 00196 00199 error_type endPack(); 00200 00204 ATTRIBUTE_PRINTF(2, 3) 00205 error_type pack(const char* format, ...); 00206 00209 error_type vpack(const char* format, va_list args); 00210 00213 error_type sendFile(const std::string& f); 00214 00217 ATTRIBUTE_PRINTF(3, 4) 00218 UCallbackID sendCommand(UCallback, const char*, ...); 00219 00222 ATTRIBUTE_PRINTF(4, 5) 00223 UCallbackID sendCommand(UCustomCallback, void *, const char*, ...); 00224 00226 error_type sendSound(const char* device, 00227 const urbi::USound& sound, const char* tag = 0); 00228 00230 error_type putFile(const char* localName, const char* remoteName = 0); 00231 00233 error_type putFile(const void* buffer, size_t length, 00234 const char* remoteName); 00235 00237 00239 00249 00250 00254 UCallbackID setCallback(UCallbackWrapper& callback, const char* tag); 00255 00257 UCallbackID setErrorCallback(UCallbackWrapper& callback); 00258 00260 UCallbackID setWildcardCallback(UCallbackWrapper& callback); 00261 00263 UCallbackID setClientErrorCallback(UCallbackWrapper& callback); 00264 00266 UCallbackID setCallback(UCallback, const char* tag); 00267 00271 UCallbackID setCallback(UCustomCallback, void* callbackData, 00272 const char* tag); 00273 00275 00276 00277 00278 template<class C> 00279 UCallbackID 00280 setCallback(C& ref, UCallbackAction (C::*)(const UMessage&), 00281 const char * tag); 00282 template<class C, class P1> 00283 UCallbackID 00284 setCallback(C& ref, UCallbackAction (C::*)(P1, const UMessage&), 00285 P1, const char * tag); 00286 template<class C, class P1, class P2> 00287 UCallbackID 00288 setCallback(C& ref, UCallbackAction (C::*)(P1 , P2, const UMessage&), 00289 P1, P2, const char * tag); 00290 00291 template<class C, class P1, class P2, class P3> 00292 UCallbackID 00293 setCallback(C& ref, UCallbackAction (C::*)(P1 , P2, P3, const UMessage&), 00294 P1, P2, P3, const char* tag); 00295 00296 template<class C, class P1, class P2, class P3, class P4> 00297 UCallbackID 00298 setCallback(C& ref, UCallbackAction(C::*)(P1 , P2, P3, P4, const UMessage&), 00299 P1, P2, P3, P4, const char* tag); 00301 00304 int getAssociatedTag(UCallbackID id, char* tag); 00305 00308 int deleteCallback(UCallbackID id); 00309 00311 std::string fresh(); 00312 00315 ATTRIBUTE_DEPRECATED 00316 void makeUniqueTag(char* tag); 00317 00320 virtual void notifyCallbacks(const UMessage& msg); 00321 00323 ATTRIBUTE_PRINTF(2, 3) 00324 virtual void printf(const char* format, ...) = 0; 00325 00328 virtual unsigned int getCurrentTime() const = 0; 00329 00337 virtual void setKeepAliveCheck(unsigned pingInterval, 00338 unsigned pongTimeout) = 0; 00339 00341 const std::string& getServerName() const; 00342 00344 unsigned getServerPort() const; 00346 void processRecvBuffer(); 00347 00348 private: 00351 bool process_recv_buffer_binary_(); 00352 00355 bool process_recv_buffer_text_(); 00356 00357 public: 00359 std::ostream& stream_get(); 00360 00362 static const char* CLIENTERROR_TAG; 00363 00367 /* Inherited from LockableOstream libport::Lockable sendBufferLock;*/ 00368 protected: 00370 void onConnection(); 00371 00373 virtual error_type onClose(); 00374 bool closed_; 00375 00377 virtual error_type effectiveSend(const void* buffer, size_t size) = 0; 00378 00381 error_type effective_send(const void* buffer, size_t size); 00382 00384 error_type effective_send(const char* buffer); 00385 00387 error_type effective_send(const std::string& buffer); 00388 00389 libport::Lockable listLock; 00390 00392 UCallbackID addCallback(const char* tag, UCallbackWrapper& w); 00393 00398 void clientError(std::string msg, int code = 0); 00399 void clientError(const char* msg = 0, int code = 0); 00400 00402 std::string host_; 00404 unsigned port_; 00405 00407 bool server_; 00408 00410 size_t sendBufSize; 00411 size_t recvBufSize; 00412 00416 error_type rc; 00417 00419 char* recvBuffer; 00421 size_t recvBufferPosition; 00423 char* sendBuffer; 00424 00427 public: 00432 const std::string& kernelVersion() const; 00434 int kernelMajor() const; 00436 int kernelMinor() const; 00440 virtual void waitForKernelVersion() const = 0; 00441 00442 protected: 00445 std::string kernelVersion_; 00447 int kernelMajor_; 00449 int kernelMinor_; 00450 00453 virtual UCallbackAction setVersion(const UMessage& msg); 00455 00456 public: 00457 const std::string& connectionID() const; 00458 00459 protected: 00460 std::string connectionID_; 00463 virtual UCallbackAction setConnectionID(const UMessage& msg); 00464 00465 private: 00467 binaries_type bins; 00468 00470 void bins_clear(); 00471 00473 void* binaryBuffer; 00475 size_t binaryBufferPosition; 00477 size_t binaryBufferLength; 00478 00480 size_t parsePosition; 00482 bool inString; 00484 size_t nBracket; 00486 char* currentCommand; 00487 00489 bool binaryMode; 00490 00492 bool system; 00493 00495 size_t endOfHeaderPosition; 00496 char currentTag[URBI_MAX_TAG_LENGTH]; 00497 00498 int currentTimestamp; 00499 00500 protected: 00502 bool init_; 00503 00504 public: 00505 int getCurrentTimestamp() const; 00506 00507 private: 00508 typedef std::list<UCallbackInfo> callbacks_type; 00509 callbacks_type callbacks_; 00510 00512 unsigned int counter_; 00513 00516 std::ostream* stream_; 00517 00518 friend class UClientStreambuf; 00519 }; 00520 00522 class UCallbackWrapper 00523 { 00524 public: 00525 virtual UCallbackAction operator ()(const UMessage&)=0; 00526 virtual ~UCallbackWrapper() {} 00527 }; 00528 00529 00532 class UCallbackWrapperF 00533 : public UCallbackWrapper 00534 { 00535 UCallback cb; 00536 public: 00537 UCallbackWrapperF(UCallback cb) : cb(cb) {} 00538 virtual UCallbackAction operator ()(const UMessage& msg) 00539 { 00540 return cb(msg); 00541 } 00542 virtual ~UCallbackWrapperF() {} 00543 }; 00544 00545 class UCallbackWrapperCF 00546 : public UCallbackWrapper 00547 { 00548 UCustomCallback cb; 00549 void* cbData; 00550 public: 00551 UCallbackWrapperCF(UCustomCallback cb, void* cbData) 00552 : cb(cb), cbData(cbData) 00553 {} 00554 virtual UCallbackAction operator ()(const UMessage& msg) 00555 { 00556 return cb(cbData, msg); 00557 } 00558 virtual ~UCallbackWrapperCF() {} 00559 }; 00560 00561 template<class C> 00562 class UCallbackWrapper0 : 00563 public UCallbackWrapper 00564 { 00565 C& instance; 00566 UCallbackAction (C::*func)(const UMessage&); 00567 public: 00568 UCallbackWrapper0(C& instance, UCallbackAction (C::*func)(const UMessage&)) 00569 : instance(instance), func(func) 00570 {} 00571 virtual UCallbackAction operator ()(const UMessage& msg) 00572 { 00573 return (instance.*func)(msg); 00574 } 00575 virtual ~UCallbackWrapper0() {} 00576 }; 00577 00578 template<class C, class P1> 00579 class UCallbackWrapper1 00580 : public UCallbackWrapper 00581 { 00582 C& instance; 00583 UCallbackAction (C::*funcPtr)(P1, const UMessage&); 00584 typename libport::traits::remove_reference<P1>::type p1; 00585 public: 00586 UCallbackWrapper1(C& instance, 00587 UCallbackAction (C::*func)(P1, const UMessage&), P1 p1) 00588 : instance(instance), funcPtr(func), p1(p1) 00589 {} 00590 virtual UCallbackAction operator ()(const UMessage& msg) 00591 { 00592 return (instance.*funcPtr)(p1, msg); 00593 } 00594 virtual ~UCallbackWrapper1() 00595 {} 00596 }; 00597 00598 template<class C, class P1, class P2> 00599 class UCallbackWrapper2 : public UCallbackWrapper 00600 { 00601 C& instance; 00602 UCallbackAction (C::*func)(P1, P2, const UMessage&); 00603 typename libport::traits::remove_reference<P1>::type p1; 00604 typename libport::traits::remove_reference<P2>::type p2; 00605 public: 00606 UCallbackWrapper2( 00607 C& instance, UCallbackAction (C::*func)(P1, P2, const UMessage&), 00608 P1 p1, P2 p2) 00609 : instance(instance), func(func), p1(p1), p2(p2) 00610 {} 00611 virtual UCallbackAction operator ()(const UMessage& msg) 00612 { 00613 return (instance.*func)(p1, p2, msg); 00614 } 00615 virtual ~UCallbackWrapper2() 00616 {} 00617 }; 00618 00619 00620 template<class C, class P1, class P2, class P3> 00621 class UCallbackWrapper3 : public UCallbackWrapper 00622 { 00623 C& instance; 00624 UCallbackAction (C::*func)(P1, P2, P3, const UMessage&); 00625 typename libport::traits::remove_reference<P1>::type p1; 00626 typename libport::traits::remove_reference<P2>::type p2; 00627 typename libport::traits::remove_reference<P3>::type p3; 00628 public: 00629 UCallbackWrapper3( 00630 C& instance, UCallbackAction (C::*func)(P1, P2, P3, const UMessage&), 00631 P1 p1, P2 p2, P3 p3) 00632 : instance(instance), func(func), p1(p1), p2(p2), p3(p3) 00633 {} 00634 virtual UCallbackAction operator ()(const UMessage& msg) 00635 { 00636 return (instance.*func)(p1, p2, p3, msg); 00637 } 00638 virtual ~UCallbackWrapper3() 00639 {} 00640 }; 00641 00642 00643 template<class C, class P1, class P2, class P3, class P4> 00644 class UCallbackWrapper4 : public UCallbackWrapper 00645 { 00646 C& instance; 00647 UCallbackAction (C::*func)(P1, P2, P3, P4, const UMessage&); 00648 typename libport::traits::remove_reference<P1>::type p1; 00649 typename libport::traits::remove_reference<P2>::type p2; 00650 typename libport::traits::remove_reference<P3>::type p3; 00651 typename libport::traits::remove_reference<P4>::type p4; 00652 public: 00653 UCallbackWrapper4( 00654 C& instance, UCallbackAction(C::*func)(P1, P2, P3, P4, const UMessage&), 00655 P1 p1, P2 p2, P3 p3, P4 p4) 00656 : instance(instance), func(func), p1(p1), p2(p2), p3(p3), p4(p4) 00657 {} 00658 virtual UCallbackAction operator ()(const UMessage& msg) 00659 { 00660 return (instance.*func)(p1, p2, p3, p4, msg); 00661 } 00662 virtual ~UCallbackWrapper4() 00663 {} 00664 }; 00666 //overloaded callback generators 00667 00669 00670 00677 inline UCallbackWrapper& callback(UCallback cb) 00678 { 00679 return *new UCallbackWrapperF(cb); 00680 } 00681 inline UCallbackWrapper& callback(UCustomCallback cb, void* data) 00682 { 00683 return *new UCallbackWrapperCF(cb, data); 00684 } 00685 00686 00687 template<class C> UCallbackWrapper& 00688 callback(C& ref, UCallbackAction (C::*func)(const UMessage&)) 00689 { 00690 return *new UCallbackWrapper0<C>(ref, func); 00691 } 00692 00693 template<class C, class P1> UCallbackWrapper& 00694 callback(C& ref, UCallbackAction (C::*func)(P1, const UMessage&), P1 p1) 00695 { 00696 return *new UCallbackWrapper1<C, P1>(ref, func, p1); 00697 } 00698 00699 template<class C, class P1, class P2> UCallbackWrapper& 00700 callback(C& ref, UCallbackAction (C::*func)(P1, P2, const UMessage&), 00701 P1 p1, P2 p2) 00702 { 00703 return *new UCallbackWrapper2<C, P1, P2>(ref, func, p1, p2); 00704 } 00705 00706 template<class C, class P1, class P2, class P3> UCallbackWrapper& 00707 callback(C& ref, UCallbackAction (C::*func)(P1, P2, P3, const UMessage&), 00708 P1 p1, P2 p2, P3 p3) 00709 { 00710 return *new UCallbackWrapper3<C, P1, P2, P3>(ref, func, p1, p2, p3); 00711 } 00712 00713 template<class C, class P1, class P2, class P3, class P4> UCallbackWrapper& 00714 callback(C& ref, UCallbackAction (C::*func)(P1, P2, P3, P4, const UMessage&), 00715 P1 p1, P2 p2, P3 p3, P4 p4) 00716 { 00717 return *new UCallbackWrapper4<C, P1, P2, P3, P4>(ref, func, p1, p2, p3, p4); 00718 } 00719 00721 00722 00723 //old-style addCallback, deprecated 00724 template<class C> 00725 UCallbackID 00726 UAbstractClient::setCallback(C& ref, 00727 UCallbackAction (C::*func)(const UMessage&), 00728 const char* tag) 00729 { 00730 return addCallback(tag,*new UCallbackWrapper0<C>(ref, func)); 00731 } 00732 00733 template<class C, class P1> 00734 UCallbackID 00735 UAbstractClient::setCallback(C& ref, 00736 UCallbackAction (C::*func)(P1 , const UMessage&), 00737 P1 p1, const char* tag) 00738 { 00739 return addCallback(tag, *new UCallbackWrapper1<C, P1>(ref, func, p1)); 00740 } 00741 00742 template<class C, class P1, class P2> 00743 UCallbackID 00744 UAbstractClient::setCallback( 00745 C& ref, UCallbackAction (C::*func)(P1, P2, const UMessage&), 00746 P1 p1, P2 p2, const char* tag) 00747 { 00748 return addCallback(tag, *new UCallbackWrapper2<C, P1, P2> 00749 (ref, func, p1, p2)); 00750 } 00751 00752 template<class C, class P1, class P2, class P3> 00753 UCallbackID 00754 UAbstractClient::setCallback( 00755 C& ref, UCallbackAction (C::*func)(P1, P2, P3, const UMessage&), 00756 P1 p1 , P2 p2, P3 p3, const char* tag) 00757 { 00758 return addCallback(tag, *new UCallbackWrapper3<C, P1, P2, P3> 00759 (ref, func, p1, p2, p3)); 00760 } 00761 00762 template<class C, class P1, class P2, class P3, class P4> 00763 UCallbackID 00764 UAbstractClient::setCallback( 00765 C& ref, UCallbackAction (C::*func)(P1, P2, P3, P4, const UMessage&), 00766 P1 p1, P2 p2, P3 p3, P4 p4, const char* tag) 00767 { 00768 return addCallback(tag, *new UCallbackWrapper4<C, P1, P2, P3, P4> 00769 (ref, func, p1, p2, p3, p4)); 00770 } 00771 00772 00774 00792 # ifndef URBI 00793 # define URBI(A) \ 00794 ::urbi::unarmorAndSend(#A) 00795 # endif 00796 00797 static const char semicolon = ';'; 00798 static const char pipe = '|'; 00799 static const char parallel = '&'; 00800 static const char comma = ','; 00801 00803 URBI_SDK_API 00804 void execute(void); 00805 00807 URBI_SDK_API 00808 void exit(int code); 00809 00811 URBI_SDK_API 00812 UClient& connect(const std::string& host); 00813 00816 URBI_SDK_API 00817 void disconnect(UClient &client); 00818 00819 /*-----------------. 00820 | Default client. | 00821 `-----------------*/ 00822 00824 URBI_SDK_API 00825 UClient* getDefaultClient(); 00826 00828 URBI_SDK_API 00829 UClient& get_default_client(); 00830 00832 URBI_SDK_API 00833 void setDefaultClient(UClient* cl); 00834 00835 URBI_SDK_API 00836 std::string getClientConnectionID(const UAbstractClient* cli); 00837 00838 # ifndef DISABLE_IOSTREAM 00839 00840 URBI_SDK_API 00841 std::ostream& 00842 unarmorAndSend(const char* str, 00843 UAbstractClient* c = (UAbstractClient*)getDefaultClient()); 00844 # endif 00845 00846 URBI_SDK_API 00847 extern UClient* defaultClient; 00848 00850 URBI_SDK_API 00851 std::ostream& default_stream(); 00852 00853 } // namespace urbi 00854 00855 # include <urbi/uabstractclient.hxx> 00856 00857 #endif // URBI_UABSTRACTCLIENT_HH