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  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  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  if (*offset >= int(xml.length())) return std::string();
112  size_t istart = xml.find(tag, *offset);
113  if (istart == std::string::npos) return std::string();
114  istart += strlen(tag);
115  std::string etag = "</";
116  etag += tag + 1;
117  size_t iend = xml.find(etag, istart);
118  if (iend == std::string::npos) return std::string();
119 
120  *offset = int(iend + etag.length());
121  return xml.substr(istart, iend-istart);
122 }
123 
124 
125 // Returns true if the tag is found and updates offset to the char after the tag
126 bool
127 XmlRpcUtil::findTag(const char* tag, std::string const& xml, int* offset)
128 {
129  if (*offset >= int(xml.length())) return false;
130  size_t istart = xml.find(tag, *offset);
131  if (istart == std::string::npos)
132  return false;
133 
134  *offset = int(istart + strlen(tag));
135  return true;
136 }
137 
138 
139 // Returns true if the tag is found at the specified offset (modulo any whitespace)
140 // and updates offset to the char after the tag
141 bool
142 XmlRpcUtil::nextTagIs(const char* tag, std::string const& xml, int* offset)
143 {
144  if (*offset >= int(xml.length())) return false;
145  const char* cp = xml.c_str() + *offset;
146  int nc = 0;
147  while (*cp && isspace(*cp)) {
148  ++cp;
149  ++nc;
150  }
151 
152  int len = int(strlen(tag));
153  if (*cp && (strncmp(cp, tag, len) == 0)) {
154  *offset += nc + len;
155  return true;
156  }
157  return false;
158 }
159 
160 // Returns the next tag and updates offset to the char after the tag, or empty string
161 // if the next non-whitespace character is not '<'
162 std::string
163 XmlRpcUtil::getNextTag(std::string const& xml, int* offset)
164 {
165  if (*offset >= int(xml.length())) return std::string();
166 
167  size_t pos = *offset;
168  const char* cp = xml.c_str() + pos;
169  while (*cp && isspace(*cp)) {
170  ++cp;
171  ++pos;
172  }
173 
174  if (*cp != '<') return std::string();
175 
176  std::string s;
177  do {
178  s += *cp;
179  ++pos;
180  } while (*cp++ != '>' && *cp != 0);
181 
182  *offset = int(pos);
183  return s;
184 }
185 
186 
187 
188 // xml encodings (xml-encoded entities are preceded with '&')
189 static const char AMP = '&';
190 static const char rawEntity[] = { '<', '>', '&', '\'', '\"', 0 };
191 static const char* xmlEntity[] = { "lt;", "gt;", "amp;", "apos;", "quot;", 0 };
192 static const int xmlEntLen[] = { 3, 3, 4, 5, 5 };
193 
194 
195 // Replace xml-encoded entities with the raw text equivalents.
196 
197 std::string
198 XmlRpcUtil::xmlDecode(const std::string& encoded)
199 {
200  std::string::size_type iAmp = encoded.find(AMP);
201  if (iAmp == std::string::npos)
202  return encoded;
203 
204  std::string decoded(encoded, 0, iAmp);
205  std::string::size_type iSize = encoded.size();
206  decoded.reserve(iSize);
207 
208  const char* ens = encoded.c_str();
209  while (iAmp != iSize) {
210  if (encoded[iAmp] == AMP && iAmp+1 < iSize) {
211  int iEntity;
212  for (iEntity=0; xmlEntity[iEntity] != 0; ++iEntity)
213  //if (encoded.compare(iAmp+1, xmlEntLen[iEntity], xmlEntity[iEntity]) == 0)
214  if (strncmp(ens+iAmp+1, xmlEntity[iEntity], xmlEntLen[iEntity]) == 0)
215  {
216  decoded += rawEntity[iEntity];
217  iAmp += xmlEntLen[iEntity]+1;
218  break;
219  }
220  if (xmlEntity[iEntity] == 0) // unrecognized sequence
221  decoded += encoded[iAmp++];
222 
223  } else {
224  decoded += encoded[iAmp++];
225  }
226  }
227 
228  return decoded;
229 }
230 
231 
232 // Replace raw text with xml-encoded entities.
233 
234 std::string
235 XmlRpcUtil::xmlEncode(const std::string& raw)
236 {
237  std::string::size_type iRep = raw.find_first_of(rawEntity);
238  if (iRep == std::string::npos)
239  return raw;
240 
241  std::string encoded(raw, 0, iRep);
242  std::string::size_type iSize = raw.size();
243 
244  while (iRep != iSize) {
245  int iEntity;
246  for (iEntity=0; rawEntity[iEntity] != 0; ++iEntity)
247  if (raw[iRep] == rawEntity[iEntity])
248  {
249  encoded += AMP;
250  encoded += xmlEntity[iEntity];
251  break;
252  }
253  if (rawEntity[iEntity] == 0)
254  encoded += raw[iRep];
255  ++iRep;
256  }
257  return encoded;
258 }
259 
260 
261 
static XmlRpcLogHandler * getLogHandler()
Returns a pointer to the currently installed message reporting object.
Definition: XmlRpcUtil.h:54
void log(int level, const char *msg)
Output a message. Custom error handlers should define this method.
Definition: XmlRpcUtil.cpp:33
const char XMLRPC_VERSION[]
Version identifier.
Definition: XmlRpcUtil.cpp:24
static XmlRpcErrorHandler * _errorHandler
Definition: XmlRpcUtil.h:45
static int getVerbosity()
Returns the level of verbosity of informational messages. 0 is no output, 5 is very verbose...
Definition: XmlRpcUtil.h:62
static const char rawEntity[]
Definition: XmlRpcUtil.cpp:190
static std::string getNextTag(std::string const &xml, int *offset)
Definition: XmlRpcUtil.cpp:163
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:66
static XmlRpcErrorHandler * getErrorHandler()
Returns a pointer to the currently installed error handling object.
Definition: XmlRpcUtil.h:34
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:127
virtual void error(const char *msg)=0
Report an error. Custom error handlers should define this method.
int getVerbosity()
Returns log message verbosity. This is short for XmlRpcLogHandler::getVerbosity() ...
Definition: XmlRpcUtil.cpp:75
static const char AMP
Definition: XmlRpcUtil.cpp:189
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:49
static XmlRpcLogHandler * _logHandler
Definition: XmlRpcUtil.h:73
DefaultLogHandler defaultLogHandler
static std::string xmlEncode(const std::string &raw)
Convert raw text to encoded xml.
Definition: XmlRpcUtil.cpp:235
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:192
static std::string xmlDecode(const std::string &encoded)
Convert encoded xml to raw text.
Definition: XmlRpcUtil.cpp:198
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:142
static const char * xmlEntity[]
Definition: XmlRpcUtil.cpp:191
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:29


xmlrpcpp
Author(s): Chris Morley, Konstantin Pilipchuk, Morgan Quigley, Austin Hendrix
autogenerated on Sun Feb 3 2019 03:29:51