KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > imagero > uio > RandomAccessBuffer


1 /*
2  * Copyright (c) Andrey Kuznetsov. All Rights Reserved.
3  *
4  * http://uio.imagero.com
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions are met:
8  *
9  * o Redistributions of source code must retain the above copyright notice,
10  * this list of conditions and the following disclaimer.
11  *
12  * o Redistributions in binary form must reproduce the above copyright notice,
13  * this list of conditions and the following disclaimer in the documentation
14  * and/or other materials provided with the distribution.
15  *
16  * o Neither the name of imagero Andrei Kouznetsov nor the names of
17  * its contributors may be used to endorse or promote products derived
18  * from this software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
22  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
27  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
29  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */

32 package com.imagero.uio;
33
34 import com.imagero.uio.buffer.Buffer;
35 import com.imagero.uio.buffer.DefaultBufferManager;
36 import com.imagero.uio.buffer.MutableBufferManager;
37 import com.imagero.uio.buffer.arrays.AbstractArrayBufferManager;
38
39 import java.io.EOFException JavaDoc;
40 import java.io.IOException JavaDoc;
41
42 /**
43  * Makes possible to represent (multiple) Buffers as RandomAccess<br>
44  *
45  * @author Andrey Kuzentsov
46  */

47 public class RandomAccessBuffer extends AbstractRandomAccess {
48
49     MutableBufferManager bufferManager;
50     int dataIndex;
51     int fp;
52     byte[] buf;
53     boolean dirty;
54
55
56     /**
57      * create new RABuffer
58      *
59      * @throws java.io.IOException
60      */

61     public RandomAccessBuffer(Buffer[] ds, int byteOrder) throws IOException JavaDoc {
62         this(new DefaultBufferManager(ds), byteOrder);
63     }
64
65     /**
66      * create new RABuffer
67      *
68      * @param bufferManager
69      *
70      * @throws java.io.IOException
71      */

72     public RandomAccessBuffer(MutableBufferManager bufferManager, int byteOrder) throws IOException JavaDoc {
73         this.bufferManager = bufferManager;
74         this.buf = bufferManager.getData(0);
75         _setByteOrder(byteOrder);
76     }
77
78
79     /**
80      * Reads a byte of data from this byte array. The byte is returned as an integer in the range 0 to 255
81      * (<code>0x00-0x0ff</code>).
82      *
83      * @return the next byte of data, or <code>-1</code> if the end of the file has been reached.
84      */

85     public int read() {
86         if(fp < buf.length) {
87             return buf[fp++] & 0xFF;
88         }
89         else {
90             nextArray();
91             if(buf == null) {
92                 return -1;
93             }
94             return buf[fp++] & 0xFF;
95         }
96     }
97
98     protected boolean nextArray() {
99         //Sys.out.println("nextArray: " + totalRead);
100
try {
101             if(dirty) {
102                 bufferManager.setDirty(dataIndex);
103                 dirty = false;
104             }
105             this.buf = bufferManager.getData(++dataIndex);
106             this.fp = 0;
107             return true;
108         }
109         catch(Exception JavaDoc ex) {
110             //ex.printStackTrace();
111
this.buf = null;
112             this.fp = 0;
113             return false;
114         }
115     }
116
117     public long getFilePointer() throws IOException JavaDoc {
118         return bufferManager.getDataStart(dataIndex) + fp;
119     }
120
121     /**
122      * Sets the pointer offset, measured in bytes from the begin of the data,
123      * at which the next read or write occurs.
124      *
125      * @param pos the offset position, measured in bytes from the begin of the data, at which
126      * to set the pointer.
127      */

128     public void seek(long pos) throws IOException JavaDoc {
129         if(pos < 0) {
130             throw new IOException JavaDoc("" + pos);
131         }
132
133         final int index = bufferManager.getIndex((int) pos);
134         if(index != dataIndex && dirty) {
135             bufferManager.setDirty(dataIndex);
136         }
137         this.dataIndex = index;
138         this.buf = bufferManager.getData(dataIndex);
139         this.fp = (int) (pos - bufferManager.getDataStart(dataIndex));
140     }
141
142     /**
143      * Returns the data length (please note, that real length is not always known)
144      *
145      * @return the data length, measured in bytes.
146      */

147     public long length() {
148         return bufferManager.getLength();
149     }
150
151     /**
152      * just ignored, no exception is thrown
153      */

154     public void setLength(long newLength) throws IOException JavaDoc {
155     }
156
157     public int read(byte[] b) throws IOException JavaDoc {
158         return read(b, 0, b.length);
159     }
160
161     public int read(byte[] b, int off, int length) throws IOException JavaDoc {
162         int read = 0;
163         int _off = off;
164         int _length = length;
165
166         while(read < length) {
167             int len = readBytes(b, _off, _length);
168             if(length == -1) {
169                 if(!nextArray()) {
170                     return read;
171                 }
172             }
173             else {
174                 read += len;
175                 fp += len;
176                 _off += len;
177                 _length -= len;
178             }
179         }
180
181         return read;
182     }
183
184     private int readBytes(byte[] b, int off, int length) {
185         int len = Math.min(length, buf.length - fp);
186         if(len <= 0) {
187             return -1;
188         }
189         System.arraycopy(buf, fp, b, off, len);
190         return len;
191     }
192
193     /**
194      * Writes max <code>b.length</code> bytes from the specified byte array
195      * to this array, starting at the current array pointer.
196      * <p/>
197      * This method doesn't write beyond array bounds,
198      * but <code>off</code> and <code>length</code> are not checked.
199      *
200      * @param b the data.
201      */

202     public void write(byte[] b) throws IOException JavaDoc {
203         write(b, 0, b.length);
204     }
205
206     /**
207      * Writes <code>len</code> bytes from the specified byte array
208      * starting at offset <code>off</code> to this RandomAccess.<br>
209      * <p/>
210      * This method doesn't write beyond array bounds,
211      * but <code>off</code> and <code>length</code> are not checked.
212      *
213      * @param b the data.
214      * @param off the start offset in the data.
215      * @param length the number of bytes to write
216      *
217      * @throws java.io.IOException if end of last array reached
218      */

219     public void write(byte[] b, int off, int length) throws IOException JavaDoc {
220         int write = 0;
221         int _off = off;
222         int _length = length;
223
224         while(write < length) {
225             int len = writeBytes(b, _off, _length);
226             dirty = true;
227             if(len == -1) {
228                 if(!nextArray()) {
229                     throw new EOFException JavaDoc();
230                 }
231             }
232             else {
233                 write += len;
234                 fp += len;
235                 _off += len;
236                 _length -= len;
237                 if(_length == 0) {
238                     break;
239                 }
240             }
241         }
242     }
243
244     public void flush() throws IOException JavaDoc {
245         if(dirty) {
246             bufferManager.setDirty(dataIndex);
247             dirty = false;
248         }
249         bufferManager.flush();
250     }
251
252     public void setByteOrder(int byteOrder) throws IOException JavaDoc {
253         super.setByteOrder(byteOrder);
254         if(bufferManager instanceof AbstractArrayBufferManager) {
255             ((AbstractArrayBufferManager) bufferManager).setByteOrder(getByteOrder());
256         }
257     }
258
259     protected void _setByteOrder(int byteOrder) throws IOException JavaDoc {
260         super._setByteOrder(byteOrder);
261         if(bufferManager instanceof AbstractArrayBufferManager) {
262             ((AbstractArrayBufferManager) bufferManager).setByteOrder(getByteOrder());
263         }
264     }
265
266     private int writeBytes(byte[] b, int off, int length) {
267         int len = Math.min(length, buf.length - fp);
268         if(len <= 0) {
269             return -1;
270         }
271         System.arraycopy(b, off, buf, fp, len);
272         return len;
273     }
274
275     /**
276      * Writes the specified byte to this array. The write starts at the current array pointer.
277      *
278      * @param b the <code>byte</code> to be written.
279      *
280      * @throws java.io.IOException if end of last array reached
281      */

282     public void write(int b) throws IOException JavaDoc {
283         if(fp < buf.length) {
284             buf[fp++] = (byte) b;
285         }
286         else {
287             nextArray();
288             if(buf == null) {
289                 throw new EOFException JavaDoc();
290             }
291             buf[fp++] = (byte) b;
292         }
293         dirty = true;
294     }
295
296     /**
297      * sets dirty flag in bufferManager and closes it
298      */

299     public void close() {
300         if(dirty) {
301             bufferManager.setDirty(dataIndex);
302             dirty = false;
303         }
304         bufferManager.close();
305     }
306
307     public int skip(int n) throws IOException JavaDoc {
308         return skipBytes(n);
309     }
310
311     protected int _read() throws EOFException JavaDoc {
312         int a = read();
313         if(a < 0) {
314             throw new EOFException JavaDoc();
315         }
316         return a;
317     }
318 }
319
Popular Tags