001: /*
002: * Copyright (c) 2007, intarsys consulting GmbH
003: *
004: * Redistribution and use in source and binary forms, with or without
005: * modification, are permitted provided that the following conditions are met:
006: *
007: * - Redistributions of source code must retain the above copyright notice,
008: * this list of conditions and the following disclaimer.
009: *
010: * - Redistributions in binary form must reproduce the above copyright notice,
011: * this list of conditions and the following disclaimer in the documentation
012: * and/or other materials provided with the distribution.
013: *
014: * - Neither the name of intarsys nor the names of its contributors may be used
015: * to endorse or promote products derived from this software without specific
016: * prior written permission.
017: *
018: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
019: * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
020: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
021: * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
022: * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
023: * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
024: * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
025: * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
026: * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
027: * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
028: * POSSIBILITY OF SUCH DAMAGE.
029: */
030: package de.intarsys.tools.randomaccess;
031:
032: import java.io.IOException;
033:
034: /**
035: * A wrapper around a byte array to allow random access like API.
036: *
037: */
038: public class RandomAccessByteArray extends AbstractRandomAccess {
039: /**
040: * The minimum number of bytes we will resize the byte array buffer
041: */
042: private static final int RESIZE_BYTES = 32;
043:
044: /**
045: * The byte array data
046: */
047: private byte[] data;
048:
049: /**
050: * The current offset into the byte array
051: */
052: private int offset;
053:
054: /**
055: * The number of valid bytes in the byte array
056: */
057: private int length;
058:
059: /**
060: *
061: */
062: public RandomAccessByteArray(byte[] buffer) {
063: this .offset = 0;
064: if (buffer == null) {
065: this .data = new byte[RESIZE_BYTES];
066: this .length = 0;
067: } else {
068: this .data = buffer;
069: this .length = buffer.length;
070: }
071: }
072:
073: /**
074: * @return Returns the data.
075: */
076: protected byte[] getData() {
077: return data;
078: }
079:
080: /*
081: * (non-Javadoc)
082: *
083: * @see de.intarsys.tools.randomaccess.IRandomAccessData#seek(long)
084: */
085: public void seek(long pOffset) throws IOException {
086: this .offset = (int) pOffset;
087: if (offset < 0) {
088: offset = 0;
089: throw new IOException("offset less than 0");
090: }
091: }
092:
093: public void seekBy(long delta) throws IOException {
094: this .offset = (int) (offset + delta);
095: if (offset < 0) {
096: offset = 0;
097: throw new IOException("offset less than 0");
098: }
099: }
100:
101: /*
102: * (non-Javadoc)
103: *
104: * @see de.intarsys.tools.randomaccess.IRandomAccessData#read()
105: */
106: public int read() {
107: if (offset < length) {
108: return data[offset++] & 0xff;
109: }
110: return -1;
111: }
112:
113: /*
114: * (non-Javadoc)
115: *
116: * @see de.intarsys.tools.randomaccess.IRandomAccessData#getOffset()
117: */
118: public long getOffset() {
119: return offset;
120: }
121:
122: /*
123: * (non-Javadoc)
124: *
125: * @see de.intarsys.tools.randomaccess.IRandomAccessData#getLength()
126: */
127: public long getLength() throws IOException {
128: return length;
129: }
130:
131: /*
132: * (non-Javadoc)
133: *
134: * @see de.intarsys.tools.randomaccess.IRandomAccessData#read(byte[])
135: */
136: public int read(byte[] buffer) {
137: return read(buffer, 0, buffer.length);
138: }
139:
140: /*
141: * (non-Javadoc)
142: *
143: * @see de.intarsys.tools.randomaccess.IRandomAccessData#read(byte[], int,
144: * int)
145: */
146: public int read(byte[] buffer, int bufferOffset, int numBytes) {
147: int remaining = (int) (length - offset);
148: if (numBytes > remaining) {
149: numBytes = remaining;
150: if (numBytes == 0) {
151: return -1;
152: }
153: }
154: System.arraycopy(data, offset, buffer, bufferOffset, numBytes);
155: offset += numBytes;
156: return numBytes;
157: }
158:
159: /* (non-Javadoc)
160: * @see de.intarsys.tools.randomaccess.IRandomAccess#close()
161: */
162: public void close() throws IOException {
163: flush();
164: }
165:
166: /*
167: * (non-Javadoc)
168: *
169: * @see de.intarsys.tools.randomaccess.IRandomAccess#flush()
170: */
171: public void flush() throws IOException {
172: //
173: }
174:
175: /*
176: * (non-Javadoc)
177: *
178: * @see de.intarsys.tools.randomaccess.IRandomAccessData#isReadOnly()
179: */
180: public boolean isReadOnly() {
181: return false;
182: }
183:
184: /*
185: * (non-Javadoc)
186: *
187: * @see de.intarsys.tools.randomaccess.IRandomAccessData#setLength(int)
188: */
189: public void setLength(long newLength) {
190: if (newLength > length) {
191: if (newLength > data.length) {
192: byte[] newData;
193: if ((newLength - data.length) < RESIZE_BYTES) {
194: newData = new byte[data.length + RESIZE_BYTES];
195: } else {
196: newData = new byte[(int) newLength];
197: }
198: System.arraycopy(data, 0, newData, 0, length);
199: data = newData;
200: }
201: } else {
202: if (offset > newLength) {
203: offset = (int) newLength;
204: }
205: }
206: length = (int) newLength;
207: }
208:
209: /*
210: * (non-Javadoc)
211: *
212: * @see de.intarsys.tools.randomaccess.IRandomAccessData#write(int)
213: */
214: public void write(int b) {
215: int newLength = offset + 1;
216: if (newLength > length) {
217: setLength(newLength);
218: }
219: data[offset++] = (byte) b;
220: }
221:
222: /*
223: * (non-Javadoc)
224: *
225: * @see de.intarsys.tools.randomaccess.IRandomAccessData#write(byte[])
226: */
227: public void write(byte[] buffer) {
228: write(buffer, 0, buffer.length);
229: }
230:
231: /*
232: * (non-Javadoc)
233: *
234: * @see de.intarsys.tools.randomaccess.IRandomAccessData#write(byte[])
235: */
236: public void write(byte[] buffer, int start, int numBytes) {
237: long newLength = offset + numBytes;
238: if (newLength > length) {
239: setLength(newLength);
240: }
241: System.arraycopy(buffer, start, data, offset, numBytes);
242: offset += numBytes;
243: }
244:
245: public byte[] toByteArray() {
246: byte[] newbuf = new byte[length];
247: System.arraycopy(data, 0, newbuf, 0, length);
248: return newbuf;
249: }
250: }
|