2
* Licensed to the Apache Software Foundation (ASF) under one or more
3
* contributor license agreements. See the NOTICE file distributed with
4
* this work for additional information regarding copyright ownership.
5
* The ASF licenses this file to You under the Apache License, Version 2.0
6
* (the "License"); you may not use this file except in compliance with
7
* the License. You may obtain a copy of the License at
9
* http://www.apache.org/licenses/LICENSE-2.0
11
* Unless required by applicable law or agreed to in writing, software
12
* distributed under the License is distributed on an "AS IS" BASIS,
13
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
* See the License for the specific language governing permissions and
15
* limitations under the License.
19
* $Id: DOMCasts.hpp 673975 2008-07-04 09:23:56Z borisk $
22
#if !defined(XERCESC_INCLUDE_GUARD_DOMCASTS_HPP)
23
#define XERCESC_INCLUDE_GUARD_DOMCASTS_HPP
26
// This file is part of the internal implementation of the C++ XML DOM.
27
// It should NOT be included or used directly by application programs.
29
// Applications should include the file <xercesc/dom/DOM.hpp> for the entire
30
// DOM API, or xercesc/dom/DOM*.hpp for individual DOM classes, where the class
31
// name is substituded for the *.
35
// Define inline casting functions to convert from
36
// (DOMNode *) to DOMParentNode or DOMChildNode *.
38
// This requires knowledge of the structure of the fields of
39
// for all node types. There are three categories -
41
// Nodetypes that can have children and can be a child themselves.
46
// DOMParentNode fParent;
47
// DOMChildNode fChild;
48
// ... // other fields, depending on node type.
50
// Nodetypes that can not have children, e.g. TEXT
54
// DOMChildNode fChild;
55
// ... // other fields, depending on node type
57
// Nodetypes that can not be a child of other nodes, but that can
58
// have children (are a parent) e.g. ATTR
61
// DOMParentNode fParent
62
// ... // other fields, depending on node type
64
// The casting functions make these assumptions:
65
// 1. The cast is possible. Using code will not attempt to
66
// cast to something that does not exist, such as the child
69
// 2. The nodes belong to this implementation.
71
// Some of the casts use the LEAFNODE flag in the common fNode part to
72
// determine whether an fParent field exists, and thus the
73
// position of the fChild part within the node.
75
// These functions also cast off const. It was either do that, or make
76
// a second overloaded set that took and returned const arguements.
80
// Note that using offsetof, or taking the offset of an object member at
81
// a 0 address, is now undefined in C++. And gcc now warns about this behavior.
82
// This is because doing do so is unreliable for some types of objects.
83
// See: http://gcc.gnu.org/ml/gcc/2004-06/msg00227.html
84
// : http://gcc.gnu.org/ml/gcc-bugs/2000-03/msg00805.html
85
// The casting code below works around gcc's warnings by using a dummy
86
// pointer, which the compiler cannot tell is null. The defeats the warning,
87
// but also masks the potential problem.
88
// The gcc option -Wno-invalid-offsetof may also be used to turn off this warning.
91
#include "DOMElementImpl.hpp"
92
#include "DOMTextImpl.hpp"
94
XERCES_CPP_NAMESPACE_BEGIN
97
static inline DOMNodeImpl *castToNodeImpl(const DOMNode *p)
99
DOMElementImpl *pE = (DOMElementImpl *)p;
104
static inline DOMParentNode *castToParentImpl(const DOMNode *p) {
105
DOMElementImpl *pE = (DOMElementImpl *)p;
106
return &(pE->fParent);
110
static inline DOMChildNode *castToChildImpl(const DOMNode *p) {
111
DOMElementImpl *pE = (DOMElementImpl *)p;
112
if (pE->fNode.isLeafNode()) {
113
DOMTextImpl *pT = (DOMTextImpl *)p;
114
return &(pT->fChild);
116
return &(pE->fChild);
120
static inline DOMNode *castToNode(const DOMParentNode *p ) {
121
DOMElementImpl* dummy = 0;
122
XMLSize_t parentOffset = (char *)&(dummy->fParent) - (char *)dummy;
123
char *retPtr = (char *)p - parentOffset;
124
return (DOMNode *)retPtr;
127
static inline DOMNode *castToNode(const DOMNodeImpl *p) {
128
DOMElementImpl* dummy = 0;
129
XMLSize_t nodeImplOffset = (char *)&(dummy->fNode) - (char *)dummy;
130
char *retPtr = (char *)p - nodeImplOffset;
131
return (DOMNode *)retPtr;
135
static inline DOMNodeImpl *castToNodeImpl(const DOMParentNode *p)
137
DOMElementImpl* dummy = 0;
138
XMLSize_t nodeImplOffset = (char *)&(dummy->fNode) - (char *)dummy;
139
XMLSize_t parentOffset = (char *)&(dummy->fParent) - (char *)dummy;
140
char *retPtr = (char *)p - parentOffset + nodeImplOffset;
141
return (DOMNodeImpl *)retPtr;
144
XERCES_CPP_NAMESPACE_END