Skip to content

Commit 4a365aa

Browse files
committed
DataHandle: fix findString(..) and support handles with unknown length
The findString(..) method used to require the exact length of the handle, this length can be unknown, e.g. for compressed handles. This is no longer the case.
1 parent 6c094f7 commit 4a365aa

File tree

1 file changed

+10
-12
lines changed

1 file changed

+10
-12
lines changed

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

+10-12
Original file line numberDiff line numberDiff line change
@@ -350,10 +350,7 @@ default String findString(final boolean saveString, final int blockSize,
350350
final StringBuilder out = new StringBuilder();
351351
final long startPos = offset();
352352
long bytesDropped = 0;
353-
final long inputLen = length();
354-
long maxLen = inputLen - startPos;
355-
final boolean tooLong = saveString && maxLen > MAX_SEARCH_SIZE;
356-
if (tooLong) maxLen = MAX_SEARCH_SIZE;
353+
final long maxLen = saveString ? MAX_SEARCH_SIZE : Long.MAX_VALUE;
357354
boolean match = false;
358355
int maxTermLen = 0;
359356
for (final String term : terminators) {
@@ -366,7 +363,10 @@ default String findString(final boolean saveString, final int blockSize,
366363
new DataHandleInputStream<>(this), getEncoding());
367364
final char[] buf = new char[blockSize];
368365
long loc = 0;
369-
while (loc < maxLen && offset() < length() - 1) {
366+
int r = 0;
367+
368+
// NB: we need at least 2 bytes to read a char
369+
while (loc < maxLen && ((r = in.read(buf, 0, blockSize)) > 1)) {
370370
// if we're not saving the string, drop any old, unnecessary output
371371
if (!saveString) {
372372
final int outLen = out.length();
@@ -378,16 +378,12 @@ default String findString(final boolean saveString, final int blockSize,
378378
bytesDropped += dropIndex;
379379
}
380380
}
381-
382-
// read block from stream
383-
final int r = in.read(buf, 0, blockSize);
384-
if (r <= 0) throw new IOException("Cannot read from stream: " + r);
385-
386381
// append block to output
387382
out.append(buf, 0, r);
388383

389384
// check output, returning smallest possible string
390-
int min = Integer.MAX_VALUE, tagLen = 0;
385+
int min = Integer.MAX_VALUE;
386+
int tagLen = 0;
391387
for (final String t : terminators) {
392388
final int len = t.length();
393389
final int start = (int) (loc - bytesDropped - len);
@@ -415,7 +411,9 @@ default String findString(final boolean saveString, final int blockSize,
415411
}
416412

417413
// no match
418-
if (tooLong) throw new IOException("Maximum search length reached.");
414+
if (loc > MAX_SEARCH_SIZE) {
415+
throw new IOException("Maximum search length reached.");
416+
}
419417
return saveString ? out.toString() : null;
420418
}
421419

0 commit comments

Comments
 (0)