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 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... 46 /* protected */ abstract HashCode makeHash(Hasher[] hashers); 47 48 @Override 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 @Override public Hasher putUnencodedChars(CharSequence chars) { 126 for (Hasher hasher : hashers) { 127 hasher.putUnencodedChars(chars); 128 } 129 return this; 130 } 131 132 @Override public Hasher putString(CharSequence chars, Charset charset) { 133 for (Hasher hasher : hashers) { 134 hasher.putString(chars, charset); 135 } 136 return this; 137 } 138 139 @Override public <T> Hasher putObject(T instance, Funnel<? super T> funnel) { 140 for (Hasher hasher : hashers) { 141 hasher.putObject(instance, funnel); 142 } 143 return this; 144 } 145 146 @Override public HashCode hash() { 147 return makeHash(hashers); 148 } 149 }; 150 } 151 152 private static final long serialVersionUID = 0L; 153 } 154