XmlRpcUtil.cpp
Go to the documentation of this file.
1 
2 #include "xmlrpcpp/XmlRpcUtil.h"
3 
4 #ifndef MAKEDEPEND
5 # include <ctype.h>
6 # include <iostream>
7 # include <stdarg.h>
8 # include <stdio.h>
9 # include <string.h>
10 # include <climits>
11 #endif
12 
13 #include "xmlrpcpp/XmlRpc.h"
14 
15 using namespace XmlRpc;
16 
17 
18 //#define USE_WINDOWS_DEBUG // To make the error and log messages go to VC++ debug output
19 #ifdef USE_WINDOWS_DEBUG
20 #define WIN32_LEAN_AND_MEAN
21 #include <windows.h>
22 #endif
23 
24 // Version id
25 const char XmlRpc::XMLRPC_VERSION[] = "XMLRPC++ 0.7";
26 
27 // Default log verbosity: 0 for no messages through 5 (writes everything)
29 
30 // Default log handler
31 static class DefaultLogHandler : public XmlRpcLogHandler {
32 public:
33 
34  void log(int level, const char* msg) {
35 #ifdef USE_WINDOWS_DEBUG
36  if (level <= _verbosity) { OutputDebugString(msg); OutputDebugString("\n"); }
37 #else
38  if (level <= _verbosity) std::cout << msg << std::endl;
39 #endif
40  }
41 
43 
44 // Message log singleton
46 
47 
48 // Default error handler
49 static class DefaultErrorHandler : public XmlRpcErrorHandler {
50 public:
51 
52 #ifdef USE_WINDOWS_DEBUG
53  void error(const char* msg) {
54  OutputDebugString(msg); OutputDebugString("\n");
55 #else
56  void error(const char*) {
57 #endif
58  // As far as I can tell, throwing an exception here is a bug, unless
59  // the intention is that the program should exit. Throughout the code,
60  // calls to error() are followed by cleanup code that does things like
61  // closing a failed socket. Thus it would seem that it should be
62  // possible to continue execution. But if the user just catches the
63  // exception that's thrown here, the library ends up in a bogus state.
64  // So I'm commenting out the throw. - BPG
65  //
66  //throw std::runtime_error(msg);
67  }
69 
70 
71 // Error handler singleton
73 
74 
75 // Easy API for log verbosity
78 
79 
80 
81 void XmlRpcUtil::log(int level, const char* fmt, ...)
82 {
83  if (level <= XmlRpcLogHandler::getVerbosity())
84  {
85  va_list va;
86  char buf[1024];
87  va_start( va, fmt);
88  std::vsnprintf(buf,sizeof(buf)-1,fmt,va);
89  va_end(va);
90  buf[sizeof(buf)-1] = 0;
91  XmlRpcLogHandler::getLogHandler()->log(level, buf);
92  }
93 }
94 
95 
96 void XmlRpcUtil::error(const char* fmt, ...)
97 {
98  va_list va;
99  va_start(va, fmt);
100  char buf[1024];
101  std::vsnprintf(buf,sizeof(buf)-1,fmt,va);
102  va_end(va);
103  buf[sizeof(buf)-1] = 0;
105 }
106 
107 
108 // Returns contents between <tag> and </tag>, updates offset to char after </tag>
109 std::string
110 XmlRpcUtil::parseTag(const char* tag, std::string const& xml, int* offset)
111 {
112  // avoid attempting to parse overly long xml input
113  if (xml.length() > size_t(INT_MAX)) return std::string();
114  if (*offset >= int(xml.length())) return std::string();
115  size_t istart = xml.find(tag, *offset);
116  if (istart == std::string::npos) return std::string();
117  istart += strlen(tag);
118  std::string etag = "</";
119  etag += tag + 1;
120  size_t iend = xml.find(etag, istart);
121  if (iend == std::string::npos) return std::string();
122 
123  *offset = int(iend + etag.length());
124  return xml.substr(istart, iend-istart);
125 }
126 
127 
128 // Returns true if the tag is found and updates offset to the char after the tag
129 bool
130 XmlRpcUtil::findTag(const char* tag, std::string const& xml, int* offset)
131 {
132  if (xml.length() > size_t(INT_MAX)) return false;
133  if (*offset >= int(xml.length())) return false;
134  size_t istart = xml.find(tag, *offset);
135  if (istart == std::string::npos)
136  return false;
137 
138  *offset = int(istart + strlen(tag));
139  return true;
140 }
141 
142 
143 // Returns true if the tag is found at the specified offset (modulo any whitespace)
144 // and updates offset to the char after the tag
145 bool
146 XmlRpcUtil::nextTagIs(const char* tag, std::string const& xml, int* offset)
147 {
148  if (xml.length() > size_t(INT_MAX)) return false;
149  if (*offset >= int(xml.length())) return false;
150  const char* cp = xml.c_str() + *offset;
151  int nc = 0;
152  while (*cp && isspace(*cp)) {
153  ++cp;
154  ++nc;
155  }
156 
157  int len = int(strlen(tag));
158  if (*cp && (strncmp(cp, tag, len) == 0)) {
159  *offset += nc + len;
160  return true;
161  }
162  return false;
163 }
164 
165 // Returns the next tag and updates offset to the char after the tag, or empty string
166 // if the next non-whitespace character is not '<'
167 std::string
168 XmlRpcUtil::getNextTag(std::string const& xml, int* offset)
169 {
170  if (xml.length() > size_t(INT_MAX)) return std::string();
171  if (*offset >= int(xml.length())) return std::string();
172 
173  size_t pos = *offset;
174  const char* cp = xml.c_str() + pos;
175  while (*cp && isspace(*cp)) {
176  ++cp;
177  ++pos;
178  }
179 
180  if (*cp != '<') return std::string();
181 
182  std::string s;
183  do {
184  s += *cp;
185  ++pos;
186  } while (*cp++ != '>' && *cp != 0);
187 
188  *offset = int(pos);
189  return s;
190 }
191 
192 
193 
194 // xml encodings (xml-encoded entities are preceded with '&')
195 static const char AMP = '&';
196 static const char rawEntity[] = { '<', '>', '&', '\'', '\"', 0 };
197 static const char* xmlEntity[] = { "lt;", "gt;", "amp;", "apos;", "quot;", 0 };
198 static const int xmlEntLen[] = { 3, 3, 4, 5, 5 };
199 
200 
201 // Replace xml-encoded entities with the raw text equivalents.
202 
203 std::string
204 XmlRpcUtil::xmlDecode(const std::string& encoded)
205 {
206  std::string::size_type iAmp = encoded.find(AMP);
207  if (iAmp == std::string::npos)
208  return encoded;
209 
210  std::string decoded(encoded, 0, iAmp);
211  std::string::size_type iSize = encoded.size();
212  decoded.reserve(iSize);
213 
214  const char* ens = encoded.c_str();
215  while (iAmp != iSize) {
216  if (encoded[iAmp] == AMP && iAmp+1 < iSize) {
217  int iEntity;
218  for (iEntity=0; xmlEntity[iEntity] != 0; ++iEntity)
219  //if (encoded.compare(iAmp+1, xmlEntLen[iEntity], xmlEntity[iEntity]) == 0)
220  if (strncmp(ens+iAmp+1, xmlEntity[iEntity], xmlEntLen[iEntity]) == 0)
221  {
222  decoded += rawEntity[iEntity];
223  iAmp += xmlEntLen[iEntity]+1;
224  break;
225  }
226  if (xmlEntity[iEntity] == 0) // unrecognized sequence
227  decoded += encoded[iAmp++];
228 
229  } else {
230  decoded += encoded[iAmp++];
231  }
232  }
233 
234  return decoded;
235 }
236 
237 
238 // Replace raw text with xml-encoded entities.
239 
240 std::string
241 XmlRpcUtil::xmlEncode(const std::string& raw)
242 {
243  std::string::size_type iRep = raw.find_first_of(rawEntity);
244  if (iRep == std::string::npos)
245  return raw;
246 
247  std::string encoded(raw, 0, iRep);
248  std::string::size_type iSize = raw.size();
249 
250  while (iRep != iSize) {
251  int iEntity;
252  for (iEntity=0; rawEntity[iEntity] != 0; ++iEntity)
253  if (raw[iRep] == rawEntity[iEntity])
254  {
255  encoded += AMP;
256  encoded += xmlEntity[iEntity];
257  break;
258  }
259  if (rawEntity[iEntity] == 0)
260  encoded += raw[iRep];
261  ++iRep;
262  }
263  return encoded;
264 }
265 
266 
267 
XmlRpc::setVerbosity
XMLRPCPP_DECL void setVerbosity(int level)
Sets log message verbosity. This is short for XmlRpcLogHandler::setVerbosity(level)
Definition: XmlRpcUtil.cpp:77
defaultErrorHandler
DefaultErrorHandler defaultErrorHandler
XmlRpc::XmlRpcLogHandler
An interface allowing custom handling of informational message reporting.
Definition: XmlRpcUtil.h:47
XmlRpc::XmlRpcUtil::xmlEncode
static std::string xmlEncode(const std::string &raw)
Convert raw text to encoded xml.
Definition: XmlRpcUtil.cpp:241
s
XmlRpcServer s
Definition: HelloServer.cpp:11
DefaultLogHandler::log
void log(int level, const char *msg)
Output a message. Custom error handlers should define this method.
Definition: XmlRpcUtil.cpp:34
XmlRpc::XmlRpcUtil::log
static void log(int level, const char *fmt,...)
Dump messages somewhere.
Definition: XmlRpcUtil.cpp:81
XmlRpc::getVerbosity
XMLRPCPP_DECL int getVerbosity()
Returns log message verbosity. This is short for XmlRpcLogHandler::getVerbosity()
Definition: XmlRpcUtil.cpp:76
XmlRpc
Definition: XmlRpcClient.h:20
XmlRpc::XmlRpcLogHandler::getLogHandler
static XmlRpcLogHandler * getLogHandler()
Returns a pointer to the currently installed message reporting object.
Definition: XmlRpcUtil.h:52
xmlEntLen
static const int xmlEntLen[]
Definition: XmlRpcUtil.cpp:198
XmlRpc::XmlRpcUtil::parseTag
static std::string parseTag(const char *tag, std::string const &xml, int *offset)
Returns contents between <tag> and </tag>, updates offset to char after </tag>
Definition: XmlRpcUtil.cpp:110
DefaultLogHandler
Definition: XmlRpcUtil.cpp:31
XmlRpc::XmlRpcUtil::findTag
static bool findTag(const char *tag, std::string const &xml, int *offset)
Returns true if the tag is found and updates offset to the char after the tag.
Definition: XmlRpcUtil.cpp:130
xmlEntity
static const char * xmlEntity[]
Definition: XmlRpcUtil.cpp:197
XmlRpc::XmlRpcLogHandler::setVerbosity
static void setVerbosity(int v)
Specify the level of verbosity of informational messages. 0 is no output, 5 is very verbose.
Definition: XmlRpcUtil.h:64
XmlRpc::XmlRpcErrorHandler::_errorHandler
static XMLRPCPP_DECL XmlRpcErrorHandler * _errorHandler
Definition: XmlRpcUtil.h:43
DefaultErrorHandler::error
void error(const char *)
Report an error. Custom error handlers should define this method.
Definition: XmlRpcUtil.cpp:56
XmlRpc::XmlRpcErrorHandler::error
virtual void error(const char *msg)=0
Report an error. Custom error handlers should define this method.
XmlRpc::XmlRpcErrorHandler
An interface allowing custom handling of error message reporting.
Definition: XmlRpcUtil.h:27
XmlRpc::XmlRpcUtil::nextTagIs
static bool nextTagIs(const char *tag, std::string const &xml, int *offset)
Definition: XmlRpcUtil.cpp:146
DefaultErrorHandler
Definition: XmlRpcUtil.cpp:49
XmlRpc::XmlRpcUtil::error
static void error(const char *fmt,...)
Dump error messages somewhere.
Definition: XmlRpcUtil.cpp:96
XmlRpc.h
XmlRpc::XmlRpcUtil::xmlDecode
static std::string xmlDecode(const std::string &encoded)
Convert encoded xml to raw text.
Definition: XmlRpcUtil.cpp:204
rawEntity
static const char rawEntity[]
Definition: XmlRpcUtil.cpp:196
defaultLogHandler
DefaultLogHandler defaultLogHandler
XmlRpc::XmlRpcLogHandler::_verbosity
static XMLRPCPP_DECL int _verbosity
Definition: XmlRpcUtil.h:72
XmlRpc::XMLRPC_VERSION
const XMLRPCPP_DECL char XMLRPC_VERSION[]
Version identifier.
Definition: XmlRpcUtil.cpp:25
XmlRpc::XmlRpcErrorHandler::getErrorHandler
static XmlRpcErrorHandler * getErrorHandler()
Returns a pointer to the currently installed error handling object.
Definition: XmlRpcUtil.h:32
XmlRpc::XmlRpcLogHandler::_logHandler
static XMLRPCPP_DECL XmlRpcLogHandler * _logHandler
Definition: XmlRpcUtil.h:71
XmlRpcUtil.h
AMP
static const char AMP
Definition: XmlRpcUtil.cpp:195
XmlRpc::XmlRpcLogHandler::log
virtual void log(int level, const char *msg)=0
Output a message. Custom error handlers should define this method.
XmlRpc::XmlRpcUtil::getNextTag
static std::string getNextTag(std::string const &xml, int *offset)
Definition: XmlRpcUtil.cpp:168
XmlRpc::XmlRpcLogHandler::getVerbosity
static int getVerbosity()
Returns the level of verbosity of informational messages. 0 is no output, 5 is very verbose.
Definition: XmlRpcUtil.h:60


xmlrpcpp
Author(s): Chris Morley, Konstantin Pilipchuk, Morgan Quigley, Austin Hendrix, Dirk Thomas
autogenerated on Fri Jul 2 2021 03:00:11