/* * Copyright (c) 2014, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. * */ package com.facebook.crypto.streams; import com.facebook.crypto.mac.NativeMac; import java.io.IOException; import java.io.OutputStream; public class NativeMacLayeredOutputStream extends OutputStream { private final NativeMac mMac; private final OutputStream mOutputDelegate; private boolean mMacAppended = false; /** * Creates a new output stream to write to. * * @param mac The object used to compute the mac. * @param outputDelegate The stream to write data to. */ public NativeMacLayeredOutputStream(NativeMac mac, OutputStream outputDelegate) { mMac = mac; mOutputDelegate = outputDelegate; } @Override public void close() throws IOException { try { appendMac(); } finally { mOutputDelegate.close(); } } private void appendMac() throws IOException { if (mMacAppended) { return; } mMacAppended = true; try { byte[] mac = mMac.doFinal(); mOutputDelegate.write(mac); } finally { mMac.destroy(); } } @Override public void flush() throws IOException { mOutputDelegate.flush(); } @Override public void write(byte[] buffer) throws IOException { write(buffer, 0, buffer.length); } @Override public void write(byte[] buffer, int offset, int count) throws IOException { mMac.update(buffer, offset, count); mOutputDelegate.write(buffer, offset, count); } @Override public void write(int oneByte) throws IOException { mMac.update((byte) oneByte); mOutputDelegate.write(oneByte); } }