Example #1
0
  private CommonHFSExtentDescriptor getExtent(int extIndex, long startBlock) {
    long curStartBlock = startBlock;

    while (extIndex >= extentDescriptors.size()) {
      /* Need to read the next overflow extent into
       * extentDescriptors. */

      if (overflowExtentsStore == null) {
        throw new RuntimeIOException(
            "No overflow extents store to " + "query for overflow extents.");
      }

      CommonHFSExtentLeafRecord extentRecord;

      if (all_extents_mapped) {
        extentRecord = null;
      } else {
        extentRecord = overflowExtentsStore.getExtentRecord(curStartBlock);
      }

      final CommonHFSExtentDescriptor[] descriptors = extentRecord.getRecordData();

      for (int i = 0; i < descriptors.length; ++i) {
        final CommonHFSExtentDescriptor curDescriptor = descriptors[i];
        final long blockCount = curDescriptor.getBlockCount();

        if (blockCount == 0) {
          /* End-of-fork at first occurrence of block count 0. */
          all_extents_mapped = true;
          break;
        }

        extentDescriptors.add(curDescriptor);
        curStartBlock += blockCount;
      }
    }

    return extentDescriptors.get(extIndex);
  }
Example #2
0
  /* @Override */
  public int read(byte[] data, int pos, int len) {
    // System.err.println("ForkFilter.read(" + data + ", " + pos + ", " + len);
    long offset = Long.MAX_VALUE; // MAX_VALUE as a sentinel for seek
    long bytesToSkip = logicalPosition;
    long curLogicalBlock = 0;
    int extIndex;
    long currentExtentLength;

    if (extentDescriptors.size() < 1 || logicalPosition > forkLength) {
      return -1; // EOF
    }

    // Skip all extents whose range is located before the requested position (logicalPosition)
    // System.out.println("ForkFilter.read: skipping extents (bytesToSkip=" +
    //        bytesToSkip + ")...");
    for (extIndex = 0; ; ++extIndex) {
      CommonHFSExtentDescriptor cur = getExtent(extIndex, curLogicalBlock);
      if (cur == null) {
        /* No such extent available. */
        return -1;
      }

      long currentBlockCount = cur.getBlockCount();
      currentExtentLength = currentBlockCount * allocationBlockSize;

      if (bytesToSkip >= currentExtentLength) {
        bytesToSkip -= currentExtentLength;
        curLogicalBlock += currentBlockCount;
      } else {
        offset =
            fsOffset
                + firstBlockByteOffset
                + (cur.getStartBlock() * allocationBlockSize)
                + bytesToSkip;
        break;
      }
    }
    // System.out.println("done. skipped " + extIndex + " extents.");

    if (logicalPosition != lastLogicalPos) {
      // System.out.print("ForkFilter.read: (1)seeking to " + offset + "...");
      sourceFile.seek(offset); // Seek to the correct position
      // System.out.println("done.");
    } else if (sourceFile.getFilePointer() != lastPhysicalPos) {
      // System.out.print("ForkFilter.read: (2)seeking to " + offset + "...");
      sourceFile.seek(lastPhysicalPos);
      // System.out.println("done.");
    }

    long bytesLeftInStream = forkLength - logicalPosition;
    // System.err.println("bytesLeftInStream: " + bytesLeftInStream + " len: " + len);
    int totalBytesToRead = bytesLeftInStream < len ? (int) bytesLeftInStream : len;
    int bytesLeftToRead = totalBytesToRead;
    // System.err.println("bytesLeftToRead: " + bytesLeftToRead);
    // Start reading. Extent by extent if needed.
    for (; ; ++extIndex) {
      // System.out.println("ForkFilter.read: reading extent " + extIndex + ".");

      CommonHFSExtentDescriptor cur;
      try {
        cur = getExtent(extIndex, curLogicalBlock);
      } catch (RuntimeException e) {
        if (bytesLeftToRead == totalBytesToRead) {
          throw e;
        } else {
          break;
        }
      }

      sourceFile.seek(
          fsOffset
              + firstBlockByteOffset
              + (cur.getStartBlock() * allocationBlockSize)
              + bytesToSkip);

      long blockCount = cur.getBlockCount();
      long bytesInExtent = blockCount * allocationBlockSize - bytesToSkip;
      int bytesToReadFromExtent =
          (bytesInExtent < bytesLeftToRead) ? (int) bytesInExtent : bytesLeftToRead;

      int bytesReadFromExtent = 0;
      while (bytesReadFromExtent < bytesToReadFromExtent) {
        int bytesToRead = bytesToReadFromExtent - bytesReadFromExtent;
        int positionInArray = pos + (totalBytesToRead - bytesLeftToRead) + bytesReadFromExtent;

        int bytesRead = sourceFile.read(data, positionInArray, bytesToRead);
        if (bytesRead > 0) bytesReadFromExtent += bytesRead;
        else {
          // Update tracker variables before returning
          lastPhysicalPos = sourceFile.getFilePointer();
          int totalBytesRead = positionInArray - pos;
          logicalPosition += totalBytesRead;
          return totalBytesRead;
        }
      }

      bytesLeftToRead -= bytesReadFromExtent;
      bytesToSkip = 0;
      curLogicalBlock += blockCount;

      if (bytesLeftToRead == 0) break;
    }

    // Update tracker variables before returning
    lastPhysicalPos = sourceFile.getFilePointer();
    logicalPosition += totalBytesToRead - bytesLeftToRead;

    if (bytesLeftToRead < totalBytesToRead) {
      int bytesRead = totalBytesToRead - bytesLeftToRead;
      // System.err.println("final bytesRead: " + bytesRead);
      return bytesRead;
    } else return -1;
  }