LCOV - code coverage report
Current view: top level - common/stream - xz_stream.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 50 93 53.8 %
Date: 2024-10-04 20:04:04 Functions: 8 14 57.1 %

          Line data    Source code
       1             : /*
       2             :  * SPDX-License-Identifier: MPL-2.0
       3             :  *
       4             :  * This Source Code Form is subject to the terms of the Mozilla Public
       5             :  * License, v. 2.0.  If a copy of the MPL was not distributed with this
       6             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       7             :  *
       8             :  * Copyright 2024 MonetDB Foundation;
       9             :  * Copyright August 2008 - 2023 MonetDB B.V.;
      10             :  * Copyright 1997 - July 2008 CWI.
      11             :  */
      12             : 
      13             : /* streams working on a lzma/xz-compressed disk file */
      14             : 
      15             : #include "monetdb_config.h"
      16             : #include "stream.h"
      17             : #include "stream_internal.h"
      18             : #include "pump.h"
      19             : 
      20             : 
      21             : #ifdef HAVE_LIBLZMA
      22             : 
      23             : struct inner_state {
      24             :         lzma_stream strm;
      25             :         uint8_t buf[64*1024];
      26             :         lzma_ret error_code;
      27             : };
      28             : 
      29             : static pump_buffer
      30        2690 : xz_get_src_win(inner_state_t *xz)
      31             : {
      32        2690 :         return (pump_buffer) {
      33        2690 :                 .start = (char*) xz->strm.next_in,
      34        2690 :                 .count = xz->strm.avail_in,
      35             :         };
      36             : }
      37             : 
      38             : static void
      39         726 : xz_set_src_win(inner_state_t *xz, pump_buffer buf)
      40             : {
      41         726 :         xz->strm.next_in = (const uint8_t*)buf.start;
      42         726 :         xz->strm.avail_in = buf.count;
      43         726 : }
      44             : 
      45             : static pump_buffer
      46        1460 : xz_get_dst_win(inner_state_t *xz)
      47             : {
      48        1460 :         return (pump_buffer) {
      49        1460 :                 .start = (char*) xz->strm.next_out,
      50        1460 :                 .count = xz->strm.avail_out,
      51             :         };
      52             : }
      53             : 
      54             : static void
      55         214 : xz_set_dst_win(inner_state_t *xz, pump_buffer buf)
      56             : {
      57         214 :         xz->strm.next_out = (uint8_t*)buf.start;
      58         214 :         xz->strm.avail_out = buf.count;
      59         214 : }
      60             : 
      61             : static pump_buffer
      62         728 : xz_get_buffer(inner_state_t *xz)
      63             : {
      64         728 :         return (pump_buffer) {
      65         728 :                 .start = (char*)xz->buf,
      66             :                 .count = sizeof(xz->buf),
      67             :         };
      68             : }
      69             : 
      70             : static pump_result
      71         728 : xz_work(inner_state_t *xz, pump_action action)
      72             : {
      73         728 :         lzma_action a;
      74         728 :         switch (action) {
      75             :         case PUMP_NO_FLUSH:
      76             :                 a = LZMA_RUN;
      77             :                 break;
      78             :         case PUMP_FLUSH_DATA:
      79             :                 a = LZMA_SYNC_FLUSH;
      80             :                 break;
      81             :         case PUMP_FLUSH_ALL:
      82             :                 a = LZMA_FULL_FLUSH;
      83             :                 break;
      84             :         case PUMP_FINISH:
      85             :                 a = LZMA_FINISH;
      86             :                 break;
      87             :         default:
      88           0 :                 assert(0 /* unknown action */);
      89             :                 return PUMP_ERROR;
      90             :         }
      91             : 
      92         728 :         lzma_ret ret = lzma_code(&xz->strm, a);
      93         728 :         xz->error_code = ret;
      94             : 
      95         728 :         switch (ret) {
      96             :                 case LZMA_OK:
      97             :                         return PUMP_OK;
      98         211 :                 case LZMA_STREAM_END:
      99         211 :                         return PUMP_END;
     100           0 :                 default:
     101           0 :                         return PUMP_ERROR;
     102             :         }
     103             : }
     104             : 
     105             : static void
     106           2 : xz_finalizer(inner_state_t *xz)
     107             : {
     108           2 :         lzma_end(&xz->strm);
     109           2 :         free(xz);
     110           2 : }
     111             : 
     112             : static const char *
     113           0 : xz_get_error(inner_state_t *xz)
     114             : {
     115           0 :         static const char *msgs[] = {
     116             :                 "LZMA_OK",
     117             :                 "LZMA_STREAM_END",
     118             :                 "LZMA_NO_CHECK",
     119             :                 "LZMA_UNSUPPORTED_CHECK",
     120             :                 "LZMA_GET_CHECK",
     121             :                 "LZMA_MEM_ERROR",
     122             :                 "LZMA_MEMLIMIT_ERROR",
     123             :                 "LZMA_FORMAT_ERROR",
     124             :                 "LZMA_OPTIONS_ERROR",
     125             :                 "LZMA_DATA_ERROR",
     126             :                 "LZMA_BUF_ERROR",
     127             :                 "LZMA_PROG_ERROR"
     128             :         };
     129             : 
     130           0 :         if (xz->error_code <= LZMA_PROG_ERROR)
     131           0 :                 return msgs[xz->error_code];
     132             :         else
     133             :                 return "unknown LZMA error code";
     134             : }
     135             : 
     136             : 
     137             : 
     138             : 
     139             : stream *
     140           2 : xz_stream(stream *inner, int preset)
     141             : {
     142           2 :         inner_state_t *xz = calloc(1, sizeof(inner_state_t));
     143           2 :         pump_state *state = calloc(1, sizeof(pump_state));
     144           2 :         if (xz == NULL || state == NULL) {
     145           0 :                 free(xz);
     146           0 :                 free(state);
     147           0 :                 mnstr_set_open_error(inner->name, errno, "couldn't initialize xz stream");
     148           0 :                 return NULL;
     149             :         }
     150             : 
     151           2 :         state->inner_state = xz;
     152           2 :         state->get_src_win = xz_get_src_win;
     153           2 :         state->set_src_win = xz_set_src_win;
     154           2 :         state->get_dst_win = xz_get_dst_win;
     155           2 :         state->set_dst_win = xz_set_dst_win;
     156           2 :         state->get_buffer = xz_get_buffer;
     157           2 :         state->worker = xz_work;
     158           2 :         state->finalizer = xz_finalizer;
     159           2 :         state->get_error = xz_get_error;
     160             : 
     161           2 :         lzma_ret ret;
     162           2 :         if (inner->readonly) {
     163           1 :                 ret = lzma_stream_decoder(&xz->strm, UINT64_MAX, LZMA_CONCATENATED);
     164             :         } else {
     165           1 :                 ret = lzma_easy_encoder(&xz->strm, preset, LZMA_CHECK_CRC64);
     166             :         }
     167             : 
     168           2 :         stream *s;
     169             : 
     170           2 :         if (ret != LZMA_OK || (s = pump_stream(inner, state)) == NULL) {
     171           0 :                 lzma_end(&xz->strm);
     172           0 :                 free(xz);
     173           0 :                 free(state);
     174           0 :                 return NULL;
     175             :         }
     176             : 
     177             :         return s;
     178             : }
     179             : 
     180             : static stream *
     181           0 : open_xzstream(const char *restrict filename, const char *restrict flags)
     182             : {
     183           0 :         stream *inner;
     184           0 :         int preset = 0;
     185             : 
     186           0 :         inner = open_stream(filename, flags);
     187           0 :         if (inner == NULL)
     188             :                 return NULL;
     189             : 
     190           0 :         return xz_stream(inner, preset);
     191             : }
     192             : 
     193             : stream *
     194           0 : open_xzrstream(const char *filename)
     195             : {
     196           0 :         stream *s = open_xzstream(filename, "rb");
     197           0 :         if (s == NULL)
     198             :                 return NULL;
     199             : 
     200           0 :         assert(s->readonly == true);
     201           0 :         assert(s->binary == true);
     202             :         return s;
     203             : }
     204             : 
     205             : stream *
     206           0 : open_xzwstream(const char *restrict filename, const char *restrict mode)
     207             : {
     208           0 :         stream *s = open_xzstream(filename, mode);
     209           0 :         if (s == NULL)
     210             :                 return NULL;
     211             : 
     212           0 :         assert(s->readonly == false);
     213           0 :         assert(s->binary == true);
     214             :         return s;
     215             : }
     216             : 
     217             : stream *
     218           0 : open_xzrastream(const char *filename)
     219             : {
     220           0 :         stream *s = open_xzstream(filename, "r");
     221           0 :         s = create_text_stream(s);
     222           0 :         if (s == NULL)
     223             :                 return NULL;
     224             : 
     225           0 :         assert(s->readonly == true);
     226           0 :         assert(s->binary == false);
     227             :         return s;
     228             : }
     229             : 
     230             : stream *
     231           0 : open_xzwastream(const char *restrict filename, const char *restrict mode)
     232             : {
     233           0 :         stream *s = open_xzstream(filename, mode);
     234           0 :         s = create_text_stream(s);
     235           0 :         if (s == NULL)
     236             :                 return NULL;
     237           0 :         assert(s->readonly == false);
     238           0 :         assert(s->binary == false);
     239             :         return s;
     240             : }
     241             : #else
     242             : 
     243             : stream *
     244             : xz_stream(stream *inner, int preset)
     245             : {
     246             :         (void) inner;
     247             :         (void) preset;
     248             :         mnstr_set_open_error(inner->name, 0, "XZ/LZMA support has been left out of this MonetDB");
     249             :         return NULL;
     250             : }
     251             : stream *
     252             : open_xzrstream(const char *filename)
     253             : {
     254             :         mnstr_set_open_error(filename, 0, "XZ/LZMA support has been left out of this MonetDB");
     255             :         return NULL;
     256             : }
     257             : 
     258             : stream *
     259             : open_xzwstream(const char *restrict filename, const char *restrict mode)
     260             : {
     261             :         (void) mode;
     262             :         mnstr_set_open_error(filename, 0, "XZ/LZMA support has been left out of this MonetDB");
     263             :         return NULL;
     264             : }
     265             : 
     266             : stream *
     267             : open_xzrastream(const char *filename)
     268             : {
     269             :         mnstr_set_open_error(filename, 0, "XZ/LZMA support has been left out of this MonetDB");
     270             :         return NULL;
     271             : }
     272             : 
     273             : stream *
     274             : open_xzwastream(const char *restrict filename, const char *restrict mode)
     275             : {
     276             :         (void) mode;
     277             :         mnstr_set_open_error(filename, 0, "XZ/LZMA support has been left out of this MonetDB");
     278             :         return NULL;
     279             : }
     280             : 
     281             : #endif

Generated by: LCOV version 1.14