public static boolean ReadBlock(_RandomAccessFile file,
			ReadOptions options, BlockHandle handle, Block block)
			throws Exception {
		boolean may_cache = false;
		// *block = NULL;

		// Read the block contents as well as the type/crc footer.
		// See table_builder.java for the code that built this structure.
		int n = (int) handle.size();
		byte[] buf = new byte[n + Footer.kBlockTrailerSize];
		Slice iocontents = new Slice();
		buf = file.Read(handle.offset(), n + Footer.kBlockTrailerSize,
				iocontents); // set contents

		if (iocontents.size() != n + Footer.kBlockTrailerSize) {

			throw new Exception("truncated block read");
		}

		// Check the crc of the type and the block contents
		byte[] data = iocontents.data(); // Pointer to where Read put the data
		if (options.verify_checksums) {
			// get the value @ ofs n+1
			long crc = crc32java.Unmask(util.toInt(data, n + 1));
			crc32java crc32 = new crc32java();
			// calculate the value from 0 to n
			long actual = crc32.Value(data, n + 1);
			if (actual != crc) {
				throw new Exception("block checksum mismatch");
			}
		}

		/* compression or not */
		switch (data[n]) {
		case CompressionType.kNoCompression:
			if (data != buf) {
				// File implementation gave us pointer to some other data.
				// Use it directly under the assumption that it will be live
				// while the file is open.
				buf = null;
				block._Block(data, n, false);
				// block.setData_(data);
				// block.setSize_(n);
				// block.setOwned_(false);
				// block = new Block(data, n, false /* do not take ownership
				// */);
				may_cache = false; // Do not double-cache
			} else {
				block._Block(buf, n, true);
				// block.setData_(buf);
				// block.setSize_(n);
				// block.setOwned_(true);
				// block = new Block(buf, n, true /* take ownership */);
				may_cache = true;
			}

			// Ok
			break;
		// case CompressionType.kSnappyCompression:
		// int ulength = coding.GetVarint32(data, n); // get the vint32 as
		// // length
		//
		// // if (!port::Snappy_GetUncompressedLength(data, n, &ulength)) {
		// // buf = null;
		// // throw new Exception("corrupted compressed block contents");
		// // }
		// byte[] ubuf = new byte[ulength];
		// ubuf = SnappyDecompressor.decompress(data, 0, n).toByteArray();
		// // if (!port::Snappy_Uncompress(data, n, ubuf)) {
		// // buf = null;
		// // dubuf = null;
		// // throw new Exception("corrupted compressed block contents");
		// // }
		// buf = null;
		// block._Block(ubuf, ulength, true);
		// // block.setData_(ubuf);
		// // block.setSize_(ulength);
		// // block.setOwned_(true);
		// // *block = new Block(ubuf, ulength, true /* take ownership */);
		// may_cache = true;
		// break;

		default:
			buf = null;
			throw new Exception("bad block type");
		}

		return may_cache;
	}