KickJava   Java API By Example, From Geeks To Geeks.

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


1 /*
2
3    Derby - Class org.apache.derby.impl.store.raw.data.MemByteHolder
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
26 import java.io.IOException JavaDoc;
27 import java.io.InputStream JavaDoc;
28 import java.io.OutputStream JavaDoc;
29 import java.util.Vector JavaDoc;
30
31 /**
32   A ByteHolder that stores all its bytes in memory.
33   */

34 public class MemByteHolder
35 implements ByteHolder
36 {
37     int bufSize;
38
39     boolean writing = true;
40     
41     Vector JavaDoc bufV;
42     int curBufVEleAt;
43
44     byte[] curBuf;
45     int curBufPos;
46
47     //
48
//We use this to determine when we have reached the end
49
//of the current buffer whild reading. For the last
50
//buffer this may be less than bufSize.
51
int curBufDataBytes;
52
53     //
54
//We use these to remember the location of the last byte
55
//of data we have stored. The read methods use these to
56
//avoid reading more bytes than we have stored. These
57
//values are set by startReading.
58
int lastBufVEleAt = 0;
59     int lastBufDataBytes = 0;
60     
61     /**
62       Create a new MemByteHolder. Store bytes as a list of buffers
63       of size 'bufSize'.
64       */

65     public MemByteHolder(int bufSize)
66     {
67         this.bufSize = bufSize;
68
69         this.curBuf = new byte[bufSize];
70         this.curBufPos = 0;
71
72         this.bufV = new Vector JavaDoc(128);
73         bufV.addElement(curBuf);
74         this.curBufVEleAt = 0;
75     }
76
77     /**
78       @see ByteHolder#write
79       @exception IOException Thrown on error
80       */

81     public void write(int b) throws IOException JavaDoc
82     {
83         if (SanityManager.DEBUG)
84             SanityManager.ASSERT(writing == true,
85                                  "Writing should be true 1");
86
87         if(curBufPos>=curBuf.length)
88             getNextBuffer_w();
89
90         curBuf[curBufPos++] = (byte)b;
91     }
92
93     /**
94       @see ByteHolder#write
95       @exception IOException Thrown on error
96       */

97     public void write(byte[] data, int offset, int len) throws IOException JavaDoc
98     {
99         if (SanityManager.DEBUG)
100             SanityManager.ASSERT(writing == true,
101                                  "Writing should be true 2");
102
103         while(len > 0)
104         {
105             if(curBufPos>=curBuf.length)
106                 getNextBuffer_w();
107
108             int bytesToCopyThisTime = len;
109             int bytesInCurBuf = curBuf.length - curBufPos;
110
111             if (bytesToCopyThisTime > bytesInCurBuf)
112                 bytesToCopyThisTime = bytesInCurBuf;
113             System.arraycopy(data,offset,curBuf,curBufPos,bytesToCopyThisTime);
114             offset += bytesToCopyThisTime;
115             curBufPos += bytesToCopyThisTime;
116             len -= bytesToCopyThisTime;
117         }
118     }
119
120     /**
121       @see ByteHolder#write
122       @exception IOException Thrown on error
123       */

124     public long write(InputStream JavaDoc is, long count) throws IOException JavaDoc
125     {
126         long bytesToTransfer = count;
127         int bytesTransferredThisTime = 0;
128         
129         do
130         {
131             if(curBufPos>=curBuf.length)
132                 getNextBuffer_w();
133  
134             int bytesToTransferThisTime;
135             int bytesInCurBuf = curBuf.length - curBufPos;
136
137             if (bytesToTransfer >= bytesInCurBuf)
138                 bytesToTransferThisTime = bytesInCurBuf;
139             else
140                  bytesToTransferThisTime = (int)bytesToTransfer;
141             //
142
//Note read should never return 0. Thus we keep looping
143
//transferring bytes from the stream to our buffer until
144
//we transfer count bytes or reach the end of the stream.
145
//
146
bytesTransferredThisTime =
147                 is.read(curBuf,curBufPos,bytesToTransferThisTime);
148
149             if (bytesTransferredThisTime > 0)
150             {
151                 if (SanityManager.DEBUG)
152                     SanityManager.ASSERT(
153                         writing == true, "Writing should be true 3");
154
155                 bytesToTransfer -= bytesTransferredThisTime;
156                 curBufPos += bytesTransferredThisTime;
157             }
158         } while (bytesToTransfer > 0 &&
159                  bytesTransferredThisTime > 0);
160
161         return count - bytesToTransfer;
162     }
163
164     /**
165       @see ByteHolder#clear
166
167       @exception IOException Thrown on error
168       */

169     public void clear() throws IOException JavaDoc
170     {
171         writing = true;
172         
173         curBuf = (byte[])bufV.elementAt(0);
174         this.curBufVEleAt = 0;
175         this.curBufPos = 0;
176         
177         lastBufVEleAt = 0;
178         lastBufDataBytes = 0;
179     }
180
181     /**
182       @see ByteHolder#startReading
183       */

184     public void startReading()
185         throws IOException JavaDoc
186     {
187         if (writing == true)
188         {
189             //Enter read mode.
190
writing = false;
191             lastBufDataBytes = curBufPos;
192             lastBufVEleAt = curBufVEleAt;
193         }
194         //
195
//Reposition so reads start from the first
196
//byte.
197
curBuf = (byte[])bufV.elementAt(0);
198         this.curBufVEleAt = 0;
199         this.curBufPos = 0;
200         if (curBufVEleAt == lastBufVEleAt)
201             curBufDataBytes = lastBufDataBytes;
202         else
203             curBufDataBytes = bufSize;
204     }
205
206     /**
207       @see ByteHolder#read
208       @exception IOException Thrown on error
209       */

210     public int read() throws IOException JavaDoc
211     {
212         if (SanityManager.DEBUG)
213             SanityManager.ASSERT(writing == false,
214                                  "Reading should be true 2");
215         
216         if (curBufPos >= curBufDataBytes)
217             getNextBuffer_r();
218
219         if (curBufPos >= curBufDataBytes)
220             return -1;
221         else
222             return 0xff & curBuf[curBufPos++];
223     }
224
225     /**
226       @see ByteHolder#read
227       @exception IOException Thrown on error
228       */

229     public int read(byte b[],
230                     int off,
231                     int len)
232         throws IOException JavaDoc
233     {
234         return (read(b, off, (OutputStream JavaDoc) null, len));
235     }
236
237     /**
238       @see ByteHolder#read
239       @exception IOException Thrown on error
240       */

241     public int read(OutputStream JavaDoc out,
242                     int len)
243         throws IOException JavaDoc
244     {
245         return(read((byte []) null, 0, out, len));
246     }
247
248     /**
249       @see ByteHolder#read
250       @exception IOException Thrown on error
251       */

252     public int read(byte b[],
253                     int off,
254                     OutputStream JavaDoc out,
255                     int len)
256         throws IOException JavaDoc
257     {
258         int bytesIRead = 0;
259         boolean eof = false;
260         
261         if (SanityManager.DEBUG)
262             SanityManager.ASSERT(writing == false,
263                                  "Reading should be true 3");
264         
265         if (curBufPos >= curBufDataBytes)
266             eof = getNextBuffer_r();
267
268         if (eof) return -1;
269
270         while (len > 0 && !eof)
271         {
272             int bytesInCurBuf = curBufDataBytes - curBufPos;
273             int bytesIReadThisTime;
274             if (len >= bytesInCurBuf)
275                 bytesIReadThisTime = bytesInCurBuf;
276             else
277                  bytesIReadThisTime = len;
278
279             if (out == null) {
280                 // write the data to the byte array
281
System.arraycopy(curBuf,curBufPos,b,off,bytesIReadThisTime);
282             } else {
283                 // write the data to the output stream
284
out.write(curBuf, curBufPos, bytesIReadThisTime);
285             }
286             off+=bytesIReadThisTime;
287             curBufPos+=bytesIReadThisTime;
288             len -= bytesIReadThisTime;
289             bytesIRead+=bytesIReadThisTime;
290             if (curBufPos >= curBufDataBytes)
291                 eof = getNextBuffer_r();
292         }
293
294         return bytesIRead;
295     }
296
297     /**
298       @see ByteHolder#shiftToFront
299       @exception IOException Thrown on error
300       */

301     public int shiftToFront() throws IOException JavaDoc
302     {
303         int remainingBytes = available();
304         remainingBytes = remainingBytes > 0 ? remainingBytes : (-1) * remainingBytes;
305
306         byte b[] = new byte[remainingBytes + 1];
307         int bytesRead = read(b, 0, remainingBytes);
308
309         // clear the buffer
310
clear();
311
312         // put the bytes at the beginning of the buffer
313
writing = true;
314         write(b, 0, bytesRead);
315
316         curBufDataBytes = 0;
317
318         return bytesRead;
319     }
320
321     /**
322       @see ByteHolder#available
323       */

324     public int available()
325     {
326         //if (SanityManager.DEBUG)
327
// SanityManager.ASSERT(writing == false,
328
// "Reading should be true 3");
329

330         int curBufAvailable = curBufDataBytes - curBufPos;
331         int lastBufAvailable = 0;
332         int middleBuffers = 0;
333         if (curBufVEleAt != lastBufVEleAt)
334         {
335             middleBuffers = lastBufVEleAt - curBufVEleAt - 1;
336             lastBufAvailable = lastBufDataBytes;
337         }
338         int availableBytes =
339             curBufAvailable +
340             lastBufAvailable +
341             middleBuffers * bufSize;
342
343         return availableBytes;
344     }
345
346     /**
347       Return the number of bytes that have been saved to this byte holder.
348       This result is different from available() as it is unaffected by the
349       current read position on the ByteHolder.
350
351       @see ByteHolder#numBytesSaved
352       */

353     public int numBytesSaved()
354     {
355         int ret_val;
356
357         if (writing)
358         {
359             // still writing, so use the cur* variables
360
if (SanityManager.DEBUG)
361                 SanityManager.ASSERT(
362                     lastBufVEleAt == 0 && lastBufDataBytes == 0,
363                     "counters were somehow bumped during writing");
364
365             ret_val = (curBufVEleAt * bufSize) + curBufPos;
366         }
367         else
368         {
369             ret_val = (lastBufVEleAt * bufSize) + lastBufDataBytes;
370         }
371
372         return(ret_val);
373     }
374
375     /**
376       @see ByteHolder#skip
377       @exception IOException Thrown on error
378       */

379     public long skip(long count) throws IOException JavaDoc
380     {
381         long bytesISkipped = 0;
382         boolean eof = false;
383         
384         if (SanityManager.DEBUG)
385             SanityManager.ASSERT(writing == false,
386                                  "Reading should be true 4");
387         
388         if (curBufPos >= curBufDataBytes)
389             eof = getNextBuffer_r();
390
391         while (count > 0 && !eof)
392         {
393             int bytesInCurBuf = curBufDataBytes - curBufPos;
394             int bytesISkippedThisTime;
395             
396             if (count >= bytesInCurBuf)
397                 bytesISkippedThisTime = bytesInCurBuf;
398             else
399                  bytesISkippedThisTime = (int)count;
400
401             curBufPos+=bytesISkippedThisTime;
402             count -= bytesISkippedThisTime;
403             bytesISkipped+=bytesISkippedThisTime;
404
405             if (count > 0)
406                 eof = getNextBuffer_r();
407         }
408
409         return bytesISkipped;
410     }
411
412     /**
413       @see ByteHolder#writingMode
414      */

415     public boolean writingMode()
416     {
417         return writing;
418     }
419
420     /**
421       Get the next buffer for writing bytes.
422       @exception IOException Thrown on error
423       */

424     protected void getNextBuffer_w() throws IOException JavaDoc
425     {
426         if (SanityManager.DEBUG)
427         {
428             getNextBuffer_w_Sanity();
429         }
430         
431         curBufVEleAt++;
432
433         if (bufV.size() <= curBufVEleAt)
434         {
435             curBuf = new byte[bufSize];
436             bufV.addElement(curBuf);
437         }
438         else
439         {
440             curBuf = (byte[])bufV.elementAt(curBufVEleAt);
441         }
442         
443         initBuffer_w();
444     }
445
446     /** Do sanity checking when getting the next write buffer */
447     protected void getNextBuffer_w_Sanity()
448     {
449         if (SanityManager.DEBUG)
450         {
451             SanityManager.ASSERT(curBufPos == curBuf.length,
452                                  "partial write");
453
454             SanityManager.ASSERT(writing == true,
455                                  "Writing should be true 5");
456         }
457     }
458         
459     /** Initialize a buffer for writing */
460     protected void initBuffer_w()
461     {
462         curBufPos = 0;
463         
464         if (SanityManager.DEBUG)
465         {
466             SanityManager.ASSERT(curBuf.length == bufSize,
467                                  "bad Buf Length "+curBuf.length);
468         }
469     }
470
471     /**
472       Get the next buffer for reading bytes.
473
474       @return true if the user has read all the bytes
475       in this ByteHolder.
476
477       @exception IOException Thrown on error
478       */

479     protected boolean getNextBuffer_r() throws IOException JavaDoc
480     {
481         if (SanityManager.DEBUG)
482             SanityManager.ASSERT(writing == false,
483                                  "Reading should be true 5");
484         if (curBufVEleAt >= lastBufVEleAt) return true;
485         curBuf = (byte[])bufV.elementAt(++curBufVEleAt);
486         curBufPos = 0;
487         if (curBufVEleAt == lastBufVEleAt)
488             curBufDataBytes = lastBufDataBytes;
489         else
490             curBufDataBytes = bufSize;
491         return false;
492     }
493
494     /**
495       Create a string representation of an internal buffer of bytes.
496       This is useful during debugging.
497       */

498     private String JavaDoc dumpBuf(int bufVEleAt)
499     {
500         StringBuffer JavaDoc sb = new StringBuffer JavaDoc(100);
501
502         byte[] buf = (byte[])bufV.elementAt(bufVEleAt);
503         sb.append("(");
504         for (int ix = 0;ix<buf.length;ix++)
505             sb.append(buf[ix]+".");
506         sb.append(")");
507         return sb.toString();
508     }
509
510     /**
511       Produce a string describing the state of this ByteHolder.
512       This is mainly for debugging.
513       */

514     public String JavaDoc toString()
515     {
516         return
517             " writing: "+writing+
518             " curBufVEleAt: "+curBufVEleAt+
519             " curBufPos: "+curBufPos+
520             " curBufDataBytes: "+curBufDataBytes+
521             " lastBufVEleAt: "+lastBufVEleAt+
522             " lastBufDataBytes: "+lastBufDataBytes+
523             " curBuf: "+dumpBuf(curBufVEleAt);
524     }
525 }
526
Popular Tags