Added epoch caching for DateTime attributes.
[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, public virtual xmltooling::ValidatingXMLObject { \
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, public virtual xmltooling::ValidatingXMLObject { \
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         public virtual xmltooling::ValidatingXMLObject { \
281     protected: \
282         cname() {} \
283     public: \
284         virtual ~cname() {} \
285         XMLTOOLING_DOXYGEN(Type-specific clone method.) \
286         virtual cname* clone##cname() const=0; \
287         XMLTOOLING_DOXYGEN(Element local name) \
288         static const XMLCh LOCAL_NAME[]
289
290 /**
291  * Begins the declaration of an XMLObject specialization with four base classes.
292  * Basic boilerplate includes a protected constructor, empty virtual destructor,
293  * and Unicode constants for the default associated element's name and prefix.
294  * 
295  * @param linkage   linkage specifier for the class
296  * @param cname     the name of the class to declare
297  * @param base      the first base class to derive from using public virtual inheritance
298  * @param base2     the second base class to derive from using public virtual inheritance
299  * @param base3     the third base class to derive from using public virtual inheritance
300  * @param base4     the fourth base class to derive from using public virtual inheritance
301  * @param desc      documentation comment for class
302  */
303 #define BEGIN_XMLOBJECT4(linkage,cname,base,base2,base3,base4,desc) \
304     XMLTOOLING_DOXYGEN(desc) \
305     class linkage cname : public virtual base, public virtual base2, public virtual base3, \
306         public virtual base4, public virtual xmltooling::ValidatingXMLObject { \
307     protected: \
308         cname() {} \
309     public: \
310         virtual ~cname() {} \
311         XMLTOOLING_DOXYGEN(Type-specific clone method.) \
312         virtual cname* clone##cname() const=0; \
313         XMLTOOLING_DOXYGEN(Element local name) \
314         static const XMLCh LOCAL_NAME[]
315
316 /**
317  * Ends the declaration of an XMLObject specialization.
318  */
319 #define END_XMLOBJECT }
320
321 /**
322  * Declares abstract get/set methods for a typed XML attribute.
323  * 
324  * @param proper    the proper name of the attribute
325  * @param upcased   the upcased name of the attribute
326  * @param type      the attribute's data type
327  */
328 #define DECL_XMLOBJECT_ATTRIB(proper,upcased,type) \
329     public: \
330         XMLTOOLING_DOXYGEN(proper attribute name) \
331         static const XMLCh upcased##_ATTRIB_NAME[]; \
332         XMLTOOLING_DOXYGEN(Returns the proper attribute.) \
333         virtual const type* get##proper() const=0; \
334         XMLTOOLING_DOXYGEN(Sets the proper attribute.) \
335         virtual void set##proper(const type* proper)=0
336
337 /**
338  * Declares abstract get/set methods for a string XML attribute.
339  * 
340  * @param proper    the proper name of the attribute
341  * @param upcased   the upcased name of the attribute
342  */
343 #define DECL_STRING_ATTRIB(proper,upcased) \
344     DECL_XMLOBJECT_ATTRIB(proper,upcased,XMLCh)
345
346 /**
347  * Declares abstract get/set methods for a string XML attribute.
348  * 
349  * @param proper    the proper name of the attribute
350  * @param upcased   the upcased name of the attribute
351  */
352 #define DECL_DATETIME_ATTRIB(proper,upcased) \
353     DECL_XMLOBJECT_ATTRIB(proper,upcased,xmltooling::DateTime); \
354     XMLTOOLING_DOXYGEN(Returns the proper attribute in epoch form.) \
355     virtual time_t get##proper##Epoch() const=0; \
356     XMLTOOLING_DOXYGEN(Sets the proper attribute.) \
357     virtual void set##proper(time_t proper)=0; \
358     XMLTOOLING_DOXYGEN(Sets the proper attribute.) \
359     virtual void set##proper(const XMLCh* proper)=0
360
361 /**
362  * Declares abstract get/set methods for an integer XML attribute.
363  * 
364  * @param proper    the proper name of the attribute
365  * @param upcased   the upcased name of the attribute
366  */
367 #define DECL_INTEGER_ATTRIB(proper,upcased) \
368     public: \
369         XMLTOOLING_DOXYGEN(proper attribute name) \
370         static const XMLCh upcased##_ATTRIB_NAME[]; \
371         XMLTOOLING_DOXYGEN(Returns the proper attribute after a NULL indicator.) \
372         virtual std::pair<bool,int> get##proper() const=0; \
373         XMLTOOLING_DOXYGEN(Sets the proper attribute using a string value.) \
374         virtual void set##proper(const XMLCh* proper)=0; \
375         XMLTOOLING_DOXYGEN(Sets the proper attribute.) \
376         virtual void set##proper(int proper)=0
377
378 /**
379  * Declares abstract get/set methods for a boolean XML attribute.
380  * 
381  * @param proper    the proper name of the attribute
382  * @param upcased   the upcased name of the attribute
383  */
384 #define DECL_BOOLEAN_ATTRIB(proper,upcased) \
385     public: \
386         XMLTOOLING_DOXYGEN(proper attribute name) \
387         static const XMLCh upcased##_ATTRIB_NAME[]; \
388         XMLTOOLING_DOXYGEN(Returns the proper attribute after a NULL indicator.) \
389         virtual std::pair<bool,bool> proper() const=0; \
390         XMLTOOLING_DOXYGEN(Sets the proper attribute using an enumerated value.) \
391         virtual void proper(xmltooling::XMLConstants::xmltooling_bool_t value)=0; \
392         XMLTOOLING_DOXYGEN(Sets the proper attribute.) \
393         void proper(bool value) { \
394             proper(value ? xmltooling::XMLConstants::XML_BOOL_ONE : xmltooling::XMLConstants::XML_BOOL_ZERO); \
395         } \
396         XMLTOOLING_DOXYGEN(Sets the proper attribute using a string constant.) \
397         void set##proper(const XMLCh* value) { \
398             if (value) { \
399                 switch (*value) { \
400                     case chLatin_t: \
401                         proper(xmltooling::XMLConstants::XML_BOOL_TRUE); \
402                         break; \
403                     case chLatin_f: \
404                         proper(xmltooling::XMLConstants::XML_BOOL_FALSE); \
405                         break; \
406                     case chDigit_1: \
407                         proper(xmltooling::XMLConstants::XML_BOOL_ONE); \
408                         break; \
409                     case chDigit_0: \
410                         proper(xmltooling::XMLConstants::XML_BOOL_ZERO); \
411                         break; \
412                     default: \
413                         proper(xmltooling::XMLConstants::XML_BOOL_NULL); \
414                 } \
415             } \
416             else \
417                 proper(xmltooling::XMLConstants::XML_BOOL_NULL); \
418         }
419
420 /**
421  * Implements get/set methods and a private member for a typed XML attribute.
422  * 
423  * @param proper    the proper name of the attribute
424  * @param type      the attribute's data type
425  */
426 #define IMPL_XMLOBJECT_ATTRIB(proper,type) \
427     protected: \
428         type* m_##proper; \
429     public: \
430         const type* get##proper() const { \
431             return m_##proper; \
432         } \
433         void set##proper(const type* proper) { \
434             m_##proper = prepareForAssignment(m_##proper,proper); \
435         }
436
437 /**
438  * Implements get/set methods and a private member for a string XML attribute.
439  * 
440  * @param proper    the proper name of the attribute
441  */
442 #define IMPL_STRING_ATTRIB(proper) \
443     IMPL_XMLOBJECT_ATTRIB(proper,XMLCh)
444
445 /**
446  * Implements get/set methods and a private member for a DateTime XML attribute.
447  * 
448  * @param proper    the proper name of the attribute
449  * @param fallback  epoch to return when attribute is NULL
450  */
451 #define IMPL_DATETIME_ATTRIB(proper,fallback) \
452     protected: \
453         DateTime* m_##proper; \
454         time_t m_##proper##Epoch; \
455     public: \
456         const DateTime* get##proper() const { \
457             return m_##proper; \
458         } \
459         time_t get##proper##Epoch() const { \
460             return m_##proper ? m_##proper##Epoch : fallback; \
461         } \
462         void set##proper(const DateTime* proper) { \
463             m_##proper = prepareForAssignment(m_##proper,proper); \
464             if (m_##proper) \
465                 m_##proper##Epoch=m_##proper->getEpoch(); \
466         } \
467         void set##proper(time_t proper) { \
468             m_##proper = prepareForAssignment(m_##proper,proper); \
469             m_##proper##Epoch = proper; \
470         } \
471         void set##proper(const XMLCh* proper) { \
472             m_##proper = prepareForAssignment(m_##proper,proper); \
473             if (m_##proper) \
474                 m_##proper##Epoch=m_##proper->getEpoch(); \
475         }
476
477 /**
478  * Implements get/set methods and a private member for an integer XML attribute.
479  * 
480  * @param proper    the proper name of the attribute
481  */
482 #define IMPL_INTEGER_ATTRIB(proper) \
483     protected: \
484         XMLCh* m_##proper; \
485     public: \
486         pair<bool,int> get##proper() const { \
487             return make_pair((m_##proper!=NULL),(m_##proper!=NULL ? XMLString::parseInt(m_##proper): NULL)); \
488         } \
489         void set##proper(const XMLCh* proper) { \
490             m_##proper = prepareForAssignment(m_##proper,proper); \
491         } \
492         void set##proper(int proper) { \
493             char buf##proper[64]; \
494             sprintf(buf##proper,"%d",proper); \
495             auto_ptr_XMLCh wide##proper(buf##proper); \
496             set##proper(wide##proper.get()); \
497         }
498
499 /**
500  * Implements get/set methods and a private member for a boolean XML attribute.
501  * 
502  * @param proper    the proper name of the attribute
503  */
504 #define IMPL_BOOLEAN_ATTRIB(proper) \
505     protected: \
506         XMLConstants::xmltooling_bool_t m_##proper; \
507     public: \
508         pair<bool,bool> proper() const { \
509             return make_pair( \
510                 (m_##proper!=XMLConstants::XML_BOOL_NULL), \
511                 (m_##proper==XMLConstants::XML_BOOL_TRUE || m_##proper==XMLConstants::XML_BOOL_ONE) \
512                 ); \
513         } \
514         void proper(XMLConstants::xmltooling_bool_t value) { \
515             if (m_##proper != value) { \
516                 releaseThisandParentDOM(); \
517                 m_##proper = value; \
518             } \
519         }
520
521 /**
522  * Declares abstract get/set methods for a typed XML child object in a foreign namespace.
523  * 
524  * @param proper    the proper name of the child type
525  * @param ns        the C++ namespace for the type
526  */
527 #define DECL_TYPED_FOREIGN_CHILD(proper,ns) \
528     public: \
529         XMLTOOLING_DOXYGEN(Returns the proper child.) \
530         virtual ns::proper* get##proper() const=0; \
531         XMLTOOLING_DOXYGEN(Sets the proper child.) \
532         virtual void set##proper(ns::proper* child)=0
533
534 /**
535  * Declares abstract get/set methods for a typed XML child object.
536  * 
537  * @param proper    the proper name of the child type
538  */
539 #define DECL_TYPED_CHILD(proper) \
540     public: \
541         XMLTOOLING_DOXYGEN(Returns the proper child.) \
542         virtual proper* get##proper() const=0; \
543         XMLTOOLING_DOXYGEN(Sets the proper child.) \
544         virtual void set##proper(proper* child)=0
545
546 /**
547  * Declares abstract get/set methods for a generic XML child object.
548  * 
549  * @param proper    the proper name of the child
550  */
551 #define DECL_XMLOBJECT_CHILD(proper) \
552     public: \
553         XMLTOOLING_DOXYGEN(Returns the proper child.) \
554         virtual xmltooling::XMLObject* get##proper() const=0; \
555         XMLTOOLING_DOXYGEN(Sets the proper child.) \
556         virtual void set##proper(xmltooling::XMLObject* child)=0
557
558
559 /**
560  * Implements get/set methods and a private list iterator member for a typed XML child object.
561  * 
562  * @param proper    the proper name of the child type
563  */
564 #define IMPL_TYPED_CHILD(proper) \
565     protected: \
566         proper* m_##proper; \
567         std::list<xmltooling::XMLObject*>::iterator m_pos_##proper; \
568     public: \
569         proper* get##proper() const { \
570             return m_##proper; \
571         } \
572         void set##proper(proper* child) { \
573             prepareForAssignment(m_##proper,child); \
574             *m_pos_##proper = m_##proper = child; \
575         }
576
577 /**
578  * Implements get/set methods and a private list iterator member for
579  * a typed XML child object in a foreign namespace
580  * 
581  * @param proper    the proper name of the child type
582  * @param ns        the C++ namespace for the type
583  */
584 #define IMPL_TYPED_FOREIGN_CHILD(proper,ns) \
585     protected: \
586         ns::proper* m_##proper; \
587         std::list<xmltooling::XMLObject*>::iterator m_pos_##proper; \
588     public: \
589         ns::proper* get##proper() const { \
590             return m_##proper; \
591         } \
592         void set##proper(ns::proper* child) { \
593             prepareForAssignment(m_##proper,child); \
594             *m_pos_##proper = m_##proper = child; \
595         }
596
597 /**
598  * Implements get/set methods and a private list iterator member for a generic XML child object.
599  * 
600  * @param proper    the proper name of the child
601  */
602 #define IMPL_XMLOBJECT_CHILD(proper) \
603     protected: \
604         xmltooling::XMLObject* m_##proper; \
605         std::list<xmltooling::XMLObject*>::iterator m_pos_##proper; \
606     public: \
607         xmltooling::XMLObject* get##proper() const { \
608             return m_##proper; \
609         } \
610         void set##proper(xmltooling::XMLObject* child) { \
611             prepareForAssignment(m_##proper,child); \
612             *m_pos_##proper = m_##proper = child; \
613         }
614
615 /**
616  * Declares abstract get/set methods for a typed XML child collection.
617  * 
618  * @param proper    the proper name of the child type
619  */
620 #define DECL_TYPED_CHILDREN(proper) \
621     public: \
622         XMLTOOLING_DOXYGEN(Returns modifiable proper collection.) \
623         virtual VectorOf(proper) get##proper##s()=0; \
624         XMLTOOLING_DOXYGEN(Returns reference to immutable proper collection.) \
625         virtual const std::vector<proper*>& get##proper##s() const=0
626
627 /**
628  * Declares abstract get/set methods for a typed XML child collection in a foreign namespace.
629  * 
630  * @param proper    the proper name of the child type
631  * @param ns        the C++ namespace for the type
632  */
633 #define DECL_TYPED_FOREIGN_CHILDREN(proper,ns) \
634     public: \
635         XMLTOOLING_DOXYGEN(Returns modifiable proper collection.) \
636         virtual VectorOf(ns::proper) get##proper##s()=0; \
637         XMLTOOLING_DOXYGEN(Returns reference to immutable proper collection.) \
638         virtual const std::vector<ns::proper*>& get##proper##s() const=0
639
640 /**
641  * Declares abstract get/set methods for a generic XML child collection.
642  * 
643  * @param proper    the proper name of the child
644  */
645 #define DECL_XMLOBJECT_CHILDREN(proper) \
646     public: \
647         XMLTOOLING_DOXYGEN(Returns modifiable proper collection.) \
648         virtual VectorOf(xmltooling::XMLObject) get##proper##s()=0; \
649         XMLTOOLING_DOXYGEN(Returns reference to immutable proper collection.) \
650         virtual const std::vector<xmltooling::XMLObject*>& get##proper##s() const=0
651
652 /**
653  * Implements get method and a private vector member for a typed XML child collection.
654  * 
655  * @param proper    the proper name of the child type
656  * @param fence     insertion fence for new objects of the child collection in backing list
657  */
658 #define IMPL_TYPED_CHILDREN(proper,fence) \
659     protected: \
660         std::vector<proper*> m_##proper##s; \
661     public: \
662         VectorOf(proper) get##proper##s() { \
663             return VectorOf(proper)(this, m_##proper##s, &m_children, fence); \
664         } \
665         const std::vector<proper*>& get##proper##s() const { \
666             return m_##proper##s; \
667         } 
668
669 /**
670  * Implements get method and a private vector member for a typed XML child collection
671  * in a foreign namespace.
672  * 
673  * @param proper    the proper name of the child type
674  * @param ns        the C++ namespace for the type
675  * @param fence     insertion fence for new objects of the child collection in backing list
676  */
677 #define IMPL_TYPED_FOREIGN_CHILDREN(proper,ns,fence) \
678     protected: \
679         std::vector<ns::proper*> m_##proper##s; \
680     public: \
681         VectorOf(ns::proper) get##proper##s() { \
682             return VectorOf(ns::proper)(this, m_##proper##s, &m_children, fence); \
683         } \
684         const std::vector<ns::proper*>& get##proper##s() const { \
685             return m_##proper##s; \
686         } 
687
688 /**
689  * Implements get method and a private vector member for a generic XML child collection.
690  * 
691  * @param proper    the proper name of the child
692  * @param fence     insertion fence for new objects of the child collection in backing list
693  */
694 #define IMPL_XMLOBJECT_CHILDREN(proper,fence) \
695     protected: \
696         std::vector<xmltooling::XMLObject*> m_##proper##s; \
697     public: \
698         VectorOf(xmltooling::XMLObject) get##proper##s() { \
699             return VectorOf(xmltooling::XMLObject)(this, m_##proper##s, &m_children, fence); \
700         } \
701         const std::vector<xmltooling::XMLObject*>& get##proper##s() const { \
702             return m_##proper##s; \
703         } 
704
705 /**
706  * Implements marshalling for a string attribute
707  * 
708  * @param proper        the proper name of the attribute
709  * @param ucase         the upcased name of the attribute
710  * @param namespaceURI  the XML namespace of the attribute
711  */
712 #define MARSHALL_STRING_ATTRIB(proper,ucase,namespaceURI) \
713     if (m_##proper) { \
714         domElement->setAttributeNS(namespaceURI, ucase##_ATTRIB_NAME, m_##proper); \
715     }
716
717 /**
718  * Implements marshalling for a DateTime attribute
719  * 
720  * @param proper        the proper name of the attribute
721  * @param ucase         the upcased name of the attribute
722  * @param namespaceURI  the XML namespace of the attribute
723  */
724 #define MARSHALL_DATETIME_ATTRIB(proper,ucase,namespaceURI) \
725     if (m_##proper) { \
726         domElement->setAttributeNS(namespaceURI, ucase##_ATTRIB_NAME, m_##proper->getRawData()); \
727     }
728
729 /**
730  * Implements marshalling for an integer attribute
731  * 
732  * @param proper        the proper name of the attribute
733  * @param ucase         the upcased name of the attribute
734  * @param namespaceURI  the XML namespace of the attribute
735  */
736 #define MARSHALL_INTEGER_ATTRIB(proper,ucase,namespaceURI) \
737     if (m_##proper) { \
738         domElement->setAttributeNS(namespaceURI, ucase##_ATTRIB_NAME, m_##proper); \
739     }
740
741 /**
742  * Implements marshalling for a boolean attribute
743  * 
744  * @param proper        the proper name of the attribute
745  * @param ucase         the upcased name of the attribute
746  * @param namespaceURI  the XML namespace of the attribute
747  */
748 #define MARSHALL_BOOLEAN_ATTRIB(proper,ucase,namespaceURI) \
749     switch (m_##proper) { \
750         case XMLConstants::XML_BOOL_TRUE: \
751             domElement->setAttributeNS(namespaceURI, ucase##_ATTRIB_NAME, XMLConstants::XML_TRUE); \
752             break; \
753         case XMLConstants::XML_BOOL_ONE: \
754             domElement->setAttributeNS(namespaceURI, ucase##_ATTRIB_NAME, XMLConstants::XML_ONE); \
755             break; \
756         case XMLConstants::XML_BOOL_FALSE: \
757             domElement->setAttributeNS(namespaceURI, ucase##_ATTRIB_NAME, XMLConstants::XML_FALSE); \
758             break; \
759         case XMLConstants::XML_BOOL_ZERO: \
760             domElement->setAttributeNS(namespaceURI, ucase##_ATTRIB_NAME, XMLConstants::XML_ZERO); \
761             break; \
762         case XMLConstants::XML_BOOL_NULL: \
763             break; \
764     }
765
766 /**
767  * Implements marshalling for a QName attribute
768  * 
769  * @param proper        the proper name of the attribute
770  * @param ucase         the upcased name of the attribute
771  * @param namespaceURI  the XML namespace of the attribute
772  */
773 #define MARSHALL_QNAME_ATTRIB(proper,ucase,namespaceURI) \
774     if (m_##proper) { \
775         auto_ptr_XMLCh qstr(m_##proper->toString().c_str()); \
776         domElement->setAttributeNS(namespaceURI, ucase##_ATTRIB_NAME, qstr.get()); \
777     }
778
779 /**
780  * Implements marshalling for an ID attribute
781  * 
782  * @param proper        the proper name of the attribute
783  * @param ucase         the upcased name of the attribute
784  * @param namespaceURI  the XML namespace of the attribute
785  */
786 #define MARSHALL_ID_ATTRIB(proper,ucase,namespaceURI) \
787     if (m_##proper) { \
788         domElement->setAttributeNS(namespaceURI, ucase##_ATTRIB_NAME, m_##proper); \
789         domElement->setIdAttributeNS(namespaceURI, ucase##_ATTRIB_NAME); \
790     }
791
792 /**
793  * Implements unmarshalling process branch for a string attribute
794  * 
795  * @param proper        the proper name of the attribute
796  * @param ucase         the upcased name of the attribute
797  * @param namespaceURI  the XML namespace of the attribute
798  */
799 #define PROC_STRING_ATTRIB(proper,ucase,namespaceURI) \
800     if (xmltooling::XMLHelper::isNodeNamed(attribute, namespaceURI, ucase##_ATTRIB_NAME)) { \
801         set##proper(attribute->getValue()); \
802         return; \
803     }
804
805 /**
806  * Implements unmarshalling process branch for an ID attribute
807  * 
808  * @param proper        the proper name of the attribute
809  * @param ucase         the upcased name of the attribute
810  * @param namespaceURI  the XML namespace of the attribute
811  */
812 #define PROC_ID_ATTRIB(proper,ucase,namespaceURI) \
813     if (xmltooling::XMLHelper::isNodeNamed(attribute, namespaceURI, ucase##_ATTRIB_NAME)) { \
814         set##proper(attribute->getValue()); \
815         attribute->getOwnerElement()->setIdAttributeNode(attribute); \
816         return; \
817     }
818
819 /**
820  * Implements unmarshalling process branch for a DateTime attribute
821  * 
822  * @param proper        the proper name of the attribute
823  * @param ucase         the upcased name of the attribute
824  * @param namespaceURI  the XML namespace of the attribute
825  */
826 #define PROC_DATETIME_ATTRIB(proper,ucase,namespaceURI) \
827     PROC_STRING_ATTRIB(proper,ucase,namespaceURI)
828
829 /**
830  * Implements unmarshalling process branch for a DateTime attribute
831  * 
832  * @param proper        the proper name of the attribute
833  * @param ucase         the upcased name of the attribute
834  * @param namespaceURI  the XML namespace of the attribute
835  */
836 #define PROC_QNAME_ATTRIB(proper,ucase,namespaceURI) \
837     if (xmltooling::XMLHelper::isNodeNamed(attribute, namespaceURI, ucase##_ATTRIB_NAME)) { \
838         set##proper(XMLHelper::getAttributeValueAsQName(attribute)); \
839         return; \
840     }
841
842 /**
843  * Implements unmarshalling process branch for an integer attribute
844  * 
845  * @param proper        the proper name of the attribute
846  * @param ucase         the upcased name of the attribute
847  * @param namespaceURI  the XML namespace of the attribute
848  */
849 #define PROC_INTEGER_ATTRIB(proper,ucase,namespaceURI) \
850     PROC_STRING_ATTRIB(proper,ucase,namespaceURI)
851
852 /**
853  * Implements unmarshalling process branch for a boolean attribute
854  * 
855  * @param proper        the proper name of the attribute
856  * @param ucase         the upcased name of the attribute
857  * @param namespaceURI  the XML namespace of the attribute
858  */
859 #define PROC_BOOLEAN_ATTRIB(proper,ucase,namespaceURI) \
860     PROC_STRING_ATTRIB(proper,ucase,namespaceURI)
861
862 /**
863  * Implements unmarshalling process branch for typed child collection element
864  * 
865  * @param proper        the proper name of the child type
866  * @param namespaceURI  the XML namespace of the child element
867  * @param force         bypass use of hint and just cast down to check child
868  */
869 #define PROC_TYPED_CHILDREN(proper,namespaceURI,force) \
870     if (force || xmltooling::XMLHelper::isNodeNamed(root,namespaceURI,proper::LOCAL_NAME)) { \
871         proper* typesafe=dynamic_cast<proper*>(childXMLObject); \
872         if (typesafe) { \
873             get##proper##s().push_back(typesafe); \
874             return; \
875         } \
876     }
877
878 /**
879  * Implements unmarshalling process branch for typed child collection element
880  * in a foreign namespace.
881  * 
882  * @param proper        the proper name of the child type
883  * @param ns            the C++ namespace for the type
884  * @param namespaceURI  the XML namespace of the child element
885  * @param force         bypass use of hint and just cast down to check child
886  */
887 #define PROC_TYPED_FOREIGN_CHILDREN(proper,ns,namespaceURI,force) \
888     if (force || xmltooling::XMLHelper::isNodeNamed(root,namespaceURI,ns::proper::LOCAL_NAME)) { \
889         ns::proper* typesafe=dynamic_cast<ns::proper*>(childXMLObject); \
890         if (typesafe) { \
891             get##proper##s().push_back(typesafe); \
892             return; \
893         } \
894     }
895
896 /**
897  * Implements unmarshalling process branch for typed child singleton element
898  * 
899  * @param proper        the proper name of the child type
900  * @param namespaceURI  the XML namespace of the child element
901  * @param force         bypass use of hint and just cast down to check child
902  */
903 #define PROC_TYPED_CHILD(proper,namespaceURI,force) \
904     if (force || xmltooling::XMLHelper::isNodeNamed(root,namespaceURI,proper::LOCAL_NAME)) { \
905         proper* typesafe=dynamic_cast<proper*>(childXMLObject); \
906         if (typesafe) { \
907             set##proper(typesafe); \
908             return; \
909         } \
910     }
911
912 /**
913  * Implements unmarshalling process branch for typed child singleton element
914  * in a foreign namespace.
915  * 
916  * @param proper        the proper name of the child type
917  * @param ns            the C++ namespace for the type
918  * @param namespaceURI  the XML namespace of the child element
919  * @param force         bypass use of hint and just cast down to check child
920  */
921 #define PROC_TYPED_FOREIGN_CHILD(proper,ns,namespaceURI,force) \
922     if (force || xmltooling::XMLHelper::isNodeNamed(root,namespaceURI,ns::proper::LOCAL_NAME)) { \
923         ns::proper* typesafe=dynamic_cast<ns::proper*>(childXMLObject); \
924         if (typesafe) { \
925             set##proper(typesafe); \
926             return; \
927         } \
928     }
929
930 /**
931  * Implements unmarshalling process branch for a generic child singleton element
932  * 
933  * @param proper        the proper name of the child type
934  * @param namespaceURI  the XML namespace of the child element
935  */
936 #define PROC_XMLOBJECT_CHILD(proper,namespaceURI) \
937     if (xmltooling::XMLHelper::isNodeNamed(root,namespaceURI,proper::LOCAL_NAME)) { \
938         set##proper(childXMLObject); \
939         return; \
940     }
941
942 /**
943  * Declares aliased get/set methods for named XML element content.
944  * 
945  * @param proper    the proper name to label the element's content
946  */
947 #define DECL_XMLOBJECT_CONTENT(proper) \
948     XMLTOOLING_DOXYGEN(Returns proper.) \
949     const XMLCh* get##proper() const { \
950         return getTextContent(); \
951     } \
952     XMLTOOLING_DOXYGEN(Sets or clears proper.) \
953     void set##proper(const XMLCh* proper) { \
954         setTextContent(proper); \
955     }
956
957 /**
958  * Declares aliased get/set methods for named integer XML element content.
959  * 
960  * @param proper    the proper name to label the element's content
961  */
962 #define DECL_INTEGER_CONTENT(proper) \
963     XMLTOOLING_DOXYGEN(Returns proper in integer form after a NULL indicator.) \
964     std::pair<bool,int> get##proper() const { \
965         return std::make_pair((getTextContent()!=NULL), (getTextContent()!=NULL ? XMLString::parseInt(getTextContent()) : NULL)); \
966     } \
967     XMLTOOLING_DOXYGEN(Sets proper.) \
968     void set##proper(int proper) { \
969         char buf[64]; \
970         sprintf(buf,"%d",proper); \
971         xmltooling::auto_ptr_XMLCh widebuf(buf); \
972         setTextContent(widebuf.get()); \
973     } \
974     XMLTOOLING_DOXYGEN(Sets or clears proper.) \
975     void set##proper(const XMLCh* proper) { \
976         setTextContent(proper); \
977     }
978
979 /**
980  * Implements marshalling/unmarshalling for element content.
981  */
982 #define IMPL_XMLOBJECT_CONTENT \
983     protected: \
984         void marshallElementContent(DOMElement* domElement) const { \
985             if(getTextContent()) { \
986                 domElement->appendChild(domElement->getOwnerDocument()->createTextNode(getTextContent())); \
987             } \
988         } \
989         void processElementContent(const XMLCh* elementContent) { \
990             setTextContent(elementContent); \
991         }
992
993
994 /**
995  * Implements cloning methods for an XMLObject specialization implementation class.
996  * 
997  * @param cname    the name of the XMLObject specialization
998  */
999 #define IMPL_XMLOBJECT_CLONE(cname) \
1000     cname* clone##cname() const { \
1001         return clone(); \
1002     } \
1003     cname* clone() const { \
1004         std::auto_ptr<xmltooling::XMLObject> domClone(xmltooling::AbstractDOMCachingXMLObject::clone()); \
1005         cname##Impl* ret=dynamic_cast<cname##Impl*>(domClone.get()); \
1006         if (ret) { \
1007             domClone.release(); \
1008             return ret; \
1009         } \
1010         return new cname##Impl(*this); \
1011     }
1012
1013 /**
1014  * Declares an XMLObject specialization with a simple content model and type,
1015  * handling it as string data.
1016  * 
1017  * @param linkage   linkage specifier for the class
1018  * @param cname     the name of the XMLObject specialization
1019  * @param proper    the proper name to label the element's content
1020  * @param desc      documentation for class
1021  */
1022 #define DECL_XMLOBJECT_SIMPLE(linkage,cname,proper,desc) \
1023     BEGIN_XMLOBJECT(linkage,cname,xmltooling::SimpleElement,desc); \
1024         DECL_XMLOBJECT_CONTENT(proper); \
1025     END_XMLOBJECT
1026
1027 /**
1028  * Declares and defines an implementation class for an XMLObject with
1029  * a simple content model and type, handling it as string data.
1030  * 
1031  * @param linkage   linkage specifier for the class
1032  * @param cname     the name of the XMLObject specialization
1033  */
1034 #define DECL_XMLOBJECTIMPL_SIMPLE(linkage,cname) \
1035     class linkage cname##Impl \
1036         : public virtual cname, \
1037             public xmltooling::AbstractSimpleElement, \
1038             public xmltooling::AbstractChildlessElement, \
1039             public xmltooling::AbstractDOMCachingXMLObject, \
1040             public xmltooling::AbstractValidatingXMLObject, \
1041             public xmltooling::AbstractXMLObjectMarshaller, \
1042             public xmltooling::AbstractXMLObjectUnmarshaller \
1043     { \
1044     public: \
1045         virtual ~cname##Impl() {} \
1046         cname##Impl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType) \
1047             : xmltooling::AbstractXMLObject(nsURI, localName, prefix, schemaType) { \
1048         } \
1049         cname##Impl(const cname##Impl& src) \
1050             : xmltooling::AbstractXMLObject(src), \
1051                 xmltooling::AbstractSimpleElement(src), \
1052                 xmltooling::AbstractDOMCachingXMLObject(src), \
1053                 xmltooling::AbstractValidatingXMLObject(src) {} \
1054         IMPL_XMLOBJECT_CLONE(cname) \
1055         IMPL_XMLOBJECT_CONTENT \
1056     }
1057     
1058 /**
1059  * Begins the declaration of an XMLObjectBuilder specialization.
1060  * Basic boilerplate includes an empty virtual destructor, and
1061  * a default builder that defaults the element name.
1062  * 
1063  * @param linkage           linkage specifier for the class
1064  * @param cname             the name of the XMLObject specialization
1065  * @param namespaceURI      the XML namespace of the default associated element
1066  * @param namespacePrefix   the XML namespace prefix of the default associated element
1067  */
1068 #define BEGIN_XMLOBJECTBUILDER(linkage,cname,namespaceURI,namespacePrefix) \
1069     XMLTOOLING_DOXYGEN(Builder for cname objects.) \
1070     class linkage cname##Builder : public xmltooling::XMLObjectBuilder { \
1071     public: \
1072         virtual ~cname##Builder() {} \
1073         XMLTOOLING_DOXYGEN(Default builder.) \
1074         virtual cname* buildObject() const { \
1075             return buildObject(namespaceURI,cname::LOCAL_NAME,namespacePrefix); \
1076         } \
1077         XMLTOOLING_DOXYGEN(Builder that allows element/type override.) \
1078         virtual cname* buildObject( \
1079             const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix=NULL, const xmltooling::QName* schemaType=NULL \
1080             ) const
1081
1082 /**
1083  * Ends the declaration of an XMLObjectBuilder specialization.
1084  */
1085 #define END_XMLOBJECTBUILDER }
1086
1087 /**
1088  * Declares a generic XMLObjectBuilder specialization.
1089  * 
1090  * @param linkage           linkage specifier for the class
1091  * @param cname             the name of the XMLObject specialization
1092  * @param namespaceURI      the XML namespace of the default associated element
1093  * @param namespacePrefix   the XML namespace prefix of the default associated element
1094  */
1095  #define DECL_XMLOBJECTBUILDER(linkage,cname,namespaceURI,namespacePrefix) \
1096     BEGIN_XMLOBJECTBUILDER(linkage,cname,namespaceURI,namespacePrefix); \
1097     XMLTOOLING_DOXYGEN(Singleton builder.) \
1098     static cname* build##cname() { \
1099         const cname##Builder* b = dynamic_cast<const cname##Builder*>( \
1100             XMLObjectBuilder::getBuilder(xmltooling::QName(namespaceURI,cname::LOCAL_NAME)) \
1101             ); \
1102         if (b) \
1103             return b->buildObject(); \
1104         throw xmltooling::XMLObjectException("Unable to obtain typed builder for "#cname"."); \
1105     } \
1106     END_XMLOBJECTBUILDER
1107
1108 /**
1109  * Implements the standard XMLObjectBuilder specialization function. 
1110  * 
1111  * @param cname the name of the XMLObject specialization
1112  */
1113 #define IMPL_XMLOBJECTBUILDER(cname) \
1114     cname* cname##Builder::buildObject( \
1115         const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType \
1116         ) const \
1117     { \
1118         return new cname##Impl(nsURI,localName,prefix,schemaType); \
1119     }
1120
1121 /**
1122  * Begins the declaration of a Schema Validator specialization.
1123  * 
1124  * @param linkage           linkage specifier for the class
1125  * @param cname the base name of the Validator specialization
1126  */
1127  #define BEGIN_XMLOBJECTVALIDATOR(linkage,cname) \
1128     class linkage cname##SchemaValidator : public xmltooling::Validator \
1129     { \
1130     public: \
1131         virtual ~cname##SchemaValidator() {} \
1132         virtual cname##SchemaValidator* clone() const { \
1133             return new cname##SchemaValidator(); \
1134         } \
1135         virtual void validate(const xmltooling::XMLObject* xmlObject) const { \
1136             const cname* ptr=dynamic_cast<const cname*>(xmlObject); \
1137             if (!ptr) \
1138                 throw xmltooling::ValidationException(#cname"SchemaValidator: unsupported object type ($1).",xmltooling::params(1,typeid(xmlObject).name()))
1139
1140 /**
1141  * Begins the declaration of a Schema Validator specialization subclass.
1142  * 
1143  * @param linkage   linkage specifier for the class
1144  * @param cname     the base name of the Validator specialization
1145  * @param base      base class for the validator
1146  */
1147  #define BEGIN_XMLOBJECTVALIDATOR_SUB(linkage,cname,base) \
1148     class linkage cname##SchemaValidator : public base##SchemaValidator \
1149     { \
1150     public: \
1151         virtual ~cname##SchemaValidator() {} \
1152         virtual cname##SchemaValidator* clone() const { \
1153             return new cname##SchemaValidator(); \
1154         } \
1155         virtual void validate(const xmltooling::XMLObject* xmlObject) const { \
1156             const cname* ptr=dynamic_cast<const cname*>(xmlObject); \
1157             if (!ptr) \
1158                 throw xmltooling::ValidationException(#cname"SchemaValidator: unsupported object type ($1).",xmltooling::params(1,typeid(xmlObject).name()))
1159
1160 /**
1161  * Ends the declaration of a Validator specialization.
1162  */
1163 #define END_XMLOBJECTVALIDATOR } }
1164
1165 /**
1166  * Validator code that checks the object type.
1167  * 
1168  * @param cname     the name of the XMLObject specialization
1169  */
1170 #define XMLOBJECTVALIDATOR_CHECKTYPE(cname) \
1171     const cname* ptr=dynamic_cast<const cname*>(xmlObject); \
1172     if (!ptr) \
1173         throw xmltooling::ValidationException(#cname"SchemaValidator: unsupported object type ($1).",xmltooling::params(1,typeid(xmlObject).name()))
1174
1175 /**
1176  * Validator code that checks for a required attribute, content, or singleton.
1177  * 
1178  * @param cname     the name of the XMLObject specialization
1179  * @param proper    the proper name of the attribute, content, or singleton member 
1180  */
1181 #define XMLOBJECTVALIDATOR_REQUIRE(cname,proper) \
1182     if (!ptr->get##proper()) \
1183         throw xmltooling::ValidationException(#cname" must have "#proper".")
1184
1185 /**
1186  * Validator code that checks for a required integer attribute
1187  * 
1188  * @param cname     the name of the XMLObject specialization
1189  * @param proper    the proper name of the attribute, content, or singleton member 
1190  */
1191 #define XMLOBJECTVALIDATOR_REQUIRE_INTEGER(cname,proper) \
1192     if (!ptr->get##proper().first) \
1193         throw xmltooling::ValidationException(#cname" must have "#proper".")
1194
1195 /**
1196  * Validator code that checks for one of a pair of
1197  * required attributes, content, or singletons.
1198  * 
1199  * @param cname     the name of the XMLObject specialization
1200  * @param proper1   the proper name of the first attribute, content, or singleton member 
1201  * @param proper2   the proper name of the second attribute, content, or singleton member 
1202  */
1203 #define XMLOBJECTVALIDATOR_ONEOF(cname,proper1,proper2) \
1204     if (!ptr->get##proper1() && !ptr->get##proper2()) \
1205         throw xmltooling::ValidationException(#cname" must have "#proper1" or "#proper2".")
1206
1207 /**
1208  * Validator code that checks for one of a pair of
1209  * required attributes, content, or singletons, but disallows both.
1210  * 
1211  * @param cname     the name of the XMLObject specialization
1212  * @param proper1   the proper name of the first attribute, content, or singleton member 
1213  * @param proper2   the proper name of the second attribute, content, or singleton member 
1214  */
1215 #define XMLOBJECTVALIDATOR_ONLYONEOF(cname,proper1,proper2) \
1216     if ((!ptr->get##proper1() && !ptr->get##proper2()) || (ptr->get##proper1() && ptr->get##proper2())) \
1217         throw xmltooling::ValidationException(#cname" must have "#proper1" or "#proper2" but not both.")
1218
1219 /**
1220  * Validator code that checks for one of a set of three
1221  * required attributes, content, or singletons.
1222  * 
1223  * @param cname     the name of the XMLObject specialization
1224  * @param proper1   the proper name of the first attribute, content, or singleton member
1225  * @param proper2   the proper name of the second attribute, content, or singleton member
1226  * @param proper3   the proper name of the third attribute, content, or singleton member
1227  */
1228 #define XMLOBJECTVALIDATOR_ONEOF3(cname,proper1,proper2,proper3) \
1229     if (!ptr->get##proper1() && !ptr->get##proper2() && !ptr->get##proper3()) \
1230         throw xmltooling::ValidationException(#cname" must have "#proper1", "#proper2", or "#proper3".")
1231
1232 /**
1233  * Validator code that checks for one of a set of three
1234  * required attributes, content, or singletons but disallows more than one.
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_ONLYONEOF3(cname,proper1,proper2,proper3) \
1242     int c##proper1##proper2##proper3=0; \
1243     if (ptr->get##proper1()!=NULL) \
1244         c##proper1##proper2##proper3++; \
1245     if (ptr->get##proper2()!=NULL) \
1246         c##proper1##proper2##proper3++; \
1247     if (ptr->get##proper3()!=NULL) \
1248         c##proper1##proper2##proper3++; \
1249     if (c##proper1##proper2##proper3 != 1) \
1250         throw xmltooling::ValidationException(#cname" must have only one of "#proper1", "#proper2", or "#proper3".")
1251
1252 /**
1253  * Validator code that checks a co-constraint (if one present, the other must be)
1254  * between a pair of attributes, content, or singletons.
1255  * 
1256  * @param cname     the name of the XMLObject specialization
1257  * @param proper1   the proper name of the first attribute, content, or singleton member 
1258  * @param proper2   the proper name of the second attribute, content, or singleton member 
1259  */
1260 #define XMLOBJECTVALIDATOR_NONEORBOTH(cname,proper1,proper2) \
1261     if ((ptr->get##proper1() && !ptr->get##proper2()) || (!ptr->get##proper1() && ptr->get##proper2())) \
1262         throw xmltooling::ValidationException(#cname" cannot have "#proper1" without "#proper2".")
1263
1264 /**
1265  * Validator code that checks for a non-empty collection.
1266  * 
1267  * @param cname     the name of the XMLObject specialization
1268  * @param proper    the proper name of the collection item 
1269  */
1270 #define XMLOBJECTVALIDATOR_NONEMPTY(cname,proper) \
1271     if (ptr->get##proper##s().empty()) \
1272         throw xmltooling::ValidationException(#cname" must have at least one "#proper".")
1273
1274 /**
1275  * Declares/defines a Validator specialization that checks object type and
1276  * a non-empty simple content model.
1277  * 
1278  * @param linkage   linkage specifier for the class
1279  * @param cname     the name of the XMLObject specialization
1280  */
1281 #define XMLOBJECTVALIDATOR_SIMPLE(linkage,cname) \
1282     BEGIN_XMLOBJECTVALIDATOR(linkage,cname); \
1283         XMLOBJECTVALIDATOR_REQUIRE(cname,TextContent); \
1284     END_XMLOBJECTVALIDATOR
1285
1286 #include <utility>
1287
1288 /**
1289  * @namespace xmltooling
1290  * Public namespace of XML Tooling library
1291  */
1292 namespace xmltooling {
1293
1294     /**
1295      * Template function for cloning a sequence of XMLObjects.
1296      * Invokes the clone() member on each element of the input sequence and adds the copy to
1297      * the output sequence. Order is preserved.
1298      * 
1299      * @param in    input sequence to clone
1300      * @param out   output sequence to copy cloned pointers into
1301      */
1302     template<class InputSequence,class OutputSequence> void clone(const InputSequence& in, OutputSequence& out) {
1303         for (typename InputSequence::const_iterator i=in.begin(); i!=in.end(); i++) {
1304             if (*i)
1305                 out.push_back((*i)->clone());
1306             else
1307                 out.push_back(*i);
1308         }
1309     }
1310
1311     /**
1312      * Functor for cleaning up heap objects in containers.
1313      */
1314     template<class T> struct cleanup
1315     {
1316         /**
1317          * Function operator to delete an object.
1318          * 
1319          * @param ptr   object to delete
1320          */
1321         void operator()(T* ptr) {delete ptr;}
1322         
1323         /**
1324          * Function operator to delete an object stored as const.
1325          * 
1326          * @param ptr   object to delete after casting away const
1327          */
1328         void operator()(const T* ptr) {delete const_cast<T*>(ptr);}
1329     };
1330
1331     /**
1332      * Functor for cleaning up heap objects in key/value containers.
1333      */
1334     template<class A,class B> struct cleanup_pair
1335     {
1336         /**
1337          * Function operator to delete an object.
1338          * 
1339          * @param p   a pair in which the second component is the object to delete
1340          */
1341         void operator()(const std::pair<A,B*>& p) {delete p.second;}
1342     };
1343 };
1344
1345 #endif /* __xmltooling_base_h__ */