BOSS 8.0.0
BESIII Offline Software System
Loading...
Searching...
No Matches
XmlRpcUtil.cpp
Go to the documentation of this file.
1
2#include "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 "XmlRpc.h"
13
14using namespace XmlRpc;
15
16// #define USE_WINDOWS_DEBUG // To make the error and log messages go to VC++ debug output
17#ifdef USE_WINDOWS_DEBUG
18# define WIN32_LEAN_AND_MEAN
19# include <windows.h>
20#endif
21
22// Version id
23const char XmlRpc::XMLRPC_VERSION[] = "XMLRPC++ 0.7";
24
25// Default log verbosity: 0 for no messages through 5 (writes everything)
27
28// Default log handler
29static class DefaultLogHandler : public XmlRpcLogHandler {
30public:
31 void log( int level, const char* msg ) {
32#ifdef USE_WINDOWS_DEBUG
33 if ( level <= _verbosity )
34 {
35 OutputDebugString( msg );
36 OutputDebugString( "\n" );
37 }
38#else
39 if ( level <= _verbosity ) std::cout << msg << std::endl;
40#endif
41 }
42
43} defaultLogHandler;
44
45// Message log singleton
47
48// Default error handler
49static class DefaultErrorHandler : public XmlRpcErrorHandler {
50public:
51 void error( const char* msg ) {
52#ifdef USE_WINDOWS_DEBUG
53 OutputDebugString( msg );
54 OutputDebugString( "\n" );
55#else
56 std::cerr << msg << std::endl;
57#endif
58 }
59} defaultErrorHandler;
60
61// Error handler singleton
63
64// Easy API for log verbosity
67
68void XmlRpcUtil::log( int level, const char* fmt, ... ) {
69 if ( level <= XmlRpcLogHandler::getVerbosity() )
70 {
71 va_list va;
72 char buf[1024];
73 va_start( va, fmt );
74 vsnprintf( buf, sizeof( buf ) - 1, fmt, va );
75 buf[sizeof( buf ) - 1] = 0;
76 XmlRpcLogHandler::getLogHandler()->log( level, buf );
77 }
78}
79
80void XmlRpcUtil::error( const char* fmt, ... ) {
81 va_list va;
82 va_start( va, fmt );
83 char buf[1024];
84 vsnprintf( buf, sizeof( buf ) - 1, fmt, va );
85 buf[sizeof( buf ) - 1] = 0;
87}
88
89// Returns contents between <tag> and </tag>, updates offset to char after </tag>
90std::string XmlRpcUtil::parseTag( const char* tag, std::string const& xml, int* offset ) {
91 if ( *offset >= int( xml.length() ) ) return std::string();
92 size_t istart = xml.find( tag, *offset );
93 if ( istart == std::string::npos ) return std::string();
94 istart += strlen( tag );
95 std::string etag = "</";
96 etag += tag + 1;
97 size_t iend = xml.find( etag, istart );
98 if ( iend == std::string::npos ) return std::string();
99
100 *offset = int( iend + etag.length() );
101 return xml.substr( istart, iend - istart );
102}
103
104// Returns true if the tag is found and updates offset to the char after the tag
105bool XmlRpcUtil::findTag( const char* tag, std::string const& xml, int* offset ) {
106 if ( *offset >= int( xml.length() ) ) return false;
107 size_t istart = xml.find( tag, *offset );
108 if ( istart == std::string::npos ) return false;
109
110 *offset = int( istart + strlen( tag ) );
111 return true;
112}
113
114// Returns true if the tag is found at the specified offset (modulo any whitespace)
115// and updates offset to the char after the tag
116bool XmlRpcUtil::nextTagIs( const char* tag, std::string const& xml, int* offset ) {
117 if ( *offset >= int( xml.length() ) ) return false;
118 const char* cp = xml.c_str() + *offset;
119 int nc = 0;
120 while ( *cp && isspace( *cp ) )
121 {
122 ++cp;
123 ++nc;
124 }
125
126 int len = int( strlen( tag ) );
127 if ( *cp && ( strncmp( cp, tag, len ) == 0 ) )
128 {
129 *offset += nc + len;
130 return true;
131 }
132 return false;
133}
134
135// Returns the next tag and updates offset to the char after the tag, or empty string
136// if the next non-whitespace character is not '<'
137std::string XmlRpcUtil::getNextTag( std::string const& xml, int* offset ) {
138 if ( *offset >= int( xml.length() ) ) return std::string();
139
140 size_t pos = *offset;
141 const char* cp = xml.c_str() + pos;
142 while ( *cp && isspace( *cp ) )
143 {
144 ++cp;
145 ++pos;
146 }
147
148 if ( *cp != '<' ) return std::string();
149
150 std::string s;
151 do {
152 s += *cp;
153 ++pos;
154 } while ( *cp++ != '>' && *cp != 0 );
155
156 *offset = int( pos );
157 return s;
158}
159
160// xml encodings (xml-encoded entities are preceded with '&')
161static const char AMP = '&';
162static const char rawEntity[] = { '<', '>', '&', '\'', '\"', 0 };
163static const char* xmlEntity[] = { "lt;", "gt;", "amp;", "apos;", "quot;", 0 };
164static const int xmlEntLen[] = { 3, 3, 4, 5, 5 };
165
166// Replace xml-encoded entities with the raw text equivalents.
167
168std::string XmlRpcUtil::xmlDecode( const std::string& encoded ) {
169 std::string::size_type iAmp = encoded.find( AMP );
170 if ( iAmp == std::string::npos ) return encoded;
171
172 std::string decoded( encoded, 0, iAmp );
173 std::string::size_type iSize = encoded.size();
174 decoded.reserve( iSize );
175
176 const char* ens = encoded.c_str();
177 while ( iAmp != iSize )
178 {
179 if ( encoded[iAmp] == AMP && iAmp + 1 < iSize )
180 {
181 int iEntity;
182 for ( iEntity = 0; xmlEntity[iEntity] != 0; ++iEntity )
183 // if (encoded.compare(iAmp+1, xmlEntLen[iEntity], xmlEntity[iEntity]) == 0)
184 if ( strncmp( ens + iAmp + 1, xmlEntity[iEntity], xmlEntLen[iEntity] ) == 0 )
185 {
186 decoded += rawEntity[iEntity];
187 iAmp += xmlEntLen[iEntity] + 1;
188 break;
189 }
190 if ( xmlEntity[iEntity] == 0 ) // unrecognized sequence
191 decoded += encoded[iAmp++];
192 }
193 else { decoded += encoded[iAmp++]; }
194 }
195
196 return decoded;
197}
198
199// Replace raw text with xml-encoded entities.
200
201std::string XmlRpcUtil::xmlEncode( const std::string& raw ) {
202 std::string::size_type iRep = raw.find_first_of( rawEntity );
203 if ( iRep == std::string::npos ) return raw;
204
205 std::string encoded( raw, 0, iRep );
206 std::string::size_type iSize = raw.size();
207
208 while ( iRep != iSize )
209 {
210 int iEntity;
211 for ( iEntity = 0; rawEntity[iEntity] != 0; ++iEntity )
212 if ( raw[iRep] == rawEntity[iEntity] )
213 {
214 encoded += AMP;
215 encoded += xmlEntity[iEntity];
216 break;
217 }
218 if ( rawEntity[iEntity] == 0 ) encoded += raw[iRep];
219 ++iRep;
220 }
221 return encoded;
222}
XmlRpcServer s
An interface allowing custom handling of error message reporting.
Definition XmlRpc.h:38
static XmlRpcErrorHandler * getErrorHandler()
Returns a pointer to the currently installed error handling object.
Definition XmlRpc.h:41
virtual void error(const char *msg)=0
Report an error. Custom error handlers should define this method.
static XmlRpcErrorHandler * _errorHandler
Definition XmlRpc.h:50
An interface allowing custom handling of informational message reporting.
Definition XmlRpc.h:54
static int _verbosity
Definition XmlRpc.h:75
static XmlRpcLogHandler * getLogHandler()
Returns a pointer to the currently installed message reporting object.
Definition XmlRpc.h:57
virtual void log(int level, const char *msg)=0
Output a message. Custom error handlers should define this method.
static int getVerbosity()
Definition XmlRpc.h:64
static void setVerbosity(int v)
Definition XmlRpc.h:68
static XmlRpcLogHandler * _logHandler
Definition XmlRpc.h:74
static bool nextTagIs(const char *tag, std::string const &xml, int *offset)
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>.
static void error(const char *fmt,...)
Dump error messages somewhere.
static std::string xmlEncode(const std::string &raw)
Convert raw text to encoded xml.
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.
static void log(int level, const char *fmt,...)
Dump messages somewhere.
static std::string getNextTag(std::string const &xml, int *offset)
static std::string xmlDecode(const std::string &encoded)
Convert encoded xml to raw text.
int getVerbosity()
Returns log message verbosity. This is short for XmlRpcLogHandler::getVerbosity().
const char XMLRPC_VERSION[]
Version identifier.
void setVerbosity(int level)
Sets log message verbosity. This is short for XmlRpcLogHandler::setVerbosity(level).