1 /******************************************************************************
2 * Copyright (c) 2000-2016 Ericsson Telecom AB
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/epl-v10.html
14 ******************************************************************************/
18 * Created on: Oct 17, 2008
22 #include "XerAttributes.hh"
23 // The above line must be the first in this file
24 #include "../common/memory.h"
28 static const NamespaceRestriction empty_nsr
= {
29 0, 0, NamespaceRestriction::UNUSED
32 static const XerAttributes::NameChange nochange
= { NamespaceSpecification::NO_MANGLING
};
34 XerAttributes::XerAttributes()
37 , anyAttributes_(empty_nsr
)
38 , anyElement_(empty_nsr
)
61 , whitespace_(PRESERVE
)
64 //fprintf(stderr, "XER attributes(%p) new\n", (void*)this);
67 void FreeNamespaceRestriction(NamespaceRestriction
& nsr
)
69 for (size_t i
=0; i
< nsr
.nElements_
; ++i
) {
75 XerAttributes::~XerAttributes()
77 FreeNamespaceRestriction(anyAttributes_
);
78 FreeNamespaceRestriction(anyElement_
);
80 Free(defaultForEmpty_
);
83 FreeNameChange(name_
);
84 FreeNamespace(namespace_
);
86 //if (pi_or_comment_.position_ > AFTER_VALUE) {
87 // Free(pi_or_comment_.value_);
90 for (size_t i
=0; i
< num_text_
; ++i
) {
91 if ((unsigned long)text_
[i
].keyword
92 > (unsigned long)NamespaceSpecification::LOWERCASED
) {
95 if (text_
[i
].prefix
> (char*)NamespaceSpecification::ALL
) {
96 Free(text_
[i
].prefix
);
102 void XerAttributes::FreeNamespace(NamespaceSpecification
&ns
) {
103 switch (ns
.keyword
) {
104 case NamespaceSpecification::NO_MANGLING
:
105 case NamespaceSpecification::CAPITALIZED
:
106 case NamespaceSpecification::UNCAPITALIZED
:
107 case NamespaceSpecification::UPPERCASED
:
108 case NamespaceSpecification::LOWERCASED
:
109 break; // nothing to do
110 default: // real string, must be freed
119 void XerAttributes::FreeNameChange(XerAttributes::NameChange
& n
) {
121 case NamespaceSpecification::NO_MANGLING
:
122 case NamespaceSpecification::CAPITALIZED
:
123 case NamespaceSpecification::UNCAPITALIZED
:
124 case NamespaceSpecification::UPPERCASED
:
125 case NamespaceSpecification::LOWERCASED
:
126 break; // nothing to do
127 default: // real string, must be freed
131 n
.kw_
= NamespaceSpecification::NO_MANGLING
;
135 void XerAttributes::print(const char *type_name
) const {
136 fprintf(stderr
, "XER attributes(%p) for %s:\n", (const void*)this, type_name
);
137 if (empty()) fputs("...Empty...\n", stderr
);
139 fputs(abstract_
? "ABSTRACT\n" : "", stderr
);
140 fputs(attribute_
? "ATTRIBUTE\n" : "", stderr
);
143 if (anyAttributes_
.type_
== NamespaceRestriction::NOTHING
) {
144 fputs("ANY-ATTRIBUTES\n", stderr
);
146 else for (size_t i
= 0; i
< anyAttributes_
.nElements_
; ++i
) {
147 fprintf(stderr
, "ANY-ATTRIBUTES %s %s\n",
148 anyAttributes_
.type_
== NamespaceRestriction::FROM
? "EXCEPT" : "FROM",
149 (anyAttributes_
.uris_
[i
] && *anyAttributes_
.uris_
[i
]) ?
150 anyAttributes_
.uris_
[i
] : "ABSENT");
155 if (anyElement_
.type_
== NamespaceRestriction::NOTHING
) {
156 fputs("ANY-ELEMENT\n", stderr
);
158 else for (size_t i
= 0; i
< anyElement_
.nElements_
; ++i
) {
159 fprintf(stderr
, "ANY-ELEMENT %s %s\n",
160 anyElement_
.type_
== NamespaceRestriction::FROM
? "EXCEPT" : "FROM",
161 (anyElement_
.uris_
[i
] && *anyElement_
.uris_
[i
]) ?
162 anyElement_
.uris_
[i
] : "ABSENT");
165 fputs(base64_
? "BASE64\n" : "", stderr
);
166 fputs(block_
? "BLOCK\n" : "", stderr
);
167 fputs(decimal_
? "DECIMAL\n" : "", stderr
);
169 if (defaultForEmpty_
) fprintf(stderr
, "DEFAULT-FOR-EMPTY '%s'\n", defaultForEmpty_
);
171 if (element_
) fputs("ELEMENT\n", stderr
);
172 fputs(embedValues_
? "EMBED-VALUES\n" : "", stderr
);
173 fputs((form_
& QUALIFIED
) ? "FORM AS QUALIFIED\n" : "", stderr
);
174 fputs(hex_
? "hexBinary" : "", stderr
);
175 fputs(list_
? "LIST\n" : "", stderr
);
177 static const char * xforms
[] = {
178 "CAPITALIZED", "UNCAPITALIZED", "UPPERCASED", "LOWERCASED"
181 case NamespaceSpecification::NO_MANGLING
: // nothing to do
184 fprintf(stderr
, "NAME AS '%s'\n", name_
.nn_
);
186 case NamespaceSpecification::CAPITALIZED
:
187 case NamespaceSpecification::UNCAPITALIZED
:
188 case NamespaceSpecification::LOWERCASED
:
189 case NamespaceSpecification::UPPERCASED
:
190 fprintf(stderr
, "NAME AS %s\n",
191 xforms
[name_
.kw_
- NamespaceSpecification::CAPITALIZED
]);
195 if (namespace_
.uri
) {
196 fprintf(stderr
, "NAMESPACE '%s' %s %s\n", namespace_
.uri
,
197 (namespace_
.prefix
? "PREFIX" : ""),
198 (namespace_
.prefix
? namespace_
.prefix
: ""));
201 //if (pi_or_comment_.position_ != NOWHERE) {
202 // fputs("PI-OR-COMMENT\n", stderr);
205 fputs("TEXT\n", stderr
);
206 for (size_t t
=0; t
< num_text_
; ++t
) {
207 const char* who
= 0, *action
= 0;
208 switch ((unsigned long)(text_
[t
].uri
) ) {
209 case NamespaceSpecification::LOWERCASED
:
210 action
= "LOWERCASED"; break;
211 case NamespaceSpecification::UPPERCASED
:
212 action
= "UPPERCASED"; break;
213 case NamespaceSpecification::CAPITALIZED
:
214 action
= "CAPITALIZED"; break;
215 case NamespaceSpecification::UNCAPITALIZED
:
216 action
= "UNCAPITALIZED"; break;
218 action
= "text"; break;
220 action
= text_
[t
].uri
; break;
223 switch ((unsigned long)text_
[t
].prefix
) {
224 case 0: who
= ""; break;
225 case NamespaceSpecification::ALL
: who
= "ALL"; break;
226 default: who
= text_
[t
].prefix
; break;
228 fprintf(stderr
, " %s as %s\n", who
, action
);
231 fputs(untagged_
? "UNTAGGED\n" : "", stderr
);
232 fputs(useNil_
? "USE-NIL\n" : "", stderr
);
233 fputs(useNumber_
? "USE-NUMBER\n" : "", stderr
);
234 fputs(useOrder_
? "USE-ORDER\n" : "", stderr
);
235 fputs(useQName_
? "USE-QNAME\n" : "", stderr
);
236 fputs(useType_
? "USE-TYPE\n" : "", stderr
);
237 fputs(useUnion_
? "USE-UNION\n" : "", stderr
);
238 if (whitespace_
!= PRESERVE
) fprintf(stderr
, "WHITESPACE %s\n",
239 whitespace_
== COLLAPSE
? "COLLAPSE" : "REPLACE");
240 fputs(". . . . .\n", stderr
);
244 XerAttributes
& XerAttributes::operator |= (const XerAttributes
& other
)
246 if (other
.empty()) FATAL_ERROR("XerAttributes::operator |=");
248 fprintf(stderr, "@@@ replacing:\n");
250 other.print("other");
252 abstract_
|= other
.abstract_
;
253 attribute_
|= other
.attribute_
;
254 if (has_aa(&other
)) {
255 FreeNamespaceRestriction(anyAttributes_
);
256 anyAttributes_
.nElements_
= other
.anyAttributes_
.nElements_
;
257 anyAttributes_
.type_
= other
.anyAttributes_
.type_
;
258 anyAttributes_
.uris_
= (char**)Malloc(anyAttributes_
.nElements_
260 for (size_t i
=0; i
< anyAttributes_
.nElements_
; ++i
) {
261 anyAttributes_
.uris_
[i
] = mcopystr(other
.anyAttributes_
.uris_
[i
]);
264 if (has_ae(&other
)) {
265 FreeNamespaceRestriction(anyElement_
);
266 anyElement_
.nElements_
= other
.anyElement_
.nElements_
;
267 anyElement_
.type_
= other
.anyElement_
.type_
;
268 anyElement_
.uris_
= (char**)Malloc(anyElement_
.nElements_
270 for (size_t i
=0; i
< anyElement_
.nElements_
; ++i
) {
271 anyElement_
.uris_
[i
] = mcopystr(other
.anyElement_
.uris_
[i
]);
274 base64_
|= other
.base64_
;
275 block_
|= other
.block_
;
276 decimal_
|= other
.decimal_
;
278 if (other
.defaultForEmpty_
!= 0) {
279 Free(defaultForEmpty_
);
280 defaultForEmpty_
= mcopystr(other
.defaultForEmpty_
);
283 element_
|= other
.element_
;
284 embedValues_
|= other
.embedValues_
;
287 list_
|= other
.list_
;
288 if (other
.name_
.kw_
!= NamespaceSpecification::NO_MANGLING
) {
289 FreeNameChange(name_
);
290 switch (other
.name_
.kw_
) {
291 case NamespaceSpecification::NO_MANGLING
:
292 break; // not possible inside the if
293 case NamespaceSpecification::CAPITALIZED
:
294 case NamespaceSpecification::UNCAPITALIZED
:
295 case NamespaceSpecification::UPPERCASED
:
296 case NamespaceSpecification::LOWERCASED
:
297 name_
.kw_
= other
.name_
.kw_
;
299 default: // a real string
300 name_
.nn_
= mcopystr(other
.name_
.nn_
);
305 if (other
.namespace_
.uri
!= 0) {
306 switch (namespace_
.keyword
) {
307 case NamespaceSpecification::NO_MANGLING
:
308 case NamespaceSpecification::CAPITALIZED
:
309 case NamespaceSpecification::UNCAPITALIZED
:
310 case NamespaceSpecification::UPPERCASED
:
311 case NamespaceSpecification::LOWERCASED
:
312 break; // nothing to do
313 default: // real string, must be freed
314 Free(namespace_
.uri
);
317 switch (other
.namespace_
.keyword
) {
318 case NamespaceSpecification::NO_MANGLING
:
319 case NamespaceSpecification::CAPITALIZED
:
320 case NamespaceSpecification::UNCAPITALIZED
:
321 case NamespaceSpecification::UPPERCASED
:
322 case NamespaceSpecification::LOWERCASED
:
323 namespace_
.uri
= other
.namespace_
.uri
;
325 default: // real string
326 namespace_
.uri
= mcopystr(other
.namespace_
.uri
);
329 Free(namespace_
.prefix
);
330 namespace_
.prefix
= mcopystr(other
.namespace_
.prefix
);
334 if (other
.num_text_
) {
335 // Append the other TEXT. No attempt is made to eliminate duplicates.
336 // This will be done in Type::chk_xer_text().
337 size_t old_num
= num_text_
;
338 num_text_
+= other
.num_text_
;
339 text_
= (NamespaceSpecification
*)Realloc(
340 text_
, num_text_
* sizeof(NamespaceSpecification
));
341 for (size_t t
= 0; t
< other
.num_text_
; ++t
) {
342 switch ((unsigned long)(other
.text_
[t
].uri
) ) {
343 case NamespaceSpecification::LOWERCASED
:
344 case NamespaceSpecification::UPPERCASED
:
345 case NamespaceSpecification::CAPITALIZED
:
346 case NamespaceSpecification::UNCAPITALIZED
:
347 case NamespaceSpecification::NO_MANGLING
:
348 text_
[old_num
+ t
].uri
= other
.text_
[t
].uri
;
351 text_
[old_num
+ t
].uri
= mcopystr(other
.text_
[t
].uri
);
355 switch ((unsigned long)other
.text_
[t
].prefix
) {
356 case 0: case NamespaceSpecification::ALL
:
357 text_
[old_num
+ t
].prefix
= other
.text_
[t
].prefix
;
360 text_
[old_num
+ t
].prefix
= mcopystr(other
.text_
[t
].prefix
);
365 untagged_
|= other
.untagged_
;
366 useNil_
|= other
.useNil_
;
367 useNumber_
|= other
.useNumber_
;
368 useOrder_
|= other
.useOrder_
;
369 useQName_
|= other
.useQName_
;
370 useType_
|= other
.useType_
;
371 useUnion_
|= other
.useUnion_
;
372 whitespace_
= other
.whitespace_
;
376 bool XerAttributes::empty() const
385 && defaultForEmpty_
== 0
388 && !(form_
& LOCALLY_SET
)
391 && name_
.kw_
== NamespaceSpecification::NO_MANGLING
392 && namespace_
.uri
== 0
401 && whitespace_
== PRESERVE
;