1/* 2 * Copyright (C) 2011 The Guava Authors 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 * in compliance with the License. You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software distributed under the License 10 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 * or implied. See the License for the specific language governing permissions and limitations under 12 * the License. 13 */ 14 15package com.google.common.hash; 16 17/** 18 * Static factories for {@link HashCode} instances. 19 * 20 * @author andreou@google.com (Dimitris Andreou) 21 */ 22final class HashCodes { 23 private HashCodes() { } 24 25 /** 26 * Creates a 32-bit {@code HashCode}, of which the bytes will form the passed int, interpreted 27 * in little endian order. 28 */ 29 static HashCode fromInt(int hash) { 30 return new IntHashCode(hash); 31 } 32 33 private static class IntHashCode extends HashCode { 34 final int hash; 35 36 IntHashCode(int hash) { 37 this.hash = hash; 38 } 39 40 @Override public int bits() { 41 return 32; 42 } 43 44 @Override public byte[] asBytes() { 45 return new byte[] { 46 (byte) hash, 47 (byte) (hash >> 8), 48 (byte) (hash >> 16), 49 (byte) (hash >> 24)}; 50 } 51 52 @Override public int asInt() { 53 return hash; 54 } 55 56 @Override public long asLong() { 57 throw new IllegalStateException("this HashCode only has 32 bits; cannot create a long"); 58 } 59 } 60 61 /** 62 * Creates a 64-bit {@code HashCode}, of which the bytes will form the passed long, interpreted 63 * in little endian order. 64 */ 65 static HashCode fromLong(long hash) { 66 return new LongHashCode(hash); 67 } 68 69 private static class LongHashCode extends HashCode { 70 final long hash; 71 72 LongHashCode(long hash) { 73 this.hash = hash; 74 } 75 76 @Override public int bits() { 77 return 64; 78 } 79 80 @Override public byte[] asBytes() { 81 return new byte[] { 82 (byte) hash, 83 (byte) (hash >> 8), 84 (byte) (hash >> 16), 85 (byte) (hash >> 24), 86 (byte) (hash >> 32), 87 (byte) (hash >> 40), 88 (byte) (hash >> 48), 89 (byte) (hash >> 56)}; 90 } 91 92 @Override public int asInt() { 93 return (int) hash; 94 } 95 96 @Override public long asLong() { 97 return hash; 98 } 99 } 100 101 /** 102 * Creates a {@code HashCode} from a byte array. The array is <i>not</i> copied defensively, 103 * so it must be handed-off so as to preserve the immutability contract of {@code HashCode}. 104 * The array must be at least of length 4 (not checked). 105 */ 106 static HashCode fromBytes(byte[] bytes) { 107 return new BytesHashCode(bytes); 108 } 109 110 private static class BytesHashCode extends HashCode { 111 final byte[] bytes; 112 113 BytesHashCode(byte[] bytes) { 114 this.bytes = bytes; 115 } 116 117 @Override public int bits() { 118 return bytes.length * 8; 119 } 120 121 @Override public byte[] asBytes() { 122 return bytes.clone(); 123 } 124 125 @Override public int asInt() { 126 return (bytes[0] & 0xFF) 127 | ((bytes[1] & 0xFF) << 8) 128 | ((bytes[2] & 0xFF) << 16) 129 | ((bytes[3] & 0xFF) << 24); 130 } 131 132 @Override public long asLong() { 133 if (bytes.length < 8) { 134 // Checking this to throw the correct type of exception 135 throw new IllegalStateException("Not enough bytes"); 136 } 137 return (bytes[0] & 0xFFL) 138 | ((bytes[1] & 0xFFL) << 8) 139 | ((bytes[2] & 0xFFL) << 16) 140 | ((bytes[3] & 0xFFL) << 24) 141 | ((bytes[4] & 0xFFL) << 32) 142 | ((bytes[5] & 0xFFL) << 40) 143 | ((bytes[6] & 0xFFL) << 48) 144 | ((bytes[7] & 0xFFL) << 56); 145 } 146 } 147} 148