PTLib  Version 2.12.9
 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: 28521 $
27  * $Author: rjongbloed $
28  * $Date: 2012-11-16 11:29:10 +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) { 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 faultText; }
94  PINDEX GetFaultCode() const { return 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 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 
119  PBoolean Load(const PString & str);
120 
122  PXMLElement * GetParam(PINDEX idx) const;
123  PINDEX GetParamCount() const;
124 
125  // used when used as a response
126  PINDEX GetFaultCode() const { return faultCode; }
127  PString GetFaultText() const { return faultText; }
128  void SetFault(PINDEX code, const PString & text) { faultCode = code; faultText = text; }
130 
131  // helper functions for getting parameters
133  PBoolean GetParam(PINDEX idx, PString & type, PString & result);
134  PBoolean GetExpectedParam(PINDEX idx, const PString & expectedType, PString & value);
135 
136  PBoolean GetParam(PINDEX idx, PString & result);
137  PBoolean GetParam(PINDEX idx, int & result);
138  PBoolean GetParam(PINDEX idx, double & result);
139  PBoolean GetParam(PINDEX idx, PTime & result, int tz = PTime::GMT);
140  PBoolean GetParam(PINDEX idx, PStringToString & result);
141  PBoolean GetParam(PINDEX idx, PXMLRPCStructBase & result);
142  PBoolean GetParam(PINDEX idx, PStringArray & result);
143  PBoolean GetParam(PINDEX idx, PArray<PStringToString> & result);
144 
145  // static functions for parsing values
146  PBoolean ParseScalar(PXMLElement * element, PString & type, PString & value);
147  PBoolean ParseStruct(PXMLElement * element, PStringToString & structDict);
148  PBoolean ParseStruct(PXMLElement * element, PXMLRPCStructBase & structData);
149  PBoolean ParseArray(PXMLElement * element, PStringArray & array);
152 
153  // static functions for creating values
154  static PXMLElement * CreateValueElement(PXMLElement * element);
155  static PXMLElement * CreateScalar(const PString & type, const PString & scalar);
156  static PXMLElement * CreateMember(const PString & name, PXMLElement * value);
157 
158  static PXMLElement * CreateScalar(const PString & str);
159  static PXMLElement * CreateScalar(int value);
160  static PXMLElement * CreateScalar(double value);
161  static PXMLElement * CreateDateAndTime(const PTime & time);
162  static PXMLElement * CreateBinary(const PBYTEArray & data);
163 
164  static PXMLElement * CreateStruct();
165  static PXMLElement * CreateStruct(const PStringToString & dict);
166  static PXMLElement * CreateStruct(const PStringToString & dict, const PString & typeStr);
167  static PXMLElement * CreateStruct(const PXMLRPCStructBase & structData);
168 
169  static PXMLElement * CreateArray(const PStringArray & array);
170  static PXMLElement * CreateArray(const PStringArray & array, const PString & typeStr);
171  static PXMLElement * CreateArray(const PStringArray & array, const PStringArray & types);
172  static PXMLElement * CreateArray(const PArray<PStringToString> & array);
173  static PXMLElement * CreateArray(const PXMLRPCVariableBase & array);
174 
175  // helper functions for adding parameters
176  void AddParam(PXMLElement * parm);
177  void AddParam(const PString & str);
178  void AddParam(int value);
179  void AddParam(double value);
180  void AddParam(const PTime & time);
181  void AddParam(const PXMLRPCStructBase & structData);
182  void AddBinary(const PBYTEArray & data);
183  void AddStruct(const PStringToString & dict);
184  void AddStruct(const PStringToString & dict, const PString & typeStr);
185  void AddArray(const PStringArray & array);
186  void AddArray(const PStringArray & array, const PString & typeStr);
187  void AddArray(const PStringArray & array, const PStringArray & types);
188  void AddArray(const PArray<PStringToString> & array);
189 
190  protected:
193  PINDEX faultCode;
194 };
195 
196 
198 
199 class PXMLRPCVariableBase : public PObject {
200  PCLASSINFO(PXMLRPCVariableBase, PObject);
201  protected:
202  PXMLRPCVariableBase(const char * name, const char * type = NULL);
203 
204  public:
205  const char * GetName() const { return name; }
206  const char * GetType() const { return type; }
207 
208  virtual void Copy(const PXMLRPCVariableBase & other) = 0;
209  virtual PString ToString(PINDEX i) const;
210  virtual void FromString(PINDEX i, const PString & str);
211  virtual PXMLRPCStructBase * GetStruct(PINDEX i) const;
212  virtual PBoolean IsArray() const;
213  virtual PINDEX GetSize() const;
214  virtual PBoolean SetSize(PINDEX);
215 
216  PString ToBase64(PAbstractArray & data) const;
217  void FromBase64(const PString & str, PAbstractArray & data);
218 
219  protected:
220  const char * name;
221  const char * type;
222 
223  private:
225 };
226 
227 
230  protected:
231  PXMLRPCArrayBase(PContainer & array, const char * name, const char * type);
233 
234  public:
235  virtual void PrintOn(ostream & strm) const;
236  virtual void Copy(const PXMLRPCVariableBase & other);
237  virtual PBoolean IsArray() const;
238  virtual PINDEX GetSize() const;
239  virtual PBoolean SetSize(PINDEX);
240 
241  protected:
243 };
244 
245 
248  protected:
249  PXMLRPCArrayObjectsBase(PArrayObjects & array, const char * name, const char * type);
251 
252  public:
253  virtual PString ToString(PINDEX i) const;
254  virtual void FromString(PINDEX i, const PString & str);
255  virtual PBoolean SetSize(PINDEX);
256 
257  virtual PObject * CreateObject() const = 0;
258 
259  protected:
261 };
262 
263 
264 class PXMLRPCStructBase : public PObject {
265  PCLASSINFO(PXMLRPCStructBase, PObject);
266  protected:
269  private:
271 
272  public:
273  void PrintOn(ostream & strm) const;
274 
275  PINDEX GetNumVariables() const { return variablesByOrder.GetSize(); }
276  PXMLRPCVariableBase & GetVariable(PINDEX idx) const { return variablesByOrder[idx]; }
277  PXMLRPCVariableBase * GetVariable(const char * name) const { return variablesByName.GetAt(name); }
278 
279  void AddVariable(PXMLRPCVariableBase * var);
281 
282  protected:
283  void EndConstructor();
284 
287 
291 };
292 
293 
294 #define PXMLRPC_STRUCT_BEGIN(name) \
295  class name : public PXMLRPCStructBase { \
296  public: name() { EndConstructor(); } \
297  public: name(const name & other) { EndConstructor(); operator=(other); } \
298  public: name & operator=(const name & other) { PXMLRPCStructBase::operator=(other); return *this; }
299 
300 #define PXMLRPC_VARIABLE_CLASS(base, type, variable, xmltype, init, extras) \
301  private: struct PXMLRPCVar_##variable : public PXMLRPCVariableBase { \
302  PXMLRPCVar_##variable() \
303  : PXMLRPCVariableBase(#variable, xmltype), \
304  instance(((base &)base::GetInitialiser()).variable) \
305  { init } \
306  virtual void PrintOn (ostream & s) const { s << instance; } \
307  virtual void ReadFrom(istream & s) { s >> instance; } \
308  virtual void Copy(const PXMLRPCVariableBase & other) \
309  { instance = ((PXMLRPCVar_##variable &)other).instance; } \
310  extras \
311  type & instance; \
312  } pxmlrpcvar_##variable
313 
314 #define PXMLRPC_VARIABLE_CUSTOM(base, type, variable, xmltype, init, extras) \
315  public: type variable; \
316  PXMLRPC_VARIABLE_CLASS(base, type, variable, xmltype, init, extras)
317 
318 #define PXMLRPC_ARRAY_CUSTOM(base, arraytype, basetype, variable, xmltype, par, extras) \
319  public: arraytype variable; \
320  private: struct PXMLRPCVar_##variable : public par { \
321  PXMLRPCVar_##variable() \
322  : par(((base &)base::GetInitialiser()).variable, #variable, xmltype), \
323  instance((arraytype &)array) \
324  { } \
325  extras \
326  arraytype & instance; \
327  } pxmlrpcvar_##variable
328 #ifdef DOCPLUSPLUS
329 }
330 #endif
331 
332 
333 #define PXMLRPC_STRUCT_END() \
334  };
335 
336 
337 #define PXMLRPC_VARIABLE(base, type, variable, xmltype) \
338  PXMLRPC_VARIABLE_CUSTOM(base, type, variable, xmltype, ;, ;)
339 
340 
341 #define PXMLRPC_VARIABLE_INIT(base, type, variable, xmltype, init) \
342  PXMLRPC_VARIABLE_CUSTOM(base, type, variable, xmltype, instance=init;, ;)
343 
344 
345 #define PXMLRPC_STRING(base, type, variable) \
346  PXMLRPC_VARIABLE(base, type, variable, "string")
347 
348 
349 #define PXMLRPC_STRING_INIT(base, type, variable, init) \
350  PXMLRPC_VARIABLE_INIT(base, type, variable, "string", init)
351 
352 
353 #define PXMLRPC_INTEGER(base, type, variable) \
354  PXMLRPC_VARIABLE(base, type, variable, "int")
355 
356 
357 #define PXMLRPC_INTEGER_INIT(base, type, variable, init) \
358  PXMLRPC_VARIABLE_INIT(base, type, variable, "int", init)
359 
360 
361 #define PXMLRPC_BOOLEAN(base, type, variable) \
362  PXMLRPC_VARIABLE(base, type, variable, "boolean")
363 
364 
365 #define PXMLRPC_BOOLEAN_INIT(base, type, variable, init) \
366  PXMLRPC_VARIABLE_INIT(base, type, variable, "boolean", init)
367 
368 
369 #define PXMLRPC_DOUBLE(base, type, variable) \
370  PXMLRPC_VARIABLE(base, type, variable, "double")
371 
372 
373 #define PXMLRPC_DOUBLE_INIT(base, type, variable, init) \
374  PXMLRPC_VARIABLE_INIT(base, type, variable, "double", init)
375 
376 
377 #define PXMLRPC_DATETIME(base, type, variable) \
378  PXMLRPC_VARIABLE_CUSTOM(base, type, variable, "dateTime.iso8601", ;, \
379  PString ToString(PINDEX) const { return instance.AsString(PTime::ShortISO8601); } )
380 
381 
382 #define PXMLRPC_BINARY(base, type, variable) \
383  PXMLRPC_VARIABLE_CUSTOM(base, type, variable, "base64", ;, \
384  PString ToString(PINDEX) const { return ToBase64(instance); } \
385  void FromString(PINDEX, const PString & str) { FromBase64(str, instance); } )
386 
387 
388 #define PXMLRPC_STRUCT(base, type, variable) \
389  PXMLRPC_VARIABLE_CUSTOM(base, type, variable, "struct", ;, \
390  PXMLRPCStructBase * GetStruct(PINDEX) const { return &instance; } )
391 
392 
393 #define PXMLRPC_ARRAY(base, arraytype, basetype, variable, xmltype) \
394  PXMLRPC_ARRAY_CUSTOM(base, arraytype, basetype, variable, xmltype, PXMLRPCArrayObjectsBase, \
395  PObject * CreateObject() const { return new basetype; })
396 
397 
398 #define PXMLRPC_ARRAY_STRING(base, arraytype, basetype, variable) \
399  PXMLRPC_ARRAY(base, arraytype, basetype, variable, "string")
400 
401 #define PXMLRPC_ARRAY_INTEGER(base, type, variable) \
402  PXMLRPC_ARRAY_CUSTOM(base, PScalarArray<type>, type, variable, "int", PXMLRPCArrayBase, \
403  PString ToString(PINDEX i) const { return PString(instance[i]); } \
404  void FromString(PINDEX i, const PString & str) { instance[i] = (type)str.AsInteger(); })
405 
406 #define PXMLRPC_ARRAY_DOUBLE(base, type, variable) \
407  PXMLRPC_ARRAY_CUSTOM(base, PScalarArray<type>, type, variable, "double", PXMLRPCArrayBase, \
408  PString ToString(PINDEX i) const { return psprintf("%f", instance[i]); } \
409  void FromString(PINDEX i, const PString & str) { instance[i] = (type)str.AsReal(); })
410 
411 #define PXMLRPC_ARRAY_STRUCT(base, type, variable) \
412  PXMLRPC_ARRAY_CUSTOM(base, PArray<type>, type, variable, "struct", PXMLRPCArrayObjectsBase, \
413  PXMLRPCStructBase * GetStruct(PINDEX i) const { return &instance[i]; } \
414  PObject * CreateObject() const { return new type; })
415 
416 
417 #define PXMLRPC_FUNC_NOARG_NOREPLY(name) \
418  PBoolean name() { return MakeRequest(#name); }
419 
420 
421 #define PXMLRPC_FUNC_SINGLE_ARG(name, vartype, argtype) \
422  class name##_in : public PXMLRPCStructBase { \
423  public: name##_in(const argtype & var) : variable(var) { EndConstructor(); } \
424  vartype(name##_in, argtype, variable);
425 
426 
427 #define PXMLRPC_FUNC_MULTI_ARGS(name) \
428  PXMLRPC_STRUCT_BEGIN(name##_in)
429 
430 
431 #ifdef DOCPLUSPLUS
432 {
433 #endif
434 #define PXMLRPC_FUNC_MULTI_REPLY(name) \
435  }; PXMLRPC_STRUCT_BEGIN(name##_out)
436 
437 
438 #ifdef DOCPLUSPLUS
439 {
440 #endif
441 #define PXMLRPC_FUNC_NO_ARGS(name) \
442  }; \
443  PBoolean name(name##_out & reply) \
444  { return MakeRequest(#name, name##_in(), reply); }
445 
446 
447 #ifdef DOCPLUSPLUS
448 {
449 #endif
450 #define PXMLRPC_FUNC_STRUCT_ARG(name) \
451  }; \
452  class name##_in_carrier : public PXMLRPCStructBase { \
453  public: name##_in_carrier(const name##_in & var) : variable(var) { EndConstructor(); } \
454  private: struct var_class : public PXMLRPCVariableBase { \
455  var_class(const name##_in & var) \
456  : PXMLRPCVariableBase("variable", "struct"), instance(var) { } \
457  virtual void PrintOn (ostream & s) const { s << instance; } \
458  virtual PXMLRPCStructBase * GetStruct(PINDEX) const { return (PXMLRPCStructBase *)&instance; } \
459  virtual void Copy(const PXMLRPCVariableBase &) { } \
460  const name##_in & instance; \
461  } variable; \
462  }; \
463  PBoolean name(const name##_in & args, name##_out & reply) \
464  { return MakeRequest(#name, name##_in_carrier(args), reply); }
465 
466 
467 #ifdef DOCPLUSPLUS
468 {
469 #endif
470 #define PXMLRPC_FUNC_NORM_ARGS(name) \
471  }; \
472  PBoolean name(const name##_in & args, name##_out & reply) \
473  { return MakeRequest(#name, args, reply); }
474 
475 
476 
478 
479 #endif // P_XMLRPC
480 
481 #endif // PTLIB_PXMLRPC_H
482 
483 
484 // End Of File ///////////////////////////////////////////////////////////////