All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.eclipse.core.internal.dtree.DataTreeWriter Maven / Gradle / Ivy

Go to download

AspectJ tools most notably contains the AspectJ compiler (AJC). AJC applies aspects to Java classes during compilation, fully replacing Javac for plain Java classes and also compiling native AspectJ or annotation-based @AspectJ syntax. Furthermore, AJC can weave aspects into existing class files in a post-compile binary weaving step. This library is a superset of AspectJ weaver and hence also of AspectJ runtime.

There is a newer version: 1.9.22.1
Show newest version
/*******************************************************************************
 * 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.Assert;
import org.eclipse.core.runtime.IPath;

/**
 * Class for writing a single data tree (no parents) to an output stream.
 */
public class DataTreeWriter {
	/**
	 * Callback for serializing tree data
	 */
	protected IDataFlattener flatener;

	/**
	 * The stream to write output to
	 */
	protected DataOutput output;

	/**
	 * Constant representing infinite recursion depth
	 */
	public static final int D_INFINITE = -1;

	/**
	 * Creates a new DeltaTreeWriter.
	 */
	public DataTreeWriter(IDataFlattener f) {
		flatener = f;
	}

	/**
	 * 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.
	 */
	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.
	 */
	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.
	 *
	 * @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(DeltaDataTree tree, IPath path, int depth, DataOutput output) throws IOException {
		this.output = output;
		/* tunnel down relevant path */
		AbstractDataTreeNode node = tree.getRootNode();
		IPath currentPath = IPath.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);
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy