platform35/org.eclipse.core.resources/src/org/eclipse/core/internal/dtree/DataTreeReader.java
changeset 40 eb3c938c7fef
equal deleted inserted replaced
39:2a03ec4dbf31 40:eb3c938c7fef
       
     1 /*******************************************************************************
       
     2  * Copyright (c) 2000, 2005 IBM Corporation and others.
       
     3  * All rights reserved. This program and the accompanying materials
       
     4  * are made available under the terms of the Eclipse Public License v1.0
       
     5  * which accompanies this distribution, and is available at
       
     6  * http://www.eclipse.org/legal/epl-v10.html
       
     7  * 
       
     8  * Contributors:
       
     9  *     IBM Corporation - initial API and implementation
       
    10  *******************************************************************************/
       
    11 package org.eclipse.core.internal.dtree;
       
    12 
       
    13 import java.io.DataInput;
       
    14 import java.io.IOException;
       
    15 import org.eclipse.core.internal.utils.Messages;
       
    16 import org.eclipse.core.runtime.*;
       
    17 
       
    18 /**
       
    19  * Class used for reading a single data tree (no parents) from an input stream
       
    20  */
       
    21 public class DataTreeReader {
       
    22 	/**
       
    23 	 * Callback for reading tree data
       
    24 	 */
       
    25 	protected IDataFlattener flatener;
       
    26 
       
    27 	/**
       
    28 	 * The stream to read the tree from
       
    29 	 */
       
    30 	protected DataInput input;
       
    31 
       
    32 	/**
       
    33 	 * Creates a new DeltaTreeReader.
       
    34 	 */
       
    35 	public DataTreeReader(IDataFlattener f) {
       
    36 		flatener = f;
       
    37 	}
       
    38 
       
    39 	/**
       
    40 	 * Returns true if the given node type has data.
       
    41 	 */
       
    42 	protected boolean hasData(int nodeType) {
       
    43 		switch (nodeType) {
       
    44 			case AbstractDataTreeNode.T_COMPLETE_NODE :
       
    45 			case AbstractDataTreeNode.T_DELTA_NODE :
       
    46 				return true;
       
    47 			case AbstractDataTreeNode.T_DELETED_NODE :
       
    48 			case AbstractDataTreeNode.T_NO_DATA_DELTA_NODE :
       
    49 			default :
       
    50 				return false;
       
    51 		}
       
    52 	}
       
    53 
       
    54 	/**
       
    55 	 * Reads a node from the given input stream
       
    56 	 */
       
    57 	protected AbstractDataTreeNode readNode(IPath parentPath) throws IOException {
       
    58 		/* read the node name */
       
    59 		String name = input.readUTF();
       
    60 
       
    61 		/* read the node type */
       
    62 		int nodeType = readNumber();
       
    63 
       
    64 		/* maybe read the data */
       
    65 		IPath path;
       
    66 
       
    67 		/* if not the root node */
       
    68 		if (parentPath != null) {
       
    69 			path = parentPath.append(name);
       
    70 		} else {
       
    71 			path = Path.ROOT;
       
    72 		}
       
    73 
       
    74 		Object data = null;
       
    75 		if (hasData(nodeType)) {
       
    76 
       
    77 			/* read flag indicating if the data is null */
       
    78 			int dataFlag = readNumber();
       
    79 			if (dataFlag != 0) {
       
    80 				data = flatener.readData(path, input);
       
    81 			}
       
    82 		}
       
    83 
       
    84 		/* read the number of children */
       
    85 		int childCount = readNumber();
       
    86 
       
    87 		/* read the children */
       
    88 		AbstractDataTreeNode[] children;
       
    89 		if (childCount == 0) {
       
    90 			children = AbstractDataTreeNode.NO_CHILDREN;
       
    91 		} else {
       
    92 			children = new AbstractDataTreeNode[childCount];
       
    93 			for (int i = 0; i < childCount; i++) {
       
    94 				children[i] = readNode(path);
       
    95 			}
       
    96 		}
       
    97 
       
    98 		/* create the appropriate node */
       
    99 		switch (nodeType) {
       
   100 			case AbstractDataTreeNode.T_COMPLETE_NODE :
       
   101 				return new DataTreeNode(name, data, children);
       
   102 			case AbstractDataTreeNode.T_DELTA_NODE :
       
   103 				return new DataDeltaNode(name, data, children);
       
   104 			case AbstractDataTreeNode.T_DELETED_NODE :
       
   105 				return new DeletedNode(name);
       
   106 			case AbstractDataTreeNode.T_NO_DATA_DELTA_NODE :
       
   107 				return new NoDataDeltaNode(name, children);
       
   108 			default :
       
   109 				Assert.isTrue(false, Messages.dtree_switchError);
       
   110 				return null;
       
   111 		}
       
   112 	}
       
   113 
       
   114 	/** 
       
   115 	 * Reads an integer stored in compact format.  Numbers between
       
   116 	 * 0 and 254 inclusive occupy 1 byte; other numbers occupy 5 bytes,
       
   117 	 * the first byte being 0xff and the next 4 bytes being the standard
       
   118 	 * representation of an int.
       
   119 	 */
       
   120 	protected int readNumber() throws IOException {
       
   121 		byte b = input.readByte();
       
   122 		int number = (b & 0xff); // not a no-op! converts unsigned byte to int
       
   123 
       
   124 		if (number == 0xff) { // magic escape value
       
   125 			number = input.readInt();
       
   126 		}
       
   127 		return number;
       
   128 	}
       
   129 
       
   130 	/**
       
   131 	 * Reads a DeltaDataTree from the given input stream
       
   132 	 */
       
   133 	public DeltaDataTree readTree(DeltaDataTree parent, DataInput input) throws IOException {
       
   134 		this.input = input;
       
   135 		AbstractDataTreeNode root = readNode(Path.ROOT);
       
   136 		return new DeltaDataTree(root, parent);
       
   137 	}
       
   138 }