Line data Source code
1 : #ifndef HEADER_fd_src_discof_restore_utils_fd_zstd_frame_h 2 : #define HEADER_fd_src_discof_restore_utils_fd_zstd_frame_h 3 : 4 : /* A Zstandard stream is a sequence of independent frames. A normal 5 : frame contains a variable-size header, repeated 3-byte block headers 6 : and payloads, and an optional 4-byte checksum. The last-block bit 7 : marks the frame boundary. A skippable frame contains an 8-byte 8 : header followed by a sized payload. 9 : 10 : stream: 11 : +---------- frame 0 ----------+ +---------- frame 1 ----------+ 12 : | header | blocks | checksum? | | header | blocks | checksum? | 13 : +-----------------------------+ +-----------------------------+ 14 : 15 : normal frame: 16 : +--------+ +-------------------------+ +-----------+ 17 : | header | | block header(3) | data | ... | checksum? | 18 : +--------+ +-------------------------+ +-----------+ 19 : `last` marks the final block 20 : 21 : skippable frame: 22 : +----------+-----------------+---------+ 23 : | magic(4) | payload size(4) | payload | 24 : +----------+-----------------+---------+ 25 : 26 : This scanner accepts fragmented input, keeps only partial headers, 27 : skips payload bytes without decompressing them, and returns END at 28 : the exact frame boundary. */ 29 : 30 : #include "../../../util/fd_util_base.h" 31 : 32 1974 : #define FD_ZSTD_FRAME_MORE (0) /* Frame end not reached */ 33 1323 : #define FD_ZSTD_FRAME_END (1) /* Frame end reached */ 34 30 : #define FD_ZSTD_FRAME_ERR (-1) /* Frame is invalid */ 35 : 36 : #define FD_ZSTD_FRAME_HEADER_MAX (18UL) 37 1293 : #define FD_ZSTD_FRAME_BLOCK_HEADER_SZ (3UL) 38 : 39 : struct fd_zstd_frame { 40 : uchar header [ FD_ZSTD_FRAME_HEADER_MAX ]; 41 : uchar block_header[ FD_ZSTD_FRAME_BLOCK_HEADER_SZ ]; 42 : ulong bytes_remaining; 43 : uint block_sz_max; 44 : uchar header_sz; 45 : uchar block_header_sz; 46 : uchar state; 47 : uchar checksum_sz; 48 : uchar last_block; 49 : }; 50 : 51 : typedef struct fd_zstd_frame fd_zstd_frame_t; 52 : 53 : FD_PROTOTYPES_BEGIN 54 : 55 : static inline fd_zstd_frame_t * 56 26133 : fd_zstd_frame_new( fd_zstd_frame_t * frame ) { 57 26133 : if( FD_UNLIKELY( !frame ) ) return NULL; 58 26133 : fd_memset( frame, 0, sizeof(fd_zstd_frame_t) ); 59 26133 : return frame; 60 26133 : } 61 : 62 : /* fd_zstd_frame_advance assumes frame, data, and consumed are non-NULL. 63 : It scans up to data_sz bytes and writes the number used to *consumed. 64 : It returns MORE if more input is needed, END at the frame boundary, 65 : or ERR for invalid framing. */ 66 : 67 : int 68 : fd_zstd_frame_advance( fd_zstd_frame_t * frame, 69 : void const * data, 70 : ulong data_sz, 71 : ulong * consumed ); 72 : 73 : FD_PROTOTYPES_END 74 : 75 : #endif /* HEADER_fd_src_discof_restore_utils_fd_zstd_frame_h */