blob: 16170fd10bdbe93bd6024e0c48dd1f030e646747 [file] [log] [blame]
#ifndef DOMCasts_HEADER_GUARD_
#define DOMCasts_HEADER_GUARD_
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* $Id: DOMCasts.hpp 568078 2007-08-21 11:43:25Z amassari $
*/
//
// This file is part of the internal implementation of the C++ XML DOM.
// It should NOT be included or used directly by application programs.
//
// Applications should include the file <xercesc/dom/DOM.hpp> for the entire
// DOM API, or xercesc/dom/DOM*.hpp for individual DOM classes, where the class
// name is substituded for the *.
//
//
// Define inline casting functions to convert from
// (DOMNode *) to DOMParentNode or DOMChildNode *.
//
// This requires knowledge of the structure of the fields of
// for all node types. There are three categories -
//
// Nodetypes that can have children and can be a child themselves.
// e.g. Elements
//
// Object
// DOMNodeImpl fNode;
// DOMParentNode fParent;
// DOMChildNode fChild;
// ... // other fields, depending on node type.
//
// Nodetypes that can not have children, e.g. TEXT
//
// Object
// DOMNodeImpl fNode;
// DOMChildNode fChild;
// ... // other fields, depending on node type
//
// Nodetypes that can not be a child of other nodes, but that can
// have children (are a parent) e.g. ATTR
// Object
// DOMNodeImpl fNode;
// DOMParentNode fParent
// ... // other fields, depending on node type
//
// The casting functions make these assumptions:
// 1. The cast is possible. Using code will not attempt to
// cast to something that does not exist, such as the child
// part of an ATTR
//
// 2. The nodes belong to this implementation.
//
// Some of the casts use the LEAFNODE flag in the common fNode part to
// determine whether an fParent field exists, and thus the
// position of the fChild part within the node.
//
// These functions also cast off const. It was either do that, or make
// a second overloaded set that took and returned const arguements.
//
//
// Note that using offsetof, or taking the offset of an object member at
// a 0 address, is now undefined in C++. And gcc now warns about this behavior.
// This is because doing do so is unreliable for some types of objects.
// See: http://gcc.gnu.org/ml/gcc/2004-06/msg00227.html
// : http://gcc.gnu.org/ml/gcc-bugs/2000-03/msg00805.html
// The casting code below works around gcc's warnings by using a dummy
// pointer, which the compiler cannot tell is null. The defeats the warning,
// but also masks the potential problem.
// The gcc option -Wno-invalid-offsetof may also be used to turn off this warning.
//
#include "DOMElementImpl.hpp"
#include "DOMTextImpl.hpp"
XERCES_CPP_NAMESPACE_BEGIN
static inline DOMNodeImpl *castToNodeImpl(const DOMNode *p)
{
DOMElementImpl *pE = (DOMElementImpl *)p;
return &(pE->fNode);
}
static inline DOMParentNode *castToParentImpl(const DOMNode *p) {
DOMElementImpl *pE = (DOMElementImpl *)p;
return &(pE->fParent);
}
static inline DOMChildNode *castToChildImpl(const DOMNode *p) {
DOMElementImpl *pE = (DOMElementImpl *)p;
if (pE->fNode.isLeafNode()) {
DOMTextImpl *pT = (DOMTextImpl *)p;
return &(pT->fChild);
}
return &(pE->fChild);
}
static inline DOMNode *castToNode(const DOMParentNode *p ) {
DOMElementImpl* dummy = 0;
size_t parentOffset = (char *)&(dummy->fParent) - (char *)dummy;
char *retPtr = (char *)p - parentOffset;
return (DOMNode *)retPtr;
}
static inline DOMNode *castToNode(const DOMNodeImpl *p) {
DOMElementImpl* dummy = 0;
size_t nodeImplOffset = (char *)&(dummy->fNode) - (char *)dummy;
char *retPtr = (char *)p - nodeImplOffset;
return (DOMNode *)retPtr;
}
static inline DOMNodeImpl *castToNodeImpl(const DOMParentNode *p)
{
DOMElementImpl* dummy = 0;
size_t nodeImplOffset = (char *)&(dummy->fNode) - (char *)dummy;
size_t parentOffset = (char *)&(dummy->fParent) - (char *)dummy;
char *retPtr = (char *)p - parentOffset + nodeImplOffset;
return (DOMNodeImpl *)retPtr;
}
XERCES_CPP_NAMESPACE_END
#endif