LCOV - code coverage report
Current view: top level - ballet/zstd - fd_zstd.c (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 70 85 82.4 %
Date: 2025-01-08 12:08:44 Functions: 8 8 100.0 %

          Line data    Source code
       1             : #include "fd_zstd.h"
       2             : #include "fd_zstd_private.h"
       3             : #include "../../util/fd_util.h"
       4             : 
       5             : #if !FD_HAS_ZSTD
       6             : #error "fd_zstd requires libzstd"
       7             : #endif
       8             : 
       9             : #define ZSTD_STATIC_LINKING_ONLY
      10             : #include <zstd.h>
      11             : #include <errno.h>
      12             : 
      13             : fd_zstd_peek_t *
      14             : fd_zstd_peek( fd_zstd_peek_t * peek,
      15             :               void const *     buf,
      16          57 :               ulong            bufsz ) {
      17          57 :   ZSTD_frameHeader hdr[1];
      18          57 :   ulong const err = ZSTD_getFrameHeader( hdr, buf, bufsz );
      19          57 :   if( FD_UNLIKELY( ZSTD_isError( err ) ) ) return NULL;
      20          57 :   if( FD_UNLIKELY( err>0               ) ) return NULL;
      21          36 :   fd_msan_unpoison( hdr, sizeof(ZSTD_frameHeader) );
      22          36 :   if( FD_UNLIKELY( hdr->windowSize > (1U<<ZSTD_WINDOWLOG_MAX) ) ) return NULL;
      23          36 :   peek->window_sz          = hdr->windowSize;
      24          36 :   peek->frame_content_sz   = hdr->frameContentSize;
      25          36 :   peek->frame_is_skippable = hdr->frameType == ZSTD_skippableFrame;
      26          36 :   return peek;
      27          36 : }
      28             : 
      29             : ulong
      30           3 : fd_zstd_dstream_align( void ) {
      31           3 :   return FD_ZSTD_DSTREAM_ALIGN;
      32           3 : }
      33             : 
      34             : ulong
      35           3 : fd_zstd_dstream_footprint( ulong max_window_sz ) {
      36           3 :   return offsetof(fd_zstd_dstream_t, mem) + ZSTD_estimateDStreamSize( max_window_sz );
      37           3 : }
      38             : 
      39             : fd_zstd_dstream_t *
      40             : fd_zstd_dstream_new( void * mem,
      41           3 :                      ulong  max_window_sz ) {
      42           3 :   fd_zstd_dstream_t * dstream = mem;
      43           3 :   dstream->mem_sz = ZSTD_estimateDStreamSize( max_window_sz );
      44             : 
      45           3 :   ZSTD_DCtx * ctx = ZSTD_initStaticDStream( dstream->mem, ZSTD_estimateDStreamSize( max_window_sz ) );
      46           3 :   if( FD_UNLIKELY( !ctx ) ) {
      47             :     /* should never happen */
      48           0 :     FD_LOG_WARNING(( "ZSTD_initStaticDStream failed (max_window_sz=%lu)", max_window_sz ));
      49           0 :     return NULL;
      50           0 :   }
      51           3 :   if( FD_UNLIKELY( (ulong)ctx != (ulong)dstream->mem ) )
      52           0 :     FD_LOG_CRIT(( "ZSTD_initStaticDStream returned unexpected pointer (ctx=%p, mem=%p)",
      53           3 :                   (void *)ctx, (void *)dstream->mem ));
      54             : 
      55           3 :   FD_COMPILER_MFENCE();
      56           3 :   dstream->magic = FD_ZSTD_DSTREAM_MAGIC;
      57           3 :   FD_COMPILER_MFENCE();
      58           3 :   return dstream;
      59           3 : }
      60             : 
      61             : static ZSTD_DCtx *
      62         231 : fd_zstd_dstream_ctx( fd_zstd_dstream_t * dstream ) {
      63         231 :   if( FD_UNLIKELY( dstream->magic != FD_ZSTD_DSTREAM_MAGIC ) )
      64           0 :     FD_LOG_CRIT(( "fd_zstd_dstream_t at %p has invalid magic (memory corruption?)", (void *)dstream ));
      65         231 :   return (ZSTD_DCtx *)fd_type_pun( dstream->mem );
      66         231 : }
      67             : 
      68             : void *
      69           3 : fd_zstd_dstream_delete( fd_zstd_dstream_t * dstream ) {
      70             : 
      71           3 :   if( FD_UNLIKELY( !dstream ) ) return NULL;
      72             : 
      73           3 :   if( FD_UNLIKELY( dstream->magic != FD_ZSTD_DSTREAM_MAGIC ) )
      74           0 :       FD_LOG_CRIT(( "fd_zstd_dstream_t at %p has invalid magic (memory corruption?)", (void *)dstream ));
      75             : 
      76             :   /* No need to inform libzstd */
      77             : 
      78           3 :   FD_COMPILER_MFENCE();
      79           3 :   dstream->magic  = 0UL;
      80           3 :   dstream->mem_sz = 0UL;
      81           3 :   FD_COMPILER_MFENCE();
      82             : 
      83           3 :   return (void *)dstream;
      84           3 : }
      85             : 
      86             : void
      87           3 : fd_zstd_dstream_reset( fd_zstd_dstream_t * dstream ) {
      88           3 :   ZSTD_DCtx_reset( fd_zstd_dstream_ctx( dstream ), ZSTD_reset_session_only );
      89           3 : }
      90             : 
      91             : int
      92             : fd_zstd_dstream_read( fd_zstd_dstream_t *     dstream,
      93             :                       uchar const ** restrict in_p,
      94             :                       uchar const *           in_end,
      95             :                       uchar ** restrict       out_p,
      96             :                       uchar *                 out_end,
      97         228 :                       ulong *                 opt_errcode ) {
      98             : 
      99         228 :   ulong _opt_errcode[1];
     100         228 :   opt_errcode = opt_errcode ? opt_errcode : _opt_errcode;
     101             : 
     102         228 :   uchar const * in_start  = *in_p;
     103         228 :   uchar *       out_start = *out_p;
     104             : 
     105         228 :   if( FD_UNLIKELY( ( in_start  > in_end  ) |
     106         228 :                    ( out_start > out_end ) ) )
     107           0 :     return EINVAL;
     108             : 
     109         228 :   ZSTD_inBuffer in_buf =
     110         228 :     { .src  = in_start,
     111         228 :       .size = (ulong)in_end - (ulong)in_start,
     112         228 :       .pos  = 0UL };
     113         228 :   ZSTD_outBuffer out_buf =
     114         228 :     { .dst  = out_start,
     115         228 :       .size = (ulong)out_end - (ulong)out_start,
     116         228 :       .pos  = 0UL };
     117             : 
     118         228 :   ZSTD_DCtx * ctx = fd_zstd_dstream_ctx( dstream );
     119         228 :   ulong const rc = ZSTD_decompressStream( ctx, &out_buf, &in_buf );
     120         228 :   if( FD_UNLIKELY( ZSTD_isError( rc ) ) ) {
     121           0 :     FD_LOG_WARNING(( "err: %s", ZSTD_getErrorName( rc ) ));
     122           0 :     *opt_errcode = rc;
     123           0 :     return EPROTO;
     124           0 :   }
     125             : 
     126         228 :   if( FD_UNLIKELY( (in_buf.size ) & (!in_buf.pos ) &
     127         228 :                    (out_buf.size) & (!out_buf.pos) ) ) {
     128             :     /* should not happen */
     129           0 :     FD_LOG_WARNING(( "libzstd returned success but failed to do any progress" ));
     130           0 :     *opt_errcode = 0UL;
     131           0 :     return EPIPE;
     132           0 :   }
     133             : 
     134         228 :   *in_p  = (void const *)((ulong)in_start  + in_buf.pos );
     135         228 :   *out_p = (void *      )((ulong)out_start + out_buf.pos);
     136         228 :   return rc==0UL ? -1 /* frame complete */ : 0 /* still working */;
     137         228 : }

Generated by: LCOV version 1.14