package freenet.crypt; import java.io.FilterOutputStream; import java.io.OutputStream; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.ArrayList; import freenet.support.Logger; public class MultiHashOutputStream extends FilterOutputStream { // Bit flags for generateHashes private Digester[] digesters; class Digester { HashType hashType; MessageDigest digest; Digester(HashType hashType) throws NoSuchAlgorithmException { this.hashType= hashType; digest = hashType.get(); } HashResult getResult() { HashResult result = new HashResult(hashType, digest.digest()); hashType.recycle(digest); digest = null; return result; } } public MultiHashOutputStream(OutputStream proxy, long generateHashes) { super(proxy); ArrayList<Digester> digesters = new ArrayList<Digester>(); for(HashType type : HashType.values()) { if((generateHashes & type.bitmask) == type.bitmask) { try { digesters.add(new Digester(type)); } catch (NoSuchAlgorithmException e) { Logger.error(this, "Algorithm not available: "+type); } } } this.digesters = digesters.toArray(new Digester[digesters.size()]); } @Override public void write(int arg0) throws java.io.IOException { out.write(arg0); for(Digester d : digesters) d.digest.update(new byte[] { (byte)arg0 }); } @Override public void write(byte[] arg0) throws java.io.IOException { out.write(arg0); for(Digester d : digesters) d.digest.update(arg0); } @Override public void write(byte[] arg0, int arg1, int arg2) throws java.io.IOException { out.write(arg0, arg1, arg2); for(Digester d : digesters) d.digest.update(arg0, arg1, arg2); } public HashResult[] getResults() { HashResult[] results = new HashResult[digesters.length]; for(int i=0;i<digesters.length;i++) results[i] = digesters[i].getResult(); digesters = null; return results; } }