KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > derby > impl > store > raw > data > RememberBytesInputStream


1 /*
2
3    Derby - Class org.apache.derby.impl.store.raw.data.RememberBytesInputStream
4
5    Licensed to the Apache Software Foundation (ASF) under one or more
6    contributor license agreements. See the NOTICE file distributed with
7    this work for additional information regarding copyright ownership.
8    The ASF licenses this file to you under the Apache License, Version 2.0
9    (the "License"); you may not use this file except in compliance with
10    the License. You may obtain a copy of the License at
11
12       http://www.apache.org/licenses/LICENSE-2.0
13
14    Unless required by applicable law or agreed to in writing, software
15    distributed under the License is distributed on an "AS IS" BASIS,
16    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17    See the License for the specific language governing permissions and
18    limitations under the License.
19
20  */

21
22 package org.apache.derby.impl.store.raw.data;
23
24 import org.apache.derby.iapi.services.sanity.SanityManager;
25 import java.io.FilterInputStream JavaDoc;
26 import java.io.IOException JavaDoc;
27 import java.io.InputStream JavaDoc;
28 import java.io.OutputStream JavaDoc;
29
30 /**
31   A FilterInputStream that remembers read or skipped bytes.
32
33   <P>In record mode this stream remembers all the bytes a
34   caller reads or skips. After reading some bytes this
35   returns a 'replay' stream to re-read them.
36
37   <P>A caller may call getReplaySteam to get a stream
38   to re-read the the remembered bytes. Any number of calls
39   to getReplayStream are supported.
40
41   <P>The clear function causes this stream to forget the remembered
42   bytes and re-enter record mode.
43   */

44 public class RememberBytesInputStream extends FilterInputStream JavaDoc
45 {
46     ByteHolder bh;
47     boolean recording = true;
48     
49     // In case of streams (e.g ReaderToUTF8Stream,
50
// RawToBinaryFormatStream) that cannot be re-used
51
// a read on a closed stream will throw an EOFException
52
// hence keep track if the stream is closed or not
53
boolean streamClosed = false;
54     
55     /**
56       Construct a RememberBytesInputStream.
57
58       @param bh for storing the remembered bytes. (must be
59       in writing mode.
60       */

61     public RememberBytesInputStream(InputStream JavaDoc in, ByteHolder bh) {
62         super(in);
63
64         if (SanityManager.DEBUG)
65             SanityManager.ASSERT(bh.writingMode());
66
67         this.bh = bh;
68
69     }
70     
71     /**
72       @see java.io.InputStream#read
73       @exception IOException thrown on an io error spooling rememberd bytes
74                  to backing storage.
75       */

76     public int read() throws IOException JavaDoc {
77         if (SanityManager.DEBUG)
78             SanityManager.ASSERT(recording,
79                                  "Must be in record mode to perform a read.");
80         
81         int value = -1;
82         
83         if ( !streamClosed )
84         {
85             value = super.read();
86             if ( value != -1 )
87                 bh.write(value);
88             else
89                 streamClosed =true;
90         }
91         
92         return value;
93     }
94
95     /**
96       @see java.io.InputStream#read
97       @exception IOException thrown on an io error spooling rememberd bytes
98                  to backing storage.
99       */

100     public int read(byte b[], int off, int len) throws IOException JavaDoc {
101         if (SanityManager.DEBUG)
102             SanityManager.ASSERT(recording,
103                                  "Must be in record mode to perform a read.");
104         
105         if ( !streamClosed ) {
106             if ((len + off) > b.length)
107                 len = b.length - off;
108
109             len = super.read(b, off, len);
110             if (len > 0 )
111                 bh.write(b, off, len);
112             else
113                 streamClosed = true;
114         } else {
115             return -1;
116         }
117
118         return len;
119     }
120
121     /**
122       read len bytes from the input stream, and store it in the byte holder.
123
124       Note, fillBuf does not return negative values, if there are no
125       bytes to store in the byteholder, it will return 0
126       @exception IOException thrown on an io error spooling rememberd bytes
127                  to backing storage.
128       */

129     public long fillBuf(int len) throws IOException JavaDoc{
130         
131         long val = 0;
132
133         if ( !streamClosed )
134         {
135             val = bh.write(this.in, len);
136             
137             // if bh.write returns less than len, then the stream
138
// has reached end of stream. See logic in MemByteHolder.write
139
if ( val < len )
140                 streamClosed=true;
141         }
142
143         return val;
144     }
145
146     /**
147       read len bytes from the byte holder, and write it to the output stream.
148
149       @exception IOException thrown on an io error spooling rememberd bytes
150                  to backing storage.
151       */

152     public int putBuf(OutputStream JavaDoc out, int len) throws IOException JavaDoc {
153         bh.startReading();
154         return bh.read(out, len);
155     }
156
157     /**
158       @see java.io.InputStream#skip
159       @exception IOException thrown on an io error spooling rememberd bytes
160                  to backing storage.
161       */

162     public long skip(long count) throws IOException JavaDoc {
163         if (SanityManager.DEBUG)
164             SanityManager.ASSERT(recording,
165                                  "Must be in record mode to perform a read.");
166         return bh.write(in,count);
167     }
168
169     /**
170       Get an input stream for re-reading the remembered bytes.
171       */

172     public InputStream JavaDoc getReplayStream() throws IOException JavaDoc {
173         bh.startReading();
174         recording = false;
175         return new ByteHolderInputStream(bh);
176     }
177
178     /**
179       Get the byteHolder.
180       */

181     public ByteHolder getByteHolder() throws IOException JavaDoc {
182         return bh;
183     }
184
185     /**
186       Clear all the remembered bytes. This stream will
187       remember any bytes read after this call.
188       @exception IOException thrown on an io error clearing backing
189                  storage.
190       */

191     public void clear() throws IOException JavaDoc {
192         bh.clear();
193         recording = true;
194     }
195
196     /**
197       Set the InputStream from which this reads.
198
199       <P>Please note this does not clear remembered
200       bytes.
201      */

202     public void setInput(InputStream JavaDoc in) {
203         this.in = in;
204         streamClosed = false;
205     }
206
207     /**
208       Return true iff this RememberBytesInputStream is
209       in recording mode.
210       */

211     public boolean recording() {
212         return recording;
213     }
214
215     /**
216       Return the number of bytes remains in the byteHolder
217       for reading, without setting the write/read mode.
218       */

219     public int available() throws IOException JavaDoc {
220         // may not have set reading to be true, then,
221
// we are getting available in negative numbers.
222
int remainingBytes = bh.available();
223         remainingBytes = remainingBytes > 0 ? remainingBytes : (-1) * remainingBytes;
224         return remainingBytes;
225     }
226
227     /**
228       Return the number of bytes that have been saved to this byte holder.
229       This result is different from available() as it is unaffected by the
230       current read position on the ByteHolder.
231       */

232     public int numBytesSaved() throws IOException JavaDoc
233     {
234         return(bh.numBytesSaved());
235     }
236
237     /**
238       remove the remaining bytes in the byteHolder to the beginning
239       set the position to start recording just after these bytes.
240       returns how many bytes was transfered to the beginning.
241       */

242     public int shiftToFront() throws IOException JavaDoc {
243         int bytesShifted = bh.shiftToFront();
244         return bytesShifted;
245     }
246
247     /**
248       @see java.lang.Object#toString
249       */

250     public String JavaDoc toString()
251     {
252         return
253             "RememberBytesInputStream: "+
254             " recording: "+recording+" "+bh;
255     }
256 }
257
258
Popular Tags