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


xmlrpcpp
Author(s): Chris Morley, Konstantin Pilipchuk, Morgan Quigley, Austin Hendrix, Dirk Thomas
autogenerated on Mon Oct 19 2020 03:23:56