HFileBlock unpack(HFileContext fileContext, FSReader reader) throws IOException {
    if (!fileContext.isCompressedOrEncrypted()) {
      // TODO: cannot use our own fileContext here because HFileBlock(ByteBuffer, boolean),
      // which is used for block serialization to L2 cache, does not preserve encoding and
      // encryption details.
      return this;
    }

    ByteBuff newBuf = allocateBufferForUnpacking(); // allocates space for the decompressed block
    HFileBlock unpacked = shallowClone(this, newBuf);

    boolean succ = false;
    final Context context =
      Context.current().with(CONTEXT_KEY, new HFileContextAttributesBuilderConsumer(fileContext));
    try (Scope ignored = context.makeCurrent()) {
      HFileBlockDecodingContext ctx = blockType == BlockType.ENCODED_DATA
        ? reader.getBlockDecodingContext()
        : reader.getDefaultBlockDecodingContext();
      // Create a duplicated buffer without the header part.
      int headerSize = this.headerSize();
      ByteBuff dup = this.bufWithoutChecksum.duplicate();
      dup.position(headerSize);
      dup = dup.slice();
      // Decode the dup into unpacked#buf
      ctx.prepareDecoding(unpacked.getOnDiskDataSizeWithHeader() - headerSize,
        unpacked.getUncompressedSizeWithoutHeader(), unpacked.getBufferWithoutHeader(), dup);
      succ = true;
      return unpacked;
    } finally {
      if (!succ) {
        unpacked.release();
      }
    }
  }
Retrieves the decompressed/decrypted view of this block. An encoded block remains in its
encoded structure. Internal structures are shared between instances where applicable.
hbase-server/src/main/java/org/apache/hadoop/hbase/io/hfile/HFileBlock.java