Genivia Home Documentation
README.md Source File

updated Wed Feb 3 2016
 
README.md
Go to the documentation of this file.
1 
2 XML Data Bindings {#mainpage}
3 =================
4 
5 [TOC]
6 
7 Introduction {#intro}
8 ============
9 
10 This is a detailed overview of the gSOAP XML data bindings concepts and
11 implementation. At the end of this document two examples are given to
12 illustrate the application of data bindings.
13 
14 The first simple example `address.cpp` shows how to use wsdl2h to bind an XML
15 schema to C++. The C++ application reads and writes an XML file into and from
16 a C++ "address book" data structure. The C++ data structure is an STL vector
17 of address objects.
18 
19 The second example `graph.cpp` shows how XML is serialized as a tree, digraph,
20 and cyclic graph. The digraph and cyclic graph serialization rules are similar
21 to SOAP 1.1/1.2 encoded multi-ref elements with id-ref attributes to link
22 elements through IDREF XML references, creating a an XML graph with pointers to
23 XML nodes.
24 
25 These examples demonstrate XML data bindings only for relatively simple data
26 structures and types. The gSOAP tools support more than just these type of
27 structures, which we will explain in the next sections. Support for XML schema
28 components is practically unlimited. The wsdl2h tool maps schemas to C and C++
29 using built-in intuitive mapping rules, while allowing the mappings to be
30 customized using a `typemap.dat` file with mapping instructions for wsdl2h.
31 
32 The information in this document is applicable to gSOAP 2.8.26 and higher, which
33 supports C++11 features. However, C++11 is not required to use this material
34 and follow the example, unless we need smart pointers and scoped enumerations.
35 While most of the examples in this document are given in C++, the concepts also
36 apply to C with the exception of containers, smart pointers, classes and their
37 methods. None of these exceptions limit the use of the gSOAP tools for C in any
38 way.
39 
40 The data binding concepts described in this document were first envisioned in
41 1999 by Prof. van Engelen at the Florida State University. An implementation
42 was created in 2000, named "stub/skeleton compiler". The first articles on
43 its successor version "gSOAP" appeared in 2002. The principle of mapping XSD
44 components to C/C++ types and vice versa is now widely adopted in systems and
45 programming languages, including Java web services and by C# WCF.
46 
47 
48 Mapping WSDL and XML schemas to C/C++ {#tocpp}
49 =====================================
50 
51 To convert WSDL and XML schemas (XSD files) to code, we first use the wsdl2h
52 command to generate the data binding interface code that is saved to a special
53 gSOAP header file:
54 
55  wsdl2h [options] -o file.h ... XSD and WSDL files ...
56 
57 This command converts WSDL and XSD files to C++ (or pure C with wsdl2h option
58 `-c`) and saves a data binding interface file `file.h` that uses familar C/C++
59 syntax extended with `gsoap` directives and includes notational conventions
60 to declare C/C++ types and functions that are associated with these bindings.
61 
62 The WSDL 1.1/2.0, SOAP 1.1/1.2, and XSD 1.0/1.1 standards are supported by the
63 gSOAP tools. In addition, the most popular WS specifications are also
64 supported, including WS-Addressing, WS-ReliableMessaging, WS-Discovery,
65 WS-Security, WS-Policy, WS-SecurityPolicy, and WS-SecureConversation.
66 
67 This document focusses on XML data bindings and mapping C/C++ to XML 1.0/1.1
68 and XSD 1.0/1.1. This covers all of the following standard XSD components with
69 their optional attributes and properties:
70 
71 | XSD Component | Attributes and Properties |
72 | -------------- | ------------------------------------------------------------------------------------------------------------------- |
73 | schema | targetNamespace, version, elementFormDefault, attributeFormDefault, defaultAttributes |
74 | attribute | name, ref, type, use, default, fixed, form, targetNamespace, wsdl:arrayType |
75 | element | name, ref, type, default, fixed, form, nillable, abstract, substitutionGroup, minOccurs, maxOccurs, targetNamespace |
76 | simpleType | name |
77 | complexType | name, abstract, mixed, defaultAttributesApply |
78 | all | |
79 | choice | minOccurs, maxOccurs |
80 | sequence | minOccurs, maxOccurs |
81 | group | name, ref, minOccurs, maxOccurs |
82 | attributeGroup | name, ref |
83 | any | minOccurs, maxOccurs |
84 | anyAttribute | |
85 
86 And also the following standard XSD directives are covered:
87 
88 | Directive | Description |
89 | ---------- | ---------------------------------------------------------- |
90 | import | Imports a schema into the importing schema for referencing |
91 | include | Include schema component definitions into a schema |
92 | override | Override by replacing schema component definitions |
93 | redefine | Extend or restrict schema component definitions |
94 | annotation | Annotates a component |
95 
96 The XSD facets and their mappings to C/C++ are:
97 
98 | XSD Facet | Maps to |
99 | -------------- | ------------------------------------------------------------------------------------------- |
100 | enumeration | `enum` |
101 | simpleContent | class/struct wrapper with `__item` member |
102 | complexContent | class/struct |
103 | list | `enum*` bitmask (`enum*` enumerates up to 64 bit masks) |
104 | extension | class/struct inheritance/extension |
105 | restriction | `typedef` and class/struct inheritance/redeclaration |
106 | length | `typedef` with restricted content length annotation |
107 | minLength | `typedef` with restricted content length annotation |
108 | maxLength | `typedef` with restricted content length annotation |
109 | minInclusive | `typedef` with restrict numerical value range annotation |
110 | maxInclusive | `typedef` with restrict numerical value range annotation |
111 | minExclusive | `typedef` with restrict numerical value range annotation |
112 | maxExclusive | `typedef` with restrict numerical value range annotation |
113 | precision | `typedef` with pattern annotation (pattern used for output, but input is not validated) |
114 | scale | `typedef` with pattern annotation (pattern used for output, but input is not validated) |
115 | totalDigits | `typedef` with pattern annotation (pattern used for output, but input is not validated) |
116 | fractionDigits | `typedef` with pattern annotation (pattern used for output, but input is not validated) |
117 | pattern | `typedef` with pattern annotation (define `soap::fsvalidate` callback to validate patterns) |
118 | union | string with union of values
119 
120 All primitive XSD types are supported, including but not limited to the
121 following XSD types:
122 
123 | XSD Type | Maps to |
124 | ---------------- | --------------------------------------------------------------------------------- |
125 | any/anyType | `_XML` string with literal XML content (or enable DOM with wsdl2h option `-d`) |
126 | anyURI | string (i.e. `char*`, `wchar_t*`, `std::string`, `std::wstring`) |
127 | string | string (i.e. `char*`, `wchar_t*`, `std::string`, `std::wstring`) |
128 | boolean | `bool` (C++) or `enum xsd__boolean` (C) |
129 | byte | `char` (i.e. `int8_t`) |
130 | short | `short` (i.e. `int16_t`) |
131 | int | `int` (i.e. `int32_t`) |
132 | long | `LONG64` (i.e. `long long` and `int64_t`) |
133 | unsignedByte | `unsigned char` (i.e. `uint8_t`) |
134 | unsignedShort | `unsigned short` (i.e. `uint16_t`) |
135 | unsignedInt | `unsigned int` (i.e. `uint32_t`) |
136 | unsignedLong | `ULONG64` (i.e. `unsigned long long` and `uint64_t`) |
137 | float | `float` |
138 | double | `double` |
139 | integer | string or `#import "custom/int128.h"` to use 128 bit `xsd__integer` |
140 | decimal | string or `#import "custom/long_double.h"` to use `long double` |
141 | precisionDecimal | string |
142 | duration | string or `#import "custom/duration.h"` to use 64 bit `xsd__duration` |
143 | dateTime | `time_t` or `#import "custom/struct_tm.h"` to use `struct tm` for `xsd__dateTime` |
144 | time | string or `#import "custom/long_time.h"` to use 64 bit `xsd__time` |
145 | date | string or `#import "custom/struct_tm_date.h"` to use `struct tm` for `xsd__date` |
146 | hexBinary | special class/struct `xsd__hexBinary` |
147 | base64Bianry | special class/struct `xsd__base64Binary` |
148 | QName | `_QName` string (URI normalization rules are applied) |
149 
150 All other primitive XSD types not listed above are mapped to strings, by
151 wsdl2h generating a typedef to string for these types. For example, xsd:token
152 is bound to a C++ or C string:
153 
154 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
155  typedef std::string xsd__token; // C++
156  typedef char *xsd__token; // C (wsdl2h option -c)
157 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
158 
159 This associates a compatible value space to the type with the appropriate XSD
160 type name used by the soapcpp2-generated serializers.
161 
162 It is possible to remap types by adding the appropriate mapping rules to
163 `typemap.dat` as we will explain in more detail in the next section.
164 
165 Imported custom serializers are intended to extend the C/C++ type bindings when
166 the default binding to string is not satisfactory to your taste and if the
167 target platform supports these C/C++ types. To add custom serializers to
168 `typemap.dat` for wsdl2h, see [Adding custom serializers](#custom) below.
169 
170 
171 Using typemap.dat to customize data bindings {#typemap}
172 ============================================
173 
174 We use a `typemap.dat` file to redefine namespace prefixes and to customize
175 type bindings for the the generated header files produced by the wsdl2h tool.
176 The `typemap.dat` is the default file processed by wsdl2h. Use wsdl2h option
177 `-t` to specify a different file.
178 
179 Declarations in `typemap.dat` can be broken up over multiple lines by
180 continuing on the next line by ending each line to be continued with a
181 backslash `\`. The limit is 4095 characters per line, whether the line is
182 broken up or not.
183 
184 
185 XML namespace bindings {#typemap1}
186 ----------------------
187 
188 The wsdl2h tool generates C/C++ type declarations that use `ns1`, `ns2`, etc.
189 as schema-binding URI prefixes. These default prefixes are generated somewhat
190 arbitrarily for each schema targetNamespace URI, meaning that their ordering
191 may change depending on the WSDL and XSD order of processing with wsdl2h.
192 
193 Therefore, it is **strongly recommended** to declare your own prefix for each
194 schema URI in `typemap.dat` to reduce maintaince effort of your code. This
195 is more robust when anticipating possible changes of the schema(s) and/or the
196 binding URI(s) and/or the tooling algorithms.
197 
198 The first and foremost important thing to do is to define prefix-URI bindings
199 for our C/C++ code by adding the following line(s) to our `typemap.dat` or make
200 a copy of this file and add the line(s) that bind our choice of prefix name to
201 each URI:
202 
203  prefix = "URI"
204 
205 For example:
206 
207  g = "urn:graph"
208 
209 This produces `g__name` C/C++ type names that are bound to the "urn:graph"
210 schema by association of `g` to the generated C/C++ types.
211 
212 This means that `<g:name xmlns:g="urn:graph">` is parsed as an instance of a
213 `g__name` C/C++ type. Also `<x:name xmlns:x="urn:graph">` parses as an instance
214 of `g__name`, because the prefix `x` has the same URI value `urn:graph`.
215 Prefixes in XML have local scopes (like variables in a block).
216 
217 The first run of wsdl2h will reveal the URIs, so you do not need to search
218 WSDLs and XSD files for all of the target namespaces. Just copy them from the
219 generated header file after the first run into `typemap.dat` for editing.
220 
221 
222 XSD type bindings {#typemap2}
223 -----------------
224 
225 Custom C/C++ type bindings can be declared in `typemap.dat` to associate C/C++
226 types with specific schema types. These type bindings have four parts:
227 
228  prefix__type = declaration | use | ptruse
229 
230 where
231 
232 - `prefix__type` is the schema type to be customized (the `prefix__type` name
233  uses the common double underscore naming convention);
234 - `declaration` declares the C/C++ type in the wsdl2h-generated header file.
235  This part can be empty if no explicit declaration is needed;
236 - `use` is an optional part that specifies how the C/C++ type is used in the
237  code. When omitted, it is the same as `prefix__type`;
238 - `ptruse` is an optional part that specifies how the type is used as a
239  pointer type. By default it is the `use` type name with a `*` or C++11
240  `std::shared_ptr<>` when enabled (see further below).
241 
242 For example, to map xsd:duration to a `long long` (`LONG64`) type that holds
243 millisecond duration values, we can use the custom serializer declared in
244 `custom/duration.h` by adding the following line to `typemap.dat`:
245 
246  xsd__duration = #import "custom/duration.h"
247 
248 Here, we omitted the second field, because `xsd__duration` is the name that
249 wsdl2h uses to identify and use this type for our code. The third field is
250 omitted to let wsdl2h use `xsd__duration *` for pointers or
251 `std::shared_ptr<xsd__duration>` if smart pointers are enabled.
252 
253 To map xsd:string to `wchar_t*` wide strings:
254 
255  xsd__string = | wchar_t* | wchar_t*
256 
257 Note that the first field is empty, because `wchar_t` is a C type and does not
258 need to be declared. A `ptruse` field is given so that we do not end up
259 generating the wrong pointer types, such as `wchar_t**` and
260 `std::shared_ptr<wchar_t>`.
261 
262 When the auto-generated declaration should be preserved but the `use` or
263 `ptruse` fields replaced, then we use an ellipsis for the declaration part:
264 
265  prefix__type = ... | use | ptruse
266 
267 This is useful to map schema polymorphic types to C types for example, where we
268 need to be able to both handle a base type and its extensions as per schema
269 extensibility. Say we have a base type called ns:base that is extended, then we
270 can remap this to a C type that permits referening the extended types via a
271 `void*` as follows:
272 
273  ns__base = ... | int __type_base; void*
274 
275 such that `__type_base` and `void*` will be used to (de)serialize any data
276 type, including base and its derived types. The `__type_base` integer is set
277 to a `SOAP_TYPE_T` value to indicate what type of data the `void*` pointer
278 points to.
279 
280 
281 Custom serializers for XSD types {#custom}
282 --------------------------------
283 
284 In the previous part we saw how a custom serializer is used to bind
285 xsd:duration to a `long long` (`LONG64` or `int64_t`) type to store millisecond
286 duration values:
287 
288  xsd__duration = #import "custom/duration.h"
289 
290 The `xsd__duration` type is an alias of `long long` (`LONG64` or `int64_t`).
291 
292 While wsdl2h will use this binding declared in `typemap.dat` automatically, you
293 will also need to compile `custom/duration.c`. Each custom serializer has a
294 header file and an implementation file written in C. You can compile these in
295 C++ (rename files to `.cpp` if needed).
296 
297 We will discuss the custom serializers that are available to you.
298 
299 ### xsd:integer {#custom-1}
300 
301 The wsdl2h tool maps xsd:integer to a string by default. To map xsd:integer to
302 the 128 bit big int type `__int128_t`:
303 
304  xsd__integer = #import "custom/int128.h"
305 
306 The `xsd__integer` type is an alias of `__int128_t`.
307 
308 @warning Beware that the xsd:integer value space of integers is in principle
309 unbounded and values can be of arbitrary length. A value range fault
310 `SOAP_TYPE` (value exceeds native representation) or `SOAP_LENGTH` (value
311 exceeds range bounds) will be thrown by the deserializer if the value is out of
312 range.
313 
314 Other XSD integer types that are restrictions of xsd:integer, are
315 xsd:nonNegativeInteger and xsd:nonPositiveInteger, which are further restricted
316 by xsd:positiveInteger and xsd:negativeInteger. To bind these types to
317 `__int128_t` we should also add the following definitions to `typemap.dat`:
318 
319  xsd__nonNegativeInteger = typedef xsd__integer xsd__nonNegativeInteger 0 : ;
320  xsd__nonPositiveInteger = typedef xsd__integer xsd__nonPositiveInteger : 0 ;
321  xsd__positiveInteger = typedef xsd__integer xsd__positiveInteger 1 : ;
322  xsd__negativeInteger = typedef xsd__integer xsd__negativeInteger : -1 ;
323 
324 @note If `__int128_t` 128 bit integers are not supported on your platform and if it
325 is certain that xsd:integer values are within 64 bit value bounds for your
326 application's use, then you can map this type to `LONG64`:
327 
328  xsd__integer = typedef LONG64 xsd__integer;
329 
330 @note Again, a value range fault `SOAP_TYPE` or `SOAP_LENGTH` will be thrown by
331 the deserializer if the value is out of range.
332 
333 @see Section [Numerical types](#toxsd5).
334 
335 ### xsd:decimal {#custom-2}
336 
337 The wsdl2h tool maps xsd:decimal to a string by default. To map xsd:decimal to
338 extended precision floating point:
339 
340  xsd__decimal = #import "custom/long_double.h" | long double
341 
342 By contrast to all other custom serializers, this serializer enables `long
343 double` natively without requiring a new binding name (`xsd__decimal` is NOT
344 defined).
345 
346 If your system supports `<quadmath.h>` quadruple precision floating point
347 `__float128`, you can map xsd:decimal to `xsd__decimal` that is an alias of
348 `__float128`:
349 
350  xsd__decimal = #import "custom/float128.h"
351 
352 @warning Beware that xsd:decimal is in principle a decimal value with arbitraty
353 lengths. A value range fault `SOAP_TYPE` will be thrown by the deserializer if
354 the value is out of range.
355 
356 In the XML payload the special values `INF`, `-INF`, `NaN` represent plus or
357 minus infinity and not-a-number, respectively.
358 
359 @see Section [Numerical types](#toxsd5).
360 
361 ### xsd:dateTime {#custom-3}
362 
363 The wsdl2h tool maps xsd:dateTime to `time_t` by default.
364 
365 The trouble with `time_t` when represented as 32 bit `long` integers is that it
366 is limited to dates between 1970 and 2038. A 64 bit `time_t` is safe to use if
367 the target platform supports it, but lack of 64 bit `time_t` portability may
368 still cause date range issues.
369 
370 For this reason `struct tm` should be used to represent wider date ranges. This
371 custom serializer avoids using date and time information in `time_t`. You get
372 the raw date and time information. You only lose the day of the week
373 information. It is always Sunday (`tm_wday=0`).
374 
375 To map xsd:dateTime to `xsd__dateTime` which is an alias of `struct tm`:
376 
377  xsd__dateTime = #import "custom/struct_tm.h"
378 
379 If the limited date range of `time_t` is not a problem but you want to increase
380 the time precision with fractional seconds, then we suggest to map xsd:dateTime
381 to `struct timeval`:
382 
383  xsd__dateTime = #import "custom/struct_timeval.h"
384 
385 If the limited date range of `time_t` is not a problem but you want to use the
386 C++11 time point type `std::chrono::system_clock::time_point` (which internally
387 uses `time_t`):
388 
389  xsd__dateTime = #import "custom/chrono_time_point.h"
390 
391 Again, we should make sure that the dates will not exceed the date range when
392 using the default `time_t` binding for xsd:dateTime or when binding
393 xsd:dateTime to `struct timeval` or to `std::chrono::system_clock::time_point`.
394 These are safe to use in applications that use xsd:dateTime to record date
395 stamps within a given window. Otherwise, we recommend the `struct tm` custom
396 serializer. You could even map xsd:dateTime to a plain string (use `char*` with
397 C and `std::string` with C++). For example:
398 
399  xsd__dateTime = | char*
400 
401 @see Section [Date and time types](#toxsd7).
402 
403 ### xsd:date {#custom-4}
404 
405 The wsdl2h tool maps xsd:date to a string by default. We can map xsd:date to
406 `struct tm`:
407 
408  xsd__date = #import "custom/struct_tm_date.h"
409 
410 The `xsd__date` type is an alias of `struct tm`. The serializer ignores the
411 time part and the deserializer only populates the date part of the struct,
412 setting the time to 00:00:00. There is no unreasonable limit on the date range
413 because the year field is stored as an integer (`int`).
414 
415 @see Section [Date and time types](#toxsd7).
416 
417 ### xsd:time {#custom-5}
418 
419 The wsdl2h tool maps xsd:time to a string by default. We can map xsd:time to
420 an `unsigned long long` (`ULONG64` or `uint64_t`) integer with microsecond time
421 precision:
422 
423  xsd__time = #import "custom/long_time.h"
424 
425 This type represents 00:00:00.000000 to 23:59:59.999999, from `0` to an upper
426 bound of `86399999999`. A microsecond resolution means that a 1 second
427 increment requires an increment of 1000000 in the integer value. The serializer
428 adds a UTC time zone.
429 
430 @see Section [Date and time types](#toxsd7).
431 
432 ### xsd:duration {#custom-6}
433 
434 The wsdl2h tool maps xsd:duration to a string by default, unless xsd:duration
435 is mapped to a `long long` (`LONG64` or `int64_t`) type with with millisecond
436 (ms) time duration precision:
437 
438  xsd__duration = #import "custom/duration.h"
439 
440 The `xsd__duration` type is a 64 bit signed integer that can represent
441 106,751,991,167 days forwards (positive) and backwards (negative) in time in
442 increments of 1 ms (1/1000 of a second).
443 
444 Rescaling of the duration value by may be needed when adding the duration value
445 to a `time_t` value, because `time_t` may or may not have a seconds resolution,
446 depending on the platform and possible changes to `time_t`.
447 
448 Rescaling is done automatically when you add a C++11 `std::chrono::nanoseconds`
449 value to a `std::chrono::system_clock::time_point` value. To use
450 `std::chrono::nanoseconds` as xsd:duration:
451 
452  xsd__duration = #import "custom/chrono_duration.h"
453 
454 This type can represent 384,307,168 days (2^63 nanoseconds) forwards and
455 backwards in time in increments of 1 ns (1/1,000,000,000 of a second).
456 
457 Certain observations with respect to receiving durations in years and months
458 apply to both of these serializer decoders for xsd:duration.
459 
460 @see Section [Time duration types](#toxsd8).
461 
462 
463 Class/struct member additions {#typemap3}
464 -----------------------------
465 
466 All generated classes and structs can be augmented with additional
467 members such as methods, constructors and destructors, and private members:
468 
469  prefix__type = $ member-declaration
470 
471 For example, we can add method declarations and private members to a class, say
472 `ns__record` as follows:
473 
474  ns__record = $ ns__record(const ns__record &); // copy constructor
475  ns__record = $ void print(); // a print method
476  ns__record = $ private: int status; // a private member
477 
478 Note that method declarations cannot include any code, because soapcpp2's input
479 permits only type declarations, not code.
480 
481 
482 Replacing XSD types by equivalent alternatives {#typemap4}
483 ----------------------------------------------
484 
485 Type replacements can be given to replace one type entirely with another given
486 type:
487 
488  prefix__type1 == prefix__type2
489 
490 This replaces all `prefix__type1` by `prefix__type2` in the wsdl2h output.
491 
492 @warning Do not agressively replace types, because this can cause XML
493 validation to fail when a value-type mismatch is encountered in the XML input.
494 Therefore, only replace similar types with other similar types that are wider
495 (e.g. `short` by `int` and `float` by `double`).
496 
497 
498 The built-in typemap.dat variables $CONTAINER and $POINTER {#typemap5}
499 ----------------------------------------------------------
500 
501 The `typemap.dat` `$CONTAINER` variable defines the container to emit in the
502 generated declarations, which is `std::vector` by default. For example, to emit
503 `std::list` as the container in the wsdl2h-generated declarations:
504 
505  $CONTAINER = std::list
506 
507 The `typemap.dat` `$POINTER` variable defines the smart pointer to emit in the
508 generated declarations, which replaces the use of `*` pointers. For example:
509 
510  $POINTER = std::shared_ptr
511 
512 Not all pointers in the generated output can be replaced by smart pointers.
513 Regular pointers are still used as union members and for pointers to arrays of
514 objects.
515 
516 @note The standard smart pointer `std::shared_ptr` is generally safe to use.
517 Other smart pointers such as `std::unique_ptr` and `std::auto_ptr` may cause
518 compile-time errors when classes have smart pointer members but no copy
519 constructor (a default copy constructor). A copy constructor is required for
520 non-shared smart pointer copying or swapping.
521 
522 Alternatives to `std::shared_ptr` of the form `NAMESPACE::shared_ptr` can be
523 assigned to `$POINTER` when the namespace `NAMESPACE` also implements
524 `NAMESPACE::make_shared` and when the shared pointer class provides `reset()`
525 and`get()` methods and the dereference operator. For example Boost
526 `boost::shared_ptr`:
527 
528  [
529  #include <boost/shared_ptr.hpp>
530  ]
531  $POINTER = boost::shared_ptr
532 
533 The user-defined content between `[` and `]` ensures that we include the Boost
534 header files that are needed to support `boost::shared_ptr` and
535 `boost::make_shared`.
536 
537 
538 User-defined content {#typemap6}
539 --------------------
540 
541 Any other content to be generated by wsdl2h can be included in `typemap.dat` by
542 enclosing it within brackets `[` and `]` anywhere in the `typemap.dat` file.
543 Each of the two brackets MUST appear at the start of a new line.
544 
545 For example, we can add an `#import "wsa5.h"` directive to the wsdl2h-generated
546 output as follows:
547 
548  [
549  #import "import/wsa5.h"
550  ]
551 
552 which emits the `#import "import/wsa5.h"` literally at the start of the
553 wsdl2h-generated header file.
554 
555 
556 Mapping C/C++ to XML schema {#toxsd}
557 ===========================
558 
559 The soapcpp2 command generates the data binding implementation code from a data
560 binding interface `file.h`:
561 
562  soapcpp2 [options] file.h
563 
564 where `file.h` is a gSOAP header file that declares the XML data binding
565 interface. The `file.h` is typically generated by wsdl2h, but we can also
566 declare one ourself. If so, we add gSOAP directives and declare in this file
567 all our C/C++ types we want to serialize in XML. We can also declare functions
568 that will be converted to service operations by soapcpp2.
569 
570 Global function declarations define service operations, which are of the form:
571 
572  int ns__name(arg1, arg2, ..., argn, result);
573 
574 where `arg1`, `arg2`, ..., `argn` are formal argument declarations of the input
575 and `result` is a formal argument for the output, which must be a pointer or
576 reference to the result object to be populated. More information can be found
577 in the gSOAP user guide.
578 
579 
580 Overview of serializable C/C++ types {#toxsd1}
581 ------------------------------------
582 
583 The following C/C++ types are supported by soapcpp2 and mapped to XSD types
584 and constructs. See the subsections below for more details or follow the links.
585 
586 ### List of Boolean types
587 
588 | Boolean Type | Notes |
589 | ----------------------------- | ----------------------------------------------------------------------------------- |
590 | `bool` | C++ bool |
591 | `enum xsd__boolean` | C alternative to C++ `bool` with `false_` and `true_` |
592 
593 @see Section [C++ bool and C alternative](#toxsd3).
594 
595 ### List of enumeration and bitmask types
596 
597 | Enumeration Type | Notes |
598 | ----------------------------- | ----------------------------------------------------------------------------------- |
599 | `enum` | enumeration |
600 | `enum class` | C++11 scoped enumeration (soapcpp2 `-c++11`) |
601 | `enum*` | a bitmask that enumerates values 1, 2, 4, 8, ... |
602 | `enum* class` | C++11 scoped enumeration bitmask (soapcpp2 `-c++11`) |
603 
604 @see Section [Enumerations and bitmasks](#toxsd4).
605 
606 ### List of numerical types
607 
608 | Numerical Type | Notes |
609 | ----------------------------- | ----------------------------------------------------------------------------------- |
610 | `char` | byte |
611 | `short` | 16 bit integer |
612 | `int` | 32 bit integer |
613 | `long` | 32 bit integer |
614 | `LONG64` | 64 bit integer |
615 | `xsd__integer` | 128 bit integer, use `#import "custom/int128.h"` |
616 | `long long` | same as `LONG64` |
617 | `unsigned char` | unsigned byte |
618 | `unsigned short` | unsigned 16 bit integer |
619 | `unsigned int` | unsigned 32 bit integer |
620 | `unsigned long` | unsigned 32 bit integer |
621 | `ULONG64` | unsigned 64 bit integer |
622 | `unsigned long long` | same as `ULONG64` |
623 | `int8_t` | same as `char` |
624 | `int16_t` | same as `short` |
625 | `int32_t` | same as `int` |
626 | `int64_t` | same as `LONG64` |
627 | `uint8_t` | same as `unsigned char` |
628 | `uint16_t` | same as `unsigned short` |
629 | `uint32_t` | same as `unsigned int` |
630 | `uint64_t` | same as `ULONG64` |
631 | `size_t` | transient type (not serializable) |
632 | `float` | 32 bit float |
633 | `double` | 64 bit float |
634 | `long double` | extended precision float, use `#import "custom/long_double.h"` |
635 | `xsd__decimal` | `<quadmath.h>` 128 bit quadruple precision float, use `#import "custom/float128.h"` |
636 | `typedef` | declares a type name, with optional value range and string length bounds |
637 
638 @see Section [Numerical types](#toxsd5).
639 
640 ### List of string types
641 
642 | String Type | Notes |
643 | ----------------------------- | ----------------------------------------------------------------------------------- |
644 | `char*` | string (may contain UTF-8 with flag `SOAP_C_UTFSTRING`) |
645 | `wchar_t*` | wide string |
646 | `std::string` | C++ string (may contain UTF-8 with flag `SOAP_C_UTFSTRING`) |
647 | `std::wstring` | C++ wide string |
648 | `char[N]` | fixed-size string, requires soapcpp2 option `-b` |
649 | `_QName` | normalized QName content |
650 | `_XML` | literal XML string content with wide characters in UTF-8 |
651 | `typedef` | declares a new string type name, may restrict string length |
652 
653 @see Section [String types](#toxsd6).
654 
655 ### List of date and time types
656 
657 | Date and Time Type | Notes |
658 | --------------------------------------- | ------------------------------------------------------------------------- |
659 | `time_t` | date and time point since epoch |
660 | `struct tm` | date and time point, use `#import "custom/struct_tm.h"` |
661 | `struct tm` | date point, use `#import "custom/struct_tm_date.h"` |
662 | `struct timeval` | date and time point, use `#import "custom/struct_timeval.h"` |
663 | `unsigned long long` | time point in microseconds, use `#import "custom/long_time.h"` |
664 | `std::chrono::system_clock::time_point` | date and time point, use `#import "custom/chrono_time_point.h"` |
665 
666 @see Section [Date and time types](#toxsd7).
667 
668 ### List of time duration types
669 
670 | Time Duration Type | Notes |
671 | ----------------------------- | ----------------------------------------------------------------------------------- |
672 | `long long` | duration in milliseconds, use `#import "custom/duration.h"` |
673 | `std::chrono::nanoseconds` | duration in nanoseconds, use `#import "custom/chrono_duration.h"` |
674 
675 @see Section [Time duration types](#toxsd8).
676 
677 ### List of classes and structs
678 
679 | Classes, Structs, and Members | Notes |
680 | ----------------------------- | ----------------------------------------------------------------------------------- |
681 | `class` | C++ class with single inheritance only |
682 | `struct` | C struct or C++ struct without inheritance |
683 | `std::shared_ptr<T>` | C++11 smart shared pointer |
684 | `std::unique_ptr<T>` | C++11 smart pointer |
685 | `std::auto_ptr<T>` | C++ smart pointer |
686 | `std::deque<T>` | use `#import "import/stldeque.h"` |
687 | `std::list<T>` | use `#import "import/stllist.h"` |
688 | `std::vector<T>` | use `#import "import/stlvector.h"` |
689 | `std::set<T>` | use `#import "import/stlset.h"` |
690 | `template<T> class` | a container with `begin()`, `end()`, `size()`, `clear()`, and `insert()` methods |
691 | `T*` | data member: pointer to data of type `T` or points to array of `T` of size `__size` |
692 | `T[N]` | data member: fixed-size array of type `T` |
693 | `union` | data member: requires a variant selector member `__union` |
694 | `void*` | data member: requires a `__type` member to indicate the type of object pointed to |
695 
696 @see Section [Classes and structs](#toxsd9).
697 
698 ### List of special classes and structs
699 
700 | Special Classes and Structs | Notes |
701 | ----------------------------- | ----------------------------------------------------------------------------------- |
702 | Special Array class/struct | single and multidimensional SOAP Arrays |
703 | Special Wrapper class/struct | complexTypes with simpleContent, wraps `__item` member |
704 | `xsd__hexBinary` | binary content |
705 | `xsd__base64Binary` | binary content and optional MIME/MTOM attachments |
706 | `xsd__anyType` | DOM elements, use `#import "dom.h"` |
707 | `@xsd__anyAttribute` | DOM attributes, use `#import "dom.h"` |
708 
709 @see Section [Special classes and structs](#toxsd10).
710 
711 
712 Colon notation versus name prefixing {#toxsd2}
713 ------------------------------------
714 
715 To bind C/C++ type names to XSD types, a simple form of name prefixing is used
716 by the gSOAP tools by prepending the XML namespace prefix to the C/C++ type
717 name with a pair of undescrores. This also ensures that name clashes cannot
718 occur when multiple WSDL and XSD files are converted to C/C++. Also, C++
719 namespaces are not sufficiently rich to capture XML schema namespaces
720 accurately, for example when class members are associated with schema elements
721 defined in another XML namespace and thus the XML namespace scope of the
722 member's name is relevant, not just its type.
723 
724 However, from a C/C++ centric point of view this can be cumbersome. Therefore,
725 colon notation is an alternative to physically augmenting C/C++ names with
726 prefixes.
727 
728 For example, the following class uses colon notation to bind the `record` class
729 to the `urn:types` schema:
730 
731 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
732  //gsoap ns schema namespace: urn:types
733  class ns:record // binding 'ns:' to a type name
734  {
735  public:
736  std::string name;
737  uint64_t SSN;
738  ns:record *spouse; // using 'ns:' with the type name
739  ns:record(); // using 'ns:' here too
740  ~ns:record(); // and here
741  };
742 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
743 
744 The colon notation is stripped away by soapcpp2 when generating the data
745 binding implementation code for our project. So the final code just uses
746 `record` to identify this class and its constructor/destructor.
747 
748 When using colon notation we have to be consistent and not use colon notation
749 mixed with prefixed forms. The name `ns:record` differs from `ns__record`,
750 because `ns:record` is compiled to an unqualified `record` name.
751 
752 Colon notation also facilitates overruling the elementFormDefault and
753 attributeFormDefault declaration that is applied to local elements and
754 attributes, when declared as members of classes, structs, and unions. For more
755 details, see [Qualified and unqualified members](#toxsd9-6).
756 
757 
758 C++ Bool and C alternatives {#toxsd3}
759 ---------------------------
760 
761 The C++ `bool` type is bound to built-in XSD type xsd:boolean.
762 
763 The C alternative is to define an enumeration:
764 
765 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
766  enum xsd__boolean { false_, true_ };
767 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
768 
769 or by defining an enumeration in C with pseudo-scoped enumeration constants:
770 
771 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
772  enum xsd__boolean { xsd__boolean__false, xsd__boolean__true };
773 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
774 
775 The XML value space of these types is `false` and `true`, but also accepted are
776 `0` and `1` values for false and true, respectively.
777 
778 To prevent name clashes, `false_` and `true_` have an underscore. Trailing
779 underscores are removed from the XML value space.
780 
781 
782 Enumerations and bitmasks {#toxsd4}
783 -------------------------
784 
785 Enumerations are mapped to XSD simpleType enumeration restrictions of
786 xsd:string, xsd:QName, and xsd:long.
787 
788 Consider for example:
789 
790 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
791  enum ns__Color { RED, WHITE, BLUE };
792 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
793 
794 which maps to a simpleType restriction of xsd:string in the soapcpp2-generated
795 schema:
796 
797  <simpleType name="Color">
798  <restriction base="xsd:string">
799  <enumeration value="RED"/>
800  <enumeration value="WHITE"/>
801  <enumeration value="BLUE"/>
802  </restriction>
803  </simpleType>
804 
805 Enumeration name constants can be pseudo-scoped to prevent name clashes,
806 because enumeration name constants have a global scope in C and C++:
807 
808 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
809  enum ns__Color { ns__Color__RED, ns__Color__WHITE, ns__Color__BLUE };
810 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
811 
812 We can also use C++11 scoped enumerations to prevent name clashes:
813 
814 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
815  enum class ns__Color : int { RED, WHITE, BLUE };
816 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
817 
818 Here, the enumeration class base type `: int` is optional. In place of `int`
819 in the example above, we can also use `int8_t`, `int16_t`, `int32_t`, or
820 `int64_t`.
821 
822 The XML value space of the enumertions defined above is `RED`, `WHITE`, and
823 `BLUE`.
824 
825 Prefix-qualified enumeration name constants are mapped to simpleType
826 restrictions of xsd:QName, for example:
827 
828 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
829  enum ns__types { xsd__int, xsd__float };
830 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
831 
832 which maps to a simpleType restriction of xsd:QName in the soapcpp2-generated
833 schema:
834 
835  <simpleType name="types">
836  <restriction base="xsd:QName">
837  <enumeration value="xsd:int"/>
838  <enumeration value="xsd:float"/>
839  </restriction>
840  </simpleType>
841 
842 Enumeration name constants can be pseudo-numeric as follows:
843 
844 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
845  enum ns__Primes { _3 = 3, _5 = 5, _7 = 7, _11 = 11 };
846 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
847 
848 which maps to a simpleType restriction of `xsd:long`:
849 
850  <simpleType name="Color">
851  <restriction base="xsd:long">
852  <enumeration value="3"/>
853  <enumeration value="5"/>
854  <enumeration value="7"/>
855  <enumeration value="11"/>
856  </restriction>
857  </simpleType>
858 
859 The XML value space of this type is `3`, `5`, `7`, and `11`.
860 
861 Besides (pseudo-) scoped enumerations, another way to prevent name clashes
862 accross enumerations is to start an enumeration name constant with one
863 underscore or followed it by any number of underscores, which makes it
864 unique. The leading and trailing underscores are removed from the XML value
865 space.
866 
867 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
868  enum ns__ABC { A, B, C };
869  enum ns__BA { B, A }; // BAD: B = 1 but B is already defined as 2
870  enum ns__BA_ { B_, A_ }; // OK
871 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
872 
873 The gSOAP soapcpp2 tool permits reusing enumeration name constants across
874 (non-scoped) enumerations as long as these values are assigned the same
875 constant. Therefore, the following is permitted:
876 
877 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
878  enum ns__Primes { _3 = 3, _5 = 5, _7 = 7, _11 = 11 };
879  enum ns__Throws { _1 = 1, _2 = 2, _3 = 3, _4 = 4, _5 = 5, _6 = 6 };
880 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
881 
882 A bitmask type is an `enum*` "product" enumeration with a geometric,
883 power-of-two sequence of values assigned to the enumeration constants:
884 
885 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
886  enum* ns__Options { SSL3, TLS10, TLS11, TLS12 };
887 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
888 
889 where the product enum assigns 1 to `SSL3`, 2 to `TLS10`, 4 to `TLS11`, and 8
890 to `TLS12`, which allows these enumeration constants to be used in composing
891 bitmasks with `|` (bitwise or) `&` (bitwise and), and `~` (bitwise not):
892 
893 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
894  enum ns__Options options = (enum ns__Options)(SSL3 | TLS10 | TLS11 | TLS12);
895  if (options & SSL3) // if SSL3 is an option, warn and remove from options
896  {
897  warning();
898  options &= ~SSL3;
899  }
900 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
901 
902 The bitmask type maps to a simpleType list restriction of xsd:string in the
903 soapcpp2-generated schema:
904 
905  <simpleType name="Options">
906  <list>
907  <restriction base="xsd:string">
908  <enumeration value="SSL3"/>
909  <enumeration value="TLS10"/>
910  <enumeration value="TLS11"/>
911  <enumeration value="TLS12"/>
912  </restriction>
913  </list>
914  </simpleType>
915 
916 The XML value space of this type consists of all 16 possible subsets of the
917 four values, represented by an XML string with space-separated values. For
918 example, the bitmask `TLS10 | TLS11 | TLS12` equals 14 and is represented in by
919 the XML string `TLS10 TLS11 TLS12`.
920 
921 We can also use C++11 scoped enumerations with bitmasks:
922 
923 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
924  enum* class ns__Options { SSL3, TLS10, TLS11, TLS12 };
925 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
926 
927 The base type of a scoped enumeration bitmask, when explicitly given, is
928 ignored. The base type is either `int` or `int64_t`, depending on the number
929 of constants enumerated in the bitmask.
930 
931 To convert `enum` name constants and bitmasks to a string, we use the
932 auto-generated function for enum `T`:
933 
934 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
935  const char *soap_T2s(struct soap*, enum T val)
936 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
937 
938 The string returned is stored in an internal buffer of the current `soap`
939 context, so you MUST copy it to keep it from being overwritten. For example,
940 use `char *soap_strdup(struct soap*, const char*)`.
941 
942 To convert a string to an `enum` constant or bitmask, we use the auto-generated
943 function
944 
945 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
946  int soap_s2T(struct soap*, const char *str, enum T *val)
947 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
948 
949 This function takes the name (or names, space-separated for bitmasks) of
950 the enumeration constant in a string `str`. Names should be given without the
951 pseudo-scope prefix and without trailing underscores. The function sets `val`
952 to the corresponding integer enum constant or to a bitmask. The function
953 returns `SOAP_OK` (zero) on success or an error if the string is not a valid
954 enumeration name.
955 
956 
957 Numerical types {#toxsd5}
958 ---------------
959 
960 Integer and floating point types are mapped to the equivalent built-in XSD
961 types with the same sign and bit width.
962 
963 The `size_t` type is transient (not serializable) because its width is platform
964 dependent. We recommend to use `uint64_t` instead.
965 
966 The XML value space of integer types are their decimal representations without
967 loss of precision.
968 
969 The XML value space of floating point types are their decimal representations.
970 The decimal representations are formatted with the printf format string "%.9G"
971 for floats and the printf format string "%.17lG" for double. To change the
972 format strings, we can assign new strings to the following `struct soap`
973 context members:
974 
975 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
976  soap.float_format = "%g";
977  soap.double_format = "%lg";
978  soap.long_double_format = "%Lg";
979 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
980 
981 Note that decimal representations may result in a loss of precision of the
982 least significant decimal. Therefore, the format strings that are used by
983 default are sufficiently precise to avoid loss, but this may result in long
984 decimal fractions in the XML value space.
985 
986 The `long double` extended floating point type requires a custom serializer:
987 
988 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
989  #import "custom/long_double.h"
990  ... use long double ...
991 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
992 
993 You can now use `long double`, which has a serializer that serializes this type
994 as `xsd:decimal`. Compile and link your code with `custom/long_double.c`.
995 
996 The value space of floating point values includes the special values `INF`,
997 `-INF`, and `NaN`. You can check a value for plus or minus infinity and
998 not-a-number as follows:
999 
1000 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
1001  soap_isinf(x) && x > 0 // is x INF?
1002  soap_isinf(x) && x < 0 // is x -INF?
1003  soap_isnan(x) // is x NaN?
1004 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1005 
1006 To assign these values, use:
1007 
1008 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
1009  // x is float // x is double, long double, or __float128
1010  x = FLT_PINFY; x = DBL_PINFTY;
1011  x = FLT_NINFY; x = DBL_NINFTY;
1012  x = FLT_NAN; x = DBL_NAN;
1013 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1014 
1015 If your system supports `__float128` then you can also use this 128 bit
1016 floating point type with a custom serializer:
1017 
1018 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
1019  #import "custom/float128.h"
1020  ... use xsd__decimal ...
1021 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1022 
1023 Then use the `xsd__decimal` alias of `__float128`, which has a serializer. Do
1024 not use `__float128` directly, which is transient (not serializable).
1025 
1026 To check for `INF`, `-INF`, and `NaN` of a `__float128` value use:
1027 
1028 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
1029  isinfq(x) && x > 0 // is x INF?
1030  isinfq(x) && x < 0 // is x -INF?
1031  isnanq(x) // is x NaN?
1032 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1033 
1034 The range of a typedef-defined numerical type can be restricted using the range
1035 `:` operator with inclusive lower and upper bounds. For example:
1036 
1037 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
1038  typedef int ns__narrow -10 : 10;
1039 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1040 
1041 This maps to a simpleType restriction of xsd:int in the soapcpp2-generated
1042 schema:
1043 
1044  <simpleType name="narrow">
1045  <restriction base="xsd:int">
1046  <minInclusive value="-10"/>
1047  <maxInclusive value="10"/>
1048  </restriction>
1049  </simpleType>
1050 
1051 The lower and upper bound of a range are optional. When omitted, values are
1052 not bound from below or from above, respectively.
1053 
1054 The range of a floating point typedef-defined type can be restricted within
1055 floating point constant bounds.
1056 
1057 Also with a floating point typedef a printf format pattern can be given of the
1058 form `"%[width][.precision]f"` to format decimal values using the given width
1059 and precision fields:
1060 
1061 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
1062  typedef float ns__PH "%5.2f" 0.0 : 14.0;
1063 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1064 
1065 This maps to a simpleType restriction of xsd:float in the soapcpp2-generated
1066 schema:
1067 
1068  <simpleType name="PH">
1069  <restriction base="xsd:float">
1070  <totalDigits value="5"/>
1071  <fractionDigits value="2"/>
1072  <minInclusive value="0"/>
1073  <maxInclusive value="14"/>
1074  </restriction>
1075  </simpleType>
1076 
1077 For exclusive bounds, we use the `<` operator instead of the `:` range
1078 operator:
1079 
1080 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
1081  typedef float ns__epsilon 0.0 < 1.0;
1082 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1083 
1084 Values `eps` of `ns__epsilon` are restricted between `0.0 < eps < 1.0`.
1085 
1086 This maps to a simpleType restriction of xsd:float in the soapcpp2-generated
1087 schema:
1088 
1089  <simpleType name="epsilon">
1090  <restriction base="xsd:float">
1091  <minExclusive value="0"/>
1092  <maxExclusive value="1"/>
1093  </restriction>
1094  </simpleType>
1095 
1096 To make just one of the bounds exclusive, while keeping the other bound
1097 inclusive, we add a `<` on the left or on the right side of the range ':'
1098 operator. For example:
1099 
1100 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
1101  typedef float ns__pos 0.0 < : ; // 0.0 < pos
1102  typedef float ns__neg : < 0.0 ; // neg < 0.0
1103 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1104 
1105 It is valid to make both left and right side exclusive with `< : <` which is in
1106 fact identical to the exlusive range `<` operator:
1107 
1108 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
1109  typedef float ns__epsilon 0.0 < : < 1.0; // 0.0 < eps < 1.0
1110 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1111 
1112 It helps to think of the `:` as a placeholder of the value between the two
1113 bounds, which is easier to memorize than the shorthand forms of bounds from
1114 which the `:` is removed:
1115 
1116 | Bounds | Validation Check | Shorthand |
1117 | ---------- | ---------------- | --------- |
1118 | 1 : | 1 <= x | 1 |
1119 | 1 : 10 | 1 <= x <= 10 | |
1120 | : 10 | x <= 10 | |
1121 | 1 < : < 10 | 1 < x < 10 | 1 < 10 |
1122 | 1 : < 10 | 1 <= x < 10 | |
1123 | : < 10 | x < 10 | < 10 |
1124 | 1 < : | 1 < x | 1 < |
1125 | 1 < : 10 | 1 < x <= 10 | |
1126 
1127 Besides `float`, also `double` and `long double` values can be restricted. For
1128 example, consider a nonzero probability extended floating point precision type:
1129 
1130 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
1131  #import "custom/long_double.h"
1132  typedef long double ns__probability "%16Lg" 0.0 < : 1.0;
1133 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1134 
1135 Value range restrictions are validated by the parser for all inbound XML data.
1136 A type fault `SOAP_TYPE` will be thrown by the deserializer if the value is out
1137 of range.
1138 
1139 Finally, if your system supports `__int128_t` then you can also use this 128
1140 bit integer type with a custom serializer:
1141 
1142 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
1143  #import "custom/int128.h"
1144  ... use xsd__integer ...
1145 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1146 
1147 We use the `xsd__integer` alias of `__int128_t`, which has a serializer. Do not
1148 use `__int128_t` directly, which is transient (not serializable).
1149 
1150 To convert numeric values to a string, we use the auto-generated function for
1151 numeric type `T`:
1152 
1153 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
1154  const char *soap_T2s(struct soap*, T val)
1155 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1156 
1157 For numeric types `T`, the string returned is stored in an internal buffer of
1158 the current `soap` context, so you MUST copy it to keep it from being
1159 overwritten. For example, use `char *soap_strdup(struct soap*, const char*)`.
1160 
1161 To convert a string to a numeric value, we use the auto-generated function
1162 
1163 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
1164  int soap_s2T(struct soap*, const char *str, T *val)
1165 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1166 
1167 where `T` is for example `int`, `LONG64`, `float`, `decimal` (the custom
1168 serializer name of `long double`) or `xsd__integer` (the custom serializer name
1169 of `__int128_t`). The function `soap_s2T` returns `SOAP_OK` on success or an
1170 error when the value is not numeric. For floating point types, "INF", "-INF"
1171 and "NaN" are valid strings to convert to numbers.
1172 
1173 
1174 String types {#toxsd6}
1175 ------------
1176 
1177 String types are mapped to the built-in xsd:string and xsd:QName XSD types.
1178 
1179 The wide strings `wchar_t*` and `std::wstring` may contain Unicode that is
1180 preserved in the XML value space.
1181 
1182 Strings `char*` and `std::string` can only contain extended Latin, but we can
1183 store UTF-8 content that is preserved in the XML value space when the `struct
1184 soap` context is initialized with the flag `XML_C_UTFSTRING`.
1185 
1186 @warning Beware that many XML 1.0 parsers reject all control characters (those
1187 between `#x1` and `#x1F`) except `#x9`, `#xA`, and `#xD`. With the newer XML
1188 1.1 version parsers (including gSOAP) you should be fine.
1189 
1190 The length of a string of a typedef-defined string type can be restricted:
1191 
1192 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
1193  typedef std::string ns__password 6 : 16;
1194 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1195 
1196 which maps to a simpleType restriction of xsd:string in the soapcpp2-generated
1197 schema:
1198 
1199  <simpleType name="password">
1200  <restriction base="xsd:string">
1201  <minLength value="6"/>
1202  <maxLength value="16"/>
1203  </restriction>
1204  </simpleType>
1205 
1206 String length restrictions are validated by the parser for inbound XML data.
1207 A value length fault `SOAP_LENGTH` will be thrown by the deserializer if the
1208 string is too long or too short.
1209 
1210 In addition, an XSD regex pattern restriction can be associated with a string
1211 typedef:
1212 
1213 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
1214  typedef std::string ns__password "([a-zA-Z]|[0-9]|-)+" 6 : 16;
1215 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1216 
1217 which maps to a simpleType restriction of xsd:string in the soapcpp2-generated
1218 schema:
1219 
1220  <simpleType name="password">
1221  <restriction base="xsd:string">
1222  <pattern value="([a-zA-Z0-9]|-)+"/>
1223  <minLength value="6"/>
1224  <maxLength value="16"/>
1225  </restriction>
1226  </simpleType>
1227 
1228 Pattern restrictions are validated by the parser for inbound XML data only if
1229 the `soap::fsvalidate` and `soap::fwvalidate` callbacks are defined, see the
1230 gSOAP user guide for more details.
1231 
1232 Exclusive length bounds can be used with strings:
1233 
1234 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
1235  typedef std::string ns__string255 : < 256; // same as 0 : 255
1236 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1237 
1238 Fixed-size strings (`char[N]`) are rare occurrences in the wild, but apparently
1239 still used in some projects to store strings. To facilitate fixed-size string
1240 serialization, use soapcpp2 option `-b`. For example:
1241 
1242 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
1243  typedef char ns__buffer[10]; // requires soapcpp2 option -b
1244 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1245 
1246 which maps to a simpleType restriction of xsd:string in the soapcpp2-generated
1247 schema:
1248 
1249  <simpleType name="buffer">
1250  <restriction base="xsd:string">
1251  <maxLength value="9"/>
1252  </restriction>
1253  </simpleType>
1254 
1255 Note that fixed-size strings MUST contain NUL-terminated text and SHOULD NOT
1256 contain raw binary data. Also, the length limitation is more restrictive for
1257 UTF-8 content (enabled with the `SOAP_C_UTFSTRING`) that requires multibyte
1258 character encodings. As a consequence, UTF-8 content may be truncated to fit.
1259 
1260 Note that raw binary data can be stored in a `xsd__base64Binary` or
1261 `xsd__hexBinary` structure, or transmitted as a MIME attachment.
1262 
1263 The built-in `_QName` type is a regular C string type (`char*`) that maps to
1264 xsd:QName but has the added advantage that it holds normalized qualified names.
1265 There are actually two forms of normalized QName content, to ensure any QName
1266 is represented accurately and uniquely:
1267 
1268 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
1269  "prefix:name"
1270  "\"URI\":name"
1271 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1272 
1273 The first form of string is used when the prefix (and the binding URI) is
1274 defined in the namespace table and is bound to a URI (see the .nsmap file).
1275 The second form is used when the URI is not defined in the namespace table and
1276 therefore no prefix is available to bind and normalize the URI to.
1277 
1278 A `_QName` string may contain a sequence of space-separated QName values, not
1279 just one, and all QName values are normalized to the format shown above.
1280 
1281 To define a `std::string` base type for xsd:QName, we use a typedef:
1282 
1283 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
1284  typedef std::string xsd__QName;
1285 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1286 
1287 The `xsd__QName` string content is normalized, just as with the `_QName`
1288 normalization.
1289 
1290 To serialize strings that contain literal XML content to be reproduced in the
1291 XML value space, use the built-in `_XML` string type, which is a regular C
1292 string type (`char*`) that maps to plain XML CDATA.
1293 
1294 To define a `std::string` base type for literal XML content, use a typedef:
1295 
1296 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
1297  typedef std::string XML;
1298 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1299 
1300 Strings can hold any of the values of the XSD built-in primitive types. We can
1301 use a string typedef to declare the use of the string type as a XSD built-in
1302 type:
1303 
1304 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
1305  typedef std::string xsd__token;
1306 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1307 
1308 We MUST ensure that the string values we populate in this type conform to the
1309 XML standard, which in case of xsd:token is: the lexical and value spaces of
1310 xsd:token are the sets of all strings after whitespace replacement of any
1311 occurrence of `#x9`, `#xA` , and `#xD` by `#x20` and collapsing.
1312 
1313 To copy `char*` or `wchar_t*` strings with a context that manages the allocated
1314 memory, use functions
1315 
1316 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
1317  char *soap_strdup(struct soap*, const char*)
1318  wchar_t *soap_wstrdup(struct soap*, const wchar_t*)
1319 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1320 
1321 To convert a wide string to a UTF-8 encoded string, use function
1322 
1323 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
1324  const char* SOAP_FMAC2 soap_wchar2s(struct soap*, const wchar_t *s)
1325 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1326 
1327 The function allocates and returns a string, with its memory being managed by
1328 the context.
1329 
1330 To convert a UTF-8 encoded string to a wide string, use function
1331 
1332 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
1333  int soap_s2wchar(struct soap*, const char *from, wchar_t **to, long minlen, long maxlen)
1334 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1335 
1336 where `to` is set to point to an allocated `wchar_t*` string. Pass `-1` for
1337 `minlen` and `maxlen` to ignore length constraints on the target string. The
1338 function returns `SOAP_OK` or an error when the length constraints are not met.
1339 
1340 
1341 Date and time types {#toxsd7}
1342 -------------------
1343 
1344 The C/C++ `time_t` type is mapped to the built-in xsd:dateTime XSD type that
1345 represents a date and time within a time zone (typically UTC).
1346 
1347 The XML value space contains ISO 8601 Gregorian time instances of the form
1348 `[-]CCYY-MM-DDThh:mm:ss.sss[Z|(+|-)hh:mm]`, where `Z` is the UTC time zone or a
1349 time zone offset `(+|-)hh:mm]` from UTC is used.
1350 
1351 A `time_t` value is considered and represented in UTC by the serializer.
1352 
1353 Because the `time_t` value range is restricted to dates after 01/01/1970 and
1354 before 2038 assuming `time_t` is a `long` 32 bit, care must be taken to ensure
1355 the range of xsd:dateTime values in XML exchanges do not exceed the `time_t`
1356 range.
1357 
1358 This restriction does not hold for `struct tm` (`<time.h>`), which we can use
1359 to store and exchange a date and time in UTC without date range restrictions.
1360 The serializer uses the `struct tm` members directly for the XML value space of
1361 xsd:dateTime:
1362 
1363 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
1364  struct tm
1365  {
1366  int tm_sec; // seconds (0 - 60)
1367  int tm_min; // minutes (0 - 59)
1368  int tm_hour; // hours (0 - 23)
1369  int tm_mday; // day of month (1 - 31)
1370  int tm_mon; // month of year (0 - 11)
1371  int tm_year; // year - 1900
1372  int tm_wday; // day of week (Sunday = 0) (NOT USED)
1373  int tm_yday; // day of year (0 - 365) (NOT USED)
1374  int tm_isdst; // is summer time in effect?
1375  char* tm_zone; // abbreviation of timezone (NOT USED)
1376  };
1377 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1378 
1379 You will lose the day of the week information. It is always Sunday
1380 (`tm_wday=0`) and the day of the year is not set either. The time zone is UTC.
1381 
1382 This `struct tm` type is mapped to the built-in xsd:dateTime XSD type and
1383 serialized with the custom serializer `custom/struct_tm.h` that declares a
1384 `xsd__dateTime` type:
1385 
1386 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
1387  #import "custom/struct_tm.h" // import typedef struct tm xsd__dateTime;
1388  ... use xsd__dateTime ...
1389 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1390 
1391 Compile and link your code with `custom/struct_tm.c`.
1392 
1393 The `struct timeval` (`<sys/time.h>`) type is mapped to the built-in
1394 xsd:dateTime XSD type and serialized with the custom serializer
1395 `custom/struct_timeval.h` that declares a `xsd__dateTime` type:
1396 
1397 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
1398  #import "custom/struct_timeval.h" // import typedef struct timeval xsd__dateTime;
1399  ... use xsd__dateTime ...
1400 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1401 
1402 Compile and link your code with `custom/struct_timeval.c`.
1403 
1404 Note that the same value range restrictions apply to `struct timeval` as they
1405 apply to `time_t`. The added benefit of `struct timeval` is the addition of
1406 a microsecond-precise clock:
1407 
1408 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
1409  struct timeval
1410  {
1411  time_t tv_sec; // seconds since Jan. 1, 1970
1412  suseconds_t tv_usec; // and microseconds
1413  };
1414 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1415 
1416 A C++11 `std::chrono::system_clock::time_point` type is mapped to the built-in
1417 xsd:dateTime XSD type and serialized with the custom serializer
1418 `custom/chrono_time_point.h` that declares a `xsd__dateTime` type:
1419 
1420 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
1421  #import "custom/chrono_time_point.h" // import typedef std::chrono::system_clock::time_point xsd__dateTime;
1422  ... use xsd__dateTime ...
1423 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1424 
1425 Compile and link your code with `custom/chrono_time_point.cpp`.
1426 
1427 The `struct tm` type is mapped to the built-in xsd:date XSD type and serialized
1428 with the custom serializer `custom/struct_tm_date.h` that declares a
1429 `xsd__date` type:
1430 
1431 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
1432  #import "custom/struct_tm_date.h" // import typedef struct tm xsd__date;
1433  ... use xsd__date ...
1434 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1435 
1436 Compile and link your code with `custom/struct_tm_date.c`.
1437 
1438 The XML value space of xsd:date are Gregorian calendar dates of the form
1439 `[-]CCYY-MM-DD[Z|(+|-)hh:mm]` with a time zone.
1440 
1441 The serializer ignores the time part and the deserializer only populates the
1442 date part of the struct, setting the time to 00:00:00. There is no unreasonable
1443 limit on the date range because the year field is stored as an integer (`int`).
1444 
1445 An `unsigned long long` (`ULONG64` or `uint64_t`) type that contains a 24 hour
1446 time in microseconds UTC is mapped to the built-in xsd:time XSD type and
1447 serialized with the custom serializer `custom/long_time.h` that declares a
1448 `xsd__time` type:
1449 
1450 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
1451  #import "custom/long_time.h" // import typedef unsigned long long xsd__time;
1452  ... use xsd__time ...
1453 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1454 
1455 Compile and link your code with `custom/long_time.c`.
1456 
1457 This type represents 00:00:00.000000 to 23:59:59.999999, from `0` to an upper
1458 bound of `86399999999`. A microsecond resolution means that a 1 second
1459 increment requires an increment of 1000000 in the integer value.
1460 
1461 The XML value space of xsd:time are points in time recurring each day of the
1462 form `hh:mm:ss.sss[Z|(+|-)hh:mm]`, where `Z` is the UTC time zone or a time
1463 zone offset from UTC is used. The `xsd__time` value is always considered and
1464 represented in UTC by the serializer.
1465 
1466 To convert date and/or time values to a string, we use the auto-generated
1467 function for type `T`:
1468 
1469 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
1470  const char *soap_T2s(struct soap*, T val)
1471 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1472 
1473 For date and time types `T`, the string returned is stored in an internal
1474 buffer of the current `soap` context, so you MUST copy it to keep it from being
1475 overwritten. For example, use `char *soap_strdup(struct soap*, const char*)`.
1476 
1477 To convert a string to a date/time value, we use the auto-generated function
1478 
1479 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
1480  int soap_s2T(struct soap*, const char *str, T *val)
1481 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1482 
1483 where `T` is for example `dateTime` (for `time_t`), `xsd__dateTime` (for
1484 `struct tm`, `struct timeval`, or `std::chrono::system_clock::time_point`).
1485 The function `soap_s2T` returns `SOAP_OK` on success or an error when the value
1486 is not a date/time.
1487 
1488 
1489 Time duration types {#toxsd8}
1490 -------------------
1491 
1492 The XML value space of xsd:duration are values of the form `PnYnMnDTnHnMnS`
1493 where the capital letters are delimiters. Delimiters may be omitted when the
1494 corresponding member is not used.
1495 
1496 A `long long` (`LONG64` or `int64_t`) type that contains a duration (time
1497 lapse) in milliseconds is mapped to the built-in xsd:duration XSD type and
1498 serialized with the custom serializer `custom/duration.h` that declares a
1499 `xsd__duration` type:
1500 
1501 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
1502  #import "custom/duration.h" // import typedef long long xsd__duration;
1503  ... use xsd__duration ...
1504 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1505 
1506 Compile and link your code with `custom/duration.c`.
1507 
1508 The duration type `xsd__duration` can represent 106,751,991,167 days forward
1509 and backward with millisecond precision.
1510 
1511 Durations that exceed a month are always output in days, rather than months to
1512 avoid days-per-month conversion inacurracies.
1513 
1514 Durations that are received in years and months instead of total number of days
1515 from a reference point are not well defined, since there is no accepted
1516 reference time point (it may or may not be the current time). The decoder
1517 simple assumes that there are 30 days per month. For example, conversion of
1518 "P4M" gives 120 days. Therefore, the durations "P4M" and "P120D" are assumed
1519 to be identical, which is not necessarily true depending on the reference point
1520 in time.
1521 
1522 Rescaling of the duration value by may be needed when adding the duration value
1523 to a `time_t` value, because `time_t` may or may not have a seconds resolution,
1524 depending on the platform and possible changes to `time_t`.
1525 
1526 Rescaling is done automatically when you add a C++11 `std::chrono::nanoseconds`
1527 value to a `std::chrono::system_clock::time_point` value. To use
1528 `std::chrono::nanoseconds` as xsd:duration:
1529 
1530 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
1531  #import "custom/chrono_duration.h" // import typedef std::chrono::duration xsd__duration;
1532  ... use xsd__duration ...
1533 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1534 
1535 Compile and link your code with `custom/chrono_duration.cpp`.
1536 
1537 This type can represent 384,307,168 days (2^63 nanoseconds) forwards and
1538 backwards in time in increments of 1 ns (1/1000000000 second).
1539 
1540 The same observations with respect to receiving durations in years and months
1541 apply to this serializer's decoder.
1542 
1543 To convert duration values to a string, we use the auto-generated function
1544 
1545 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
1546  const char *soap_xsd__duration2s(struct soap*, xsd__duration val)
1547 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1548 
1549 The string returned is stored in an internal buffer, so you MUST copy it to
1550 keep it from being overwritten, Use `soap_strdup(struct soap*, const char*)`
1551 for example to copy this string.
1552 
1553 To convert a string to a duration value, we use the auto-generated function
1554 
1555 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
1556  int soap_s2xsd__dateTime(struct soap*, const char *str, xsd__dateTime *val)
1557 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1558 
1559 The function returns `SOAP_OK` on success or an error when the value is not a
1560 duration.
1561 
1562 
1563 Classes and structs {#toxsd9}
1564 -------------------
1565 
1566 Classes and structs are mapped to XSD complexTypes. The XML value space
1567 consists of XML elements with attributes and subelements, possibly constrained
1568 by validation rules that enforce element and attribute occurrence contraints,
1569 numerical value range constraints, and string length and pattern constraints.
1570 
1571 Classes that are declared with the gSOAP tools are limited to single
1572 inheritence only. Structs cannot be inherited.
1573 
1574 The class and struct name is bound to an XML namespace by means of the prefix
1575 naming convention or by using [Colon notation](#toxsd1):
1576 
1577 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
1578  //gsoap ns schema namespace: urn:types
1579  class ns__record
1580  {
1581  public:
1582  std::string name;
1583  uint64_t SSN;
1584  ns__record *spouse;
1585  ns__record();
1586  ~ns__record();
1587  protected:
1588  struct soap *soap;
1589  };
1590 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1591 
1592 In the example above, we also added a context pointer to the `struct soap` that
1593 manages this instance. It is set when the instance is created in the engine's
1594 context, for example when deserialized and populated by the engine.
1595 
1596 The class maps to a complexType in the soapcpp2-generated schema:
1597 
1598  <complexType name="record">
1599  <sequence>
1600  <element name="name" type="xsd:string" minOccurs="1" maxOccurs="1"/>
1601  <element name="SSN" type="xsd:unsignedLong" minOccurs="1" maxOccurs="1"/>
1602  <element name="spouse" type="ns:record" minOccurs="0" maxOccurs="1" nillable="true"/>
1603  </sequence>
1604  </complexType>
1605 
1606 ### Serializable versus transient types and members {#toxsd9-1}
1607 
1608 Public data members of a class or struct are serialized. Private and protected
1609 members are transient and not serializable.
1610 
1611 Also `const` and `static` members are not serializable, with the exception of
1612 `const char*` and `const wchar_t*`.
1613 
1614 Types and specific class/struct members can be made transient by using the
1615 `extern` qualifier:
1616 
1617 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
1618  extern class std::ostream; // declare 'std::ostream' transient
1619  class ns__record
1620  {
1621  public:
1622  extern int num; // not serialized
1623  std::ostream out; // not serialized
1624  static const int MAX = 1024; // not serialized
1625  };
1626 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1627 
1628 By declaring `std::ostream` transient we can use this type where we need it and
1629 without soapcpp2 complaining that this class is not defined.
1630 
1631 ### Volatile classes and structs {#toxsd9-2}
1632 
1633 Classes and structs can be declared `volatile` with the gSOAP tools. This means
1634 that they are already declared elsewhere in our project's source code. We do
1635 not want soapcpp2 to generate a second definition for these types.
1636 
1637 For example, `struct tm` is declared in `<time.h>`. We want it serializable and
1638 serialize only a selection of its data members:
1639 
1640 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
1641  volatile struct tm
1642  {
1643  int tm_sec; // seconds (0 - 60)
1644  int tm_min; // minutes (0 - 59)
1645  int tm_hour; // hours (0 - 23)
1646  int tm_mday; // day of month (1 - 31)
1647  int tm_mon; // month of year (0 - 11)
1648  int tm_year; // year - 1900
1649  };
1650 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1651 
1652 We can declare classes and structs `volatile` for any such types we want to
1653 serialize by only providing the public data members we want to serialize.
1654 
1655 Colon notation is a simple and effective way to bind an existing class or
1656 struct to a schema. For example, we can change the `tm` name as follows
1657 without affecting the code that uses `struct tm` generated by soapcpp2:
1658 
1659 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
1660  volatile struct ns:tm { ... }
1661 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1662 
1663 This struct maps to a complexType in the soapcpp2-generated schema:
1664 
1665  <complexType name="tm">
1666  <sequence>
1667  <element name="tm-sec" type="xsd:int" minOccurs="1" maxOccurs="1"/>
1668  <element name="tm-min" type="xsd:int" minOccurs="1" maxOccurs="1"/>
1669  <element name="tm-hour" type="xsd:int" minOccurs="1" maxOccurs="1"/>
1670  <element name="tm-mday" type="xsd:int" minOccurs="1" maxOccurs="1"/>
1671  <element name="tm-mon" type="xsd:int" minOccurs="1" maxOccurs="1"/>
1672  <element name="tm-year" type="xsd:int" minOccurs="1" maxOccurs="1"/>
1673  </sequence>
1674  </complexType>
1675 
1676 ### Mutable classes and structs {#toxsd9-3}
1677 
1678 Classes and structs can be declared `mutable` with the gSOAP tools. This means
1679 that their definition can be spread out over the source code. This promotes the
1680 concept of a class or struct as a *row of named values*, also known as a *named
1681 tuple*, that can be extended at compile time in our source code with additional
1682 members. Because these types differ from the traditional object-oriented
1683 principles and design concepts of classes and objects, constructors and
1684 destructors cannot be defined (also because we cannot guarantee merging these
1685 into one such that all members will be initialized). A default constructor,
1686 copy constructor, assignment operation, and destructor will be assigned
1687 automatically by soapcpp2.
1688 
1689 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
1690  mutable struct ns__tuple
1691  {
1692  @std::string id;
1693  };
1694 
1695  mutable struct ns__tuple
1696  {
1697  std::string name;
1698  std::string value;
1699  };
1700 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1701 
1702 The members are collected into one definition generated by soapcpp2. Members
1703 may be repeated from one definition to another, but only if their associated
1704 types are identical. So, for example, a third extension with a `value` member
1705 with a different type fails:
1706 
1707 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
1708  mutable struct ns__tuple
1709  {
1710  float value; // BAD: value is already declared std::string
1711  };
1712 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1713 
1714 The `mutable` concept has proven to be very useful when declaring and
1715 collecting SOAP Headers for multiple services, which are collected into one
1716 `struct SOAP_ENV__Header` by the soapcpp2 tool.
1717 
1718 ### Default member values in C and C++ {#toxsd9-4}
1719 
1720 Class and struct data members in C and C++ may be declared with an optional
1721 default initialization value that is provided "inline" with the declaration of
1722 the member:
1723 
1724 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
1725  class ns__record
1726  {
1727  public:
1728  std::string name = "Joe";
1729  ...
1730  };
1731 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1732 
1733 These initializations are made by the default constructor that is added by
1734 soapcpp2 to each class and struct. A constructor is only added when a default
1735 constructor is not already defined with the class declaration. You can
1736 explicitly (re)initialize an object with the auto-generated
1737 `soap_default(struct soap*)` method of a class and the auto-generated
1738 `soap_default_T(struct soap*, T*)` function for a struct `T` in C and C++.
1739 
1740 Initializations can only be provided for members that have primitive types
1741 (`bool`, `enum`, `time_t`, numeric and string types).
1742 
1743 ### Attribute members {#toxsd9-5}
1744 
1745 Class and struct data members can be declared as XML attributes by annotating
1746 their type with a `@` with the declaration of the member:
1747 
1748 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
1749  class ns__record
1750  {
1751  public:
1752  @std::string name;
1753  @uint64_t SSN;
1754  ns__record *spouse;
1755  };
1756 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1757 
1758 This class maps to a complexType in the soapcpp2-generated schema:
1759 
1760  <complexType name="record">
1761  <sequence>
1762  <element name="spouse" type="ns:record" minOccurs="0" maxOccurs="1" nillable="true"/>
1763  </sequence>
1764  <attribute name="name" type="xsd:string" use="required"/>
1765  <attribute name="SSN" type="xsd:unsignedLong" use="required"/>
1766  </complexType>
1767 
1768 An example XML instance of `ns__record` is:
1769 
1770  <ns:record xmlns:ns="urn:types" name="Joe" SSN="1234567890">
1771  <spouse name="Jane" SSN="1987654320">
1772  </spouse>
1773  </ns:record>
1774 
1775 Attribute data members are restricted to primitive types (`bool`, `enum`,
1776 `time_t`, numeric and string types), `xsd__hexBinary`, `xsd__base64Binary`, and
1777 custom serializers, such as `xsd__dateTime`. Custom serializers for types that
1778 may be used as attributes MUST define `soap_s2T` and `soap_T2s` functions that
1779 convert values of type `T` to strings and back.
1780 
1781 Attribute data members can be pointers and smart pointers to these types, which
1782 permits attributes to be optional.
1783 
1784 ### Qualified and unqualified members {#toxsd9-6}
1785 
1786 Class, struct, and union data members are mapped to namespace qualified or
1787 unqualified tag names of local elements and attributes. If a data member has
1788 no prefix then the default form of qualification is applied based on the
1789 element/attribute form that is declared with the schema of the class, struct,
1790 or union type. If the member name has a namespace prefix by colon notation,
1791 then the prefix overrules the default (un)qualified form. Colon notation is an
1792 effective mechanism to control qualification of tag names of individual members
1793 of classes, structs, and unions.
1794 
1795 The XML schema elementFormDefault and attributeFormDefault declarations control
1796 the tag name qualification of local elements and attributes, respectively.
1797 
1798 - "unqualified" indicates that local elements/attributes are not qualified with
1799  the namespace prefix.
1800 
1801 - "qualified" indicates that local elements/attributes must be qualified with
1802  the namespace prefix.
1803 
1804 Individual schema declarations of local elements and attributes may overrule
1805 this by using the form declaration in a schema and by using colon notation to
1806 add namespace prefixes to class, struct, and union members in the header file
1807 for soapcpp2.
1808 
1809 Consider for example an `ns__record` class in the `ns` namespace in which local
1810 elements are qualified and local attributes are unqualified by default:
1811 
1812 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
1813  //gsoap ns schema namespace: urn:types
1814  //gsoap ns schema elementForm: qualified
1815  //gsoap ns schema attributeForm: unqualified
1816  class ns__record
1817  {
1818  public:
1819  @std::string name;
1820  @uint64_t SSN;
1821  ns__record *spouse;
1822  };
1823 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1824 
1825 This class maps to a complexType in the soapcpp2-generated schema with
1826 targetNamespace "urn:types", elementFormDefault qualified and
1827 attributeFormDefault unqualified:
1828 
1829  <schema targetNamespace="urn:types"
1830  ...
1831  elementFormDefault="qualified"
1832  attributeFormDefault="unqualified"
1833  ... >
1834  <complexType name="record">
1835  <sequence>
1836  <element name="spouse" type="ns:record" minOccurs="0" maxOccurs="1" nillable="true"/>
1837  </sequence>
1838  <attribute name="name" type="xsd:string" use="required"/>
1839  <attribute name="SSN" type="xsd:unsignedLong" use="required"/>
1840  </complexType>
1841  </schema>
1842 
1843 An example XML instance of `ns__record` is:
1844 
1845  <ns:record xmlns:ns="urn:types" name="Joe" SSN="1234567890">
1846  <ns:spouse> name="Jane" SSN="1987654320">
1847  </ns:spouse>
1848  </ns:record>
1849 
1850 Note that the root element ns:record is qualified because it is a root element
1851 of the schema with target namespace "urn:types". Its local element ns:spouse
1852 is namespace qualified because the elementFormDefault of local elements is
1853 qualified. Attributes are unqualified.
1854 
1855 The default namespace (un)qualification of local elements and attributes can be
1856 overruled by adding a prefix to the member name by using colon notation:
1857 
1858 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
1859  //gsoap ns schema namespace: urn:types
1860  //gsoap ns schema elementForm: qualified
1861  //gsoap ns schema attributeForm: unqualified
1862  class ns__record
1863  {
1864  public:
1865  @std::string ns:name; // 'ns:' qualified
1866  @uint64_t SSN;
1867  ns__record *:spouse; // ':' unqualified
1868  };
1869 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1870 
1871 The colon notation for member `ns:name` forces qualification of its attribute
1872 tag in XML. The colon notation for member `:spouse` removes qualification from
1873 its local element tag:
1874 
1875  <schema targetNamespace="urn:types"
1876  ...
1877  elementFormDefault="unqualified"
1878  attributeFormDefault="unqualified"
1879  ... >
1880  <complexType name="record">
1881  <sequence>
1882  <element name="spouse" type="ns:record" minOccurs="0" maxOccurs="1" nillable="true" form="unqualified"/>
1883  </sequence>
1884  <attribute name="name" type="xsd:string" use="required" form="qualified"/>
1885  <attribute name="SSN" type="xsd:unsignedLong" use="required"/>
1886  </complexType>
1887  </schema>
1888 
1889 XML instances of `ns__record` have unqualified spouse elements and qualified
1890 ns:name attributes:
1891 
1892  <ns:record xmlns:ns="urn:types" ns:name="Joe" SSN="1234567890">
1893  <spouse> ns:name="Jane" SSN="1987654320">
1894  </spouse>
1895  </ns:record>
1896 
1897 Note that data members can also be prefixed using the `prefix__name`
1898 convention. However, this has a different effect by referring to global (root)
1899 elements and attributes, see [Defining document root elements](#toxsd9-7).
1900 
1901 @note You must declare a target namespace with a `//gsoap ns schema namespace:`
1902 directive to enable the `elementForm` and `attributeForm` directives in order
1903 to generate valid schemas with soapcpp2.
1904 
1905 ### Defining document root elements {#toxsd9-7}
1906 
1907 To define and reference XML document root elements we use type names that start
1908 with an underscore:
1909 
1910 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
1911  class _ns__record
1912 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1913 
1914 Alternatively, we can use a typedef to define a document root element with a
1915 given type:
1916 
1917 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
1918  typedef ns__record _ns__record;
1919 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1920 
1921 This typedef maps to a global root element that is added to the
1922 soapcpp2-generated schema:
1923 
1924  <element name="record" type="ns:record"/>
1925 
1926 An example XML instance of `_ns__record` is:
1927 
1928  <ns:record xmlns:ns="urn:types">
1929  <name>Joe</name>
1930  <SSN>1234567890</SSN>
1931  <spouse>
1932  <name>Jane</name>
1933  <SSN>1987654320</SSN>
1934  </spouse>
1935  </ns:record>
1936 
1937 Global-level element/attribute definitions are also referenced and/or added to
1938 the generated schema when serializable data members reference these by their
1939 qualified name:
1940 
1941 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
1942  typedef std::string _ns__name 1 : 100;
1943  class _ns__record
1944  {
1945  public:
1946  @_QName xsi__type; // built-in XSD attribute xsi:type
1947  _ns__name ns__name; // ref to global ns:name element
1948  uint64_t SSN;
1949  _ns__record *spouse;
1950  };
1951 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1952 
1953 These types map to the following comonents in the soapcpp2-generated schema:
1954 
1955  <simpleType name="name">
1956  <restriction base="xsd:string">
1957  <minLength value="1"/>
1958  <maxLength value="100"/>
1959  </restriction>
1960  </simpleType>
1961  <element name="name" type="ns:name"/>
1962  <complexType name="record">
1963  <sequence>
1964  <element ref="ns:name" minOccurs="1" maxOccurs="1"/>
1965  <element name="SSN" type="xsd:unsignedLong" minOccurs="1" maxOccurs="1"/>
1966  <element name="spouse" type="ns:record" minOccurs="0" maxOccurs="1" nillable="true"/>
1967  </sequence>
1968  <attribute ref="xsi:type" use="optional"/>
1969  </complexType>
1970  <element name="record" type="ns:record"/>
1971 
1972 Use only use qualified member names when their types match the global-level
1973 element types that they refer to. For example:
1974 
1975 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
1976  typedef std::string _ns__name; // global element ns:name of type xsd:string
1977  class _ns__record
1978  {
1979  public:
1980  int ns__name; // BAD: global element ns:name is NOT type int
1981  _ns__record ns__record; // OK: ns:record is a global-level root element
1982  ...
1983  };
1984 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1985 
1986 Therefore, we recommend to use qualified member names only when necessary to
1987 refer to standard XSD elements and attributes, such as `xsi__type`, and
1988 `xsd__lang`.
1989 
1990 By contrast, colon notation has the desired effect to (un)qualify local tag
1991 names by overruling the default element/attribute namespace qualification, see
1992 [Qualified and unqualified members](#toxsd9-6).
1993 
1994 ### (Smart) pointer members and their occurrence constraints {#toxsd9-8}
1995 
1996 A public pointer-typed data member is serialized by following its (smart)
1997 pointer(s) to the value pointed to. To serialize pointers to dynamic arrays of
1998 data, please see the next section on [Container members and their occurrence
1999 constraints](#toxsd9-9).
2000 
2001 Pointers that are NULL and smart pointers that are empty are serialized to
2002 produce omitted element and attribute values, unless an element is required
2003 and is nillable.
2004 
2005 To control the occurrence requirements of pointer-based data members,
2006 occurrence constraints are associated with data members in the form of a range
2007 `minOccurs : maxOccurs`. For non-repeatable (meaning, not a container or array)
2008 data members, there are only three reasonable occurrence constraints:
2009 
2010 - `0:0` means that this element or attribute is prohibited.
2011 - `0:1` means that this element or attribute is optional.
2012 - `1:1` means that this element or attribute is required.
2013 
2014 Pointer-based data members have a default `0:1` occurrence constraint, making
2015 them optional, and their XML schema local element/attribute definition is
2016 marked as nillable. Non-pointer data members have a default `1:1` occurence
2017 constraint, making them required.
2018 
2019 A pointer data member that is explicitly marked as required with `1:1` will be
2020 serialized as an element with an xsi:nil attribute, thus effectively revealing
2021 the NULL property of its value.
2022 
2023 A non-pointer data member that is explicitly marked as optional with `0:1` will
2024 be set to its default value when no XML value is presented to the deserializer.
2025 A default value can be assigned to data members that have primitive types.
2026 
2027 Consider for example:
2028 
2029 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
2030  class ns__record
2031  {
2032  public:
2033  std::shared_ptr<std::string> name; // optional (0:1)
2034  uint64_t SSN 0:1 = 999; // forced this to be optional with default 999
2035  ns__record *spouse 1:1; // forced this to be required (only married people)
2036  };
2037 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2038 
2039 This class maps to a complexType in the soapcpp2-generated schema:
2040 
2041  <complexType name="record">
2042  <sequence>
2043  <element name="name" type="xsd:string" minOccurs="0" maxOccurs="1" nillable="true"/>
2044  <element name="SSN" type="xsd:unsignedLong" minOccurs="0" maxOccurs="1" default="999"/>
2045  <element name="spouse" type="ns:record" minOccurs="1" maxOccurs="1" nillable="true"/>
2046  </sequence>
2047  </complexType>
2048 
2049 An example XML instance of `ns__record` with its `name` string value set to
2050 `Joe`, `SSN` set to its default, and `spouse` set to NULL:
2051 
2052  <ns:record xmlns:ns="urn:types" ...>
2053  <name>Joe</name>
2054  <SSN>999</SSN>
2055  <spouse xsi:nil="true"/>
2056  </ns:record>
2057 
2058 @note In general, a smart pointer is simply declared as a `volatile` template
2059 in a gSOAP header file for soapcpp2:
2060 
2061 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
2062  volatile template <class T> class NAMESPACE::shared_ptr;
2063 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2064 
2065 @note The soapcpp2 tool generates code that uses `NAMESPACE::shared_ptr` and
2066 `NAMESPACE::make_shared` to create shared pointers to objects, where
2067 `NAMESPACE` is any valid C++ namespace such as `std` and `boost` if you have
2068 Boost installed.
2069 
2070 ### Container members and their occurrence constraints {#toxsd9-9}
2071 
2072 Class and struct data member types that are containers `std::deque`,
2073 `std::list`, `std::vector` and `std::set` are serialized as a collection of
2074 the values they contain. You can also serialize dynamic arrays, which is the
2075 alternative for C to store collections of data. Let's start with STL containers.
2076 
2077 You can use `std::deque`, `std::list`, `std::vector`, and `std::set` containers
2078 by importing:
2079 
2080 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
2081  #import "import/stl.h" // import all containers
2082  #import "import/stldeque.h" // import deque
2083  #import "import/stllist.h" // import list
2084  #import "import/stlvector.h" // import vector
2085  #import "import/stlset.h" // import set
2086 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2087 
2088 For example, to use a vector data mamber to store names in a record:
2089 
2090 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
2091  #import "import/stlvector.h"
2092  class ns__record
2093  {
2094  public:
2095  std::vector<std::string> names;
2096  uint64_t SSN;
2097  };
2098 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2099 
2100 To limit the number of names in the vector within reasonable bounds, occurrence
2101 constraints are associated with the container. Occurrence constraints are of
2102 the form `minOccurs : maxOccurs`:
2103 
2104 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
2105  #import "import/stlvector.h"
2106  class ns__record
2107  {
2108  public:
2109  std::vector<std::string> names 1:10;
2110  uint64_t SSN;
2111  };
2112 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2113 
2114 This class maps to a complexType in the soapcpp2-generated schema:
2115 
2116  <complexType name="record">
2117  <sequence>
2118  <element name="name" type="xsd:string" minOccurs="1" maxOccurs="10"/>
2119  <element name="SSN" type="xsd:unsignedLong" minOccurs="1" maxOccurs="1""/>
2120  </sequence>
2121  </complexType>
2122 
2123 @note In general, a container is simply declared as a template in a gSOAP
2124 header file for soapcpp2. All class templates are considered containers
2125 (except when declared `volatile`, see smart pointers). For example,
2126 `std::vector` is declared in `gsoap/import/stlvector.h` as:
2127 
2128 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
2129  template <class T> class std::vector;
2130 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2131 
2132 @note You can define and use your own containers. The soapcpp2 tool generates
2133 code that uses the following members of the `template <typename T> class C`
2134 container:
2135 
2136 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
2137  void C::clear()
2138  C::iterator C::begin()
2139  C::const_iterator C::begin() const
2140  C::iterator C::end()
2141  C::const_iterator C::end() const
2142  size_t C::size() const
2143  C::iterator C::insert(C::iterator pos, const T& val)
2144 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2145 
2146 @note For more details see the example `simple_vector` container with
2147 documentation in the package under `gsoap/samples/template`.
2148 
2149 Because C does not support a container template library, we can use a
2150 dynamically-sized array of values. This array is declared as a size-pointer
2151 pair of members within a struct or class. The array size information is stored
2152 in a special size tag member with the name `__size` or `__sizeX`, where `X` can
2153 be any name, or by an `$int` member to identify the member as a special size
2154 tag:
2155 
2156 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
2157  struct ns__record
2158  {
2159  $int sizeofnames; // array size
2160  char* *names; // array of char* names
2161  uint64_t SSN;
2162  };
2163 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2164 
2165 This class maps to a complexType in the soapcpp2-generated schema:
2166 
2167  <complexType name="record">
2168  <sequence>
2169  <element name="name" type="xsd:string" minOccurs="0" maxOccurs="unbounded" nillable="true"/>
2170  <element name="SSN" type="xsd:unsignedLong" minOccurs="1" maxOccurs="1""/>
2171  </sequence>
2172  </complexType>
2173 
2174 To limit the number of names in the array within reasonable bounds, occurrence
2175 constraints are associated with the array size member. Occurrence constraints
2176 are of the form `minOccurs : maxOccurs`:
2177 
2178 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
2179  struct ns__record
2180  {
2181  $int sizeofnames 1:10; // array size 1..10
2182  char* *names; // array of one to ten char* names
2183  uint64_t SSN;
2184  };
2185 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2186 
2187 This class maps to a complexType in the soapcpp2-generated schema:
2188 
2189  <complexType name="record">
2190  <sequence>
2191  <element name="name" type="xsd:string" minOccurs="1" maxOccurs="10" nillable="true"/>
2192  <element name="SSN" type="xsd:unsignedLong" minOccurs="1" maxOccurs="1""/>
2193  </sequence>
2194  </complexType>
2195 
2196 ### Tagged union members {#toxsd9-10}
2197 
2198 A union member in a class or in a struct cannot be serialized unless a
2199 discriminating *variant selector* member is provided that tells the serializer
2200 which union field to serialize. This effectively creates a *tagged union*.
2201 
2202 The variant selector is associated with the union as a selector-union pair of members.
2203 The variant selector is a member with the name `__union` or `__unionX`, where
2204 `X` can be any name, or by an `$int` member to identify the member as a variant
2205 selector tag:
2206 
2207 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
2208  class ns__record
2209  {
2210  public:
2211  $int xORnORs; // variant selector with values SOAP_UNION_fieldname
2212  union choice
2213  {
2214  float x;
2215  int n;
2216  char *s;
2217  } u;
2218  std::string name;
2219  };
2220 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2221 
2222 The variant selector values are auto-generated based on the union name `choice`
2223 and the names of its members `x`, `n`, and `s`:
2224 
2225 - `xORnORs = SOAP_UNION_choice_x` when `u.x` is valid.
2226 - `xORnORs = SOAP_UNION_choice_n` when `u.n` is valid.
2227 - `xORnORs = SOAP_UNION_choice_s` when `u.s` is valid.
2228 - `xORnORs = 0` when none are valid (should only be used with great care,
2229  because XML content validation may fail when content is required but absent).
2230 
2231 This class maps to a complexType with a sequence and choice in the
2232 soapcpp2-generated schema:
2233 
2234  <complexType name="record">
2235  <sequence>
2236  <choice>
2237  <element name="x" type="xsd:float" minOccurs="1" maxOccurs="1"/>
2238  <element name="n" type="xsd:int" minOccurs="1" maxOccurs="1"/>
2239  <element name="s" type="xsd:string" minOccurs="0" maxOccurs="1" nillable="true"/>
2240  </choice>
2241  <element name="names" type="xsd:string" minOccurs="1" maxOccurs="1" nillable="true"/>
2242  </sequence>
2243  </complexType>
2244 
2245 An STL container or dynamic array of a union requires wrapping the variant
2246 selector and union member in a struct:
2247 
2248 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
2249  class ns__record
2250  {
2251  public:
2252  std::vector<
2253  struct ns__data // data with a choice of x, n, or s
2254  {
2255  $int xORnORs; // variant selector with values SOAP_UNION_fieldname
2256  union choice
2257  {
2258  float x;
2259  int n;
2260  char *s;
2261  } u;
2262  }> data; // vector with data
2263  };
2264 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2265 
2266 and an equivalent definition with a dynamic array instead of a `std::vector`
2267 (you can use this in C with structs):
2268 
2269 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
2270  class ns__record
2271  {
2272  public:
2273  $int sizeOfdata; // size of dynamic array
2274  struct ns__data // data with a choice of x, n, or s
2275  {
2276  $int xORnORs; // variant selector with values SOAP_UNION_fieldname
2277  union choice
2278  {
2279  float x;
2280  int n;
2281  char *s;
2282  } u;
2283  } *data; // points to the data array of length sizeOfdata
2284  };
2285 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2286 
2287 This maps to two complexTypes in the soapcpp2-generated schema:
2288 
2289  <complexType name="data">
2290  <choice>
2291  <element name="x" type="xsd:float" minOccurs="1" maxOccurs="1"/>
2292  <element name="n" type="xsd:int" minOccurs="1" maxOccurs="1"/>
2293  <element name="s" type="xsd:string" minOccurs="0" maxOccurs="1" nillable="true"/>
2294  </choice>
2295  </complexType>
2296  <complexType name="record">
2297  <sequence>
2298  <element name="data" type="ns:data" minOccurs="0" maxOccurs="unbounded"/>
2299  </sequence>
2300  </complexType>
2301 
2302 The XML value space consists of a sequence of item elements each wrapped in an
2303 data element:
2304 
2305  <ns:record xmlns:ns="urn:types" ...>
2306  <data>
2307  <n>123</n>
2308  </data>
2309  <data>
2310  <x>3.1</x>
2311  </data>
2312  <data>
2313  <s>hello</s>
2314  </data>
2315  <data>
2316  <s>world</s>
2317  </data>
2318  </ns:record>
2319 
2320 To remove the wrapping data element, simply rename the wrapping struct and
2321 member to `__data` to make this member invisible to the serializer with the
2322 double underscore prefix naming convention. Also use a dynamic array instead
2323 of a STL container (you can use this in C with structs):
2324 
2325 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
2326  class ns__record
2327  {
2328  public:
2329  $int sizeOfdata; // size of dynamic array
2330  struct __data // contains choice of x, n, or s
2331  {
2332  $int xORnORs; // variant selector with values SOAP_UNION_fieldname
2333  union choice
2334  {
2335  float x;
2336  int n;
2337  char *s;
2338  } u;
2339  } *__data; // points to the data array of length sizeOfdata
2340  };
2341 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2342 
2343 This maps to a complexType in the soapcpp2-generated schema:
2344 
2345  <complexType name="record">
2346  <sequence minOccurs="0" maxOccurs="unbounded">
2347  <choice>
2348  <element name="x" type="xsd:float" minOccurs="1" maxOccurs="1"/>
2349  <element name="n" type="xsd:int" minOccurs="1" maxOccurs="1"/>
2350  <element name="s" type="xsd:string" minOccurs="0" maxOccurs="1" nillable="true"/>
2351  </choice>
2352  </sequence>
2353  </complexType>
2354 
2355 The XML value space consists of a sequence of x, n, and/or s elements:
2356 
2357  <ns:record xmlns:ns="urn:types" ...>
2358  <n>123</n>
2359  <x>3.1</x>
2360  <s>hello</s>
2361  <s>world</s>
2362  </ns:record>
2363 
2364 Please note that structs, classes, and unions are unnested by soapcpp2 (as in
2365 the C standard of nested structs and unions). Therefore, the `choice` union in
2366 the `ns__record` class is redeclared at the top level despite its nesting
2367 within the `ns__record` class. This means that you will have to choose a
2368 unique name for each nested struct, class, and union.
2369 
2370 ### Tagged void pointer members {#toxsd9-11}
2371 
2372 To serialize data pointed to by `void*` requires run-time type information that
2373 tells the serializer what type of data to serialize by means of a *tagged void
2374 pointer*. This type information is stored in a special type tag member of a
2375 struct/class with the name `__type` or `__typeX`, where `X` can be any name, or
2376 alternatively by an `$int` special member of any name as a type tag:
2377 
2378 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
2379  class ns__record
2380  {
2381  public:
2382  $int typeOfdata; // type tag with values SOAP_TYPE_T
2383  void *data; // points to some data of type T
2384  };
2385 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2386 
2387 A type tag member has nonzero values `SOAP_TYPE_T` where `T` is the name of a
2388 struct/class or the name of a primitive type, such as `int`, `std__string` (for
2389 `std::string`), `string` (for `char*`).
2390 
2391 This class maps to a complexType with a sequence in the soapcpp2-generated
2392 schema:
2393 
2394  <complexType name="record">
2395  <sequence>
2396  <element name="data" type="xsd:anyType" minOccurs="0" maxOccurs="1"/>
2397  </sequence>
2398  </complexType>
2399 
2400 The XML value space consists of the XML value space of the type with the
2401 addition of an xsi:type attribute to the enveloping element:
2402 
2403  <ns:record xmlns:ns="urn:types" ...>
2404  <data xsi:type="xsd:int">123</data>
2405  </ns:record>
2406 
2407 This xsi:type attribute is important for the receiving end to distinguish the
2408 type of data to instantiate. The receiver cannot deserialize the data without
2409 an xsd:type attribute.
2410 
2411 You can find the `SOAP_TYPE_T` name of each serializable type in the
2412 auto-generated soapStub.h file.
2413 
2414 Also all serializable C++ classes have a virtual `int T::soap_type()` member
2415 that returns their `SOAP_TYPE_T` value that you can use.
2416 
2417 When the `void*` pointer is NULL or when `typeOfdata` is zero, the data is not
2418 serialized.
2419 
2420 An STL container or dynamic array of `void*` pointers to xsd:anyType data
2421 requires wrapping the type tag and `void*` members in a struct:
2422 
2423 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
2424  class ns__record
2425  {
2426  public:
2427  std::vector<
2428  struct ns__data // data with an xsd:anyType item
2429  {
2430  $int typeOfitem; // type tag with values SOAP_TYPE_T
2431  void *item; // points to some item of type T
2432  }> data; // vector with data
2433  };
2434 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2435 
2436 and an equivalent definition with a dynamic array instead of a `std::vector`
2437 (you can use this in C with structs):
2438 
2439 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
2440  class ns__record
2441  {
2442  public:
2443  $int sizeOfdata; // size of dynamic array
2444  struct ns__data // data with an xsd:anyType item
2445  {
2446  $int typeOfitem; // type tag with values SOAP_TYPE_T
2447  void *item; // points to some item of type T
2448  } *data; // points to the data array of length sizeOfdata
2449  };
2450 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2451 
2452 This maps to two complexTypes in the soapcpp2-generated schema:
2453 
2454  <complexType name="data">
2455  <sequence>
2456  <element name="item" type="xsd:anyType" minOccurs="1" maxOccurs="1" nillable="true"/>
2457  </sequence>
2458  </complexType>
2459  <complexType name="record">
2460  <sequence>
2461  <element name="data" type="ns:data" minOccurs="0" maxOccurs="unbounded"/>
2462  </sequence>
2463  </complexType>
2464 
2465 The XML value space consists of a sequence of item elements each wrapped in a
2466 data element:
2467 
2468  <ns:record xmlns:ns="urn:types" ...>
2469  <data>
2470  <item xsi:type="xsd:int">123</item>
2471  </data>
2472  <data>
2473  <item xsi:type="xsd:double">3.1</item>
2474  </data>
2475  <data>
2476  <item xsi:type="xsd:string">abc</item>
2477  </data>
2478  </ns:record>
2479 
2480 To remove the wrapping data elements, simply rename the wrapping struct and
2481 member to `__data` to make this member invisible to the serializer with the
2482 double underscore prefix naming convention. Also use a dynamic array instead
2483 of a STL container (you can use this in C with structs):
2484 
2485 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
2486  class ns__record
2487  {
2488  public:
2489  $int sizeOfdata; // size of dynamic array
2490  struct __data // contains xsd:anyType item
2491  {
2492  $int typeOfitem; // type tag with values SOAP_TYPE_T
2493  void *item; // points to some item of type T
2494  } *__data; // points to the data array of length sizeOfdata
2495  };
2496 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2497 
2498 This maps to a complexType in the soapcpp2-generated schema:
2499 
2500  <complexType name="record">
2501  <sequence minOccurs="0" maxOccurs="unbounded">
2502  <element name="item" type="xsd:anyType" minOccurs="1" maxOccurs="1"/>
2503  </sequence>
2504  </complexType>
2505 
2506 The XML value space consists of a sequence of data elements:
2507 
2508  <ns:record xmlns:ns="urn:types" ...>
2509  <item xsi:type="xsd:int">123</item>
2510  <item xsi:type="xsd:double">3.1</item>
2511  <item xsi:type="xsd:string">abc</item>
2512  </ns:record>
2513 
2514 Again, please note that structs, classes, and unions are unnested by soapcpp2
2515 (as in the C standard of nested structs and unions). Therefore, the `__data`
2516 struct in the `ns__record` class is redeclared at the top level despite its
2517 nesting within the `ns__record` class. This means that you will have to choose
2518 a unique name for each nested struct, class, and union.
2519 
2520 @see Section [XSD type bindings](#typemap2).
2521 
2522 ### Adding get and set methods {#toxsd9-12}
2523 
2524 A public `get` method may be added to a class or struct, which will be
2525 triggered by the deserializer. This method will be invoked right after the
2526 instance is populated by the deserializer. The `get` method can be used to
2527 update or verify deserialized content. It should return `SOAP_OK` or set
2528 `soap::error` to a nonzero error code and return it.
2529 
2530 A public `set` method may be added to a class or struct, which will be
2531 triggered by the serializer. The method will be invoked just before the
2532 instance is serialized. Likewise, the `set` method should return `SOAP_OK` or
2533 set set `soap::error` to a nonzero error code and return it.
2534 
2535 For example, adding a `set` and `get` method to a class declaration:
2536 
2537 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
2538  class ns__record
2539  {
2540  public:
2541  int set(struct soap*); // triggered before serialization
2542  int get(struct soap*); // triggered after deserialization
2543  ...
2544  };
2545 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2546 
2547 To add these and othe rmethods to classes and structs with wsdl2h and
2548 `typemap.dat`, please see [Class/struct member additions](#typemap3).
2549 
2550 ### Operations on classes and structs {#toxsd9-13}
2551 
2552 The following functions/macros are generated by soapcpp2 for each type `T`,
2553 which should make it easier to send, receive, and copy XML data in C and in
2554 C++:
2555 
2556 - `int soap_write_T(struct soap*, T*)` writes an instance of `T` to a file via
2557  file descriptor `int soap::sendfd)` or to a stream via `std::ostream
2558  *soap::os` (C++ only) or saves into a NUL-terminated string by setting
2559  `const char **soap::os` to a string pointer to be set (C only). Returns
2560  `SOAP_OK` on success or an error code, also stored in `soap->error`.
2561 
2562 - `int soap_read_T(struct soap*, T*)` reads an instance of `T` from a file via
2563  file descriptor `int soap::recvfd)` or from a stream via `std::istream
2564  *soap::is` (C++ only) or reads from a NUL-termianted string `const char
2565  *soap::is` (C only). Returns `SOAP_OK` on success or an error code, also
2566  stored in `soap->error`.
2567 
2568 - `void soap_default_T(struct soap*, T*)` sets an instance `T` to its default
2569  value, resetting members of a struct to their initial values (for classes we
2570  use method `T::soap_default`, see below).
2571 
2572 - `T * soap_dup_T(struct soap*, T *dst, const T *src)` (soapcpp2 option `-Ec`)
2573  deep copy `src` into `dst`, replicating all deep cycles and shared pointers
2574  when a managing soap context is provided as argument. When `dst` is NULL,
2575  allocates space for `dst`. Deep copy is a tree when argument is NULL, but the
2576  presence of deep cycles will lead to non-termination. Use flag
2577  `SOAP_XML_TREE` with managing context to copy into a tree without cycles and
2578  pointers to shared objects. Returns `dst` (or allocated space when `dst` is
2579  NULL).
2580 
2581 - `void soap_del_T(const T*)` (soapcpp2 option `-Ed`) deletes all
2582  heap-allocated members of this object by deep deletion ONLY IF this object
2583  and all of its (deep) members are not managed by a soap context AND the deep
2584  structure is a tree (no cycles and co-referenced objects by way of multiple
2585  (non-smart) pointers pointing to the same data). Can be safely used after
2586  `soap_dup(NULL)` to delete the deep copy. Does not delete the object itself.
2587 
2588 When in C++ mode, soapcpp2 tool adds several methods to classes and structs, in
2589 addition to adding a default constructor and destructor (when these were not
2590 explicitly declared).
2591 
2592 The public methods added to a class/struct `T`:
2593 
2594 - `virtual int T::soap_type(void)` returns a unique type ID (`SOAP_TYPE_T`).
2595  This numeric ID can be used to distinguish base from derived instances.
2596 
2597 - `virtual void T::soap_default(struct soap*)` sets all data members to
2598  default values.
2599 
2600 - `virtual void T::soap_serialize(struct soap*) const` serializes object to
2601  prepare for SOAP 1.1/1.2 encoded output (or with `SOAP_XML_GRAPH`) by
2602  analyzing its (cyclic) structures.
2603 
2604 - `virtual int T::soap_put(struct soap*, const char *tag, const char *type) const`
2605  emits object in XML, compliant with SOAP 1.1 encoding style, return error
2606  code or `SOAP_OK`. Requires `soap_begin_send(soap)` and
2607  `soap_end_send(soap)`.
2608 
2609 - `virtual int T::soap_out(struct soap*, const char *tag, int id, const char *type) const`
2610  emits object in XML, with tag and optional id attribute and xsi:type, return
2611  error code or `SOAP_OK`. Requires `soap_begin_send(soap)` and
2612  `soap_end_send(soap)`.
2613 
2614 - `virtual void * T::soap_get(struct soap*, const char *tag, const char *type)`
2615  Get object from XML, compliant with SOAP 1.1 encoding style, return pointer
2616  to object or NULL on error. Requires `soap_begin_recv(soap)` and
2617  `soap_end_recv(soap)`.
2618 
2619 - `virtual void *soap_in(struct soap*, const char *tag, const char *type)`
2620  Get object from XML, with matching tag and type (NULL matches any tag and
2621  type), return pointer to object or NULL on error. Requires
2622  `soap_begin_recv(soap)` and `soap_end_recv(soap)`
2623 
2624 - `virtual T * T::soap_alloc(void) const` returns a new object of type `T`,
2625  default initialized and not managed by a soap context.
2626 
2627 - `virtual T * T::soap_dup(struct soap*) const` (soapcpp2 option `-Ec`) returns
2628  a duplicate of this object by deep copying, replicating all deep cycles and
2629  shared pointers when a managing soap context is provided as argument. Deep
2630  copy is a tree when argument is NULL, but the presence of deep cycles will
2631  lead to non-termination. Use flag `SOAP_XML_TREE` with the managing context
2632  to copy into a tree without cycles and pointers to shared objects.
2633 
2634 - `virtual void T::soap_del() const` (soapcpp2 option `-Ed`) deletes all
2635  heap-allocated members of this object by deep deletion ONLY IF this object
2636  and all of its (deep) members are not managed by a soap context AND the deep
2637  structure is a tree (no cycles and co-referenced objects by way of multiple
2638  (non-smart) pointers pointing to the same data). Can be safely used after
2639  `soap_dup(NULL)` to delete the deep copy. Does not delete the object itself.
2640 
2641 
2642 Special classes and structs {#toxsd10}
2643 ---------------------------
2644 
2645 ### SOAP encoded arrays {#toxsd10-1}
2646 
2647 A class or struct with the following layout is a one-dimensional SOAP encoded
2648 Array type:
2649 
2650 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
2651  class ArrayOfT
2652  {
2653  public:
2654  T *__ptr; // array pointer
2655  int __size; // array size
2656  };
2657 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2658 
2659 where `T` is the array element type. A multidimensional SOAP Array is:
2660 
2661 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
2662  class ArrayOfT
2663  {
2664  public:
2665  T *__ptr; // array pointer
2666  int __size[N]; // array size of each dimension
2667  };
2668 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2669 
2670 where `N` is the constant number of dimensions. The pointer points to an array
2671 of `__size[0]*__size[1]* ... * __size[N-1]` elements.
2672 
2673 This maps to a complexType restriction of SOAP-ENC:Array in the
2674 soapcpp2-generated schema:
2675 
2676  <complexType name="ArrayOfT">
2677  <complexContent>
2678  <restriction base="SOAP-ENC:Array">
2679  <sequence>
2680  <element name="item" type="T" minOccurs="0" maxOccurs="unbounded" nillable="true"/>
2681  </sequence>
2682  <attribute ref="SOAP-ENC:arrayType" WSDL:arrayType="ArrayOfT[]"/>
2683  </restriction>
2684  </complexContent>
2685  </complexType>
2686 
2687 The name of the class can be arbitrary. We often use `ArrayOfT` without a
2688 prefix to distinguish arrays from other classes and structs.
2689 
2690 With SOAP 1.1 encoding, an optional offset member can be added that controls
2691 the start of the index range for each dimension:
2692 
2693 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
2694  class ArrayOfT
2695  {
2696  public:
2697  T *__ptr; // array pointer
2698  int __size[N]; // array size of each dimension
2699  int __offset[N]; // array offsets to start each dimension
2700  };
2701 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2702 
2703 For example, we can define a matrix of floats as follows:
2704 
2705 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
2706  class Matrix
2707  {
2708  public:
2709  double *__ptr;
2710  int __size[2];
2711  };
2712 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2713 
2714 The following code populates the matrix and serializes it in XML:
2715 
2716 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
2717  soap *soap = soap_new1(SOAP_XML_INDENT);
2718  Matrix A;
2719  double a[6] = { 1, 2, 3, 4, 5, 6 };
2720  A.__ptr = a;
2721  A.__size[0] = 2;
2722  A.__size[1] = 3;
2723  soap_write_Matrix(soap, &A);
2724 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2725 
2726 Matrix A is serialized as an array with 2x3 values:
2727 
2728  <SOAP-ENC:Array SOAP-ENC:arrayType="xsd:double[2,3]" ...>
2729  <item>1</item>
2730  <item>2</item>
2731  <item>3</item>
2732  <item>4</item>
2733  <item>5</item>
2734  <item>6</item>
2735  </SOAP-ENC:Array>
2736 
2737 ### XSD hexBinary and base64Binary types {#toxsd10-2}
2738 
2739 A special case of a one-dimensional array is used to define xsd:hexBinary and
2740 xsd:base64Binary types when the pointer type is `unsigned char`:
2741 
2742 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
2743  class xsd__hexBinary
2744  {
2745  public:
2746  unsigned char *__ptr; // points to raw binary data
2747  int __size; // size of data
2748  };
2749 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2750 
2751 and
2752 
2753 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
2754  class xsd__base64Binary
2755  {
2756  public:
2757  unsigned char *__ptr; // points to raw binary data
2758  int __size; // size of data
2759  };
2760 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2761 
2762 ### MIME/MTOM attachment binary types {#toxsd10-3}
2763 
2764 A class or struct with a binary content layout can be extended to support
2765 MIME/MTOM (and older DIME) attachments, such as in xop:Include elements:
2766 
2767 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
2768  //gsoap xop schema import: http://www.w3.org/2004/08/xop/include
2769  class _xop__Include
2770  {
2771  public:
2772  unsigned char *__ptr; // points to raw binary data
2773  int __size; // size of data
2774  char *id; // NULL to generate an id, or set to a unique UUID
2775  char *type; // MIME type of the data
2776  char *options; // optional description of MIME attachment
2777  };
2778 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2779 
2780 Attachments are beyond the scope of this document and we refer to the gSOAP
2781 user guide for more details.
2782 
2783 ### Wrapper class/struct with simpleContent {#toxsd10-4}
2784 
2785 A class or struct with the following layout is a complexType that wraps
2786 simpleContent:
2787 
2788 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
2789  class ns__simple
2790  {
2791  public:
2792  T __item;
2793  };
2794 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2795 
2796 The type `T` is a primitive type (`bool`, `enum`, `time_t`, numeric and string
2797 types), `xsd__hexBinary`, `xsd__base64Binary`, and custom serializers, such as
2798 `xsd__dateTime`.
2799 
2800 This maps to a complexType with simpleContent in the soapcpp2-generated schema:
2801 
2802  <complexType name="simple">
2803  <simpleContent>
2804  <extension base="T"/>
2805  </simpleContent>
2806  </complexType>
2807 
2808 A wrapper class/struct may include any number of attributes declared with `@`.
2809 
2810 ### DOM anyType and anyAttribute {#toxsd10-5}
2811 
2812 Use of a DOM is optional and enabled by `#import "dom.h"` to use the DOM
2813 `xsd__anyType` element node and `xsd__anyAttribute` attribute node:
2814 
2815 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
2816  #import "dom.h"
2817 
2818  class ns__record
2819  {
2820  public:
2821  @xsd__anyAttribute attributes; // list of DOM attributes
2822  ...
2823  xsd__anyType *name; // optional DOM element
2824  };
2825 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2826 
2827 where `name` contains XML stored in a DOM node set and `attributes` is a list
2828 of all visibly rendered attributes. The name `attributes` is arbitrary and any
2829 name will suffice.
2830 
2831 We should place the `xsd__anyType` members at the end of the struct or class.
2832 This ensures that the DOM members are populated last as a "catch all". A
2833 member name starting with double underscore is a wildcard member name and
2834 matches any XML tag. These members are placed at the end of a struct or class
2835 automatically by soapcpp2.
2836 
2837 An `#import "dom.h"` import is automatically added by wsdl2h with option `-d`
2838 to bind xsd:anyType to DOM nodes, and also to populate xsd:any,
2839 xsd:anyAttribute and xsd:mixed XML content:
2840 
2841 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
2842  #import "dom.h"
2843 
2844  class ns__record
2845  {
2846  public:
2847  ...
2848  @xsd__anyAttribute __anyAttribute; // optional DOM attributes
2849  std::vector<xsd__anyType> __any 0; // optional DOM elements
2850  xsd__anyType __mixed 0; // optional mixed content
2851  };
2852 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2853 
2854 where the members prefixed with `__` are "invisible" to the XML parser, meaning
2855 that these members are not bound to XML tag names.
2856 
2857 In C you can use a dynamic arrary instead of `std::vector`:
2858 
2859 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.c}
2860  #import "dom.h"
2861 
2862  struct ns__record
2863  {
2864  ...
2865  @xsd__anyAttribute __anyAttribute; // optional DOM attributes
2866  $int __sizeOfany; // size of the array
2867  xsd__anyType *__any; // optional DOM elements
2868  xsd__anyType __mixed 0; // optional mixed content
2869  };
2870 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2871 
2872 Classes can inherit DOM, which enables full use of polymorphism with one base
2873 DOM class:
2874 
2875 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
2876  #import "dom.h"
2877 
2878  class ns__record : public xsd__anyType
2879  {
2880  ...
2881  std::vector<xsd__anyType*> array; // array of objects of any class
2882  };
2883 
2884 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2885 
2886 This permits an `xsd__anyType` pointer to refer to a derived class such as
2887 `ns__record`, which will be serialized with an xsi:type attribute that is set
2888 to "ns:record". The xsi:type attributes add the necessary type information to
2889 distinguish the XML content from the DOM base type. This is important for the
2890 receiving end: without xsd:type attributes with type names, only base DOM
2891 objects are recognized and instantiated.
2892 
2893 Because C lacks OOP principles such as class inheritance and polymorphism, you
2894 will need to use the special [`void*` members](#toxsd9-11) to serialize data
2895 pointed to by a `void*` member.
2896 
2897 To ensure that wsdl2h generates pointer-based `xsd__anyType` DOM nodes with
2898 option `-d` for xsd:any, add the following line to `typemap.dat`:
2899 
2900  xsd__any = | xsd__anyType*
2901 
2902 This lets wsdl2h produce class/struct members and containers with
2903 `xsd__anyType*` for xsd:any instead of `xsd__anyType`. To just force all
2904 xsd:anyType uses to be pointer-based, declare in `typemap.dat`:
2905 
2906  xsd__anyType = | xsd__anyType*
2907 
2908 If you use wsdl2h with option `-p` with option `-d` then every class will
2909 inherit DOM as shown above. Without option `-d`, an `xsd__anyType` type is
2910 generated to serve as the root type in the type hierarchy:
2911 
2912 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
2913  class xsd__anyType { _XML __item; struct soap *soap; };
2914 
2915  class ns__record : public xsd__anyType
2916  {
2917  ...
2918  };
2919 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2920 
2921 where the `_XML __item` member holds any XML content as a literal XML string.
2922 
2923 To use the DOM API, compile `dom.c` (or `dom.cpp` for C++), or link with
2924 `-lgsoapssl` (or `-lgsoapssl++` for C++).
2925 
2926 @see Documentation of the [gSOAP DOM parser](http://www.genivia.com/doc/dom/html) for
2927 more details.
2928 
2929 
2930 Serialization rules {#rules}
2931 ===================
2932 
2933 A presentation on XML data bindings is not complete without discussing the
2934 serialization rules and options that put your data in XML on the wire or store
2935 it a file or buffer.
2936 
2937 There are several options to choose from to serialize data in XML. The choice
2938 depends on the use of the SOAP protocol or if SOAP is not required. The wsdl2h
2939 tool automates this for you by taking the WSDL transport bindings into account
2940 when generating the service functions in C and C++ that use SOAP or REST.
2941 
2942 The gSOAP tools are not limited to SOAP. The tools implement generic XML data
2943 bindings for SOAP, REST, and other uses of XML. So you can read and write XML
2944 using the serializing [Operations on classes and structs](#toxsd9-13).
2945 
2946 The following sections briefly explain the serialization rules with respect to
2947 the SOAP protocol for XML Web services. A basic understanding of the SOAP
2948 protocol is useful when developing client and server applications that must
2949 interoperate with other SOAP applications.
2950 
2951 SOAP/REST Web service client and service operations are represented as
2952 functions in our gSOAP header file for soapcpp2. The soapcpp2 tool will
2953 translate these function to client-side service invocation calls and
2954 server-side service operation dispatchers.
2955 
2956 A discussion of SOAP clients and servers is beyond the scope of this document.
2957 However, the SOAP options discussed here also apply to SOAP client and server
2958 development.
2959 
2960 
2961 SOAP document versus rpc style {#doc-rpc}
2962 ------------------------------
2963 
2964 The `wsdl:binding/soap:binding/@style` attribute in the wsdl:binding section of
2965 a WSDL is either "document" or "rpc". The "rpc" style refers to SOAP RPC
2966 (Remote Procedure Call), which is more restrictive than the "document" style by
2967 requiring one XML element in the SOAP Body to act as the procedure name with
2968 XML subelements as its parameters.
2969 
2970 For example, the following directives in the gSOAP header file for soapcpp2
2971 declare that `DBupdate` is a SOAP RPC encoding service method:
2972 
2973 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
2974  //gsoap ns service namespace: urn:DB
2975  //gsoap ns service method-protocol: DBupdate SOAP
2976  //gsoap ns service method-style: DBupdate rpc
2977  int ns__DBupdate(...);
2978 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2979 
2980 The XML payload has a SOAP envelope, optional SOAP header, and a SOAP body with
2981 one element representing the operation with the parameters as subelements:
2982 
2983  <SOAP-ENV:Envelope
2984  xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
2985  xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
2986  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
2987  xmlns:xsd="http://www.w3.org/2001/XMLSchema"
2988  xmlsn:ns="urn:DB">
2989  <SOAP-ENV:Body>
2990  <ns:DBupdate>
2991  ...
2992  </ns:DBupdate>
2993  </SOAP-ENV:Body>
2994  </SOAP-ENV:Envelope>
2995 
2996 The "document" style puts no restrictions on the SOAP Body content. However, we
2997 recommend that the first element's tag name in the SOAP Body should be unique
2998 to each type of operation, so that the receiver can dispatch the operation
2999 based on this element's tag name. Alternatively, the HTTP URL path can be used
3000 to specify the operation, or the HTTP action header can be used to dispatch
3001 operations automatically on the server side (soapcpp2 options -a and -A).
3002 
3003 
3004 SOAP literal versus encoding {#lit-enc}
3005 ----------------------------
3006 
3007 The `wsdl:operation/soap:body/@use` attribute in the wsdl:binding section of a
3008 WSDL is either "literal" or "encoded". The "encoded" use refers to the SOAP
3009 encoding rules that support id-ref multi-referenced elements to serialize
3010 data as graphs.
3011 
3012 SOAP encoding is very useful if the data internally forms a graph (including
3013 cycles) and we want the graph to be serialized in XML in a format that ensures
3014 that its structure is preserved. In that case, SOAP 1.2 encoding is the best
3015 option.
3016 
3017 SOAP encoding also adds encoding rules for [SOAP arrays](toxsd10) to serialize
3018 multi-dimensional arrays. The use of XML attributes to exchange XML data in
3019 SOAP encoding is not permitted. The only attributes permitted are the standard
3020 XSD attributes, SOAP encoding attributes (such as for arrays), and id-ref.
3021 
3022 For example, the following directives in the gSOAP header file for soapcpp2
3023 declare that `DBupdate` is a SOAP RPC encoding service method:
3024 
3025 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
3026  //gsoap ns service namespace: urn:DB
3027  //gsoap ns service method-protocol: DBupdate SOAP
3028  //gsoap ns service method-style: DBupdate rpc
3029  //gsoap ns service method-encoding: DBupdate encoded
3030  int ns__DBupdate(...);
3031 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3032 
3033 The XML payload has a SOAP envelope, optional SOAP header, and a SOAP body with
3034 an encodingStyle attribute for SOAP 1.1 encoding and an element representing the
3035 operation with parameters that are SOAP 1.1 encoded:
3036 
3037  <SOAP-ENV:Envelope
3038  xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
3039  xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
3040  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3041  xmlns:xsd="http://www.w3.org/2001/XMLSchema"
3042  xmlsn:ns="urn:DB">
3043  <SOAP-ENV:Body SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
3044  <ns:DBupdate>
3045  <records SOAP-ENC:arrayType="ns:record[3]">
3046  <item>
3047  <name href="#_1"/>
3048  <SSN>1234567890</SSN>
3049  </item>
3050  <item>
3051  <name>Jane</name>
3052  <SSN>1987654320</SSN>
3053  </item>
3054  <item>
3055  <name href="#_1"/>
3056  <SSN>2345678901</SSN>
3057  </item>
3058  </records>
3059  </ns:DBupdate>
3060  <id id="_1" xsi:type="xsd:string">Joe</id>
3061  </SOAP-ENV:Body>
3062  </SOAP-ENV:Envelope>
3063 
3064 Note that the name "Joe" is shared by two records and the string is referenced
3065 by SOAP 1.1 href and id attributes.
3066 
3067 While gSOAP only introduces multi-referenced elements in the payload when they
3068 are actually multi-referenced in the data graph, other SOAP applications may
3069 render multi-referenced elements more aggressively. The example could also be
3070 rendered as:
3071 
3072  <SOAP-ENV:Envelope
3073  xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
3074  xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
3075  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3076  xmlns:xsd="http://www.w3.org/2001/XMLSchema"
3077  xmlsn:ns="urn:DB">
3078  <SOAP-ENV:Body SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
3079  <ns:DBupdate>
3080  <records SOAP-ENC:arrayType="ns:record[3]">
3081  <item href="#id1"/>
3082  <item href="#id2"/>
3083  <item href="#id3"/>
3084  </records>
3085  </ns:DBupdate>
3086  <id id="id1" xsi:type="ns:record">
3087  <name href="#id4"/>
3088  <SSN>1234567890</SSN>
3089  </id>
3090  <id id="id2" xsi:type="ns:record">
3091  <name href="#id5"/>
3092  <SSN>1987654320</SSN>
3093  </id>
3094  <id id="id3" xsi:type="ns:record">
3095  <name href="#id4"/>
3096  <SSN>2345678901</SSN>
3097  </id>
3098  <id id="id4" xsi:type="xsd:string">Joe</id>
3099  <id id="id5" xsi:type="xsd:string">Jane</id>
3100  </SOAP-ENV:Body>
3101  </SOAP-ENV:Envelope>
3102 
3103 SOAP 1.2 encoding is cleaner and produces more accurate XML encodings of data
3104 graphs by setting the id attribute on the element that is referenced:
3105 
3106  <SOAP-ENV:Envelope
3107  xmlns:SOAP-ENV="http://www.w3.org/2003/05/soap-envelope"
3108  xmlns:SOAP-ENC="http://www.w3.org/2003/05/soap-encoding"
3109  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3110  xmlns:xsd="http://www.w3.org/2001/XMLSchema"
3111  xmlsn:ns="urn:DB">
3112  <SOAP-ENV:Body>
3113  <ns:DBupdate SOAP-ENV:encodingStyle="http://www.w3.org/2003/05/soap-encoding">
3114  <records SOAP-ENC:itemType="ns:record" SOAP-ENC:arraySize="3">
3115  <item>
3116  <name SOAP-ENC:id="_1">Joe</name>
3117  <SSN>1234567890</SSN>
3118  </item>
3119  <item>
3120  <name>Jane</name>
3121  <SSN>1987654320</SSN>
3122  </item>
3123  <item>
3124  <name SOAP-ENC:ref="_1"/>
3125  <SSN>2345678901</SSN>
3126  </item>
3127  </records>
3128  </ns:DBupdate>
3129  </SOAP-ENV:Body>
3130  </SOAP-ENV:Envelope>
3131 
3132 @note Some SOAP 1.2 applications consider the namespace `SOAP-ENC` of
3133 `SOAP-ENC:id` and `SOAP-ENC:ref` optional. The gSOAP SOAP 1.2 encoding
3134 serialization follows the 2007 standard, while accepting unqualified id and
3135 ref attributes.
3136 
3137 To remove all rendered id-ref multi-referenced elements in gSOAP, use the
3138 `SOAP_XML_TREE` flag to initialize the gSOAP engine context.
3139 
3140 Some XML validation rules are turned off with SOAP encoding, because of the
3141 presence of additional attributes, such as id and ref/href, SOAP arrays with
3142 arbitrary element tags for array elements, and the occurrence of additional
3143 multi-ref elements in the SOAP 1.1 Body.
3144 
3145 The use of "literal" puts no restrictions on the XML in the SOAP Body. Full
3146 XML validation is possible, which can be enabled with the `SOAP_XML_STRICT`
3147 flag to initialize the gSOAP engine context. However, data graphs will be
3148 serialized as trees and cycles in the data will be cut from the XML rendition.
3149 
3150 
3151 SOAP 1.1 versus SOAP 1.2 {#soap}
3152 ------------------------
3153 
3154 There are two SOAP protocol versions: 1.1 and 1.2. The gSOAP tools can switch
3155 between the two versions seamlessly. You can declare the default SOAP version
3156 for a service operation as follows:
3157 
3158 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
3159  //gsoap ns service method-protocol: DBupdate SOAP1.2
3160 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3161 
3162 The gSOAP soapcpp2 auto-generates client and server code. At the client side,
3163 this operation sends data with SOAP 1.2 but accepts responses also in SOAP 1.1.
3164 At the server side, this operation accepts requests in SOAP 1.1 and 1.2 and
3165 will return responses in the same SOAP version.
3166 
3167 As we discussed in the previous section, the SOAP 1.2 protocol has a cleaner
3168 multi-referenced element serialization format that greatly enhances the
3169 accuracy of data graph serialization with SOAP RPC encoding and is therefore
3170 recommended.
3171 
3172 The SOAP 1.2 protocol default can also be set by importing and loading
3173 `gsoap/import/soap12.h`:
3174 
3175 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
3176  #import "soap12.h"
3177 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3178 
3179 
3180 Non-SOAP XML serialization {#non-soap}
3181 --------------------------
3182 
3183 You can serialize data that is stored on the heap, on the stack (locals), and
3184 static data as long as the serializable (i.e. non-transient) members are
3185 properly initialized and pointers in the structures are either NULL or point to
3186 valid structures. Deserialized data is put on the heap and managed by the
3187 gSOAP engine context `struct soap`, see also [Memory management](#memory).
3188 
3189 You can read and write XML directly to a file or stream with the serializing
3190 [Operations on classes and structs](#toxsd9-13).
3191 
3192 To define and use XML Web service client and service operations, we can declare
3193 these operations in our gSOAP header file for soapcpp2 as functions that
3194 soapcpp2 will translate in client-side service invocation calls and server-side
3195 service operation dispatchers. These functions are auto-generated by wsdl2h
3196 from WSDLs. Note that XSDs do not include service definitions.
3197 
3198 The REST operations POST, GET, and PUT are declared with gSOAP directives in
3199 the gSOAP header file for soapcpp2. For example, a REST POST operation is
3200 declared as follows:
3201 
3202 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
3203  //gsoap ns service namespace: urn:DB
3204  //gsoap ns service method-protocol: DBupdate POST
3205  int ns__DBupdate(...);
3206 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3207 
3208 There is no SOAP Envelope and no SOAP Body in the payload for `DBupdate`. Also
3209 the XML serialization rules are identical to SOAP document/literal. The XML
3210 payload only has the operation name as an element with its parameters
3211 serialized as subelements:
3212 
3213  <ns:DBupdate xmln:ns="urn:DB" ...>
3214  ...
3215  </ns:DBupdate>
3216 
3217 To force id-ref serialization with REST similar to SOAP 1.2 multi-reference
3218 encoding, use the `SOAP_XML_GRAPH` flag to initialize the gSOAP engine context.
3219 The XML serialization includes id and ref attributes for multi-referenced
3220 elements as follows:
3221 
3222  <ns:DBupdate xmln:ns="urn:DB" ...>
3223  <records>
3224  <item>
3225  <name id="_1">Joe</name>
3226  <SSN>1234567890</SSN>
3227  </item>
3228  <item>
3229  <name>Jane</name>
3230  <SSN>1987654320</SSN>
3231  </item>
3232  <item>
3233  <name ref="_1"/>
3234  <SSN>2345678901</SSN>
3235  </item>
3236  </records>
3237  </ns:DBupdate>
3238 
3239 
3240 Input and output {#io}
3241 ================
3242 
3243 Reading and writing XML from/to files, streams and string buffers is done via
3244 the managing context by setting one of the following context members that
3245 control IO sources and sinks:
3246 
3247 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
3248  soap->recvfd = fd; // an int file descriptor to read from (0 by default)
3249  soap->sendfd = fd; // an int file descriptor to write to (1 by default)
3250  soap->is = &is; // C++ only: a std::istream is object to read from
3251  soap->os = &os; // C++ only: a std::ostream os object to write to
3252  soap->is = cs; // C only: a const char* string to read from (soap->is will advance)
3253  soap->os = &cs; // C only: pointer to a const char*, will be set to point to the string output
3254 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3255 
3256 Normally, all of these context members are NULL, which is required to send and
3257 receive data over sockets by gSOAP clients and servers. Therefore, if you set
3258 any of these context members in a client or server application then you MUST
3259 reset them to NULL to ensure that socket communications are not blocked.
3260 
3261 Note: the use of `soap->is` and `soap->os` in C requires gSOAP 2.8.28 or later.
3262 
3263 In the following sections, we present more details on how to read and write to
3264 files and streams, and use string buffers as sources and sinks for XML data.
3265 
3266 In addition, you can set IO callback functions to handle IO at a lower level.
3267 For more details, see the gSOAP user guide.
3268 
3269 
3270 Reading and writing from/to files and streams {#io1}
3271 ---------------------------------------------
3272 
3273 The default IO is standard input and output. Other sources and sinks (those
3274 listed above) will be used until you (re)set them. For example with file-based
3275 input and output:
3276 
3277 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
3278  FILE *fp = fopen("record.xml", "r");
3279  if (fp != NULL)
3280  {
3281  soap->recvfd = fileno(fp); // get file descriptor of file to read from
3282  if (soap_read_ns__record(soap, &pers1))
3283  ... // handle IO error
3284  fclose(fp);
3285  soap->recvfd = 0; // read from stdin, or -1 to block reading
3286  }
3287 
3288  FILE *fp = fopen("record.xml", "w");
3289  if (fp != NULL)
3290  {
3291  soap->sendfd = fileno(fp); // get file descriptor of file to write to
3292  if (soap_write_ns__record(soap, &pers1))
3293  ... // handle IO error
3294  fclose(fp);
3295  soap->sendfd = 1; // write to stdout, or -1 to block writing
3296  }
3297 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3298 
3299 Similar code with streams in C++:
3300 
3301 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
3302  #include <fstream>
3303 
3304  std::fstream fs;
3305  fs.open("record.xml", std::ios::in);
3306  if (fs)
3307  {
3308  soap->is = &fs;
3309  if (soap_read__ns__record(soap, &pers1))
3310  ... // handle IO error
3311  fs.close();
3312  soap->is = NULL;
3313  }
3314 
3315  fs.open("record.xml", std::ios::out);
3316  if (fs)
3317  {
3318  soap->os = &fs;
3319  if (soap_write__ns__record(soap, &pers1))
3320  ... // handle IO error
3321  fs.close();
3322  soap->os = NULL;
3323  }
3324 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3325 
3326 
3327 Reading and writing from/to string buffers {#io2}
3328 ------------------------------------------
3329 
3330 For C++ we recommend to use `std::stringstream` objects from `<sstream>` as
3331 illustrated in the following example:
3332 
3333 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
3334  #include <sstream>
3335 
3336  std::stringstream ss;
3337  ss.str("..."); // XML to parse
3338  soap->is = &ss;
3339  if (soap_read__ns__record(soap, &pers1))
3340  ... // handle IO error
3341  soap->is = NULL;
3342 
3343  soap->os = &ss;
3344  if (soap_write__ns__record(soap, &pers1))
3345  ... // handle IO error
3346  soap->os = NULL;
3347  std::string s = ss.str(); // string with XML
3348 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3349 
3350 For C we can use `soap->is` and `soap->os` to point to strings of XML content
3351 as follows (this requires gSOAP 2.8.28 or later):
3352 
3353 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
3354  soap->is = "..."; // XML to parse
3355  if (soap_read__ns__record(soap, &pers1))
3356  ... // handle IO error
3357  soap->is = NULL;
3358 
3359  const char *cs = NULL;
3360  soap->os = &cs;
3361  if (soap_write__ns__record(soap, &pers1))
3362  ... // handle IO error
3363  soap->os = NULL;
3364  ... = cs; // string with XML (do not free(cs): managed by the context and freed with soap_end())
3365 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3366 
3367 Note that `soap->os` is a pointer to a `const char*` string. The pointer is
3368 set by the managing context to point to the XML data that is stored on the
3369 context-managed heap.
3370 
3371 For earlier gSOAP versions we recommend to use IO callbacks `soap->frecv` and
3372 `soap->fsend` as shown in the gSOAP user guide.
3373 
3374 
3375 Memory management {#memory}
3376 =================
3377 
3378 Memory management with the `soap` context enables us to allocate data in
3379 context-managed heap space that can be collectively deleted. All deserialized
3380 data is placed on the context-managed heap by the gSOAP engine.
3381 
3382 
3383 Memory management in C {#memory1}
3384 ----------------------
3385 
3386 In C (wsdl2h option `-c` and soapcpp2 option `-c`), the gSOAP engine allocates
3387 data on a context-managed heap with:
3388 
3389 - `void *soap_malloc(struct soap*, size_t len)`.
3390 
3391 You can also make shallow copies of data with `soap_memdup` that uses
3392 `soap_malloc` and a safe version of `memcpy` to copy a chunk of data `src` with
3393 length `len` to the context-managed heap:
3394 
3395 - `void *soap_memdup(struct soap*, const void *src, size_t len)`
3396 
3397 This function returns a pointer to the copy. This function requires gSOAP
3398 2.8.27 or later.
3399 
3400 The `soap_malloc` function is a wrapper around `malloc`, but which also permits
3401 the `struct soap` context to track all heap allocations for collective deletion
3402 with `soap_end(soap)`:
3403 
3404 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
3405  #include "soapH.h"
3406  #include "ns.nsmap"
3407  ...
3408  struct soap *soap = soap_new(); // new context
3409  ...
3410  struct ns__record *record = soap_malloc(soap, sizeof(struct ns__record));
3411  soap_default_ns__record(soap, record);
3412  ...
3413  soap_destroy(soap); // only for C++, see section on C++ below
3414  soap_end(soap); // delete record and all other heap allocations
3415  soap_free(soap); // delete context
3416 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3417 
3418 The soapcpp2 auto-generated deserializers in C use `soap_malloc` to allocate
3419 and populate deserialized structures, which are managed by the context for
3420 collective deletion.
3421 
3422 To make `char*` and `wchar_t*` string copies to the context-managed heap, we
3423 can use the functions:
3424 
3425 - `char *soap_strdup(struct soap*, const char *str)` and
3426 - `wchar_t *soap_wstrdup(struct soap*, const wchar_t *wstr)`.
3427 
3428 We use the soapcpp2 auto-generated `soap_dup_T` functions to duplicate data
3429 into another context (this requires soapcpp2 option `-Ec` to generate), here
3430 shown for C with the second argument `dst` NULL because we want to allocate a
3431 new managed structure:
3432 
3433 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
3434  struct soap *other_soap = soap_new(); // another context
3435  struct ns__record *other_record = soap_dup_ns__record(other_soap, NULL, record);
3436  ...
3437  soap_destroy(other_soap); // only for C++, see section on C++ below
3438  soap_end(other_soap); // delete other_record and all of its deep data
3439  soap_free(other_soap); // delete context
3440 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3441 
3442 Note that the only reason to use another context and not to use the primary
3443 context is when the primary context must be destroyed together with all of the
3444 objects it manages while some of the objects must be kept alive. If the objects
3445 that are kept alive contain deep cycles then this is the only option we have,
3446 because deep copy with a managing context detects and preserves these
3447 cycles unless the `SOAP_XML_TREE` flag is used with the context:
3448 
3449 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
3450  struct soap *other_soap = soap_new1(SOAP_XML_TREE); // another context
3451  struct ns__record *other_record = soap_dup_ns__record(other_soap, NULL, record);
3452 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3453 
3454 The resulting deep copy will be a full copy of the source data structure as a
3455 tree without co-referenced data (i.e. no digraph) and without cycles. Cycles
3456 are pruned and (one of the) pointers that forms a cycle is repaced by NULL.
3457 
3458 We can also deep copy into unmanaged space and use the auto-generated
3459 `soap_del_T()` function (requires soapcpp2 option `-Ed` to generate) to delete
3460 it later, but we MUST NOT do this for any data that we suspect has deep cycles:
3461 
3462 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
3463  struct ns__record *other_record = soap_dup_ns__record(NULL, NULL, record);
3464  ...
3465  soap_del_ns__record(other_record); // deep delete record data members
3466  free(other_record); // delete the record
3467 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3468 
3469 Cycles in the data structure will lead to non-termination when making unmanaged
3470 deep copies. Consider for example:
3471 
3472 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
3473  struct ns__record
3474  {
3475  const char *name;
3476  uint64_t SSN;
3477  ns__record *spouse;
3478  };
3479 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3480 
3481 Our code to populate a structure with a mutual spouse relationship:
3482 
3483 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
3484  struct soap *soap = soap_new();
3485  ...
3486  struct ns__record pers1, pers2;
3487  soap_default_ns__record(soap, &pers1);
3488  soap_default_ns__record(soap, &pers2);
3489  pers1.name = "Joe"; // OK to serialize static data
3490  pers1.SSN = 1234567890;
3491  pers1.spouse = &pers2;
3492  pers2.name = soap_strdup(soap, "Jane"); // allocates and copies a string
3493  pers2.SSN = 1987654320;
3494  pers2.spouse = &pers1;
3495  ...
3496  struct ns__record *pers3 = soap_dup_ns__record(NULL, NULL, &pers1); // BAD
3497  struct ns__record *pers4 = soap_dup_ns__record(soap, NULL, &pers1); // OK
3498  soap_set_mode(soap, SOAP_XML_TREE);
3499  struct ns__record *pers5 = soap_dup_ns__record(soap, NULL, &pers1); // OK
3500 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3501 
3502 As we can see, the gSOAP serializer can serialize any heap, stack, or static
3503 allocated data, such as in our code above. So we can serialize the
3504 stack-allocated `pers1` record as follows:
3505 
3506 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
3507  FILE *fp = fopen("record.xml", "w");
3508  if (fp != NULL)
3509  {
3510  soap->sendfd = fileno(fp); // file descriptor to write to
3511  soap_set_mode(soap, SOAP_XML_GRAPH); // support id-ref w/o requiring SOAP
3512  soap_clr_mode(soap, SOAP_XML_TREE); // if set, clear
3513  soap_write_ns__record(soap, &pers1);
3514  fclose(fp);
3515  soap->sendfd = -1; // block further writing
3516  }
3517 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3518 
3519 which produces an XML document record.xml that is similar to:
3520 
3521  <ns:record xmlns:ns="urn:types" id="Joe">
3522  <name>Joe</name>
3523  <SSN>1234567890</SSN>
3524  <spouse id="Jane">
3525  <name>Jane</name>
3526  <SSN>1987654320</SSN>
3527  <spouse ref="#Joe"/>
3528  </spouse>
3529  </ns:record>
3530 
3531 Deserialization of an XML document with a SOAP 1.1/1.2 encoded id-ref graph
3532 leads to the same non-termination problem when we later try to copy the data
3533 into unmanaged space:
3534 
3535 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
3536  struct soap *soap = soap_new1(SOAP_XML_GRAPH); // support id-ref w/o SOAP
3537  ...
3538  struct ns__record pers1;
3539  FILE *fp = fopen("record.xml", "r");
3540  if (fp != NULL)
3541  {
3542  soap->recvfd = fileno(fp);
3543  if (soap_read_ns__record(soap, &pers1))
3544  ... // handle IO error
3545  fclose(fp);
3546  soap->recvfd = -1; // blocks further reading
3547  }
3548  ...
3549  struct ns__record *pers3 = soap_dup_ns__record(NULL, NULL, &pers1); // BAD
3550  struct ns__record *pers4 = soap_dup_ns__record(soap, NULL, &pers1); // OK
3551  soap_set_mode(soap, SOAP_XML_TREE);
3552  struct ns__record *pers5 = soap_dup_ns__record(soap, NULL, &pers1); // OK
3553 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3554 
3555 Copying data with `soap_dup_T(soap)` into managed space is always safe. Copying
3556 into unmanaged space requires diligence. But deleting unmanaged data is easy
3557 with `soap_del_T()`.
3558 
3559 We can also use `soap_del_T()` to delete structures that we created in C, but
3560 only if these structures are created with `malloc` and do NOT contain pointers
3561 to stack and static data.
3562 
3563 
3564 Memory management in C++ {#memory2}
3565 ------------------------
3566 
3567 In C++, the gSOAP engine allocates data on a managed heap using a combination
3568 of `void *soap_malloc(struct soap*, size_t len)` and `soap_new_T()`, where `T`
3569 is the name of a class, struct, or class template (container or smart pointer).
3570 Heap allocation is tracked by the `struct soap` context for collective
3571 deletion with `soap_destroy(soap)` and `soap_end(soap)`.
3572 
3573 Only structs, classes, and class templates are allocated with `new` via
3574 `soap_new_T(struct soap*)` and mass-deleted with `soap_destroy(soap)`.
3575 
3576 There are four variations of `soap_new_T` for class/struct/template type `T`
3577 that soapcpp2 auto-generates to create instances on a context-managed heap:
3578 
3579 - `T * soap_new_T(struct soap*)` returns a new instance of `T` with default data
3580  member initializations that are set with the soapcpp2 auto-generated `void
3581  T::soap_default(struct soap*)` method), but ONLY IF the soapcpp2
3582  auto-generated default constructor is used that invokes `soap_default()` and
3583  was not replaced by a user-defined default constructor.
3584 
3585 - `T * soap_new_T(struct soap*, int n)` returns an array of `n` new instances of
3586  `T`. Similar to the above, instances are initialized.
3587 
3588 - `T * soap_new_req_T(struct soap*, ...)` returns a new instance of `T` and sets
3589  the required data members to the values specified in `...`. The required data
3590  members are those with nonzero minOccurs, see the subsections on
3591  [(Smart) pointer members and their occurrence constraints](#toxsd9-8) and
3592  [Container members and their occurrence constraints](#toxsd9-9).
3593 
3594 - `T * soap_new_set_T(struct soap*, ...)` returns a new instance of `T` and sets
3595  the public/serializable data members to the values specified in `...`.
3596 
3597 The above functions can be invoked with a NULL `soap` context, but we will be
3598 responsible to use `delete T` to remove this instance from the unmanaged heap.
3599 
3600 Primitive types and arrays of these are allocated with `soap_malloc` by the
3601 gSOAP engine. As we stated above, all types except for classes, structs, class
3602 templates (containers and smart pointers) are allocated with `soap_malloc` for
3603 reasons of efficiency.
3604 
3605 We can use a C++ template to simplify the managed allocation and initialization
3606 of primitive values as follows (this is for primitive types only, because we
3607 should allocate structs and classes with `soap_new_T`):
3608 
3609 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
3610  template<class T>
3611  T * soap_make(struct soap *soap, T val)
3612  {
3613  T *p = (T*)soap_malloc(soap, sizeof(T));
3614  if (p) // out of memory? Can also guard with assert(p != NULL) or throw an error
3615  *p = val;
3616  return p;
3617  }
3618 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3619 
3620 For example, assuming we have the following class:
3621 
3622 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
3623  class ns__record
3624  {
3625  public:
3626  std::string name; // required name
3627  uint64_t *SSN; // optional SSN
3628  ns__record *spouse; // optional spouse
3629  };
3630 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3631 
3632 We can instantiate a record by using the auto-generated
3633 `soap_new_set_ns__record` and our `soap_make` to create a SSN value on the
3634 managed heap:
3635 
3636 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
3637  soap *soap = soap_new(); // new context
3638  ...
3639  ns__record *record = soap_new_set_ns__record(
3640  soap,
3641  "Joe",
3642  soap_make<uint64_t>(soap, 1234567890LL),
3643  NULL);
3644  ...
3645  soap_destroy(soap); // delete record and all other managed instances
3646  soap_end(soap); // delete managed soap_malloc'ed heap data
3647  soap_free(soap); // delete context
3648 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3649 
3650 Note however that the gSOAP serializer can serialize any heap, stack, or static
3651 allocated data. So we can also create a new record as follows:
3652 
3653 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
3654  uint64_t SSN = 1234567890LL;
3655  ns__record *record = soap_new_set_ns__record(soap, "Joe", &SSN, NULL);
3656 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3657 
3658 which will be fine to serialize this record as long as the local `SSN`
3659 stack-allocated value remains in scope when invoking the serializer and/or
3660 using `record`. It does not matter if `soap_destroy` and `soap_end` are called
3661 beyond the scope of `SSN`.
3662 
3663 To facilitate our class methods to access the managing context, we can add a
3664 soap context pointer to a class/struct:
3665 
3666 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
3667  class ns__record
3668  {
3669  ...
3670  void create_more(); // needs a context to create more internal data
3671  protected:
3672  struct soap *soap; // the context that manages this instance, or NULL
3673  };
3674 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3675 
3676 The context is set when invoking `soap_new_T` (and similar) with a non-NULL
3677 context argument.
3678 
3679 We use the soapcpp2 auto-generated `soap_dup_T` functions to duplicate data
3680 into another context (this requires soapcpp2 option `-Ec` to generate), here
3681 shown for C++ with the second argument `dst` NULL because we want to allocate a
3682 new managed object:
3683 
3684 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
3685  soap *other_soap = soap_new(); // another context
3686  ns__record *other_record = soap_dup_ns__record(other_soap, NULL, record);
3687  ...
3688  soap_destroy(other_soap); // delete record and other managed instances
3689  soap_end(other_soap); // delete other data (the SSNs on the heap)
3690  soap_free(other_soap); // delete context
3691 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3692 
3693 To duplicate base and derived instances when a base class pointer or reference
3694 is provided, use the auto-generated method `T * T::soap_dup(struct soap*)`:
3695 
3696 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
3697  soap *other_soap = soap_new(); // another context
3698  ns__record *other_record = record->soap_dup(other_soap);
3699  ...
3700  soap_destroy(other_soap); // delete record and other managed instances
3701  soap_end(other_soap); // delete other data (the SSNs on the heap)
3702  soap_free(other_soap); // delete context
3703 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3704 
3705 Note that the only reason to use another context and not to use the primary
3706 context is when the primary context must be destroyed together with all of the
3707 objects it manages while some of the objects must be kept alive. If the objects
3708 that are kept alive contain deep cycles then this is the only option we have,
3709 because deep copy with a managing context detects and preserves these
3710 cycles unless the `SOAP_XML_TREE` flag is used with the context:
3711 
3712 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
3713  soap *other_soap = soap_new1(SOAP_XML_TREE); // another context
3714  ns__record *other_record = record->soap_dup(other_soap); // deep tree copy
3715 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3716 
3717 The resulting deep copy will be a full copy of the source data structure as a
3718 tree without co-referenced data (i.e. no digraph) and without cycles. Cycles
3719 are pruned and (one of the) pointers that forms a cycle is repaced by NULL.
3720 
3721 We can also deep copy into unmanaged space and use the auto-generated
3722 `soap_del_T()` function or the `T::soap_del()` method (requires soapcpp2 option
3723 `-Ed` to generate) to delete it later, but we MUST NOT do this for any data
3724 that we suspect has deep cycles:
3725 
3726 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
3727  ns__record *other_record = record->soap_dup(NULL);
3728  ...
3729  other_record->soap_del(); // deep delete record data members
3730  delete other_record; // delete the record
3731 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3732 
3733 Cycles in the data structure will lead to non-termination when making unmanaged
3734 deep copies. Consider for example:
3735 
3736 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
3737  class ns__record
3738  {
3739  const char *name;
3740  uint64_t SSN;
3741  ns__record *spouse;
3742  };
3743 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3744 
3745 Our code to populate a structure with a mutual spouse relationship:
3746 
3747 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
3748  soap *soap = soap_new();
3749  ...
3750  ns__record pers1, pers2;
3751  pers1.name = "Joe";
3752  pers1.SSN = 1234567890;
3753  pers1.spouse = &pers2;
3754  pers2.name = "Jane";
3755  pers2.SSN = 1987654320;
3756  pers2.spouse = &pers1;
3757  ...
3758  ns__record *pers3 = soap_dup_ns__record(NULL, NULL, &pers1); // BAD
3759  ns__record *pers4 = soap_dup_ns__record(soap, NULL, &pers1); // OK
3760  soap_set_mode(soap, SOAP_XML_TREE);
3761  ns__record *pers5 = soap_dup_ns__record(soap, NULL, &pers1); // OK
3762 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3763 
3764 Note that the gSOAP serializer can serialize any heap, stack, or static
3765 allocated data, such as in our code above. So we can serialize the
3766 stack-allocated `pers1` record as follows:
3767 
3768 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
3769  FILE *fp = fopen("record.xml", "w");
3770  if (fp != NULL)
3771  {
3772  soap->sendfd = fileno(fp); // file descriptor to write to
3773  soap_set_mode(soap, SOAP_XML_GRAPH); // support id-ref w/o requiring SOAP
3774  soap_clr_mode(soap, SOAP_XML_TREE); // if set, clear
3775  if (soap_write_ns__record(soap, &pers1))
3776  ... // handle IO error
3777  fclose(fp);
3778  soap->sendfd = -1; // block further writing
3779  }
3780 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3781 
3782 which produces an XML document record.xml that is similar to:
3783 
3784  <ns:record xmlns:ns="urn:types" id="Joe">
3785  <name>Joe</name>
3786  <SSN>1234567890</SSN>
3787  <spouse id="Jane">
3788  <name>Jane</name>
3789  <SSN>1987654320</SSN>
3790  <spouse ref="#Joe"/>
3791  </spouse>
3792  </ns:record>
3793 
3794 Deserialization of an XML document with a SOAP 1.1/1.2 encoded id-ref graph
3795 leads to the same non-termination problem when we later try to copy the data
3796 into unmanaged space:
3797 
3798 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
3799  soap *soap = soap_new1(SOAP_XML_GRAPH); // support id-ref w/o SOAP
3800  ...
3801  ns__record pers1;
3802  FILE *fp = fopen("record.xml", "r");
3803  if (fp != NULL)
3804  {
3805  soap->recvfd = fileno(fp); // file descriptor to read from
3806  if (soap_read_ns__record(soap, &pers1))
3807  ... // handle IO error
3808  fclose(fp);
3809  soap->recvfd = -1; // block further reading
3810  }
3811  ...
3812  ns__record *pers3 = soap_dup_ns__record(NULL, NULL, &pers1); // BAD
3813  ns__record *pers4 = soap_dup_ns__record(soap, NULL, &pers1); // OK
3814  soap_set_mode(soap, SOAP_XML_TREE);
3815  ns__record *pers5 = soap_dup_ns__record(soap, NULL, &pers1); // OK
3816 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3817 
3818 Copying data with `soap_dup_T(soap)` into managed space is always safe. Copying
3819 into unmanaged space requires diligence. But deleting unmanaged data is easy
3820 with `soap_del_T()`.
3821 
3822 We can also use `soap_del_T()` to delete structures in C++, but only if these
3823 structures are created with `new` (and `new []` for arrays when applicable) for
3824 classes, structs, and class templates and with `malloc` for anything else, and
3825 the structures do NOT contain pointers to stack and static data.
3826 
3827 Features and limitations {#features}
3828 ========================
3829 
3830 In general, to use the generated code:
3831 
3832 - Make sure to `#include "soapH.h"` in your code and also define a namespace
3833  table or `#include "ns.nsmap"` with the generated table, where `ns` is the
3834  namespace prefix for services.
3835 
3836 - Use soapcpp2 option -j (C++ only) to generate C++ proxy and service objects.
3837  The auto-generated files include documented inferfaces. Compile with
3838  soapC.cpp and link with -lgsoap++, or alternatively compile stdsoap2.cpp.
3839 
3840 - Without soapcpp2 option -j: client-side uses the auto-generated
3841  soapClient.cpp and soapC.cpp (or C versions of those). Compile and link with
3842  -lgsoap++ (-lgsoap for C), or alternatively compile stdsoap2.cpp
3843  (stdsoap2.c for C).
3844 
3845 - Without soapcpp2 option -j: server-side uses the auto-generated
3846  soapServer.cpp and soapC.cpp (or C versions of those). Compile and link with
3847  -lgsoap++ (-lgsoap for C), or alternatively compile stdsoap2.cpp (stdsoap2.c
3848  for C).
3849 
3850 - Use `soap_new()` or `soap_new1(int flags)` to allocate and initialize a
3851  heap-allocated context with or without flags. Delete this context with
3852  `soap_free(struct soap*)`, but only after `soap_destroy(struct soap*)` and
3853  `soap_end(struct soap*)`.
3854 
3855 - Use `soap_init(struct *soap)` or `soap_init1(struct soap*, int flags)` to
3856  initialize a stack-allocated context with or without flags. End the use of
3857  this context with `soap_done(struct soap*)`, but only after
3858  `soap_destroy(struct soap*)` and `soap_end(struct soap*)`.
3859 
3860 There are several context initialization flags and context mode flags to
3861 control XML serialization at runtime:
3862 
3863 - `SOAP_C_UTFSTRING`: enables all `std::string` and `char*` strings to
3864  contain UTF-8 content. This option is recommended.
3865 
3866 - `SOAP_XML_STRICT`: strictly validates XML while deserializing. Should not be
3867  used together with SOAP 1.1/1.2 encoding style of messaging. Use soapcpp2
3868  option `-s` to hard code `SOAP_XML_STRICT` in the generated serializers. Not
3869  recommended with SOAP 1.1/1.2 encoding style messaging.
3870 
3871 - `SOAP_XML_INDENT`: produces indented XML.
3872 
3873 - `SOAP_XML_CANONICAL`: c14n canonocalization, removes unused `xmlns` bindings
3874  and adds them to appropriate places by applying c14n normalization rules.
3875  Should not be used together with SOAP 1.1/1.2 encoding style messaging.
3876 
3877 - `SOAP_XML_TREE`: write tree XML without id-ref, while pruning data structure
3878  cycles to prevent nontermination of the serializer for cyclic structures.
3879 
3880 - `SOAP_XML_GRAPH`: write graph (digraph and cyclic graphs with shared pointers
3881  to objects) using id-ref attributes. That is, XML with SOAP multi-ref
3882  encoded id-ref elements. This is a structure-preserving serialization format,
3883  because co-referenced data and also cyclic relations are accurately represented.
3884 
3885 - `SOAP_XML_DEFAULTNS`: uses xmlns default namespace declarations, assuming
3886  that the schema attribute form is "qualified" by default (be warned if it is
3887  not, since attributes in the null namespace will get bound to namespaces!).
3888 
3889 - `SOAP_XML_NOTYPE`: removes all xsi:type attribuation. This option is usually
3890  not needed unless the receiver rejects all xs:type attributes. This option
3891  may affect the quality of the deserializer, which relies on xsi:type
3892  attributes to distinguish base class instances from derived class instances
3893  transported in the XML payloads.
3894 
3895 Additional notes with respect to the wsdl2h and soapcpp2 tools:
3896 
3897 - Nested classes, structs, and unions in a gSOAP header file are unnested by
3898  soapcpp2.
3899 
3900 - Use `#import "file.h"` instead of `#include` to import other header files in
3901  a gSOAP header file for soapcpp2. The `#include` and `#define` directives are
3902  accepted, but are moved to the very start of the generated code for the C/C++
3903  compiler to include before all generated definitions. You should use
3904  `#include` in combinatio with "volatile" types and to ensure transient
3905  (incomplete) types are declared when these are used in the gSOAP header file.
3906 
3907 - To remove any SOAP-specific bindings, use soapcpp2 option `-0`.
3908 
3909 - A gSOAP header file for soapcpp2 should not include any code statements, only
3910  data type declarations. This includes constructor initialization lists that are
3911  not permitted. Use member initializations instead.
3912 
3913 - C++ namespaces are supported. Use wsdl2h option `-qname`. Or add a `namespace
3914  name { ... }` to the header file, but the `{ ... }` MUST cover the entire
3915  header file content from begin to end.
3916 
3917 - Optional DOM support can be used to store mixed content or literal XML
3918  content. Otherwise, mixed content may be lost. Use wsdl2h option `-d` for
3919  DOM support and compile and link with `dom.c` or `dom.cpp`.
3920 
3921 
3922 Removing SOAP namespaces from XML payloads {#nsmap}
3923 ==========================================
3924 
3925 The soapcpp2 tool generates a `.nsmap` file that includes two bindings for SOAP
3926 namespaces. We can remove all SOAP namespaces (and SOAP processing logic) with
3927 soapcpp2 option `-0` or by simply setting the two entries to NULL:
3928 
3929 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
3930  struct Namespace namespaces[] =
3931  {
3932  {"SOAP-ENV", NULL, NULL, NULL},
3933  {"SOAP-ENC", NULL, NULL, NULL},
3934  ...
3935  };
3936 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3937 
3938 Note that once the `.nsmap` is generated, we can copy-paste the content into
3939 our project code. However, if we rerun wsdl2h on updated WSDL/XSD files or
3940 `typemap.dat` declarations then we need to use the updated table.
3941 
3942 In cases that no XML namespaces are used at all, for example with
3943 [XML-RPC](http://www.genivia.com/doc/xml-rpc-json/html), you may use an empty
3944 namespace table:
3945 
3946 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
3947  struct Namespace namespaces[] = {{NULL,NULL,NULL,NULL}};
3948 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3949 
3950 However, beware that any built-in xsi attributes that are rendered will lack
3951 the proper namespace binding. At least we suggest to use `SOAP_XML_NOTYPE` for
3952 this reason.
3953 
3954 Examples {#examples}
3955 ========
3956 
3957 Select the project files below to peruse the source code examples.
3958 
3959 
3960 Source files
3961 ------------
3962 
3963 - `address.xsd` Address book schema
3964 - `address.cpp` Address book app (reads/writes address.xml file)
3965 - `addresstypemap.dat` Schema namespace prefix name preference for wsdl2h
3966 - `graph.h` Graph data binding (tree, digraph, cyclic graph)
3967 - `graph.cpp` Test graph serialization as tree, digraph, and cyclic
3968 
3969 
3970 Generated files
3971 ---------------
3972 
3973 - `address.h` gSOAP-specific data binding definitions from address.xsd
3974 - `addressStub.h` C++ data binding definitions
3975 - `addressH.h` Serializers
3976 - `addressC.cpp` Serializers
3977 - `address.xml` Address book data generated by address app
3978 - `graphStub.h` C++ data binding definitions
3979 - `graphH.h` Serializers
3980 - `graphC.cpp` Serializers
3981 - `g.xsd` XSD schema with `g:Graph` complexType
3982 - `g.nsmap` xmlns bindings namespace mapping table
3983 
3984 
3985 Build steps
3986 -----------
3987 
3988 Building the AddressBook example:
3989 
3990  wsdl2h -g -t addresstypemap.dat address.xsd
3991  soapcpp2 -0 -CS -I../../import -p address address.h
3992  c++ -I../.. address.cpp addressC.cpp -o address -lgsoap++
3993 
3994 Option `-g` produces bindings for global (root) elements in addition to types.
3995 In this case the root element `a:address-book` is bound to `_a__address_book`.
3996 The complexType `a:address` is bound to class `a__address`, which is also the
3997 type of `_a__address_book`. This option is not required, but allows you to use
3998 global element tag names when referring to their serializers, instead of their
3999 type name. Option `-0` removes the SOAP protocol. Options `-C` and `-S`
4000 removes client and server code generation. Option `-p` renames the output
4001 `soap` files to `address` files.
4002 
4003 See the `address.cpp` implementation and [Related Pages](pages.html).
4004 
4005 The `addresstypemap.dat` file specifies the XML namespace prefix for the
4006 bindings:
4007 
4008  # Bind the address book schema namespace to prefix 'a'
4009 
4010  a = "urn:address-book-example"
4011 
4012  # By default the xsd:dateTime schema type is translated to time_t
4013  # To map xsd:dateTime to struct tm, enable the following line:
4014 
4015  # xsd__dateTime = #import "../../custom/struct_tm.h"
4016 
4017  # ... and compile/link with custom/struct_tm.c
4018 
4019 The DOB field is a xsd:dateTime, which is bound to `time_t` by default. To
4020 change this to `struct tm`, enable the import of the `xsd__dateTime` custom
4021 serializer by uncommenting the definition of `xsd__dateTime` in
4022 `addresstypemap.dat`. Then change `soap_dateTime2s` to `soap_xsd__dateTime2s`
4023 in the code.
4024 
4025 Building the graph serialization example:
4026 
4027  soapcpp2 -CS -I../../import -p graph graph.h
4028  c++ -I../.. graph.cpp graphC.cpp -o graph -lgsoap++
4029 
4030 To compile without using the `libgsoap++` library: simply compile
4031 `stdsoap2.cpp` together with the above.
4032 
4033 
4034 Usage
4035 -----
4036 
4037 To execute the AddressBook example:
4038 
4039  ./address
4040 
4041 To execute the Graph serialization example:
4042 
4043  ./graph
4044