1 // Copyright 2011 Google Inc. All Rights Reserved. 2 3 package com.google.common.hash; 4 5 import java.nio.charset.Charset; 6 7 /** 8 * An abstract composition of multiple hash functions. {@linkplain #newHasher()} delegates to the 9 * {@code Hasher} objects of the delegate hash functions, and in the end, they are used by 10 * {@linkplain #makeHash(Hasher[])} that constructs the final {@code HashCode}. 11 * 12 * @author andreou@google.com (Dimitris Andreou) 13 */ 14 abstract class AbstractCompositeHashFunction extends AbstractStreamingHashFunction { 15 final HashFunction[] functions; 16 AbstractCompositeHashFunction(HashFunction... functions)17 AbstractCompositeHashFunction(HashFunction... functions) { 18 this.functions = functions; 19 } 20 21 /** 22 * Constructs a {@code HashCode} from the {@code Hasher} objects of the functions. Each of them 23 * has consumed the entire input and they are ready to output a {@code HashCode}. The order of 24 * the hashers are the same order as the functions given to the constructor. 25 */ 26 // this could be cleaner if it passed HashCode[], but that would create yet another array... makeHash(Hasher[] hashers)27 /* protected */ abstract HashCode makeHash(Hasher[] hashers); 28 29 @Override newHasher()30 public Hasher newHasher() { 31 final Hasher[] hashers = new Hasher[functions.length]; 32 for (int i = 0; i < hashers.length; i++) { 33 hashers[i] = functions[i].newHasher(); 34 } 35 return new Hasher() { 36 @Override public Hasher putByte(byte b) { 37 for (Hasher hasher : hashers) { 38 hasher.putByte(b); 39 } 40 return this; 41 } 42 43 @Override public Hasher putBytes(byte[] bytes) { 44 for (Hasher hasher : hashers) { 45 hasher.putBytes(bytes); 46 } 47 return this; 48 } 49 50 @Override public Hasher putBytes(byte[] bytes, int off, int len) { 51 for (Hasher hasher : hashers) { 52 hasher.putBytes(bytes, off, len); 53 } 54 return this; 55 } 56 57 @Override public Hasher putShort(short s) { 58 for (Hasher hasher : hashers) { 59 hasher.putShort(s); 60 } 61 return this; 62 } 63 64 @Override public Hasher putInt(int i) { 65 for (Hasher hasher : hashers) { 66 hasher.putInt(i); 67 } 68 return this; 69 } 70 71 @Override public Hasher putLong(long l) { 72 for (Hasher hasher : hashers) { 73 hasher.putLong(l); 74 } 75 return this; 76 } 77 78 @Override public Hasher putFloat(float f) { 79 for (Hasher hasher : hashers) { 80 hasher.putFloat(f); 81 } 82 return this; 83 } 84 85 @Override public Hasher putDouble(double d) { 86 for (Hasher hasher : hashers) { 87 hasher.putDouble(d); 88 } 89 return this; 90 } 91 92 @Override public Hasher putBoolean(boolean b) { 93 for (Hasher hasher : hashers) { 94 hasher.putBoolean(b); 95 } 96 return this; 97 } 98 99 @Override public Hasher putChar(char c) { 100 for (Hasher hasher : hashers) { 101 hasher.putChar(c); 102 } 103 return this; 104 } 105 106 @Override public Hasher putString(CharSequence chars) { 107 for (Hasher hasher : hashers) { 108 hasher.putString(chars); 109 } 110 return this; 111 } 112 113 @Override public Hasher putString(CharSequence chars, Charset charset) { 114 for (Hasher hasher : hashers) { 115 hasher.putString(chars, charset); 116 } 117 return this; 118 } 119 120 @Override public <T> Hasher putObject(T instance, Funnel<? super T> funnel) { 121 for (Hasher hasher : hashers) { 122 hasher.putObject(instance, funnel); 123 } 124 return this; 125 } 126 127 @Override public HashCode hash() { 128 return makeHash(hashers); 129 } 130 }; 131 } 132 133 private static final long serialVersionUID = 0L; 134 } 135