Skip to content

Commit b2ce4d5

Browse files
joewizclaude
andcommitted
[refactor] Extract readBinary validation and I/O into helper methods
Reduce NPath complexity of readBinary from 816 to within threshold by extracting validateBinaryRange() and readBinaryData() helper methods. No behavioral change. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent bf52c30 commit b2ce4d5

File tree

1 file changed

+30
-27
lines changed
  • extensions/expath/src/main/java/org/expath/exist/file

1 file changed

+30
-27
lines changed

extensions/expath/src/main/java/org/expath/exist/file/FileIO.java

Lines changed: 30 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -217,41 +217,44 @@ private Sequence readBinary(final Path path, final Sequence[] args) throws XPath
217217

218218
try {
219219
final long fileSize = Files.size(path);
220-
if (offset < 0 || offset > fileSize) {
221-
throw new XPathException(this, ExpathFileErrorCode.OUT_OF_RANGE,
222-
"Offset " + offset + " is out of range for file of size " + fileSize);
223-
}
224-
if (hasLength && length < 0) {
225-
throw new XPathException(this, ExpathFileErrorCode.OUT_OF_RANGE,
226-
"Length must not be negative: " + length);
227-
}
228-
if (hasLength && offset + length > fileSize) {
229-
throw new XPathException(this, ExpathFileErrorCode.OUT_OF_RANGE,
230-
"Offset + length exceeds file size: " + (offset + length) + " > " + fileSize);
231-
}
232-
233-
final byte[] data;
234-
if (offset == 0 && !hasLength) {
235-
// Read entire file
236-
data = Files.readAllBytes(path);
237-
} else {
238-
// Partial read
239-
try (final RandomAccessFile raf = new RandomAccessFile(path.toFile(), "r")) {
240-
raf.seek(offset);
241-
final int readLen = hasLength ? (int) length : (int) (fileSize - offset);
242-
data = new byte[readLen];
243-
raf.readFully(data);
244-
}
245-
}
220+
validateBinaryRange(offset, length, hasLength, fileSize);
246221

247-
// Encode as base64 and return a lightweight BinaryValue with no open handles
222+
final byte[] data = readBinaryData(path, offset, hasLength, length, fileSize);
248223
final String base64 = java.util.Base64.getEncoder().encodeToString(data);
249224
return new BinaryValueFromBinaryString(this, new Base64BinaryValueType(), base64);
250225
} catch (final IOException e) {
251226
throw new XPathException(this, ExpathFileErrorCode.IO_ERROR, e.getMessage());
252227
}
253228
}
254229

230+
private void validateBinaryRange(final long offset, final long length, final boolean hasLength, final long fileSize) throws XPathException {
231+
if (offset < 0 || offset > fileSize) {
232+
throw new XPathException(this, ExpathFileErrorCode.OUT_OF_RANGE,
233+
"Offset " + offset + " is out of range for file of size " + fileSize);
234+
}
235+
if (hasLength && length < 0) {
236+
throw new XPathException(this, ExpathFileErrorCode.OUT_OF_RANGE,
237+
"Length must not be negative: " + length);
238+
}
239+
if (hasLength && offset + length > fileSize) {
240+
throw new XPathException(this, ExpathFileErrorCode.OUT_OF_RANGE,
241+
"Offset + length exceeds file size: " + (offset + length) + " > " + fileSize);
242+
}
243+
}
244+
245+
private byte[] readBinaryData(final Path path, final long offset, final boolean hasLength, final long length, final long fileSize) throws IOException {
246+
if (offset == 0 && !hasLength) {
247+
return Files.readAllBytes(path);
248+
}
249+
try (final RandomAccessFile raf = new RandomAccessFile(path.toFile(), "r")) {
250+
raf.seek(offset);
251+
final int readLen = hasLength ? (int) length : (int) (fileSize - offset);
252+
final byte[] data = new byte[readLen];
253+
raf.readFully(data);
254+
return data;
255+
}
256+
}
257+
255258
/**
256259
* Reads a file as text with the given encoding.
257260
* If fallback is true, malformed byte sequences and XML-illegal characters

0 commit comments

Comments
 (0)