2 * Copyright (C) 2008, Robin Rosenberg <robin.rosenberg@dewire.com>
3 * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
7 * Redistribution and use in source and binary forms, with or
8 * without modification, are permitted provided that the following
11 * - Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
14 * - Redistributions in binary form must reproduce the above
15 * copyright notice, this list of conditions and the following
16 * disclaimer in the documentation and/or other materials provided
17 * with the distribution.
19 * - Neither the name of the Git Development Community nor the
20 * names of its contributors may be used to endorse or promote
21 * products derived from this software without specific prior
24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
25 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
26 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
27 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
29 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
31 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
32 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
33 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
34 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
36 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39 package org
.spearce
.jgit
.lib
;
41 import java
.io
.UnsupportedEncodingException
;
43 import org
.spearce
.jgit
.util
.NB
;
46 * A SHA-1 abstraction.
48 public class ObjectId
extends AnyObjectId
{
49 private static final ObjectId ZEROID
;
51 private static final String ZEROID_STR
;
54 ZEROID
= new ObjectId(0, 0, 0, 0, 0);
55 ZEROID_STR
= ZEROID
.toString();
59 * Get the special all-null ObjectId.
61 * @return the all-null ObjectId, often used to stand-in for no object.
63 public static final ObjectId
zeroId() {
68 * Test a string of characters to verify it is a hex format.
70 * If true the string can be parsed with {@link #fromString(String)}.
74 * @return true if the string can converted into an ObjectId.
76 public static final boolean isId(final String id
) {
77 if (id
.length() != 2 * Constants
.OBJECT_ID_LENGTH
)
80 for (int k
= id
.length() - 1; k
>= 0; k
--)
81 if (fromhex
[id
.charAt(k
)] < 0)
84 } catch (ArrayIndexOutOfBoundsException e
) {
90 * Convert an ObjectId into a hex string representation.
93 * the id to convert. May be null.
94 * @return the hex string conversion of this id's content.
96 public static final String
toString(final ObjectId i
) {
97 return i
!= null ? i
.toString() : ZEROID_STR
;
101 * Compare to object identifier byte sequences for equality.
104 * the first buffer to compare against. Must have at least 20
105 * bytes from position ai through the end of the buffer.
107 * first offset within firstBuffer to begin testing.
108 * @param secondBuffer
109 * the second buffer to compare against. Must have at least 2
110 * bytes from position bi through the end of the buffer.
112 * first offset within secondBuffer to begin testing.
113 * @return true if the two identifiers are the same.
115 public static boolean equals(final byte[] firstBuffer
, final int fi
,
116 final byte[] secondBuffer
, final int si
) {
117 return firstBuffer
[fi
] == secondBuffer
[si
]
118 && firstBuffer
[fi
+ 1] == secondBuffer
[si
+ 1]
119 && firstBuffer
[fi
+ 2] == secondBuffer
[si
+ 2]
120 && firstBuffer
[fi
+ 3] == secondBuffer
[si
+ 3]
121 && firstBuffer
[fi
+ 4] == secondBuffer
[si
+ 4]
122 && firstBuffer
[fi
+ 5] == secondBuffer
[si
+ 5]
123 && firstBuffer
[fi
+ 6] == secondBuffer
[si
+ 6]
124 && firstBuffer
[fi
+ 7] == secondBuffer
[si
+ 7]
125 && firstBuffer
[fi
+ 8] == secondBuffer
[si
+ 8]
126 && firstBuffer
[fi
+ 9] == secondBuffer
[si
+ 9]
127 && firstBuffer
[fi
+ 10] == secondBuffer
[si
+ 10]
128 && firstBuffer
[fi
+ 11] == secondBuffer
[si
+ 11]
129 && firstBuffer
[fi
+ 12] == secondBuffer
[si
+ 12]
130 && firstBuffer
[fi
+ 13] == secondBuffer
[si
+ 13]
131 && firstBuffer
[fi
+ 14] == secondBuffer
[si
+ 14]
132 && firstBuffer
[fi
+ 15] == secondBuffer
[si
+ 15]
133 && firstBuffer
[fi
+ 16] == secondBuffer
[si
+ 16]
134 && firstBuffer
[fi
+ 17] == secondBuffer
[si
+ 17]
135 && firstBuffer
[fi
+ 18] == secondBuffer
[si
+ 18]
136 && firstBuffer
[fi
+ 19] == secondBuffer
[si
+ 19];
140 * Convert an ObjectId from raw binary representation.
143 * the raw byte buffer to read from. At least 20 bytes must be
144 * available within this byte array.
145 * @return the converted object id.
147 public static final ObjectId
fromRaw(final byte[] bs
) {
148 return fromRaw(bs
, 0);
152 * Convert an ObjectId from raw binary representation.
155 * the raw byte buffer to read from. At least 20 bytes after p
156 * must be available within this byte array.
158 * position to read the first byte of data from.
159 * @return the converted object id.
161 public static final ObjectId
fromRaw(final byte[] bs
, final int p
) {
162 final int a
= NB
.decodeInt32(bs
, p
);
163 final int b
= NB
.decodeInt32(bs
, p
+ 4);
164 final int c
= NB
.decodeInt32(bs
, p
+ 8);
165 final int d
= NB
.decodeInt32(bs
, p
+ 12);
166 final int e
= NB
.decodeInt32(bs
, p
+ 16);
167 return new ObjectId(a
, b
, c
, d
, e
);
171 * Convert an ObjectId from hex characters (US-ASCII).
174 * the US-ASCII buffer to read from. At least 40 bytes after
175 * offset must be available within this byte array.
177 * position to read the first character from.
178 * @return the converted object id.
180 public static final ObjectId
fromString(final byte[] buf
, final int offset
) {
181 return fromHexString(buf
, offset
);
185 * Convert an ObjectId from hex characters.
188 * the string to read from. Must be 40 characters long.
189 * @return the converted object id.
191 public static final ObjectId
fromString(final String str
) {
192 if (str
.length() != STR_LEN
)
193 throw new IllegalArgumentException("Invalid id: " + str
);
194 return fromHexString(Constants
.encodeASCII(str
), 0);
197 private static final ObjectId
fromHexString(final byte[] bs
, int p
) {
199 final int a
= hexUInt32(bs
, p
);
200 final int b
= hexUInt32(bs
, p
+ 8);
201 final int c
= hexUInt32(bs
, p
+ 16);
202 final int d
= hexUInt32(bs
, p
+ 24);
203 final int e
= hexUInt32(bs
, p
+ 32);
204 return new ObjectId(a
, b
, c
, d
, e
);
205 } catch (ArrayIndexOutOfBoundsException e1
) {
207 final String str
= new String(bs
, p
, STR_LEN
, "US-ASCII");
208 throw new IllegalArgumentException("Invalid id: " + str
);
209 } catch (UnsupportedEncodingException e2
) {
210 throw new IllegalArgumentException("Invalid id");
215 protected ObjectId(final int new_1
, final int new_2
, final int new_3
,
216 final int new_4
, final int new_5
) {
225 * Initialize this instance by copying another existing ObjectId.
227 * This constructor is mostly useful for subclasses who want to extend an
228 * ObjectId with more properties, but initialize from an existing ObjectId
229 * instance acquired by other means.
232 * another already parsed ObjectId to copy the value out of.
234 protected ObjectId(final AnyObjectId src
) {
243 public ObjectId
toObjectId() {