1 /* 2 * Copyright (C) 2011 The Guava Authors 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.google.common.hash; 18 19 import static com.google.common.base.Preconditions.checkNotNull; 20 21 import java.nio.charset.Charset; 22 23 /** 24 * An abstract composition of multiple hash functions. {@linkplain #newHasher()} delegates to the 25 * {@code Hasher} objects of the delegate hash functions, and in the end, they are used by 26 * {@linkplain #makeHash(Hasher[])} that constructs the final {@code HashCode}. 27 * 28 * @author Dimitris Andreou 29 */ 30 abstract class AbstractCompositeHashFunction extends AbstractStreamingHashFunction { 31 final HashFunction[] functions; 32 AbstractCompositeHashFunction(HashFunction... functions)33 AbstractCompositeHashFunction(HashFunction... functions) { 34 for (HashFunction function : functions) { 35 checkNotNull(function); 36 } 37 this.functions = functions; 38 } 39 40 /** 41 * Constructs a {@code HashCode} from the {@code Hasher} objects of the functions. Each of them 42 * has consumed the entire input and they are ready to output a {@code HashCode}. The order of 43 * the hashers are the same order as the functions given to the constructor. 44 */ 45 // this could be cleaner if it passed HashCode[], but that would create yet another array... makeHash(Hasher[] hashers)46 /* protected */ abstract HashCode makeHash(Hasher[] hashers); 47 48 @Override newHasher()49 public Hasher newHasher() { 50 final Hasher[] hashers = new Hasher[functions.length]; 51 for (int i = 0; i < hashers.length; i++) { 52 hashers[i] = functions[i].newHasher(); 53 } 54 return new Hasher() { 55 @Override public Hasher putByte(byte b) { 56 for (Hasher hasher : hashers) { 57 hasher.putByte(b); 58 } 59 return this; 60 } 61 62 @Override public Hasher putBytes(byte[] bytes) { 63 for (Hasher hasher : hashers) { 64 hasher.putBytes(bytes); 65 } 66 return this; 67 } 68 69 @Override public Hasher putBytes(byte[] bytes, int off, int len) { 70 for (Hasher hasher : hashers) { 71 hasher.putBytes(bytes, off, len); 72 } 73 return this; 74 } 75 76 @Override public Hasher putShort(short s) { 77 for (Hasher hasher : hashers) { 78 hasher.putShort(s); 79 } 80 return this; 81 } 82 83 @Override public Hasher putInt(int i) { 84 for (Hasher hasher : hashers) { 85 hasher.putInt(i); 86 } 87 return this; 88 } 89 90 @Override public Hasher putLong(long l) { 91 for (Hasher hasher : hashers) { 92 hasher.putLong(l); 93 } 94 return this; 95 } 96 97 @Override public Hasher putFloat(float f) { 98 for (Hasher hasher : hashers) { 99 hasher.putFloat(f); 100 } 101 return this; 102 } 103 104 @Override public Hasher putDouble(double d) { 105 for (Hasher hasher : hashers) { 106 hasher.putDouble(d); 107 } 108 return this; 109 } 110 111 @Override public Hasher putBoolean(boolean b) { 112 for (Hasher hasher : hashers) { 113 hasher.putBoolean(b); 114 } 115 return this; 116 } 117 118 @Override public Hasher putChar(char c) { 119 for (Hasher hasher : hashers) { 120 hasher.putChar(c); 121 } 122 return this; 123 } 124 125 /** 126 * @deprecated Use {@link Hasher#putUnencodedChars} instead. 127 */ 128 @Deprecated 129 @Override public Hasher putString(CharSequence chars) { 130 return putUnencodedChars(chars); 131 } 132 133 @Override public Hasher putUnencodedChars(CharSequence chars) { 134 for (Hasher hasher : hashers) { 135 hasher.putUnencodedChars(chars); 136 } 137 return this; 138 } 139 140 @Override public Hasher putString(CharSequence chars, Charset charset) { 141 for (Hasher hasher : hashers) { 142 hasher.putString(chars, charset); 143 } 144 return this; 145 } 146 147 @Override public <T> Hasher putObject(T instance, Funnel<? super T> funnel) { 148 for (Hasher hasher : hashers) { 149 hasher.putObject(instance, funnel); 150 } 151 return this; 152 } 153 154 @Override public HashCode hash() { 155 return makeHash(hashers); 156 } 157 }; 158 } 159 160 private static final long serialVersionUID = 0L; 161 } 162