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
;
29 ZEROID
= new ObjectId(new byte[Constants
.OBJECT_ID_LENGTH
]);
30 ZEROID_STR
= ZEROID
.toString();
33 public static ObjectId
zeroId() {
37 public static final boolean isId(final String id
) {
38 if (id
.length() != (2 * Constants
.OBJECT_ID_LENGTH
)) {
42 for (int k
= id
.length() - 1; k
>= 0; k
--) {
43 final char c
= id
.charAt(k
);
44 if ('0' <= c
&& c
<= '9') {
46 } else if ('a' <= c
&& c
<= 'f') {
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
++];
66 if ('0' <= c1
&& c1
<= '9')
68 else if ('a' <= c1
&& c1
<= 'f')
71 throw new IllegalArgumentException("Invalid id: " + (char) c1
);
75 if ('0' <= c2
&& c2
<= '9')
77 else if ('a' <= c2
&& c2
<= 'f')
80 throw new IllegalArgumentException("Invalid id: " + (char) c2
);
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;
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;
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");
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
++];
130 if ('0' <= c1
&& c1
<= '9') {
132 } else if ('a' <= c1
&& c1
<= 'f') {
135 throw new IllegalArgumentException("Invalid id: " + i
);
140 if ('0' <= c2
&& c2
<= '9') {
142 } else if ('a' <= c2
&& c2
<= 'f') {
145 throw new IllegalArgumentException("Invalid id: " + i
);
152 public ObjectId(final byte[] i
) {
156 public int getFirstByte() {
160 public byte[] getBytes() {
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
);
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
;
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
++) {
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
++) {
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];
222 for (int k
= 0; k
< Constants
.OBJECT_ID_LENGTH
; 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);