/* * Copyright (c) Meta Platforms, Inc. and affiliates. * All rights reserved. * * This source code is licensed under both the BSD-style license (found in the * LICENSE file in the root directory of this source tree) and the GPLv2 (found * in the COPYING file in the root directory of this source tree). * You may select, at your option, one of the above-listed licenses. */ /* * Compressed-block decoding is implemented in * rust/src/zstd_decompress_block.rs. Keep `ZSTD_DCtx` C-owned: it has * optional build-dependent fields, while this small view contains only the * leaves read or written by the Rust decoder. No decoder algorithm remains * in this translation unit. */ #include "../common/zstd_deps.h" #include "../common/zstd_internal.h" #include "zstd_decompress_internal.h" #include "zstd_decompress_block.h" #if defined(ZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT) && \ defined(ZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG) #error "Cannot force the use of the short and the long ZSTD_decompressSequences variants!" #endif typedef struct { int forceShort; int forceLong; } ZSTD_rustSequenceDecoderPolicy; typedef char ZSTD_rust_sequence_decoder_policy_layout[ (offsetof(ZSTD_rustSequenceDecoderPolicy, forceShort) == 0 && offsetof(ZSTD_rustSequenceDecoderPolicy, forceLong) == sizeof(int) && sizeof(ZSTD_rustSequenceDecoderPolicy) == 2 * sizeof(int)) ? 1 : -1]; int ZSTD_rust_sequence_decoder_mode( const ZSTD_rustSequenceDecoderPolicy* policy); typedef char ZSTD_rust_block_seq_symbol_layout[(sizeof(ZSTD_seqSymbol) == 8) ? 1 : -1]; typedef char ZSTD_rust_block_entropy_rep_offset[ (offsetof(ZSTD_entropyDTables_t, rep) == 26652) ? 1 : -1]; typedef char ZSTD_rust_block_entropy_workspace_offset[ (offsetof(ZSTD_entropyDTables_t, workspace) == 26664) ? 1 : -1]; typedef struct { const ZSTD_seqSymbol** lltPtr; const ZSTD_seqSymbol** mltPtr; const ZSTD_seqSymbol** oftPtr; const HUF_DTable** hufPtr; ZSTD_entropyDTables_t* entropy; U32* workspace; size_t workspaceSize; const void** previousDstEnd; const void** prefixStart; const void** virtualStart; const void** dictEnd; size_t blockSizeMax; int* isFrameDecompression; U32* litEntropy; U32* fseEntropy; int bmi2; int* ddictIsCold; int disableHufAsm; const BYTE** litPtr; size_t* litSize; size_t* rleSize; BYTE** litBuffer; const BYTE** litBufferEnd; ZSTD_litLocation_e* litBufferLocation; BYTE* litExtraBuffer; size_t litExtraBufferSize; int sequenceDecoderMode; } ZSTD_rustBlockCtx; static ZSTD_rustBlockCtx ZSTD_rust_block_context(ZSTD_DCtx* dctx) { ZSTD_rustBlockCtx ctx; ZSTD_rustSequenceDecoderPolicy const sequencePolicy = { #if defined(ZSTD_FORCE_DECOMPRESS_SEQUENCES_SHORT) 1, 0 #elif defined(ZSTD_FORCE_DECOMPRESS_SEQUENCES_LONG) 0, 1 #else 0, 0 #endif }; ctx.lltPtr = &dctx->LLTptr; ctx.mltPtr = &dctx->MLTptr; ctx.oftPtr = &dctx->OFTptr; ctx.hufPtr = &dctx->HUFptr; ctx.entropy = &dctx->entropy; ctx.workspace = dctx->workspace; ctx.workspaceSize = sizeof(dctx->workspace); ctx.previousDstEnd = &dctx->previousDstEnd; ctx.prefixStart = &dctx->prefixStart; ctx.virtualStart = &dctx->virtualStart; ctx.dictEnd = &dctx->dictEnd; ctx.blockSizeMax = dctx->fParams.blockSizeMax; ctx.isFrameDecompression = &dctx->isFrameDecompression; ctx.litEntropy = &dctx->litEntropy; ctx.fseEntropy = &dctx->fseEntropy; ctx.bmi2 = ZSTD_DCtx_get_bmi2(dctx); ctx.ddictIsCold = &dctx->ddictIsCold; ctx.disableHufAsm = dctx->disableHufAsm; ctx.litPtr = &dctx->litPtr; ctx.litSize = &dctx->litSize; ctx.rleSize = &dctx->rleSize; ctx.litBuffer = &dctx->litBuffer; ctx.litBufferEnd = &dctx->litBufferEnd; ctx.litBufferLocation = &dctx->litBufferLocation; ctx.litExtraBuffer = dctx->litExtraBuffer; ctx.litExtraBufferSize = ZSTD_LITBUFFEREXTRASIZE; ctx.sequenceDecoderMode = ZSTD_rust_sequence_decoder_mode(&sequencePolicy); return ctx; } /* Rust owns the hidden fullbench wrappers, the block decoder's internal * entrypoints, and the public ZSTD_decompressBlock ABI. Keep only this * private-context projection in C: the layout is configuration-dependent and * must continue to be assembled next to ZSTD_DCtx. */ void ZSTD_rust_block_context_init(ZSTD_rustBlockCtx* out, ZSTD_DCtx* dctx); void ZSTD_rust_block_context_init(ZSTD_rustBlockCtx* out, ZSTD_DCtx* dctx) { *out = ZSTD_rust_block_context(dctx); }