History

My first initial commit with all of mine experimental changes.

Dmitry Kabak (userdima committed 13 years ago

Commit d37b88d1 parent 3f5b46618352 files · +2598093 −-8690Browse files

Showing the changes to java/pkg/javax/imageio/stream/MemoryCacheImageInputStream.java (1 of 18352 files). Show all

Unified · Split

java/pkg/javax/imageio/stream/MemoryCacheImageInputStream.java+202−0
@@ -0,0 +1,202 @@
1+/*
2+ * Copyright (c) 2000, 2007, Oracle and/or its affiliates. All rights reserved.
3+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+ *
5+ * This code is free software; you can redistribute it and/or modify it
6+ * under the terms of the GNU General Public License version 2 only, as
7+ * published by the Free Software Foundation. Oracle designates this
8+ * particular file as subject to the "Classpath" exception as provided
9+ * by Oracle in the LICENSE file that accompanied this code.
10+ *
11+ * This code is distributed in the hope that it will be useful, but WITHOUT
12+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+ * version 2 for more details (a copy is included in the LICENSE file that
15+ * accompanied this code).
16+ *
17+ * You should have received a copy of the GNU General Public License version
18+ * 2 along with this work; if not, write to the Free Software Foundation,
19+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+ *
21+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+ * or visit www.oracle.com if you need additional information or have any
23+ * questions.
24+ */
25+
26+package javax.imageio.stream;
27+
28+import java.io.InputStream;
29+import java.io.IOException;
30+import com.sun.imageio.stream.StreamFinalizer;
31+import sun.java2d.Disposer;
32+import sun.java2d.DisposerRecord;
33+
34+/**
35+ * An implementation of <code>ImageInputStream</code> that gets its
36+ * input from a regular <code>InputStream</code>. A memory buffer is
37+ * used to cache at least the data between the discard position and
38+ * the current read position.
39+ *
40+ * <p> In general, it is preferable to use a
41+ * <code>FileCacheImageInputStream</code> when reading from a regular
42+ * <code>InputStream</code>. This class is provided for cases where
43+ * it is not possible to create a writable temporary file.
44+ *
45+ */
46+public class MemoryCacheImageInputStream extends ImageInputStreamImpl {
47+
48+ private InputStream stream;
49+
50+ private MemoryCache cache = new MemoryCache();
51+
52+ /** The referent to be registered with the Disposer. */
53+ private final Object disposerReferent;
54+
55+ /** The DisposerRecord that resets the underlying MemoryCache. */
56+ private final DisposerRecord disposerRecord;
57+
58+ /**
59+ * Constructs a <code>MemoryCacheImageInputStream</code> that will read
60+ * from a given <code>InputStream</code>.
61+ *
62+ * @param stream an <code>InputStream</code> to read from.
63+ *
64+ * @exception IllegalArgumentException if <code>stream</code> is
65+ * <code>null</code>.
66+ */
67+ public MemoryCacheImageInputStream(InputStream stream) {
68+ if (stream == null) {
69+ throw new IllegalArgumentException("stream == null!");
70+ }
71+ this.stream = stream;
72+
73+ disposerRecord = new StreamDisposerRecord(cache);
74+ if (getClass() == MemoryCacheImageInputStream.class) {
75+ disposerReferent = new Object();
76+ Disposer.addRecord(disposerReferent, disposerRecord);
77+ } else {
78+ disposerReferent = new StreamFinalizer(this);
79+ }
80+ }
81+
82+ public int read() throws IOException {
83+ checkClosed();
84+ bitOffset = 0;
85+ long pos = cache.loadFromStream(stream, streamPos+1);
86+ if (pos >= streamPos+1) {
87+ return cache.read(streamPos++);
88+ } else {
89+ return -1;
90+ }
91+ }
92+
93+ public int read(byte[] b, int off, int len) throws IOException {
94+ checkClosed();
95+
96+ if (b == null) {
97+ throw new NullPointerException("b == null!");
98+ }
99+ if (off < 0 || len < 0 || off + len > b.length || off + len < 0) {
100+ throw new IndexOutOfBoundsException
101+ ("off < 0 || len < 0 || off+len > b.length || off+len < 0!");
102+ }
103+
104+ bitOffset = 0;
105+
106+ if (len == 0) {
107+ return 0;
108+ }
109+
110+ long pos = cache.loadFromStream(stream, streamPos+len);
111+
112+ len = (int)(pos - streamPos); // In case stream ended early
113+
114+ if (len > 0) {
115+ cache.read(b, off, len, streamPos);
116+ streamPos += len;
117+ return len;
118+ } else {
119+ return -1;
120+ }
121+ }
122+
123+ public void flushBefore(long pos) throws IOException {
124+ super.flushBefore(pos); // this will call checkClosed() for us
125+ cache.disposeBefore(pos);
126+ }
127+
128+ /**
129+ * Returns <code>true</code> since this
130+ * <code>ImageInputStream</code> caches data in order to allow
131+ * seeking backwards.
132+ *
133+ * @return <code>true</code>.
134+ *
135+ * @see #isCachedMemory
136+ * @see #isCachedFile
137+ */
138+ public boolean isCached() {
139+ return true;
140+ }
141+
142+ /**
143+ * Returns <code>false</code> since this
144+ * <code>ImageInputStream</code> does not maintain a file cache.
145+ *
146+ * @return <code>false</code>.
147+ *
148+ * @see #isCached
149+ * @see #isCachedMemory
150+ */
151+ public boolean isCachedFile() {
152+ return false;
153+ }
154+
155+ /**
156+ * Returns <code>true</code> since this
157+ * <code>ImageInputStream</code> maintains a main memory cache.
158+ *
159+ * @return <code>true</code>.
160+ *
161+ * @see #isCached
162+ * @see #isCachedFile
163+ */
164+ public boolean isCachedMemory() {
165+ return true;
166+ }
167+
168+ /**
169+ * Closes this <code>MemoryCacheImageInputStream</code>, freeing
170+ * the cache. The source <code>InputStream</code> is not closed.
171+ */
172+ public void close() throws IOException {
173+ super.close();
174+ disposerRecord.dispose(); // this resets the MemoryCache
175+ stream = null;
176+ cache = null;
177+ }
178+
179+ /**
180+ * {@inheritDoc}
181+ */
182+ protected void finalize() throws Throwable {
183+ // Empty finalizer: for performance reasons we instead use the
184+ // Disposer mechanism for ensuring that the underlying
185+ // MemoryCache is reset prior to garbage collection
186+ }
187+
188+ private static class StreamDisposerRecord implements DisposerRecord {
189+ private MemoryCache cache;
190+
191+ public StreamDisposerRecord(MemoryCache cache) {
192+ this.cache = cache;
193+ }
194+
195+ public synchronized void dispose() {
196+ if (cache != null) {
197+ cache.reset();
198+ cache = null;
199+ }
200+ }
201+ }
202+}