Copyright (c) 2000, 2005 IBM Corporation and others. This program and the accompanying materials are made available under the terms of the Eclipse Public License 2.0 which accompanies this distribution, and is available at https://www.eclipse.org/legal/epl-2.0/ SPDX-License-Identifier: EPL-2.0 Contributors: IBM Corporation - initial API and implementation
/******************************************************************************* * Copyright (c) 2000, 2005 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 * which accompanies this distribution, and is available at * https://www.eclipse.org/legal/epl-2.0/ * * SPDX-License-Identifier: EPL-2.0 * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/
package org.eclipse.core.internal.dtree; import java.io.DataOutput; import java.io.IOException; import org.eclipse.core.runtime.*;
Class for writing a single data tree (no parents) to an output stream.
/** * Class for writing a single data tree (no parents) to an output stream. */
public class DataTreeWriter {
Callback for serializing tree data
/** * Callback for serializing tree data */
protected IDataFlattener flatener;
The stream to write output to
/** * The stream to write output to */
protected DataOutput output;
Constant representing infinite recursion depth
/** * Constant representing infinite recursion depth */
public static final int D_INFINITE = -1;
Creates a new DeltaTreeWriter.
/** * Creates a new DeltaTreeWriter. */
public DataTreeWriter(IDataFlattener f) { flatener = f; }
Writes the subtree rooted at the given node.
Params:
  • node – The subtree to write.
  • path – The path of the current node.
  • depth – The depth of the subtree to write.
/** * Writes the subtree rooted at the given node. * @param node The subtree to write. * @param path The path of the current node. * @param depth The depth of the subtree to write. */
protected void writeNode(AbstractDataTreeNode node, IPath path, int depth) throws IOException { int type = node.type(); /* write the node name */ String name = node.getName(); if (name == null) { name = ""; //$NON-NLS-1$ } output.writeUTF(name); /* write the node type */ writeNumber(type); /* maybe write the data */ if (node.hasData()) { Object data = node.getData(); /** * Write a flag indicating whether or not the data field is null. * Zero means data is null, non-zero means data is present */ if (data == null) { writeNumber(0); } else { writeNumber(1); flatener.writeData(path, node.getData(), output); } } /* maybe write the children */ if (depth > 0 || depth == D_INFINITE) { AbstractDataTreeNode[] children = node.getChildren(); /* write the number of children */ writeNumber(children.length); /* write the children */ int newDepth = (depth == D_INFINITE) ? D_INFINITE : depth - 1; for (AbstractDataTreeNode element : children) { writeNode(element, path.append(element.getName()), newDepth); } } else { /* write the number of children */ writeNumber(0); } }
Writes an integer in a compact format biased towards small non-negative numbers. Numbers between 0 and 254 inclusive occupy 1 byte; other numbers occupy 5 bytes.
/** * Writes an integer in a compact format biased towards * small non-negative numbers. Numbers between * 0 and 254 inclusive occupy 1 byte; other numbers occupy 5 bytes. */
protected void writeNumber(int number) throws IOException { if (number >= 0 && number < 0xff) { output.writeByte(number); } else { output.writeByte(0xff); output.writeInt(number); } }
Writes a single node to the output. Does not recurse on child nodes, and does not write the number of children.
/** * Writes a single node to the output. Does not recurse * on child nodes, and does not write the number of children. */
protected void writeSingleNode(AbstractDataTreeNode node, IPath path) throws IOException { /* write the node name */ String name = node.getName(); if (name == null) { name = ""; //$NON-NLS-1$ } output.writeUTF(name); /* write the node type */ writeNumber(node.type()); /* maybe write the data */ if (node.hasData()) { Object data = node.getData(); /** * Write a flag indicating whether or not the data field is null. * Zero means data is null, non-zero means data is present */ if (data == null) { writeNumber(0); } else { writeNumber(1); flatener.writeData(path, node.getData(), output); } } }
Writes the given AbstractDataTree to the given stream. This writes a single DataTree or DeltaDataTree, ignoring parent trees.
Params:
  • path – Only writes data for the subtree rooted at the given path, and for all nodes directly between the root and the subtree.
  • depth – In the subtree rooted at the given path, only write up to this depth. A depth of infinity is given by the constant D_INFINITE.
/** * Writes the given AbstractDataTree to the given stream. This * writes a single DataTree or DeltaDataTree, ignoring parent * trees. * * @param path Only writes data for the subtree rooted at the given path, and * for all nodes directly between the root and the subtree. * @param depth In the subtree rooted at the given path, * only write up to this depth. A depth of infinity is given * by the constant D_INFINITE. */
public void writeTree(AbstractDataTree tree, IPath path, int depth, DataOutput output) throws IOException { this.output = output; /* tunnel down relevant path */ AbstractDataTreeNode node = tree.getRootNode(); IPath currentPath = Path.ROOT; String[] segments = path.segments(); for (String nextSegment : segments) { /* write this node to the output */ writeSingleNode(node, currentPath); currentPath = currentPath.append(nextSegment); node = node.childAtOrNull(nextSegment); /* write the number of children for this node */ if (node != null) { writeNumber(1); } else { /* can't navigate down the path, just give up with what we have so far */ writeNumber(0); return; } } Assert.isTrue(currentPath.equals(path), "dtree.navigationError"); //$NON-NLS-1$ /* recursively write the subtree we're interested in */ writeNode(node, path, depth); } }