Mercurial > hg4j
comparison src/org/tmatesoft/hg/core/Nodeid.java @ 74:6f1b88693d48
Complete refactoring to org.tmatesoft
author | Artem Tikhomirov <tikhomirov.artem@gmail.com> |
---|---|
date | Mon, 24 Jan 2011 03:14:45 +0100 |
parents | src/com/tmate/hgkit/ll/Nodeid.java@4022c34a4804 |
children | c25c5c348d1b |
comparison
equal
deleted
inserted
replaced
73:0d279bcc4442 | 74:6f1b88693d48 |
---|---|
1 /* | |
2 * Copyright (c) 2010-2011 TMate Software Ltd | |
3 * | |
4 * This program is free software; you can redistribute it and/or modify | |
5 * it under the terms of the GNU General Public License as published by | |
6 * the Free Software Foundation; version 2 of the License. | |
7 * | |
8 * This program 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 | |
11 * GNU General Public License for more details. | |
12 * | |
13 * For information on how to redistribute this software under | |
14 * the terms of a license other than GNU General Public License | |
15 * contact TMate Software at support@svnkit.com | |
16 */ | |
17 package org.tmatesoft.hg.core; | |
18 | |
19 import static org.tmatesoft.hg.internal.DigestHelper.toHexString; | |
20 | |
21 import java.util.Arrays; | |
22 | |
23 | |
24 | |
25 /** | |
26 * A 20-bytes (40 characters) long hash value to identify a revision. | |
27 * @see http://mercurial.selenic.com/wiki/Nodeid | |
28 * | |
29 * @author Artem Tikhomirov | |
30 * @author TMate Software Ltd. | |
31 * | |
32 */ | |
33 public final class Nodeid { | |
34 | |
35 /** | |
36 * <b>nullid</b>, empty root revision. | |
37 */ | |
38 public static final Nodeid NULL = new Nodeid(new byte[20], false); | |
39 | |
40 private final byte[] binaryData; | |
41 | |
42 /** | |
43 * @param binaryRepresentation - array of exactly 20 bytes | |
44 * @param shallClone - true if array is subject to future modification and shall be copied, not referenced | |
45 */ | |
46 public Nodeid(byte[] binaryRepresentation, boolean shallClone) { | |
47 // 5 int fields => 32 bytes | |
48 // byte[20] => 48 bytes | |
49 if (binaryRepresentation == null || binaryRepresentation.length != 20) { | |
50 throw new IllegalArgumentException(); | |
51 } | |
52 this.binaryData = shallClone ? binaryRepresentation.clone() : binaryRepresentation; | |
53 } | |
54 | |
55 @Override | |
56 public int hashCode() { | |
57 // digest (part thereof) seems to be nice candidate for the hashCode | |
58 byte[] b = binaryData; | |
59 return b[0] << 24 | (b[1] & 0xFF) << 16 | (b[2] & 0xFF) << 8 | (b[3] & 0xFF); | |
60 } | |
61 | |
62 @Override | |
63 public boolean equals(Object o) { | |
64 if (o instanceof Nodeid) { | |
65 return Arrays.equals(this.binaryData, ((Nodeid) o).binaryData); | |
66 } | |
67 return false; | |
68 } | |
69 | |
70 public boolean equalsTo(byte[] buf) { | |
71 return Arrays.equals(this.binaryData, buf); | |
72 } | |
73 | |
74 @Override | |
75 public String toString() { | |
76 // XXX may want to output just single 0 for the NULL id? | |
77 return toHexString(binaryData, 0, binaryData.length); | |
78 } | |
79 | |
80 public String shortNotation() { | |
81 return toHexString(binaryData, 0, 6); | |
82 } | |
83 | |
84 public boolean isNull() { | |
85 if (this == NULL) { | |
86 return true; | |
87 } | |
88 for (int i = 0; i < 20; i++) { | |
89 if (this.binaryData[i] != 0) { | |
90 return false; | |
91 } | |
92 } | |
93 return true; | |
94 } | |
95 | |
96 // copy | |
97 public byte[] toByteArray() { | |
98 return binaryData.clone(); | |
99 } | |
100 | |
101 // primary difference with cons is handling of NULL id (this method returns constant) | |
102 // always makes a copy of an array passed | |
103 public static Nodeid fromBinary(byte[] binaryRepresentation, int offset) { | |
104 if (binaryRepresentation == null || binaryRepresentation.length - offset < 20) { | |
105 throw new IllegalArgumentException(); | |
106 } | |
107 int i = 0; | |
108 while (i < 20 && binaryRepresentation[offset+i] == 0) i++; | |
109 if (i == 20) { | |
110 return NULL; | |
111 } | |
112 if (offset == 0 && binaryRepresentation.length == 20) { | |
113 return new Nodeid(binaryRepresentation, true); | |
114 } | |
115 byte[] b = new byte[20]; // create new instance if no other reasonable guesses possible | |
116 System.arraycopy(binaryRepresentation, offset, b, 0, 20); | |
117 return new Nodeid(b, false); | |
118 } | |
119 | |
120 public static Nodeid fromAscii(byte[] asciiRepresentation, int offset, int length) { | |
121 if (length != 40) { | |
122 throw new IllegalArgumentException(); | |
123 } | |
124 byte[] data = new byte[20]; | |
125 boolean zeroBytes = true; | |
126 for (int i = 0, j = offset; i < data.length; i++) { | |
127 int hiNibble = Character.digit(asciiRepresentation[j++], 16); | |
128 int lowNibble = Character.digit(asciiRepresentation[j++], 16); | |
129 byte b = (byte) (((hiNibble << 4) | lowNibble) & 0xFF); | |
130 data[i] = b; | |
131 zeroBytes = zeroBytes && b == 0; | |
132 } | |
133 if (zeroBytes) { | |
134 return NULL; | |
135 } | |
136 return new Nodeid(data, false); | |
137 } | |
138 } |