Mercurial > hg4j
comparison src/org/tmatesoft/hg/core/Nodeid.java @ 500:465316bf97e8
Tailored subclass of IAE for malformed Nodeids:HgBadNodeidFormatException
author | Artem Tikhomirov <tikhomirov.artem@gmail.com> |
---|---|
date | Mon, 29 Oct 2012 18:16:21 +0100 |
parents | 85b8efde5586 |
children | d9c07e1432c4 |
comparison
equal
deleted
inserted
replaced
499:899a1b68ef03 | 500:465316bf97e8 |
---|---|
42 private final byte[] binaryData; | 42 private final byte[] binaryData; |
43 | 43 |
44 /** | 44 /** |
45 * @param binaryRepresentation - array of exactly 20 bytes | 45 * @param binaryRepresentation - array of exactly 20 bytes |
46 * @param shallClone - true if array is subject to future modification and shall be copied, not referenced | 46 * @param shallClone - true if array is subject to future modification and shall be copied, not referenced |
47 * @throws IllegalArgumentException if supplied binary representation doesn't correspond to 20 bytes of sha1 digest | 47 * @throws HgBadNodeidFormatException custom {@link IllegalArgumentException} subclass if supplied binary representation doesn't correspond to 20 bytes of sha1 digest |
48 */ | 48 */ |
49 public Nodeid(byte[] binaryRepresentation, boolean shallClone) { | 49 public Nodeid(byte[] binaryRepresentation, boolean shallClone) { |
50 // 5 int fields => 32 bytes | 50 // 5 int fields => 32 bytes |
51 // byte[20] => 48 bytes (16 bytes is Nodeid with one field, 32 bytes for byte[20] | 51 // byte[20] => 48 bytes (16 bytes is Nodeid with one field, 32 bytes for byte[20] |
52 if (binaryRepresentation == null || binaryRepresentation.length != 20) { | 52 if (binaryRepresentation == null || binaryRepresentation.length != 20) { |
53 throw new IllegalArgumentException(); | 53 throw new HgBadNodeidFormatException(String.format("Bad value: %s", String.valueOf(binaryRepresentation))); |
54 } | 54 } |
55 /* | 55 /* |
56 * byte[].clone() is not reflected when ran with -agentlib:hprof=heap=sites | 56 * byte[].clone() is not reflected when ran with -agentlib:hprof=heap=sites |
57 * thus not to get puzzled why there are N Nodeids and much less byte[] instances, | 57 * thus not to get puzzled why there are N Nodeids and much less byte[] instances, |
58 * may use following code to see N byte[] as well. | 58 * may use following code to see N byte[] as well. |
138 * Factory for {@link Nodeid Nodeids}. | 138 * Factory for {@link Nodeid Nodeids}. |
139 * Primary difference with cons is handling of NULL id (this method returns constant) and control over array | 139 * Primary difference with cons is handling of NULL id (this method returns constant) and control over array |
140 * duplication - this method always makes a copy of an array passed | 140 * duplication - this method always makes a copy of an array passed |
141 * @param binaryRepresentation - byte array of a length at least offset + 20 | 141 * @param binaryRepresentation - byte array of a length at least offset + 20 |
142 * @param offset - index in the array to start from | 142 * @param offset - index in the array to start from |
143 * @throws IllegalArgumentException when arguments don't select 20 bytes | 143 * @throws HgBadNodeidFormatException custom {@link IllegalArgumentException} subclass when arguments don't select 20 bytes |
144 */ | 144 */ |
145 public static Nodeid fromBinary(byte[] binaryRepresentation, int offset) { | 145 public static Nodeid fromBinary(byte[] binaryRepresentation, int offset) { |
146 if (binaryRepresentation == null || binaryRepresentation.length - offset < 20) { | 146 if (binaryRepresentation == null || binaryRepresentation.length - offset < 20) { |
147 throw new IllegalArgumentException(); | 147 throw new HgBadNodeidFormatException(String.format("Bad value: %s", String.valueOf(binaryRepresentation))); |
148 } | 148 } |
149 int i = 0; | 149 int i = 0; |
150 while (i < 20 && binaryRepresentation[offset+i] == 0) i++; | 150 while (i < 20 && binaryRepresentation[offset+i] == 0) i++; |
151 if (i == 20) { | 151 if (i == 20) { |
152 return NULL; | 152 return NULL; |
162 /** | 162 /** |
163 * Parse encoded representation. | 163 * Parse encoded representation. |
164 * | 164 * |
165 * @param asciiRepresentation - encoded form of the Nodeid. | 165 * @param asciiRepresentation - encoded form of the Nodeid. |
166 * @return object representation | 166 * @return object representation |
167 * @throws IllegalArgumentException when argument doesn't match encoded form of 20-bytes sha1 digest. | 167 * @throws HgBadNodeidFormatException custom {@link IllegalArgumentException} subclass when argument doesn't match encoded form of 20-bytes sha1 digest. |
168 */ | 168 */ |
169 public static Nodeid fromAscii(String asciiRepresentation) { | 169 public static Nodeid fromAscii(String asciiRepresentation) { |
170 if (asciiRepresentation.length() != 40) { | 170 if (asciiRepresentation.length() != 40) { |
171 throw new IllegalArgumentException(); | 171 throw new HgBadNodeidFormatException(String.format("Bad value: %s", asciiRepresentation)); |
172 } | 172 } |
173 // XXX is better impl for String possible? | 173 // XXX is better impl for String possible? |
174 return fromAscii(asciiRepresentation.toCharArray(), 0, 40); | 174 return fromAscii(asciiRepresentation.toCharArray(), 0, 40); |
175 } | 175 } |
176 | 176 |
177 /** | 177 /** |
178 * Parse encoded representation. Similar to {@link #fromAscii(String)}. | 178 * Parse encoded representation. Similar to {@link #fromAscii(String)}. |
179 * @throws HgBadNodeidFormatException custom {@link IllegalArgumentException} subclass when bytes are not hex digits or number of bytes != 40 (160 bits) | |
179 */ | 180 */ |
180 public static Nodeid fromAscii(byte[] asciiRepresentation, int offset, int length) { | 181 public static Nodeid fromAscii(byte[] asciiRepresentation, int offset, int length) { |
181 if (length != 40) { | 182 if (length != 40) { |
182 throw new IllegalArgumentException(); | 183 throw new IllegalArgumentException(); |
183 } | 184 } |
184 byte[] data = new byte[20]; | 185 try { |
185 boolean zeroBytes = DigestHelper.ascii2bin(asciiRepresentation, offset, length, data); | 186 byte[] data = new byte[20]; |
186 if (zeroBytes) { | 187 boolean zeroBytes = DigestHelper.ascii2bin(asciiRepresentation, offset, length, data); |
187 return NULL; | 188 if (zeroBytes) { |
188 } | 189 return NULL; |
189 return new Nodeid(data, false); | 190 } |
191 return new Nodeid(data, false); | |
192 } catch (IllegalArgumentException ex) { | |
193 throw new HgBadNodeidFormatException(ex.getMessage()); | |
194 } | |
190 } | 195 } |
191 | 196 |
192 public static Nodeid fromAscii(char[] asciiRepresentation, int offset, int length) { | 197 public static Nodeid fromAscii(char[] asciiRepresentation, int offset, int length) { |
193 byte[] b = new byte[length]; | 198 byte[] b = new byte[length]; |
194 for (int i = 0; i < b.length; i++) { | 199 for (int i = 0; i < b.length; i++) { |