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