Tor 0.4.9.0-alpha-dev
compress_buf.c
Go to the documentation of this file.
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
14#include "lib/buf/buffers.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. */
30int
32 const char *data, size_t data_len,
33 const int done)
34{
35 char *next;
36 size_t old_avail, avail;
37 int over = 0;
38
39 do {
40 int need_new_chunk = 0;
41 if (!buf->tail || ! CHUNK_REMAINING_CAPACITY(buf->tail)) {
42 size_t cap = data_len / 4;
43 buf_add_chunk_with_capacity(buf, cap, 1);
44 }
45 next = CHUNK_WRITE_PTR(buf->tail);
46 avail = old_avail = CHUNK_REMAINING_CAPACITY(buf->tail);
47 switch (tor_compress_process(state, &next, &avail,
48 &data, &data_len, done)) {
49 case TOR_COMPRESS_DONE:
50 over = 1;
51 break;
52 case TOR_COMPRESS_ERROR:
53 return -1;
54 case TOR_COMPRESS_OK:
55 if (data_len == 0) {
56 tor_assert_nonfatal(!done);
57 over = 1;
58 }
59 break;
60 case TOR_COMPRESS_BUFFER_FULL:
61 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 need_new_chunk = 1;
66 }
67 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 over = 1;
71 }
72 break;
73 }
74 buf->datalen += old_avail - avail;
75 buf->tail->datalen += old_avail - avail;
76 if (need_new_chunk) {
77 buf_add_chunk_with_capacity(buf, data_len/4, 1);
78 }
79
80 } while (!over);
81 check();
82 return 0;
83}
chunk_t * buf_add_chunk_with_capacity(buf_t *buf, size_t capacity, int capped)
Definition: buffers.c:475
Header file for buffers.c.
Utility macros to handle different features and behavior in different compilers.
tor_compress_output_t tor_compress_process(tor_compress_state_t *state, char **out, size_t *out_len, const char **in, size_t *in_len, int finish)
Definition: compress.c:557
Headers for compress.c.
int buf_add_compress(buf_t *buf, tor_compress_state_t *state, const char *data, size_t data_len, const int done)
Definition: compress_buf.c:31
Macros to manage assertions, fatal and non-fatal.