Merge branch '1.x' of ssh://authdev.it.ohio-state.edu/~scantor/git/cpp-xmltooling...
[shibboleth/cpp-xmltooling.git] / xmltooling / base.h
1 /**
2  * Licensed to the University Corporation for Advanced Internet
3  * Development, Inc. (UCAID) under one or more contributor license
4  * agreements. See the NOTICE file distributed with this work for
5  * additional information regarding copyright ownership.
6  *
7  * UCAID licenses this file to you under the Apache License,
8  * Version 2.0 (the "License"); you may not use this file except
9  * in compliance with the License. You may obtain a copy of the
10  * License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing,
15  * software distributed under the License is distributed on an
16  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
17  * either express or implied. See the License for the specific
18  * language governing permissions and limitations under the License.
19  */
20
21 /**
22  * @file xmltooling/base.h
23  *
24  * Base header file definitions.
25  * Must be included prior to including any other header.
26  */
27
28 #ifndef __xmltooling_base_h__
29 #define __xmltooling_base_h__
30
31 #include <typeinfo>
32
33 /* Required for sprintf, used by integer XML attribute macros. */
34 #include <cstdio>
35
36 #if defined (_MSC_VER) || defined(__BORLANDC__)
37   #include <xmltooling/config_pub_win32.h>
38 #else
39   #include <xmltooling/config_pub.h>
40 #endif
41
42 #ifdef XMLTOOLING_LITE
43 # define XMLTOOLING_NO_XMLSEC 1
44 #endif
45
46 #ifndef HAVE_NULLPTR
47 # define nullptr 0
48 #endif
49
50 #if defined(XMLTOOLING_NO_XMLSEC) || !defined(HAVE_XSECSIZE_T)
51 # ifdef XMLTOOLING_XERCESC_64BITSAFE
52 #   include <xercesc/util/XercesDefs.hpp>
53     typedef XMLSize_t xsecsize_t;
54 # else
55     typedef unsigned int xsecsize_t;
56 # endif
57 #endif
58
59 // Windows and GCC4 Symbol Visibility Macros
60 #ifdef WIN32
61   #define XMLTOOL_IMPORT __declspec(dllimport)
62   #define XMLTOOL_EXPORT __declspec(dllexport)
63   #define XMLTOOL_DLLLOCAL
64   #define XMLTOOL_DLLPUBLIC
65 #else
66   #define XMLTOOL_IMPORT
67   #ifdef GCC_HASCLASSVISIBILITY
68     #define XMLTOOL_EXPORT __attribute__ ((visibility("default")))
69     #define XMLTOOL_DLLLOCAL __attribute__ ((visibility("hidden")))
70     #define XMLTOOL_DLLPUBLIC __attribute__ ((visibility("default")))
71   #else
72     #define XMLTOOL_EXPORT
73     #define XMLTOOL_DLLLOCAL
74     #define XMLTOOL_DLLPUBLIC
75   #endif
76 #endif
77
78 // Define XMLTOOL_API for DLL builds
79 #ifdef XMLTOOLING_EXPORTS
80   #define XMLTOOL_API XMLTOOL_EXPORT
81 #else
82   #define XMLTOOL_API XMLTOOL_IMPORT
83 #endif
84
85 // Throwable classes must always be visible on GCC in all binaries
86 #ifdef WIN32
87   #define XMLTOOL_EXCEPTIONAPI(api) api
88 #elif defined(GCC_HASCLASSVISIBILITY)
89   #define XMLTOOL_EXCEPTIONAPI(api) XMLTOOL_EXPORT
90 #else
91   #define XMLTOOL_EXCEPTIONAPI(api)
92 #endif
93
94 #ifdef _MSC_VER
95     #define XMLTOOLING_DOXYGEN(desc) /##** desc */
96 #else
97     #define XMLTOOLING_DOXYGEN(desc)
98 #endif
99
100 /**
101  * Blocks copy c'tor and assignment operator for a class.
102  */
103 #define MAKE_NONCOPYABLE(type) \
104     private: \
105         type(const type&); \
106         type& operator=(const type&)
107
108 #ifndef DOXYGEN_SKIP
109 #ifndef NULL
110 #define NULL    0
111 #endif
112 #define UNICODE_LITERAL_1(a) {xercesc::chLatin_##a, xercesc::chNull}
113 #define UNICODE_LITERAL_2(a,b) {xercesc::chLatin_##a, xercesc::chLatin_##b, xercesc::chNull}
114 #define UNICODE_LITERAL_3(a,b,c) {xercesc::chLatin_##a, xercesc::chLatin_##b, xercesc::chLatin_##c, xercesc::chNull}
115 #define UNICODE_LITERAL_4(a,b,c,d) {xercesc::chLatin_##a, xercesc::chLatin_##b, xercesc::chLatin_##c, xercesc::chLatin_##d, xercesc::chNull}
116 #define UNICODE_LITERAL_5(a,b,c,d,e) \
117     {xercesc::chLatin_##a, xercesc::chLatin_##b, xercesc::chLatin_##c, xercesc::chLatin_##d, xercesc::chLatin_##e, xercesc::chNull}
118 #define UNICODE_LITERAL_6(a,b,c,d,e,f) \
119     {xercesc::chLatin_##a, xercesc::chLatin_##b, xercesc::chLatin_##c, xercesc::chLatin_##d, xercesc::chLatin_##e, xercesc::chLatin_##f, xercesc::chNull}
120 #define UNICODE_LITERAL_7(a,b,c,d,e,f,g) \
121     {xercesc::chLatin_##a, xercesc::chLatin_##b, xercesc::chLatin_##c, xercesc::chLatin_##d, xercesc::chLatin_##e, xercesc::chLatin_##f, xercesc::chLatin_##g, xercesc::chNull}
122 #define UNICODE_LITERAL_8(a,b,c,d,e,f,g,h) \
123     {xercesc::chLatin_##a, xercesc::chLatin_##b, xercesc::chLatin_##c, xercesc::chLatin_##d, xercesc::chLatin_##e, xercesc::chLatin_##f, xercesc::chLatin_##g, xercesc::chLatin_##h, xercesc::chNull}
124 #define UNICODE_LITERAL_9(a,b,c,d,e,f,g,h,i) \
125     {xercesc::chLatin_##a, xercesc::chLatin_##b, xercesc::chLatin_##c, xercesc::chLatin_##d, xercesc::chLatin_##e, xercesc::chLatin_##f, xercesc::chLatin_##g, xercesc::chLatin_##h, xercesc::chLatin_##i, xercesc::chNull}
126 #define UNICODE_LITERAL_10(a,b,c,d,e,f,g,h,i,j) \
127     {xercesc::chLatin_##a, xercesc::chLatin_##b, xercesc::chLatin_##c, xercesc::chLatin_##d, xercesc::chLatin_##e, xercesc::chLatin_##f, xercesc::chLatin_##g, xercesc::chLatin_##h, xercesc::chLatin_##i, \
128         xercesc::chLatin_##j, xercesc::chNull}
129 #define UNICODE_LITERAL_11(a,b,c,d,e,f,g,h,i,j,k) \
130     {xercesc::chLatin_##a, xercesc::chLatin_##b, xercesc::chLatin_##c, xercesc::chLatin_##d, xercesc::chLatin_##e, xercesc::chLatin_##f, xercesc::chLatin_##g, xercesc::chLatin_##h, xercesc::chLatin_##i, \
131         xercesc::chLatin_##j, xercesc::chLatin_##k, xercesc::chNull}
132 #define UNICODE_LITERAL_12(a,b,c,d,e,f,g,h,i,j,k,l) \
133     {xercesc::chLatin_##a, xercesc::chLatin_##b, xercesc::chLatin_##c, xercesc::chLatin_##d, xercesc::chLatin_##e, xercesc::chLatin_##f, xercesc::chLatin_##g, xercesc::chLatin_##h, xercesc::chLatin_##i, \
134         xercesc::chLatin_##j, xercesc::chLatin_##k, xercesc::chLatin_##l, xercesc::chNull}
135 #define UNICODE_LITERAL_13(a,b,c,d,e,f,g,h,i,j,k,l,m) \
136     {xercesc::chLatin_##a, xercesc::chLatin_##b, xercesc::chLatin_##c, xercesc::chLatin_##d, xercesc::chLatin_##e, xercesc::chLatin_##f, xercesc::chLatin_##g, xercesc::chLatin_##h, xercesc::chLatin_##i, \
137         xercesc::chLatin_##j, xercesc::chLatin_##k, xercesc::chLatin_##l, xercesc::chLatin_##m, xercesc::chNull}
138 #define UNICODE_LITERAL_14(a,b,c,d,e,f,g,h,i,j,k,l,m,n) \
139     {xercesc::chLatin_##a, xercesc::chLatin_##b, xercesc::chLatin_##c, xercesc::chLatin_##d, xercesc::chLatin_##e, xercesc::chLatin_##f, xercesc::chLatin_##g, xercesc::chLatin_##h, xercesc::chLatin_##i, \
140         xercesc::chLatin_##j, xercesc::chLatin_##k, xercesc::chLatin_##l, xercesc::chLatin_##m, xercesc::chLatin_##n, xercesc::chNull}
141 #define UNICODE_LITERAL_15(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o) \
142     {xercesc::chLatin_##a, xercesc::chLatin_##b, xercesc::chLatin_##c, xercesc::chLatin_##d, xercesc::chLatin_##e, xercesc::chLatin_##f, xercesc::chLatin_##g, xercesc::chLatin_##h, xercesc::chLatin_##i, \
143         xercesc::chLatin_##j, xercesc::chLatin_##k, xercesc::chLatin_##l, xercesc::chLatin_##m, xercesc::chLatin_##n, xercesc::chLatin_##o, xercesc::chNull}
144 #define UNICODE_LITERAL_16(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p) \
145     {xercesc::chLatin_##a, xercesc::chLatin_##b, xercesc::chLatin_##c, xercesc::chLatin_##d, xercesc::chLatin_##e, xercesc::chLatin_##f, xercesc::chLatin_##g, xercesc::chLatin_##h, xercesc::chLatin_##i, \
146         xercesc::chLatin_##j, xercesc::chLatin_##k, xercesc::chLatin_##l, xercesc::chLatin_##m, xercesc::chLatin_##n, xercesc::chLatin_##o, xercesc::chLatin_##p, xercesc::chNull}
147 #define UNICODE_LITERAL_17(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q) \
148     {xercesc::chLatin_##a, xercesc::chLatin_##b, xercesc::chLatin_##c, xercesc::chLatin_##d, xercesc::chLatin_##e, xercesc::chLatin_##f, xercesc::chLatin_##g, xercesc::chLatin_##h, xercesc::chLatin_##i, \
149         xercesc::chLatin_##j, xercesc::chLatin_##k, xercesc::chLatin_##l, xercesc::chLatin_##m, xercesc::chLatin_##n, xercesc::chLatin_##o, xercesc::chLatin_##p, xercesc::chLatin_##q, xercesc::chNull}
150 #define UNICODE_LITERAL_18(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r) \
151     {xercesc::chLatin_##a, xercesc::chLatin_##b, xercesc::chLatin_##c, xercesc::chLatin_##d, xercesc::chLatin_##e, xercesc::chLatin_##f, xercesc::chLatin_##g, xercesc::chLatin_##h, xercesc::chLatin_##i, \
152         xercesc::chLatin_##j, xercesc::chLatin_##k, xercesc::chLatin_##l, xercesc::chLatin_##m, xercesc::chLatin_##n, xercesc::chLatin_##o, xercesc::chLatin_##p, xercesc::chLatin_##q, xercesc::chLatin_##r, xercesc::chNull}
153 #define UNICODE_LITERAL_19(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s) \
154     {xercesc::chLatin_##a, xercesc::chLatin_##b, xercesc::chLatin_##c, xercesc::chLatin_##d, xercesc::chLatin_##e, xercesc::chLatin_##f, xercesc::chLatin_##g, xercesc::chLatin_##h, xercesc::chLatin_##i, \
155         xercesc::chLatin_##j, xercesc::chLatin_##k, xercesc::chLatin_##l, xercesc::chLatin_##m, xercesc::chLatin_##n, xercesc::chLatin_##o, xercesc::chLatin_##p, xercesc::chLatin_##q, xercesc::chLatin_##r, \
156         xercesc::chLatin_##s, xercesc::chNull}
157 #define UNICODE_LITERAL_20(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t) \
158     {xercesc::chLatin_##a, xercesc::chLatin_##b, xercesc::chLatin_##c, xercesc::chLatin_##d, xercesc::chLatin_##e, xercesc::chLatin_##f, xercesc::chLatin_##g, xercesc::chLatin_##h, xercesc::chLatin_##i, \
159         xercesc::chLatin_##j, xercesc::chLatin_##k, xercesc::chLatin_##l, xercesc::chLatin_##m, xercesc::chLatin_##n, xercesc::chLatin_##o, xercesc::chLatin_##p, xercesc::chLatin_##q, xercesc::chLatin_##r, \
160         xercesc::chLatin_##s, xercesc::chLatin_##t, xercesc::chNull}
161 #define UNICODE_LITERAL_21(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u) \
162     {xercesc::chLatin_##a, xercesc::chLatin_##b, xercesc::chLatin_##c, xercesc::chLatin_##d, xercesc::chLatin_##e, xercesc::chLatin_##f, xercesc::chLatin_##g, xercesc::chLatin_##h, xercesc::chLatin_##i, \
163         xercesc::chLatin_##j, xercesc::chLatin_##k, xercesc::chLatin_##l, xercesc::chLatin_##m, xercesc::chLatin_##n, xercesc::chLatin_##o, xercesc::chLatin_##p, xercesc::chLatin_##q, xercesc::chLatin_##r, \
164         xercesc::chLatin_##s, xercesc::chLatin_##t, xercesc::chLatin_##u, xercesc::chNull}
165 #define UNICODE_LITERAL_22(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v) \
166     {xercesc::chLatin_##a, xercesc::chLatin_##b, xercesc::chLatin_##c, xercesc::chLatin_##d, xercesc::chLatin_##e, xercesc::chLatin_##f, xercesc::chLatin_##g, xercesc::chLatin_##h, xercesc::chLatin_##i, \
167         xercesc::chLatin_##j, xercesc::chLatin_##k, xercesc::chLatin_##l, xercesc::chLatin_##m, xercesc::chLatin_##n, xercesc::chLatin_##o, xercesc::chLatin_##p, xercesc::chLatin_##q, xercesc::chLatin_##r, \
168         xercesc::chLatin_##s, xercesc::chLatin_##t, xercesc::chLatin_##u, xercesc::chLatin_##v, xercesc::chNull}
169 #define UNICODE_LITERAL_23(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w) \
170     {xercesc::chLatin_##a, xercesc::chLatin_##b, xercesc::chLatin_##c, xercesc::chLatin_##d, xercesc::chLatin_##e, xercesc::chLatin_##f, xercesc::chLatin_##g, xercesc::chLatin_##h, xercesc::chLatin_##i, \
171         xercesc::chLatin_##j, xercesc::chLatin_##k, xercesc::chLatin_##l, xercesc::chLatin_##m, xercesc::chLatin_##n, xercesc::chLatin_##o, xercesc::chLatin_##p, xercesc::chLatin_##q, xercesc::chLatin_##r, \
172         xercesc::chLatin_##s, xercesc::chLatin_##t, xercesc::chLatin_##u, xercesc::chLatin_##v, xercesc::chLatin_##w, xercesc::chNull}
173 #define UNICODE_LITERAL_24(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x) \
174     {xercesc::chLatin_##a, xercesc::chLatin_##b, xercesc::chLatin_##c, xercesc::chLatin_##d, xercesc::chLatin_##e, xercesc::chLatin_##f, xercesc::chLatin_##g, xercesc::chLatin_##h, xercesc::chLatin_##i, \
175         xercesc::chLatin_##j, xercesc::chLatin_##k, xercesc::chLatin_##l, xercesc::chLatin_##m, xercesc::chLatin_##n, xercesc::chLatin_##o, xercesc::chLatin_##p, xercesc::chLatin_##q, xercesc::chLatin_##r, \
176         xercesc::chLatin_##s, xercesc::chLatin_##t, xercesc::chLatin_##u, xercesc::chLatin_##v, xercesc::chLatin_##w, xercesc::chLatin_##x, xercesc::chNull}
177 #define UNICODE_LITERAL_25(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y) \
178     {xercesc::chLatin_##a, xercesc::chLatin_##b, xercesc::chLatin_##c, xercesc::chLatin_##d, xercesc::chLatin_##e, xercesc::chLatin_##f, xercesc::chLatin_##g, xercesc::chLatin_##h, xercesc::chLatin_##i, \
179         xercesc::chLatin_##j, xercesc::chLatin_##k, xercesc::chLatin_##l, xercesc::chLatin_##m, xercesc::chLatin_##n, xercesc::chLatin_##o, xercesc::chLatin_##p, xercesc::chLatin_##q, xercesc::chLatin_##r, \
180         xercesc::chLatin_##s, xercesc::chLatin_##t, xercesc::chLatin_##u, xercesc::chLatin_##v, xercesc::chLatin_##w, xercesc::chLatin_##x, xercesc::chLatin_##y, xercesc::chNull}
181 #define UNICODE_LITERAL_26(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z) \
182     {xercesc::chLatin_##a, xercesc::chLatin_##b, xercesc::chLatin_##c, xercesc::chLatin_##d, xercesc::chLatin_##e, xercesc::chLatin_##f, xercesc::chLatin_##g, xercesc::chLatin_##h, xercesc::chLatin_##i, \
183         xercesc::chLatin_##j, xercesc::chLatin_##k, xercesc::chLatin_##l, xercesc::chLatin_##m, xercesc::chLatin_##n, xercesc::chLatin_##o, xercesc::chLatin_##p, xercesc::chLatin_##q, xercesc::chLatin_##r, \
184         xercesc::chLatin_##s, xercesc::chLatin_##t, xercesc::chLatin_##u, xercesc::chLatin_##v, xercesc::chLatin_##w, xercesc::chLatin_##x, xercesc::chLatin_##y, xercesc::chLatin_##z, xercesc::chNull}
185 #define UNICODE_LITERAL_27(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,aa) \
186     {xercesc::chLatin_##a, xercesc::chLatin_##b, xercesc::chLatin_##c, xercesc::chLatin_##d, xercesc::chLatin_##e, xercesc::chLatin_##f, xercesc::chLatin_##g, xercesc::chLatin_##h, xercesc::chLatin_##i, \
187         xercesc::chLatin_##j, xercesc::chLatin_##k, xercesc::chLatin_##l, xercesc::chLatin_##m, xercesc::chLatin_##n, xercesc::chLatin_##o, xercesc::chLatin_##p, xercesc::chLatin_##q, xercesc::chLatin_##r, \
188         xercesc::chLatin_##s, xercesc::chLatin_##t, xercesc::chLatin_##u, xercesc::chLatin_##v, xercesc::chLatin_##w, xercesc::chLatin_##x, xercesc::chLatin_##y, xercesc::chLatin_##z, \
189         xercesc::chLatin_##aa, xercesc::chNull}
190 #define UNICODE_LITERAL_28(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,aa,bb) \
191     {xercesc::chLatin_##a, xercesc::chLatin_##b, xercesc::chLatin_##c, xercesc::chLatin_##d, xercesc::chLatin_##e, xercesc::chLatin_##f, xercesc::chLatin_##g, xercesc::chLatin_##h, xercesc::chLatin_##i, \
192         xercesc::chLatin_##j, xercesc::chLatin_##k, xercesc::chLatin_##l, xercesc::chLatin_##m, xercesc::chLatin_##n, xercesc::chLatin_##o, xercesc::chLatin_##p, xercesc::chLatin_##q, xercesc::chLatin_##r, \
193         xercesc::chLatin_##s, xercesc::chLatin_##t, xercesc::chLatin_##u, xercesc::chLatin_##v, xercesc::chLatin_##w, xercesc::chLatin_##x, xercesc::chLatin_##y, xercesc::chLatin_##z, \
194         xercesc::chLatin_##aa, xercesc::chLatin_##bb, xercesc::chNull}
195 #define UNICODE_LITERAL_29(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,aa,bb,cc) \
196     {xercesc::chLatin_##a, xercesc::chLatin_##b, xercesc::chLatin_##c, xercesc::chLatin_##d, xercesc::chLatin_##e, xercesc::chLatin_##f, xercesc::chLatin_##g, xercesc::chLatin_##h, xercesc::chLatin_##i, \
197         xercesc::chLatin_##j, xercesc::chLatin_##k, xercesc::chLatin_##l, xercesc::chLatin_##m, xercesc::chLatin_##n, xercesc::chLatin_##o, xercesc::chLatin_##p, xercesc::chLatin_##q, xercesc::chLatin_##r, \
198         xercesc::chLatin_##s, xercesc::chLatin_##t, xercesc::chLatin_##u, xercesc::chLatin_##v, xercesc::chLatin_##w, xercesc::chLatin_##x, xercesc::chLatin_##y, xercesc::chLatin_##z, \
199         xercesc::chLatin_##aa, xercesc::chLatin_##bb, xercesc::chLatin_##cc, xercesc::chNull}
200 #define UNICODE_LITERAL_30(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,aa,bb,cc,dd) \
201     {xercesc::chLatin_##a, xercesc::chLatin_##b, xercesc::chLatin_##c, xercesc::chLatin_##d, xercesc::chLatin_##e, xercesc::chLatin_##f, xercesc::chLatin_##g, xercesc::chLatin_##h, xercesc::chLatin_##i, \
202         xercesc::chLatin_##j, xercesc::chLatin_##k, xercesc::chLatin_##l, xercesc::chLatin_##m, xercesc::chLatin_##n, xercesc::chLatin_##o, xercesc::chLatin_##p, xercesc::chLatin_##q, xercesc::chLatin_##r, \
203         xercesc::chLatin_##s, xercesc::chLatin_##t, xercesc::chLatin_##u, xercesc::chLatin_##v, xercesc::chLatin_##w, xercesc::chLatin_##x, xercesc::chLatin_##y, xercesc::chLatin_##z, \
204         xercesc::chLatin_##aa, xercesc::chLatin_##bb, xercesc::chLatin_##cc, xercesc::chLatin_##dd, xercesc::chNull}
205 #define UNICODE_LITERAL_31(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,aa,bb,cc,dd,ee) \
206     {xercesc::chLatin_##a, xercesc::chLatin_##b, xercesc::chLatin_##c, xercesc::chLatin_##d, xercesc::chLatin_##e, xercesc::chLatin_##f, xercesc::chLatin_##g, xercesc::chLatin_##h, xercesc::chLatin_##i, \
207         xercesc::chLatin_##j, xercesc::chLatin_##k, xercesc::chLatin_##l, xercesc::chLatin_##m, xercesc::chLatin_##n, xercesc::chLatin_##o, xercesc::chLatin_##p, xercesc::chLatin_##q, xercesc::chLatin_##r, \
208         xercesc::chLatin_##s, xercesc::chLatin_##t, xercesc::chLatin_##u, xercesc::chLatin_##v, xercesc::chLatin_##w, xercesc::chLatin_##x, xercesc::chLatin_##y, xercesc::chLatin_##z, \
209         xercesc::chLatin_##aa, xercesc::chLatin_##bb, xercesc::chLatin_##cc, xercesc::chLatin_##dd, xercesc::chLatin_##ee, xercesc::chNull}
210 #define UNICODE_LITERAL_32(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,aa,bb,cc,dd,ee,ff) \
211     {xercesc::chLatin_##a, xercesc::chLatin_##b, xercesc::chLatin_##c, xercesc::chLatin_##d, xercesc::chLatin_##e, xercesc::chLatin_##f, xercesc::chLatin_##g, xercesc::chLatin_##h, xercesc::chLatin_##i, \
212         xercesc::chLatin_##j, xercesc::chLatin_##k, xercesc::chLatin_##l, xercesc::chLatin_##m, xercesc::chLatin_##n, xercesc::chLatin_##o, xercesc::chLatin_##p, xercesc::chLatin_##q, xercesc::chLatin_##r, \
213         xercesc::chLatin_##s, xercesc::chLatin_##t, xercesc::chLatin_##u, xercesc::chLatin_##v, xercesc::chLatin_##w, xercesc::chLatin_##x, xercesc::chLatin_##y, xercesc::chLatin_##z, \
214         xercesc::chLatin_##aa, xercesc::chLatin_##bb, xercesc::chLatin_##cc, xercesc::chLatin_##dd, xercesc::chLatin_##ee, xercesc::chLatin_##ff, xercesc::chNull}
215 #define UNICODE_LITERAL_33(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,aa,bb,cc,dd,ee,ff,gg) \
216     {xercesc::chLatin_##a, xercesc::chLatin_##b, xercesc::chLatin_##c, xercesc::chLatin_##d, xercesc::chLatin_##e, xercesc::chLatin_##f, xercesc::chLatin_##g, xercesc::chLatin_##h, xercesc::chLatin_##i, \
217         xercesc::chLatin_##j, xercesc::chLatin_##k, xercesc::chLatin_##l, xercesc::chLatin_##m, xercesc::chLatin_##n, xercesc::chLatin_##o, xercesc::chLatin_##p, xercesc::chLatin_##q, xercesc::chLatin_##r, \
218         xercesc::chLatin_##s, xercesc::chLatin_##t, xercesc::chLatin_##u, xercesc::chLatin_##v, xercesc::chLatin_##w, xercesc::chLatin_##x, xercesc::chLatin_##y, xercesc::chLatin_##z, \
219         xercesc::chLatin_##aa, xercesc::chLatin_##bb, xercesc::chLatin_##cc, xercesc::chLatin_##dd, xercesc::chLatin_##ee, xercesc::chLatin_##ff, xercesc::chLatin_##gg, xercesc::chNull}
220 #define UNICODE_LITERAL_34(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,aa,bb,cc,dd,ee,ff,gg,hh) \
221     {xercesc::chLatin_##a, xercesc::chLatin_##b, xercesc::chLatin_##c, xercesc::chLatin_##d, xercesc::chLatin_##e, xercesc::chLatin_##f, xercesc::chLatin_##g, xercesc::chLatin_##h, xercesc::chLatin_##i, \
222         xercesc::chLatin_##j, xercesc::chLatin_##k, xercesc::chLatin_##l, xercesc::chLatin_##m, xercesc::chLatin_##n, xercesc::chLatin_##o, xercesc::chLatin_##p, xercesc::chLatin_##q, xercesc::chLatin_##r, \
223         xercesc::chLatin_##s, xercesc::chLatin_##t, xercesc::chLatin_##u, xercesc::chLatin_##v, xercesc::chLatin_##w, xercesc::chLatin_##x, xercesc::chLatin_##y, xercesc::chLatin_##z, \
224         xercesc::chLatin_##aa, xercesc::chLatin_##bb, xercesc::chLatin_##cc, xercesc::chLatin_##dd, xercesc::chLatin_##ee, xercesc::chLatin_##ff, xercesc::chLatin_##gg, xercesc::chLatin_##hh, xercesc::chNull}
225 #endif /* DOXYGEN_SKIP */
226
227 /**
228  * Begins the declaration of an XMLObject specialization for an abstract element/type.
229  * Basic boilerplate includes a protected constructor, empty virtual destructor,
230  * and Unicode constants for the default associated element's name and prefix.
231  *
232  * @param linkage   linkage specifier for the class
233  * @param cname     the name of the class to declare
234  * @param base      the base class to derive from using public virtual inheritance
235  * @param desc      documentation comment for class
236  */
237 #define DECL_XMLOBJECT_ABSTRACT(linkage,cname,base,desc) \
238     XMLTOOLING_DOXYGEN(desc) \
239     class linkage cname : public virtual base { \
240     protected: \
241         cname() {} \
242     public: \
243         virtual ~cname() {} \
244         XMLTOOLING_DOXYGEN(Element local name) \
245         static const XMLCh LOCAL_NAME[]; \
246     }
247
248 /**
249  * Begins the declaration of an XMLObject specialization.
250  * Basic boilerplate includes a protected constructor, empty virtual destructor,
251  * and Unicode constants for the default associated element's name and prefix.
252  *
253  * @param linkage   linkage specifier for the class
254  * @param cname     the name of the class to declare
255  * @param base      the base class to derive from using public virtual inheritance
256  * @param desc      documentation comment for class
257  */
258 #define BEGIN_XMLOBJECT(linkage,cname,base,desc) \
259     XMLTOOLING_DOXYGEN(desc) \
260     class linkage cname : public virtual base { \
261     protected: \
262         cname() {} \
263     public: \
264         virtual ~cname() {} \
265         XMLTOOLING_DOXYGEN(Type-specific clone method.) \
266         virtual cname* clone##cname() const=0; \
267         XMLTOOLING_DOXYGEN(Element local name) \
268         static const XMLCh LOCAL_NAME[]
269
270 /**
271  * Begins the declaration of an XMLObject specialization with two base classes.
272  * Basic boilerplate includes a protected constructor, empty virtual destructor,
273  * and Unicode constants for the default associated element's name and prefix.
274  *
275  * @param linkage   linkage specifier for the class
276  * @param cname     the name of the class to declare
277  * @param base      the first base class to derive from using public virtual inheritance
278  * @param base2     the second base class to derive from using public virtual inheritance
279  * @param desc      documentation comment for class
280  */
281 #define BEGIN_XMLOBJECT2(linkage,cname,base,base2,desc) \
282     XMLTOOLING_DOXYGEN(desc) \
283     class linkage cname : public virtual base, public virtual base2 { \
284     protected: \
285         cname() {} \
286     public: \
287         virtual ~cname() {} \
288         XMLTOOLING_DOXYGEN(Type-specific clone method.) \
289         virtual cname* clone##cname() const=0; \
290         XMLTOOLING_DOXYGEN(Element local name) \
291         static const XMLCh LOCAL_NAME[]
292
293 /**
294  * Begins the declaration of an XMLObject specialization with three base classes.
295  * Basic boilerplate includes a protected constructor, empty virtual destructor,
296  * and Unicode constants for the default associated element's name and prefix.
297  *
298  * @param linkage   linkage specifier for the class
299  * @param cname     the name of the class to declare
300  * @param base      the first base class to derive from using public virtual inheritance
301  * @param base2     the second base class to derive from using public virtual inheritance
302  * @param base3     the third base class to derive from using public virtual inheritance
303  * @param desc      documentation comment for class
304  */
305 #define BEGIN_XMLOBJECT3(linkage,cname,base,base2,base3,desc) \
306     XMLTOOLING_DOXYGEN(desc) \
307     class linkage cname : public virtual base, public virtual base2, public virtual base3 { \
308     protected: \
309         cname() {} \
310     public: \
311         virtual ~cname() {} \
312         XMLTOOLING_DOXYGEN(Type-specific clone method.) \
313         virtual cname* clone##cname() const=0; \
314         XMLTOOLING_DOXYGEN(Element local name) \
315         static const XMLCh LOCAL_NAME[]
316
317 /**
318  * Begins the declaration of an XMLObject specialization with four base classes.
319  * Basic boilerplate includes a protected constructor, empty virtual destructor,
320  * and Unicode constants for the default associated element's name and prefix.
321  *
322  * @param linkage   linkage specifier for the class
323  * @param cname     the name of the class to declare
324  * @param base      the first base class to derive from using public virtual inheritance
325  * @param base2     the second base class to derive from using public virtual inheritance
326  * @param base3     the third base class to derive from using public virtual inheritance
327  * @param base4     the fourth base class to derive from using public virtual inheritance
328  * @param desc      documentation comment for class
329  */
330 #define BEGIN_XMLOBJECT4(linkage,cname,base,base2,base3,base4,desc) \
331     XMLTOOLING_DOXYGEN(desc) \
332     class linkage cname : public virtual base, public virtual base2, public virtual base3, public virtual base4 { \
333     protected: \
334         cname() {} \
335     public: \
336         virtual ~cname() {} \
337         XMLTOOLING_DOXYGEN(Type-specific clone method.) \
338         virtual cname* clone##cname() const=0; \
339         XMLTOOLING_DOXYGEN(Element local name) \
340         static const XMLCh LOCAL_NAME[]
341
342 /**
343  * Begins the declaration of an XMLObject specialization with five base classes.
344  * Basic boilerplate includes a protected constructor, empty virtual destructor,
345  * and Unicode constants for the default associated element's name and prefix.
346  *
347  * @param linkage   linkage specifier for the class
348  * @param cname     the name of the class to declare
349  * @param base      the first base class to derive from using public virtual inheritance
350  * @param base2     the second base class to derive from using public virtual inheritance
351  * @param base3     the third base class to derive from using public virtual inheritance
352  * @param base4     the fourth base class to derive from using public virtual inheritance
353  * @param base5     the fifth base class to derive from using public virtual inheritance
354  * @param desc      documentation comment for class
355  */
356 #define BEGIN_XMLOBJECT5(linkage,cname,base,base2,base3,base4,base5,desc) \
357     XMLTOOLING_DOXYGEN(desc) \
358     class linkage cname : public virtual base, public virtual base2, public virtual base3, public virtual base4, public virtual base5 { \
359     protected: \
360         cname() {} \
361     public: \
362         virtual ~cname() {} \
363         XMLTOOLING_DOXYGEN(Type-specific clone method.) \
364         virtual cname* clone##cname() const=0; \
365         XMLTOOLING_DOXYGEN(Element local name) \
366         static const XMLCh LOCAL_NAME[]
367
368 /**
369  * Ends the declaration of an XMLObject specialization.
370  */
371 #define END_XMLOBJECT }
372
373 /**
374  * Declares a static variable holding the XMLObject's element QName.
375  */
376 #define DECL_ELEMENT_QNAME \
377     public: \
378         XMLTOOLING_DOXYGEN(Element QName) \
379         static xmltooling::QName ELEMENT_QNAME
380
381 /**
382  * Declares a static variable holding the XMLObject's schema type QName.
383  */
384 #define DECL_TYPE_QNAME \
385     public: \
386         XMLTOOLING_DOXYGEN(Type QName) \
387         static xmltooling::QName TYPE_QNAME
388
389 /**
390  * Implements a static variable holding an XMLObject's element QName.
391  *
392  * @param cname             the name of the XMLObject specialization
393  * @param namespaceURI      the XML namespace of the default associated element
394  * @param namespacePrefix   the XML namespace prefix of the default associated element
395  */
396 #define IMPL_ELEMENT_QNAME(cname,namespaceURI,namespacePrefix) \
397     xmltooling::QName cname::ELEMENT_QNAME(namespaceURI,cname::LOCAL_NAME,namespacePrefix)
398
399 /**
400  * Implements a static variable holding an XMLObject's schema type QName.
401  *
402  * @param cname             the name of the XMLObject specialization
403  * @param namespaceURI      the XML namespace of the default associated element
404  * @param namespacePrefix   the XML namespace prefix of the default associated element
405  */
406 #define IMPL_TYPE_QNAME(cname,namespaceURI,namespacePrefix) \
407     xmltooling::QName cname::TYPE_QNAME(namespaceURI,cname::TYPE_NAME,namespacePrefix)
408
409 /**
410  * Declares abstract set method for a typed XML attribute.
411  * The get method is omitted.
412  *
413  * @param proper    the proper name of the attribute
414  * @param upcased   the upcased name of the attribute
415  * @param type      the attribute's data type
416  */
417 #define DECL_INHERITED_XMLOBJECT_ATTRIB(proper,upcased,type) \
418     public: \
419         XMLTOOLING_DOXYGEN(proper attribute name) \
420         static const XMLCh upcased##_ATTRIB_NAME[]; \
421         XMLTOOLING_DOXYGEN(Sets the proper attribute.) \
422         virtual void set##proper(const type* proper)=0
423
424 /**
425  * Declares abstract get/set methods for a typed XML attribute.
426  *
427  * @param proper    the proper name of the attribute
428  * @param upcased   the upcased name of the attribute
429  * @param type      the attribute's data type
430  */
431 #define DECL_XMLOBJECT_ATTRIB(proper,upcased,type) \
432     public: \
433         XMLTOOLING_DOXYGEN(proper attribute name) \
434         static const XMLCh upcased##_ATTRIB_NAME[]; \
435         XMLTOOLING_DOXYGEN(Returns the proper attribute.) \
436         virtual const type* get##proper() const=0; \
437         XMLTOOLING_DOXYGEN(Sets the proper attribute.) \
438         virtual void set##proper(const type* proper)=0
439
440 /**
441  * Declares abstract set method for a string XML attribute.
442  * The get method is omitted.
443  *
444  * @param proper    the proper name of the attribute
445  * @param upcased   the upcased name of the attribute
446  */
447 #define DECL_INHERITED_STRING_ATTRIB(proper,upcased) \
448     DECL_INHERITED_XMLOBJECT_ATTRIB(proper,upcased,XMLCh)
449
450 /**
451  * Declares abstract get/set methods for a string XML attribute.
452  *
453  * @param proper    the proper name of the attribute
454  * @param upcased   the upcased name of the attribute
455  */
456 #define DECL_STRING_ATTRIB(proper,upcased) \
457     DECL_XMLOBJECT_ATTRIB(proper,upcased,XMLCh)
458
459 /**
460  * Declares abstract set method for a DateTime XML attribute.
461  * The get method is omitted.
462  *
463  * @param proper    the proper name of the attribute
464  * @param upcased   the upcased name of the attribute
465  */
466 #define DECL_INHERITED_DATETIME_ATTRIB(proper,upcased) \
467     DECL_INHERITED_XMLOBJECT_ATTRIB(proper,upcased,xmltooling::DateTime); \
468     XMLTOOLING_DOXYGEN(Sets the proper attribute.) \
469     virtual void set##proper(time_t proper)=0; \
470     XMLTOOLING_DOXYGEN(Sets the proper attribute.) \
471     virtual void set##proper(const XMLCh* proper)=0
472
473 /**
474  * Declares abstract get/set methods for a DateTime XML attribute.
475  *
476  * @param proper    the proper name of the attribute
477  * @param upcased   the upcased name of the attribute
478  */
479 #define DECL_DATETIME_ATTRIB(proper,upcased) \
480     DECL_XMLOBJECT_ATTRIB(proper,upcased,xmltooling::DateTime); \
481     XMLTOOLING_DOXYGEN(Returns the proper attribute in epoch form.) \
482     virtual time_t get##proper##Epoch() const=0; \
483     XMLTOOLING_DOXYGEN(Sets the proper attribute.) \
484     virtual void set##proper(time_t proper)=0; \
485     XMLTOOLING_DOXYGEN(Sets the proper attribute.) \
486     virtual void set##proper(const XMLCh* proper)=0
487
488 /**
489  * Declares abstract set method for an integer XML attribute.
490  * The get method is omitted.
491  *
492  * @param proper    the proper name of the attribute
493  * @param upcased   the upcased name of the attribute
494  */
495 #define DECL_INHERITED_INTEGER_ATTRIB(proper,upcased) \
496     public: \
497         XMLTOOLING_DOXYGEN(proper attribute name) \
498         static const XMLCh upcased##_ATTRIB_NAME[]; \
499         XMLTOOLING_DOXYGEN(Sets the proper attribute using a string value.) \
500         virtual void set##proper(const XMLCh* proper)=0; \
501         XMLTOOLING_DOXYGEN(Sets the proper attribute.) \
502         virtual void set##proper(int proper)=0
503
504 /**
505  * Declares abstract get/set methods for an integer XML attribute.
506  *
507  * @param proper    the proper name of the attribute
508  * @param upcased   the upcased name of the attribute
509  */
510 #define DECL_INTEGER_ATTRIB(proper,upcased) \
511     public: \
512         XMLTOOLING_DOXYGEN(proper attribute name) \
513         static const XMLCh upcased##_ATTRIB_NAME[]; \
514         XMLTOOLING_DOXYGEN(Returns the proper attribute after a NULL indicator.) \
515         virtual std::pair<bool,int> get##proper() const=0; \
516         XMLTOOLING_DOXYGEN(Sets the proper attribute using a string value.) \
517         virtual void set##proper(const XMLCh* proper)=0; \
518         XMLTOOLING_DOXYGEN(Sets the proper attribute.) \
519         virtual void set##proper(int proper)=0
520
521 /**
522  * Declares abstract get/set methods for a boolean XML attribute.
523  *
524  * @param proper    the proper name of the attribute
525  * @param upcased   the upcased name of the attribute
526  * @param def       the default/presumed value, if no explicit value has been set
527  */
528 #define DECL_BOOLEAN_ATTRIB(proper,upcased,def) \
529     public: \
530         XMLTOOLING_DOXYGEN(proper attribute name) \
531         static const XMLCh upcased##_ATTRIB_NAME[]; \
532         XMLTOOLING_DOXYGEN(Returns the proper attribute or def if not set.) \
533         bool proper() const { \
534             switch (get##proper()) { \
535                 case xmlconstants::XML_BOOL_TRUE: \
536                 case xmlconstants::XML_BOOL_ONE: \
537                     return true; \
538                 case xmlconstants::XML_BOOL_FALSE: \
539                 case xmlconstants::XML_BOOL_ZERO: \
540                     return false; \
541                 default: \
542                     return def; \
543             } \
544         } \
545         XMLTOOLING_DOXYGEN(Returns the proper attribute as an explicit enumerated value.) \
546         virtual xmlconstants::xmltooling_bool_t get##proper() const=0; \
547         XMLTOOLING_DOXYGEN(Sets the proper attribute using an enumerated value.) \
548         virtual void proper(xmlconstants::xmltooling_bool_t value)=0; \
549         XMLTOOLING_DOXYGEN(Sets the proper attribute.) \
550         void proper(bool value) { \
551             proper(value ? xmlconstants::XML_BOOL_ONE : xmlconstants::XML_BOOL_ZERO); \
552         } \
553         XMLTOOLING_DOXYGEN(Sets the proper attribute using a string constant.) \
554         void set##proper(const XMLCh* value) { \
555             if (value) { \
556                 switch (*value) { \
557                     case xercesc::chLatin_t: \
558                         proper(xmlconstants::XML_BOOL_TRUE); \
559                         break; \
560                     case xercesc::chLatin_f: \
561                         proper(xmlconstants::XML_BOOL_FALSE); \
562                         break; \
563                     case xercesc::chDigit_1: \
564                         proper(xmlconstants::XML_BOOL_ONE); \
565                         break; \
566                     case xercesc::chDigit_0: \
567                         proper(xmlconstants::XML_BOOL_ZERO); \
568                         break; \
569                     default: \
570                         proper(xmlconstants::XML_BOOL_NULL); \
571                 } \
572             } \
573             else \
574                 proper(xmlconstants::XML_BOOL_NULL); \
575         }
576
577 /**
578  * Implements get/set methods and a private member for a typed XML attribute.
579  *
580  * @param proper    the proper name of the attribute
581  * @param type      the attribute's data type
582  */
583 #define IMPL_XMLOBJECT_ATTRIB(proper,type) \
584     protected: \
585         type* m_##proper; \
586     public: \
587         const type* get##proper() const { \
588             return m_##proper; \
589         } \
590         void set##proper(const type* proper) { \
591             m_##proper = prepareForAssignment(m_##proper,proper); \
592         }
593
594 /**
595  * Implements get/set methods and a private member for a string XML attribute.
596  *
597  * @param proper    the proper name of the attribute
598  */
599 #define IMPL_STRING_ATTRIB(proper) \
600     IMPL_XMLOBJECT_ATTRIB(proper,XMLCh)
601
602 /**
603  * Implements get/set methods and a private member for a string XML attribute,
604  * plus a getXMLID override.
605  *
606  * @param proper    the proper name of the attribute
607  */
608 #define IMPL_ID_ATTRIB(proper) \
609     IMPL_XMLOBJECT_ATTRIB(proper,XMLCh) \
610     const XMLCh* getXMLID() const { \
611         return m_##proper; \
612     }
613
614 /**
615  * Implements get/set methods and a private member for a string XML attribute,
616  * plus a getXMLID override and attribute node clearance when DOM is dropped.
617  *
618  * @param proper    the proper name of the attribute
619  * @param ucase         the upcased name of the attribute
620  * @param namespaceURI  the XML namespace of the attribute
621  */
622 #define IMPL_ID_ATTRIB_EX(proper, ucase, namespaceURI) \
623     IMPL_XMLOBJECT_ATTRIB(proper,XMLCh) \
624     const XMLCh* getXMLID() const { \
625         return m_##proper; \
626     } \
627     void releaseDOM() const { \
628         if (getDOM()) \
629             getDOM()->removeAttributeNS(namespaceURI, ucase##_ATTRIB_NAME); \
630         AbstractDOMCachingXMLObject::releaseDOM(); \
631     }
632
633 /**
634  * Implements get/set methods and a private member for a DateTime XML attribute.
635  *
636  * @param proper    the proper name of the attribute
637  * @param fallback  epoch to return when attribute is NULL
638  */
639 #define IMPL_DATETIME_ATTRIB(proper,fallback) \
640     IMPL_DATETIME_ATTRIB_EX(proper,fallback,false)
641
642 /**
643  * Implements get/set methods and a private member for a duration-valued DateTime XML attribute.
644  *
645  * @param proper    the proper name of the attribute
646  * @param fallback  epoch to return when attribute is NULL
647  */
648 #define IMPL_DURATION_ATTRIB(proper,fallback) \
649     IMPL_DATETIME_ATTRIB_EX(proper,fallback,true)
650
651 /**
652  * Implements get/set methods and a private member for a DateTime XML attribute.
653  *
654  * @param proper    the proper name of the attribute
655  * @param fallback  epoch to return when attribute is NULL
656  * @param duration  true iff the attribute should be handled as a duration
657  */
658 #define IMPL_DATETIME_ATTRIB_EX(proper,fallback,duration) \
659     protected: \
660         DateTime* m_##proper; \
661         time_t m_##proper##Epoch; \
662     public: \
663         const DateTime* get##proper() const { \
664             return m_##proper; \
665         } \
666         time_t get##proper##Epoch() const { \
667             return m_##proper ? m_##proper##Epoch : fallback; \
668         } \
669         void set##proper(const DateTime* proper) { \
670             m_##proper = prepareForAssignment(m_##proper,proper); \
671             if (m_##proper) \
672                 m_##proper##Epoch=m_##proper->getEpoch(duration); \
673         } \
674         void set##proper(time_t proper) { \
675             m_##proper = prepareForAssignment(m_##proper,proper,duration); \
676             m_##proper##Epoch = proper; \
677         } \
678         void set##proper(const XMLCh* proper) { \
679             m_##proper = prepareForAssignment(m_##proper,proper,duration); \
680             if (m_##proper) \
681                 m_##proper##Epoch=m_##proper->getEpoch(duration); \
682         }
683
684 /**
685  * Implements get/set methods and a private member for an integer XML attribute.
686  *
687  * @param proper    the proper name of the attribute
688  */
689 #define IMPL_INTEGER_ATTRIB(proper) \
690     protected: \
691         XMLCh* m_##proper; \
692     public: \
693         pair<bool,int> get##proper() const { \
694             return make_pair((m_##proper!=nullptr),(m_##proper!=nullptr ? xercesc::XMLString::parseInt(m_##proper): 0)); \
695         } \
696         void set##proper(const XMLCh* proper) { \
697             m_##proper = prepareForAssignment(m_##proper,proper); \
698         } \
699         void set##proper(int proper) { \
700             char buf##proper[64]; \
701             sprintf(buf##proper,"%d",proper); \
702             auto_ptr_XMLCh wide##proper(buf##proper); \
703             set##proper(wide##proper.get()); \
704         }
705
706 /**
707  * Implements get/set methods and a private member for a boolean XML attribute.
708  *
709  * @param proper    the proper name of the attribute
710  */
711 #define IMPL_BOOLEAN_ATTRIB(proper) \
712     protected: \
713         xmlconstants::xmltooling_bool_t m_##proper; \
714     public: \
715         xmlconstants::xmltooling_bool_t get##proper() const { \
716             return m_##proper; \
717         } \
718         void proper(xmlconstants::xmltooling_bool_t value) { \
719             if (m_##proper != value) { \
720                 releaseThisandParentDOM(); \
721                 m_##proper = value; \
722             } \
723         }
724
725 /**
726  * Implements get/set methods and a private member for a typed, qualified XML attribute.
727  *
728  * @param proper    the proper name of the attribute
729  * @param type      the attribute's data type
730  */
731 #define IMPL_XMLOBJECT_FOREIGN_ATTRIB(proper,type) \
732     protected: \
733     XMLCh* m_##proper##Prefix; \
734         type* m_##proper; \
735     public: \
736         const type* get##proper() const { \
737             return m_##proper; \
738         } \
739         void set##proper(const type* proper) { \
740             m_##proper = prepareForAssignment(m_##proper,proper); \
741             XMLString::release(&m_##proper##Prefix); \
742             m_##proper##Prefix = nullptr; \
743         }
744
745 /**
746  * Declares abstract set method for a typed XML child object in a foreign namespace.
747  * The get method is omitted.
748  *
749  * @param proper    the proper name of the child type
750  * @param ns        the C++ namespace for the type
751  */
752 #define DECL_INHERITED_TYPED_FOREIGN_CHILD(proper,ns) \
753     public: \
754         XMLTOOLING_DOXYGEN(Sets the proper child.) \
755         virtual void set##proper(ns::proper* child)=0
756
757 /**
758  * Declares abstract get/set methods for a typed XML child object in a foreign namespace.
759  *
760  * @param proper    the proper name of the child type
761  * @param ns        the C++ namespace for the type
762  */
763 #define DECL_TYPED_FOREIGN_CHILD(proper,ns) \
764     public: \
765         XMLTOOLING_DOXYGEN(Returns the proper child.) \
766         virtual ns::proper* get##proper() const=0; \
767         XMLTOOLING_DOXYGEN(Sets the proper child.) \
768         virtual void set##proper(ns::proper* child)=0
769
770 /**
771  * Declares abstract set method for a typed XML child object.
772  * The get method is omitted.
773  *
774  * @param proper    the proper name of the child type
775  */
776 #define DECL_INHERITED_TYPED_CHILD(proper) \
777     public: \
778         XMLTOOLING_DOXYGEN(Sets the proper child.) \
779         virtual void set##proper(proper* child)=0
780
781 /**
782  * Declares abstract get/set methods for a typed XML child object.
783  *
784  * @param proper    the proper name of the child type
785  */
786 #define DECL_TYPED_CHILD(proper) \
787     public: \
788         XMLTOOLING_DOXYGEN(Returns the proper child.) \
789         virtual proper* get##proper() const=0; \
790         XMLTOOLING_DOXYGEN(Sets the proper child.) \
791         virtual void set##proper(proper* child)=0
792
793 /**
794  * Declares abstract get/set methods for a generic XML child object.
795  *
796  * @param proper    the proper name of the child
797  */
798 #define DECL_XMLOBJECT_CHILD(proper) \
799     public: \
800         XMLTOOLING_DOXYGEN(Returns the proper child.) \
801         virtual xmltooling::XMLObject* get##proper() const=0; \
802         XMLTOOLING_DOXYGEN(Sets the proper child.) \
803         virtual void set##proper(xmltooling::XMLObject* child)=0
804
805
806 /**
807  * Implements get/set methods and a private list iterator member for a typed XML child object.
808  *
809  * @param proper    the proper name of the child type
810  */
811 #define IMPL_TYPED_CHILD(proper) \
812     protected: \
813         proper* m_##proper; \
814         std::list<xmltooling::XMLObject*>::iterator m_pos_##proper; \
815     public: \
816         proper* get##proper() const { \
817             return m_##proper; \
818         } \
819         void set##proper(proper* child) { \
820             prepareForAssignment(m_##proper,child); \
821             *m_pos_##proper = m_##proper = child; \
822         }
823
824 /**
825  * Implements get/set methods and a private list iterator member for
826  * a typed XML child object in a foreign namespace
827  *
828  * @param proper    the proper name of the child type
829  * @param ns        the C++ namespace for the type
830  */
831 #define IMPL_TYPED_FOREIGN_CHILD(proper,ns) \
832     protected: \
833         ns::proper* m_##proper; \
834         std::list<xmltooling::XMLObject*>::iterator m_pos_##proper; \
835     public: \
836         ns::proper* get##proper() const { \
837             return m_##proper; \
838         } \
839         void set##proper(ns::proper* child) { \
840             prepareForAssignment(m_##proper,child); \
841             *m_pos_##proper = m_##proper = child; \
842         }
843
844 /**
845  * Implements get/set methods and a private list iterator member for a generic XML child object.
846  *
847  * @param proper    the proper name of the child
848  */
849 #define IMPL_XMLOBJECT_CHILD(proper) \
850     protected: \
851         xmltooling::XMLObject* m_##proper; \
852         std::list<xmltooling::XMLObject*>::iterator m_pos_##proper; \
853     public: \
854         xmltooling::XMLObject* get##proper() const { \
855             return m_##proper; \
856         } \
857         void set##proper(xmltooling::XMLObject* child) { \
858             prepareForAssignment(m_##proper,child); \
859             *m_pos_##proper = m_##proper = child; \
860         }
861
862 /**
863  * Declares abstract get/set methods for a typed XML child collection.
864  *
865  * @param proper    the proper name of the child type
866  */
867 #define DECL_TYPED_CHILDREN(proper) \
868     public: \
869         XMLTOOLING_DOXYGEN(Returns modifiable proper collection.) \
870         virtual VectorOf(proper) get##proper##s()=0; \
871         XMLTOOLING_DOXYGEN(Returns reference to immutable proper collection.) \
872         virtual const std::vector<proper*>& get##proper##s() const=0
873
874 /**
875  * Declares abstract get/set methods for a typed XML child collection in a foreign namespace.
876  *
877  * @param proper    the proper name of the child type
878  * @param ns        the C++ namespace for the type
879  */
880 #define DECL_TYPED_FOREIGN_CHILDREN(proper,ns) \
881     public: \
882         XMLTOOLING_DOXYGEN(Returns modifiable proper collection.) \
883         virtual VectorOf(ns::proper) get##proper##s()=0; \
884         XMLTOOLING_DOXYGEN(Returns reference to immutable proper collection.) \
885         virtual const std::vector<ns::proper*>& get##proper##s() const=0
886
887 /**
888  * Declares abstract get/set methods for a generic XML child collection.
889  *
890  * @param proper    the proper name of the child
891  */
892 #define DECL_XMLOBJECT_CHILDREN(proper) \
893     public: \
894         XMLTOOLING_DOXYGEN(Returns modifiable proper collection.) \
895         virtual VectorOf(xmltooling::XMLObject) get##proper##s()=0; \
896         XMLTOOLING_DOXYGEN(Returns reference to immutable proper collection.) \
897         virtual const std::vector<xmltooling::XMLObject*>& get##proper##s() const=0
898
899 /**
900  * Implements get method and a private vector member for a typed XML child collection.
901  *
902  * @param proper    the proper name of the child type
903  * @param fence     insertion fence for new objects of the child collection in backing list
904  */
905 #define IMPL_TYPED_CHILDREN(proper,fence) \
906     protected: \
907         std::vector<proper*> m_##proper##s; \
908     public: \
909         VectorOf(proper) get##proper##s() { \
910             return VectorOf(proper)(this, m_##proper##s, &m_children, fence); \
911         } \
912         const std::vector<proper*>& get##proper##s() const { \
913             return m_##proper##s; \
914         }
915
916 /**
917  * Implements get method and a private vector member for a typed XML child collection
918  * in a foreign namespace.
919  *
920  * @param proper    the proper name of the child type
921  * @param ns        the C++ namespace for the type
922  * @param fence     insertion fence for new objects of the child collection in backing list
923  */
924 #define IMPL_TYPED_FOREIGN_CHILDREN(proper,ns,fence) \
925     protected: \
926         std::vector<ns::proper*> m_##proper##s; \
927     public: \
928         VectorOf(ns::proper) get##proper##s() { \
929             return VectorOf(ns::proper)(this, m_##proper##s, &m_children, fence); \
930         } \
931         const std::vector<ns::proper*>& get##proper##s() const { \
932             return m_##proper##s; \
933         }
934
935 /**
936  * Implements get method and a private vector member for a generic XML child collection.
937  *
938  * @param proper    the proper name of the child
939  * @param fence     insertion fence for new objects of the child collection in backing list
940  */
941 #define IMPL_XMLOBJECT_CHILDREN(proper,fence) \
942     protected: \
943         std::vector<xmltooling::XMLObject*> m_##proper##s; \
944     public: \
945         VectorOf(xmltooling::XMLObject) get##proper##s() { \
946             return VectorOf(xmltooling::XMLObject)(this, m_##proper##s, &m_children, fence); \
947         } \
948         const std::vector<xmltooling::XMLObject*>& get##proper##s() const { \
949             return m_##proper##s; \
950         }
951
952 /**
953  * Implements marshalling for a string attribute
954  *
955  * @param proper        the proper name of the attribute
956  * @param ucase         the upcased name of the attribute
957  * @param namespaceURI  the XML namespace of the attribute
958  */
959 #define MARSHALL_STRING_ATTRIB(proper,ucase,namespaceURI) \
960     if (m_##proper && *m_##proper) { \
961         domElement->setAttributeNS(namespaceURI, ucase##_ATTRIB_NAME, m_##proper); \
962     }
963
964 /**
965  * Implements marshalling for a DateTime attribute
966  *
967  * @param proper        the proper name of the attribute
968  * @param ucase         the upcased name of the attribute
969  * @param namespaceURI  the XML namespace of the attribute
970  */
971 #define MARSHALL_DATETIME_ATTRIB(proper,ucase,namespaceURI) \
972     if (m_##proper) { \
973         domElement->setAttributeNS(namespaceURI, ucase##_ATTRIB_NAME, m_##proper->getRawData()); \
974     }
975
976 /**
977  * Implements marshalling for an integer attribute
978  *
979  * @param proper        the proper name of the attribute
980  * @param ucase         the upcased name of the attribute
981  * @param namespaceURI  the XML namespace of the attribute
982  */
983 #define MARSHALL_INTEGER_ATTRIB(proper,ucase,namespaceURI) \
984     if (m_##proper && *m_##proper) { \
985         domElement->setAttributeNS(namespaceURI, ucase##_ATTRIB_NAME, m_##proper); \
986     }
987
988 /**
989  * Implements marshalling for a boolean attribute
990  *
991  * @param proper        the proper name of the attribute
992  * @param ucase         the upcased name of the attribute
993  * @param namespaceURI  the XML namespace of the attribute
994  */
995 #define MARSHALL_BOOLEAN_ATTRIB(proper,ucase,namespaceURI) \
996     switch (m_##proper) { \
997         case xmlconstants::XML_BOOL_TRUE: \
998             domElement->setAttributeNS(namespaceURI, ucase##_ATTRIB_NAME, xmlconstants::XML_TRUE); \
999             break; \
1000         case xmlconstants::XML_BOOL_ONE: \
1001             domElement->setAttributeNS(namespaceURI, ucase##_ATTRIB_NAME, xmlconstants::XML_ONE); \
1002             break; \
1003         case xmlconstants::XML_BOOL_FALSE: \
1004             domElement->setAttributeNS(namespaceURI, ucase##_ATTRIB_NAME, xmlconstants::XML_FALSE); \
1005             break; \
1006         case xmlconstants::XML_BOOL_ZERO: \
1007             domElement->setAttributeNS(namespaceURI, ucase##_ATTRIB_NAME, xmlconstants::XML_ZERO); \
1008             break; \
1009         case xmlconstants::XML_BOOL_NULL: \
1010             break; \
1011     }
1012
1013 /**
1014  * Implements marshalling for a QName attribute
1015  *
1016  * @param proper        the proper name of the attribute
1017  * @param ucase         the upcased name of the attribute
1018  * @param namespaceURI  the XML namespace of the attribute
1019  */
1020 #define MARSHALL_QNAME_ATTRIB(proper,ucase,namespaceURI) \
1021     if (m_##proper) { \
1022         auto_ptr_XMLCh qstr(m_##proper->toString().c_str()); \
1023         domElement->setAttributeNS(namespaceURI, ucase##_ATTRIB_NAME, qstr.get()); \
1024     }
1025
1026 #ifdef XMLTOOLING_XERCESC_BOOLSETIDATTRIBUTE
1027 /**
1028  * Implements marshalling for an ID attribute
1029  *
1030  * @param proper        the proper name of the attribute
1031  * @param ucase         the upcased name of the attribute
1032  * @param namespaceURI  the XML namespace of the attribute
1033  */
1034 # define MARSHALL_ID_ATTRIB(proper,ucase,namespaceURI) \
1035     if (m_##proper && *m_##proper) { \
1036         domElement->setAttributeNS(namespaceURI, ucase##_ATTRIB_NAME, m_##proper); \
1037         domElement->setIdAttributeNS(namespaceURI, ucase##_ATTRIB_NAME, true); \
1038     }
1039 #else
1040 /**
1041  * Implements marshalling for an ID attribute
1042  *
1043  * @param proper        the proper name of the attribute
1044  * @param ucase         the upcased name of the attribute
1045  * @param namespaceURI  the XML namespace of the attribute
1046  */
1047 # define MARSHALL_ID_ATTRIB(proper,ucase,namespaceURI) \
1048     if (m_##proper && *m_##proper) { \
1049         domElement->setAttributeNS(namespaceURI, ucase##_ATTRIB_NAME, m_##proper); \
1050         domElement->setIdAttributeNS(namespaceURI, ucase##_ATTRIB_NAME); \
1051     }
1052 #endif
1053
1054 /**
1055  * Implements unmarshalling process branch for a string attribute
1056  *
1057  * @param proper        the proper name of the attribute
1058  * @param ucase         the upcased name of the attribute
1059  * @param namespaceURI  the XML namespace of the attribute
1060  */
1061 #define PROC_STRING_ATTRIB(proper,ucase,namespaceURI) \
1062     if (xmltooling::XMLHelper::isNodeNamed(attribute, namespaceURI, ucase##_ATTRIB_NAME)) { \
1063         set##proper(attribute->getValue()); \
1064         return; \
1065     }
1066
1067 #ifdef XMLTOOLING_XERCESC_BOOLSETIDATTRIBUTE
1068 /**
1069  * Implements unmarshalling process branch for an ID attribute
1070  *
1071  * @param proper        the proper name of the attribute
1072  * @param ucase         the upcased name of the attribute
1073  * @param namespaceURI  the XML namespace of the attribute
1074  */
1075 # define PROC_ID_ATTRIB(proper,ucase,namespaceURI) \
1076     if (xmltooling::XMLHelper::isNodeNamed(attribute, namespaceURI, ucase##_ATTRIB_NAME)) { \
1077         set##proper(attribute->getValue()); \
1078         attribute->getOwnerElement()->setIdAttributeNode(attribute, true); \
1079         return; \
1080     }
1081 #else
1082 /**
1083  * Implements unmarshalling process branch for an ID attribute
1084  *
1085  * @param proper        the proper name of the attribute
1086  * @param ucase         the upcased name of the attribute
1087  * @param namespaceURI  the XML namespace of the attribute
1088  */
1089 # define PROC_ID_ATTRIB(proper,ucase,namespaceURI) \
1090     if (xmltooling::XMLHelper::isNodeNamed(attribute, namespaceURI, ucase##_ATTRIB_NAME)) { \
1091         set##proper(attribute->getValue()); \
1092         attribute->getOwnerElement()->setIdAttributeNode(attribute); \
1093         return; \
1094     }
1095 #endif
1096
1097 /**
1098  * Implements unmarshalling process branch for a DateTime attribute
1099  *
1100  * @param proper        the proper name of the attribute
1101  * @param ucase         the upcased name of the attribute
1102  * @param namespaceURI  the XML namespace of the attribute
1103  */
1104 #define PROC_DATETIME_ATTRIB(proper,ucase,namespaceURI) \
1105     PROC_STRING_ATTRIB(proper,ucase,namespaceURI)
1106
1107 /**
1108  * Implements unmarshalling process branch for a DateTime attribute
1109  *
1110  * @param proper        the proper name of the attribute
1111  * @param ucase         the upcased name of the attribute
1112  * @param namespaceURI  the XML namespace of the attribute
1113  */
1114 #define PROC_QNAME_ATTRIB(proper,ucase,namespaceURI) \
1115     if (xmltooling::XMLHelper::isNodeNamed(attribute, namespaceURI, ucase##_ATTRIB_NAME)) { \
1116         set##proper(XMLHelper::getAttributeValueAsQName(attribute)); \
1117         return; \
1118     }
1119
1120 /**
1121  * Implements unmarshalling process branch for an integer attribute
1122  *
1123  * @param proper        the proper name of the attribute
1124  * @param ucase         the upcased name of the attribute
1125  * @param namespaceURI  the XML namespace of the attribute
1126  */
1127 #define PROC_INTEGER_ATTRIB(proper,ucase,namespaceURI) \
1128     PROC_STRING_ATTRIB(proper,ucase,namespaceURI)
1129
1130 /**
1131  * Implements unmarshalling process branch for a boolean attribute
1132  *
1133  * @param proper        the proper name of the attribute
1134  * @param ucase         the upcased name of the attribute
1135  * @param namespaceURI  the XML namespace of the attribute
1136  */
1137 #define PROC_BOOLEAN_ATTRIB(proper,ucase,namespaceURI) \
1138     PROC_STRING_ATTRIB(proper,ucase,namespaceURI)
1139
1140 /**
1141  * Implements unmarshalling process branch for typed child collection element
1142  *
1143  * @param proper        the proper name of the child type
1144  * @param namespaceURI  the XML namespace of the child element
1145  * @param force         bypass use of hint and just cast down to check child
1146  */
1147 #define PROC_TYPED_CHILDREN(proper,namespaceURI,force) \
1148     if (force || xmltooling::XMLHelper::isNodeNamed(root,namespaceURI,proper::LOCAL_NAME)) { \
1149         proper* typesafe=dynamic_cast<proper*>(childXMLObject); \
1150         if (typesafe) { \
1151             get##proper##s().push_back(typesafe); \
1152             return; \
1153         } \
1154     }
1155
1156 /**
1157  * Implements unmarshalling process branch for typed child collection element
1158  * in a foreign namespace.
1159  *
1160  * @param proper        the proper name of the child type
1161  * @param ns            the C++ namespace for the type
1162  * @param namespaceURI  the XML namespace of the child element
1163  * @param force         bypass use of hint and just cast down to check child
1164  */
1165 #define PROC_TYPED_FOREIGN_CHILDREN(proper,ns,namespaceURI,force) \
1166     if (force || xmltooling::XMLHelper::isNodeNamed(root,namespaceURI,ns::proper::LOCAL_NAME)) { \
1167         ns::proper* typesafe=dynamic_cast<ns::proper*>(childXMLObject); \
1168         if (typesafe) { \
1169             get##proper##s().push_back(typesafe); \
1170             return; \
1171         } \
1172     }
1173
1174 /**
1175  * Implements unmarshalling process branch for typed child singleton element
1176  *
1177  * @param proper        the proper name of the child type
1178  * @param namespaceURI  the XML namespace of the child element
1179  * @param force         bypass use of hint and just cast down to check child
1180  */
1181 #define PROC_TYPED_CHILD(proper,namespaceURI,force) \
1182     if (force || xmltooling::XMLHelper::isNodeNamed(root,namespaceURI,proper::LOCAL_NAME)) { \
1183         proper* typesafe=dynamic_cast<proper*>(childXMLObject); \
1184         if (typesafe && !m_##proper) { \
1185             typesafe->setParent(this); \
1186             *m_pos_##proper = m_##proper = typesafe; \
1187             return; \
1188         } \
1189     }
1190
1191 /**
1192  * Implements unmarshalling process branch for typed child singleton element
1193  * in a foreign namespace.
1194  *
1195  * @param proper        the proper name of the child type
1196  * @param ns            the C++ namespace for the type
1197  * @param namespaceURI  the XML namespace of the child element
1198  * @param force         bypass use of hint and just cast down to check child
1199  */
1200 #define PROC_TYPED_FOREIGN_CHILD(proper,ns,namespaceURI,force) \
1201     if (force || xmltooling::XMLHelper::isNodeNamed(root,namespaceURI,ns::proper::LOCAL_NAME)) { \
1202         ns::proper* typesafe=dynamic_cast<ns::proper*>(childXMLObject); \
1203         if (typesafe && !m_##proper) { \
1204             typesafe->setParent(this); \
1205             *m_pos_##proper = m_##proper = typesafe; \
1206             return; \
1207         } \
1208     }
1209
1210 /**
1211  * Implements unmarshalling process branch for a generic child singleton element
1212  *
1213  * @param proper        the proper name of the child type
1214  * @param namespaceURI  the XML namespace of the child element
1215  */
1216 #define PROC_XMLOBJECT_CHILD(proper,namespaceURI) \
1217     if (xmltooling::XMLHelper::isNodeNamed(root,namespaceURI,proper::LOCAL_NAME)) { \
1218         if (!m_##proper) { \
1219             childXMLObject->setParent(this); \
1220             *m_pos_##proper = m_##proper = childXMLObject; \
1221             return; \
1222         } \
1223     }
1224
1225 /**
1226  * Declares aliased get/set methods for named XML element simple content.
1227  *
1228  * @param proper    the proper name to label the element's content
1229  */
1230 #define DECL_SIMPLE_CONTENT(proper) \
1231     XMLTOOLING_DOXYGEN(Returns proper.) \
1232     const XMLCh* get##proper() const { \
1233         return getTextContent(); \
1234     } \
1235     XMLTOOLING_DOXYGEN(Sets or clears proper.) \
1236     void set##proper(const XMLCh* proper) { \
1237         setTextContent(proper); \
1238     }
1239
1240 /**
1241  * Declares aliased get/set methods for named integer XML element content.
1242  *
1243  * @param proper    the proper name to label the element's content
1244  */
1245 #define DECL_INTEGER_CONTENT(proper) \
1246     XMLTOOLING_DOXYGEN(Returns proper in integer form after a NULL indicator.) \
1247     std::pair<bool,int> get##proper() const { \
1248         return std::make_pair((getTextContent()!=nullptr), (getTextContent()!=nullptr ? xercesc::XMLString::parseInt(getTextContent()) : 0)); \
1249     } \
1250     XMLTOOLING_DOXYGEN(Sets proper.) \
1251     void set##proper(int proper) { \
1252         char buf[64]; \
1253         sprintf(buf,"%d",proper); \
1254         xmltooling::auto_ptr_XMLCh widebuf(buf); \
1255         setTextContent(widebuf.get()); \
1256     } \
1257     XMLTOOLING_DOXYGEN(Sets or clears proper.) \
1258     void set##proper(const XMLCh* proper) { \
1259         setTextContent(proper); \
1260     }
1261
1262 /**
1263  * Implements cloning methods for an XMLObject specialization implementation class.
1264  *
1265  * @param cname    the name of the XMLObject specialization
1266  */
1267 #define IMPL_XMLOBJECT_CLONE(cname) \
1268     cname* clone##cname() const { \
1269         return dynamic_cast<cname*>(clone()); \
1270     } \
1271     xmltooling::XMLObject* clone() const { \
1272         std::auto_ptr<xmltooling::XMLObject> domClone(xmltooling::AbstractDOMCachingXMLObject::clone()); \
1273         cname##Impl* ret=dynamic_cast<cname##Impl*>(domClone.get()); \
1274         if (ret) { \
1275             domClone.release(); \
1276             return ret; \
1277         } \
1278         return new cname##Impl(*this); \
1279     }
1280
1281 /**
1282  * Declares an XMLObject specialization with a simple content model and type,
1283  * handling it as string data.
1284  *
1285  * @param linkage   linkage specifier for the class
1286  * @param cname     the name of the XMLObject specialization
1287  * @param proper    the proper name to label the element's content
1288  * @param desc      documentation for class
1289  */
1290 #define DECL_XMLOBJECT_SIMPLE(linkage,cname,proper,desc) \
1291     BEGIN_XMLOBJECT(linkage,cname,xmltooling::XMLObject,desc); \
1292         DECL_SIMPLE_CONTENT(proper); \
1293     END_XMLOBJECT
1294
1295 /**
1296  * Declares and defines an implementation class for an XMLObject with
1297  * a simple content model and type, handling it as string data.
1298  *
1299  * @param linkage   linkage specifier for the class
1300  * @param cname     the name of the XMLObject specialization
1301  */
1302 #define DECL_XMLOBJECTIMPL_SIMPLE(linkage,cname) \
1303     class linkage cname##Impl \
1304         : public virtual cname, \
1305             public xmltooling::AbstractSimpleElement, \
1306             public xmltooling::AbstractDOMCachingXMLObject, \
1307             public xmltooling::AbstractXMLObjectMarshaller, \
1308             public xmltooling::AbstractXMLObjectUnmarshaller \
1309     { \
1310     public: \
1311         virtual ~cname##Impl() {} \
1312         cname##Impl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType) \
1313             : xmltooling::AbstractXMLObject(nsURI, localName, prefix, schemaType) { \
1314         } \
1315         cname##Impl(const cname##Impl& src) \
1316             : xmltooling::AbstractXMLObject(src), \
1317                 xmltooling::AbstractSimpleElement(src), \
1318                 xmltooling::AbstractDOMCachingXMLObject(src) {} \
1319         IMPL_XMLOBJECT_CLONE(cname) \
1320     }
1321
1322 #ifdef HAVE_COVARIANT_RETURNS
1323
1324 /**
1325  * Begins the declaration of an XMLObjectBuilder specialization.
1326  * Basic boilerplate includes an empty virtual destructor, and
1327  * a default builder that defaults the element name.
1328  *
1329  * @param linkage           linkage specifier for the class
1330  * @param cname             the name of the XMLObject specialization
1331  * @param namespaceURI      the XML namespace of the default associated element
1332  * @param namespacePrefix   the XML namespace prefix of the default associated element
1333  */
1334 #define BEGIN_XMLOBJECTBUILDER(linkage,cname,namespaceURI,namespacePrefix) \
1335     XMLTOOLING_DOXYGEN(Builder for cname objects.) \
1336     class linkage cname##Builder : public xmltooling::ConcreteXMLObjectBuilder { \
1337     public: \
1338         virtual ~cname##Builder() {} \
1339         XMLTOOLING_DOXYGEN(Default builder.) \
1340         virtual cname* buildObject() const { \
1341             return buildObject(namespaceURI,cname::LOCAL_NAME,namespacePrefix); \
1342         } \
1343         XMLTOOLING_DOXYGEN(Builder that allows element/type override.) \
1344         virtual cname* buildObject( \
1345             const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix=nullptr, const xmltooling::QName* schemaType=nullptr \
1346             ) const
1347
1348 /**
1349  * Ends the declaration of an XMLObjectBuilder specialization.
1350  */
1351 #define END_XMLOBJECTBUILDER }
1352
1353 /**
1354  * Declares a generic XMLObjectBuilder specialization.
1355  *
1356  * @param linkage           linkage specifier for the class
1357  * @param cname             the name of the XMLObject specialization
1358  * @param namespaceURI      the XML namespace of the default associated element
1359  * @param namespacePrefix   the XML namespace prefix of the default associated element
1360  */
1361  #define DECL_XMLOBJECTBUILDER(linkage,cname,namespaceURI,namespacePrefix) \
1362     BEGIN_XMLOBJECTBUILDER(linkage,cname,namespaceURI,namespacePrefix); \
1363     XMLTOOLING_DOXYGEN(Singleton builder.) \
1364     static cname* build##cname() { \
1365         const cname##Builder* b = dynamic_cast<const cname##Builder*>( \
1366             XMLObjectBuilder::getBuilder(xmltooling::QName(namespaceURI,cname::LOCAL_NAME)) \
1367             ); \
1368         if (b) \
1369             return b->buildObject(); \
1370         throw xmltooling::XMLObjectException("Unable to obtain typed builder for "#cname"."); \
1371     } \
1372     END_XMLOBJECTBUILDER
1373
1374 /**
1375  * Implements the standard XMLObjectBuilder specialization function.
1376  *
1377  * @param cname the name of the XMLObject specialization
1378  */
1379 #define IMPL_XMLOBJECTBUILDER(cname) \
1380     cname* cname##Builder::buildObject( \
1381         const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType \
1382         ) const \
1383     { \
1384         return new cname##Impl(nsURI,localName,prefix,schemaType); \
1385     }
1386
1387 #else   /* !HAVE_COVARIANT_RETURNS */
1388
1389 /**
1390  * Begins the declaration of an XMLObjectBuilder specialization.
1391  * Basic boilerplate includes an empty virtual destructor, and
1392  * a default builder that defaults the element name.
1393  *
1394  * @param linkage           linkage specifier for the class
1395  * @param cname             the name of the XMLObject specialization
1396  * @param namespaceURI      the XML namespace of the default associated element
1397  * @param namespacePrefix   the XML namespace prefix of the default associated element
1398  */
1399 #define BEGIN_XMLOBJECTBUILDER(linkage,cname,namespaceURI,namespacePrefix) \
1400     XMLTOOLING_DOXYGEN(Builder for cname objects.) \
1401     class linkage cname##Builder : public xmltooling::ConcreteXMLObjectBuilder { \
1402     public: \
1403         virtual ~cname##Builder() {} \
1404         XMLTOOLING_DOXYGEN(Default builder.) \
1405         virtual xmltooling::XMLObject* buildObject() const { \
1406             return buildObject(namespaceURI,cname::LOCAL_NAME,namespacePrefix); \
1407         } \
1408         XMLTOOLING_DOXYGEN(Builder that allows element/type override.) \
1409         virtual xmltooling::XMLObject* buildObject( \
1410             const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix=nullptr, const xmltooling::QName* schemaType=nullptr \
1411             ) const
1412
1413 /**
1414  * Ends the declaration of an XMLObjectBuilder specialization.
1415  */
1416 #define END_XMLOBJECTBUILDER }
1417
1418 /**
1419  * Declares a generic XMLObjectBuilder specialization.
1420  *
1421  * @param linkage           linkage specifier for the class
1422  * @param cname             the name of the XMLObject specialization
1423  * @param namespaceURI      the XML namespace of the default associated element
1424  * @param namespacePrefix   the XML namespace prefix of the default associated element
1425  */
1426  #define DECL_XMLOBJECTBUILDER(linkage,cname,namespaceURI,namespacePrefix) \
1427     BEGIN_XMLOBJECTBUILDER(linkage,cname,namespaceURI,namespacePrefix); \
1428     XMLTOOLING_DOXYGEN(Singleton builder.) \
1429     static cname* build##cname() { \
1430         const cname##Builder* b = dynamic_cast<const cname##Builder*>( \
1431             XMLObjectBuilder::getBuilder(xmltooling::QName(namespaceURI,cname::LOCAL_NAME)) \
1432             ); \
1433         if (b) \
1434             return dynamic_cast<cname*>(b->buildObject()); \
1435         throw xmltooling::XMLObjectException("Unable to obtain typed builder for "#cname"."); \
1436     } \
1437     END_XMLOBJECTBUILDER
1438
1439 /**
1440  * Implements the standard XMLObjectBuilder specialization function.
1441  *
1442  * @param cname the name of the XMLObject specialization
1443  */
1444 #define IMPL_XMLOBJECTBUILDER(cname) \
1445     xmltooling::XMLObject* cname##Builder::buildObject( \
1446         const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType \
1447         ) const \
1448     { \
1449         return new cname##Impl(nsURI,localName,prefix,schemaType); \
1450     }
1451
1452 #endif  /* HAVE_COVARIANT_RETURNS */
1453
1454 /**
1455  * Begins the declaration of a Schema Validator specialization.
1456  *
1457  * @param linkage           linkage specifier for the class
1458  * @param cname the base name of the Validator specialization
1459  */
1460  #define BEGIN_XMLOBJECTVALIDATOR(linkage,cname) \
1461     class linkage cname##SchemaValidator : public xmltooling::Validator \
1462     { \
1463     public: \
1464         virtual ~cname##SchemaValidator() {} \
1465         virtual void validate(const xmltooling::XMLObject* xmlObject) const { \
1466             const cname* ptr=dynamic_cast<const cname*>(xmlObject); \
1467             if (!ptr) \
1468                 throw xmltooling::ValidationException(#cname"SchemaValidator: unsupported object type ($1).",xmltooling::params(1,typeid(xmlObject).name())); \
1469             if (ptr->nil() && (ptr->hasChildren() || ptr->getTextContent())) \
1470                 throw xmltooling::ValidationException("Object has nil property but with children or content.")
1471
1472 /**
1473  * Begins the declaration of a Schema Validator specialization subclass.
1474  *
1475  * @param linkage   linkage specifier for the class
1476  * @param cname     the base name of the Validator specialization
1477  * @param base      base class for the validator
1478  */
1479  #define BEGIN_XMLOBJECTVALIDATOR_SUB(linkage,cname,base) \
1480     class linkage cname##SchemaValidator : public base##SchemaValidator \
1481     { \
1482     public: \
1483         virtual ~cname##SchemaValidator() {} \
1484         virtual void validate(const xmltooling::XMLObject* xmlObject) const { \
1485             const cname* ptr=dynamic_cast<const cname*>(xmlObject); \
1486             if (!ptr) \
1487                 throw xmltooling::ValidationException(#cname"SchemaValidator: unsupported object type ($1).",xmltooling::params(1,typeid(xmlObject).name()));
1488
1489 /**
1490  * Ends the declaration of a Validator specialization.
1491  */
1492 #define END_XMLOBJECTVALIDATOR } }
1493
1494 /**
1495  * Validator code that checks the object type.
1496  *
1497  * @param cname     the name of the XMLObject specialization
1498  */
1499 #define XMLOBJECTVALIDATOR_CHECKTYPE(cname) \
1500     const cname* ptr=dynamic_cast<const cname*>(xmlObject); \
1501     if (!ptr) \
1502         throw xmltooling::ValidationException(#cname"SchemaValidator: unsupported object type ($1).",xmltooling::params(1,typeid(xmlObject).name()))
1503
1504 /**
1505  * Validator code that checks for a required attribute, content, or singleton.
1506  *
1507  * @param cname     the name of the XMLObject specialization
1508  * @param proper    the proper name of the attribute, content, or singleton member
1509  */
1510 #define XMLOBJECTVALIDATOR_REQUIRE(cname,proper) \
1511     if (!ptr->get##proper()) \
1512         throw xmltooling::ValidationException(#cname" must have "#proper".")
1513
1514 /**
1515  * Validator code that checks for a required integer attribute
1516  *
1517  * @param cname     the name of the XMLObject specialization
1518  * @param proper    the proper name of the attribute, content, or singleton member
1519  */
1520 #define XMLOBJECTVALIDATOR_REQUIRE_INTEGER(cname,proper) \
1521     if (!ptr->get##proper().first) \
1522         throw xmltooling::ValidationException(#cname" must have "#proper".")
1523
1524 /**
1525  * Validator code that checks for one of a pair of
1526  * required attributes, content, or singletons.
1527  *
1528  * @param cname     the name of the XMLObject specialization
1529  * @param proper1   the proper name of the first attribute, content, or singleton member
1530  * @param proper2   the proper name of the second attribute, content, or singleton member
1531  */
1532 #define XMLOBJECTVALIDATOR_ONEOF(cname,proper1,proper2) \
1533     if (!ptr->get##proper1() && !ptr->get##proper2()) \
1534         throw xmltooling::ValidationException(#cname" must have "#proper1" or "#proper2".")
1535
1536 /**
1537  * Validator code that checks for one of a pair of
1538  * required attributes, content, or singletons, but disallows both.
1539  *
1540  * @param cname     the name of the XMLObject specialization
1541  * @param proper1   the proper name of the first attribute, content, or singleton member
1542  * @param proper2   the proper name of the second attribute, content, or singleton member
1543  */
1544 #define XMLOBJECTVALIDATOR_ONLYONEOF(cname,proper1,proper2) \
1545     if ((!ptr->get##proper1() && !ptr->get##proper2()) || (ptr->get##proper1() && ptr->get##proper2())) \
1546         throw xmltooling::ValidationException(#cname" must have "#proper1" or "#proper2" but not both.")
1547
1548 /**
1549  * Validator code that checks for one of a set of three
1550  * required attributes, content, or singletons.
1551  *
1552  * @param cname     the name of the XMLObject specialization
1553  * @param proper1   the proper name of the first attribute, content, or singleton member
1554  * @param proper2   the proper name of the second attribute, content, or singleton member
1555  * @param proper3   the proper name of the third attribute, content, or singleton member
1556  */
1557 #define XMLOBJECTVALIDATOR_ONEOF3(cname,proper1,proper2,proper3) \
1558     if (!ptr->get##proper1() && !ptr->get##proper2() && !ptr->get##proper3()) \
1559         throw xmltooling::ValidationException(#cname" must have "#proper1", "#proper2", or "#proper3".")
1560
1561 /**
1562  * Validator code that checks for one of a set of three
1563  * required attributes, content, or singletons but disallows more than one.
1564  *
1565  * @param cname     the name of the XMLObject specialization
1566  * @param proper1   the proper name of the first attribute, content, or singleton member
1567  * @param proper2   the proper name of the second attribute, content, or singleton member
1568  * @param proper3   the proper name of the third attribute, content, or singleton member
1569  */
1570 #define XMLOBJECTVALIDATOR_ONLYONEOF3(cname,proper1,proper2,proper3) \
1571     int c##proper1##proper2##proper3=0; \
1572     if (ptr->get##proper1()!=nullptr) \
1573         c##proper1##proper2##proper3++; \
1574     if (ptr->get##proper2()!=nullptr) \
1575         c##proper1##proper2##proper3++; \
1576     if (ptr->get##proper3()!=nullptr) \
1577         c##proper1##proper2##proper3++; \
1578     if (c##proper1##proper2##proper3 != 1) \
1579         throw xmltooling::ValidationException(#cname" must have only one of "#proper1", "#proper2", or "#proper3".")
1580
1581 /**
1582  * Validator code that checks a co-constraint (if one present, the other must be)
1583  * between a pair of attributes, content, or singletons.
1584  *
1585  * @param cname     the name of the XMLObject specialization
1586  * @param proper1   the proper name of the first attribute, content, or singleton member
1587  * @param proper2   the proper name of the second attribute, content, or singleton member
1588  */
1589 #define XMLOBJECTVALIDATOR_NONEORBOTH(cname,proper1,proper2) \
1590     if ((ptr->get##proper1() && !ptr->get##proper2()) || (!ptr->get##proper1() && ptr->get##proper2())) \
1591         throw xmltooling::ValidationException(#cname" cannot have "#proper1" without "#proper2".")
1592
1593 /**
1594  * Validator code that checks for a non-empty collection.
1595  *
1596  * @param cname     the name of the XMLObject specialization
1597  * @param proper    the proper name of the collection item
1598  */
1599 #define XMLOBJECTVALIDATOR_NONEMPTY(cname,proper) \
1600     if (ptr->get##proper##s().empty()) \
1601         throw xmltooling::ValidationException(#cname" must have at least one "#proper".")
1602
1603 /**
1604  * Declares/defines a Validator specialization that checks object type and
1605  * a non-empty simple content model.
1606  *
1607  * @param linkage   linkage specifier for the class
1608  * @param cname     the name of the XMLObject specialization
1609  */
1610 #define XMLOBJECTVALIDATOR_SIMPLE(linkage,cname) \
1611     BEGIN_XMLOBJECTVALIDATOR(linkage,cname); \
1612         XMLOBJECTVALIDATOR_REQUIRE(cname,TextContent); \
1613     END_XMLOBJECTVALIDATOR
1614
1615 #include <utility>
1616
1617 /**
1618  * @namespace xmltooling
1619  * Public namespace of XML Tooling library
1620  */
1621 namespace xmltooling {
1622
1623     /**
1624      * Template function for cloning a sequence of XMLObjects.
1625      * Invokes the clone() member on each element of the input sequence and adds the copy to
1626      * the output sequence. Order is preserved.
1627      *
1628      * @param in    input sequence to clone
1629      * @param out   output sequence to copy cloned pointers into
1630      */
1631     template<class InputSequence,class OutputSequence> void clone(const InputSequence& in, OutputSequence& out) {
1632         for (typename InputSequence::const_iterator i=in.begin(); i!=in.end(); i++) {
1633             if (*i)
1634                 out.push_back((*i)->clone());
1635             else
1636                 out.push_back(*i);
1637         }
1638     }
1639
1640     /**
1641      * Functor for cleaning up heap objects in containers.
1642      */
1643     template<class T> struct cleanup
1644     {
1645         /**
1646          * Function operator to delete an object.
1647          *
1648          * @param ptr   object to delete
1649          */
1650         void operator()(T* ptr) {delete ptr;}
1651
1652         /**
1653          * Function operator to delete an object stored as const.
1654          *
1655          * @param ptr   object to delete after casting away const
1656          */
1657         void operator()(const T* ptr) {delete const_cast<T*>(ptr);}
1658     };
1659
1660     /**
1661      * Functor for cleaning up heap objects in key/value containers.
1662      */
1663     template<class A,class B> struct cleanup_pair
1664     {
1665         /**
1666          * Function operator to delete an object.
1667          *
1668          * @param p   a pair in which the second component is the object to delete
1669          */
1670         void operator()(const std::pair<const A,B*>& p) {delete p.second;}
1671     };
1672
1673     /**
1674      * Functor for cleaning up const heap objects in key/value containers.
1675      */
1676     template<class A,class B> struct cleanup_const_pair
1677     {
1678         /**
1679          * Function operator to delete an object stored as const
1680          *
1681          * @param p   a pair in which the second component is the const object to delete
1682          */
1683         void operator()(const std::pair<const A,const B*>& p) {delete const_cast<B*>(p.second);}
1684     };
1685 };
1686
1687 #endif /* __xmltooling_base_h__ */