Skip to content

Commit 557de79

Browse files
ctruedengab1one
authored andcommitted
Add a DataHandle which operates on a BytesLocation
This was migrated from SCIFIO/Bio-Formats's ByteArrayHandle.
1 parent 26fcec1 commit 557de79

File tree

1 file changed

+301
-0
lines changed

1 file changed

+301
-0
lines changed
Lines changed: 301 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,301 @@
1+
/*
2+
* #%L
3+
* SciJava Common shared library for SciJava software.
4+
* %%
5+
* Copyright (C) 2009 - 2016 Board of Regents of the University of
6+
* Wisconsin-Madison, Broad Institute of MIT and Harvard, and Max Planck
7+
* Institute of Molecular Cell Biology and Genetics.
8+
* %%
9+
* Redistribution and use in source and binary forms, with or without
10+
* modification, are permitted provided that the following conditions are met:
11+
*
12+
* 1. Redistributions of source code must retain the above copyright notice,
13+
* this list of conditions and the following disclaimer.
14+
* 2. Redistributions in binary form must reproduce the above copyright notice,
15+
* this list of conditions and the following disclaimer in the documentation
16+
* and/or other materials provided with the distribution.
17+
*
18+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21+
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
22+
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23+
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24+
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25+
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26+
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27+
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28+
* POSSIBILITY OF SUCH DAMAGE.
29+
* #L%
30+
*/
31+
32+
package org.scijava.io;
33+
34+
import java.io.EOFException;
35+
import java.io.IOException;
36+
import java.nio.BufferUnderflowException;
37+
import java.nio.ByteBuffer;
38+
import java.nio.ByteOrder;
39+
40+
import org.scijava.plugin.Plugin;
41+
42+
/**
43+
* {@link DataHandle} for a {@link BytesLocation}.
44+
*
45+
* @author Curtis Rueden
46+
* @author Melissa Linkert
47+
*/
48+
@Plugin(type = DataHandle.class)
49+
public class BytesHandle extends AbstractDataHandle<BytesLocation> {
50+
51+
// -- DataHandle methods --
52+
53+
@Override
54+
public long offset() {
55+
return bytes().position();
56+
}
57+
58+
@Override
59+
public long length() {
60+
return bytes().limit();
61+
}
62+
63+
@Override
64+
public void setLength(final long length) throws IOException {
65+
if (length > bytes().capacity()) {
66+
// NB: We cannot extend the length of a ByteBuffer beyond its capacity.
67+
// We have no choice but to allocate a new, higher capacity ByteBuffer,
68+
// and copy the contents and state of the old ByteBuffer into it.
69+
// This will change the backing ByteBuffer of the BytesLocation!
70+
71+
// save state of the existing buffer
72+
final long off = offset();
73+
final ByteOrder order = getOrder();
74+
75+
// allocate a new, higher capacity buffer
76+
final ByteBuffer newBytes = ByteBuffer.allocate((int) (length * 2));
77+
78+
// copy bytes from the old buffer to the new one
79+
seek(0);
80+
newBytes.put(bytes());
81+
82+
// update the backing BytesLocation's backing ByteBuffer
83+
get().setByteBuffer(newBytes);
84+
85+
// restore the previous state (order and offset) to the new buffer
86+
setOrder(order);
87+
seek(off);
88+
}
89+
90+
// set the length (a.k.a. "limit") of the buffer to match
91+
bytes().limit((int) length);
92+
}
93+
94+
@Override
95+
public ByteOrder getOrder() {
96+
return bytes().order();
97+
}
98+
99+
@Override
100+
public void setOrder(final ByteOrder order) {
101+
bytes().order(order);
102+
}
103+
104+
@Override
105+
public int read(final byte[] b, final int off, int len) throws IOException {
106+
if (offset() + len > length()) {
107+
len = (int) (length() - offset());
108+
}
109+
bytes().get(b, off, len);
110+
return len;
111+
}
112+
113+
@Override
114+
public void seek(final long pos) throws IOException {
115+
if (pos > length()) setLength(pos);
116+
bytes().position((int) pos);
117+
}
118+
119+
// -- DataInput methods --
120+
121+
@Override
122+
public byte readByte() throws IOException {
123+
ensureReadable(1);
124+
try {
125+
// we need to convert the bytes into the range 0-255
126+
return bytes().get();
127+
}
128+
catch (final BufferUnderflowException e) {
129+
throw eofException(e);
130+
}
131+
}
132+
133+
@Override
134+
public char readChar() throws IOException {
135+
ensureReadable(2);
136+
try {
137+
return bytes().getChar();
138+
}
139+
catch (final BufferUnderflowException e) {
140+
throw eofException(e);
141+
}
142+
}
143+
144+
@Override
145+
public double readDouble() throws IOException {
146+
ensureReadable(8);
147+
try {
148+
return bytes().getDouble();
149+
}
150+
catch (final BufferUnderflowException e) {
151+
throw eofException(e);
152+
}
153+
}
154+
155+
@Override
156+
public float readFloat() throws IOException {
157+
ensureReadable(4);
158+
try {
159+
return bytes().getFloat();
160+
}
161+
catch (final BufferUnderflowException e) {
162+
throw eofException(e);
163+
}
164+
}
165+
166+
@Override
167+
public void readFully(final byte[] b, final int off, final int len)
168+
throws IOException
169+
{
170+
ensureReadable(len);
171+
try {
172+
bytes().get(b, off, len);
173+
}
174+
catch (final BufferUnderflowException e) {
175+
throw eofException(e);
176+
}
177+
}
178+
179+
@Override
180+
public int readInt() throws IOException {
181+
ensureReadable(4);
182+
try {
183+
return bytes().getInt();
184+
}
185+
catch (final BufferUnderflowException e) {
186+
throw eofException(e);
187+
}
188+
}
189+
190+
@Override
191+
public long readLong() throws IOException {
192+
ensureReadable(8);
193+
try {
194+
return bytes().getLong();
195+
}
196+
catch (final BufferUnderflowException e) {
197+
throw eofException(e);
198+
}
199+
}
200+
201+
@Override
202+
public short readShort() throws IOException {
203+
ensureReadable(2);
204+
try {
205+
return bytes().getShort();
206+
}
207+
catch (final BufferUnderflowException e) {
208+
throw eofException(e);
209+
}
210+
}
211+
212+
// -- DataOutput methods --
213+
214+
@Override
215+
public void write(final byte[] b, final int off, final int len)
216+
throws IOException
217+
{
218+
ensureWritable(len);
219+
bytes().put(b, off, len);
220+
}
221+
222+
@Override
223+
public void write(final int b) throws IOException {
224+
ensureWritable(1);
225+
bytes().put((byte) b);
226+
}
227+
228+
@Override
229+
public void writeChar(final int v) throws IOException {
230+
ensureWritable(2);
231+
bytes().putChar((char) v);
232+
}
233+
234+
@Override
235+
public void writeChars(final String s) throws IOException {
236+
final int len = 2 * s.length();
237+
ensureWritable(len);
238+
final char[] c = s.toCharArray();
239+
for (int i = 0; i < c.length; i++) {
240+
writeChar(c[i]);
241+
}
242+
}
243+
244+
@Override
245+
public void writeDouble(final double v) throws IOException {
246+
ensureWritable(8);
247+
bytes().putDouble(v);
248+
}
249+
250+
@Override
251+
public void writeFloat(final float v) throws IOException {
252+
ensureWritable(4);
253+
bytes().putFloat(v);
254+
}
255+
256+
@Override
257+
public void writeInt(final int v) throws IOException {
258+
ensureWritable(4);
259+
bytes().putInt(v);
260+
}
261+
262+
@Override
263+
public void writeLong(final long v) throws IOException {
264+
ensureWritable(8);
265+
bytes().putLong(v);
266+
}
267+
268+
@Override
269+
public void writeShort(final int v) throws IOException {
270+
ensureWritable(2);
271+
bytes().putShort((short) v);
272+
}
273+
274+
// -- Closeable methods --
275+
276+
@Override
277+
public void close() {
278+
// NB: No action needed.
279+
}
280+
281+
// -- Typed methods --
282+
283+
@Override
284+
public Class<BytesLocation> getType() {
285+
return BytesLocation.class;
286+
}
287+
288+
// -- Helper methods --
289+
290+
/** Backing {@link ByteBuffer} accessor, purely for succinctness. */
291+
private ByteBuffer bytes() {
292+
return get().getByteBuffer();
293+
}
294+
295+
private EOFException eofException(final Throwable cause) {
296+
final EOFException eof = new EOFException();
297+
eof.initCause(cause);
298+
return eof;
299+
}
300+
301+
}

0 commit comments

Comments
 (0)