Path: blob/master/sourcetools/com.ibm.jpp.preprocessor/com/ibm/jpp/om/PhantomOutputStream.java
6004 views
/*******************************************************************************1* Copyright (c) 1999, 2017 IBM Corp. and others2*3* This program and the accompanying materials are made available under4* the terms of the Eclipse Public License 2.0 which accompanies this5* distribution and is available at https://www.eclipse.org/legal/epl-2.0/6* or the Apache License, Version 2.0 which accompanies this distribution and7* is available at https://www.apache.org/licenses/LICENSE-2.0.8*9* This Source Code may also be made available under the following10* Secondary Licenses when the conditions for such availability set11* forth in the Eclipse Public License, v. 2.0 are satisfied: GNU12* General Public License, version 2 with the GNU Classpath13* Exception [1] and GNU General Public License, version 2 with the14* OpenJDK Assembly Exception [2].15*16* [1] https://www.gnu.org/software/classpath/license.html17* [2] http://openjdk.java.net/legal/assembly-exception.html18*19* SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 OR LicenseRef-GPL-2.0 WITH Assembly-exception20*******************************************************************************/21package com.ibm.jpp.om;2223import java.io.BufferedOutputStream;24import java.io.ByteArrayOutputStream;25import java.io.File;26import java.io.FileInputStream;27import java.io.FileNotFoundException;28import java.io.FileOutputStream;29import java.io.FilterOutputStream;30import java.io.IOException;31import java.io.InputStream;32import java.io.OutputStream;3334public class PhantomOutputStream extends FilterOutputStream {35private final boolean forced;36private final File outputFile;3738public PhantomOutputStream(File outputFile) {39this(outputFile, true);40}4142public PhantomOutputStream(File outputFile, boolean forced) {43super(null);44this.forced = forced;45this.outputFile = outputFile;46}4748@Override49public void close() throws IOException {50if (out != null) {51try {52super.close();5354if (!forced) {55byte[] desired = ((ByteArrayOutputStream) out).toByteArray();5657if (!fileMatches(desired)) {58try (OutputStream newOut = new FileOutputStream(outputFile)) {59newOut.write(desired);60}61}62}63} finally {64out = null;65}66}67}6869private void createFile() throws IOException {70if (out == null) {71outputFile.getParentFile().mkdirs();7273if (forced) {74out = new BufferedOutputStream(new FileOutputStream(outputFile), 32768);75} else {76out = new ByteArrayOutputStream();77}78}79}8081private boolean fileMatches(byte[] desired) throws IOException {82try (InputStream existing = new FileInputStream(outputFile)) {83byte[] buffer = new byte[4096];84int offset = 0;85int remaining = desired.length;8687for (;;) {88int count = existing.read(buffer);8990if (count < 0) {91// EOF92return remaining == 0;93}9495if (count > remaining) {96// the existing file is too long97return false;98}99100for (int i = 0; i < count; ++i, ++offset) {101if (buffer[i] != desired[offset]) {102// we found a difference103return false;104}105}106107remaining -= count;108}109} catch (FileNotFoundException e) {110// the file does not exist111return false;112}113}114115@Override116public void flush() throws IOException {117if (out != null) {118super.flush();119}120}121122@Override123public void write(byte[] buffer, int offset, int length) throws IOException {124createFile();125out.write(buffer, offset, length);126}127128@Override129public void write(int value) throws IOException {130createFile();131out.write(value);132}133134}135136137