11d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert/*
21d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Copyright (C) 2011 The Guava Authors
31d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *
41d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
51d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * in compliance with the License. You may obtain a copy of the License at
61d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *
71d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * http://www.apache.org/licenses/LICENSE-2.0
81d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *
91d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Unless required by applicable law or agreed to in writing, software distributed under the License
101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * or implied. See the License for the specific language governing permissions and limitations under
121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * the License.
131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */
141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertpackage com.google.common.hash;
161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert/**
181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Static factories for {@link HashCode} instances.
191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *
201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @author andreou@google.com (Dimitris Andreou)
211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */
221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertfinal class HashCodes {
231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  private HashCodes() { }
241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Creates a 32-bit {@code HashCode}, of which the bytes will form the passed int, interpreted
271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * in little endian order.
281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  static HashCode fromInt(int hash) {
301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return new IntHashCode(hash);
311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  private static class IntHashCode extends HashCode {
341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    final int hash;
351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    IntHashCode(int hash) {
371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      this.hash = hash;
381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public int bits() {
411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return 32;
421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public byte[] asBytes() {
451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return new byte[] {
461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          (byte) hash,
471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          (byte) (hash >> 8),
481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          (byte) (hash >> 16),
491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          (byte) (hash >> 24)};
501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public int asInt() {
531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return hash;
541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public long asLong() {
571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      throw new IllegalStateException("this HashCode only has 32 bits; cannot create a long");
581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Creates a 64-bit {@code HashCode}, of which the bytes will form the passed long, interpreted
631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * in little endian order.
641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  static HashCode fromLong(long hash) {
661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return new LongHashCode(hash);
671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  private static class LongHashCode extends HashCode {
701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    final long hash;
711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    LongHashCode(long hash) {
731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      this.hash = hash;
741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public int bits() {
771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return 64;
781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public byte[] asBytes() {
811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return new byte[] {
821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          (byte) hash,
831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          (byte) (hash >> 8),
841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          (byte) (hash >> 16),
851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          (byte) (hash >> 24),
861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          (byte) (hash >> 32),
871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          (byte) (hash >> 40),
881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          (byte) (hash >> 48),
891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          (byte) (hash >> 56)};
901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public int asInt() {
931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return (int) hash;
941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public long asLong() {
971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return hash;
981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
1001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
1021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Creates a {@code HashCode} from a byte array. The array is <i>not</i> copied defensively,
1031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * so it must be handed-off so as to preserve the immutability contract of {@code HashCode}.
1041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * The array must be at least of length 4 (not checked).
1051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
1061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  static HashCode fromBytes(byte[] bytes) {
1071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return new BytesHashCode(bytes);
1081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
1091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  private static class BytesHashCode extends HashCode {
1111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    final byte[] bytes;
1121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    BytesHashCode(byte[] bytes) {
1141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      this.bytes = bytes;
1151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public int bits() {
1181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return bytes.length * 8;
1191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public byte[] asBytes() {
1221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return bytes.clone();
1231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public int asInt() {
1261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return (bytes[0] & 0xFF)
1271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          | ((bytes[1] & 0xFF) << 8)
1281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          | ((bytes[2] & 0xFF) << 16)
1291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          | ((bytes[3] & 0xFF) << 24);
1301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public long asLong() {
1331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      if (bytes.length < 8) {
1341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        // Checking this to throw the correct type of exception
1351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        throw new IllegalStateException("Not enough bytes");
1361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
1371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return (bytes[0] & 0xFFL)
1381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          | ((bytes[1] & 0xFFL) << 8)
1391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          | ((bytes[2] & 0xFFL) << 16)
1401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          | ((bytes[3] & 0xFFL) << 24)
1411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          | ((bytes[4] & 0xFFL) << 32)
1421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          | ((bytes[5] & 0xFFL) << 40)
1431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          | ((bytes[6] & 0xFFL) << 48)
1441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          | ((bytes[7] & 0xFFL) << 56);
1451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
1471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert}
148