in java/src/main/java/com/epam/deltix/zstd/ZstdFrameDecompressor.java [692:756]
private int decodeCompressedLiterals(final ByteBuffer inputBase, final int inputAddress, final int blockSize, final int literalsBlockType) {
int input = inputAddress;
verify(blockSize >= 5, input, "Not enough input bytes");
// compressed
final int compressedSize;
final int uncompressedSize;
boolean singleStream = false;
final int headerSize;
final int type = (inputBase.get(input) >> 2) & 0b11;
switch (type) {
case 0:
singleStream = true;
case 1: {
final int header = inputBase.getInt(input);
headerSize = 3;
uncompressedSize = (header >>> 4) & mask(10);
compressedSize = (header >>> 14) & mask(10);
break;
}
case 2: {
final int header = inputBase.getInt(input);
headerSize = 4;
uncompressedSize = (header >>> 4) & mask(14);
compressedSize = (header >>> 18) & mask(14);
break;
}
case 3: {
// read 5 little-endian bytes
final long header = inputBase.get(input) & 0xFF |
(inputBase.getInt(input + 1) & 0xFFFF_FFFFL) << 8;
headerSize = 5;
uncompressedSize = (int) ((header >>> 4) & mask(18));
compressedSize = (int) ((header >>> 22) & mask(18));
break;
}
default:
throw fail(input, "Invalid literals header size type");
}
verify(uncompressedSize <= MAX_BLOCK_SIZE, input, "Block exceeds maximum size");
verify(headerSize + compressedSize <= blockSize, input, "Input is corrupted");
input += headerSize;
final int inputLimit = input + compressedSize;
if (literalsBlockType != REPEAT_STATS_LITERALS_BLOCK) {
input += huffman.readTable(inputBase, input, compressedSize);
}
literalsBase = ByteBufferWrap(literals);
literalsAddress = 0;
literalsLimit = uncompressedSize;
if (singleStream) {
huffman.decodeSingleStream(inputBase, input, inputLimit, literalsBase, literalsAddress, literalsLimit);
} else {
huffman.decode4Streams(inputBase, input, inputLimit, literalsBase, literalsAddress, literalsLimit);
}
return headerSize + compressedSize;
}