/******************************************************************************* * Copyright (c) 2005, 2011 QNX Software Systems and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Doug Schaefer (QNX) - Initial API and implementation * Markus Schorn (Wind River Systems) * Andrew Ferguson (Symbian) *******************************************************************************/ package org.eclipse.cdt.internal.core.pdom.dom; import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.dom.IPDOMVisitor; import org.eclipse.cdt.internal.core.pdom.PDOM; import org.eclipse.cdt.internal.core.pdom.db.Database; import org.eclipse.core.runtime.CoreException; /** * This is a basic node in the PDOM database. * PDOM nodes form a multi-root tree with linkages being the roots. * This class managed the parent pointer. */ public abstract class PDOMNode implements IInternalPDOMNode { private static final int TYPE = 0; private static final int PARENT = 4; protected static final int RECORD_SIZE = 8; private final PDOMLinkage fLinkage; protected final long record; private volatile long cachedParentRecord; protected PDOMNode(PDOMLinkage linkage, long record) { fLinkage = linkage; this.record = record; } protected PDOMNode(PDOMLinkage linkage, PDOMNode parent) throws CoreException { this(linkage.getDB(), linkage, parent == null ? 0 : parent.getRecord()); } /** * For linkages, only. */ protected PDOMNode(Database db) throws CoreException { this(db, null, 0); } protected PDOMNode(Database db, PDOMLinkage linkage, long parentRec) throws CoreException { this.fLinkage = linkage; record = db.malloc(getRecordSize()); db.putInt(record + TYPE, getNodeType()); cachedParentRecord = parentRec; db.putRecPtr(record + PARENT, parentRec); } protected Database getDB() { return fLinkage.getDB(); } public PDOM getPDOM() { return fLinkage.getPDOM(); } public PDOMLinkage getLinkage() { return fLinkage; } protected abstract int getRecordSize(); public abstract int getNodeType(); public final long getRecord() { return record; } public final long getBindingID() { return record; } /** * Checks if <code>other</code> node is the immediate parent of this one. * @param other paternity test subject. * @return <code>true</code> if <code>other</code> node in the parent of this one. */ public boolean isChildOf(PDOMNode other) { try { return other.fLinkage == fLinkage && other.record == getParentNodeRec(); } catch (CoreException e) { return false; } } @Override public final boolean equals(Object obj) { if (obj == this) return true; if (obj instanceof PDOMNode) { PDOMNode other = (PDOMNode) obj; return getPDOM() == other.getPDOM() && record == other.record; } return super.equals(obj); } @Override public final int hashCode() { return System.identityHashCode(getPDOM()) + (int) (41 * record); } public void accept(IPDOMVisitor visitor) throws CoreException { // No children here. } public static int getNodeType(Database db, long record) throws CoreException { return db.getInt(record + TYPE); } public long getParentNodeRec() throws CoreException { if (cachedParentRecord != 0) { return cachedParentRecord; } return cachedParentRecord= getDB().getRecPtr(record + PARENT); } public PDOMNode getParentNode() throws CoreException { long parentrec = getParentNodeRec(); return parentrec != 0 ? getLinkage().getNode(parentrec) : null; } public void addChild(PDOMNode child) throws CoreException { // nothing here } /** * Convenience method for fetching a byte from the database. * @param offset Location of the byte. * @return a byte from the database. */ protected byte getByte(long offset) { try { return getDB().getByte(offset); } catch (CoreException e) { CCorePlugin.log(e); return 0; } } /** * Returns the bit at the specified offset in a bit vector. * @param bitVector Bits. * @param offset The position of the desired bit. * @return the bit at the specified offset. */ protected static boolean getBit(int bitVector, int offset) { int mask = 1 << offset; return (bitVector & mask) != 0; } /** * Delete this PDOMNode, make sure you are actually the owner of this record! * @param linkage * @throws CoreException */ public void delete(PDOMLinkage linkage) throws CoreException { getDB().free(record); } }