diff --git a/CMakeLists.txt b/CMakeLists.txt index e97a0e8a..49916a08 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -18,9 +18,10 @@ SET(CPACK_RESOURCE_FILE_README "${PROJECT_SOURCE_DIR}/README") set(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/CMakeModules;${CMAKE_MODULE_PATH}") option(SIMGEAR_SHARED "Set to ON to build SimGear as a shared library/framework" OFF) -option(SIMGEAR_HEADLESS "Set to ON to build SimGear with GUI/graphics support" OFF) +option(SIMGEAR_HEADLESS "Set to ON to build SimGear without GUI/graphics support" OFF) option(JPEG_FACTORY "Enable JPEG-factory support" OFF) option(ENABLE_LIBSVN "Set to ON to build SimGear with libsvnclient support" ON) +option(ENABLE_RTI "Set to ON to build SimGear with RTI support" OFF) set(MSVC_3RDPARTY_ROOT NOT_FOUND CACHE PATH "Location where the third-party dependencies are extracted") @@ -53,7 +54,7 @@ set (BOOST_CXX_FLAGS "-DBOOST_MULTI_INDEX_DISABLE_SERIALIZATION -DBOOST_BIMAP_DI find_package(ZLIB REQUIRED) find_package(Threads REQUIRED) -if (${SIMGEAR_HEADLESS}) +if(SIMGEAR_HEADLESS) message(STATUS "headlesss mode") set(NO_OPENSCENEGRAPH_INTERFACE 1) else() @@ -61,13 +62,13 @@ else() find_package(OpenAL REQUIRED) find_package(ALUT REQUIRED) find_package(OpenSceneGraph 2.8.1 REQUIRED osgText osgSim osgDB osgParticle osgUtil) -endif() +endif(SIMGEAR_HEADLESS) if(JPEG_FACTORY) message(STATUS "JPEG-factory enabled") find_package(JPEG REQUIRED) include_directories(${JPEG_INCLUDE_DIR}) -endif() +endif(JPEG_FACTORY) if(ENABLE_LIBSVN) find_package(SvnClient) @@ -86,8 +87,10 @@ check_include_file(sys/timeb.h HAVE_SYS_TIMEB_H) check_include_file(unistd.h HAVE_UNISTD_H) check_include_file(windows.h HAVE_WINDOWS_H) +if(ENABLE_RTI) # See if we have any rti library variant installed find_package(RTI) +endif(ENABLE_RTI) check_function_exists(gettimeofday HAVE_GETTIMEOFDAY) check_function_exists(ftime HAVE_FTIME) diff --git a/simgear/io/HTTPClient.cxx b/simgear/io/HTTPClient.cxx index 96ef25bd..fb1b812f 100644 --- a/simgear/io/HTTPClient.cxx +++ b/simgear/io/HTTPClient.cxx @@ -100,7 +100,7 @@ public: } activeRequest = r; - state = STATE_IDLE; + state = STATE_SENT_REQUEST; bodyTransferSize = -1; chunkedTransfer = false; setTerminator("\r\n"); @@ -146,7 +146,7 @@ public: virtual void foundTerminator(void) { switch (state) { - case STATE_IDLE: + case STATE_SENT_REQUEST: activeRequest->responseStart(buffer); state = STATE_GETTING_HEADERS; buffer.clear(); @@ -170,6 +170,7 @@ public: state = STATE_GETTING_CHUNKED; break; + case STATE_GETTING_TRAILER: processTrailer(); buffer.clear(); @@ -354,6 +355,7 @@ private: enum ConnectionState { STATE_IDLE = 0, + STATE_SENT_REQUEST, STATE_GETTING_HEADERS, STATE_GETTING_BODY, STATE_GETTING_CHUNKED, diff --git a/simgear/io/raw_socket.cxx b/simgear/io/raw_socket.cxx index 63c9b55e..aaa7d871 100644 --- a/simgear/io/raw_socket.cxx +++ b/simgear/io/raw_socket.cxx @@ -25,8 +25,7 @@ #endif #include - -#include "sg_socket.hxx" +#include "raw_socket.hxx" #if defined(_WIN32) && !defined(__CYGWIN__) # define WINSOCK // use winsock convetions, otherwise standard POSIX @@ -37,9 +36,11 @@ #include #include #include // for snprintf +#include #if defined(WINSOCK) -# include +# include +# include # include #else # include @@ -67,44 +68,73 @@ IPAddress::IPAddress ( const char* host, int port ) set ( host, port ) ; } +IPAddress::IPAddress( const IPAddress& other ) : + addr(NULL) +{ + if (other.addr) { + addr = (struct sockaddr_in*) malloc(sizeof(struct sockaddr_in)); + memcpy(addr, other.addr, sizeof(struct sockaddr_in)); + } +} + +const IPAddress& IPAddress::operator=(const IPAddress& other) +{ + if (addr) { + free(addr); + addr = NULL; + } + + if (other.addr) { + addr = (struct sockaddr_in*) malloc(sizeof(struct sockaddr_in)); + memcpy(addr, other.addr, sizeof(struct sockaddr_in)); + } + + return *this; +} void IPAddress::set ( const char* host, int port ) { - memset(this, 0, sizeof(IPAddress)); + addr = (struct sockaddr_in*) malloc(sizeof(struct sockaddr_in)); + memset(addr, 0, sizeof(struct sockaddr_in)); - sin_family = AF_INET ; - sin_port = htons (port); + addr->sin_family = AF_INET ; + addr->sin_port = htons (port); /* Convert a string specifying a host name or one of a few symbolic - ** names to a numeric IP address. This usually calls gethostbyname() + ** names to a numeric IP address. This usually calls getaddrinfo() ** to do the work; the names "" and "" are special. */ if (!host || host[0] == '\0') { - sin_addr = INADDR_ANY; + addr->sin_addr.s_addr = INADDR_ANY; return; } if (strcmp(host, "") == 0) { - sin_addr = INADDR_BROADCAST; + addr->sin_addr.s_addr = INADDR_BROADCAST; return; } - sin_addr = inet_addr ( host ) ; - if (sin_addr != INADDR_NONE) { - return; + struct addrinfo* result = NULL; + int err = getaddrinfo(host, NULL, NULL /* no hints */, &result); + if (err) { + SG_LOG(SG_IO, SG_WARN, "getaddrinfo failed for '" << host << "' : " << gai_strerror(err)); + } else if (result->ai_addrlen != getAddrLen()) { + SG_LOG(SG_IO, SG_ALERT, "mismatch in socket address sizes"); + } else { + memcpy(addr, result->ai_addr, result->ai_addrlen); } -// finally, try gethostbyname - struct hostent *hp = gethostbyname ( host ) ; - if (!hp) { - SG_LOG(SG_IO, SG_WARN, "gethostbyname failed for " << host); - sin_addr = INADDR_ANY ; - return; - } - - memcpy ( (char *) &sin_addr, hp->h_addr, hp->h_length ) ; + + freeaddrinfo(result); + addr->sin_port = htons (port); // fix up port after getaddrinfo } +IPAddress::~IPAddress() +{ + if (addr) { + free (addr); + } +} /* Create a string object representing an IP address. This is always a string of the form 'dd.dd.dd.dd' (with variable @@ -112,31 +142,27 @@ void IPAddress::set ( const char* host, int port ) const char* IPAddress::getHost () const { -#if 0 - const char* buf = inet_ntoa ( sin_addr ) ; -#else static char buf [32]; - long x = ntohl(sin_addr); + long x = ntohl(addr->sin_addr.s_addr); sprintf(buf, "%d.%d.%d.%d", (int) (x>>24) & 0xff, (int) (x>>16) & 0xff, (int) (x>> 8) & 0xff, (int) (x>> 0) & 0xff ); -#endif return buf; } unsigned int IPAddress::getIP () const { - return sin_addr; + return addr->sin_addr.s_addr; } unsigned int IPAddress::getPort() const { - return ntohs(sin_port); + return ntohs(addr->sin_port); } unsigned int IPAddress::getFamily () const { - return sin_family; + return addr->sin_family; } const char* IPAddress::getLocalHost () @@ -163,9 +189,18 @@ const char* IPAddress::getLocalHost () bool IPAddress::getBroadcast () const { - return sin_addr == INADDR_BROADCAST; + return (addr->sin_addr.s_addr == INADDR_BROADCAST); } +unsigned int IPAddress::getAddrLen() const +{ + return sizeof(struct sockaddr_in); +} + +struct sockaddr* IPAddress::getAddr() const +{ + return (struct sockaddr*) addr; +} Socket::Socket () { @@ -262,8 +297,8 @@ int Socket::bind ( const char* host, int port ) IPAddress addr ( host, port ) ; #if !defined(WINSOCK) - if( (result = ::bind(handle,(const sockaddr*)&addr,sizeof(IPAddress))) < 0 ) { - SG_LOG(SG_IO, SG_ALERT, "bind(" << host << ":" << port << ") failed. Errno " << errno << " (" << strerror(errno) << ")"); + if( (result = ::bind(handle, addr.getAddr(), addr.getAddrLen() ) ) < 0 ) { + SG_LOG(SG_IO, SG_ALERT, "bind(" << addr.getHost() << ":" << addr.getPort() << ") failed. Errno " << errno << " (" << strerror(errno) << ")"); return result; } #endif @@ -294,7 +329,7 @@ int Socket::bind ( const char* host, int port ) } } #if defined(WINSOCK) - else if( (result = ::bind(handle,(const sockaddr*)&addr,sizeof(IPAddress))) < 0 ) { + else if( (result = ::bind(handle,addr.getAddr(), addr.getAddrLen())) < 0 ) { SG_LOG(SG_IO, SG_ALERT, "bind(" << host << ":" << port << ") failed. Errno " << errno << " (" << strerror(errno) << ")"); return result; } @@ -321,20 +356,26 @@ int Socket::accept ( IPAddress* addr ) } else { - socklen_t addr_len = (socklen_t) sizeof(IPAddress) ; - return ::accept(handle,(sockaddr*)addr,&addr_len); + socklen_t addr_len = addr->getAddrLen(); ; + return ::accept(handle, addr->getAddr(), &addr_len); } } int Socket::connect ( const char* host, int port ) { - assert ( handle != -1 ) ; IPAddress addr ( host, port ) ; - if ( addr.getBroadcast() ) { + return connect ( &addr ); +} + + +int Socket::connect ( IPAddress* addr ) +{ + assert ( handle != -1 ) ; + if ( addr->getBroadcast() ) { setBroadcast( true ); } - return ::connect(handle,(const sockaddr*)&addr,sizeof(IPAddress)); + return ::connect(handle, addr->getAddr(), addr->getAddrLen() ); } @@ -350,7 +391,7 @@ int Socket::sendto ( const void * buffer, int size, { assert ( handle != -1 ) ; return ::sendto(handle,(const char*)buffer,size,flags, - (const sockaddr*)to,sizeof(IPAddress)); + (const sockaddr*) to->getAddr(), to->getAddrLen()); } @@ -365,8 +406,8 @@ int Socket::recvfrom ( void * buffer, int size, int flags, IPAddress* from ) { assert ( handle != -1 ) ; - socklen_t fromlen = (socklen_t) sizeof(IPAddress) ; - return ::recvfrom(handle,(char*)buffer,size,flags,(sockaddr*)from,&fromlen); + socklen_t fromlen = (socklen_t) from->getAddrLen() ; + return ::recvfrom(handle,(char*)buffer,size,flags, from->getAddr(),&fromlen); } @@ -526,8 +567,6 @@ static void netExit ( void ) int Socket::initSockets() { - assert ( sizeof(sockaddr_in) == sizeof(IPAddress) ) ; - #if defined(WINSOCK) /* Start up the windows networking */ WORD version_wanted = MAKEWORD(1,1); diff --git a/simgear/io/raw_socket.hxx b/simgear/io/raw_socket.hxx index 4eb30448..2b5031f3 100644 --- a/simgear/io/raw_socket.hxx +++ b/simgear/io/raw_socket.hxx @@ -23,12 +23,15 @@ #ifndef SG_IO_SOCKET_HXX #define SG_IO_SOCKET_HXX -#include +//#include -#if defined(__APPLE__) || defined(__FreeBSD__) -# include -#endif +//#if defined(__APPLE__) || defined(__FreeBSD__) +//# include +//#endif +struct sockaddr_in; +struct sockaddr; + namespace simgear { @@ -37,23 +40,14 @@ namespace simgear */ class IPAddress { - /* DANGER!!! This MUST match 'struct sockaddr_in' exactly! */ -#if defined(__APPLE__) || defined(__FreeBSD__) - __uint8_t sin_len; - __uint8_t sin_family; - in_port_t sin_port; - in_addr_t sin_addr; - char sin_zero[8]; -#else - short sin_family ; - unsigned short sin_port ; - unsigned int sin_addr ; - char sin_zero [ 8 ] ; -#endif - + struct sockaddr_in* addr; public: - IPAddress () {} + IPAddress () : addr(0) {} IPAddress ( const char* host, int port ) ; + ~IPAddress(); + + IPAddress( const IPAddress& other ); + const IPAddress& operator=(const IPAddress& other); void set ( const char* host, int port ) ; const char* getHost () const ; @@ -63,6 +57,9 @@ public: static const char* getLocalHost () ; bool getBroadcast () const ; + + unsigned int getAddrLen() const; + sockaddr* getAddr() const; }; @@ -89,6 +86,7 @@ public: int listen ( int backlog ) ; int accept ( IPAddress* addr ) ; int connect ( const char* host, int port ) ; + int connect ( IPAddress* addr ) ; int send ( const void * buffer, int size, int flags = 0 ) ; int sendto ( const void * buffer, int size, int flags, const IPAddress* to ) ; int recv ( void * buffer, int size, int flags = 0 ) ; diff --git a/simgear/io/sg_netChannel.cxx b/simgear/io/sg_netChannel.cxx index c6502565..c3644b6c 100644 --- a/simgear/io/sg_netChannel.cxx +++ b/simgear/io/sg_netChannel.cxx @@ -34,6 +34,7 @@ #include #include #include +#include #include diff --git a/simgear/props/condition.cxx b/simgear/props/condition.cxx index 85c539cf..d60cb440 100644 --- a/simgear/props/condition.cxx +++ b/simgear/props/condition.cxx @@ -126,21 +126,27 @@ public: const char * propname ); virtual void setRightProperty( SGPropertyNode *prop_root, const char * propname ); + virtual void setPrecisionProperty( SGPropertyNode *prop_root, + const char * propname ); // will make a local copy virtual void setLeftValue (const SGPropertyNode * value); virtual void setRightValue (const SGPropertyNode * value); + virtual void setPrecisionValue (const SGPropertyNode * value); void setLeftDExpression(SGExpressiond* dexp); void setRightDExpression(SGExpressiond* dexp); + void setPrecisionDExpression(SGExpressiond* dexp); private: Type _type; bool _reverse; SGPropertyNode_ptr _left_property; SGPropertyNode_ptr _right_property; + SGPropertyNode_ptr _precision_property; SGSharedPtr _left_dexp; SGSharedPtr _right_dexp; + SGSharedPtr _precision_dexp; }; @@ -261,8 +267,20 @@ SGOrCondition::addCondition (SGCondition * condition) // Implementation of SGComparisonCondition. //////////////////////////////////////////////////////////////////////// +template +static int doComp( T v1, T v2, T e ) +{ + T d = v1 - v2; + if( d < -e ) + return SGComparisonCondition::LESS_THAN; + else if( d > e ) + return SGComparisonCondition::GREATER_THAN; + else + return SGComparisonCondition::EQUALS; +} + static int -doComparison (const SGPropertyNode * left, const SGPropertyNode *right) +doComparison (const SGPropertyNode * left, const SGPropertyNode * right, const SGPropertyNode * precision ) { using namespace simgear; switch (left->getType()) { @@ -277,55 +295,28 @@ doComparison (const SGPropertyNode * left, const SGPropertyNode *right) return SGComparisonCondition::EQUALS; break; } - case props::INT: { - int v1 = left->getIntValue(); - int v2 = right->getIntValue(); - if (v1 < v2) - return SGComparisonCondition::LESS_THAN; - else if (v1 > v2) - return SGComparisonCondition::GREATER_THAN; - else - return SGComparisonCondition::EQUALS; - break; - } - case props::LONG: { - long v1 = left->getLongValue(); - long v2 = right->getLongValue(); - if (v1 < v2) - return SGComparisonCondition::LESS_THAN; - else if (v1 > v2) - return SGComparisonCondition::GREATER_THAN; - else - return SGComparisonCondition::EQUALS; - break; - } - case props::FLOAT: { - float v1 = left->getFloatValue(); - float v2 = right->getFloatValue(); - if (v1 < v2) - return SGComparisonCondition::LESS_THAN; - else if (v1 > v2) - return SGComparisonCondition::GREATER_THAN; - else - return SGComparisonCondition::EQUALS; - break; - } - case props::DOUBLE: { - double v1 = left->getDoubleValue(); - double v2 = right->getDoubleValue(); - if (v1 < v2) - return SGComparisonCondition::LESS_THAN; - else if (v1 > v2) - return SGComparisonCondition::GREATER_THAN; - else - return SGComparisonCondition::EQUALS; - break; - } + case props::INT: + return doComp(left->getIntValue(), right->getIntValue(), + precision ? abs(precision->getIntValue()/2) : 0 ); + + case props::LONG: + return doComp(left->getLongValue(), right->getLongValue(), + precision ? abs(precision->getLongValue()/2L) : 0L ); + + case props::FLOAT: + return doComp(left->getFloatValue(), right->getFloatValue(), + precision ? fabs(precision->getFloatValue()/2.0f) : 0.0f ); + + case props::DOUBLE: + return doComp(left->getDoubleValue(), right->getDoubleValue(), + precision ? fabs(precision->getDoubleValue()/2.0) : 0.0 ); + case props::STRING: case props::NONE: case props::UNSPECIFIED: { - string v1 = left->getStringValue(); - string v2 = right->getStringValue(); + size_t l = precision ? precision->getLongValue() : string::npos; + string v1 = string(left->getStringValue()).substr(0,l); + string v2 = string(right->getStringValue()).substr(0,l); if (v1 < v2) return SGComparisonCondition::LESS_THAN; else if (v1 > v2) @@ -367,8 +358,12 @@ SGComparisonCondition::test () const if (_right_dexp) { _right_property->setDoubleValue(_right_dexp->getValue(NULL)); } + + if (_precision_dexp) { + _precision_property->setDoubleValue(_precision_dexp->getValue(NULL)); + } - int cmp = doComparison(_left_property, _right_property); + int cmp = doComparison(_left_property, _right_property, _precision_property ); if (!_reverse) return (cmp == _type); else @@ -389,12 +384,24 @@ SGComparisonCondition::setRightProperty( SGPropertyNode *prop_root, _right_property = prop_root->getNode(propname, true); } +void +SGComparisonCondition::setPrecisionProperty( SGPropertyNode *prop_root, + const char * propname ) +{ + _precision_property = prop_root->getNode(propname, true); +} + void SGComparisonCondition::setLeftValue (const SGPropertyNode *node) { _left_property = new SGPropertyNode(*node); } +void +SGComparisonCondition::setPrecisionValue (const SGPropertyNode *node) +{ + _precision_property = new SGPropertyNode(*node); +} void SGComparisonCondition::setRightValue (const SGPropertyNode *node) @@ -414,6 +421,13 @@ SGComparisonCondition::setRightDExpression(SGExpressiond* dexp) { _right_property = new SGPropertyNode(); _right_dexp = dexp; +} + +void +SGComparisonCondition::setPrecisionDExpression(SGExpressiond* dexp) +{ + _precision_property = new SGPropertyNode(); + _precision_dexp = dexp; } //////////////////////////////////////////////////////////////////////// // Read a condition and use it if necessary. @@ -479,34 +493,54 @@ readComparison( SGPropertyNode *prop_root, bool reverse) { SGComparisonCondition * condition = new SGComparisonCondition(type, reverse); - if (node->nChildren() != 2) { - throw sg_exception("condition: comparison without two children"); + if (node->nChildren() < 2 || node->nChildren() > 3 ) { + throw sg_exception("condition: comparison without two or three children"); } const SGPropertyNode* left = node->getChild(0), *right = node->getChild(1); - string leftName(left->getName()); - if (leftName == "property") { - condition->setLeftProperty(prop_root, left->getStringValue()); - } else if (leftName == "value") { - condition->setLeftValue(left); - } else if (leftName == "expression") { - SGExpressiond* exp = SGReadDoubleExpression(prop_root, left->getChild(0)); - condition->setLeftDExpression(exp); - } else { - throw sg_exception("Unknown condition comparison left child:" + leftName); + + { + string leftName(left->getName()); + if (leftName == "property") { + condition->setLeftProperty(prop_root, left->getStringValue()); + } else if (leftName == "value") { + condition->setLeftValue(left); + } else if (leftName == "expression") { + SGExpressiond* exp = SGReadDoubleExpression(prop_root, left->getChild(0)); + condition->setLeftDExpression(exp); + } else { + throw sg_exception("Unknown condition comparison left child:" + leftName); + } } - string rightName(right->getName()); - if (rightName == "property") { - condition->setRightProperty(prop_root, right->getStringValue()); - } else if (rightName == "value") { - condition->setRightValue(right); - } else if (rightName == "expression") { - SGExpressiond* exp = SGReadDoubleExpression(prop_root, right->getChild(0)); - condition->setRightDExpression(exp); - } else { - throw sg_exception("Unknown condition comparison right child:" + rightName); + { + string rightName(right->getName()); + if (rightName == "property") { + condition->setRightProperty(prop_root, right->getStringValue()); + } else if (rightName == "value") { + condition->setRightValue(right); + } else if (rightName == "expression") { + SGExpressiond* exp = SGReadDoubleExpression(prop_root, right->getChild(0)); + condition->setRightDExpression(exp); + } else { + throw sg_exception("Unknown condition comparison right child:" + rightName); + } + } + + if( node->nChildren() == 3 ) { + const SGPropertyNode *n = node->getChild(2); + string name(n->getName()); + if (name == "precision-property") { + condition->setPrecisionProperty(prop_root, n->getStringValue()); + } else if (name == "precision-value") { + condition->setPrecisionValue(n); + } else if (name == "precision-expression") { + SGExpressiond* exp = SGReadDoubleExpression(prop_root, n->getChild(0)); + condition->setPrecisionDExpression(exp); + } else { + throw sg_exception("Unknown condition comparison precision child:" + name ); + } } return condition;