Expose idBuffer,idOffset in AbstractTreeIterator to applications
[egit/zawir.git] / org.spearce.jgit / src / org / spearce / jgit / treewalk / CanonicalTreeParser.java
blob55942ed2ef2a781ffaf005d68b914b38396b4d90
1 /*
2 * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
4 * All rights reserved.
6 * Redistribution and use in source and binary forms, with or
7 * without modification, are permitted provided that the following
8 * conditions are met:
10 * - Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
13 * - Redistributions in binary form must reproduce the above
14 * copyright notice, this list of conditions and the following
15 * disclaimer in the documentation and/or other materials provided
16 * with the distribution.
18 * - Neither the name of the Git Development Community nor the
19 * names of its contributors may be used to endorse or promote
20 * products derived from this software without specific prior
21 * written permission.
23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
24 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
25 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
26 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
28 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
29 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
30 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
31 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
32 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
33 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
35 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38 package org.spearce.jgit.treewalk;
40 import java.io.IOException;
42 import org.spearce.jgit.errors.CorruptObjectException;
43 import org.spearce.jgit.errors.IncorrectObjectTypeException;
44 import org.spearce.jgit.errors.MissingObjectException;
45 import org.spearce.jgit.lib.Constants;
46 import org.spearce.jgit.lib.FileMode;
47 import org.spearce.jgit.lib.ObjectId;
48 import org.spearce.jgit.lib.ObjectLoader;
49 import org.spearce.jgit.lib.Repository;
51 /** Parses raw Git trees from the canonical semi-text/semi-binary format. */
52 public class CanonicalTreeParser extends AbstractTreeIterator {
53 private byte[] raw;
55 private int rawPtr;
57 /** Create a new parser. */
58 public CanonicalTreeParser() {
59 // Nothing necessary.
62 private CanonicalTreeParser(final CanonicalTreeParser p) {
63 super(p);
66 /**
67 * Reset this parser to walk through the given tree data.
69 * @param treeData
70 * the raw tree content.
72 public void reset(final byte[] treeData) {
73 raw = treeData;
74 rawPtr = 0;
77 /**
78 * Reset this parser to walk through the given tree.
80 * @param repo
81 * repository to load the tree data from.
82 * @param id
83 * identity of the tree being parsed; used only in exception
84 * messages if data corruption is found.
85 * @throws MissingObjectException
86 * the object supplied is not available from the repository.
87 * @throws IncorrectObjectTypeException
88 * the object supplied as an argument is not actually a tree and
89 * cannot be parsed as though it were a tree.
90 * @throws IOException
91 * a loose object or pack file could not be read.
93 public void reset(final Repository repo, final ObjectId id)
94 throws IncorrectObjectTypeException, IOException {
95 final ObjectLoader ldr = repo.openObject(id);
96 if (ldr == null)
97 throw new MissingObjectException(id, Constants.TYPE_TREE);
98 final byte[] subtreeData = ldr.getCachedBytes();
99 if (ldr.getType() != Constants.OBJ_TREE)
100 throw new IncorrectObjectTypeException(id, Constants.TYPE_TREE);
101 reset(subtreeData);
104 public CanonicalTreeParser createSubtreeIterator(final Repository repo)
105 throws IncorrectObjectTypeException, IOException {
106 final ObjectId id = getEntryObjectId();
107 if (!FileMode.TREE.equals(mode))
108 throw new IncorrectObjectTypeException(id, Constants.TYPE_TREE);
109 final CanonicalTreeParser p = new CanonicalTreeParser(this);
110 p.reset(repo, id);
111 return p;
114 @Override
115 public byte[] idBuffer() {
116 return raw;
119 @Override
120 public int idOffset() {
121 return rawPtr - Constants.OBJECT_ID_LENGTH;
124 public boolean eof() {
125 return raw == null;
128 public void next() throws CorruptObjectException {
129 int ptr = rawPtr;
130 if (ptr >= raw.length) {
131 raw = null;
132 return;
135 byte c = raw[ptr++];
136 int tmp = c - '0';
137 for (;;) {
138 c = raw[ptr++];
139 if (' ' == c)
140 break;
141 tmp <<= 3;
142 tmp += c - '0';
144 mode = tmp;
146 tmp = pathOffset;
147 for (;; tmp++) {
148 c = raw[ptr++];
149 if (c == 0)
150 break;
151 try {
152 path[tmp] = c;
153 } catch (ArrayIndexOutOfBoundsException e) {
154 growPath(tmp);
155 path[tmp] = c;
158 pathLen = tmp;
159 rawPtr = ptr + Constants.OBJECT_ID_LENGTH;