@@ -43,12 +43,11 @@ public static FractalHeap read(SeekableByteChannel channel, long position, HdfDa
4343 filteredSize = header .filteredRootDirectSize ;
4444 filterMask = header .filterMaskRoot ;
4545 }
46- long expectedBlockOffset = 0 ;
4746 Block root ;
4847 if (nrows == 0 ) {
49- root = readDirectBlock (channel , header , rootAddress , sizeOfOffset , expectedBlockOffset , filteredSize , filterMask );
48+ root = readDirectBlock (channel , header , rootAddress , sizeOfOffset , filteredSize , filterMask );
5049 } else {
51- root = readIndirectBlock (channel , header , sizeOfOffset , sizeOfLength , rootAddress , expectedBlockOffset , -1 , nrows );
50+ root = readIndirectBlock (channel , header , sizeOfOffset , sizeOfLength , rootAddress , -1 , nrows );
5251 }
5352 FractalHeap heap = new FractalHeap ();
5453 heap .header = header ;
@@ -273,7 +272,7 @@ private static Filter parseV2Filter(ByteBuffer bb) {
273272 return f ;
274273 }
275274
276- private static Block readDirectBlock (SeekableByteChannel channel , FractalHeapHeader header , HdfFixedPoint address , FixedPointDatatype sizeOfOffset , long expectedBlockOffset , HdfFixedPoint filteredSize , long filterMask ) throws IOException , InvocationTargetException , InstantiationException , IllegalAccessException {
275+ private static Block readDirectBlock (SeekableByteChannel channel , FractalHeapHeader header , HdfFixedPoint address , FixedPointDatatype sizeOfOffset , HdfFixedPoint filteredSize , long filterMask ) throws IOException , InvocationTargetException , InstantiationException , IllegalAccessException {
277276 if (address .isUndefined ()) {
278277 throw new IOException ("Invalid direct block address" );
279278 }
@@ -299,15 +298,12 @@ private static Block readDirectBlock(SeekableByteChannel channel, FractalHeapHea
299298 throw new IOException ("Invalid heap header address in direct block" );
300299 }
301300 HdfFixedPoint blockOffset = HdfReadUtils .readHdfFixedPointFromBuffer (header .offsetBytes , headerBuffer );
302- if (blockOffset .getInstance (Long .class ) != expectedBlockOffset ) {
303- throw new IOException ("Block offset mismatch" );
304- }
305301 headerBuffer .position (4 + 1 + sizeOfOffset .getSize ()+header .offsetBytes .getSize ());
306302 long checksum = 0 ;
307303 if (header .checksumDirect ) {
308304 checksum = Integer .toUnsignedLong (headerBuffer .getInt ()); // checksum, not verifying
309305 }
310- long blockSize = getBlockSize (header , expectedBlockOffset );
306+ long blockSize = getBlockSize (header , blockOffset . getInstance ( Long . class ) );
311307 long dataSize ;
312308 if (!filteredSize .isUndefined ()) {
313309 dataSize = filteredSize .getInstance (Long .class );
@@ -317,16 +313,23 @@ private static Block readDirectBlock(SeekableByteChannel channel, FractalHeapHea
317313 if (dataSize < 0 ) {
318314 throw new IOException ("Invalid data size in direct block" );
319315 }
320- headerBuffer = ByteBuffer .allocate ((int ) dataSize ).order (ByteOrder .LITTLE_ENDIAN );
316+ // Determine the maximum number of bytes that can be read
317+ long fSize = channel .size ();
318+ long fPosition = channel .position ();
319+ long bytesRemainingInFile = fSize - fPosition ;
320+
321+ // The actual size to read is the smaller of the two values
322+ long actualReadSize = Math .min (dataSize , bytesRemainingInFile );
323+ headerBuffer = ByteBuffer .allocate ((int ) actualReadSize ).order (ByteOrder .LITTLE_ENDIAN );
321324 bytesRead = channel .read (headerBuffer );
322- if ( bytesRead != dataSize )
325+ if ( bytesRead != actualReadSize )
323326 throw new IllegalStateException ();
324327 headerBuffer .flip ();
325328
326329 byte [] data = headerBuffer .array ();
327330 DirectBlock db = new DirectBlock ();
328331 db .blockOffset = blockOffset .getInstance (Long .class );
329- db .blockSize = blockSize ;
332+ db .blockSize = actualReadSize ;
330333 db .data = data ;
331334 db .filterMask = filterMask ;
332335 db .checksum = checksum ;
@@ -367,7 +370,7 @@ private static int calculateChildrenEntriesSize(FractalHeapHeader header, int nr
367370 return entriesSize ;
368371 }
369372
370- private static void readAndVerifyIndirectBlockHeader (ByteBuffer blockBuffer , long expectedBlockOffset , FixedPointDatatype sizeOfOffset , FixedPointDatatype offsetBytes ) throws IOException , InvocationTargetException , InstantiationException , IllegalAccessException {
373+ private static long readAndVerifyIndirectBlockHeader (ByteBuffer blockBuffer , FixedPointDatatype sizeOfOffset , FixedPointDatatype offsetBytes ) throws IOException , InvocationTargetException , InstantiationException , IllegalAccessException {
371374 byte [] signatureBytes = new byte [4 ];
372375 blockBuffer .get (signatureBytes );
373376 String sig = new String (signatureBytes , StandardCharsets .US_ASCII );
@@ -386,14 +389,13 @@ private static void readAndVerifyIndirectBlockHeader(ByteBuffer blockBuffer, lon
386389 }
387390
388391 HdfFixedPoint blockOffset = HdfReadUtils .readHdfFixedPointFromBuffer (offsetBytes , blockBuffer );
389- if (blockOffset .getInstance (Long .class ) != expectedBlockOffset ) {
390- throw new IOException ("Block offset mismatch" );
391- }
392+
393+ return blockOffset .getInstance (Long .class );
392394 }
393395
394396 private static List <ChildInfo > parseChildInfos (ByteBuffer blockBuffer , FractalHeapHeader header , int nrows , long startOffset , FixedPointDatatype sizeOfOffset , FixedPointDatatype sizeOfLength ) throws InvocationTargetException , InstantiationException , IllegalAccessException , IOException {
395397 List <ChildInfo > childInfos = new ArrayList <>();
396- long currentOffset = startOffset ;
398+ // long currentOffset = startOffset;
397399 long startingBlockSize = header .startingBlockSize .getInstance (Long .class );
398400
399401 for (short r = 0 ; r < nrows ; r ++) {
@@ -410,9 +412,9 @@ private static List<ChildInfo> parseChildInfos(ByteBuffer blockBuffer, FractalHe
410412 }
411413
412414 if (!childAddress .isUndefined ()) {
413- childInfos .add (new ChildInfo (childAddress , currentOffset , isDirect , childFilteredSize , childFilterMask , rowBlockSize ));
415+ childInfos .add (new ChildInfo (childAddress , isDirect , childFilteredSize , childFilterMask , rowBlockSize ));
414416 }
415- currentOffset += rowBlockSize ;
417+ // currentOffset += rowBlockSize;
416418 }
417419 }
418420 return childInfos ;
@@ -423,17 +425,17 @@ private static List<Block> readChildren(SeekableByteChannel channel, FractalHeap
423425 for (ChildInfo info : childInfos ) {
424426 Block child ;
425427 if (info .isDirect ) {
426- child = readDirectBlock (channel , header , info .address , sizeOfOffset , info .blockOffset , info . filteredSize , info .filterMask );
428+ child = readDirectBlock (channel , header , info .address , sizeOfOffset , info .filteredSize , info .filterMask );
427429 } else {
428- child = readIndirectBlock (channel , header , sizeOfOffset , sizeOfLength , info .address , info .blockOffset , info . blockSize , 0 );
430+ child = readIndirectBlock (channel , header , sizeOfOffset , sizeOfLength , info .address , info .blockSize , 0 );
429431 }
430432 children .add (child );
431433 }
432434 return children ;
433435 }
434436 //</editor-fold>
435437
436- private static Block readIndirectBlock (SeekableByteChannel channel , FractalHeapHeader header , FixedPointDatatype sizeOfOffset , FixedPointDatatype sizeOfLength , HdfFixedPoint address , long expectedBlockOffset , long iblockSize , int passedNrows ) throws IOException , InvocationTargetException , InstantiationException , IllegalAccessException {
438+ private static Block readIndirectBlock (SeekableByteChannel channel , FractalHeapHeader header , FixedPointDatatype sizeOfOffset , FixedPointDatatype sizeOfLength , HdfFixedPoint address , long iblockSize , int passedNrows ) throws IOException , InvocationTargetException , InstantiationException , IllegalAccessException {
437439 if (address .isUndefined ()) {
438440 throw new IOException ("Invalid indirect block address" );
439441 }
@@ -456,15 +458,15 @@ private static Block readIndirectBlock(SeekableByteChannel channel, FractalHeapH
456458 blockBuffer .flip ();
457459
458460 // 4. Verify the block's header fields. The buffer position is advanced past the header.
459- readAndVerifyIndirectBlockHeader (blockBuffer , expectedBlockOffset , sizeOfOffset , header .offsetBytes );
461+ long fileBlockOffset = readAndVerifyIndirectBlockHeader (blockBuffer , sizeOfOffset , header .offsetBytes );
460462
461463 // 5. Parse child information from the buffer. The buffer position is advanced past the entries.
462- List <ChildInfo > childInfos = parseChildInfos (blockBuffer , header , nrows , expectedBlockOffset , sizeOfOffset , sizeOfLength );
464+ List <ChildInfo > childInfos = parseChildInfos (blockBuffer , header , nrows , fileBlockOffset , sizeOfOffset , sizeOfLength );
463465
464466 // 6. Create the block object and read the checksum from the end of the buffer.
465467 IndirectBlock ib = new IndirectBlock ();
466468 ib .nrows = nrows ;
467- ib .blockOffset = expectedBlockOffset ;
469+ ib .blockOffset = fileBlockOffset ;
468470 ib .checksum = Integer .toUnsignedLong (blockBuffer .getInt ());
469471
470472 // 7. Recursively read all children based on the parsed info.
@@ -575,15 +577,15 @@ public static class IndirectBlock extends Block {
575577
576578 private static class ChildInfo {
577579 HdfFixedPoint address ;
578- long blockOffset ;
580+ // long blockOffset;
579581 boolean isDirect ;
580582 HdfFixedPoint filteredSize ;
581583 long filterMask ;
582584 long blockSize ;
583585
584- public ChildInfo (HdfFixedPoint address , long blockOffset , boolean isDirect , HdfFixedPoint filteredSize , long filterMask , long blockSize ) {
586+ public ChildInfo (HdfFixedPoint address , boolean isDirect , HdfFixedPoint filteredSize , long filterMask , long blockSize ) {
585587 this .address = address ;
586- this .blockOffset = blockOffset ;
588+ // this.blockOffset = blockOffset;
587589 this .isDirect = isDirect ;
588590 this .filteredSize = filteredSize ;
589591 this .filterMask = filterMask ;
0 commit comments