LCOV - code coverage report
Current view: top level - ballet/zstd - fd_zstd.c (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 69 83 83.1 %
Date: 2024-11-13 11:58:15 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             :   /* No need to inform libzstd */
      74             : 
      75           3 :   FD_COMPILER_MFENCE();
      76           3 :   dstream->magic  = 0UL;
      77           3 :   dstream->mem_sz = 0UL;
      78           3 :   FD_COMPILER_MFENCE();
      79             : 
      80           3 :   return (void *)dstream;
      81           3 : }
      82             : 
      83             : void
      84           3 : fd_zstd_dstream_reset( fd_zstd_dstream_t * dstream ) {
      85           3 :   ZSTD_DCtx_reset( fd_zstd_dstream_ctx( dstream ), ZSTD_reset_session_only );
      86           3 : }
      87             : 
      88             : int
      89             : fd_zstd_dstream_read( fd_zstd_dstream_t *     dstream,
      90             :                       uchar const ** restrict in_p,
      91             :                       uchar const *           in_end,
      92             :                       uchar ** restrict       out_p,
      93             :                       uchar *                 out_end,
      94         228 :                       ulong *                 opt_errcode ) {
      95             : 
      96         228 :   ulong _opt_errcode[1];
      97         228 :   opt_errcode = opt_errcode ? opt_errcode : _opt_errcode;
      98             : 
      99         228 :   uchar const * in_start  = *in_p;
     100         228 :   uchar *       out_start = *out_p;
     101             : 
     102         228 :   if( FD_UNLIKELY( ( in_start  > in_end  ) |
     103         228 :                    ( out_start > out_end ) ) )
     104           0 :     return EINVAL;
     105             : 
     106         228 :   ZSTD_inBuffer in_buf =
     107         228 :     { .src  = in_start,
     108         228 :       .size = (ulong)in_end - (ulong)in_start,
     109         228 :       .pos  = 0UL };
     110         228 :   ZSTD_outBuffer out_buf =
     111         228 :     { .dst  = out_start,
     112         228 :       .size = (ulong)out_end - (ulong)out_start,
     113         228 :       .pos  = 0UL };
     114             : 
     115         228 :   ZSTD_DCtx * ctx = fd_zstd_dstream_ctx( dstream );
     116         228 :   ulong const rc = ZSTD_decompressStream( ctx, &out_buf, &in_buf );
     117         228 :   if( FD_UNLIKELY( ZSTD_isError( rc ) ) ) {
     118           0 :     FD_LOG_WARNING(( "err: %s", ZSTD_getErrorName( rc ) ));
     119           0 :     *opt_errcode = rc;
     120           0 :     return EPROTO;
     121           0 :   }
     122             : 
     123         228 :   if( FD_UNLIKELY( (in_buf.size ) & (!in_buf.pos ) &
     124         228 :                    (out_buf.size) & (!out_buf.pos) ) ) {
     125             :     /* should not happen */
     126           0 :     FD_LOG_WARNING(( "libzstd returned success but failed to do any progress" ));
     127           0 :     *opt_errcode = 0UL;
     128           0 :     return EPIPE;
     129           0 :   }
     130             : 
     131         228 :   *in_p  = (void const *)((ulong)in_start  + in_buf.pos );
     132         228 :   *out_p = (void *      )((ulong)out_start + out_buf.pos);
     133         228 :   return rc==0UL ? -1 /* frame complete */ : 0 /* still working */;
     134         228 : }

Generated by: LCOV version 1.14