From 922cb5559b9f2f97279fa24cc9c5862c8b666495 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?IOhannes=20m=20zm=C3=B6lnig?= Date: Tue, 8 Mar 2005 10:23:43 +0000 Subject: This commit was generated by cvs2svn to compensate for changes in r2603, which included commits to RCS files with non-trunk default branches. svn path=/trunk/externals/iem/iemxmlrpc/; revision=2604 --- xmlrpc++/src/XmlRpcUtil.cpp | 250 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 250 insertions(+) create mode 100644 xmlrpc++/src/XmlRpcUtil.cpp (limited to 'xmlrpc++/src/XmlRpcUtil.cpp') diff --git a/xmlrpc++/src/XmlRpcUtil.cpp b/xmlrpc++/src/XmlRpcUtil.cpp new file mode 100644 index 0000000..1bd583a --- /dev/null +++ b/xmlrpc++/src/XmlRpcUtil.cpp @@ -0,0 +1,250 @@ + +#include "XmlRpcUtil.h" + +#ifndef MAKEDEPEND +# include +# include +# include +# include +# include +#endif + +#include "XmlRpc.h" + +using namespace XmlRpc; + + +//#define USE_WINDOWS_DEBUG // To make the error and log messages go to VC++ debug output +#ifdef USE_WINDOWS_DEBUG +#define WIN32_LEAN_AND_MEAN +#include +#endif + +// Version id +const char XmlRpc::XMLRPC_VERSION[] = "XMLRPC++ 0.7"; + +// Default log verbosity: 0 for no messages through 5 (writes everything) +int XmlRpcLogHandler::_verbosity = 0; + +// Default log handler +static class DefaultLogHandler : public XmlRpcLogHandler { +public: + + void log(int level, const char* msg) { +#ifdef USE_WINDOWS_DEBUG + if (level <= _verbosity) { OutputDebugString(msg); OutputDebugString("\n"); } +#else + if (level <= _verbosity) std::cout << msg << std::endl; +#endif + } + +} defaultLogHandler; + +// Message log singleton +XmlRpcLogHandler* XmlRpcLogHandler::_logHandler = &defaultLogHandler; + + +// Default error handler +static class DefaultErrorHandler : public XmlRpcErrorHandler { +public: + + void error(const char* msg) { +#ifdef USE_WINDOWS_DEBUG + OutputDebugString(msg); OutputDebugString("\n"); +#else + std::cerr << msg << std::endl; +#endif + } +} defaultErrorHandler; + + +// Error handler singleton +XmlRpcErrorHandler* XmlRpcErrorHandler::_errorHandler = &defaultErrorHandler; + + +// Easy API for log verbosity +int XmlRpc::getVerbosity() { return XmlRpcLogHandler::getVerbosity(); } +void XmlRpc::setVerbosity(int level) { XmlRpcLogHandler::setVerbosity(level); } + + + +void XmlRpcUtil::log(int level, const char* fmt, ...) +{ + if (level <= XmlRpcLogHandler::getVerbosity()) + { + va_list va; + char buf[1024]; + va_start( va, fmt); + vsnprintf(buf,sizeof(buf)-1,fmt,va); + buf[sizeof(buf)-1] = 0; + XmlRpcLogHandler::getLogHandler()->log(level, buf); + } +} + + +void XmlRpcUtil::error(const char* fmt, ...) +{ + va_list va; + va_start(va, fmt); + char buf[1024]; + vsnprintf(buf,sizeof(buf)-1,fmt,va); + buf[sizeof(buf)-1] = 0; + XmlRpcErrorHandler::getErrorHandler()->error(buf); +} + + +// Returns contents between and , updates offset to char after +std::string +XmlRpcUtil::parseTag(const char* tag, std::string const& xml, int* offset) +{ + if (*offset >= int(xml.length())) return std::string(); + size_t istart = xml.find(tag, *offset); + if (istart == std::string::npos) return std::string(); + istart += strlen(tag); + std::string etag = "= int(xml.length())) return false; + size_t istart = xml.find(tag, *offset); + if (istart == std::string::npos) + return false; + + *offset = int(istart + strlen(tag)); + return true; +} + + +// Returns true if the tag is found at the specified offset (modulo any whitespace) +// and updates offset to the char after the tag +bool +XmlRpcUtil::nextTagIs(const char* tag, std::string const& xml, int* offset) +{ + if (*offset >= int(xml.length())) return false; + const char* cp = xml.c_str() + *offset; + int nc = 0; + while (*cp && isspace(*cp)) { + ++cp; + ++nc; + } + + int len = int(strlen(tag)); + if (*cp && (strncmp(cp, tag, len) == 0)) { + *offset += nc + len; + return true; + } + return false; +} + +// Returns the next tag and updates offset to the char after the tag, or empty string +// if the next non-whitespace character is not '<' +std::string +XmlRpcUtil::getNextTag(std::string const& xml, int* offset) +{ + if (*offset >= int(xml.length())) return std::string(); + + size_t pos = *offset; + const char* cp = xml.c_str() + pos; + while (*cp && isspace(*cp)) { + ++cp; + ++pos; + } + + if (*cp != '<') return std::string(); + + std::string s; + do { + s += *cp; + ++pos; + } while (*cp++ != '>' && *cp != 0); + + *offset = int(pos); + return s; +} + + + +// xml encodings (xml-encoded entities are preceded with '&') +static const char AMP = '&'; +static const char rawEntity[] = { '<', '>', '&', '\'', '\"', 0 }; +static const char* xmlEntity[] = { "lt;", "gt;", "amp;", "apos;", "quot;", 0 }; +static const int xmlEntLen[] = { 3, 3, 4, 5, 5 }; + + +// Replace xml-encoded entities with the raw text equivalents. + +std::string +XmlRpcUtil::xmlDecode(const std::string& encoded) +{ + std::string::size_type iAmp = encoded.find(AMP); + if (iAmp == std::string::npos) + return encoded; + + std::string decoded(encoded, 0, iAmp); + std::string::size_type iSize = encoded.size(); + decoded.reserve(iSize); + + const char* ens = encoded.c_str(); + while (iAmp != iSize) { + if (encoded[iAmp] == AMP && iAmp+1 < iSize) { + int iEntity; + for (iEntity=0; xmlEntity[iEntity] != 0; ++iEntity) + //if (encoded.compare(iAmp+1, xmlEntLen[iEntity], xmlEntity[iEntity]) == 0) + if (strncmp(ens+iAmp+1, xmlEntity[iEntity], xmlEntLen[iEntity]) == 0) + { + decoded += rawEntity[iEntity]; + iAmp += xmlEntLen[iEntity]+1; + break; + } + if (xmlEntity[iEntity] == 0) // unrecognized sequence + decoded += encoded[iAmp++]; + + } else { + decoded += encoded[iAmp++]; + } + } + + return decoded; +} + + +// Replace raw text with xml-encoded entities. + +std::string +XmlRpcUtil::xmlEncode(const std::string& raw) +{ + std::string::size_type iRep = raw.find_first_of(rawEntity); + if (iRep == std::string::npos) + return raw; + + std::string encoded(raw, 0, iRep); + std::string::size_type iSize = raw.size(); + + while (iRep != iSize) { + int iEntity; + for (iEntity=0; rawEntity[iEntity] != 0; ++iEntity) + if (raw[iRep] == rawEntity[iEntity]) + { + encoded += AMP; + encoded += xmlEntity[iEntity]; + break; + } + if (rawEntity[iEntity] == 0) + encoded += raw[iRep]; + ++iRep; + } + return encoded; +} + + + -- cgit v1.2.1