PTLib  Version 2.14.3
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
pxmlrpc.h
Go to the documentation of this file.
1 /*
2  * pxmlrpc.h
3  *
4  * XML/RPC support
5  *
6  * Portable Windows Library
7  *
8  * Copyright (c) 2002 Equivalence Pty. Ltd.
9  *
10  * The contents of this file are subject to the Mozilla Public License
11  * Version 1.0 (the "License"); you may not use this file except in
12  * compliance with the License. You may obtain a copy of the License at
13  * http://www.mozilla.org/MPL/
14  *
15  * Software distributed under the License is distributed on an "AS IS"
16  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
17  * the License for the specific language governing rights and limitations
18  * under the License.
19  *
20  * The Original Code is Portable Windows Library.
21  *
22  * The Initial Developer of the Original Code is Equivalence Pty. Ltd.
23  *
24  * Contributor(s): ______________________________________.
25  *
26  * $Revision: 28522 $
27  * $Author: rjongbloed $
28  * $Date: 2012-11-16 11:31:31 +1100 (Fri, 16 Nov 2012) $
29  */
30 
31 #ifndef PTLIB_PXMLRPC_H
32 #define PTLIB_PXMLRPC_H
33 
34 #ifdef P_USE_PRAGMA
35 #pragma interface
36 #endif
37 
38 #include <ptclib/pxml.h>
39 
40 #if P_XMLRPC
41 
42 #include <ptclib/url.h>
43 
44 
45 class PXMLRPCBlock;
47 class PXMLRPCStructBase;
48 
49 
51 
52 class PXMLRPC : public PObject
53 {
54  PCLASSINFO(PXMLRPC, PObject);
55  public:
56  enum {
77 
78  UserFault = 1000,
79  };
80 
81  PXMLRPC(
82  const PURL & url,
83  PXML::Options options = PXML::NoOptions
84  );
85 
86  void SetTimeout(const PTimeInterval & t) { m_timeout = t; }
87 
88  PBoolean MakeRequest(const PString & method);
89  PBoolean MakeRequest(const PString & method, PXMLRPCBlock & response);
90  PBoolean MakeRequest(PXMLRPCBlock & request, PXMLRPCBlock & response);
91  PBoolean MakeRequest(const PString & method, const PXMLRPCStructBase & args, PXMLRPCStructBase & reply);
92 
93  PString GetFaultText() const { return m_faultText; }
94  PINDEX GetFaultCode() const { return m_faultCode; }
95 
96  static PBoolean ISO8601ToPTime(const PString & iso8601, PTime & val, int tz = PTime::GMT);
97  static PString PTimeToISO8601(const PTime & val);
98 
99  protected:
100  PBoolean PerformRequest(PXMLRPCBlock & request, PXMLRPCBlock & response);
101 
103  PINDEX m_faultCode;
106  PXML::Options m_options;
107 };
108 
110 
111 class PXMLRPCBlock : public PXML
112 {
113  PCLASSINFO(PXMLRPCBlock, PXML);
114  public:
115  PXMLRPCBlock();
116  PXMLRPCBlock(const PString & method);
117  PXMLRPCBlock(const PString & method, const PXMLRPCStructBase & structData);
118 
120  PXMLElement * GetParam(PINDEX idx) const;
121  PINDEX GetParamCount() const;
122 
123  // used when used as a response
124  PINDEX GetFaultCode() const { return m_faultCode; }
125  PString GetFaultText() const { return m_faultText; }
126  void SetFault(PINDEX code, const PString & text) { m_faultCode = code; m_faultText = text; }
128 
129  // helper functions for getting parameters
131  PBoolean GetParam(PINDEX idx, PString & type, PString & result);
132  PBoolean GetExpectedParam(PINDEX idx, const PString & expectedType, PString & value);
133 
134  PBoolean GetParam(PINDEX idx, PString & result);
135  PBoolean GetParam(PINDEX idx, int & result);
136  PBoolean GetParam(PINDEX idx, double & result);
137  PBoolean GetParam(PINDEX idx, PTime & result, int tz = PTime::GMT);
138  PBoolean GetParam(PINDEX idx, PStringToString & result);
139  PBoolean GetParam(PINDEX idx, PXMLRPCStructBase & result);
140  PBoolean GetParam(PINDEX idx, PStringArray & result);
141  PBoolean GetParam(PINDEX idx, PArray<PStringToString> & result);
142 
143  // functions for parsing values
144  PBoolean ParseScalar(PXMLElement * element, PString & type, PString & value);
145  PBoolean ParseStruct(PXMLElement * element, PStringToString & structDict);
146  PBoolean ParseStruct(PXMLElement * element, PXMLRPCStructBase & structData);
147  PBoolean ParseArray(PXMLElement * element, PStringArray & array);
150 
151  // functions for creating values
153  PXMLElement * CreateScalar(const PString & type, const PString & scalar);
154  PXMLElement * CreateMember(const PString & name, PXMLElement * value);
155 
156  PXMLElement * CreateScalar(const PString & str);
157  PXMLElement * CreateScalar(int value);
158  PXMLElement * CreateScalar(double value);
159  PXMLElement * CreateDateAndTime(const PTime & time);
160  PXMLElement * CreateBinary(const PBYTEArray & data);
161 
163  PXMLElement * CreateStruct(const PStringToString & dict);
164  PXMLElement * CreateStruct(const PStringToString & dict, const PString & typeStr);
165  PXMLElement * CreateStruct(const PXMLRPCStructBase & structData);
166 
167  PXMLElement * CreateArray(PXMLElement * & data);
168  PXMLElement * CreateArray(const PStringArray & array);
169  PXMLElement * CreateArray(const PStringArray & array, const PString & typeStr);
170  PXMLElement * CreateArray(const PStringArray & array, const PStringArray & types);
173 
174  // helper functions for adding parameters
175  void AddParam(PXMLElement * parm);
176  void AddParam(const PString & str);
177  void AddParam(int value);
178  void AddParam(double value);
179  void AddParam(const PTime & time);
180  void AddParam(const PXMLRPCStructBase & structData);
181  void AddBinary(const PBYTEArray & data);
182  void AddStruct(const PStringToString & dict);
183  void AddStruct(const PStringToString & dict, const PString & typeStr);
184  void AddArray(const PStringArray & array);
185  void AddArray(const PStringArray & array, const PString & typeStr);
186  void AddArray(const PStringArray & array, const PStringArray & types);
187  void AddArray(const PArray<PStringToString> & array);
188 
189  protected:
192  PINDEX m_faultCode;
193 };
194 
195 
197 
198 class PXMLRPCVariableBase : public PObject {
199  PCLASSINFO(PXMLRPCVariableBase, PObject);
200  protected:
201  PXMLRPCVariableBase(const char * name, const char * type = NULL);
202 
203  public:
204  const char * GetName() const { return m_name; }
205  const char * GetType() const { return m_type; }
206 
207  virtual void Copy(const PXMLRPCVariableBase & other) = 0;
208  virtual PString ToString(PINDEX i) const;
209  virtual void FromString(PINDEX i, const PString & str);
210  virtual PXMLRPCStructBase * GetStruct(PINDEX i) const;
211  virtual PBoolean IsArray() const;
212  virtual PINDEX GetSize() const;
213  virtual PBoolean SetSize(PINDEX);
214 
215  PString ToBase64(PAbstractArray & data) const;
216  void FromBase64(const PString & str, PAbstractArray & data);
217 
218  protected:
219  const char * m_name;
220  const char * m_type;
221 
222  private:
224 };
225 
226 
229  protected:
230  PXMLRPCArrayBase(PContainer & array, const char * name, const char * type);
232 
233  public:
234  virtual void PrintOn(ostream & strm) const;
235  virtual void Copy(const PXMLRPCVariableBase & other);
236  virtual PBoolean IsArray() const;
237  virtual PINDEX GetSize() const;
238  virtual PBoolean SetSize(PINDEX);
239 
240  protected:
242 };
243 
244 
247  protected:
248  PXMLRPCArrayObjectsBase(PArrayObjects & array, const char * name, const char * type);
250 
251  public:
252  virtual PString ToString(PINDEX i) const;
253  virtual void FromString(PINDEX i, const PString & str);
254  virtual PBoolean SetSize(PINDEX);
255 
256  virtual PObject * CreateObject() const = 0;
257 
258  protected:
260 };
261 
262 
263 class PXMLRPCStructBase : public PObject {
264  PCLASSINFO(PXMLRPCStructBase, PObject);
265  protected:
268  private:
270 
271  public:
272  void PrintOn(ostream & strm) const;
273 
274  PINDEX GetNumVariables() const { return variablesByOrder.GetSize(); }
275  PXMLRPCVariableBase & GetVariable(PINDEX idx) const { return variablesByOrder[idx]; }
276  PXMLRPCVariableBase * GetVariable(const char * name) const { return variablesByName.GetAt(name); }
277 
278  void AddVariable(PXMLRPCVariableBase * var);
280 
281  protected:
282  void EndConstructor();
283 
286 
290 };
291 
292 
293 #define PXMLRPC_STRUCT_BEGIN(name) \
294  class name : public PXMLRPCStructBase { \
295  public: name() { EndConstructor(); } \
296  public: name(const name & other) { EndConstructor(); operator=(other); } \
297  public: name & operator=(const name & other) { PXMLRPCStructBase::operator=(other); return *this; }
298 
299 #define PXMLRPC_VARIABLE_CLASS(base, type, variable, xmltype, init, extras) \
300  private: struct PXMLRPCVar_##variable : public PXMLRPCVariableBase { \
301  PXMLRPCVar_##variable() \
302  : PXMLRPCVariableBase(#variable, xmltype), \
303  instance(((base &)base::GetInitialiser()).variable) \
304  { init } \
305  virtual void PrintOn (ostream & s) const { s << instance; } \
306  virtual void ReadFrom(istream & s) { s >> instance; } \
307  virtual void Copy(const PXMLRPCVariableBase & other) \
308  { instance = ((PXMLRPCVar_##variable &)other).instance; } \
309  extras \
310  type & instance; \
311  } pxmlrpcvar_##variable
312 
313 #define PXMLRPC_VARIABLE_CUSTOM(base, type, variable, xmltype, init, extras) \
314  public: type variable; \
315  PXMLRPC_VARIABLE_CLASS(base, type, variable, xmltype, init, extras)
316 
317 #define PXMLRPC_ARRAY_CUSTOM(base, arraytype, basetype, variable, xmltype, par, extras) \
318  public: arraytype variable; \
319  private: struct PXMLRPCVar_##variable : public par { \
320  PXMLRPCVar_##variable() \
321  : par(((base &)base::GetInitialiser()).variable, #variable, xmltype), \
322  instance((arraytype &)m_array) \
323  { } \
324  extras \
325  arraytype & instance; \
326  } pxmlrpcvar_##variable
327 #ifdef DOCPLUSPLUS
328 }
329 #endif
330 
331 
332 #define PXMLRPC_STRUCT_END() \
333  };
334 
335 
336 #define PXMLRPC_VARIABLE(base, type, variable, xmltype) \
337  PXMLRPC_VARIABLE_CUSTOM(base, type, variable, xmltype, ;, ;)
338 
339 
340 #define PXMLRPC_VARIABLE_INIT(base, type, variable, xmltype, init) \
341  PXMLRPC_VARIABLE_CUSTOM(base, type, variable, xmltype, instance=init;, ;)
342 
343 
344 #define PXMLRPC_STRING(base, type, variable) \
345  PXMLRPC_VARIABLE(base, type, variable, "string")
346 
347 
348 #define PXMLRPC_STRING_INIT(base, type, variable, init) \
349  PXMLRPC_VARIABLE_INIT(base, type, variable, "string", init)
350 
351 
352 #define PXMLRPC_INTEGER(base, type, variable) \
353  PXMLRPC_VARIABLE(base, type, variable, "int")
354 
355 
356 #define PXMLRPC_INTEGER_INIT(base, type, variable, init) \
357  PXMLRPC_VARIABLE_INIT(base, type, variable, "int", init)
358 
359 
360 #define PXMLRPC_BOOLEAN(base, type, variable) \
361  PXMLRPC_VARIABLE(base, type, variable, "boolean")
362 
363 
364 #define PXMLRPC_BOOLEAN_INIT(base, type, variable, init) \
365  PXMLRPC_VARIABLE_INIT(base, type, variable, "boolean", init)
366 
367 
368 #define PXMLRPC_DOUBLE(base, type, variable) \
369  PXMLRPC_VARIABLE(base, type, variable, "double")
370 
371 
372 #define PXMLRPC_DOUBLE_INIT(base, type, variable, init) \
373  PXMLRPC_VARIABLE_INIT(base, type, variable, "double", init)
374 
375 
376 #define PXMLRPC_DATETIME(base, type, variable) \
377  PXMLRPC_VARIABLE_CUSTOM(base, type, variable, "dateTime.iso8601", ;, \
378  PString ToString(PINDEX) const { return instance.AsString(PTime::ShortISO8601); } )
379 
380 
381 #define PXMLRPC_BINARY(base, type, variable) \
382  PXMLRPC_VARIABLE_CUSTOM(base, type, variable, "base64", ;, \
383  PString ToString(PINDEX) const { return ToBase64(instance); } \
384  void FromString(PINDEX, const PString & str) { FromBase64(str, instance); } )
385 
386 
387 #define PXMLRPC_STRUCT(base, type, variable) \
388  PXMLRPC_VARIABLE_CUSTOM(base, type, variable, "struct", ;, \
389  PXMLRPCStructBase * GetStruct(PINDEX) const { return &instance; } )
390 
391 
392 #define PXMLRPC_ARRAY(base, arraytype, basetype, variable, xmltype) \
393  PXMLRPC_ARRAY_CUSTOM(base, arraytype, basetype, variable, xmltype, PXMLRPCArrayObjectsBase, \
394  PObject * CreateObject() const { return new basetype; })
395 
396 
397 #define PXMLRPC_ARRAY_STRING(base, arraytype, basetype, variable) \
398  PXMLRPC_ARRAY(base, arraytype, basetype, variable, "string")
399 
400 #define PXMLRPC_ARRAY_INTEGER(base, type, variable) \
401  PXMLRPC_ARRAY_CUSTOM(base, PScalarArray<type>, type, variable, "int", PXMLRPCArrayBase, \
402  PString ToString(PINDEX i) const { return PString(instance[i]); } \
403  void FromString(PINDEX i, const PString & str) { instance[i] = (type)str.AsInteger(); })
404 
405 #define PXMLRPC_ARRAY_DOUBLE(base, type, variable) \
406  PXMLRPC_ARRAY_CUSTOM(base, PScalarArray<type>, type, variable, "double", PXMLRPCArrayBase, \
407  PString ToString(PINDEX i) const { return psprintf("%f", instance[i]); } \
408  void FromString(PINDEX i, const PString & str) { instance[i] = (type)str.AsReal(); })
409 
410 #define PXMLRPC_ARRAY_STRUCT(base, type, variable) \
411  PXMLRPC_ARRAY_CUSTOM(base, PArray<type>, type, variable, "struct", PXMLRPCArrayObjectsBase, \
412  PXMLRPCStructBase * GetStruct(PINDEX i) const { return &instance[i]; } \
413  PObject * CreateObject() const { return new type; })
414 
415 
416 #define PXMLRPC_FUNC_NOARG_NOREPLY(name) \
417  PBoolean name() { return MakeRequest(#name); }
418 
419 
420 #define PXMLRPC_FUNC_SINGLE_ARG(name, vartype, argtype) \
421  class name##_in : public PXMLRPCStructBase { \
422  public: name##_in(const argtype & var) : variable(var) { EndConstructor(); } \
423  vartype(name##_in, argtype, variable);
424 
425 
426 #define PXMLRPC_FUNC_MULTI_ARGS(name) \
427  PXMLRPC_STRUCT_BEGIN(name##_in)
428 
429 
430 #ifdef DOCPLUSPLUS
431 {
432 #endif
433 #define PXMLRPC_FUNC_MULTI_REPLY(name) \
434  }; PXMLRPC_STRUCT_BEGIN(name##_out)
435 
436 
437 #ifdef DOCPLUSPLUS
438 {
439 #endif
440 #define PXMLRPC_FUNC_NO_ARGS(name) \
441  }; \
442  PBoolean name(name##_out & reply) \
443  { return MakeRequest(#name, name##_in(), reply); }
444 
445 
446 #ifdef DOCPLUSPLUS
447 {
448 #endif
449 #define PXMLRPC_FUNC_STRUCT_ARG(name) \
450  }; \
451  class name##_in_carrier : public PXMLRPCStructBase { \
452  public: name##_in_carrier(const name##_in & var) : variable(var) { EndConstructor(); } \
453  private: struct var_class : public PXMLRPCVariableBase { \
454  var_class(const name##_in & var) \
455  : PXMLRPCVariableBase("variable", "struct"), instance(var) { } \
456  virtual void PrintOn (ostream & s) const { s << instance; } \
457  virtual PXMLRPCStructBase * GetStruct(PINDEX) const { return (PXMLRPCStructBase *)&instance; } \
458  virtual void Copy(const PXMLRPCVariableBase &) { } \
459  const name##_in & instance; \
460  } variable; \
461  }; \
462  PBoolean name(const name##_in & args, name##_out & reply) \
463  { return MakeRequest(#name, name##_in_carrier(args), reply); }
464 
465 
466 #ifdef DOCPLUSPLUS
467 {
468 #endif
469 #define PXMLRPC_FUNC_NORM_ARGS(name) \
470  }; \
471  PBoolean name(const name##_in & args, name##_out & reply) \
472  { return MakeRequest(#name, args, reply); }
473 
474 
475 
477 
478 #endif // P_XMLRPC
479 
480 #endif // PTLIB_PXMLRPC_H
481 
482 
483 // End Of File ///////////////////////////////////////////////////////////////