Cache pack index fully
[egit.git] / org.spearce.jgit / src / org / spearce / jgit / lib / ObjectId.java
blobf99c303f1d7955434471ead2bf1cfba68f020c07
1 /*
2 * Copyright (C) 2006 Shawn Pearce <spearce@spearce.org>
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public
6 * License, version 2, as published by the Free Software Foundation.
8 * This library is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * General Public License for more details.
13 * You should have received a copy of the GNU General Public
14 * License along with this library; if not, write to the Free Software
15 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
17 package org.spearce.jgit.lib;
19 import java.io.IOException;
20 import java.io.OutputStream;
21 import java.io.Writer;
23 public class ObjectId implements Comparable {
24 private static final ObjectId ZEROID;
26 private static final String ZEROID_STR;
28 static {
29 ZEROID = new ObjectId(new byte[Constants.OBJECT_ID_LENGTH]);
30 ZEROID_STR = ZEROID.toString();
33 public static ObjectId zeroId() {
34 return ZEROID;
37 public static final boolean isId(final String id) {
38 if (id.length() != (2 * Constants.OBJECT_ID_LENGTH)) {
39 return false;
42 for (int k = id.length() - 1; k >= 0; k--) {
43 final char c = id.charAt(k);
44 if ('0' <= c && c <= '9') {
45 continue;
46 } else if ('a' <= c && c <= 'f') {
47 continue;
48 } else {
49 return false;
52 return true;
55 public static String toString(final ObjectId i) {
56 return i != null ? i.toString() : ZEROID_STR;
59 public static ObjectId fromString(final byte[] i, int offset) {
60 final byte[] id = new byte[Constants.OBJECT_ID_LENGTH];
61 for (int k = 0; k < Constants.OBJECT_ID_LENGTH; k++) {
62 final byte c1 = i[offset++];
63 final byte c2 = i[offset++];
64 int b;
66 if ('0' <= c1 && c1 <= '9')
67 b = c1 - '0';
68 else if ('a' <= c1 && c1 <= 'f')
69 b = c1 - 'a' + 10;
70 else
71 throw new IllegalArgumentException("Invalid id: " + (char) c1);
73 b <<= 4;
75 if ('0' <= c2 && c2 <= '9')
76 b |= c2 - '0';
77 else if ('a' <= c2 && c2 <= 'f')
78 b |= c2 - 'a' + 10;
79 else
80 throw new IllegalArgumentException("Invalid id: " + (char) c2);
81 id[k] = (byte) b;
83 return new ObjectId(id);
86 public int compareTo(byte[] b, long pos) {
87 for (int k = 0; k < Constants.OBJECT_ID_LENGTH; k++) {
88 final int ak = id[k] & 0xff;
89 final int bk = b[k + (int)pos] & 0xff;
90 if (ak < bk)
91 return -1;
92 else if (ak > bk)
93 return 1;
95 return 0;
98 private static int compare(final byte[] a, final byte[] b) {
99 for (int k = 0 ; k < Constants.OBJECT_ID_LENGTH; k++) {
100 final int ak = a[k] & 0xff;
101 final int bk = b[k] & 0xff;
102 if (ak < bk)
103 return -1;
104 else if (ak > bk)
105 return 1;
107 if (a.length != Constants.OBJECT_ID_LENGTH)
108 throw new IllegalArgumentException("Looks like a bad object id");
109 if (b.length != Constants.OBJECT_ID_LENGTH)
110 throw new IllegalArgumentException("Looks like a bad object id");
111 return 0;
114 private final byte[] id;
116 public ObjectId(final String i) {
117 if (i.length() != (2 * Constants.OBJECT_ID_LENGTH)) {
118 throw new IllegalArgumentException("Invalid id \"" + i
119 + "\"; length = " + i.length());
122 id = new byte[Constants.OBJECT_ID_LENGTH];
123 char[] bs = new char[Constants.OBJECT_ID_LENGTH*2];
124 i.getChars(0,Constants.OBJECT_ID_LENGTH*2,bs,0);
125 for (int j = 0, k = 0; k < Constants.OBJECT_ID_LENGTH; k++) {
126 final char c1 = bs[j++];
127 final char c2 = bs[j++];
128 int b;
130 if ('0' <= c1 && c1 <= '9') {
131 b = c1 - '0';
132 } else if ('a' <= c1 && c1 <= 'f') {
133 b = c1 - 'a' + 10;
134 } else {
135 throw new IllegalArgumentException("Invalid id: " + i);
138 b <<= 4;
140 if ('0' <= c2 && c2 <= '9') {
141 b |= c2 - '0';
142 } else if ('a' <= c2 && c2 <= 'f') {
143 b |= c2 - 'a' + 10;
144 } else {
145 throw new IllegalArgumentException("Invalid id: " + i);
148 id[k] = (byte) b;
152 public ObjectId(final byte[] i) {
153 id = i;
156 public int getFirstByte() {
157 return id[0] & 0xff;
160 public byte[] getBytes() {
161 return id;
164 public int compareTo(final byte[] b) {
165 return b != null ? compare(id, b) : 1;
168 public int compareTo(final ObjectId b) {
169 return b != null ? compare(id, b.id) : 1;
172 public int compareTo(final Object o) {
173 if (o instanceof ObjectId) {
174 return compare(id, ((ObjectId) o).id);
175 } else if (o instanceof byte[]) {
176 return compare(id, (byte[]) o);
178 return 1;
181 public int hashCode() {
182 // Object Id' are well distributed so grab the first four bytes
183 int b0 = id[0] & 0xff;
184 int b1 = id[1] & 0xff;
185 int b2 = id[2] & 0xff;
186 int b3 = id[3] & 0xff;
187 int h = (b0 << 24) | (b1 << 16) | (b2 << 8) | b3;
188 return h;
191 public boolean equals(final ObjectId o) {
192 return compareTo(o) == 0;
195 public boolean equals(final Object o) {
196 return compareTo(o) == 0;
199 public void copyTo(final OutputStream w) throws IOException {
200 for (int k = 0; k < Constants.OBJECT_ID_LENGTH; k++) {
201 final int b = id[k];
202 final int b1 = (b >> 4) & 0xf;
203 final int b2 = b & 0xf;
204 w.write(b1 < 10 ? (char) ('0' + b1) : (char) ('a' + b1 - 10));
205 w.write(b2 < 10 ? (char) ('0' + b2) : (char) ('a' + b2 - 10));
209 public void copyTo(final Writer w) throws IOException {
210 for (int k = 0; k < Constants.OBJECT_ID_LENGTH; k++) {
211 final int b = id[k];
212 final int b1 = (b >> 4) & 0xf;
213 final int b2 = b & 0xf;
214 w.write(b1 < 10 ? (char) ('0' + b1) : (char) ('a' + b1 - 10));
215 w.write(b2 < 10 ? (char) ('0' + b2) : (char) ('a' + b2 - 10));
219 public String toString() {
220 byte s[] = new byte[Constants.OBJECT_ID_LENGTH*2];
221 int i = 0;
222 for (int k = 0; k < Constants.OBJECT_ID_LENGTH; k++) {
223 final int b = id[k];
224 final int b1 = (b >> 4) & 0xf;
225 final int b2 = b & 0xf;
226 s[i++] = (b1 < 10 ? (byte) ('0' + b1) : (byte) ('a' + b1 - 10));
227 s[i++] = (b2 < 10 ? (byte) ('0' + b2) : (byte) ('a' + b2 - 10));
229 return new String(s,0);