source: libwandio/iow-lzma.c @ e4eff86

4.0.1-hotfixescachetimestampsdevelopdpdk-ndagetsilivelibtrace4ndag_formatpfringrc-4.0.1rc-4.0.2rc-4.0.3rc-4.0.4ringdecrementfixringperformanceringtimestampfixes
Last change on this file since e4eff86 was e4eff86, checked in by Shane Alcock <salcock@…>, 5 years ago

Ensure all libwandio code includes config.h

This fixes a nasty bug on 32 bit machines where the size of off_t will
change between functions, causing all sorts of havoc. The reason the size
changes is because FILE_OFFSET_BITS is defined to 64 inside config.h so
any source files that include config.h will have 64 bit off_t's whereas
any files that don't include it will end up with a 32 bit off_t (on a 32 bit
machine).

  • Property mode set to 100644
File size: 4.2 KB
Line 
1/*
2 * This file is part of libtrace
3 *
4 * Copyright (c) 2014 The University of Waikato, Hamilton,
5 * New Zealand.
6 *
7 * Authors: Perry Lorier
8 *          Shane Alcock
9 *
10 * All rights reserved.
11 *
12 * This code has been developed by the University of Waikato WAND
13 * research group. For further information please see http://www.wand.net.nz/
14 *
15 * libtrace is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
19 *
20 * libtrace is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with libtrace; if not, write to the Free Software
27 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
28 *
29 * $Id$
30 *
31 */
32
33
34#include "config.h"
35#include <lzma.h>
36#include "wandio.h"
37#include <sys/types.h>
38#include <sys/stat.h>
39#include <fcntl.h>
40#include <stdlib.h>
41#include <string.h>
42#include <assert.h>
43
44/* Libtrace IO module implementing an lzma writer */
45
46enum err_t {
47        ERR_OK  = 1,
48        ERR_EOF = 0,
49        ERR_ERROR = -1
50};
51
52struct lzmaw_t {
53        lzma_stream strm;
54        uint8_t outbuff[1024*1024];
55        iow_t *child;
56        enum err_t err;
57        int inoffset;
58};
59
60
61extern iow_source_t lzma_wsource;
62
63#define DATA(iow) ((struct lzmaw_t *)((iow)->data))
64#define min(a,b) ((a)<(b) ? (a) : (b))
65
66iow_t *lzma_wopen(iow_t *child, int compress_level)
67{
68        iow_t *iow;
69        if (!child)
70                return NULL;
71        iow = malloc(sizeof(iow_t));
72        iow->source = &lzma_wsource;
73        iow->data = malloc(sizeof(struct lzmaw_t));
74
75        DATA(iow)->child = child;
76
77        memset(&DATA(iow)->strm, 0, sizeof(DATA(iow)->strm));
78        DATA(iow)->strm.next_out = DATA(iow)->outbuff;
79        DATA(iow)->strm.avail_out = sizeof(DATA(iow)->outbuff);
80        DATA(iow)->err = ERR_OK;
81
82        if (lzma_easy_encoder(&DATA(iow)->strm,
83                    compress_level,
84                    LZMA_CHECK_CRC64) != LZMA_OK) {
85            free(iow->data);
86            free(iow);
87            return NULL;
88        }
89
90        return iow;
91}
92
93
94static off_t lzma_wwrite(iow_t *iow, const char *buffer, off_t len)
95{
96        if (DATA(iow)->err == ERR_EOF) {
97                return 0; /* EOF */
98        }
99        if (DATA(iow)->err == ERR_ERROR) {
100                return -1; /* ERROR! */
101        }
102
103        DATA(iow)->strm.next_in = (const uint8_t*)buffer;
104        DATA(iow)->strm.avail_in = len;
105
106        while (DATA(iow)->err == ERR_OK && DATA(iow)->strm.avail_in > 0) {
107                /* Flush output data. */
108                while (DATA(iow)->strm.avail_out <= 0) {
109                        int bytes_written = wandio_wwrite(DATA(iow)->child,
110                                DATA(iow)->outbuff,
111                                sizeof(DATA(iow)->outbuff));
112                        if (bytes_written <= 0) { /* Error */
113                                DATA(iow)->err = ERR_ERROR;
114                                /* Return how much data we managed to write */
115                                if (DATA(iow)->strm.avail_in != (uint32_t)len) {
116                                        return len-DATA(iow)->strm.avail_in;
117                                }
118                                /* Now return error */
119                                return -1;
120                        }
121                        DATA(iow)->strm.next_out = DATA(iow)->outbuff;
122                        DATA(iow)->strm.avail_out = sizeof(DATA(iow)->outbuff);
123                }
124                /* Decompress some data into the output buffer */
125                lzma_ret err=lzma_code(&DATA(iow)->strm, LZMA_RUN);
126                switch(err) {
127                        case LZMA_OK:
128                                DATA(iow)->err = ERR_OK;
129                                break;
130                        default:
131                                DATA(iow)->err = ERR_ERROR;
132                }
133        }
134        /* Return the number of bytes decompressed */
135        return len-DATA(iow)->strm.avail_in;
136}
137
138static void lzma_wclose(iow_t *iow)
139{
140        lzma_ret res;
141        while (1) {
142                res = lzma_code(&DATA(iow)->strm, LZMA_FINISH);
143
144                if (res == LZMA_STREAM_END)
145                        break;
146                if (res != LZMA_OK) {
147                        fprintf(stderr, "Z_STREAM_ERROR while closing output\n");
148                        break;
149                }
150
151                wandio_wwrite(DATA(iow)->child,
152                                (char*)DATA(iow)->outbuff,
153                                sizeof(DATA(iow)->outbuff)-DATA(iow)->strm.avail_out);
154                DATA(iow)->strm.next_out = DATA(iow)->outbuff;
155                DATA(iow)->strm.avail_out = sizeof(DATA(iow)->outbuff);
156        }
157
158        wandio_wwrite(DATA(iow)->child,
159                        (char *)DATA(iow)->outbuff,
160                        sizeof(DATA(iow)->outbuff)-DATA(iow)->strm.avail_out);
161        lzma_end(&DATA(iow)->strm);
162        wandio_wdestroy(DATA(iow)->child);
163        free(iow->data);
164        free(iow);
165}
166
167iow_source_t lzma_wsource = {
168        "xz",
169        lzma_wwrite,
170        lzma_wclose
171};
172
Note: See TracBrowser for help on using the repository browser.