LCOV - code coverage report
Current view: top level - lib/compress - compress_buf.c (source / functions) Hit Total Coverage
Test: lcov.info Lines: 26 28 92.9 %
Date: 2021-11-24 03:28:48 Functions: 1 1 100.0 %

          Line data    Source code
       1             : /* Copyright (c) 2003, Roger Dingledine
       2             :  * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
       3             :  * Copyright (c) 2007-2021, The Tor Project, Inc. */
       4             : /* See LICENSE for licensing information */
       5             : 
       6             : /**
       7             :  * \file compress_buf.c
       8             :  *
       9             :  * \brief Working with compressed data in buffers.
      10             :  **/
      11             : 
      12             : #define BUFFERS_PRIVATE
      13             : #include "lib/cc/compat_compiler.h"
      14             : #include "lib/buf/buffers.h"
      15             : #include "lib/compress/compress.h"
      16             : #include "lib/log/util_bug.h"
      17             : 
      18             : #ifdef PARANOIA
      19             : /** Helper: If PARANOIA is defined, assert that the buffer in local variable
      20             :  * <b>buf</b> is well-formed. */
      21             : #define check() STMT_BEGIN buf_assert_ok(buf); STMT_END
      22             : #else
      23             : #define check() STMT_NIL
      24             : #endif /* defined(PARANOIA) */
      25             : 
      26             : /** Compress or uncompress the <b>data_len</b> bytes in <b>data</b> using the
      27             :  * compression state <b>state</b>, appending the result to <b>buf</b>.  If
      28             :  * <b>done</b> is true, flush the data in the state and finish the
      29             :  * compression/uncompression.  Return -1 on failure, 0 on success. */
      30             : int
      31         200 : buf_add_compress(buf_t *buf, tor_compress_state_t *state,
      32             :                  const char *data, size_t data_len,
      33             :                  const int done)
      34             : {
      35         200 :   char *next;
      36         200 :   size_t old_avail, avail;
      37         200 :   int over = 0;
      38             : 
      39         280 :   do {
      40         280 :     int need_new_chunk = 0;
      41         280 :     if (!buf->tail || ! CHUNK_REMAINING_CAPACITY(buf->tail)) {
      42         136 :       size_t cap = data_len / 4;
      43         136 :       buf_add_chunk_with_capacity(buf, cap, 1);
      44             :     }
      45         280 :     next = CHUNK_WRITE_PTR(buf->tail);
      46         280 :     avail = old_avail = CHUNK_REMAINING_CAPACITY(buf->tail);
      47         280 :     switch (tor_compress_process(state, &next, &avail,
      48             :                                  &data, &data_len, done)) {
      49          60 :       case TOR_COMPRESS_DONE:
      50          60 :         over = 1;
      51          60 :         break;
      52             :       case TOR_COMPRESS_ERROR:
      53             :         return -1;
      54         124 :       case TOR_COMPRESS_OK:
      55         124 :         if (data_len == 0) {
      56         124 :           tor_assert_nonfatal(!done);
      57             :           over = 1;
      58             :         }
      59             :         break;
      60          96 :       case TOR_COMPRESS_BUFFER_FULL:
      61          96 :         if (avail) {
      62             :           /* The compression module says we need more room
      63             :            * (TOR_COMPRESS_BUFFER_FULL).  Start a new chunk automatically,
      64             :            * whether were going to or not. */
      65           0 :           need_new_chunk = 1;
      66             :         }
      67          96 :         if (data_len == 0 && !done) {
      68             :           /* We've consumed all the input data, though, so there's no
      69             :            * point in forging ahead right now. */
      70          16 :           over = 1;
      71             :         }
      72             :         break;
      73             :     }
      74         280 :     buf->datalen += old_avail - avail;
      75         280 :     buf->tail->datalen += old_avail - avail;
      76         280 :     if (need_new_chunk) {
      77           0 :       buf_add_chunk_with_capacity(buf, data_len/4, 1);
      78             :     }
      79             : 
      80         280 :   } while (!over);
      81             :   check();
      82             :   return 0;
      83             : }

Generated by: LCOV version 1.14