source: libwandio/iow-lzma.c @ 3b6e0cf

4.0.1-hotfixescachetimestampsdevelopdpdk-ndagetsilivelibtrace4ndag_formatpfringrc-4.0.1rc-4.0.2rc-4.0.3rc-4.0.4ringdecrementfixringperformanceringtimestampfixes
Last change on this file since 3b6e0cf was 0e46fbc, checked in by Perry Lorier <git@…>, 7 years ago

Add read/write support for xz (lzma) files.

  • 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 <lzma.h>
35#include "wandio.h"
36#include <sys/types.h>
37#include <sys/stat.h>
38#include <fcntl.h>
39#include <stdlib.h>
40#include <string.h>
41#include <assert.h>
42
43/* Libtrace IO module implementing an lzma writer */
44
45enum err_t {
46        ERR_OK  = 1,
47        ERR_EOF = 0,
48        ERR_ERROR = -1
49};
50
51struct lzmaw_t {
52        lzma_stream strm;
53        uint8_t outbuff[1024*1024];
54        iow_t *child;
55        enum err_t err;
56        int inoffset;
57};
58
59
60extern iow_source_t lzma_wsource;
61
62#define DATA(iow) ((struct lzmaw_t *)((iow)->data))
63#define min(a,b) ((a)<(b) ? (a) : (b))
64
65iow_t *lzma_wopen(iow_t *child, int compress_level)
66{
67        iow_t *iow;
68        if (!child)
69                return NULL;
70        iow = malloc(sizeof(iow_t));
71        iow->source = &lzma_wsource;
72        iow->data = malloc(sizeof(struct lzmaw_t));
73
74        DATA(iow)->child = child;
75
76        memset(&DATA(iow)->strm, 0, sizeof(DATA(iow)->strm));
77        DATA(iow)->strm.next_out = DATA(iow)->outbuff;
78        DATA(iow)->strm.avail_out = sizeof(DATA(iow)->outbuff);
79        DATA(iow)->err = ERR_OK;
80
81        if (lzma_easy_encoder(&DATA(iow)->strm,
82                    compress_level,
83                    LZMA_CHECK_CRC64) != LZMA_OK) {
84            free(iow->data);
85            free(iow);
86            return NULL;
87        }
88
89        return iow;
90}
91
92
93static off_t lzma_wwrite(iow_t *iow, const char *buffer, off_t len)
94{
95        if (DATA(iow)->err == ERR_EOF) {
96                return 0; /* EOF */
97        }
98        if (DATA(iow)->err == ERR_ERROR) {
99                return -1; /* ERROR! */
100        }
101
102        DATA(iow)->strm.next_in = (const uint8_t*)buffer;
103        DATA(iow)->strm.avail_in = len;
104
105        while (DATA(iow)->err == ERR_OK && DATA(iow)->strm.avail_in > 0) {
106                /* Flush output data. */
107                while (DATA(iow)->strm.avail_out <= 0) {
108                        int bytes_written = wandio_wwrite(DATA(iow)->child,
109                                DATA(iow)->outbuff,
110                                sizeof(DATA(iow)->outbuff));
111                        if (bytes_written <= 0) { /* Error */
112                                DATA(iow)->err = ERR_ERROR;
113                                /* Return how much data we managed to write */
114                                if (DATA(iow)->strm.avail_in != (uint32_t)len) {
115                                        return len-DATA(iow)->strm.avail_in;
116                                }
117                                /* Now return error */
118                                return -1;
119                        }
120                        DATA(iow)->strm.next_out = DATA(iow)->outbuff;
121                        DATA(iow)->strm.avail_out = sizeof(DATA(iow)->outbuff);
122                }
123                /* Decompress some data into the output buffer */
124                lzma_ret err=lzma_code(&DATA(iow)->strm, LZMA_RUN);
125                switch(err) {
126                        case LZMA_OK:
127                                DATA(iow)->err = ERR_OK;
128                                break;
129                        default:
130                                DATA(iow)->err = ERR_ERROR;
131                }
132        }
133        /* Return the number of bytes decompressed */
134        return len-DATA(iow)->strm.avail_in;
135}
136
137static void lzma_wclose(iow_t *iow)
138{
139        lzma_ret res;
140        while (1) {
141                res = lzma_code(&DATA(iow)->strm, LZMA_FINISH);
142
143                if (res == LZMA_STREAM_END)
144                        break;
145                if (res != LZMA_OK) {
146                        fprintf(stderr, "Z_STREAM_ERROR while closing output\n");
147                        break;
148                }
149
150                wandio_wwrite(DATA(iow)->child,
151                                (char*)DATA(iow)->outbuff,
152                                sizeof(DATA(iow)->outbuff)-DATA(iow)->strm.avail_out);
153                DATA(iow)->strm.next_out = DATA(iow)->outbuff;
154                DATA(iow)->strm.avail_out = sizeof(DATA(iow)->outbuff);
155        }
156
157        wandio_wwrite(DATA(iow)->child,
158                        (char *)DATA(iow)->outbuff,
159                        sizeof(DATA(iow)->outbuff)-DATA(iow)->strm.avail_out);
160        lzma_end(&DATA(iow)->strm);
161        wandio_wdestroy(DATA(iow)->child);
162        free(iow->data);
163        free(iow);
164}
165
166iow_source_t lzma_wsource = {
167        "xz",
168        lzma_wwrite,
169        lzma_wclose
170};
171
Note: See TracBrowser for help on using the repository browser.