StreamDatabase.java 8.36 KB
/*
 * Decompiled with CFR 0_118.
 */
package com.adobe.internal.io.stream;

import com.adobe.internal.io.ByteReader;
import com.adobe.internal.io.ByteWriter;
import com.adobe.internal.io.stream.InputByteStream;
import com.adobe.internal.io.stream.OutputByteStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

class StreamDatabase {
    private Map inputStreamData = new HashMap();
    private Map outputStreamData = new HashMap();
    private ByteReader masterByteReader;
    private boolean lenientMasterByteReader = false;
    private boolean ignoreRemoveOnNonexistentReader = false;
    private boolean ignoreRemoveOnNonexistentWriter = false;

    StreamDatabase(ByteReader masterByteReader, boolean lenientMasterByteReader, boolean ignoreRemoveOnNonexistentReader, boolean ignoreRemoveOnNonexistentWriter) {
        this.lenientMasterByteReader = lenientMasterByteReader;
        this.ignoreRemoveOnNonexistentReader = ignoreRemoveOnNonexistentReader;
        this.ignoreRemoveOnNonexistentWriter = ignoreRemoveOnNonexistentWriter;
        this.initMasterByteReader(masterByteReader);
    }

    ByteReader resetMasterByteReader(ByteReader masterByteReader) throws IOException {
        ByteReader oldMasterByteReader = this.masterByteReader;
        StreamData oldBRData = (StreamData)this.inputStreamData.get(this.masterByteReader);
        if (oldBRData != null && oldBRData.getReferences() != 0 && !this.lenientMasterByteReader) {
            throw new RuntimeException("Closing master ByteReader with open streams.");
        }
        if (oldMasterByteReader != null) {
            this.inputStreamData.remove(oldMasterByteReader);
            try {
                oldMasterByteReader.close();
            }
            catch (IOException e) {
                IOException ioe = new IOException("Unable to close master ByteReader: " + oldMasterByteReader);
                ioe.initCause(e);
                throw ioe;
            }
        }
        this.initMasterByteReader(masterByteReader);
        return oldMasterByteReader;
    }

    private void initMasterByteReader(ByteReader masterByteReader) {
        this.masterByteReader = masterByteReader;
        if (this.masterByteReader != null) {
            StreamData newBRData = new StreamData();
            this.inputStreamData.put(this.masterByteReader, newBRData);
        }
    }

    boolean addIBS(InputByteStream ibs, ByteReader br) {
        boolean ibsFirstTime = false;
        StreamData data = (StreamData)this.inputStreamData.get(br);
        if (data == null) {
            data = new StreamData();
            this.inputStreamData.put(br, data);
            ibsFirstTime = true;
        }
        data.addReference();
        return ibsFirstTime;
    }

    boolean removeIBS(InputByteStream ibs, ByteReader br) {
        boolean lastReference = true;
        StreamData data = (StreamData)this.inputStreamData.get(br);
        if (data == null) {
            if (!this.ignoreRemoveOnNonexistentReader) {
                throw new RuntimeException("Closing an InputByteStream that isn't in the stream database.");
            }
        } else {
            lastReference = data.removeReference();
            if (lastReference) {
                this.inputStreamData.remove(br);
            }
        }
        return lastReference;
    }

    boolean addOBS(OutputByteStream obs, ByteWriter bw) {
        boolean obsFirstTime = false;
        StreamData data = (StreamData)this.outputStreamData.get(bw);
        if (data == null) {
            data = new StreamData();
            this.outputStreamData.put(bw, data);
            obsFirstTime = true;
        }
        data.addReference();
        return obsFirstTime;
    }

    boolean removeOBS(OutputByteStream obs, ByteWriter bw) {
        boolean lastReference = true;
        StreamData data = (StreamData)this.outputStreamData.get(bw);
        if (data == null) {
            if (!this.ignoreRemoveOnNonexistentWriter) {
                throw new RuntimeException("Closing an OutputByteStream that isn't in the stream database.");
            }
        } else {
            lastReference = data.removeReference();
            if (lastReference) {
                this.outputStreamData.remove(bw);
            }
        }
        return lastReference & !this.inputStreamData.containsKey(bw);
    }

    boolean isOutputEmpty() {
        return this.outputStreamData.isEmpty();
    }

    boolean isInputEmpty() {
        return this.inputStreamData.isEmpty();
    }

    boolean isEmpty() {
        return this.isInputEmpty() && this.isOutputEmpty();
    }

    int getOutputCount() {
        return this.outputStreamData.size();
    }

    int getInputCount() {
        return this.inputStreamData.size();
    }

    int getCount() {
        return this.getOutputCount() + this.getInputCount();
    }

    public String toString() {
        StreamData data;
        StringBuilder buffer = new StringBuilder("Open ByteReader = ");
        buffer.append(this.getInputCount()).append("\n").append("Open ByteWriter = ").append(this.getOutputCount()).append("\n").append("======== ByteReaders\n");
        for (Object key2 : this.inputStreamData.keySet()) {
            buffer.append("ByteReader = ").append(key2.toString()).append("\n");
            data = (StreamData)this.inputStreamData.get(key2);
            buffer.append(data.toString());
        }
        buffer.append("======== ByteWriters\n");
        for (Object key2 : this.outputStreamData.keySet()) {
            buffer.append("ByteWriter = ").append(key2.toString()).append("\n");
            data = (StreamData)this.outputStreamData.get(key2);
            buffer.append(data.toString());
        }
        return buffer.toString();
    }

    int closeAllOpen(boolean ignoreMaster) throws IOException {
        int numberOpen = this.closeAllOpenReaders(ignoreMaster);
        return numberOpen += this.closeAllOpenWriters(ignoreMaster);
    }

    private int closeAllOpenReaders(boolean ignoreMaster) throws IOException {
        int numberOpen = 0;
        Set openReaderSet = this.inputStreamData.keySet();
        numberOpen += openReaderSet.size();
        for (ByteReader openReader : openReaderSet) {
            if (ignoreMaster && openReader == this.masterByteReader) continue;
            try {
                openReader.close();
                continue;
            }
            catch (IOException e) {
                IOException ioe = new IOException("Unable to close ByteReader: " + openReader);
                ioe.initCause(e);
                throw ioe;
            }
        }
        this.inputStreamData.clear();
        return numberOpen;
    }

    private int closeAllOpenWriters(boolean ignoreMaster) throws IOException {
        int numberOpen = 0;
        Set openWriterSet = this.outputStreamData.keySet();
        numberOpen += openWriterSet.size();
        for (ByteWriter openWriter : openWriterSet) {
            if (ignoreMaster && openWriter == this.masterByteReader) continue;
            try {
                openWriter.close();
                continue;
            }
            catch (IOException e) {
                IOException ioe = new IOException("Unable to close  ByteWriter: " + openWriter);
                ioe.initCause(e);
                throw ioe;
            }
        }
        this.outputStreamData.clear();
        return numberOpen;
    }

    private static class StreamData {
        private long references;
        private long maxReferences;
        private String stackTrace;

        public long getReferences() {
            return this.references;
        }

        public long getMaxReferences() {
            return this.maxReferences;
        }

        public void addReference() {
            ++this.references;
            ++this.maxReferences;
        }

        public boolean removeReference() {
            --this.references;
            if (this.references < 0) {
                throw new RuntimeException("Stream closed and not removed from stream database.");
            }
            return this.references == 0;
        }

        public String toString() {
            StringBuilder buffer = new StringBuilder("Number of open references = ");
            buffer.append(this.getReferences()).append("\n").append("Number of max references = ").append(this.getMaxReferences()).append("\n").append("Originally created = \n").append(this.stackTrace).append("\n");
            return buffer.toString();
        }
    }

}