Genivia Home Developer Center

Data Bindings

 
README.md
Go to the documentation of this file.
1 
2 XML Data Bindings {#mainpage}
3 =================
4 
5 [TOC]
6 
7 This is a detailed overview of the gSOAP XML data bindings concepts and
8 implementation. At the end of this document two examples are given to
9 illustrate the application of data bindings.
10 
11 The first example `address.cpp` shows how to use wsdl2h to bind an XML
12 schema to C++. The C++ application reads and writes an XML file into and from a
13 C++ "address book" data structure. The C++ data structure is an STL vector of
14 address objects.
15 
16 The second example `graph.cpp` shows how XML is serialized as a tree, digraph,
17 and cyclic graph. The digraph and cyclic graph serialization rules are similar
18 to SOAP 1.1/1.2 encoded multi-ref elements with id-ref attributes to link
19 elements through IDREF XML "pointers".
20 
21 These examples demonstrate XML data bindings only for relatively simple data
22 structures and types. The gSOAP tools support more than just these type of
23 structures, which we will explain in the next sections. Support for XML schema
24 components is practically unlimited. The wsdl2h tool maps schemas to C and C++
25 using built-in intuitive mapping rules, while allowing the mappings to be
26 customized using a `typemap.dat` file with mapping instructions for wsdl2h.
27 
28 The information in this document is applicable to gSOAP 2.8.24 and higher, which
29 supports C++11 features. However, C++11 is not required to use this material
30 and follow the example, unless we need smart pointers and scoped enumerations.
31 While most of the examples in this document are given in C++, the concepts also
32 apply to C with the exception of containers, smart pointers, classes and their
33 methods. None of these exceptions limit the use of the gSOAP tools for C in any
34 way.
35 
36 The data binding concepts described in this document have somewhat changed
37 and improved over the years since the first version of gSOAP was developed in
38 1999 (the project was called a "XML/SOAP stub/skeleton compiler" back
39 then). However, the principle of mapping XSD components to C/C++ types and vice
40 versa was envisioned and implemented early on in research conducted by Dr. van
41 Engelen at the Florida State University and subsequently adopted by other
42 tools, including Java web services and in C# WCF.
43 
44 
45 Mapping WSDL and XML schemas to C/C++ {#tocpp}
46 =====================================
47 
48 To convert WSDL and XML schemas (XSD files), we use the wsdl2h command to
49 generate the data binding interface code in a special gSOAP header file:
50 
51  wsdl2h [options] -o file.h ... XSD and WSDL files ...
52 
53 This converts WSDL and XSD files to C++ (or pure C with wsdl2h option `-c`) and
54 saves a special `file.h` data binding interface file.
55 
56 The WSDL 1.1/2.0, SOAP 1.1/1.2, and XSD 1.0/1.1 standards are supported by the
57 gSOAP tools. In addition, the most popular WS specifications are also
58 supported, including WS-Addressing, WS-ReliableMessaging, WS-Discovery,
59 WS-Security, WS-Policy, WS-SecurityPolicy, and WS-SecureConversation.
60 
61 This document focusses on XML data bindings and mapping C/C++ to XML 1.0/1.1
62 and XSD 1.0/1.1. This covers all of the following standard XSD components with
63 their optional `[ attributes ]` properties:
64 
65  any [minOccurs, maxOccurs]
66  anyAttribute
67  all
68  choice [minOccurs, maxOccurs]
69  sequence [minOccurs, maxOccurs]
70  group [name, ref]
71  attributeGroup [name, ref]
72  attribute [name, ref, type, use, default, fixed, form, wsdl:arrayType]
73  element [name, ref, type, default, fixed, form, nillable, abstract, substitutionGroup, minOccurs, maxOccurs]
74  simpleType [name]
75  complexType [name, abstract, mixed]
76 
77 And also the following standard XSD components:
78 
79  import imports a schema into the importing schema for referencing
80  include include schema component definitions into a schema
81  override override by replacing schema component definitions
82  redefine extend or restrict schema component definitions
83  annotation annotates a component
84 
85 The XSD facets and their mappings to C/C++ are:
86 
87  enumeration maps to enum
88  simpleContent maps to class/struct wrapper with __item member
89  complexContent maps to class/struct
90  list maps to enum* bitmask (enum* enumerates up to 64 bit masks)
91  extension through inheritance
92  restriction partly through inheritance and redeclaration
93  length restricts content length
94  minLength restricst content length
95  maxLength restricst content length
96  minInclusive restricts numerical value range
97  maxInclusive restricts numerical value range
98  minExclusive restricts numerical value range
99  maxExclusive restricts numerical value range
100  precision maps to float/double but constraint is not validated
101  scale maps to float/double but constraint is not validated
102  totalDigits maps to float/double but constraint is not validated
103  fractionDigits maps to float/double but constraint is not validated
104  pattern must define `soap::fsvalidate` callback to validate patterns
105  union maps to string of values
106 
107 All primitive XSD types are supported, including but not limited to the
108 following XSD types:
109 
110  anyType maps to _XML string with literal XML content (or DOM with wsdl2h option -d)
111  anyURI maps to string
112  string maps to string (char*/wchar_t*/std::string/std::wstring)
113  boolean maps to bool (C++) or enum xsd__boolean (C)
114  byte maps to char (int8_t)
115  short maps to short (int16_t)
116  int maps to int (int32_t)
117  long maps to LONG64 (long long and int64_t)
118  unsignedByte maps to unsigned char (uint8_t)
119  unsignedShort maps to unsigned short (uint16_t)
120  unsignedInt maps to unsigned int (uint32_t)
121  unsignedLong maps to ULONG64 (unsigned long long and uint64_t)
122  float maps to float
123  double maps to double
124  integer maps to string
125  decimal maps to string, or use "#import "custom/long_double.h"
126  precisionDecimal maps to string
127  duration maps to string, or use "#import "custom/duration.h"
128  dateTime maps to time_t, or use "#import "custom/struct_tm.h"
129  time maps to string, or use "#import "custom/long_time.h"
130  date maps to string, or use "#import "custom/struct_tm_date.h"
131  hexBinary maps to class/struct xsd__hexBinary
132  base64Bianry maps to class/struct xsd__base64Binary
133  QName maps to _QName (URI normalization rules are applied)
134 
135 All other primitive XSD types not listed above are mapped to strings, by
136 generating a typedef. For example, xsd:token is bound to a C++ or C string,
137 which associates a value space to the type with the appropriate XSD type name
138 used by the soapcpp2-generated serializers:
139 
140  typedef std::string xsd__token; // C++
141  typedef char *xsd__token; // C (wsdl2h option -c)
142 
143 It is possible to remap types by adding the appropriate mapping rules to
144 `typemap.dat` as explained in the next section.
145 
146 
147 Using typemap.dat to customize generated bindings {#typemap}
148 =================================================
149 
150 We use a `typemap.dat` file to redefine namespace prefixes and to customize
151 type bindings for the the generated header files produced by the wsdl2h tool.
152 The `typemap.dat` is the default file processed by wsdl2h. Use wsdl2h option
153 `-t` to specify an alternate file.
154 
155 Declarations in `typemap.dat` can be broken up over multiple lines by
156 continuing on the next line by ending each line to be continued with a
157 backslash `\`.
158 
159 XML namespace bindings {#typemap1}
160 ----------------------
161 
162 The wsdl2h tool generates C/C++ type declarations that use `ns1`, `ns2`, etc.
163 as URI schema-binding prefixes. These default prefixes are generated somewhat
164 arbitrarily for each schema URI, meaning that their ordering may change
165 depending on the WSDL and XSD order of processing with wsdl2h.
166 
167 It is **strongly recommended** to declare your own prefix for each schema URI
168 to enhance maintaince of your code. This is to anticipate possible changes of
169 the schema(s) and/or the binding URI(s) and/or the tooling procedures.
170 
171 Therefore, the first and foremost important thing to do is to define prefix-URI
172 bindings for our C/C++ code by adding the following line(s) to our
173 `typemap.dat` or make a copy of this file and add the line(s) that bind our
174 choice of prefix name to each URI:
175 
176  prefix = "URI"
177 
178 For example:
179 
180  g = "urn:graph"
181 
182 This produces `g__name` C/C++ type names that are bound to the "urn:graph"
183 schema by association of `g` to the C/C++ types.
184 
185 This means that `<g:name xmlns:g="urn:graph">` is parsed as an instance of a
186 `g__name` C/C++ type. Also `<x:name xmlns:x="urn:graph">` parses as an instance
187 of `g__name`, because the prefix `x` has the same URI value `urn:graph`.
188 Prefixes in XML have local scopes (like variables in a block).
189 
190 The first run of wsdl2h will reveal the URIs, so we do not need to search WSDLs
191 and XSD files for all of the target namespaces.
192 
193 XSD type bindings {#typemap2}
194 -----------------
195 
196 Custom C/C++ type bindings can be declared in `typemap.dat` to associate C/C++
197 types with specific schema types. These type bindings have four parts:
198 
199  prefix__type = declaration | use | ptruse
200 
201 where
202 
203 - `prefix__type` is the schema type to be customized (the `prefix__type` name
204  uses the common double underscore naming convention);
205 - `declaration` declares the C/C++ type in the wsdl2h-generated header file.
206  This part can be empty if no explicit declaration is needed;
207 - `use` is an optional part that specifies how the C/C++ type is used in the
208  code. When omitted, it is the same as `prefix__type`;
209 - `ptruse` is an optional part that specifies how the type is used as a
210  pointer type. By default it is the `use` type name with a `*` or C++11
211  `std::shared_ptr<>` (see further below).
212 
213 For example, to map xsd:duration to a `long long` (`LONG64`) milliseconds
214 value, we can use the custom serializer declared in `custom/duration.h` by
215 adding the following line to `typemap.dat`:
216 
217  xsd__duration = #import "custom/duration.h" | xsd__duration
218 
219 Here, we could have omitted the second field, because `xsd__duration` is the
220 name that wsdl2h uses to identify this type.
221 
222 To map xsd:string to `wchar_t*` wide strings:
223 
224  xsd__string = | wchar_t* | wchar_t*
225 
226 Note that the first field is empty, because `wchar_t` is a C type and does not
227 need to be declared. A `ptruse` field is given so that we do not end up
228 generating the wrong pointer types, such as `wchar_t**` and
229 `std::shared_ptr<wchar_t>`.
230 
231 When the auto-generated declaration should be preserved but the `use` or
232 `ptruse` fields replaced, then we use an ellipsis for the declaration part:
233 
234  prefix__type = ... | use | ptruse
235 
236 This is useful to map schema polymorphic types to C types for example, where we
237 need to be able to both handle a base type and its extensions as per schema
238 extensibility. Say we have a base type called ns:base that is extended, then we
239 can remap this to a C type that permits referening the extended types via a
240 `void*` as follows:
241 
242  ns__base = ... | int __type_base; void*
243 
244 such that `__type_base` and `void*` are used to (de)serialize any data type,
245 including base and its derived types.
246 
247 Class/struct member additions {#typemap3}
248 -----------------------------
249 
250 All generated classes and structs can be augmented with additional
251 members such as methods, constructors and destructors, and private members:
252 
253  prefix__type = $ member-declaration
254 
255 For example, we can add method declarations and private members to a class, say
256 `ns__record` as follows:
257 
258  ns__record = $ ns__record(const ns__record &); // copy constructor
259  ns__record = $ void print(); // a print method
260  ns__record = $ private: int status; // a private member
261 
262 Note that method declarations cannot include any code, because soapcpp2's input
263 permits only type declarations, not code.
264 
265 Replacing XSD types by equivalent alternatives {#typemap4}
266 ----------------------------------------------
267 
268 Type replacements can be given to replace one type entirely with another given
269 type:
270 
271  prefix__type1 == prefix__type2
272 
273 This replaces all `prefix__type1` by `prefix__type2` in the wsdl2h output.
274 However, care muse be taken not to agressively replace types, because this can
275 cause XML validation to fail when a value-type mismatch is encountered in the
276 XML input. Therefore, only replace similar types with other similar types that
277 are wider (e.g. `short` by `int` and `float` by `double`).
278 
279 The built-in typemap.dat variables $CONTAINER and $POINTER {#typemap5}
280 ----------------------------------------------------------
281 
282 The `typemap.dat` `$CONTAINER` variable defines the container to emit in the
283 generated declarations, which is `std::vector` by default. For example:
284 
285  $CONTAINER = std::list
286 
287 The `typemap.dat` `$POINTER` variable defines the smart pointer to emit in the
288 generated declarations, which replaces the use of `*` pointers. For example:
289 
290  $POINTER = std::shared_ptr
291 
292 Not all pointers in the generated output can be replaced by smart pointers when
293 standard pointers are used as union members and pointers to arrays.
294 
295 User-defined content {#typemap6}
296 --------------------
297 
298 Any other content to be generated by wsdl2h can be included in `typemap.dat` by
299 enclosing it within brackets `[` and `]`. These brackets MUST appear at the
300 start of a new line.
301 
302 For example, we can add an `#import "wsa5.h"` directive to the wsdl2h-generated
303 output:
304 
305  [
306  #import "wsa5.h"
307  ]
308 
309 which emits the `#import "wsa5.h"` literally at the start of the
310 wsdl2h-generated header file.
311 
312 
313 Mapping C/C++ to XML schema {#toxsd}
314 ===========================
315 
316 The soapcpp2 command generates the data binding implementation code from a data
317 binding interface `file.h`:
318 
319  soapcpp2 [options] file.h
320 
321 where `file.h` is a gSOAP header file that declares the XML data binding
322 interface. The `file.h` is typically generated by wsdl2h, but we can also
323 declare one ourself. If so, we add gSOAP directives and declare in this file
324 all our C/C++ types we want to serialize in XML. We can also declare functions
325 that will be converted to service operations by soapcpp2.
326 
327 Global function declarations define service operations, which are of the form:
328 
329  int ns__name(arg1, arg2, ..., argn, result);
330 
331 where `arg1`, `arg2`, ..., `argn` are formal argument declarations of the input
332 and `result` is a formal argument for the output, which must be a pointer or
333 reference to the result object to be populated. More information can be found
334 in the gSOAP user guide.
335 
336 Overview of serializable C/C++ types {#toxsd1}
337 ------------------------------------
338 
339 The following C/C++ types are supported by soapcpp2 and mapped to XSD types
340 and constructs. See the subsections below for more details or follow the links.
341 
342 List of [C++ bool and C alternative](#toxsd3)
343 
344  bool C++ bool
345  enum xsd__boolean C alternative bool
346 
347 List of [enumerations and bitmasks](#toxsd4)
348 
349  enum enumeration
350  enum class C++11 scoped enumeration (soapcpp2 -c++11)
351  enum* a bitmask that enumerates values 1, 2, 4, 8, ...
352  enum* class C++11 scoped enumeration (soapcpp2 -c++11)
353 
354 List of [numerical types](#toxsd5)
355 
356  char byte
357  short 16 bit integer
358  int 32 bit integer
359  long 32 bit integer
360  LONG64 64 bit integer
361  long long same as LONG64
362  unsigned char unsigned byte
363  unsigned short unsigned 16 bit integer
364  unsigned int unsigned 32 bit integer
365  unsigned long unsigned 32 bit integer
366  ULONG64 unsigned 64 bit integer
367  unsigned long long same as ULONG64
368  int8_t same as char
369  int16_t same as short
370  int32_t same as int
371  int64_t same as LONG64
372  uint8_t same as unsigned char
373  uint16_t same as unsigned short
374  uint32_t same as unsigned int
375  uint64_t same as ULONG64
376  size_t transient type (not serializable)
377  float 32 bit float
378  double 64 bit float
379  long double 128 bit float, use #import "custom/long_double.h"
380  typedef declares a type name, may restrict numeric range
381 
382 List of [string types](#toxsd6)
383 
384  char* string
385  wchar_t* wide string
386  std::string C++ string
387  std::wstring C++ wide string
388  char[N] fixed-size string, requires soapcpp2 option -b
389  _QName normalized QName content
390  _XML literal XML string content
391  typedef declares a type name, may restrict string length
392 
393 List of [date and time types](#toxsd7)
394 
395  time_t date and time point since epoch
396  struct tm date and time point, use #import "custom/struct_tm.h"
397  struct tm date point, use #import "custom/struct_tm_date.h"
398  struct timeval date and time point, use #import "custom/struct_timeval.h"
399  unsigned long long time point in microseconds, use #import "custom/long_time.h"
400  std::chrono::system_clock::time_point
401  date and time point, use #import "custom/chrono_time_point.h"
402 
403 List of [time duration types](#toxsd8)
404 
405  long long duration in milliseconds, use #import "custom/duration.h"
406  std::chrono::nanoseconds duration in nanoseconds, use #import "custom/chrono_duration.h"
407 
408 List of [classes and structs](#toxsd9)
409 
410  class C++ class with single inheritance only
411  struct C struct or C++ struct without inheritance
412  T* pointer to type T
413  T[N] fixed-size array of type T
414  std::shared_ptr<T> C++11 smart shared pointer
415  std::unique_ptr<T> C++11 smart pointer
416  std::auto_ptr<T> C++ smart pointer
417  std::deque<T> use #import "stldeque.h"
418  std::list<T> use #import "stllist.h"
419  std::vector<T> use #import "stlvector.h"
420  std::set<T> use #import "stlset.h"
421  template<T> class a container with begin(), end(), size(), clear(), and insert() methods
422  union requires a discriminant member
423  void* requires a __type member to indicate the type of object pointed to
424 
425 List of [special classes and structs](#toxsd10)
426 
427  Array single and multidimensional SOAP Arrays
428  xsd__hexBinary binary content
429  xsd__base64Binary binary content and optional MIME/MTOM attachments
430  Wrapper complexTypes with simpleContent
431 
432 Colon notation versus name prefixing {#toxsd2}
433 ------------------------------------
434 
435 To bind C/C++ type names to XSD types, a simple form of name prefixing is used
436 by the gSOAP tools by prepending the XML namespace prefix to the C/C++ type
437 name with a pair of undescrores. This also ensures that name clashes cannot
438 occur when multiple WSDL and XSD files are converted to C/C++. Also, C++
439 namespaces are not sufficiently rich to capture XML schema namespaces
440 accurately, for example when class members are associated with schema elements
441 defined in another XML namespace and thus the XML namespace scope of the
442 member's name is relevant, not just its type.
443 
444 However, from a C/C++ centric point of view this can be cumbersome. Therefore,
445 colon notation is an alternative to physically augmenting C/C++ names with
446 prefixes.
447 
448 For example, the following class uses colon notation to bind the `record` class
449 to the `urn:types` schema:
450 
451  //gsoap ns schema namespace: urn:types
452  class ns:record // binding 'ns:' to a type name
453  {
454  public:
455  std::string name;
456  uint64_t SSN;
457  ns:record *spouse; // using 'ns:' with the type name
458  ns:record(); // using 'ns:' here too
459  ~ns:record(); // and here
460  };
461 
462 The colon notation is stripped away by soapcpp2 when generating the data
463 binding implementation code for our project. So the final code just uses
464 `record` to identify this class and its constructor/destructor.
465 
466 When using colon notation we have to be consistent as we cannot use both forms
467 together. That is, `ns:record` differs from `ns__record` as a name.
468 
469 C++ Bool and C alternative {#toxsd3}
470 --------------------------
471 
472 The C++ `bool` type is bound to built-in XSD type xsd:boolean.
473 
474 The C alternative is to define an enumeration:
475 
476  enum xsd__boolean { false_, true_ };
477 
478 or by defining an enumeration in C with pseudo-scoped enumeration values:
479 
480  enum xsd__boolean { xsd__boolean__false, xsd__boolean__true };
481 
482 The XML value space of these types is `false` and `true`, but also accepts `0`
483 and `1` as values.
484 
485 To prevent name clashes, `false_` and `true_` have an underscore which are
486 removed in the XML value space.
487 
488 Enumerations and bitmasks {#toxsd4}
489 -------------------------
490 
491 Enumerations are mapped to XSD simpleType enumeration restrictions of
492 xsd:string, xsd:QName, and xsd:long.
493 
494 Consider for example:
495 
496  enum ns__Color { RED, WHITE, BLUE };
497 
498 which maps to a simpleType restriction of xsd:string in the soapcpp2-generated
499 schema:
500 
501  <simpleType name="Color">
502  <restriction base="xsd:string">
503  <enumeration value="RED"/>
504  <enumeration value="WHITE"/>
505  <enumeration value="BLUE"/>
506  </restriction>
507  </simpleType>
508 
509 Enumeration name constants can be pseudo-scoped to prevent name clashes,
510 because enumeration name constants have a global scope in C and C++:
511 
512  enum ns__Color { ns__Color__RED, ns__Color__WHITE, ns__Color__BLUE };
513 
514 We can also use C++11 scoped enumerations to prevent name clashes:
515 
516  enum class ns__Color : int { RED, WHITE, BLUE };
517 
518 Here, the type part `: int` is optional. In place of `int` in the example
519 above, we can also use `int8_t`, `int16_t`, `int32_t`, or `int64_t`.
520 
521 The XML value space of the enumertions defined above is `RED`, `WHITE`, and
522 `BLUE`.
523 
524 Prefix-qualified enumeration name constants are mapped to simpleType
525 restrictions of xsd:QName, for example:
526 
527  enum ns__types { xsd__int, xsd__float };
528 
529 which maps to a simpleType restriction of xsd:QName in the soapcpp2-generated
530 schema:
531 
532  <simpleType name="types">
533  <restriction base="xsd:QName">
534  <enumeration value="xsd:int"/>
535  <enumeration value="xsd:float"/>
536  </restriction>
537  </simpleType>
538 
539 Enumeration name constants can be pseudo-numeric as follows:
540 
541  enum ns__Primes { _3 = 3, _5 = 5, _7 = 7, _11 = 11 };
542 
543 which maps to a simpleType restriction of `xsd:long`:
544 
545  <simpleType name="Color">
546  <restriction base="xsd:long">
547  <enumeration value="3"/>
548  <enumeration value="5"/>
549  <enumeration value="7"/>
550  <enumeration value="11"/>
551  </restriction>
552  </simpleType>
553 
554 The XML value space of this type is `3`, `5`, `7`, and `11`.
555 
556 Besides (pseudo-) scoped enumerations, another way to prevent name clashes
557 accross enumerations is to start an enumeration name constant with one
558 underscore or followed it by any number of underscores, which makes it
559 unique. The leading and trailing underscores are removed in the XML value
560 space.
561 
562  enum ns__ABC { A, B, C };
563  enum ns__BA { B, A }; // BAD: B = 1 but B is already defined as 2
564  enum ns__BA_ { B_, A_ }; // OK
565 
566 The gSOAP soapcpp2 tool permits reusing enumeration name constants in other
567 (non-scoped) enumerations as long as these values are assigned the same
568 constant. Therefore, the following is permitted:
569 
570  enum ns__Primes { _3 = 3, _5 = 5, _7 = 7, _11 = 11 };
571  enum ns__Throws { _1 = 1, _2 = 2, _3 = 3, _4 = 4, _5 = 5, _6 = 6 };
572 
573 A bitmask type is an `enum*` "product" enumeration with a geometric,
574 power-of-two sequence of values assigned to the name constants:
575 
576  enum* ns__Options { SSL3, TLS10, TLS11, TLS12 };
577 
578 where the product enum assigns 1 to `SSL3`, 2 to `TLS10`, 4 to `TLS11`, and 8
579 to `TLS12`, which allows the enumeration values to be used in composing
580 bitmasks with `|` (bitwise or) `&` (bitwise and), and `~` (bitwise not):
581 
582  enum ns__Options options = (enum ns__Options)(SSL3 | TLS10 | TLS11 | TLS12);
583  if (options & SSL3) // if SSL3 is an option, warn and remove from options
584  {
585  warning();
586  options &= ~SSL3;
587  }
588 
589 The bitmask type maps to a simpleType list restriction of xsd:string in the
590 soapcpp2-generated schema:
591 
592  <simpleType name="Options">
593  <list>
594  <restriction base="xsd:string">
595  <enumeration value="SSL3"/>
596  <enumeration value="TLS10"/>
597  <enumeration value="TLS11"/>
598  <enumeration value="TLS12"/>
599  </restriction>
600  </list>
601  </simpleType>
602 
603 The XML value space of this type consists of all 16 possible subsets of the
604 four values, represented by an XML string with space-separated values. For
605 example, the bitmask `TLS10 | TLS11 | TLS12` equals 14 and is represented in by
606 the XML string `TLS10 TLS11 TLS12`.
607 
608 To convert `enum` name constants to string, we use the soapcpp2 auto-generated
609 `const char *soap_T2s(soap, enum T)` function.
610 
611 To convert a string to an `enum` name constant, we use the soapcpp2
612 auto-generated `int soap_s2T(soap, const char *str, enum T*)` function.
613 
614 Numerical types {#toxsd5}
615 ---------------
616 
617 Integer and floating point types are mapped to the equivalent built-in XSD
618 types with the same sign and bit width.
619 
620 The `size_t` type is transient (not serializable) because its width is platform
621 dependent. We recommend to use `uint64_t` instead.
622 
623 The XML value space of integer types are their decimal representations without
624 loss of precision.
625 
626 The XML value space of floating point types are their decimal representations.
627 The decimal representations are formatted with the printf format string "%.9G"
628 for floats and the printf format string "%.17lG" for double. The value space
629 includes the values `INF`, `-INF`, and `NAN`. To change the format string, we
630 can change one of these `struct soap` context data members:
631 
632  const char * soap::float_format
633  const char * soap::double_format
634 
635 Note that decimal conversions may result in a loss of precision of the least
636 significant decimal.
637 
638 A `long double` 128 bit floating point value requires a custom serializer:
639 
640  #import "custom/long_double.h"
641  typedef long double xsd__decimal;
642 
643 Compile and link your code with `custom/long_double.c`.
644 
645 The range of a numerical type can be restricted with a typedef:
646 
647  typedef int ns__narrow -10:10;
648 
649 which maps to a simpleType restriction of xsd:int in the soapcpp2-generated
650 schema:
651 
652  <simpleType name="narrow">
653  <restriction base="xsd:int">
654  <minInclusive value="-10"/>
655  <maxInclusive value="10"/>
656  </restriction>
657  </simpleType>
658 
659 The range of a float type can only be restricted within integral bounds. This
660 restriction may be dropped in future releases.
661 
662 String types {#toxsd6}
663 ------------
664 
665 String types are mapped to the built-in xsd:string and xsd:QName XSD types.
666 
667 The wide strings `wchar_t*` and `std::wstring` may contain Unicode that is
668 preserved in the XML value space.
669 
670 Strings `char*` and `std::string` can only contain extended Latin, but we can
671 store UTF-8 content that is preserved in the XML value space when the `struct
672 soap` context is initialized with the flag `XML_C_UTFSTRING`.
673 
674 Beware that many XML 1.0 parsers reject all control characters (those between
675 `#x1` and `#x1F`) except `#x9`, `#xA`, and `#xD`. With the newer XML 1.1
676 parsers (including gSOAP) you should be fine.
677 
678 The length of a string type can be restricted with a typedef:
679 
680  typedef std::string ns__password 6:16;
681 
682 which maps to a simpleType restriction of xsd:string in the soapcpp2-generated
683 schema:
684 
685  <simpleType name="password">
686  <restriction base="xsd:string">
687  <minLength value="6"/>
688  <maxLength value="16"/>
689  </restriction>
690  </simpleType>
691 
692 In addition, an XSD regex pattern restriction can be associated with a string
693 typedef:
694 
695  typedef std::string ns__password "([a-zA-Z]|[0-9]|-)+" 6:16;
696 
697 which maps to a simpleType restriction of xsd:string in the soapcpp2-generated
698 schema:
699 
700  <simpleType name="password">
701  <restriction base="xsd:string">
702  <pattern value="([a-zA-Z0-9]|-)+"/>
703  <minLength value="6"/>
704  <maxLength value="16"/>
705  </restriction>
706  </simpleType>
707 
708 Fixed-size strings (`char[N]`) are rare occurrences in the wild, but apparently
709 still used in some projects to store strings. To facilitate fixed-size string
710 serialization, use soapcpp2 option `-b`:
711 
712  typedef char ns__buffer[10]; // requires soapcpp2 option -b
713 
714 which maps to a simpleType restriction of xsd:string in the soapcpp2-generated
715 schema:
716 
717  <simpleType name="buffer">
718  <restriction base="xsd:string">
719  <maxLength value="9"/>
720  </restriction>
721  </simpleType>
722 
723 Note that fixed-size strings MUST contain NUL-terminated text and SHOULD NOT
724 contain raw binary data. Also, the length limitation is more restrictive for
725 UTF-8 content (enabled with the `SOAP_C_UTFSTRING`) that requires multibyte
726 character encodings. As a consequence, UTF-8 content may be truncated to fit.
727 
728 Note that raw binary data can be stored in a `xsd__base64Binary` or
729 `xsd__hexBinary` structure, or transmitted as a MIME attachment.
730 
731 The built-in `_QName` type is a regular C string type (`char*`) that maps to
732 xsd:QName but has the added advantage that it holds normalized qualified names.
733 There are actually two forms of normalized QName content, to ensure any QName
734 is represented accurately and uniquely:
735 
736  prefix:name
737  "URI":name
738 
739 where the first form is used when the prefix (and the binding URI) is defined
740 in the namespace table and is bound to a URI (see the .nsmap file). The second
741 form is used when the URI is not defined in the namespace table and therefore
742 no prefix is available to bind and normalize the URI to.
743 
744 A `_QName` string may contain a sequence of space-separated QName values, not
745 just one, and all QName values are normalized to the format shown above.
746 
747 To define a `std::string` base type for xsd:QName, we use a typedef:
748 
749  typedef std::string xsd__QName;
750 
751 The `xsd__QName` string content is normalized, just as with the `_QName`
752 normalization.
753 
754 To serialize strings that contain literal XML content to be reproduced in the
755 XML value space, use the built-in `_XML` string type, which is a regular C
756 string type (`char*`) that maps to plain XML CDATA.
757 
758 To define a `std::string` base type for literal XML content, use a typedef:
759 
760  typedef std::string XML;
761 
762 Strings can hold any of the values of the XSD built-in primitive types. We can
763 use a string typedef to declare the use of the string type as a XSD built-in
764 type:
765 
766  typedef std::string xsd__token;
767 
768 We MUST ensure that the string values we populate in this type conform to the
769 XML standard, which in case of xsd:token is: the lexical and value spaces of
770 xsd:token are the sets of all strings after whitespace replacement of any
771 occurrence of `#x9`, `#xA` , and `#xD` by `#x20` and collapsing.
772 
773 Date and time types {#toxsd7}
774 -------------------
775 
776 The C/C++ `time_t` type is mapped to the built-in xsd:dateTime XSD type that
777 represents a date and time within a time zone (typically UTC).
778 
779 The XML value space contains ISO 8601 Gregorian time instances of the form
780 `[-]CCYY-MM-DDThh:mm:ss.sss[Z|(+|-)hh:mm]`, where `Z` is the UTC time zone or a
781 time zone offset `(+|-)hh:mm]` from UTC is used.
782 
783 A `time_t` value is considered and represented in UTC by the serializer.
784 
785 Because the `time_t` value range is restricted to dates after 01/01/1970, care
786 must be taken to ensure the range of xsd:dateTime values in XML exchanges do
787 not exceed the `time_t` range.
788 
789 This restriction does not hold for `struct tm` (`<time.h>`), which we can use
790 to store and communicate a date and time in UTC without date range restrictions.
791 The serializer uses the `tm` data members directly for conversion to/from the
792 XML value space of xsd:dateTime:
793 
794  struct tm
795  {
796  int tm_sec; // seconds (0 - 60)
797  int tm_min; // minutes (0 - 59)
798  int tm_hour; // hours (0 - 23)
799  int tm_mday; // day of month (1 - 31)
800  int tm_mon; // month of year (0 - 11)
801  int tm_year; // year - 1900
802  int tm_wday; // day of week (Sunday = 0) (NOT USED)
803  int tm_yday; // day of year (0 - 365) (NOT USED)
804  int tm_isdst; // is summer time in effect?
805  char* tm_zone; // abbreviation of timezone (NOT USED)
806  };
807 
808 The `struct tm` type is mapped to the built-in xsd:dateTime XSD type and
809 serialized with the custom serializer `custom/struct_tm.h` that declares a
810 `xsd__dateTime` type:
811 
812  #import "custom/struct_tm.h" // import typedef struct tm xsd__dateTime;
813  ... use xsd__dateTime ...
814 
815 Compile and link your code with `custom/struct_tm.c`.
816 
817 The `struct tm` type is mapped to the built-in xsd:date XSD type and serialized
818 with the custom serializer `custom/struct_tm_date.h` that declares a
819 `xsd__date` type:
820 
821  #import "custom/struct_tm_date.h" // import typedef struct tm xsd__date;
822  ... use xsd__date ...
823 
824 Compile and link your code with `custom/struct_tm_date.c`.
825 
826 The XML value space of xsd:date are Gregorian calendar dates of the form
827 `[-]CCYY-MM-DD[Z|(+|-)hh:mm]`.
828 
829 The `struct timeval` (`<sys/time.h>`) type is mapped to the built-in
830 xsd:dateTime XSD type and serialized with the custom serializer
831 `custom/struct_timeval.h` that declares a `xsd__dateTime` type:
832 
833  #import "custom/struct_timeval.h" // import typedef struct timeval xsd__dateTime;
834  ... use xsd__dateTime ...
835 
836 Compile and link your code with `custom/struct_timeval.c`.
837 
838 Note that the same value range restrictions apply to `struct timeval` as they
839 apply to `time_t`. The added benefit of `struct timeval` is the addition of
840 a microsecond-precise clock:
841 
842  struct timeval
843  {
844  time_t tv_sec; // seconds since Jan. 1, 1970
845  suseconds_t tv_usec; // and microseconds
846  };
847 
848 An `unsigned long long` (`ULONG64` or `uint64_t`) type that contains a 24 hour
849 time in microseconds UTC is mapped to the built-in xsd:time XSD type and
850 serialized with the custom serializer `custom/long_time.h` that declares a
851 `xsd__time` type:
852 
853  #import "custom/long_time.h" // import typedef unsigned long long xsd__time;
854  ... use xsd__time ...
855 
856 Compile and link your code with `custom/long_time.c`.
857 
858 The XML value space of xsd:time are points in time recurring each day of the
859 form `hh:mm:ss.sss[Z|(+|-)hh:mm]`, where `Z` is the UTC time zone or a time
860 zone offset from UTC is used. The `xsd__time` value is always considered and
861 represented in UTC by the serializer.
862 
863 A C++11 `std::chrono::system_clock::time_point` type is mapped to the built-in
864 xsd:dateTime XSD type and serialized with the custom serializer
865 `custom/chrono_time_point.h` that declares a `xsd__dateTime` type:
866 
867  #import "custom/chrono_time_point.h" // import typedef std::chrono::system_clock::time_point xsd__dateTime;
868  ... use xsd__dateTime ...
869 
870 Compile and link your code with `custom/chrono_time_point.cpp`.
871 
872 Time duration types {#toxsd8}
873 -------------------
874 
875 The XML value space of xsd:duration are values of the form `PnYnMnDTnHnMnS`
876 where the capital letters are delimiters. Delimiters may be omitted when the
877 corresponding member is not used.
878 
879 A `long long` (`LONG64` or `int64_t`) type that contains a duration (time
880 lapse) in milliseconds is mapped to the built-in xsd:duration XSD type and
881 serialized with the custom serializer `custom/duration.h` that declares a
882 `xsd__duration` type:
883 
884  #import "custom/duration.h" // import typedef long long xsd__duration;
885  ... use xsd__duration ...
886 
887 Compile and link your code with `custom/duration.c`.
888 
889 The duration type `xsd__duration` can represent 106,751,991,167 days forward
890 and backward with millisecond precision.
891 
892 A C++11 `std::chrono::nanoseconds` type is mapped to the built-in xsd:duration
893 XSD type and serialized with the custom serializer `custom/chrono_duration.h`
894 that declares a `xsd__duration` type:
895 
896  #import "custom/chrono_duration.h" // import typedef std::chrono::duration xsd__duration;
897  ... use xsd__duration ...
898 
899 Compile and link your code with `custom/chrono_duration.cpp`.
900 
901 Classes and structs {#toxsd9}
902 -------------------
903 
904 Classes and structs are mapped to XSD complexTypes. The XML value space
905 consists of XML elements with attributes and subelements, possibly constrained
906 by validation rules that enforce element and attribute occurrence contraints,
907 numerical value range constraints, and string length and pattern constraints.
908 
909 Classes that are declared with the gSOAP tools are limited to single
910 inheritence only. Structs cannot be inherited.
911 
912 The class and struct name is bound to an XML namespace by means of the prefix
913 naming convention or by using [colon notation](#toxsd1):
914 
915  //gsoap ns schema namespace: urn:types
916  class ns__record
917  {
918  public:
919  std::string name;
920  uint64_t SSN;
921  ns__record *spouse;
922  ns__record();
923  ~ns__record();
924  protected:
925  struct soap *soap;
926  };
927 
928 In the example above, we also added a context pointer to the `struct soap` that
929 manages this instance. It is set when the instance is created in the engine's
930 context, for example when deserialized and populated by the engine.
931 
932 The class maps to a complexType in the soapcpp2-generated schema:
933 
934  <complexType name="record">
935  <sequence>
936  <element name="name" type="xsd:string" minOccurs="1" maxOccurs="1"/>
937  <element name="SSN" type="xsd:unsignedLong" minOccurs="1" maxOccurs="1"/>
938  <element name="spouse" type="ns:record" minOccurs="0" maxOccurs="1" nillable="true"/>
939  </sequence>
940  </complexType>
941 
942 ### Serializable versus transient types and members
943 
944 Public data members of a class or struct are serialized. Private and protected
945 members are transient and not serializable.
946 
947 Also `const` and `static` members are not serializable, with the exception of
948 `const char*` and `const wchar_t*`.
949 
950 Types and specific class/struct members can be made transient by using the
951 `extern` qualifier:
952 
953  extern class std::ostream; // declare 'std::ostream' transient
954  class ns__record
955  {
956  public:
957  extern int num; // not serialized
958  std::ostream out; // not serialized
959  static const int MAX = 1024; // not serialized
960  };
961 
962 By declaring `std::ostream` transient we can use this type where we need it and
963 without soapcpp2 complaining that this class is not defined.
964 
965 ### Volatile classes and structs
966 
967 Classes and structs can be declared `volatile` with the gSOAP tools. This means
968 that they are already declared elsewhere in our project's source code. We do
969 not want soapcpp2 to generate a second definition for these types.
970 
971 For example, `struct tm` is declared in `<time.h>`. We want it serializable and
972 serialize only a selection of its data members:
973 
974  volatile struct tm
975  {
976  int tm_sec; // seconds (0 - 60)
977  int tm_min; // minutes (0 - 59)
978  int tm_hour; // hours (0 - 23)
979  int tm_mday; // day of month (1 - 31)
980  int tm_mon; // month of year (0 - 11)
981  int tm_year; // year - 1900
982  };
983 
984 We can declare classes and structs `volatile` for any such types we want to
985 serialize by only providing the public data members we want to serialize.
986 
987 Colon notation comes in handy to bind an existing class or struct to a schema.
988 For example, we can change the `tm` name as follows without affecting the code
989 that uses `struct tm` generated by soapcpp2:
990 
991  volatile struct ns:tm { ... }
992 
993 This struct maps to a complexType in the soapcpp2-generated schema:
994 
995  <complexType name="tm">
996  <sequence>
997  <element name="tm-sec" type="xsd:int" minOccurs="1" maxOccurs="1"/>
998  <element name="tm-min" type="xsd:int" minOccurs="1" maxOccurs="1"/>
999  <element name="tm-hour" type="xsd:int" minOccurs="1" maxOccurs="1"/>
1000  <element name="tm-mday" type="xsd:int" minOccurs="1" maxOccurs="1"/>
1001  <element name="tm-mon" type="xsd:int" minOccurs="1" maxOccurs="1"/>
1002  <element name="tm-year" type="xsd:int" minOccurs="1" maxOccurs="1"/>
1003  </sequence>
1004  </complexType>
1005 
1006 ### Mutable classes and structs
1007 
1008 Classes and structs can be declared `mutable` with the gSOAP tools. This means
1009 that their definition can be spread out over the source code. This promotes the
1010 concept of a class or struct as a *row of named values*, also known as a *named
1011 tuple*, that can be extended as needed with additional entries. Because these
1012 types differ from the traditional object-oriented principles of classes and
1013 objects, constructors and destructors cannot be defined (also because we cannot
1014 guarantee merging these into one such that all members will be initialized). A
1015 default constructor, copy constructor, assignment operation, and destructor
1016 will be assigned.
1017 
1018  mutable struct ns__tuple
1019  {
1020  @std::string id;
1021  };
1022 
1023  mutable struct ns__tuple
1024  {
1025  std::string name;
1026  std::string value;
1027  };
1028 
1029 The members are collected into one definition generated by soapcpp2. Members
1030 may be repeated from one definition to another, but only if their associated
1031 types are identical. So a third extension with a `value` member with a
1032 different type fails:
1033 
1034  mutable struct ns__tuple
1035  {
1036  duuble value; // BAD: value is already declared std::string
1037  };
1038 
1039 The `mutable` concept has proven to be very useful when declaring and
1040 collecting SOAP Headers for multiple services, which are collected into one
1041 `struct SOAP_ENV__Header` by the soapcpp2 tool.
1042 
1043 ### Default member values
1044 
1045 Class and struct data members may be declared with a default initialization
1046 value that is provided "inline" with the declaration of the member:
1047 
1048  class ns__record
1049  {
1050  public:
1051  std::string name = "Joe";
1052 
1053 These initializations are made by the default constructor that is added by
1054 soapcpp2 to each class and struct. A constructor is only added when a default
1055 constructor is not already defined with the class declaration.
1056 
1057 Initializations can only be provided for members that have primitive types
1058 (`bool`, `enum`, `time_t`, numeric and string types).
1059 
1060 ### Attribute members
1061 
1062 Class and struct data members can be declared as XML attributes by annotating
1063 their type with a `@` with the declaration of the member:
1064 
1065  class ns__record
1066  {
1067  public:
1068  @std::string name;
1069  @uint64_t SSN;
1070  ns__record *spouse;
1071  };
1072 
1073 This class maps to a complexType in the soapcpp2-generated schema:
1074 
1075  <complexType name="record">
1076  <sequence>
1077  <element name="spouse" type="ns:record" minOccurs="0" maxOccurs="1" nillable="true"/>
1078  </sequence>
1079  <attribute name="name" type="xsd:string" use="required"/>
1080  <attribute name="SSN" type="xsd:unsignedLong" use="required"/>
1081  </complexType>
1082 
1083 An example XML instance of `ns__record` is:
1084 
1085  <ns:record xmlns:ns="urn:types" name="Joe" SSN="1234567890">
1086  <spouse>
1087  <name>Jane</name>
1088  <SSN>1987654320</SSN>
1089  </spouse>
1090  </ns:record>
1091 
1092 Attribute data members are restricted to primitive types (`bool`, `enum`,
1093 `time_t`, numeric and string types), `xsd__hexBinary`, `xsd__base64Binary`, and
1094 custom serializers, such as `xsd__dateTime`. Custom serializers for types that
1095 may be used as attributes MUST define `soap_s2T` and `soap_T2s` functions that
1096 convert values of type `T` to strings and back.
1097 
1098 Attribute data members can be pointers and smart pointers to these types, which
1099 permits attributes to be optional.
1100 
1101 ### (Smart) pointer members and their occurrence constraints
1102 
1103 A public pointer-typed data member is serialized by following its (smart)
1104 pointer(s) to the value pointed to.
1105 
1106 Pointers that are NULL and smart pointers that are empty are serialized to
1107 produce omitted element and attribute values, unless an element is required
1108 and is nillable.
1109 
1110 To control the occurrence requirements of pointer-based data members,
1111 occurrence constraints are associated with data members in the form of a range
1112 `minOccurs : maxOccurs`. For non-repeatable (meaning, not a container or array)
1113 data members, there are only three reasonable occurrence constraints:
1114 
1115 - `0:0` means that this element or attribute is prohibited.
1116 - `0:1` means that this element or attribute is optional.
1117 - `1:1` means that this element or attribute is required.
1118 
1119 Pointer-based data members have a default `0:1` occurrence constraint, making
1120 them optional, and their XSD schema local element/attribute definition is
1121 marked as nillable. Non-pointer data members have a default `1:1` occurence
1122 constraint, making them required.
1123 
1124 A pointer data member that is explicitly marked as required with `1:1` will be
1125 serialized as an element with an xsi:nil attribute, thus effectively revealing
1126 the NULL property of its value.
1127 
1128 A non-pointer data member that is explicitly marked as optional with `0:1` will
1129 be set to its default value when no XML value is presented to the deserializer.
1130 A default value can be assigned to data members that have primitive types.
1131 
1132 Consider for example:
1133 
1134  class ns__record
1135  {
1136  public:
1137  std::shared_ptr<std::string> name; // optional (0:1)
1138  uint64_t SSN 0:1 = 999; // forced this to be optional with default 999
1139  ns__record *spouse 1:1; // forced this to be required (only married people)
1140  };
1141 
1142 This class maps to a complexType in the soapcpp2-generated schema:
1143 
1144  <complexType name="record">
1145  <sequence>
1146  <element name="name" type="xsd:string" minOccurs="0" maxOccurs="1" nillable="true"/>
1147  <element name="SSN" type="xsd:unsignedLong" minOccurs="0" maxOccurs="1" default="999"/>
1148  <element name="spouse" type="ns:record" minOccurs="1" maxOccurs="1" nillable="true"/>
1149  </sequence>
1150  </complexType>
1151 
1152 An example XML instance of `ns__record` with its `name` string value set to
1153 `Joe`, `SSN` set to its default, and `spouse` set to NULL:
1154 
1155  <ns:record xmlns:ns="urn:types">
1156  <name>Joe</name>
1157  <SSN>999</SSN>
1158  <spouse xsi:nil="true"/>
1159  </ns:record>
1160 
1161 ### Container members and their occurrence constraints
1162 
1163 Class and struct data members declared as a container `std::deque`, `std::list`,
1164 `std::set`, and `std::vector` are serialized as a collection of values:
1165 
1166  class ns__record
1167  {
1168  public:
1169  std::vector<std::string> names;
1170  uint64_t SSN;
1171  };
1172 
1173 To practically limit the number of names within reasonable bounds, occurrence
1174 constraints are associated with the container. Occurrence constraints are of
1175 the form `minOccurs : maxOccurs`:
1176 
1177  class ns__record
1178  {
1179  public:
1180  std::vector<std::string> names 1:10;
1181  uint64_t SSN;
1182  };
1183 
1184 This class maps to a complexType in the soapcpp2-generated schema:
1185 
1186  <complexType name="record">
1187  <sequence>
1188  <element name="name" type="xsd:string" minOccurs="1" maxOccurs="10"/>
1189  <element name="SSN" type="xsd:unsignedLong" minOccurs="1" maxOccurs="1""/>
1190  </sequence>
1191  </complexType>
1192 
1193 Because C does not support a container template library, we can use a
1194 dynamically-sized array of values. This array is declared as a size-pointer
1195 member pair:
1196 
1197  struct ns__record
1198  {
1199  $int sizeofnames; // array size
1200  char* *names; // array of char* names
1201  uint64_t SSN;
1202  };
1203 
1204 where the marker `$` with `int` denotes a special type that is used to store
1205 the array size and to indicate that this is a size-pointer member pair that
1206 declares a dynamically-sized array.
1207 
1208 This class maps to a complexType in the soapcpp2-generated schema:
1209 
1210  <complexType name="record">
1211  <sequence>
1212  <element name="name" type="xsd:string" minOccurs="0" maxOccurs="unbounded" nillable="true"/>
1213  <element name="SSN" type="xsd:unsignedLong" minOccurs="1" maxOccurs="1""/>
1214  </sequence>
1215  </complexType>
1216 
1217 To limit the number of names in the array within reasonable bounds, occurrence
1218 constraints are associated with the array size member. Occurrence constraints
1219 are of the form `minOccurs : maxOccurs`:
1220 
1221  struct ns__record
1222  {
1223  $int sizeofnames 1:10; // array size 1..10
1224  char* *names; // array of one to ten char* names
1225  uint64_t SSN;
1226  };
1227 
1228 This class maps to a complexType in the soapcpp2-generated schema:
1229 
1230  <complexType name="record">
1231  <sequence>
1232  <element name="name" type="xsd:string" minOccurs="1" maxOccurs="10" nillable="true"/>
1233  <element name="SSN" type="xsd:unsignedLong" minOccurs="1" maxOccurs="1""/>
1234  </sequence>
1235  </complexType>
1236 
1237 ### Union members
1238 
1239 A union member in a class or in a struct cannot be serialized unless a
1240 discriminating variant selector is provided that tells the serializer which
1241 union field to serialize.
1242 
1243 The variant selector is associated with the union as a selector-union member
1244 pair, where the variant selector is a special `$int` member:
1245 
1246  class ns__record
1247  {
1248  public:
1249  $int xORnORs; // variant selector
1250  union choice
1251  {
1252  float x;
1253  int n;
1254  char *s;
1255  } u;
1256  std::string name;
1257  };
1258 
1259 The variant selector values are auto-generated based on the union name `choice`
1260 and the names of its members `x`, `n`, and `s`:
1261 
1262 - `xORnORs = SOAP_UNION_choice_x` when `u.x` is valid.
1263 - `xORnORs = SOAP_UNION_choice_n` when `u.n` is valid.
1264 - `xORnORs = SOAP_UNION_choice_s` when `u.s` is valid.
1265 - `xORnORs = 0` when none are valid (should only be used with great care,
1266  because XML content validation may fail when content is required but absent).
1267 
1268 This class maps to a complexType with a sequence and choice in the
1269 soapcpp2-generated schema:
1270 
1271  <complexType name="record">
1272  <sequence>
1273  <choice>
1274  <element name="x" type="xsd:float" minOccurs="1" maxOccurs="1"/>
1275  <element name="n" type="xsd:int" minOccurs="1" maxOccurs="1"/>
1276  <element name="s" type="xsd:string" minOccurs="0" maxOccurs="1" nillable="true"/>
1277  </choice>
1278  <element name="names" type="xsd:string" minOccurs="1" maxOccurs="10" nillable="true"/>
1279  </sequence>
1280  </complexType>
1281 
1282 ### Adding get and set methods
1283 
1284 A public `get` method may be added to a class or struct, which will be
1285 triggered by the deserializer. This method will be invoked right after the
1286 instance is populated by the deserializer. The `get` method can be used to
1287 update or verify deserialized content. It should return `SOAP_OK` or set
1288 `soap::error` to a nonzero error code and return it.
1289 
1290 A public `set` method may be added to a class or struct, which will be
1291 triggered by the serializer. The method will be invoked just before the
1292 instance is serialized. Likewise, the `set` method should return `SOAP_OK` or
1293 set set `soap::error` to a nonzero error code and return it.
1294 
1295 For example, adding a `set` and `get` method to a class declaration:
1296 
1297  class ns__record
1298  {
1299  public:
1300  int set(struct soap*); // triggered before serialization
1301  int get(struct soap*); // triggered after deserialization
1302 
1303 To add these and othe rmethods to classes and structs with wsdl2h and
1304 `typemap.dat`, please see section [class and struct addition](#typemap3).
1305 
1306 ### Defining document root elements
1307 
1308 To define and reference XML document root elements we use type names that start
1309 with an underscore:
1310 
1311  class _ns__record
1312 
1313 Alternatively, we can use a typedef to define a document root element with a
1314 given type:
1315 
1316  typedef ns__record _ns__record;
1317 
1318 This typedef maps to a global root element that is added to the
1319 soapcpp2-generated schema:
1320 
1321  <element name="record" type="ns:record"/>
1322 
1323 An example XML instance of `_ns__record` is:
1324 
1325  <ns:record xmlns:ns="urn:types">
1326  <name>Joe</name>
1327  <SSN>1234567890</SSN>
1328  <spouse>
1329  <name>Jane</name>
1330  <SSN>1987654320</SSN>
1331  </spouse>
1332  </ns:record>
1333 
1334 Global-level element/attribute definitions are also referenced and/or added to
1335 the generated schema when serializable data members reference these by their
1336 qualified name:
1337 
1338  typedef std::string _ns__name 1:100;
1339  class _ns__record
1340  {
1341  public:
1342  @_QName xsi__type; // built-in XSD attribute xsi:type
1343  _ns__name ns__name; // ref to global ns:name element
1344  uint64_t SSN;
1345  _ns__record *spouse;
1346  };
1347 
1348 These types map to the following comonents in the soapcpp2-generated schema:
1349 
1350  <simpleType name="name">
1351  <restriction base="xsd:string">
1352  <minLength value="1"/>
1353  <maxLength value="100"/>
1354  </restriction>
1355  </simpleType>
1356  <element name="name" type="ns:name"/>
1357  <complexType name="record">
1358  <sequence>
1359  <element ref="ns:name" minOccurs="1" maxOccurs="1"/>
1360  <element name="SSN" type="xsd:unsignedLong" minOccurs="1" maxOccurs="1"/>
1361  <element name="spouse" type="ns:record" minOccurs="0" maxOccurs="1" nillable="true"/>
1362  </sequence>
1363  <attribute ref="xsi:type" use="optional"/>
1364  </complexType>
1365  <element name="record" type="ns:record"/>
1366 
1367 However, we must warn against using qualified member names when their types do
1368 not match their definitions:
1369 
1370  class _ns__record
1371  {
1372  public:
1373  int ns__name; // BAD: element ns:name is NOT of an int type
1374 
1375 Therefore, we recommend to avoid qualified member names and only use them when
1376 referring to standard XSD elements and attributes, such as `xsi__type`, and
1377 `xsd__lang`. The soapcpp2 tool does not prevent abuse of this mechanism.
1378 
1379 ### Operations on classes and structs
1380 
1381 The following functions/macros are generated by soapcpp2 for each type `T`,
1382 which should make it easier to send, receive, and copy XML data in C and in
1383 C++:
1384 
1385 - `int soap_write_T(struct soap*, T*)` writes an instance of `T` to a FILE (via
1386  `FILE *soap::sendfd)`) or to a stream (via `std::ostream *soap::os`).
1387  Returns `SOAP_OK` on success or an error code, also stored in `soap->error`.
1388 
1389 - `int soap_read_T(struct soap*, T*)` reads an instance of `T` from a FILE (via
1390  `FILE *soap::recvfd)`) or from a stream (via `std::istream *soap::is`).
1391  Returns `SOAP_OK` on success or an error code, also stored in `soap->error`.
1392 
1393 - `void soap_default_T(struct soap*, T*)` sets an instance `T` to its default
1394  value, resetting members of a struct to their initial values (for classes we
1395  use method `T::soap_default`, see below).
1396 
1397 - `T * soap_dup_T(struct soap*, T *dst, const T *src)` (soapcpp2 option `-Ec`)
1398  deep copy `src` into `dst`, replicating all deep cycles and shared pointers
1399  when a managing soap context is provided as argument. When `dst` is NULL,
1400  allocates space for `dst`. Deep copy is a tree when argument is NULL, but the
1401  presence of deep cycles will lead to non-termination. Use flag
1402  `SOAP_XML_TREE` with managing context to copy into a tree without cycles and
1403  pointers to shared objects. Returns `dst` (or allocated space when `dst` is
1404  NULL).
1405 
1406 - `void soap_del_T(const T*)` (soapcpp2 option `-Ed`) deletes all
1407  heap-allocated members of this object by deep deletion ONLY IF this object
1408  and all of its (deep) members are not managed by a soap context AND the deep
1409  structure is a tree (no cycles and co-referenced objects by way of multiple
1410  (non-smart) pointers pointing to the same data). Can be safely used after
1411  `soap_dup(NULL)` to delete the deep copy. Does not delete the object itself.
1412 
1413 When in C++ mode, soapcpp2 tool adds several methods to classes and structs, in
1414 addition to adding a default constructor and destructor (when these were not
1415 explicitly declared).
1416 
1417 The public methods added to a class/struct `T`:
1418 
1419 - `virtual int T::soap_type(void)` returns a unique type ID (`SOAP_TYPE_T`).
1420  This numeric ID can be used to distinguish base from derived instances.
1421 
1422 - `virtual void T::soap_default(struct soap*)` sets all data members to
1423  default values.
1424 
1425 - `virtual void T::soap_serialize(struct soap*) const` serializes object to
1426  prepare for SOAP 1.1/1.2 encoded output (or with `SOAP_XML_GRAPH`) by
1427  analyzing its (cyclic) structures.
1428 
1429 - `virtual int T::soap_put(struct soap*, const char *tag, const char *type) const`
1430  emits object in XML, compliant with SOAP 1.1 encoding style, return error
1431  code or `SOAP_OK`. Requires `soap_begin_send(soap)` and
1432  `soap_end_send(soap)`.
1433 
1434 - `virtual int T::soap_out(struct soap*, const char *tag, int id, const char *type) const`
1435  emits object in XML, with tag and optional id attribute and xsi:type, return
1436  error code or `SOAP_OK`. Requires `soap_begin_send(soap)` and
1437  `soap_end_send(soap)`.
1438 
1439 - `virtual void * T::soap_get(struct soap*, const char *tag, const char *type)`
1440  Get object from XML, compliant with SOAP 1.1 encoding style, return pointer
1441  to object or NULL on error. Requires `soap_begin_recv(soap)` and
1442  `soap_end_recv(soap)`.
1443 
1444 - `virtual void *soap_in(struct soap*, const char *tag, const char *type)`
1445  Get object from XML, with matching tag and type (NULL matches any tag and
1446  type), return pointer to object or NULL on error. Requires
1447  `soap_begin_recv(soap)` and `soap_end_recv(soap)`
1448 
1449 - `virtual T * T::soap_alloc(void) const` returns a new object of type `T`,
1450  default initialized and not managed by a soap context.
1451 
1452 - `virtual T * T::soap_dup(struct soap*) const` (soapcpp2 option `-Ec`) returns
1453  a duplicate of this object by deep copying, replicating all deep cycles and
1454  shared pointers when a managing soap context is provided as argument. Deep
1455  copy is a tree when argument is NULL, but the presence of deep cycles will
1456  lead to non-termination. Use flag `SOAP_XML_TREE` with managing context to
1457  copy into a tree without cycles and pointers to shared objects.
1458 
1459 - `virtual void T::soap_del() const` (soapcpp2 option `-Ed`) deletes all
1460  heap-allocated members of this object by deep deletion ONLY IF this object
1461  and all of its (deep) members are not managed by a soap context AND the deep
1462  structure is a tree (no cycles and co-referenced objects by way of multiple
1463  (non-smart) pointers pointing to the same data).Can be safely used after
1464  `soap_dup(NULL)` to delete the deep copy. Does not delete the object itself.
1465 
1466 Special classes and structs {#toxsd10}
1467 ---------------------------
1468 
1469 A class or struct with the following layout is a one-dimensional SOAP Array
1470 type:
1471 
1472  class Array
1473  {
1474  public:
1475  T *__ptr; // array pointer
1476  int __size; // array size
1477  };
1478 
1479 where `T` is the array element type. A multidimensional SOAP Array is:
1480 
1481  class Array
1482  {
1483  public:
1484  T *__ptr; // array pointer
1485  int __size[N]; // array size of each dimension
1486  };
1487 
1488 where `N` is the constant number of dimensions. The pointer points to an array
1489 of `__size[0]*__size[1]* ... * __size[N-1]` elements.
1490 
1491 A special case of a one-dimensional array is used to define xsd:hexBinary and
1492 xsd:base64Binary types when the pointer type is `unsigned char`:
1493 
1494  class xsd__hexBinary
1495  {
1496  public:
1497  unsigned char *__ptr; // points to raw binary data
1498  int __size; // size of data
1499  };
1500 
1501 and
1502 
1503  class xsd__base64Binary
1504  {
1505  public:
1506  unsigned char *__ptr; // points to raw binary data
1507  int __size; // size of data
1508  };
1509 
1510 A class or struct with a binary content layout can be extended to support
1511 MIME/MTOM (and older DIME) attachments, such as in xop:Include elements:
1512 
1513  //gsoap xop schema import: http://www.w3.org/2004/08/xop/include
1514  class _xop__Include
1515  {
1516  public:
1517  unsigned char *__ptr; // points to raw binary data
1518  int __size; // size of data
1519  char *id; // NULL to generate an id, or set to a unique UUID
1520  char *type; // MIME type of the data
1521  char *options; // optional description of MIME attachment
1522  };
1523 
1524 Attachments are beyond the scope of this document and we refer to the gSOAP
1525 user guide for more details.
1526 
1527 A class or struct with the following layout is a complexType with simpleContent
1528 wrapper:
1529 
1530  class ns__simple
1531  {
1532  public:
1533  T __item;
1534  };
1535 
1536 A wrapper class/struct may have any number of attributes declared with `@`.
1537 
1538 Memory management {#memory}
1539 =================
1540 
1541 Memory management with the `soap` context enables us to allocate data in
1542 context-managed heap space that can be collectively deleted. All deserialized
1543 data is placed on the context-managed heap by the gSOAP engine.
1544 
1545 Memory management in C {#memory1}
1546 ----------------------
1547 
1548 In C (wsdl2h option `-c` and soapcpp2 option `-c`), the gSOAP engine allocates
1549 data on a context-managed heap with:
1550 
1551 - `void *soap_malloc(struct soap*, size_t len)`.
1552 
1553 The `soap_malloc` function is a wrapper around `malloc`, but which also allows
1554 the `struct soap` context to track all heap allocations for collective deletion
1555 with `soap_end(soap)`:
1556 
1557  #include "soapH.h"
1558  #include "ns.nsmap"
1559  ...
1560  struct soap *soap = soap_new(); // new context
1561  ...
1562  struct ns__record *record = soap_malloc(soap, sizeof(struct ns__record));
1563  soap_default_ns__record(soap, record);
1564  ...
1565  soap_destroy(soap); // only for C++, see section on C++ below
1566  soap_end(soap); // delete record and all other heap allocations
1567  soap_free(soap); // delete context
1568 
1569 The soapcpp2 auto-generated deserializers in C use `soap_malloc` to allocate
1570 and populate deserialized structures, which are managed by the context for
1571 collective deletion.
1572 
1573 To make `char*` and `wchar_t*` string copies to the context-managed heap, we
1574 can use the functions:
1575 
1576 - `char *soap_strdup(struct soap*, const char*)` and
1577 
1578 - `wchar_t *soap_wstrdup(struct soap*, const wchar_t*)`.
1579 
1580 We use the soapcpp2 auto-generated `soap_dup_T` functions to duplicate data
1581 into another context (this requires soapcpp2 option `-Ec` to generate), here
1582 shown for C:
1583 
1584  struct soap *other_soap = soap_new(); // another context
1585  struct ns__record *other_record = soap_dup_ns__record(other_soap, NULL, record);
1586  ...
1587  soap_destroy(other_soap); // only for C++, see section on C++ below
1588  soap_end(other_soap); // delete other_record and all of its deep data
1589  soap_free(other_soap); // delete context
1590 
1591 Note that the only reason to use another context and not to use the primary
1592 context is when the primary context must be destroyed together with all of the
1593 objects it manages while some of the objects must be kept alive. If the objects
1594 that are kept alive contain deep cycles then this is the only option we have,
1595 because deep copy with a managing context detects and preserves these
1596 cycles unless the `SOAP_XML_TREE` flag is used with the context:
1597 
1598  struct soap *other_soap = soap_new1(SOAP_XML_TREE); // another context
1599  struct ns__record *other_record = soap_dup_ns__record(other, NULL, record);
1600 
1601 The resulting deep copy will be a full copy of the source data structure as a
1602 tree without co-referenced data (i.e. no digraph) and without cycles. Cycles
1603 are pruned and (one of the) pointers that forms a cycle is repaced by NULL.
1604 
1605 We can also deep copy into unmanaged space and use the auto-generated
1606 `soap_del_T()` function (requires soapcpp2 option `-Ed` to generate) to delete
1607 it later, but we MUST NOT do this for any data that we suspect has deep cycles:
1608 
1609  struct ns__record *other_record = soap_dup_ns__record(NULL, NULL, record);
1610  ...
1611  soap_del_ns__record(other_record); // deep delete record data members
1612  free(other_record); // delete the record
1613 
1614 Cycles in the data structure will lead to non-termination when making unmanaged
1615 deep copies. Consider for example:
1616 
1617  struct ns__record
1618  {
1619  const char *name;
1620  uint64_t SSN;
1621  ns__record *spouse;
1622  };
1623 
1624 Our code to populate a structure with a mutual spouse relationship:
1625 
1626  struct soap *soap = soap_new();
1627  ...
1628  struct ns__record pers1, pers2;
1629  soap_default_ns__record(soap, &pers1);
1630  soap_default_ns__record(soap, &pers2);
1631  pers1.name = "Joe"; // OK to serialize static data
1632  pers1.SSN = 1234567890;
1633  pers1.spouse = &pers2;
1634  pers2.name = soap_strdup(soap, "Jane"); // allocates and copies a string
1635  pers2.SSN = 1987654320;
1636  pers2.spouse = &pers1;
1637  ...
1638  struct ns__record *pers3 = soap_dup_ns__record(NULL, NULL, &pers1); // BAD
1639  struct ns__record *pers4 = soap_dup_ns__record(soap, NULL, &pers1); // OK
1640  soap_set_mode(soap, SOAP_XML_TREE);
1641  struct ns__record *pers5 = soap_dup_ns__record(soap, NULL, &pers1); // OK
1642 
1643 As we can see, the gSOAP serializer can serialize any heap, stack, or static
1644 allocated data, such as in our code above. So we can serialize the
1645 stack-allocated `pers1` record as follows:
1646 
1647  soap->sendfd = fopen("record.xml", "w");
1648  soap_set_mode(soap, SOAP_XML_GRAPH); // support id-ref w/o requiring SOAP
1649  soap_clr_mode(soap, SOAP_XML_TREE); // if set, clear
1650  soap_write_ns__record(soap, &pers1);
1651  fclose(soap->sendfd);
1652  soap->sendfd = NULL;
1653 
1654 which produces an XML document record.xml that is similar to:
1655 
1656  <ns:record xmlns:ns="urn:types" id="Joe">
1657  <name>Joe</name>
1658  <SSN>1234567890</SSN>
1659  <spouse id="Jane">
1660  <name>Jane</name>
1661  <SSN>1987654320</SSN>
1662  <spouse ref="#Joe"/>
1663  </spouse>
1664  </ns:record>
1665 
1666 Deserialization of an XML document with a SOAP 1.1/1.2 encoded id-ref graph
1667 leads to the same non-termination problem when we later try to copy the data
1668 into unmanaged space:
1669 
1670  struct soap *soap = soap_new1(SOAP_XML_GRAPH); // support id-ref w/o SOAP
1671  ...
1672  struct ns__record pers1;
1673  soap->recvfd = fopen("record.xml", "r");
1674  soap_read_ns__record(soap, &pers1);
1675  fclose(soap->recvfd);
1676  soap->recvfd = NULL;
1677  ...
1678  struct ns__record *pers3 = soap_dup_ns__record(NULL, NULL, &pers1); // BAD
1679  struct ns__record *pers4 = soap_dup_ns__record(soap, NULL, &pers1); // OK
1680  soap_set_mode(soap, SOAP_XML_TREE);
1681  struct ns__record *pers5 = soap_dup_ns__record(soap, NULL, &pers1); // OK
1682 
1683 Copying data with `soap_dup_T(soap)` into managed space is always safe. Copying
1684 into unmanaged space requires diligence. But deleting unmanaged data is easy
1685 with `soap_del_T()`.
1686 
1687 We can also use `soap_del_T()` to delete structures that we created in C, but
1688 only if these structures are created with `malloc` and do NOT contain pointers
1689 to stack and static data.
1690 
1691 Memory management in C++ {#memory2}
1692 ------------------------
1693 
1694 In C++, the gSOAP engine allocates data on a managed heap using a combination
1695 of `void *soap_malloc(struct soap*, size_t len)` and `soap_new_T()`, where `T`
1696 is the name of a class, struct, or class template (container or smart pointer).
1697 Heap allocation is tracked by the `struct soap` context for collective
1698 deletion with `soap_destroy(soap)` and `soap_end(soap)`.
1699 
1700 Only structs, classes, and class templates are allocated with `new` via
1701 `soap_new_T(struct soap*)` and mass-deleted with `soap_destroy(soap)`.
1702 
1703 There are four variations of `soap_new_T` for class/struct/template type `T`
1704 that soapcpp2 auto-generates to create instances on a context-managed heap:
1705 
1706 - `T* soap_new_T(struct soap*)` returns a new instance of `T` with default data
1707  member initializations that are set with the soapcpp2 auto-generated `void
1708  T::soap_default(struct soap*)` method), but ONLY IF the soapcpp2
1709  auto-generated default constructor is used that invokes `soap_default()` and
1710  was not replaced by a user-defined default constructor.
1711 
1712 - `T* soap_new_T(struct soap*, int n)` returns an array of `n` new instances of
1713  `T`. Similar to the above, instances are initialized.
1714 
1715 - `T* soap_new_req_T(struct soap*, ...)` returns a new instance of `T` and sets
1716  the required data members to the values specified in `...`. The required data
1717  members are those with minOccurs > 0, see the subsection on occurrence
1718  constraints in [Classes and structs](#toxsd9).
1719 
1720 - `T* soap_new_set_T(struct soap*, ...)` returns a new instance of `T` and sets
1721  the public/serializable data members to the values specified in `...`.
1722 
1723 The above functions can be invoked with a NULL `soap` context, but we will be
1724 responsible to use `delete T` to remove this instance from the unmanaged heap.
1725 
1726 Primitive types and arrays of these are allocated with `soap_malloc` by the
1727 gSOAP engine. As we stated above, all types except for classes, structs, class
1728 templates (containers and smart pointers) are allocated with `soap_malloc` for
1729 reasons of efficiency.
1730 
1731 We can use a C++ template to simplify the managed allocation and initialization
1732 of primitive values as follows (this is for primitive types only, because we
1733 should allocate structs and classes with `soap_new_T`):
1734 
1735  template<class T>
1736  T* soap_make(struct soap *soap, T val)
1737  {
1738  T *p = (T*)soap_malloc(soap, sizeof(T));
1739  if (p)
1740  *p = val;
1741  return p;
1742  }
1743 
1744 For example, assuming we have the following class:
1745 
1746  class ns__record
1747  {
1748  public:
1749  std::string name; // required name
1750  uint64_t *SSN; // optional SSN
1751  ns__record *spouse; // optional spouse
1752  };
1753 
1754 We can instantiate a record by using the auto-generated
1755 `soap_new_set_ns__record` and our `soap_make` to create a SSN value on the
1756 managed heap:
1757 
1758  soap *soap = soap_new(); // new context
1759  ...
1760  ns__record *record = soap_new_set_ns__record(
1761  soap,
1762  "Joe",
1763  soap_make<uint64_t>(soap, 1234567890),
1764  NULL);
1765  ...
1766  soap_destroy(soap); // delete record and all other managed instances
1767  soap_end(soap); // delete managed soap_malloc'ed heap data
1768  soap_free(soap); // delete context
1769 
1770 Note however that the gSOAP serializer can serialize any heap, stack, or static
1771 allocated data. So we can also create a new record as follows:
1772 
1773  uint64_t SSN = 1234567890;
1774  ns__record *record = soap_new_set_ns__record(soap, "Joe", &SSN, NULL);
1775 
1776 which will be fine to serialize this record as long as the local `SSN`
1777 stack-allocated value remains in scope when invoking the serializer and/or
1778 using `record`. It does not matter if `soap_destroy` and `soap_end` are called
1779 beyond the scope of `SSN`.
1780 
1781 To facilitate our class methods to access the managing context, we can add a
1782 soap context pointer to a class/struct:
1783 
1784  class ns__record
1785  {
1786  ...
1787  void create_more(); // needs a context to create more internal data
1788  protected:
1789  struct soap *soap; // the context that manages this instance, or NULL
1790  };
1791 
1792 The context is set when invoking `soap_new_T` (and similar) with a non-NULL
1793 context argument.
1794 
1795 We use the soapcpp2 auto-generated `soap_dup_T` functions to duplicate data
1796 into another context (this requires soapcpp2 option `-Ec` to generate):
1797 
1798  soap *other_soap = soap_new(); // another context
1799  ns__record *other_record = soap_dup_ns__record(other, NULL, record);
1800  ...
1801  soap_destroy(other_soap); // delete record and other managed instances
1802  soap_end(other_soap); // delete other data (the SSNs on the heap)
1803  soap_free(other_soap); // delete context
1804 
1805 To duplicate derived instances when a base class instance is provided, use the
1806 auto-generated method `T* T::soap_dup(struct soap*)`:
1807 
1808  soap *other_soap = soap_new(); // another context
1809  ns__record *other_record = soap_dup_ns__record(other_soap, NULL, record);
1810  ...
1811  soap_destroy(other_soap); // delete record and other managed instances
1812  soap_end(other_soap); // delete other data (the SSNs on the heap)
1813  soap_free(other_soap); // delete context
1814 
1815 Note that the only reason to use another context and not to use the primary
1816 context is when the primary context must be destroyed together with all of the
1817 objects it manages while some of the objects must be kept alive. If the objects
1818 that are kept alive contain deep cycles then this is the only option we have,
1819 because deep copy with a managing context detects and preserves these
1820 cycles unless the `SOAP_XML_TREE` flag is used with the context:
1821 
1822  soap *other_soap = soap_new1(SOAP_XML_TREE); // another context
1823  ns__record *other_record = record->soap_dup(other_soap);
1824 
1825 The resulting deep copy will be a full copy of the source data structure as a
1826 tree without co-referenced data (i.e. no digraph) and without cycles. Cycles
1827 are pruned and (one of the) pointers that forms a cycle is repaced by NULL.
1828 
1829 We can also deep copy into unmanaged space and use the auto-generated
1830 `soap_del_T()` function or the `T::soap_del()` method (requires soapcpp2 option
1831 `-Ed` to generate) to delete it later, but we MUST NOT do this for any data
1832 that we suspect has deep cycles:
1833 
1834  ns__record *other_record = record->soap_dup(NULL);
1835  ...
1836  other_record->soap_del(); // deep delete record data members
1837  delete other_record; // delete the record
1838 
1839 Cycles in the data structure will lead to non-termination when making unmanaged
1840 deep copies. Consider for example:
1841 
1842  class ns__record
1843  {
1844  const char *name;
1845  uint64_t SSN;
1846  ns__record *spouse;
1847  };
1848 
1849 Our code to populate a structure with a mutual spouse relationship:
1850 
1851  soap *soap = soap_new();
1852  ...
1853  ns__record pers1, pers2;
1854  pers1.name = "Joe";
1855  pers1.SSN = 1234567890;
1856  pers1.spouse = &pers2;
1857  pers2.name = "Jane";
1858  pers2.SSN = 1987654320;
1859  pers2.spouse = &pers1;
1860  ...
1861  ns__record *pers3 = soap_dup_ns__record(NULL, NULL, &pers1); // BAD
1862  ns__record *pers4 = soap_dup_ns__record(soap, NULL, &pers1); // OK
1863  soap_set_mode(soap, SOAP_XML_TREE);
1864  ns__record *pers5 = soap_dup_ns__record(soap, NULL, &pers1); // OK
1865 
1866 Note that the gSOAP serializer can serialize any heap, stack, or static
1867 allocated data, such as in our code above. So we can serialize the
1868 stack-allocated `pers1` record as follows:
1869 
1870  soap->sendfd = fopen("record.xml", "w");
1871  soap_set_mode(soap, SOAP_XML_GRAPH); // support id-ref w/o requiring SOAP
1872  soap_clr_mode(soap, SOAP_XML_TREE); // if set, clear
1873  soap_write_ns__record(soap, &pers1);
1874  fclose(soap->sendfd);
1875  soap->sendfd = NULL;
1876 
1877 which produces an XML document record.xml that is similar to:
1878 
1879  <ns:record xmlns:ns="urn:types" id="Joe">
1880  <name>Joe</name>
1881  <SSN>1234567890</SSN>
1882  <spouse id="Jane">
1883  <name>Jane</name>
1884  <SSN>1987654320</SSN>
1885  <spouse ref="#Joe"/>
1886  </spouse>
1887  </ns:record>
1888 
1889 Deserialization of an XML document with a SOAP 1.1/1.2 encoded id-ref graph
1890 leads to the same non-termination problem when we later try to copy the data
1891 into unmanaged space:
1892 
1893  soap *soap = soap_new1(SOAP_XML_GRAPH); // support id-ref w/o SOAP
1894  ...
1895  ns__record pers1;
1896  soap->recvfd = fopen("record.xml", "r");
1897  soap_read_ns__record(soap, &pers1);
1898  fclose(soap->recvfd);
1899  soap->recvfd = NULL;
1900  ...
1901  ns__record *pers3 = soap_dup_ns__record(NULL, NULL, &pers1); // BAD
1902  ns__record *pers4 = soap_dup_ns__record(soap, NULL, &pers1); // OK
1903  soap_set_mode(soap, SOAP_XML_TREE);
1904  ns__record *pers5 = soap_dup_ns__record(soap, NULL, &pers1); // OK
1905 
1906 Copying data with `soap_dup_T(soap)` into managed space is always safe. Copying
1907 into unmanaged space requires diligence. But deleting unmanaged data is easy
1908 with `soap_del_T()`.
1909 
1910 We can also use `soap_del_T()` to delete structures in C++, but only if these
1911 structures are created with `new` (and `new []` for arrays when applicable) for
1912 classes, structs, and class templates and with `malloc` for anything else, and
1913 the structures do NOT contain pointers to stack and static data.
1914 
1915 Features and limitations {#features}
1916 ========================
1917 
1918 There are several context initialization flags and mode flags to control XML
1919 serialization at runtime:
1920 
1921 - `SOAP_XML_STRICT`: strictly validates XML while deserializing. Should not be
1922  used together with SOAP 1.1/1.2 encoding style of messaging.
1923 
1924 - `SOAP_XML_INDENT`: produces indented XML.
1925 
1926 - `SOAP_XML_CANONICAL`: c14n canonocalization, removes unnecessary `xmlns`
1927  bindings and adds them to appropriate places by applying c14n normalization
1928  rules. Should not be used together with SOAP 1.1/1.2 encoding style of
1929  messaging.
1930 
1931 - `SOAP_XML_TREE`: write tree XML without id-ref, pruning data structure
1932  cycles to prevent nontermination.
1933 
1934 - `SOAP_XML_GRAPH`: write graph (digraph and cyclic graphs with shared pointers
1935  to objects) using id-ref attributes. That is, XML with SOAP multi-ref
1936  encoded id-ref elements. This is a structure-preserving serialization format,
1937  because co-referenced data and also cyclic relations are accurately represented.
1938 
1939 - `SOAP_XML_DEFAULTNS`: uses xmlns default bindings, assuming that the schema
1940  element form is "qualified" by default (be warned if it is not!).
1941 
1942 - `SOAP_XML_NOTYPE`: removes all xsi:type attribuation. This may affect the
1943  quality of the deserializer, which relies on xsi:type attributes to distinguish
1944  base class instances from derived class instanced.
1945 
1946 - `SOAP_C_UTFSTRING`: enables all `std::string` and `char*` strings to
1947  contain UTF-8 content.
1948 
1949 Additional notes with respect to the wsdl2h and soapcpp2 tools:
1950 
1951 - Nested classes, structs, and typedefs in a gSOAP header file are unnested by
1952  soapcpp2.
1953 
1954 - Use `#import "file.h"` instead of `#include` to import other header files in
1955  a gSOAP header file for soapcpp2. The `#include` and `#define` directives are
1956  accepted, but deferred to the generated code.
1957 
1958 - To remove any SOAP-specific bindings, use soapcpp2 option `-0`.
1959 
1960 - A gSOAP header file for soapcpp2 should not include any code statements, only
1961  data type declarations.
1962 
1963 - C++ namespaces are supported, use wsdl2h option `-qname`. Or add a `namespace
1964  name { ... }` to the header file, but the `{ ... }` MUST cover the entire
1965  header file content from begin to end.
1966 
1967 - Optional DOM support can be used to store mixed content or literal XML
1968  content. Otherwise, mixed content may be lost. Use wsdl2h option `-d` for
1969  DOM support and compile and link with `dom.c` or `dom.cpp`.
1970 
1971 
1972 Removing SOAP namespaces from XML payloads {#nsmap}
1973 ==========================================
1974 
1975 The soapcpp2 tool generates a `.nsmap` file that includes two bindings for SOAP
1976 namespaces. We can remove all SOAP namespaces (and SOAP processing logic) with
1977 soapcpp2 option `-0` or by simply setting the two entries to NULL:
1978 
1979  SOAP_NMAC struct Namespace namespaces[] =
1980  {
1981  {"SOAP-ENV", NULL, NULL, NULL},
1982  {"SOAP-ENC", NULL, NULL, NULL},
1983  ...
1984 
1985 Note that once the `.nsmap` is generated, we can copy-paste the content into
1986 our project code. However, if we rerun wsdl2h on updated WSDL/XSD files or
1987 `typemap.dat` declarations then we need to use the updated table.
1988 
1989 
1990 Examples {#examples}
1991 ========
1992 
1993 Select the project files below to peruse the source code examples.
1994 
1995 
1996 Source files
1997 ------------
1998 
1999 - `address.xsd` Address book schema
2000 - `address.cpp` Address book app (reads/writes address.xml file)
2001 - `addresstypemap.dat` Schema namespace prefix name preference for wsdl2h
2002 - `graph.h` Graph data binding (tree, digraph, cyclic graph)
2003 - `graph.cpp` Test graph serialization as tree, digraph, and cyclic
2004 
2005 
2006 Generated files
2007 ---------------
2008 
2009 - `address.h` gSOAP-specific data binding definitions from address.xsd
2010 - `addressStub.h` C++ data binding definitions
2011 - `addressH.h` Serializers
2012 - `addressC.cpp` Serializers
2013 - `address.xml` Address book data generated by address app
2014 - `graphStub.h` C++ data binding definitions
2015 - `graphH.h` Serializers
2016 - `graphC.cpp` Serializers
2017 - `g.xsd` XSD schema with `g:Graph` complexType
2018 - `g.nsmap` xmlns bindings namespace mapping table
2019 
2020 
2021 Build steps
2022 -----------
2023 
2024 Building the AddressBook example:
2025 
2026  wsdl2h -g -t addresstypemap.dat address.xsd
2027  soapcpp2 -0 -CS -I../../import -p address address.h
2028  c++ -I../.. address.cpp addressC.cpp -o address -lgsoap++
2029 
2030 Building the graph serialization example:
2031 
2032  soapcpp2 -CS -I../../import -p graph graph.h
2033  c++ -I../.. graph.cpp graphC.cpp -o graph -lgsoap++
2034 
2035 To compile without using the `libgsoap++` library: simply compile
2036 `stdsoap2.cpp` together with the above.
2037 
2038 Usage
2039 -----
2040 
2041 To execute the AddressBook example:
2042 
2043  ./address
2044 
2045 To execute the Graph serialization example:
2046 
2047  ./graph
2048