Compare commits

..

10 Commits

Author SHA1 Message Date
40718158ae fixbug 2026-03-22 17:18:19 +07:00
727233624e delete console_brigde 2026-02-06 10:12:02 +00:00
948405bba4 update for ROS 2026-01-07 16:56:28 +07:00
5f7ae1233d update if define 2026-01-05 18:55:26 +07:00
6a3dea8614 update hieplm 2026-01-05 18:14:29 +07:00
a93304418d update 2026-01-05 10:52:41 +07:00
bb14979b8a catkin_make 2025-12-31 15:34:02 +07:00
b64702260f fix 2025-12-29 18:20:31 +07:00
5575a50a32 hiep fix 2025-12-29 18:14:15 +07:00
5bdd606fff hiep sua file 2025-12-29 17:43:35 +07:00
32 changed files with 2190 additions and 1136 deletions

View File

@@ -1,15 +1,51 @@
cmake_minimum_required(VERSION 3.10) cmake_minimum_required(VERSION 3.0.2)
project(xmlrpcpp) project(robot_xmlrpcpp VERSION 1.0.0 LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 17) if(DEFINED CATKIN_DEVEL_PREFIX OR DEFINED CATKIN_TOPLEVEL)
set(CMAKE_CXX_STANDARD_REQUIRED ON) set(BUILDING_WITH_CATKIN TRUE)
set(CMAKE_POSITION_INDEPENDENT_CODE ON) message(STATUS "Building robot_xmlrpcpp with Catkin")
if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") else()
add_compile_options(-Wall -Wextra -Wpedantic -fPIC) set(BUILDING_WITH_CATKIN FALSE)
message(STATUS "Building robot_xmlrpcpp with Standalone CMake")
endif() endif()
add_library(xmlrpcpp # C++ Standard - must be set before find_package
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
if (NOT BUILDING_WITH_CATKIN)
# Enable Position Independent Code
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
# Cấu hình RPATH để tránh cycle trong runtime search path
set(CMAKE_BUILD_RPATH_USE_ORIGIN TRUE)
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
set(CMAKE_BUILD_RPATH "${CMAKE_BINARY_DIR}")
else()
# ========================================================
# Catkin specific configuration
# ========================================================
find_package(catkin REQUIRED)
catkin_package(
INCLUDE_DIRS include
LIBRARIES ${PROJECT_NAME}
)
include_directories(
include
${catkin_INCLUDE_DIRS}
)
endif()
# Libraries
add_library(${PROJECT_NAME} SHARED
src/XmlRpcClient.cpp src/XmlRpcClient.cpp
src/XmlRpcDispatch.cpp src/XmlRpcDispatch.cpp
src/XmlRpcServer.cpp src/XmlRpcServer.cpp
@@ -21,33 +57,87 @@ add_library(xmlrpcpp
src/XmlRpcValue.cpp src/XmlRpcValue.cpp
) )
target_include_directories(xmlrpcpp if(BUILDING_WITH_CATKIN)
add_dependencies(${PROJECT_NAME} ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
target_include_directories(${PROJECT_NAME}
PUBLIC PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include> $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:include/${PROJECT_NAME}> $<INSTALL_INTERFACE:include>
) )
# --- Cài đặt thư viện vào hệ thống khi chạy make install --- target_link_libraries(${PROJECT_NAME}
install(TARGETS xmlrpcpp PUBLIC ${catkin_LIBRARIES}
EXPORT xmlrpcpp-targets )
ARCHIVE DESTINATION lib # Thư viện tĩnh .a
LIBRARY DESTINATION lib # Thư viện động .so
RUNTIME DESTINATION bin # File thực thi (nếu có)
INCLUDES DESTINATION include # Cài đặt include
)
install( else()
DIRECTORY include/
DESTINATION include/
)
# --- Xuất export set xmlrpcpp-targets thành file CMake module --- target_include_directories(${PROJECT_NAME}
# --- Tạo file lib/cmake/xmlrpcpp/xmlrpcpp-targets.cmake --- PUBLIC
# --- File này chứa cấu hình giúp project khác có thể dùng --- $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
# --- Find_package(xmlrpcpp REQUIRED) --- $<INSTALL_INTERFACE:include>
# --- Target_link_libraries(my_app PRIVATE xmlrpcpp::xmlrpcpp) --- )
install(EXPORT xmlrpcpp-targets
FILE xmlrpcpp-targets.cmake # target_link_libraries(${PROJECT_NAME}
NAMESPACE xmlrpcpp::
DESTINATION lib/cmake/xmlrpcpp # )
)
set_target_properties(${PROJECT_NAME} PROPERTIES
LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}
BUILD_RPATH "${CMAKE_BINARY_DIR}"
INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib"
)
endif()
# Compiler flags
if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
target_compile_options(${PROJECT_NAME} PRIVATE -Wall -Wextra -Wpedantic -fPIC -Wno-unused-parameter)
endif()
if(BUILDING_WITH_CATKIN)
## Mark libraries for installation
## See http://docs.ros.org/melodic/api/catkin/html/howto/format1/building_libraries.html
install(TARGETS ${PROJECT_NAME}
ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
RUNTIME DESTINATION ${CATKIN_GLOBAL_BIN_DESTINATION}
)
## Mark cpp header files for installation
install(DIRECTORY include/${PROJECT_NAME}/
DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION}
FILES_MATCHING PATTERN "*.h"
PATTERN ".svn" EXCLUDE
)
else()
install(TARGETS ${PROJECT_NAME}
EXPORT ${PROJECT_NAME}-targets
ARCHIVE DESTINATION lib
LIBRARY DESTINATION lib
RUNTIME DESTINATION bin
)
# Export targets
install(EXPORT ${PROJECT_NAME}-targets
FILE ${PROJECT_NAME}-targets.cmake
NAMESPACE ${PROJECT_NAME}::
DESTINATION lib/cmake/${PROJECT_NAME}
)
## Mark cpp header files for installation
install(DIRECTORY include/${PROJECT_NAME}/
DESTINATION include
FILES_MATCHING PATTERN "*.h"
PATTERN ".svn" EXCLUDE
)
# Print configuration info
message(STATUS "=================================")
message(STATUS "Project: ${PROJECT_NAME}")
message(STATUS "Version: ${PROJECT_VERSION}")
message(STATUS "C++ Standard: ${CMAKE_CXX_STANDARD}")
message(STATUS "=================================")
endif()

View File

@@ -1,5 +1,5 @@
#ifndef _XMLRPC_H_ #ifndef _ROBOT_XMLRPC_H_
#define _XMLRPC_H_ #define _ROBOT_XMLRPC_H_
// //
// XmlRpc++ Copyright (c) 2002-2003 by Chris Morley // XmlRpc++ Copyright (c) 2002-2003 by Chris Morley
// This library is free software; you can redistribute it and/or // This library is free software; you can redistribute it and/or
@@ -32,7 +32,7 @@
#include "XmlRpcValue.h" #include "XmlRpcValue.h"
#include "XmlRpcUtil.h" #include "XmlRpcUtil.h"
namespace XmlRpc { namespace robot_xmlrpcpp {
//! An interface allowing custom handling of error message reporting. //! An interface allowing custom handling of error message reporting.
@@ -89,6 +89,6 @@ namespace XmlRpc {
//! Version identifier //! Version identifier
extern const char XMLRPC_VERSION[]; extern const char XMLRPC_VERSION[];
} // namespace XmlRpc } // namespace robot_xmlrpcpp
#endif // _XMLRPC_H_ #endif // _ROBOT_XMLRPC_H_

View File

@@ -1,6 +1,5 @@
#ifndef _ROBOT_XMLRPCCLIENT_H_
#ifndef _XMLRPCCLIENT_H_ #define _ROBOT_XMLRPCCLIENT_H_
#define _XMLRPCCLIENT_H_
// //
// XmlRpc++ Copyright (c) 2002-2003 by Chris Morley // XmlRpc++ Copyright (c) 2002-2003 by Chris Morley
// //
@@ -13,10 +12,10 @@
# include <string> # include <string>
#endif #endif
#include "xmlrpcpp/XmlRpcDispatch.h" #include "robot_xmlrpcpp/XmlRpcDispatch.h"
#include "xmlrpcpp/XmlRpcSource.h" #include "robot_xmlrpcpp/XmlRpcSource.h"
namespace XmlRpc { namespace robot_xmlrpcpp {
// Arguments and results are represented by XmlRpcValues // Arguments and results are represented by XmlRpcValues
class XmlRpcValue; class XmlRpcValue;
@@ -123,6 +122,6 @@ namespace XmlRpc {
}; // class XmlRpcClient }; // class XmlRpcClient
} // namespace XmlRpc } // namespace robot_xmlrpcpp
#endif // _XMLRPCCLIENT_H_ #endif // _ROBOT_XMLRPCCLIENT_H_

View File

@@ -1,7 +1,6 @@
#ifndef _ROBOT_XMLRPCDISPATCH_H_
#define _ROBOT_XMLRPCDISPATCH_H_
#ifndef _XMLRPCDISPATCH_H_
#define _XMLRPCDISPATCH_H_
//
// XmlRpc++ Copyright (c) 2002-2003 by Chris Morley // XmlRpc++ Copyright (c) 2002-2003 by Chris Morley
// //
#if defined(_MSC_VER) #if defined(_MSC_VER)
@@ -12,7 +11,7 @@
# include <list> # include <list>
#endif #endif
namespace XmlRpc { namespace robot_xmlrpcpp {
// An RPC source represents a file descriptor to monitor // An RPC source represents a file descriptor to monitor
class XmlRpcSource; class XmlRpcSource;
@@ -83,6 +82,6 @@ namespace XmlRpc {
bool _inWork; bool _inWork;
}; };
} // namespace XmlRpc } // namespace robot_xmlrpcpp
#endif // _XMLRPCDISPATCH_H_ #endif // _ROBOT_XMLRPCDISPATCH_H_

View File

@@ -1,7 +1,6 @@
#ifndef _ROBOT_XMLRPCEXCEPTION_H_
#define _ROBOT_XMLRPCEXCEPTION_H_
#ifndef _XMLRPCEXCEPTION_H_
#define _XMLRPCEXCEPTION_H_
//
// XmlRpc++ Copyright (c) 2002-2003 by Chris Morley // XmlRpc++ Copyright (c) 2002-2003 by Chris Morley
// //
#if defined(_MSC_VER) #if defined(_MSC_VER)
@@ -13,7 +12,7 @@
#endif #endif
namespace XmlRpc { namespace robot_xmlrpcpp {
//! A class representing an error. //! A class representing an error.
//! If server methods throw this exception, a fault response is returned //! If server methods throw this exception, a fault response is returned
@@ -37,6 +36,6 @@ namespace XmlRpc {
int _code; int _code;
}; };
} } // namespace robot_xmlrpcpp
#endif // _XMLRPCEXCEPTION_H_ #endif // _ROBOT_XMLRPCEXCEPTION_H_

View File

@@ -1,7 +1,6 @@
#ifndef _ROBOT_XMLRPCSERVER_H_
#define _ROBOT_XMLRPCSERVER_H_
#ifndef _XMLRPCSERVER_H_
#define _XMLRPCSERVER_H_
//
// XmlRpc++ Copyright (c) 2002-2003 by Chris Morley // XmlRpc++ Copyright (c) 2002-2003 by Chris Morley
// //
#if defined(_MSC_VER) #if defined(_MSC_VER)
@@ -13,10 +12,10 @@
# include <string> # include <string>
#endif #endif
#include "xmlrpcpp/XmlRpcDispatch.h" #include "robot_xmlrpcpp/XmlRpcDispatch.h"
#include "xmlrpcpp/XmlRpcSource.h" #include "robot_xmlrpcpp/XmlRpcSource.h"
namespace XmlRpc { namespace robot_xmlrpcpp {
// An abstract class supporting XML RPC methods // An abstract class supporting XML RPC methods
@@ -99,6 +98,6 @@ namespace XmlRpc {
XmlRpcServerMethod* _methodHelp; XmlRpcServerMethod* _methodHelp;
}; };
} // namespace XmlRpc } // namespace robot_xmlrpcpp
#endif //_XMLRPCSERVER_H_ #endif //_ROBOT_XMLRPCSERVER_H_

View File

@@ -1,5 +1,5 @@
#ifndef _XMLRPCSERVERCONNECTION_H_ #ifndef _ROBOT_XMLRPCSERVERCONNECTION_H_
#define _XMLRPCSERVERCONNECTION_H_ #define _ROBOT_XMLRPCSERVERCONNECTION_H_
// //
// XmlRpc++ Copyright (c) 2002-2003 by Chris Morley // XmlRpc++ Copyright (c) 2002-2003 by Chris Morley
// //
@@ -11,10 +11,10 @@
# include <string> # include <string>
#endif #endif
#include "xmlrpcpp/XmlRpcValue.h" #include "robot_xmlrpcpp/XmlRpcValue.h"
#include "xmlrpcpp/XmlRpcSource.h" #include "robot_xmlrpcpp/XmlRpcSource.h"
namespace XmlRpc { namespace robot_xmlrpcpp {
// The server waits for client connections and provides methods // The server waits for client connections and provides methods
@@ -97,6 +97,6 @@ namespace XmlRpc {
// Whether to keep the current client connection open for further requests // Whether to keep the current client connection open for further requests
bool _keepAlive; bool _keepAlive;
}; };
} // namespace XmlRpc } // namespace robot_xmlrpcpp
#endif // _XMLRPCSERVERCONNECTION_H_ #endif // _ROBOT_XMLRPCSERVERCONNECTION_H_

View File

@@ -1,7 +1,6 @@
#ifndef _ROBOT_XMLRPCSERVERMETHOD_H_
#ifndef _XMLRPCSERVERMETHOD_H_
#define _XMLRPCSERVERMETHOD_H_ #define _XMLRPCSERVERMETHOD_H_
// #define _ROBOT_XMLRPCSERVERMETHOD_H_
// XmlRpc++ Copyright (c) 2002-2003 by Chris Morley // XmlRpc++ Copyright (c) 2002-2003 by Chris Morley
// //
#if defined(_MSC_VER) #if defined(_MSC_VER)
@@ -12,7 +11,7 @@
# include <string> # include <string>
#endif #endif
namespace XmlRpc { namespace robot_xmlrpcpp {
// Representation of a parameter or result value // Representation of a parameter or result value
class XmlRpcValue; class XmlRpcValue;
@@ -42,6 +41,6 @@ namespace XmlRpc {
std::string _name; std::string _name;
XmlRpcServer* _server; XmlRpcServer* _server;
}; };
} // namespace XmlRpc } // namespace robot_xmlrpcpp
#endif // _XMLRPCSERVERMETHOD_H_ #endif // _ROBOT_XMLRPCSERVERMETHOD_H_

View File

@@ -1,5 +1,5 @@
#ifndef _XMLRPCSOCKET_H_ #ifndef _ROBOT_XMLRPCSOCKET_H_
#define _XMLRPCSOCKET_H_ #define _ROBOT_XMLRPCSOCKET_H_
// //
// XmlRpc++ Copyright (c) 2002-2003 by Chris Morley // XmlRpc++ Copyright (c) 2002-2003 by Chris Morley
// //
@@ -11,7 +11,7 @@
# include <string> # include <string>
#endif #endif
namespace XmlRpc { namespace robot_xmlrpcpp {
//! A platform-independent socket API. //! A platform-independent socket API.
class XmlRpcSocket { class XmlRpcSocket {
@@ -64,6 +64,6 @@ namespace XmlRpc {
static std::string getErrorMsg(int error); static std::string getErrorMsg(int error);
}; };
} // namespace XmlRpc } // namespace robot_xmlrpcpp
#endif #endif // _ROBOT_XMLRPCSOCKET_H_

View File

@@ -1,6 +1,5 @@
#ifndef _ROBOT_XMLRPCSOURCE_H_
#ifndef _XMLRPCSOURCE_H_ #define _ROBOT_XMLRPCSOURCE_H_
#define _XMLRPCSOURCE_H_
// //
// XmlRpc++ Copyright (c) 2002-2003 by Chris Morley // XmlRpc++ Copyright (c) 2002-2003 by Chris Morley
// //
@@ -8,7 +7,7 @@
# pragma warning(disable:4786) // identifier was truncated in debug info # pragma warning(disable:4786) // identifier was truncated in debug info
#endif #endif
namespace XmlRpc { namespace robot_xmlrpcpp {
//! An RPC source represents a file descriptor to monitor //! An RPC source represents a file descriptor to monitor
class XmlRpcSource { class XmlRpcSource {
@@ -50,6 +49,6 @@ namespace XmlRpc {
// In the client, keep connections open if you intend to make multiple calls. // In the client, keep connections open if you intend to make multiple calls.
bool _keepOpen; bool _keepOpen;
}; };
} // namespace XmlRpc } // namespace robot_xmlrpcpp
#endif //_XMLRPCSOURCE_H_ #endif //_ROBOT_XMLRPCSOURCE_H_

View File

@@ -1,5 +1,5 @@
#ifndef _XMLRPCUTIL_H_ #ifndef _ROBOT_XMLRPCUTIL_H_
#define _XMLRPCUTIL_H_ #define _ROBOT_XMLRPCUTIL_H_
// //
// XmlRpc++ Copyright (c) 2002-2003 by Chris Morley // XmlRpc++ Copyright (c) 2002-2003 by Chris Morley
// //
@@ -21,7 +21,7 @@
# define strncasecmp strnicmp # define strncasecmp strnicmp
#endif #endif
namespace XmlRpc { namespace robot_xmlrpcpp {
//! Utilities for XML parsing, encoding, and decoding and message handlers. //! Utilities for XML parsing, encoding, and decoding and message handlers.
class XmlRpcUtil { class XmlRpcUtil {
@@ -56,6 +56,6 @@ namespace XmlRpc {
static void error(const char* fmt, ...); static void error(const char* fmt, ...);
}; };
} // namespace XmlRpc } // namespace robot_xmlrpcpp
#endif // _XMLRPCUTIL_H_ #endif // _XMLRPCUTIL_H_

View File

@@ -1,6 +1,5 @@
#ifndef _ROBOT_XMLRPCVALUE_H_
#ifndef _XMLRPCVALUE_H_ #define _ROBOT_XMLRPCVALUE_H_
#define _XMLRPCVALUE_H_
// //
// XmlRpc++ Copyright (c) 2002-2003 by Chris Morley // XmlRpc++ Copyright (c) 2002-2003 by Chris Morley
// //
@@ -15,7 +14,7 @@
# include <time.h> # include <time.h>
#endif #endif
namespace XmlRpc { namespace robot_xmlrpcpp {
//! RPC method arguments and results are represented by Values //! RPC method arguments and results are represented by Values
// should probably refcount them... // should probably refcount them...
@@ -113,6 +112,9 @@ namespace XmlRpc {
//! Check for the existence of a struct member by name. //! Check for the existence of a struct member by name.
bool hasMember(const std::string& name) const; bool hasMember(const std::string& name) const;
//! If this value is a struct, returns pointer to its members; otherwise nullptr.
const ValueStruct *getStructMembers() const;
//! Decode xml. Destroys any existing value. //! Decode xml. Destroys any existing value.
bool fromXml(std::string const& valueXml, int* offset); bool fromXml(std::string const& valueXml, int* offset);
@@ -180,10 +182,9 @@ namespace XmlRpc {
} _value; } _value;
}; };
} // namespace XmlRpc } // namespace robot_xmlrpcpp
std::ostream& operator<<(std::ostream& os, XmlRpc::XmlRpcValue& v); std::ostream& operator<<(std::ostream& os, robot_xmlrpcpp::XmlRpcValue& v);
#endif // _ROBOT_XMLRPCVALUE_H_
#endif // _XMLRPCVALUE_H_

View File

@@ -6,8 +6,8 @@
// //
// //
#if !defined(__BASE64_H_INCLUDED__) #if !defined(__ROBOT_BASE64_H_INCLUDED__)
#define __BASE64_H_INCLUDED__ 1 #define __ROBOT_BASE64_H_INCLUDED__ 1
#ifndef MAKEDEPEND #ifndef MAKEDEPEND
# include <iterator> # include <iterator>
@@ -51,7 +51,6 @@ public:
// you can fill end of line // you can fill end of line
// it may be crlf, crlfsp, noline or other class like it // it may be crlf, crlfsp, noline or other class like it
struct crlf struct crlf
{ {
template<class _OI> template<class _OI>
@@ -161,7 +160,7 @@ public:
{ {
_3to4.zero(); _3to4.zero();
// áåð¸ì ïî 3 ñèìâîëà // <EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> 3 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
_3to4.set_0(*_First); _3to4.set_0(*_First);
_First++; _First++;
@@ -194,7 +193,7 @@ public:
*_To = _Tr::to_char_type(_base64Chars[_3to4.b64_2()]); ++_To; *_To = _Tr::to_char_type(_base64Chars[_3to4.b64_2()]); ++_To;
*_To = _Tr::to_char_type(_base64Chars[_3to4.b64_3()]); ++_To; *_To = _Tr::to_char_type(_base64Chars[_3to4.b64_3()]); ++_To;
if(line_octets == 17) // base64 ïîçâîëÿåò äëèíó ñòðîêè íå áîëåå 72 ñèìâîëîâ if(line_octets == 17) // base64 <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD> 72 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
{ {
//_To = _Endl(_To); //_To = _Endl(_To);
*_To = '\n'; ++_To; *_To = '\n'; ++_To;

View File

@@ -1,9 +1,9 @@
<package> <package>
<name>xmlrpcpp</name> <name>robot_xmlrpcpp</name>
<version>0.7.10</version> <version>0.7.10</version>
<description> <description>
xmlrpcpp is the second generation of the transform library, which lets robot_xmlrpcpp is the second generation of the transform library, which lets
the user keep track of multiple coordinate frames over time. xmlrpcpp the user keep track of multiple coordinate frames over time. robot_xmlrpcpp
maintains the relationship between coordinate frames in a tree maintains the relationship between coordinate frames in a tree
structure buffered in time, and lets the user transform points, structure buffered in time, and lets the user transform points,
vectors, etc between any two coordinate frames at any desired vectors, etc between any two coordinate frames at any desired
@@ -15,12 +15,8 @@
<maintainer email="tfoote@osrfoundation.org">Tully Foote</maintainer> <maintainer email="tfoote@osrfoundation.org">Tully Foote</maintainer>
<license>BSD</license> <license>BSD</license>
<url type="website">http://www.ros.org/wiki/xmlrpcpp</url> <url type="website">http://www.ros.org/wiki/robot_xmlrpcpp</url>
<buildtool_depend version_gte="0.5.68">catkin</buildtool_depend> <buildtool_depend version_gte="0.5.68">catkin</buildtool_depend>
<build_depend>libconsole-bridge-dev</build_depend>
<run_depend>libconsole-bridge-dev</run_depend>
</package> </package>

View File

@@ -1,8 +1,8 @@
#include "xmlrpcpp/XmlRpcClient.h" #include "robot_xmlrpcpp/XmlRpcClient.h"
#include "xmlrpcpp/XmlRpcSocket.h" #include "robot_xmlrpcpp/XmlRpcSocket.h"
#include "xmlrpcpp/XmlRpc.h" #include "robot_xmlrpcpp/XmlRpc.h"
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@@ -11,7 +11,7 @@
using namespace XmlRpc; using namespace robot_xmlrpcpp;
// Static data // Static data
const char XmlRpcClient::REQUEST_BEGIN[] = const char XmlRpcClient::REQUEST_BEGIN[] =
@@ -252,7 +252,7 @@ XmlRpcClient::generateHeader(std::string const& body)
header += buff; header += buff;
header += "Content-Type: text/xml\r\nContent-length: "; header += "Content-Type: text/xml\r\nContent-length: ";
sprintf(buff,"%d\r\n\r\n", body.size()); sprintf(buff,"%d\r\n\r\n", (int)body.size());
return header + buff; return header + buff;
} }
@@ -397,7 +397,7 @@ XmlRpcClient::parseResponse(XmlRpcValue& result)
// Expect either <params><param>... or <fault>... // Expect either <params><param>... or <fault>...
if ((XmlRpcUtil::nextTagIs(PARAMS_TAG,_response,&offset) && if ((XmlRpcUtil::nextTagIs(PARAMS_TAG,_response,&offset) &&
XmlRpcUtil::nextTagIs(PARAM_TAG,_response,&offset)) || XmlRpcUtil::nextTagIs(PARAM_TAG,_response,&offset)) ||
XmlRpcUtil::nextTagIs(FAULT_TAG,_response,&offset) && (_isFault = true)) (XmlRpcUtil::nextTagIs(FAULT_TAG,_response,&offset) && (_isFault = true)))
{ {
if ( ! result.fromXml(_response, &offset)) { if ( ! result.fromXml(_response, &offset)) {
XmlRpcUtil::error("Error in XmlRpcClient::parseResponse: Invalid response value. Response:\n%s", _response.c_str()); XmlRpcUtil::error("Error in XmlRpcClient::parseResponse: Invalid response value. Response:\n%s", _response.c_str());

View File

@@ -1,7 +1,7 @@
#include "xmlrpcpp/XmlRpcDispatch.h" #include "robot_xmlrpcpp/XmlRpcDispatch.h"
#include "xmlrpcpp/XmlRpcSource.h" #include "robot_xmlrpcpp/XmlRpcSource.h"
#include "xmlrpcpp/XmlRpcUtil.h" #include "robot_xmlrpcpp/XmlRpcUtil.h"
#include <math.h> #include <math.h>
#include <sys/timeb.h> #include <sys/timeb.h>
@@ -19,7 +19,7 @@
#endif // _WINDOWS #endif // _WINDOWS
using namespace XmlRpc; using namespace robot_xmlrpcpp;
XmlRpcDispatch::XmlRpcDispatch() XmlRpcDispatch::XmlRpcDispatch()

View File

@@ -1,13 +1,13 @@
#include "xmlrpcpp/XmlRpcServer.h" #include "robot_xmlrpcpp/XmlRpcServer.h"
#include "xmlrpcpp/XmlRpcServerConnection.h" #include "robot_xmlrpcpp/XmlRpcServerConnection.h"
#include "xmlrpcpp/XmlRpcServerMethod.h" #include "robot_xmlrpcpp/XmlRpcServerMethod.h"
#include "xmlrpcpp/XmlRpcSocket.h" #include "robot_xmlrpcpp/XmlRpcSocket.h"
#include "xmlrpcpp/XmlRpcUtil.h" #include "robot_xmlrpcpp/XmlRpcUtil.h"
#include "xmlrpcpp/XmlRpcException.h" #include "robot_xmlrpcpp/XmlRpcException.h"
using namespace XmlRpc; using namespace robot_xmlrpcpp;
XmlRpcServer::XmlRpcServer() XmlRpcServer::XmlRpcServer()

View File

@@ -1,8 +1,8 @@
#include "xmlrpcpp/XmlRpcServerConnection.h" #include "robot_xmlrpcpp/XmlRpcServerConnection.h"
#include "xmlrpcpp/XmlRpcSocket.h" #include "robot_xmlrpcpp/XmlRpcSocket.h"
#include "xmlrpcpp/XmlRpc.h" #include "robot_xmlrpcpp/XmlRpc.h"
#ifndef MAKEDEPEND #ifndef MAKEDEPEND
# include <stdio.h> # include <stdio.h>
# include <stdlib.h> # include <stdlib.h>
@@ -11,7 +11,7 @@
#endif #endif
using namespace XmlRpc; using namespace robot_xmlrpcpp;
// Static data // Static data
const char XmlRpcServerConnection::METHODNAME_TAG[] = "<methodName>"; const char XmlRpcServerConnection::METHODNAME_TAG[] = "<methodName>";
@@ -348,7 +348,7 @@ XmlRpcServerConnection::generateHeader(std::string const& body)
"Content-length: "; "Content-length: ";
char buffLen[40]; char buffLen[40];
sprintf(buffLen,"%d\r\n\r\n", body.size()); sprintf(buffLen,"%d\r\n\r\n", (int)body.size());
return header + buffLen; return header + buffLen;
} }

View File

@@ -1,8 +1,8 @@
#include "xmlrpcpp/XmlRpcServerMethod.h" #include "robot_xmlrpcpp/XmlRpcServerMethod.h"
#include "xmlrpcpp/XmlRpcServer.h" #include "robot_xmlrpcpp/XmlRpcServer.h"
namespace XmlRpc { namespace robot_xmlrpcpp {
XmlRpcServerMethod::XmlRpcServerMethod(std::string const& name, XmlRpcServer* server) XmlRpcServerMethod::XmlRpcServerMethod(std::string const& name, XmlRpcServer* server)
@@ -18,4 +18,4 @@ namespace XmlRpc {
} }
} // namespace XmlRpc } // namespace robot_xmlrpcpp

View File

@@ -1,6 +1,6 @@
#include "xmlrpcpp/XmlRpcSocket.h" #include "robot_xmlrpcpp/XmlRpcSocket.h"
#include "xmlrpcpp/XmlRpcUtil.h" #include "robot_xmlrpcpp/XmlRpcUtil.h"
#ifndef MAKEDEPEND #ifndef MAKEDEPEND
@@ -30,7 +30,7 @@ extern "C" {
#endif // MAKEDEPEND #endif // MAKEDEPEND
using namespace XmlRpc; using namespace robot_xmlrpcpp;

View File

@@ -1,9 +1,9 @@
#include "xmlrpcpp/XmlRpcSource.h" #include "robot_xmlrpcpp/XmlRpcSource.h"
#include "xmlrpcpp/XmlRpcSocket.h" #include "robot_xmlrpcpp/XmlRpcSocket.h"
#include "xmlrpcpp/XmlRpcUtil.h" #include "robot_xmlrpcpp/XmlRpcUtil.h"
namespace XmlRpc { namespace robot_xmlrpcpp {
XmlRpcSource::XmlRpcSource(int fd /*= -1*/, bool deleteOnClose /*= false*/) XmlRpcSource::XmlRpcSource(int fd /*= -1*/, bool deleteOnClose /*= false*/)
@@ -32,4 +32,4 @@ namespace XmlRpc {
} }
} }
} // namespace XmlRpc } // namespace robot_xmlrpcpp

View File

@@ -1,5 +1,5 @@
#include "xmlrpcpp/XmlRpcUtil.h" #include "robot_xmlrpcpp/XmlRpcUtil.h"
#ifndef MAKEDEPEND #ifndef MAKEDEPEND
# include <ctype.h> # include <ctype.h>
@@ -9,9 +9,9 @@
# include <string.h> # include <string.h>
#endif #endif
#include "xmlrpcpp/XmlRpc.h" #include "robot_xmlrpcpp/XmlRpc.h"
using namespace XmlRpc; using namespace robot_xmlrpcpp;
//#define USE_WINDOWS_DEBUG // To make the error and log messages go to VC++ debug output //#define USE_WINDOWS_DEBUG // To make the error and log messages go to VC++ debug output
@@ -21,7 +21,7 @@ using namespace XmlRpc;
#endif #endif
// Version id // Version id
const char XmlRpc::XMLRPC_VERSION[] = "XMLRPC++ 0.7"; const char robot_xmlrpcpp::XMLRPC_VERSION[] = "XMLRPC++ 0.7";
// Default log verbosity: 0 for no messages through 5 (writes everything) // Default log verbosity: 0 for no messages through 5 (writes everything)
int XmlRpcLogHandler::_verbosity = 0; int XmlRpcLogHandler::_verbosity = 0;
@@ -63,8 +63,8 @@ XmlRpcErrorHandler* XmlRpcErrorHandler::_errorHandler = &defaultErrorHandler;
// Easy API for log verbosity // Easy API for log verbosity
int XmlRpc::getVerbosity() { return XmlRpcLogHandler::getVerbosity(); } int robot_xmlrpcpp::getVerbosity() { return XmlRpcLogHandler::getVerbosity(); }
void XmlRpc::setVerbosity(int level) { XmlRpcLogHandler::setVerbosity(level); } void robot_xmlrpcpp::setVerbosity(int level) { XmlRpcLogHandler::setVerbosity(level); }

View File

@@ -1,8 +1,8 @@
#include "xmlrpcpp/XmlRpcValue.h" #include "robot_xmlrpcpp/XmlRpcValue.h"
#include "xmlrpcpp/XmlRpcException.h" #include "robot_xmlrpcpp/XmlRpcException.h"
#include "xmlrpcpp/XmlRpcUtil.h" #include "robot_xmlrpcpp/XmlRpcUtil.h"
#include "xmlrpcpp/base64.h" #include "robot_xmlrpcpp/base64.h"
#ifndef MAKEDEPEND #ifndef MAKEDEPEND
# include <iostream> # include <iostream>
@@ -11,7 +11,7 @@
# include <stdio.h> # include <stdio.h>
#endif #endif
namespace XmlRpc { namespace robot_xmlrpcpp {
static const char VALUE_TAG[] = "<value>"; static const char VALUE_TAG[] = "<value>";
@@ -209,6 +209,13 @@ namespace XmlRpc {
return _type == TypeStruct && _value.asStruct->find(name) != _value.asStruct->end(); return _type == TypeStruct && _value.asStruct->find(name) != _value.asStruct->end();
} }
const XmlRpcValue::ValueStruct *XmlRpcValue::getStructMembers() const
{
if (_type != TypeStruct)
return nullptr;
return _value.asStruct;
}
// Set the value from xml. The chars at *offset into valueXml // Set the value from xml. The chars at *offset into valueXml
// should be the start of a <value> tag. Destroys any existing value. // should be the start of a <value> tag. Destroys any existing value.
bool XmlRpcValue::fromXml(std::string const& valueXml, int* offset) bool XmlRpcValue::fromXml(std::string const& valueXml, int* offset)
@@ -597,11 +604,11 @@ namespace XmlRpc {
return os; return os;
} }
} // namespace XmlRpc } // namespace robot_xmlrpcpp
// ostream // ostream
std::ostream& operator<<(std::ostream& os, XmlRpc::XmlRpcValue& v) std::ostream& operator<<(std::ostream& os, robot_xmlrpcpp::XmlRpcValue& v)
{ {
// If you want to output in xml format: // If you want to output in xml format:
//return os << v.toXml(); //return os << v.toXml();

View File

@@ -1,108 +1,216 @@
// FileClient.cpp : A simple xmlrpc client. Usage: FileClient serverHost serverPort xmlfile // FileClient.cpp : A simple xmlrpc client. Usage: FileClient serverHost serverPort xmlfile
// Reads an xmlrpc request from the specified xmlfile and calls the method on the server. // Reads an xmlrpc request from the specified xmlfile and calls the method on the server.
// //
// Link against xmlrpc lib and whatever socket libs your system needs (ws2_32.lib on windows) // Link against xmlrpc lib and whatever socket libs your system needs (ws2_32.lib on windows)
#include "XmlRpc.h" #include "XmlRpc.h"
#include <iostream> #include <iostream>
#include <fstream> #include <fstream>
#include <stdlib.h> #include <stdlib.h>
#include "XmlRpc.h"
using namespace robot::XmlRpc;
std::string parseRequest(std::string const& xml, XmlRpcValue& params); std::string parseRequest(std::string const& xml, XmlRpcValue& params);
int main(int argc, char* argv[]) int main(int argc, char* argv[])
{ {
if (argc != 4) { if (argc != 4) {
std::cerr << "Usage: FileClient serverHost serverPort requestXmlFile\n"; std::cerr << "Usage: FileClient serverHost serverPort requestXmlFile\n";
return -1; return -1;
} }
int port = atoi(argv[2]); int port = atoi(argv[2]);
robot::XmlRpc::setVerbosity(5);
XmlRpcClient c(argv[1], port); XmlRpcClient c(argv[1], port);
// //
std::ifstream infile(argv[3]); std::ifstream infile(argv[3]);
if (infile.fail()) { if (infile.fail()) {
std::cerr << "Could not open file '" << argv[3] << "'.\n"; std::cerr << "Could not open file '" << argv[3] << "'.\n";
return -1; return -1;
} }
// Suck in the file. This is a one-liner in good compilers (which vc++ 6 is not)... // Suck in the file. This is a one-liner in good compilers (which vc++ 6 is not)...
infile.seekg(0L, std::ios::end); infile.seekg(0L, std::ios::end);
long nb = infile.tellg(); long nb = infile.tellg();
infile.clear(); infile.clear();
infile.seekg(0L); infile.seekg(0L);
char* b = new char[nb+1]; char* b = new char[nb+1];
infile.read(b, nb); infile.read(b, nb);
b[nb] = 0; b[nb] = 0;
std::cout << "Read file.\n"; std::cout << "Read file.\n";
// Find the methodName and parse the params // Find the methodName and parse the params
std::string s(b); std::string s(b);
XmlRpcValue params; XmlRpcValue params;
std::string name = parseRequest(s, params); std::string name = parseRequest(s, params);
if (name.empty()) { if (name.empty()) {
std::cerr << "Could not parse file\n"; std::cerr << "Could not parse file\n";
return -1; return -1;
} }
for (;;) { for (;;) {
XmlRpcValue result; XmlRpcValue result;
std::cout << "Calling " << name << std::endl; std::cout << "Calling " << name << std::endl;
if (c.execute(name.c_str(), params, result)) if (c.execute(name.c_str(), params, result))
std::cout << result << "\n\n"; std::cout << result << "\n\n";
else else
std::cout << "Error calling '" << name << "'\n\n"; std::cout << "Error calling '" << name << "'\n\n";
std::cout << "Again? [y]: "; std::cout << "Again? [y]: ";
std::string ans; std::string ans;
std::cin >> ans; std::cin >> ans;
if (ans != "" && ans != "y") break; if (ans != "" && ans != "y") break;
} }
return 0; return 0;
} }
// //
std::string std::string
parseRequest(std::string const& xml, XmlRpcValue& params) parseRequest(std::string const& xml, XmlRpcValue& params)
{ {
const char METHODNAME_TAG[] = "<methodName>"; const char METHODNAME_TAG[] = "<methodName>";
const char PARAMS_TAG[] = "<params>"; const char PARAMS_TAG[] = "<params>";
const char PARAMS_ETAG[] = "</params>"; const char PARAMS_ETAG[] = "</params>";
const char PARAM_TAG[] = "<param>"; const char PARAM_TAG[] = "<param>";
const char PARAM_ETAG[] = "</param>"; const char PARAM_ETAG[] = "</param>";
int offset = 0; // Number of chars parsed from the request int offset = 0; // Number of chars parsed from the request
std::string methodName = XmlRpcUtil::parseTag(METHODNAME_TAG, xml, &offset); std::string methodName = XmlRpcUtil::parseTag(METHODNAME_TAG, xml, &offset);
XmlRpcUtil::log(3, "XmlRpcServerConnection::parseRequest: parsed methodName %s.", methodName.c_str()); XmlRpcUtil::log(3, "XmlRpcServerConnection::parseRequest: parsed methodName %s.", methodName.c_str());
if (! methodName.empty() && XmlRpcUtil::findTag(PARAMS_TAG, xml, &offset)) if (! methodName.empty() && XmlRpcUtil::findTag(PARAMS_TAG, xml, &offset))
{ {
int nArgs = 0; int nArgs = 0;
while (XmlRpcUtil::nextTagIs(PARAM_TAG, xml, &offset)) { while (XmlRpcUtil::nextTagIs(PARAM_TAG, xml, &offset)) {
std::cout << "Parsing arg " << nArgs+1 << std::endl; std::cout << "Parsing arg " << nArgs+1 << std::endl;
XmlRpcValue arg(xml, &offset); XmlRpcValue arg(xml, &offset);
if ( ! arg.valid()) { if ( ! arg.valid()) {
std::cerr << "Invalid argument\n"; std::cerr << "Invalid argument\n";
return std::string(); return std::string();
} }
std::cout << "Adding arg " << nArgs+1 << " to params array." << std::endl; std::cout << "Adding arg " << nArgs+1 << " to params array." << std::endl;
params[nArgs++] = arg; params[nArgs++] = arg;
(void) XmlRpcUtil::nextTagIs(PARAM_ETAG, xml, &offset); (void) XmlRpcUtil::nextTagIs(PARAM_ETAG, xml, &offset);
} }
XmlRpcUtil::log(3, "XmlRpcServerConnection::parseRequest: parsed %d params.", nArgs); XmlRpcUtil::log(3, "XmlRpcServerConnection::parseRequest: parsed %d params.", nArgs);
(void) XmlRpcUtil::nextTagIs(PARAMS_ETAG, xml, &offset); (void) XmlRpcUtil::nextTagIs(PARAMS_ETAG, xml, &offset);
} }
return methodName; return methodName;
} }

View File

@@ -3,7 +3,7 @@
// on windows) // on windows)
#include "XmlRpc.h" #include "XmlRpc.h"
#include <iostream> #include <iostream>
using namespace XmlRpc; using namespace robot::XmlRpc;
int main(int argc, char* argv[]) int main(int argc, char* argv[])
{ {
@@ -12,7 +12,7 @@ int main(int argc, char* argv[])
return -1; return -1;
} }
int port = atoi(argv[2]); int port = atoi(argv[2]);
//XmlRpc::setVerbosity(5); //robot::XmlRpc::setVerbosity(5);
// Use introspection API to look up the supported methods // Use introspection API to look up the supported methods
XmlRpcClient c(argv[1], port); XmlRpcClient c(argv[1], port);

View File

@@ -5,7 +5,7 @@
#include <iostream> #include <iostream>
#include <stdlib.h> #include <stdlib.h>
using namespace XmlRpc; using namespace robot::XmlRpc;
// The server // The server
XmlRpcServer s; XmlRpcServer s;
@@ -66,7 +66,7 @@ int main(int argc, char* argv[])
} }
int port = atoi(argv[1]); int port = atoi(argv[1]);
XmlRpc::setVerbosity(5); robot::XmlRpc::setVerbosity(5);
// Create the server socket on the specified port // Create the server socket on the specified port
s.bindAndListen(port); s.bindAndListen(port);

View File

@@ -1,45 +1,90 @@
// TestBase64Client.cpp : A simple xmlrpc client that returns a png file // TestBase64Client.cpp : A simple xmlrpc client that returns a png file
// encoded as base64 data to the client. // encoded as base64 data to the client.
// //
// Usage: TestBase64Client serverHost serverPort outputfile // Usage: TestBase64Client serverHost serverPort outputfile
// Requests a png file from the specified server and saves it in outputfile. // Requests a png file from the specified server and saves it in outputfile.
// Link against xmlrpc lib and whatever socket libs your system needs (ws2_32.lib on windows) // Link against xmlrpc lib and whatever socket libs your system needs (ws2_32.lib on windows)
#include "XmlRpc.h" #include "XmlRpc.h"
#include <iostream> #include <iostream>
#include <fstream> #include <fstream>
#include <stdlib.h> #include <stdlib.h>
using namespace robot::XmlRpc;
int main(int argc, char* argv[]) int main(int argc, char* argv[])
{ {
if (argc != 4) { if (argc != 4) {
std::cerr << "Usage: TestBase64Client serverHost serverPort outputFile\n"; std::cerr << "Usage: TestBase64Client serverHost serverPort outputFile\n";
return -1; return -1;
} }
int port = atoi(argv[2]); int port = atoi(argv[2]);
//robot::XmlRpc::setVerbosity(5);
XmlRpcClient c(argv[1], port); XmlRpcClient c(argv[1], port);
XmlRpcValue noArgs, result; XmlRpcValue noArgs, result;
if (c.execute("TestBase64", noArgs, result)) if (c.execute("TestBase64", noArgs, result))
{ {
const XmlRpcValue::BinaryData& data = result; const XmlRpcValue::BinaryData& data = result;
std::ofstream outfile(argv[3], std::ios::binary | std::ios::trunc); std::ofstream outfile(argv[3], std::ios::binary | std::ios::trunc);
if (outfile.fail()) if (outfile.fail())
std::cerr << "Error opening " << argv[3] << " for output.\n"; std::cerr << "Error opening " << argv[3] << " for output.\n";
else else
{ {
int n = int(data.size()); int n = int(data.size());
for (int i=0; i<n; ++i) for (int i=0; i<n; ++i)
outfile << data[i]; outfile << data[i];
} }
} }
else else
std::cout << "Error calling 'TestBase64'\n\n"; std::cout << "Error calling 'TestBase64'\n\n";
return 0; return 0;
} }

View File

@@ -1,68 +1,136 @@
// TestBase64Server.cpp : Simple XMLRPC server example. Usage: TestBase64Server serverPort // TestBase64Server.cpp : Simple XMLRPC server example. Usage: TestBase64Server serverPort
// //
#if defined(_MSC_VER) #if defined(_MSC_VER)
# pragma warning(disable:4786) // identifier was truncated in debug info # pragma warning(disable:4786) // identifier was truncated in debug info
#endif #endif
#include <iostream> #include <iostream>
#include <fstream> #include <fstream>
#include <algorithm> #include <algorithm>
#include <stdlib.h> #include <stdlib.h>
#include "XmlRpc.h" #include "XmlRpc.h"
#include <iostream>
using namespace robot::XmlRpc;
// The server // The server
XmlRpcServer s; XmlRpcServer s;
// No arguments, result is Base64-encoded pngnow.png data. // No arguments, result is Base64-encoded pngnow.png data.
class TestBase64 : public XmlRpcServerMethod class TestBase64 : public XmlRpcServerMethod
{ {
public: public:
TestBase64(XmlRpcServer* s) : XmlRpcServerMethod("TestBase64", s) {} TestBase64(XmlRpcServer* s) : XmlRpcServerMethod("TestBase64", s) {}
void execute(XmlRpcValue& params, XmlRpcValue& result) void execute(XmlRpcValue& params, XmlRpcValue& result)
{ {
std::ifstream infile("pngnow.png", std::ios::binary); std::ifstream infile("pngnow.png", std::ios::binary);
if (infile.fail()) if (infile.fail())
infile.open("../pngnow.png", std::ios::binary); infile.open("../pngnow.png", std::ios::binary);
if (infile.fail()) if (infile.fail())
result = "Could not open file pngnow.png"; result = "Could not open file pngnow.png";
else { else {
XmlRpcValue::BinaryData& data = result; XmlRpcValue::BinaryData& data = result;
int n = 0; int n = 0;
for (;; ++n) { for (;; ++n) {
char c = infile.get(); char c = infile.get();
if (infile.eof()) break; if (infile.eof()) break;
data.push_back(c); data.push_back(c);
} }
std::cerr << "Read " << n << " bytes from pngnow.png\n"; std::cerr << "Read " << n << " bytes from pngnow.png\n";
} }
} }
} TestBase64(&s); // This constructor registers the method with the server } TestBase64(&s); // This constructor registers the method with the server
int main(int argc, char* argv[]) int main(int argc, char* argv[])
{ {
if (argc != 2) { if (argc != 2) {
std::cerr << "Usage: TestBase64Server serverPort\n"; std::cerr << "Usage: TestBase64Server serverPort\n";
return -1; return -1;
} }
int port = atoi(argv[1]); int port = atoi(argv[1]);
//robot::XmlRpc::setVerbosity(5);
// Create the server socket on the specified port // Create the server socket on the specified port
s.bindAndListen(port); s.bindAndListen(port);
// Wait for requests indefinitely // Wait for requests indefinitely
s.work(-1.0); s.work(-1.0);
return 0; return 0;
} }

View File

@@ -1,233 +1,466 @@
// TestValues.cpp : Test XML encoding and decoding of XmlRpcValues. // TestValues.cpp : Test XML encoding and decoding of XmlRpcValues.
#include <stdlib.h> #include <stdlib.h>
#include "XmlRpcValue.h" #include "XmlRpcValue.h"
#include <assert.h> #include <assert.h>
#include <iostream> #include <iostream>
using namespace robot::XmlRpc;
void testBoolean() void testBoolean()
{ {
XmlRpcValue booleanFalse(false); XmlRpcValue booleanFalse(false);
XmlRpcValue booleanTrue(true); XmlRpcValue booleanTrue(true);
int offset = 0; int offset = 0;
XmlRpcValue booleanFalseXml("<value><boolean>0</boolean></value>", &offset); XmlRpcValue booleanFalseXml("<value><boolean>0</boolean></value>", &offset);
offset = 0; offset = 0;
XmlRpcValue booleanTrueXml("<value><boolean>1</boolean></value>", &offset); XmlRpcValue booleanTrueXml("<value><boolean>1</boolean></value>", &offset);
assert(booleanFalse != booleanTrue); assert(booleanFalse != booleanTrue);
assert(booleanFalse == booleanFalseXml); assert(booleanFalse == booleanFalseXml);
assert(booleanFalse != booleanTrueXml); assert(booleanFalse != booleanTrueXml);
if (bool(booleanFalse)) if (bool(booleanFalse))
assert(false); assert(false);
if ( ! bool(booleanTrue)) if ( ! bool(booleanTrue))
assert(false); assert(false);
} }
// Int // Int
void testInt() void testInt()
{ {
XmlRpcValue int0(0); XmlRpcValue int0(0);
XmlRpcValue int1(1); XmlRpcValue int1(1);
XmlRpcValue int10(10); XmlRpcValue int10(10);
XmlRpcValue int_1(-1); XmlRpcValue int_1(-1);
int offset = 0; int offset = 0;
XmlRpcValue int0Xml("<value><int>0</int></value>", &offset); XmlRpcValue int0Xml("<value><int>0</int></value>", &offset);
offset = 0; offset = 0;
XmlRpcValue int9Xml("<value><i4>9</i4></value>", &offset); XmlRpcValue int9Xml("<value><i4>9</i4></value>", &offset);
assert(int0 == int0Xml); assert(int0 == int0Xml);
assert(int(int10) - int(int1) == int(int9Xml)); assert(int(int10) - int(int1) == int(int9Xml));
assert(9 == int(int9Xml)); assert(9 == int(int9Xml));
assert(int(int10) + int(int_1) == int(int9Xml)); assert(int(int10) + int(int_1) == int(int9Xml));
} }
void testDouble() void testDouble()
{ {
// Double // Double
XmlRpcValue d(43.7); XmlRpcValue d(43.7);
int offset = 0; int offset = 0;
XmlRpcValue dXml("<value><double>56.3</double></value>", &offset); XmlRpcValue dXml("<value><double>56.3</double></value>", &offset);
assert(double(d) + double(dXml) == 100.0); // questionable practice... assert(double(d) + double(dXml) == 100.0); // questionable practice...
} }
void testString() void testString()
{ {
// String // String
XmlRpcValue s("Now is the time <&"); XmlRpcValue s("Now is the time <&");
char csxml[] = "<value><string>Now is the time &lt;&amp;</string></value>"; char csxml[] = "<value><string>Now is the time &lt;&amp;</string></value>";
std::string ssxml = csxml; std::string ssxml = csxml;
int offset = 0; int offset = 0;
XmlRpcValue vscXml(csxml, &offset); XmlRpcValue vscXml(csxml, &offset);
offset = 0; offset = 0;
XmlRpcValue vssXml(ssxml, &offset); XmlRpcValue vssXml(ssxml, &offset);
assert(s == vscXml); assert(s == vscXml);
assert(s == vssXml); assert(s == vssXml);
offset = 0; offset = 0;
XmlRpcValue fromXml(vssXml.toXml(), &offset); XmlRpcValue fromXml(vssXml.toXml(), &offset);
assert(s == fromXml); assert(s == fromXml);
// Empty or blank strings with no <string> tags // Empty or blank strings with no <string> tags
std::string emptyStringXml("<value></value>"); std::string emptyStringXml("<value></value>");
offset = 0; offset = 0;
XmlRpcValue emptyStringVal1(emptyStringXml, &offset); XmlRpcValue emptyStringVal1(emptyStringXml, &offset);
XmlRpcValue emptyStringVal2(""); XmlRpcValue emptyStringVal2("");
assert(emptyStringVal1 == emptyStringVal2); assert(emptyStringVal1 == emptyStringVal2);
emptyStringXml = "<value> </value>"; emptyStringXml = "<value> </value>";
offset = 0; offset = 0;
XmlRpcValue blankStringVal(emptyStringXml, &offset); XmlRpcValue blankStringVal(emptyStringXml, &offset);
assert(std::string(blankStringVal) == " "); assert(std::string(blankStringVal) == " ");
} }
void testDateTime() void testDateTime()
{ {
// DateTime // DateTime
int offset = 0; int offset = 0;
XmlRpcValue dateTime("<value><dateTime.iso8601>19040101T03:12:35</dateTime.iso8601></value>", &offset); XmlRpcValue dateTime("<value><dateTime.iso8601>19040101T03:12:35</dateTime.iso8601></value>", &offset);
struct tm &t = dateTime; struct tm &t = dateTime;
assert(t.tm_year == 1904 && t.tm_min == 12); assert(t.tm_year == 1904 && t.tm_min == 12);
} }
void testArray(XmlRpcValue const& d) void testArray(XmlRpcValue const& d)
{ {
// Array // Array
XmlRpcValue a; XmlRpcValue a;
a.setSize(4); a.setSize(4);
a[0] = 1; a[0] = 1;
a[1] = std::string("two"); a[1] = std::string("two");
a[2] = 43.7; a[2] = 43.7;
a[3] = "four"; a[3] = "four";
assert(int(a[0]) == 1); assert(int(a[0]) == 1);
assert(a[2] == d); assert(a[2] == d);
char csaXml[] = char csaXml[] =
"<value><array>\n" "<value><array>\n"
" <data>\n" " <data>\n"
" <value><i4>1</i4></value> \n" " <value><i4>1</i4></value> \n"
" <value> <string>two</string></value>\n" " <value> <string>two</string></value>\n"
" <value><double>43.7</double></value>\n" " <value><double>43.7</double></value>\n"
" <value>four</value>\n" " <value>four</value>\n"
" </data>\n" " </data>\n"
"</array></value>"; "</array></value>";
int offset = 0; int offset = 0;
XmlRpcValue aXml(csaXml, &offset); XmlRpcValue aXml(csaXml, &offset);
assert(a == aXml); assert(a == aXml);
} }
void testStruct() void testStruct()
{ {
// Struct // Struct
XmlRpcValue struct1; XmlRpcValue struct1;
struct1["i4"] = 1; struct1["i4"] = 1;
struct1["str"] = "two"; struct1["str"] = "two";
struct1["d"] = 43.7; struct1["d"] = 43.7;
XmlRpcValue a; XmlRpcValue a;
a.setSize(4); a.setSize(4);
a[0] = 1; a[0] = 1;
a[1] = std::string("two"); a[1] = std::string("two");
a[2] = 43.7; a[2] = 43.7;
a[3] = "four"; a[3] = "four";
assert(struct1["d"] == a[2]); assert(struct1["d"] == a[2]);
char csStructXml[] = char csStructXml[] =
"<value><struct>\n" "<value><struct>\n"
" <member>\n" " <member>\n"
" <name>i4</name> \n" " <name>i4</name> \n"
" <value><i4>1</i4></value> \n" " <value><i4>1</i4></value> \n"
" </member>\n" " </member>\n"
" <member>\n" " <member>\n"
" <name>d</name> \n" " <name>d</name> \n"
" <value><double>43.7</double></value>\n" " <value><double>43.7</double></value>\n"
" </member>\n" " </member>\n"
" <member>\n" " <member>\n"
" <name>str</name> \n" " <name>str</name> \n"
" <value> <string>two</string></value>\n" " <value> <string>two</string></value>\n"
" </member>\n" " </member>\n"
"</struct></value>"; "</struct></value>";
int offset = 0; int offset = 0;
XmlRpcValue structXml(csStructXml, &offset); XmlRpcValue structXml(csStructXml, &offset);
assert(struct1 == structXml); assert(struct1 == structXml);
XmlRpcValue astruct; XmlRpcValue astruct;
astruct["array"] = a; astruct["array"] = a;
assert(astruct["array"][2] == struct1["d"]); assert(astruct["array"][2] == struct1["d"]);
for (int i=0; i<10; i++) { for (int i=0; i<10; i++) {
XmlRpcValue Event; XmlRpcValue Event;
Event["Name"] = "string"; Event["Name"] = "string";
Event.clear(); Event.clear();
const int NELMTS = 100; const int NELMTS = 100;
int ii; int ii;
for (ii=0; ii< NELMTS; ++ii) { for (ii=0; ii< NELMTS; ++ii) {
char buf[40]; char buf[40];
sprintf(buf,"%d", ii); sprintf(buf,"%d", ii);
Event[std::string(buf)] = buf; Event[std::string(buf)] = buf;
} }
Event.clear(); Event.clear();
int offset = 0;
XmlRpcValue dateTime("<value><dateTime.iso8601>19040101T03:12:35</dateTime.iso8601></value>", &offset);
struct tm &t = dateTime;
assert(t.tm_year == 1904 && t.tm_min == 12);
}
for (ii=0; ii< NELMTS; ++ii) { for (ii=0; ii< NELMTS; ++ii) {
char buf[40]; char buf[40];
sprintf(buf,"%d", ii); sprintf(buf,"%d", ii);
if (ii != NELMTS/2) if (ii != NELMTS/2)
Event[std::string(buf)] = ii;
else else
for (int jj=0; jj< NELMTS; ++jj) {
char bufj[40];
sprintf(bufj,"%d", jj);
Event[std::string(buf)][std::string(bufj)] = bufj;
}
}
for (ii=0; ii< NELMTS; ++ii) {
char buf[40];
sprintf(buf,"%d", ii);
if (ii != NELMTS/2)
assert(Event[std::string(buf)] == XmlRpcValue(ii));
else
assert(Event[std::string(buf)].size() == NELMTS); assert(Event[std::string(buf)].size() == NELMTS);
} }
} }
} }
int main(int argc, char* argv[]) int main(int argc, char* argv[])
{ {
testBoolean(); testBoolean();
testInt(); testInt();
testDouble(); testDouble();
testString(); testString();
testDateTime(); testDateTime();
testArray(43.7); testArray(43.7);
testStruct(); testStruct();
return 0; return 0;
} }

View File

@@ -1,253 +1,506 @@
// TestValues.cpp : Test XML encoding and decoding of XmlRpcValues. // TestValues.cpp : Test XML encoding and decoding of XmlRpcValues.
#define _CRTDBG_MAP_ALLOC #define _CRTDBG_MAP_ALLOC
#include <stdlib.h> #include <stdlib.h>
#include <crtdbg.h> #include <crtdbg.h>
#include "XmlRpcValue.h" #include "XmlRpcValue.h"
#include <assert.h> #include <assert.h>
#include <iostream> #include <iostream>
using namespace robot::XmlRpc;
void testBoolean() void testBoolean()
{ {
XmlRpcValue booleanFalse(false); XmlRpcValue booleanFalse(false);
XmlRpcValue booleanTrue(true); XmlRpcValue booleanTrue(true);
int offset = 0; int offset = 0;
XmlRpcValue booleanFalseXml("<value><boolean>0</boolean></value>", &offset); XmlRpcValue booleanFalseXml("<value><boolean>0</boolean></value>", &offset);
offset = 0; offset = 0;
XmlRpcValue booleanTrueXml("<value><boolean>1</boolean></value>", &offset); XmlRpcValue booleanTrueXml("<value><boolean>1</boolean></value>", &offset);
assert(booleanFalse != booleanTrue); assert(booleanFalse != booleanTrue);
assert(booleanFalse == booleanFalseXml); assert(booleanFalse == booleanFalseXml);
assert(booleanFalse == booleanFalseXml); assert(booleanFalse == booleanFalseXml);
if (booleanFalse) if (booleanFalse)
assert(false); assert(false);
if (booleanTrue) if (booleanTrue)
assert( ! false); assert( ! false);
else else
assert(false); assert(false);
} }
// Int // Int
void testInt() void testInt()
{ {
XmlRpcValue int0(0); XmlRpcValue int0(0);
XmlRpcValue int1(1); XmlRpcValue int1(1);
XmlRpcValue int10(10); XmlRpcValue int10(10);
XmlRpcValue int_1(-1); XmlRpcValue int_1(-1);
int offset = 0; int offset = 0;
XmlRpcValue int0Xml("<value><int>0</int></value>", &offset); XmlRpcValue int0Xml("<value><int>0</int></value>", &offset);
offset = 0; offset = 0;
XmlRpcValue int9Xml("<value><i4>9</i4></value>", &offset); XmlRpcValue int9Xml("<value><i4>9</i4></value>", &offset);
assert(int0 == int0Xml); assert(int0 == int0Xml);
assert(int(int10) - int(int1) == int(int9Xml)); assert(int(int10) - int(int1) == int(int9Xml));
assert(9 == int(int9Xml)); assert(9 == int(int9Xml));
assert(int(int10) + int(int_1) == int(int9Xml)); assert(int(int10) + int(int_1) == int(int9Xml));
} }
void testDouble() void testDouble()
{ {
// Double // Double
XmlRpcValue d(43.7); XmlRpcValue d(43.7);
int offset = 0; int offset = 0;
XmlRpcValue dXml("<value><double>56.3</double></value>", &offset); XmlRpcValue dXml("<value><double>56.3</double></value>", &offset);
assert(double(d) + double(dXml) == 100.0); // questionable practice... assert(double(d) + double(dXml) == 100.0); // questionable practice...
} }
void testString() void testString()
{ {
// String // String
XmlRpcValue s("Now is the time <&"); XmlRpcValue s("Now is the time <&");
char csxml[] = "<value><string>Now is the time &lt;&amp;</string></value>"; char csxml[] = "<value><string>Now is the time &lt;&amp;</string></value>";
std::string ssxml = csxml; std::string ssxml = csxml;
int offset = 0; int offset = 0;
XmlRpcValue vscXml(csxml, &offset); XmlRpcValue vscXml(csxml, &offset);
offset = 0; offset = 0;
XmlRpcValue vssXml(ssxml, &offset); XmlRpcValue vssXml(ssxml, &offset);
assert(s == vscXml); assert(s == vscXml);
assert(s == vssXml); assert(s == vssXml);
offset = 0; offset = 0;
XmlRpcValue fromXml(vssXml.toXml(), &offset); XmlRpcValue fromXml(vssXml.toXml(), &offset);
assert(s == fromXml); assert(s == fromXml);
// Empty or blank strings with no <string> tags // Empty or blank strings with no <string> tags
std::string emptyStringXml("<value></value>"); std::string emptyStringXml("<value></value>");
offset = 0; offset = 0;
XmlRpcValue emptyStringVal1(emptyStringXml, &offset); XmlRpcValue emptyStringVal1(emptyStringXml, &offset);
XmlRpcValue emptyStringVal2(""); XmlRpcValue emptyStringVal2("");
assert(emptyStringVal1 == emptyStringVal2); assert(emptyStringVal1 == emptyStringVal2);
emptyStringXml = "<value> </value>"; emptyStringXml = "<value> </value>";
offset = 0; offset = 0;
XmlRpcValue blankStringVal(emptyStringXml, &offset); XmlRpcValue blankStringVal(emptyStringXml, &offset);
assert(std::string(blankStringVal) == " "); assert(std::string(blankStringVal) == " ");
} }
void testDateTime() void testDateTime()
{ {
// DateTime // DateTime
int offset = 0; int offset = 0;
XmlRpcValue dateTime("<value><dateTime.iso8601>19040101T03:12:35</dateTime.iso8601></value>", &offset); XmlRpcValue dateTime("<value><dateTime.iso8601>19040101T03:12:35</dateTime.iso8601></value>", &offset);
struct tm &t = dateTime; struct tm &t = dateTime;
assert(t.tm_year == 1904 && t.tm_min == 12); assert(t.tm_year == 1904 && t.tm_min == 12);
} }
void testArray(XmlRpcValue const& d) void testArray(XmlRpcValue const& d)
{ {
// Array // Array
XmlRpcValue a; XmlRpcValue a;
a.setSize(4); a.setSize(4);
a[0] = 1; a[0] = 1;
a[1] = std::string("two"); a[1] = std::string("two");
a[2] = 43.7; a[2] = 43.7;
a[3] = "four"; a[3] = "four";
assert(int(a[0]) == 1); assert(int(a[0]) == 1);
assert(a[2] == d); assert(a[2] == d);
char csaXml[] = char csaXml[] =
"<value><array>\n" "<value><array>\n"
" <data>\n" " <data>\n"
" <value><i4>1</i4></value> \n" " <value><i4>1</i4></value> \n"
" <value> <string>two</string></value>\n" " <value> <string>two</string></value>\n"
" <value><double>43.7</double></value>\n" " <value><double>43.7</double></value>\n"
" <value>four</value>\n" " <value>four</value>\n"
" </data>\n" " </data>\n"
"</array></value>"; "</array></value>";
int offset = 0; int offset = 0;
XmlRpcValue aXml(csaXml, &offset); XmlRpcValue aXml(csaXml, &offset);
assert(a == aXml); assert(a == aXml);
} }
void testStruct() void testStruct()
{ {
// Struct // Struct
XmlRpcValue struct1; XmlRpcValue struct1;
struct1["i4"] = 1; struct1["i4"] = 1;
struct1["str"] = "two"; struct1["str"] = "two";
struct1["d"] = 43.7; struct1["d"] = 43.7;
XmlRpcValue a; XmlRpcValue a;
a.setSize(4); a.setSize(4);
a[0] = 1; a[0] = 1;
a[1] = std::string("two"); a[1] = std::string("two");
a[2] = 43.7; a[2] = 43.7;
a[3] = "four"; a[3] = "four";
assert(struct1["d"] == a[2]); assert(struct1["d"] == a[2]);
char csStructXml[] = char csStructXml[] =
"<value><struct>\n" "<value><struct>\n"
" <member>\n" " <member>\n"
" <name>i4</name> \n" " <name>i4</name> \n"
" <value><i4>1</i4></value> \n" " <value><i4>1</i4></value> \n"
" </member>\n" " </member>\n"
" <member>\n" " <member>\n"
" <name>d</name> \n" " <name>d</name> \n"
" <value><double>43.7</double></value>\n" " <value><double>43.7</double></value>\n"
" </member>\n" " </member>\n"
" <member>\n" " <member>\n"
" <name>str</name> \n" " <name>str</name> \n"
" <value> <string>two</string></value>\n" " <value> <string>two</string></value>\n"
" </member>\n" " </member>\n"
"</struct></value>"; "</struct></value>";
int offset = 0; int offset = 0;
XmlRpcValue structXml(csStructXml, &offset); XmlRpcValue structXml(csStructXml, &offset);
assert(struct1 == structXml); assert(struct1 == structXml);
XmlRpcValue astruct; XmlRpcValue astruct;
astruct["array"] = a; astruct["array"] = a;
assert(astruct["array"][2] == struct1["d"]); assert(astruct["array"][2] == struct1["d"]);
for (int i=0; i<10; i++) { for (int i=0; i<10; i++) {
XmlRpcValue Event; XmlRpcValue Event;
Event["Name"] = "string"; Event["Name"] = "string";
Event.clear(); Event.clear();
const int NELMTS = 100; const int NELMTS = 100;
int ii; int ii;
for (ii=0; ii< NELMTS; ++ii) { for (ii=0; ii< NELMTS; ++ii) {
char buf[40]; char buf[40];
sprintf(buf,"%d", ii); sprintf(buf,"%d", ii);
Event[buf] = buf; Event[buf] = buf;
} }
Event.clear(); Event.clear();
// DateTime
int offset = 0;
XmlRpcValue dateTime("<value><dateTime.iso8601>19040101T03:12:35</dateTime.iso8601></value>", &offset);
struct tm &t = dateTime;
assert(t.tm_year == 1904 && t.tm_min == 12);
}
for (ii=0; ii< NELMTS; ++ii) { for (ii=0; ii< NELMTS; ++ii) {
char buf[40]; char buf[40];
sprintf(buf,"%d", ii); sprintf(buf,"%d", ii);
if (ii != NELMTS/2) if (ii != NELMTS/2)
void testArray(XmlRpcValue const& d)
Event[buf] = ii;
else else
for (int jj=0; jj< NELMTS; ++jj) {
char bufj[40];
sprintf(bufj,"%d", jj);
Event[buf][bufj] = bufj;
}
}
for (ii=0; ii< NELMTS; ++ii) {
char buf[40];
sprintf(buf,"%d", ii);
if (ii != NELMTS/2)
assert(Event[buf] == XmlRpcValue(ii));
else
assert(Event[buf].size() == NELMTS); assert(Event[buf].size() == NELMTS);
} }
} }
} }
int main(int argc, char* argv[]) int main(int argc, char* argv[])
{ {
_CrtDumpMemoryLeaks(); _CrtDumpMemoryLeaks();
_CrtCheckMemory( ); _CrtCheckMemory( );
testBoolean(); testBoolean();
_CrtDumpMemoryLeaks(); _CrtDumpMemoryLeaks();
_CrtCheckMemory( ); _CrtCheckMemory( );
testInt(); testInt();
_CrtDumpMemoryLeaks(); _CrtDumpMemoryLeaks();
_CrtCheckMemory( ); _CrtCheckMemory( );
testDouble(); testDouble();
_CrtDumpMemoryLeaks(); _CrtDumpMemoryLeaks();
_CrtCheckMemory( ); _CrtCheckMemory( );
testString(); testString();
_CrtDumpMemoryLeaks(); _CrtDumpMemoryLeaks();
_CrtCheckMemory( ); _CrtCheckMemory( );
testDateTime(); testDateTime();
_CrtDumpMemoryLeaks(); _CrtDumpMemoryLeaks();
_CrtCheckMemory( ); _CrtCheckMemory( );
testArray(43.7); testArray(43.7);
_CrtDumpMemoryLeaks(); _CrtDumpMemoryLeaks();
_CrtCheckMemory( ); _CrtCheckMemory( );
testStruct(); testStruct();
_CrtDumpMemoryLeaks(); _CrtDumpMemoryLeaks();
_CrtCheckMemory( ); _CrtCheckMemory( );
return 0; return 0;
} }

View File

@@ -1,53 +1,106 @@
// TestXml.cpp : Test XML encoding and decoding. // TestXml.cpp : Test XML encoding and decoding.
// The characters <>&'" are illegal in xml and must be encoded. // The characters <>&'" are illegal in xml and must be encoded.
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers #define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
#include <iostream> #include <iostream>
// If you are using MSVC++6, you should update <string> to fix // If you are using MSVC++6, you should update <string> to fix
// BUG: getline Template Function Reads Extra Character // BUG: getline Template Function Reads Extra Character
#include <string> #include <string>
#include <assert.h> #include <assert.h>
#include <stdlib.h> #include <stdlib.h>
#include "XmlRpcUtil.h" #include "XmlRpcUtil.h"
using namespace robot::XmlRpc;
int main(int argc, char* argv[]) int main(int argc, char* argv[])
{ {
// Basic tests // Basic tests
std::string empty; std::string empty;
assert(empty == XmlRpcUtil::xmlEncode(empty)); assert(empty == XmlRpcUtil::xmlEncode(empty));
assert(empty == XmlRpcUtil::xmlDecode(empty)); assert(empty == XmlRpcUtil::xmlDecode(empty));
assert(empty == XmlRpcUtil::xmlEncode("")); assert(empty == XmlRpcUtil::xmlEncode(""));
assert(empty == XmlRpcUtil::xmlDecode("")); assert(empty == XmlRpcUtil::xmlDecode(""));
std::string raw("<>&'\""); std::string raw("<>&'\"");
assert(XmlRpcUtil::xmlDecode(XmlRpcUtil::xmlEncode(raw)) == raw); assert(XmlRpcUtil::xmlDecode(XmlRpcUtil::xmlEncode(raw)) == raw);
std::cout << "Basic tests passed.\n"; std::cout << "Basic tests passed.\n";
// Interactive tests // Interactive tests
std::string s; std::string s;
for (;;) { for (;;) {
std::cout << "\nEnter line of raw text to encode:\n"; std::cout << "\nEnter line of raw text to encode:\n";
std::getline(std::cin, s); std::getline(std::cin, s);
if (s.empty()) break; if (s.empty()) break;
std::cout << XmlRpcUtil::xmlEncode(s) << std::endl; std::cout << XmlRpcUtil::xmlEncode(s) << std::endl;
} }
for (;;) { for (;;) {
std::cout << "\nEnter line of xml-encoded text to decode:\n"; std::cout << "\nEnter line of xml-encoded text to decode:\n";
std::getline(std::cin, s); std::getline(std::cin, s);
if (s.empty()) break; if (s.empty()) break;
std::cout << XmlRpcUtil::xmlDecode(s) << std::endl; std::cout << XmlRpcUtil::xmlDecode(s) << std::endl;
} }
return 0; return 0;
} }

View File

@@ -1,207 +1,414 @@
// Validator.cpp : XMLRPC server based on the compliancy test at validator.xmlrpc.com. // Validator.cpp : XMLRPC server based on the compliancy test at validator.xmlrpc.com.
// //
#include "XmlRpc.h" #include "XmlRpc.h"
using namespace robot::XmlRpc;
#include <iostream> #include <iostream>
XmlRpcServer s; XmlRpcServer s;
// One argument is passed, an array of structs, each with a member named curly with // One argument is passed, an array of structs, each with a member named curly with
// an integer value. Return the sum of those values. // an integer value. Return the sum of those values.
class ArrayOfStructsTest : public XmlRpcServerMethod class ArrayOfStructsTest : public XmlRpcServerMethod
{ {
public: public:
ArrayOfStructsTest(XmlRpcServer* s) : XmlRpcServerMethod("validator1.arrayOfStructsTest", s) {} ArrayOfStructsTest(XmlRpcServer* s) : XmlRpcServerMethod("validator1.arrayOfStructsTest", s) {}
void execute(XmlRpcValue& params, XmlRpcValue& result) void execute(XmlRpcValue& params, XmlRpcValue& result)
{ {
std::cerr << "ArrayOfStructsTest\n"; std::cerr << "ArrayOfStructsTest\n";
XmlRpcValue& arg1 = params[0]; XmlRpcValue& arg1 = params[0];
int n = arg1.size(), sum = 0; int n = arg1.size(), sum = 0;
for (int i=0; i<n; ++i) for (int i=0; i<n; ++i)
sum += int(arg1[i]["curly"]); sum += int(arg1[i]["curly"]);
result = sum; result = sum;
} }
} arrayOfStructsTest(&s); } arrayOfStructsTest(&s);
// This handler takes a single parameter, a string, that contains any number of predefined // This handler takes a single parameter, a string, that contains any number of predefined
// entities, namely <, >, &, ' and ". // entities, namely <, >, &, ' and ".
// The handler must return a struct that contains five fields, all numbers: ctLeftAngleBrackets, // The handler must return a struct that contains five fields, all numbers: ctLeftAngleBrackets,
// ctRightAngleBrackets, ctAmpersands, ctApostrophes, ctQuotes. // ctRightAngleBrackets, ctAmpersands, ctApostrophes, ctQuotes.
// To validate, the numbers must be correct. // To validate, the numbers must be correct.
class CountTheEntities : public XmlRpcServerMethod class CountTheEntities : public XmlRpcServerMethod
{ {
public: public:
CountTheEntities(XmlRpcServer* s) : XmlRpcServerMethod("validator1.countTheEntities", s) {} CountTheEntities(XmlRpcServer* s) : XmlRpcServerMethod("validator1.countTheEntities", s) {}
void execute(XmlRpcValue& params, XmlRpcValue& result) void execute(XmlRpcValue& params, XmlRpcValue& result)
{ {
std::cerr << "CountTheEntities\n"; std::cerr << "CountTheEntities\n";
std::string& arg = params[0]; std::string& arg = params[0];
int ctLeftAngleBrackets = 0; int ctLeftAngleBrackets = 0;
int ctRightAngleBrackets = 0; int ctRightAngleBrackets = 0;
int ctAmpersands = 0; int ctAmpersands = 0;
int ctApostrophes = 0; int ctApostrophes = 0;
int ctQuotes = 0; int ctQuotes = 0;
int n = int(arg.length()); int n = int(arg.length());
for (int i=0; i<n; ++i) for (int i=0; i<n; ++i)
switch (arg[i]) switch (arg[i])
{ {
case '<': ++ctLeftAngleBrackets; break; case '<': ++ctLeftAngleBrackets; break;
case '>': ++ctRightAngleBrackets; break; case '>': ++ctRightAngleBrackets; break;
case '&': ++ctAmpersands; break; case '&': ++ctAmpersands; break;
case '\'': ++ctApostrophes; break; case '\'': ++ctApostrophes; break;
case '\"': ++ctQuotes; break; case '\"': ++ctQuotes; break;
} }
result["ctLeftAngleBrackets"] = ctLeftAngleBrackets; result["ctLeftAngleBrackets"] = ctLeftAngleBrackets;
result["ctRightAngleBrackets"] = ctRightAngleBrackets; result["ctRightAngleBrackets"] = ctRightAngleBrackets;
result["ctAmpersands"] = ctAmpersands; result["ctAmpersands"] = ctAmpersands;
result["ctApostrophes"] = ctApostrophes; result["ctApostrophes"] = ctApostrophes;
result["ctQuotes"] = ctQuotes; result["ctQuotes"] = ctQuotes;
} }
} countTheEntities(&s); } countTheEntities(&s);
// This handler takes a single parameter, a struct, containing at least three elements // This handler takes a single parameter, a struct, containing at least three elements
// named moe, larry and curly, all <i4>s. Your handler must add the three numbers and // named moe, larry and curly, all <i4>s. Your handler must add the three numbers and
// return the result. // return the result.
class EasyStructTest : public XmlRpcServerMethod class EasyStructTest : public XmlRpcServerMethod
{ {
public: public:
EasyStructTest(XmlRpcServer* s) : XmlRpcServerMethod("validator1.easyStructTest", s) {} EasyStructTest(XmlRpcServer* s) : XmlRpcServerMethod("validator1.easyStructTest", s) {}
void execute(XmlRpcValue& params, XmlRpcValue& result) void execute(XmlRpcValue& params, XmlRpcValue& result)
{ {
std::cerr << "EasyStructTest\n"; std::cerr << "EasyStructTest\n";
XmlRpcValue& arg1 = params[0]; XmlRpcValue& arg1 = params[0];
int sum = int(arg1["moe"]) + int(arg1["larry"]) + int(arg1["curly"]); int sum = int(arg1["moe"]) + int(arg1["larry"]) + int(arg1["curly"]);
result = sum; result = sum;
} }
} easyStructTest(&s); } easyStructTest(&s);
// This handler takes a single parameter, a struct. Your handler must return the struct. // This handler takes a single parameter, a struct. Your handler must return the struct.
class EchoStructTest : public XmlRpcServerMethod class EchoStructTest : public XmlRpcServerMethod
{ {
public: public:
EchoStructTest(XmlRpcServer* s) : XmlRpcServerMethod("validator1.echoStructTest", s) {} EchoStructTest(XmlRpcServer* s) : XmlRpcServerMethod("validator1.echoStructTest", s) {}
void execute(XmlRpcValue& params, XmlRpcValue& result) void execute(XmlRpcValue& params, XmlRpcValue& result)
{ {
std::cerr << "EchoStructTest\n"; std::cerr << "EchoStructTest\n";
result = params[0]; result = params[0];
} }
} echoStructTest(&s); } echoStructTest(&s);
// This handler takes six parameters, and returns an array containing all the parameters. // This handler takes six parameters, and returns an array containing all the parameters.
class ManyTypesTest : public XmlRpcServerMethod class ManyTypesTest : public XmlRpcServerMethod
{ {
public: public:
ManyTypesTest(XmlRpcServer* s) : XmlRpcServerMethod("validator1.manyTypesTest", s) {} ManyTypesTest(XmlRpcServer* s) : XmlRpcServerMethod("validator1.manyTypesTest", s) {}
void execute(XmlRpcValue& params, XmlRpcValue& result) void execute(XmlRpcValue& params, XmlRpcValue& result)
{ {
std::cerr << "ManyTypesTest\n"; std::cerr << "ManyTypesTest\n";
result = params; result = params;
} }
} manyTypesTest(&s); } manyTypesTest(&s);
// This handler takes a single parameter, which is an array containing between 100 and // This handler takes a single parameter, which is an array containing between 100 and
// 200 elements. Each of the items is a string, your handler must return a string // 200 elements. Each of the items is a string, your handler must return a string
// containing the concatenated text of the first and last elements. // containing the concatenated text of the first and last elements.
class ModerateSizeArrayCheck : public XmlRpcServerMethod class ModerateSizeArrayCheck : public XmlRpcServerMethod
{ {
public: public:
ModerateSizeArrayCheck(XmlRpcServer* s) : XmlRpcServerMethod("validator1.moderateSizeArrayCheck", s) {} ModerateSizeArrayCheck(XmlRpcServer* s) : XmlRpcServerMethod("validator1.moderateSizeArrayCheck", s) {}
void execute(XmlRpcValue& params, XmlRpcValue& result) void execute(XmlRpcValue& params, XmlRpcValue& result)
{ {
std::cerr << "ModerateSizeArrayCheck\n"; std::cerr << "ModerateSizeArrayCheck\n";
std::string s = params[0][0]; std::string s = params[0][0];
s += params[0][params[0].size()-1]; s += params[0][params[0].size()-1];
result = s; result = s;
} }
} moderateSizeArrayCheck(&s); } moderateSizeArrayCheck(&s);
// This handler takes a single parameter, a struct, that models a daily calendar. // This handler takes a single parameter, a struct, that models a daily calendar.
// At the top level, there is one struct for each year. Each year is broken down // At the top level, there is one struct for each year. Each year is broken down
// into months, and months into days. Most of the days are empty in the struct // into months, and months into days. Most of the days are empty in the struct
// you receive, but the entry for April 1, 2000 contains a least three elements // you receive, but the entry for April 1, 2000 contains a least three elements
// named moe, larry and curly, all <i4>s. Your handler must add the three numbers // named moe, larry and curly, all <i4>s. Your handler must add the three numbers
// and return the result. // and return the result.
class NestedStructTest : public XmlRpcServerMethod class NestedStructTest : public XmlRpcServerMethod
{ {
public: public:
NestedStructTest(XmlRpcServer* s) : XmlRpcServerMethod("validator1.nestedStructTest", s) {} NestedStructTest(XmlRpcServer* s) : XmlRpcServerMethod("validator1.nestedStructTest", s) {}
void execute(XmlRpcValue& params, XmlRpcValue& result) void execute(XmlRpcValue& params, XmlRpcValue& result)
{ {
std::cerr << "NestedStructTest\n"; std::cerr << "NestedStructTest\n";
XmlRpcValue& dayStruct = params[0]["2000"]["04"]["01"]; XmlRpcValue& dayStruct = params[0]["2000"]["04"]["01"];
int sum = int(dayStruct["moe"]) + int(dayStruct["larry"]) + int(dayStruct["curly"]); int sum = int(dayStruct["moe"]) + int(dayStruct["larry"]) + int(dayStruct["curly"]);
result = sum; result = sum;
} }
} nestedStructTest(&s); } nestedStructTest(&s);
// This handler takes one parameter, and returns a struct containing three elements, // This handler takes one parameter, and returns a struct containing three elements,
// times10, times100 and times1000, the result of multiplying the number by 10, 100 and 1000. // times10, times100 and times1000, the result of multiplying the number by 10, 100 and 1000.
class SimpleStructReturnTest : public XmlRpcServerMethod class SimpleStructReturnTest : public XmlRpcServerMethod
{ {
public: public:
SimpleStructReturnTest(XmlRpcServer* s) : XmlRpcServerMethod("validator1.simpleStructReturnTest", s) {} SimpleStructReturnTest(XmlRpcServer* s) : XmlRpcServerMethod("validator1.simpleStructReturnTest", s) {}
void execute(XmlRpcValue& params, XmlRpcValue& result) void execute(XmlRpcValue& params, XmlRpcValue& result)
{ {
std::cerr << "SimpleStructReturnTest\n"; std::cerr << "SimpleStructReturnTest\n";
int n = params[0]; int n = params[0];
result["times10"] = n * 10; result["times10"] = n * 10;
result["times100"] = n * 100; result["times100"] = n * 100;
result["times1000"] = n * 1000; result["times1000"] = n * 1000;
} }
} simpleStructReturnTest(&s); } simpleStructReturnTest(&s);
int main(int argc, char* argv[]) int main(int argc, char* argv[])
{ {
if (argc != 2) { if (argc != 2) {
std::cerr << "Usage: Validator port\n"; std::cerr << "Usage: Validator port\n";
return -1; return -1;
} }
int port = atoi(argv[1]); int port = atoi(argv[1]);
EchoStructTest(XmlRpcServer* s) : XmlRpcServerMethod("validator1.echoStructTest", s) {}
robot::XmlRpc::setVerbosity(5);
// Create the server socket on the specified port // Create the server socket on the specified port
s.bindAndListen(port); s.bindAndListen(port);
// Wait for requests indefinitely // Wait for requests indefinitely
s.work(-1.0); s.work(-1.0);
return 0; return 0;
} }