/home/bes3soft/bes3soft/Boss/7.0.2/dist/7.0.2/Utilities/JobInfoSvc/JobInfoSvc-00-00-02/xmlrpc++0.7/src/XmlRpcUtil.cpp

Go to the documentation of this file.
00001 
00002 #include "XmlRpcUtil.h"
00003 
00004 #ifndef MAKEDEPEND
00005 # include <ctype.h>
00006 # include <iostream>
00007 # include <stdarg.h>
00008 # include <stdio.h>
00009 # include <string.h>
00010 #endif
00011 
00012 #include "XmlRpc.h"
00013 
00014 using namespace XmlRpc;
00015 
00016 
00017 //#define USE_WINDOWS_DEBUG // To make the error and log messages go to VC++ debug output
00018 #ifdef USE_WINDOWS_DEBUG
00019 #define WIN32_LEAN_AND_MEAN
00020 #include <windows.h>
00021 #endif
00022 
00023 // Version id
00024 const char XmlRpc::XMLRPC_VERSION[] = "XMLRPC++ 0.7";
00025 
00026 // Default log verbosity: 0 for no messages through 5 (writes everything)
00027 int XmlRpcLogHandler::_verbosity = 0;
00028 
00029 // Default log handler
00030 static class DefaultLogHandler : public XmlRpcLogHandler {
00031 public:
00032 
00033   void log(int level, const char* msg) { 
00034 #ifdef USE_WINDOWS_DEBUG
00035     if (level <= _verbosity) { OutputDebugString(msg); OutputDebugString("\n"); }
00036 #else
00037     if (level <= _verbosity) std::cout << msg << std::endl; 
00038 #endif  
00039   }
00040 
00041 } defaultLogHandler;
00042 
00043 // Message log singleton
00044 XmlRpcLogHandler* XmlRpcLogHandler::_logHandler = &defaultLogHandler;
00045 
00046 
00047 // Default error handler
00048 static class DefaultErrorHandler : public XmlRpcErrorHandler {
00049 public:
00050 
00051   void error(const char* msg) {
00052 #ifdef USE_WINDOWS_DEBUG
00053     OutputDebugString(msg); OutputDebugString("\n");
00054 #else
00055     std::cerr << msg << std::endl; 
00056 #endif  
00057   }
00058 } defaultErrorHandler;
00059 
00060 
00061 // Error handler singleton
00062 XmlRpcErrorHandler* XmlRpcErrorHandler::_errorHandler = &defaultErrorHandler;
00063 
00064 
00065 // Easy API for log verbosity
00066 int XmlRpc::getVerbosity() { return XmlRpcLogHandler::getVerbosity(); }
00067 void XmlRpc::setVerbosity(int level) { XmlRpcLogHandler::setVerbosity(level); }
00068 
00069  
00070 
00071 void XmlRpcUtil::log(int level, const char* fmt, ...)
00072 {
00073   if (level <= XmlRpcLogHandler::getVerbosity())
00074   {
00075     va_list va;
00076     char buf[1024];
00077     va_start( va, fmt);
00078     vsnprintf(buf,sizeof(buf)-1,fmt,va);
00079     buf[sizeof(buf)-1] = 0;
00080     XmlRpcLogHandler::getLogHandler()->log(level, buf);
00081   }
00082 }
00083 
00084 
00085 void XmlRpcUtil::error(const char* fmt, ...)
00086 {
00087   va_list va;
00088   va_start(va, fmt);
00089   char buf[1024];
00090   vsnprintf(buf,sizeof(buf)-1,fmt,va);
00091   buf[sizeof(buf)-1] = 0;
00092   XmlRpcErrorHandler::getErrorHandler()->error(buf);
00093 }
00094 
00095 
00096 // Returns contents between <tag> and </tag>, updates offset to char after </tag>
00097 std::string 
00098 XmlRpcUtil::parseTag(const char* tag, std::string const& xml, int* offset)
00099 {
00100   if (*offset >= int(xml.length())) return std::string();
00101   size_t istart = xml.find(tag, *offset);
00102   if (istart == std::string::npos) return std::string();
00103   istart += strlen(tag);
00104   std::string etag = "</";
00105   etag += tag + 1;
00106   size_t iend = xml.find(etag, istart);
00107   if (iend == std::string::npos) return std::string();
00108 
00109   *offset = int(iend + etag.length());
00110   return xml.substr(istart, iend-istart);
00111 }
00112 
00113 
00114 // Returns true if the tag is found and updates offset to the char after the tag
00115 bool 
00116 XmlRpcUtil::findTag(const char* tag, std::string const& xml, int* offset)
00117 {
00118   if (*offset >= int(xml.length())) return false;
00119   size_t istart = xml.find(tag, *offset);
00120   if (istart == std::string::npos)
00121     return false;
00122 
00123   *offset = int(istart + strlen(tag));
00124   return true;
00125 }
00126 
00127 
00128 // Returns true if the tag is found at the specified offset (modulo any whitespace)
00129 // and updates offset to the char after the tag
00130 bool 
00131 XmlRpcUtil::nextTagIs(const char* tag, std::string const& xml, int* offset)
00132 {
00133   if (*offset >= int(xml.length())) return false;
00134   const char* cp = xml.c_str() + *offset;
00135   int nc = 0;
00136   while (*cp && isspace(*cp)) {
00137     ++cp;
00138     ++nc;
00139   }
00140 
00141   int len = int(strlen(tag));
00142   if  (*cp && (strncmp(cp, tag, len) == 0)) {
00143     *offset += nc + len;
00144     return true;
00145   }
00146   return false;
00147 }
00148 
00149 // Returns the next tag and updates offset to the char after the tag, or empty string
00150 // if the next non-whitespace character is not '<'
00151 std::string 
00152 XmlRpcUtil::getNextTag(std::string const& xml, int* offset)
00153 {
00154   if (*offset >= int(xml.length())) return std::string();
00155 
00156   size_t pos = *offset;
00157   const char* cp = xml.c_str() + pos;
00158   while (*cp && isspace(*cp)) {
00159     ++cp;
00160     ++pos;
00161   }
00162 
00163   if (*cp != '<') return std::string();
00164 
00165   std::string s;
00166   do {
00167     s += *cp;
00168     ++pos;
00169   } while (*cp++ != '>' && *cp != 0);
00170 
00171   *offset = int(pos);
00172   return s;
00173 }
00174 
00175 
00176 
00177 // xml encodings (xml-encoded entities are preceded with '&')
00178 static const char  AMP = '&';
00179 static const char  rawEntity[] = { '<',   '>',   '&',    '\'',    '\"',    0 };
00180 static const char* xmlEntity[] = { "lt;", "gt;", "amp;", "apos;", "quot;", 0 };
00181 static const int   xmlEntLen[] = { 3,     3,     4,      5,       5 };
00182 
00183 
00184 // Replace xml-encoded entities with the raw text equivalents.
00185 
00186 std::string 
00187 XmlRpcUtil::xmlDecode(const std::string& encoded)
00188 {
00189   std::string::size_type iAmp = encoded.find(AMP);
00190   if (iAmp == std::string::npos)
00191     return encoded;
00192 
00193   std::string decoded(encoded, 0, iAmp);
00194   std::string::size_type iSize = encoded.size();
00195   decoded.reserve(iSize);
00196 
00197   const char* ens = encoded.c_str();
00198   while (iAmp != iSize) {
00199     if (encoded[iAmp] == AMP && iAmp+1 < iSize) {
00200       int iEntity;
00201       for (iEntity=0; xmlEntity[iEntity] != 0; ++iEntity)
00202         //if (encoded.compare(iAmp+1, xmlEntLen[iEntity], xmlEntity[iEntity]) == 0)
00203         if (strncmp(ens+iAmp+1, xmlEntity[iEntity], xmlEntLen[iEntity]) == 0)
00204         {
00205           decoded += rawEntity[iEntity];
00206           iAmp += xmlEntLen[iEntity]+1;
00207           break;
00208         }
00209       if (xmlEntity[iEntity] == 0)    // unrecognized sequence
00210         decoded += encoded[iAmp++];
00211 
00212     } else {
00213       decoded += encoded[iAmp++];
00214     }
00215   }
00216     
00217   return decoded;
00218 }
00219 
00220 
00221 // Replace raw text with xml-encoded entities.
00222 
00223 std::string 
00224 XmlRpcUtil::xmlEncode(const std::string& raw)
00225 {
00226   std::string::size_type iRep = raw.find_first_of(rawEntity);
00227   if (iRep == std::string::npos)
00228     return raw;
00229 
00230   std::string encoded(raw, 0, iRep);
00231   std::string::size_type iSize = raw.size();
00232 
00233   while (iRep != iSize) {
00234     int iEntity;
00235     for (iEntity=0; rawEntity[iEntity] != 0; ++iEntity)
00236       if (raw[iRep] == rawEntity[iEntity])
00237       {
00238         encoded += AMP;
00239         encoded += xmlEntity[iEntity];
00240         break;
00241       }
00242     if (rawEntity[iEntity] == 0)
00243       encoded += raw[iRep];
00244     ++iRep;
00245   }
00246   return encoded;
00247 }
00248 
00249 
00250 

Generated on Tue Nov 29 23:14:44 2016 for BOSS_7.0.2 by  doxygen 1.4.7