Skip to content

Commit 966c71c

Browse files
gab1onectrueden
authored andcommitted
Add support for read-only and write-only handles
Signed-off-by: Curtis Rueden <ctrueden@wisc.edu>
1 parent 11df0fd commit 966c71c

File tree

6 files changed

+60
-3
lines changed

6 files changed

+60
-3
lines changed

src/main/java/org/scijava/io/ByteBank.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,4 +160,10 @@ default void basicRangeCheck(final long start, final long end) {
160160
*/
161161
long getMaxBufferSize();
162162

163+
/**
164+
* @return True iff the buffer is read-only.
165+
*/
166+
default boolean isReadOnly() {
167+
return false;
168+
}
163169
}

src/main/java/org/scijava/io/handle/BytesHandle.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,16 @@ public void seek(final long pos) throws IOException {
8585
offset = pos;
8686
}
8787

88+
@Override
89+
public boolean isReadable() {
90+
return true;
91+
}
92+
93+
@Override
94+
public boolean isWritable() {
95+
return !bytes().isReadOnly();
96+
}
97+
8898
// -- DataInput methods --
8999

90100
@Override

src/main/java/org/scijava/io/handle/DataHandle.java

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -115,15 +115,23 @@ default long available(final long count) throws IOException {
115115
return remain < count ? remain : count;
116116
}
117117

118+
/** Gets whether reading from this handle is supported. */
119+
boolean isReadable();
120+
121+
/** Gets whether writing to this handle is supported. */
122+
boolean isWritable();
123+
118124
/**
119125
* Ensures that the handle has sufficient bytes available to read.
120126
*
121127
* @param count Number of bytes to read.
122128
* @see #available(long)
123129
* @throws EOFException If there are insufficient bytes available.
124-
* @throws IOException If something goes wrong with the check.
130+
* @throws IOException If the handle is write-only, or something goes wrong
131+
* with the check.
125132
*/
126133
default void ensureReadable(final long count) throws IOException {
134+
if (!isReadable()) throw new IOException("This handle is write-only.");
127135
if (available(count) < count) throw new EOFException();
128136
}
129137

@@ -134,10 +142,12 @@ default void ensureReadable(final long count) throws IOException {
134142
* @param count Number of bytes to write.
135143
* @return {@code true} if the handle's length was sufficient, or
136144
* {@code false} if the handle's length required an extension.
137-
* @throws IOException If something goes wrong with the check, or there is an
138-
* error changing the handle's length.
145+
* @throws IOException If the handle is read-only, or something goes wrong
146+
* with the check, or there is an error changing the handle's
147+
* length.
139148
*/
140149
default boolean ensureWritable(final long count) throws IOException {
150+
if (!isWritable()) throw new IOException("This handle is read-only.");
141151
final long minLength = offset() + count;
142152
if (length() < minLength) {
143153
setLength(minLength);

src/main/java/org/scijava/io/handle/DummyHandle.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,16 @@ public void setLength(final long length) throws IOException {
7373
this.length = length;
7474
}
7575

76+
@Override
77+
public boolean isReadable() {
78+
return true;
79+
}
80+
81+
@Override
82+
public boolean isWritable() {
83+
return true;
84+
}
85+
7686
// -- DataInput methods --
7787

7888
@Override

src/main/java/org/scijava/io/handle/FileHandle.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,16 @@ public void setLength(final long length) throws IOException {
8888
raf().setLength(length);
8989
}
9090

91+
@Override
92+
public boolean isReadable() {
93+
return getMode().contains("r");
94+
}
95+
96+
@Override
97+
public boolean isWritable() {
98+
return getMode().contains("w");
99+
}
100+
91101
@Override
92102
public int read() throws IOException {
93103
return raf().read();

src/main/java/org/scijava/io/nio/ByteBufferByteBank.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,17 @@ public long getMaxPos() {
138138
return maxBufferedPos;
139139
}
140140

141+
@Override
142+
public boolean isReadOnly() {
143+
// NB: Some ByteBuffers are read-only. But there is no API to check it.
144+
// Therefore, we make a "best effort" guess based on known read-only types.
145+
// Since these read-only types are not public, we compare class names rather
146+
// than checking for type equality or using instanceof.
147+
final String className = buffer.getClass().getName();
148+
return className.equals("java.nio.HeapByteBufferR") ||
149+
className.equals("java.nio.DirectByteBufferR");
150+
}
151+
141152
private void ensureCapacity(final int minCapacity) {
142153
final int oldCapacity = buffer.capacity();
143154
if (minCapacity <= oldCapacity) return; // no need to grow

0 commit comments

Comments
 (0)