$search
00001 /* 00002 Dashel 00003 A cross-platform DAta Stream Helper Encapsulation Library 00004 Copyright (C) 2007 -- 2011: 00005 00006 Stephane Magnenat <stephane at magnenat dot net> 00007 (http://stephane.magnenat.net) 00008 Mobots group - Laboratory of Robotics Systems, EPFL, Lausanne 00009 (http://mobots.epfl.ch) 00010 00011 Sebastian Gerlach 00012 Kenzan Technologies 00013 (http://www.kenzantech.com) 00014 00015 All rights reserved. 00016 00017 Redistribution and use in source and binary forms, with or without 00018 modification, are permitted provided that the following conditions are met: 00019 * Redistributions of source code must retain the above copyright 00020 notice, this list of conditions and the following disclaimer. 00021 * Redistributions in binary form must reproduce the above copyright 00022 notice, this list of conditions and the following disclaimer in the 00023 documentation and/or other materials provided with the distribution. 00024 * Neither the names of "Mobots", "Laboratory of Robotics Systems", "EPFL", 00025 "Kenzan Technologies" nor the names of the contributors may be used to 00026 endorse or promote products derived from this software without specific 00027 prior written permission. 00028 00029 THIS SOFTWARE IS PROVIDED BY COPYRIGHT HOLDERS ``AS IS'' AND ANY 00030 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 00031 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 00032 DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS BE LIABLE FOR ANY 00033 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 00034 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 00035 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 00036 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00037 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 00038 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00039 */ 00040 00041 #ifndef __Dashel_H 00042 #define __Dashel_H 00043 00044 #include <string> 00045 #include <set> 00046 #include <map> 00047 #include <vector> 00048 #include <deque> 00049 #include <stdexcept> 00050 00130 00131 namespace Dashel 00132 { 00133 class Stream; 00134 00136 #define DASHEL_VERSION "1.0.5" 00137 00138 #define DASHEL_VERSION_INT 10005 00139 00141 00144 class DashelException: public std::runtime_error 00145 { 00146 public: 00148 typedef enum { 00149 Unknown, 00150 SyncError, 00151 InvalidTarget, 00152 InvalidOperation, 00153 ConnectionLost, 00154 IOError, 00155 ConnectionFailed, 00156 EnumerationError, 00157 PreviousIncomingDataNotRead 00158 } Source; 00159 00161 Source source; 00163 int sysError; 00165 Stream *stream; 00166 00167 public: 00169 00174 DashelException(Source s, int se, const char *reason, Stream* stream = NULL); 00175 }; 00176 00178 00180 class SerialPortEnumerator 00181 { 00182 public: 00184 00190 static std::map<int, std::pair<std::string, std::string> > getPorts(); 00191 }; 00192 00194 class IPV4Address 00195 { 00196 public: 00197 unsigned address; 00198 unsigned short port; 00199 00200 public: 00202 IPV4Address(unsigned addr = 0, unsigned short prt = 0); 00203 00205 IPV4Address(const std::string& name, unsigned short port); 00206 00208 bool operator==(const IPV4Address& o) const; 00209 00211 bool operator<(const IPV4Address& o) const; 00212 00214 00217 std::string format(const bool resolveName = true) const; 00218 00220 std::string hostname() const; 00221 00223 //bool isValid() const; 00224 }; 00225 00227 class ParameterSet 00228 { 00229 private: 00230 std::map<std::string, std::string> values; 00231 std::vector<std::string> params; 00232 00233 public: 00235 void add(const char *line); 00236 00238 00243 void addParam(const char *param, const char *value = NULL, bool atStart = false); 00244 00246 bool isSet(const char *key) const; 00247 00249 template<typename T> T get(const char *key) const; 00250 00252 const std::string& get(const char *key) const; 00253 00255 std::string getString() const; 00256 00258 void erase(const char *key); 00259 }; 00260 00262 class Stream 00263 { 00264 private: 00266 bool failedFlag; 00268 std::string failReason; 00269 00270 protected: 00272 ParameterSet target; 00274 std::string protocolName; 00275 00276 protected: 00277 00278 friend class Hub; 00279 00281 Stream(const std::string& protocolName) : failedFlag(false), protocolName(protocolName) {} 00282 00284 virtual ~Stream() {} 00285 00286 public: 00288 00292 void fail(DashelException::Source s, int se, const char* reason); 00293 00295 00297 bool failed() const { return failedFlag; } 00298 00300 00302 const std::string &getFailReason() const { return failReason; } 00303 00305 const std::string &getProtocolName() const { return protocolName; } 00306 00308 00312 std::string getTargetName() const { return protocolName + ":" + target.getString(); } 00313 00315 00318 const std::string &getTargetParameter(const char *param) const { return target.get(param); } 00319 00321 00329 virtual void write(const void *data, const size_t size) = 0; 00330 00332 00335 template<typename T> void write(T v) 00336 { 00337 write(&v, sizeof(T)); 00338 } 00339 00341 00345 virtual void flush() = 0; 00346 00348 00355 virtual void read(void *data, size_t size) = 0; 00356 00358 00362 template<typename T> T read() 00363 { 00364 T v; 00365 read(&v, sizeof(T)); 00366 return v; 00367 } 00368 }; 00369 00371 00379 class PacketStream: virtual public Stream 00380 { 00381 public: 00383 PacketStream(const std::string& protocolName) : Stream(protocolName) { } 00384 00386 00389 virtual void send(const IPV4Address& dest) = 0; 00390 00392 00397 virtual void receive(IPV4Address& source) = 0; 00398 }; 00399 00405 class Hub 00406 { 00407 public: 00409 typedef std::set<Stream*> StreamsSet; 00410 00411 private: 00412 void *hTerminate; 00413 void *streamsLock; 00414 StreamsSet streams; 00415 00416 protected: 00417 StreamsSet dataStreams; 00418 00419 public: 00420 const bool resolveIncomingNames; 00421 00422 public: 00426 Hub(const bool resolveIncomingNames = true); 00427 00429 virtual ~Hub(); 00430 00441 Stream* connect(const std::string &target); 00442 00452 void closeStream(Stream* stream); 00453 00456 void run(); 00457 00465 bool step(const int timeout = 0); 00466 00468 void stop(); 00469 00473 void lock(); 00474 00478 void unlock(); 00479 00480 protected: 00481 00492 virtual void connectionCreated(Stream * /* stream */) { } 00493 00504 virtual void incomingData(Stream * /* stream */) { } 00505 00517 virtual void connectionClosed(Stream * /* stream */, bool /* abnormal */) { } 00518 }; 00519 00521 struct StreamTypeRegistry 00522 { 00524 typedef Stream* (*CreatorFunc)(const std::string& target, const Hub& hub); 00525 00527 StreamTypeRegistry(); 00528 00530 void reg(const std::string& proto, const CreatorFunc func); 00531 00533 Stream* create(const std::string& proto, const std::string& target, const Hub& hub) const; 00534 00536 std::string list() const; 00537 00538 protected: 00540 typedef std::map<std::string, CreatorFunc> CreatorMap; 00542 CreatorMap creators; 00543 }; 00544 00546 template<typename C> 00547 Stream* createInstance(const std::string& target, const Hub& hub) 00548 { 00549 return new C(target); 00550 } 00551 00553 template<typename C> 00554 Stream* createInstanceWithHub(const std::string& target, const Hub& hub) 00555 { 00556 return new C(target, hub); 00557 } 00558 00560 extern StreamTypeRegistry streamTypeRegistry; 00561 } 00562 00563 #endif