Mercurial > jhg
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++) { |
