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