dashel-common.cpp
Go to the documentation of this file.
00001 /*
00002         Dashel
00003         A cross-platform DAta Stream Helper Encapsulation Library
00004         Copyright (C) 2007 -- 2012:
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 #include "dashel.h"
00042 #include "dashel-private.h"
00043 #include <algorithm>
00044 
00045 #include <ostream>
00046 #include <sstream>
00047 #ifndef WIN32
00048         #include <netdb.h>
00049         #include <sys/socket.h>
00050         #include <arpa/inet.h>
00051 #else
00052         #include <winsock2.h>
00053 #endif
00054 
00059 namespace Dashel
00060 {
00061         using namespace std;
00062         
00063         // frome dashe-private.h
00064         ExpandableBuffer::ExpandableBuffer(size_t size) :
00065                 _data((unsigned char*)malloc(size)),
00066                 _size(size),
00067                 _pos(0)
00068         {
00069         }
00070         
00071         ExpandableBuffer::~ExpandableBuffer()
00072         {
00073                 free(_data);
00074         }
00075         
00076         void ExpandableBuffer::clear()
00077         {
00078                 _pos = 0;
00079         }
00080         
00081         void ExpandableBuffer::add(const void* data, const size_t size)
00082         {
00083                 if (_pos + size > _size)
00084                 {
00085                         _size = max(_size * 2, _size + size);
00086                         _data = (unsigned char*)realloc(_data, _size);
00087                 }
00088                 memcpy(_data + _pos, (unsigned char *)data, size);
00089                 _pos += size;
00090         }
00091         
00092         // frome dashel.h
00093         DashelException::DashelException(Source s, int se, const char *reason, Stream* stream) :
00094                 std::runtime_error(reason),
00095                 source(s),
00096                 sysError(se),
00097                 stream(stream)
00098         {
00099         
00100         }
00101         
00102         IPV4Address::IPV4Address(unsigned addr, unsigned short prt)
00103         {
00104                 address = addr;
00105                 port = prt;
00106         }
00107         
00108         IPV4Address::IPV4Address(const std::string& name, unsigned short port) :
00109                 port(port)
00110         {
00111                 hostent *he = gethostbyname(name.c_str());
00112                 
00113                 if (he == NULL)
00114                 {
00115                         #ifndef WIN32
00116                         struct in_addr addr;
00117                         if (inet_aton(name.c_str(), &addr))
00118                         {
00119                                 address = ntohl(addr.s_addr);
00120                         }
00121                         else
00122                         {
00123                                 address = INADDR_ANY;
00124                         }
00125                         #else // WIN32
00126                         unsigned long addr = inet_addr(name.c_str());
00127                         if(addr != INADDR_NONE)
00128                                 address = addr;
00129                         else
00130                                 address = INADDR_ANY;
00131                         #endif // WIN32
00132                 }
00133                 else
00134                 {
00135                         #ifndef WIN32
00136                         address = ntohl(*((unsigned *)he->h_addr));
00137                         #else
00138                         address = ntohl(*((unsigned *)he->h_addr));
00139                         #endif
00140                 }
00141         }
00142         
00143         bool IPV4Address::operator==(const IPV4Address& o) const
00144         {
00145                 return address==o.address && port==o.port;
00146         }
00147         
00148         bool IPV4Address::operator<(const IPV4Address& o) const
00149         {
00150                 return address<o.address || (address==o.address && port<o.port);
00151         }
00152         
00153         std::string IPV4Address::hostname() const
00154         {
00155                 unsigned a2 = htonl(address);
00156                 struct hostent *he = gethostbyaddr((const char *)&a2, 4, AF_INET);
00157                 
00158                 if (he == NULL)
00159                 {
00160                         struct in_addr addr;
00161                         addr.s_addr = a2;
00162                         return std::string(inet_ntoa(addr));
00163                 }
00164                 else
00165                 {
00166                         return std::string(he->h_name);
00167                 }
00168         }
00169         
00170         std::string IPV4Address::format(const bool resolveName) const
00171         {
00172                 std::ostringstream buf;
00173                 unsigned a2 = htonl(address);
00174                 
00175                 if (resolveName)
00176                 {
00177                         struct hostent *he = gethostbyaddr((const char *)&a2, 4, AF_INET);
00178                         if (he != NULL)
00179                         {
00180                                 buf << "tcp:host=" << he->h_name << ";port=" << port;
00181                                 return buf.str();
00182                         }
00183                 }
00184                 
00185                 struct in_addr addr;
00186                 addr.s_addr = a2;
00187                 buf << "tcp:host=" << inet_ntoa(addr) << ";port=" << port;
00188                 return buf.str();
00189         }
00190         
00191         void ParameterSet::add(const char *line)
00192         {
00193                 char *lc = strdup(line);
00194                 int spc = 0;
00195                 char *param;
00196                 bool storeParams = (params.size() == 0);
00197                 char *protocolName = strtok(lc, ":");
00198                 
00199                 // Do nothing with this.
00200                 assert(protocolName);
00201                 
00202                 while((param = strtok(NULL, ";")) != NULL)
00203                 {
00204                         char *sep = strchr(param, '=');
00205                         if(sep)
00206                         {
00207                                 *sep++ = 0;
00208                                 values[param] = sep;
00209                                 if (storeParams)
00210                                         params.push_back(param);
00211                         }
00212                         else
00213                         {
00214                                 if (storeParams)
00215                                         params.push_back(param);
00216                                 values[params[spc]] = param;
00217                         }
00218                         ++spc;
00219                 }
00220                 
00221                 free(lc);
00222         }
00223         
00224         void ParameterSet::addParam(const char *param, const char *value, bool atStart)
00225         {
00226                 if (atStart)
00227                         params.insert(params.begin(), 1, param);
00228                 else
00229                         params.push_back(param);
00230                 
00231                 if (value)
00232                         values[param] = value;
00233         }
00234         
00235         bool ParameterSet::isSet(const char *key) const
00236         {
00237                 return (values.find(key) != values.end());
00238         }
00239 
00240         const std::string& ParameterSet::get(const char *key) const
00241         {
00242                 std::map<std::string, std::string>::const_iterator it = values.find(key);
00243                 if(it == values.end())
00244                 {
00245                         std::string r = std::string("Parameter missing: ").append(key);
00246                         throw DashelException(DashelException::InvalidTarget, 0, r.c_str());
00247                 }
00248                 return it->second;
00249         }
00250         
00251         std::string ParameterSet::getString() const
00252         {
00253                 std::ostringstream oss;
00254                 std::vector<std::string>::const_iterator i = params.begin();
00255                 while (i != params.end())
00256                 {
00257                         oss << *i << "=" << values.find(*i)->second;
00258                         if (++i == params.end())
00259                                 break;
00260                         oss << ";";
00261                 }
00262                 return oss.str();
00263         }
00264         
00265         void ParameterSet::erase(const char *key)
00266         {
00267                 std::vector<std::string>::iterator i = std::find(params.begin(), params.end(), key);
00268                 if (i != params.end())
00269                         params.erase(i);
00270                 
00271                 std::map<std::string, std::string>::iterator j = values.find(key);
00272                 if (j != values.end())
00273                         values.erase(j);
00274         }
00275         
00276         
00277         void MemoryPacketStream::write(const void *data, const size_t size)
00278         {
00279                 sendBuffer.add(data, size);
00280         }
00281         
00282         void MemoryPacketStream::read(void *data, size_t size)
00283         {
00284                 if (size > receptionBuffer.size())
00285                         fail(DashelException::IOError, 0, "Attempt to read past available data");
00286                 
00287                 unsigned char* ptr = (unsigned char*)data;
00288                 std::copy(receptionBuffer.begin(), receptionBuffer.begin() + size, ptr);
00289                 receptionBuffer.erase(receptionBuffer.begin(), receptionBuffer.begin() + size);
00290         }
00291         
00292         void Hub::closeStream(Stream* stream)
00293         {
00294                 streams.erase(stream);
00295                 dataStreams.erase(stream);
00296                 delete stream;
00297         }
00298         
00299         void StreamTypeRegistry::reg(const std::string& proto, const CreatorFunc func)
00300         {
00301                 creators[proto] = func;
00302         }
00303         
00304         Stream* StreamTypeRegistry::create(const std::string& proto, const std::string& target, const Hub& hub) const
00305         {
00306                 typedef CreatorMap::const_iterator ConstIt;
00307                 ConstIt it(creators.find(proto));
00308                 if (it == creators.end())
00309                         return 0;
00310                 const CreatorFunc& creatorFunc(it->second);
00311                 return creatorFunc(target, hub);
00312         }
00313         
00314         std::string StreamTypeRegistry::list() const
00315         {
00316                 std::string s;
00317                 for (CreatorMap::const_iterator it = creators.begin(); it != creators.end();)
00318                 {
00319                         s += it->first;
00320                         ++it;
00321                         if (it != creators.end())
00322                                 s += ", ";
00323                 }
00324                 return s;
00325         }
00326 }
00327 


dashel
Author(s): Stéphane Magnenat
autogenerated on Thu Jan 2 2014 11:17:11