KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > javax > imageio > stream > MemoryCacheImageOutputStream


1 /*
2  * @(#)MemoryCacheImageOutputStream.java 1.17 03/12/19
3  *
4  * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
5  * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
6  */

7
8 package javax.imageio.stream;
9
10 import java.io.IOException JavaDoc;
11 import java.io.OutputStream JavaDoc;
12
13 /**
14  * An implementation of <code>ImageOutputStream</code> that writes its
15  * output to a regular <code>OutputStream</code>. A memory buffer is
16  * used to cache at least the data between the discard position and
17  * the current write position. The only constructor takes an
18  * <code>OutputStream</code>, so this class may not be used for
19  * read/modify/write operations. Reading can occur only on parts of
20  * the stream that have already been written to the cache and not
21  * yet flushed.
22  *
23  * @version 0.5
24  */

25 public class MemoryCacheImageOutputStream extends ImageOutputStreamImpl JavaDoc {
26
27     private OutputStream JavaDoc stream;
28
29     private MemoryCache JavaDoc cache = new MemoryCache JavaDoc();
30
31     /**
32      * Constructs a <code>MemoryCacheImageOutputStream</code> that will write
33      * to a given <code>OutputStream</code>.
34      *
35      * @param stream an <code>OutputStream</code> to write to.
36      *
37      * @exception IllegalArgumentException if <code>stream</code> is
38      * <code>null</code>.
39      */

40     public MemoryCacheImageOutputStream(OutputStream JavaDoc stream) {
41         if (stream == null) {
42             throw new IllegalArgumentException JavaDoc("stream == null!");
43         }
44         this.stream = stream;
45     }
46
47     public int read() throws IOException JavaDoc {
48         checkClosed();
49
50         bitOffset = 0;
51
52         int val = cache.read(streamPos);
53         if (val != -1) {
54             ++streamPos;
55         }
56         return val;
57     }
58
59     public int read(byte[] b, int off, int len) throws IOException JavaDoc {
60         checkClosed();
61         
62         // Fix 4467619: read([B,I,I) doesn't throw NPE as specified
63
// Fix 4467608: read([B,I,I) works incorrectly if len<=0
64
// Will throw NullPointerException if b == null
65
// Will throw IIOBE if off, len are bad args
66
if (off < 0 || len < 0 || off + len > b.length || off + len < 0) {
67             throw new IndexOutOfBoundsException JavaDoc
68                 ("off < 0 || len < 0 || off + len > b.length!");
69         }
70
71         bitOffset = 0;
72
73         if (len == 0) {
74             return 0;
75         }
76
77         // check if we're already at/past EOF i.e.
78
// no more bytes left to read from cache
79
long bytesLeftInCache = cache.getLength() - streamPos;
80         if (bytesLeftInCache <= 0) {
81             return -1; // EOF
82
}
83
84         // guaranteed by now that bytesLeftInCache > 0 && len > 0
85
// and so the rest of the error checking is done by cache.read()
86
// NOTE that alot of error checking is duplicated
87
len = (int)Math.min(bytesLeftInCache, (long)len);
88         cache.read(b, off, len, streamPos);
89         streamPos += len;
90         return len;
91     }
92
93     public void write(int b) throws IOException JavaDoc {
94         checkClosed();
95         flushBits();
96         cache.write(b, streamPos);
97         ++streamPos;
98     }
99
100     public void write(byte[] b, int off, int len) throws IOException JavaDoc {
101         checkClosed();
102         flushBits();
103         cache.write(b, off, len, streamPos);
104         streamPos += len;
105     }
106
107     public long length() {
108         return cache.getLength();
109     }
110
111     /**
112      * Returns <code>true</code> since this
113      * <code>ImageOutputStream</code> caches data in order to allow
114      * seeking backwards.
115      *
116      * @return <code>true</code>.
117      *
118      * @see #isCachedMemory
119      * @see #isCachedFile
120      */

121     public boolean isCached() {
122         return true;
123     }
124
125     /**
126      * Returns <code>false</code> since this
127      * <code>ImageOutputStream</code> does not maintain a file cache.
128      *
129      * @return <code>false</code>.
130      *
131      * @see #isCached
132      * @see #isCachedMemory
133      */

134     public boolean isCachedFile() {
135         return false;
136     }
137
138     /**
139      * Returns <code>true</code> since this
140      * <code>ImageOutputStream</code> maintains a main memory cache.
141      *
142      * @return <code>true</code>.
143      *
144      * @see #isCached
145      * @see #isCachedFile
146      */

147     public boolean isCachedMemory() {
148         return true;
149     }
150
151     /**
152      * Closes this <code>MemoryCacheImageOutputStream</code>. All
153      * pending data is flushed to the output, and the cache
154      * is released. The destination <code>OutputStream</code>
155      * is not closed.
156      */

157     public void close() throws IOException JavaDoc {
158         long length = cache.getLength();
159         seek(length);
160         flushBefore(length);
161         super.close();
162         cache.reset();
163         stream = null;
164     }
165
166     public void flushBefore(long pos) throws IOException JavaDoc {
167         long oFlushedPos = flushedPos;
168         super.flushBefore(pos);
169
170         long flushBytes = flushedPos - oFlushedPos;
171         cache.writeToStream(stream, oFlushedPos, flushBytes);
172         cache.disposeBefore(flushedPos);
173         stream.flush();
174     }
175 }
176
Popular Tags