LCOV - code coverage report
Current view: top level - common/stream - xz_stream.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 47 87 54.0 %
Date: 2021-10-27 03:06:47 Functions: 8 14 57.1 %

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

Generated by: LCOV version 1.14