Mercurial > jhg
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 } |
