Coverage Report

Created: 2025-08-26 06:55

/src/libxmlb/src/xb-zstd-decompressor.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright 2022 Richard Hughes <richard@hughsie.com>
3
 *
4
 * SPDX-License-Identifier: LGPL-2.1-or-later
5
 */
6
7
#include "config.h"
8
9
#include <gio/gio.h>
10
#include <zstd.h>
11
12
#include "xb-zstd-decompressor.h"
13
14
static void
15
xb_zstd_decompressor_iface_init(GConverterIface *iface);
16
17
struct _XbZstdDecompressor {
18
  GObject parent_instance;
19
  ZSTD_DStream *zstdstream;
20
};
21
22
G_DEFINE_TYPE_WITH_CODE(XbZstdDecompressor,
23
      xb_zstd_decompressor,
24
      G_TYPE_OBJECT,
25
      G_IMPLEMENT_INTERFACE(G_TYPE_CONVERTER, xb_zstd_decompressor_iface_init))
26
27
static void
28
xb_zstd_decompressor_finalize(GObject *object)
29
0
{
30
0
  XbZstdDecompressor *self = XB_ZSTD_DECOMPRESSOR(object);
31
0
  ZSTD_freeDStream(self->zstdstream);
32
0
  G_OBJECT_CLASS(xb_zstd_decompressor_parent_class)->finalize(object);
33
0
}
34
35
static void
36
xb_zstd_decompressor_init(XbZstdDecompressor *self)
37
0
{
38
0
}
39
40
static void
41
xb_zstd_decompressor_constructed(GObject *object)
42
0
{
43
0
  XbZstdDecompressor *self = XB_ZSTD_DECOMPRESSOR(object);
44
0
  self->zstdstream = ZSTD_createDStream();
45
0
}
46
47
static void
48
xb_zstd_decompressor_class_init(XbZstdDecompressorClass *klass)
49
0
{
50
0
  GObjectClass *object_class = G_OBJECT_CLASS(klass);
51
0
  object_class->finalize = xb_zstd_decompressor_finalize;
52
0
  object_class->constructed = xb_zstd_decompressor_constructed;
53
0
}
54
55
XbZstdDecompressor *
56
xb_zstd_decompressor_new(void)
57
0
{
58
0
  return g_object_new(XB_TYPE_ZSTD_DECOMPRESSOR, NULL);
59
0
}
60
61
static void
62
xb_zstd_decompressor_reset(GConverter *converter)
63
0
{
64
0
  XbZstdDecompressor *self = XB_ZSTD_DECOMPRESSOR(converter);
65
0
  ZSTD_initDStream(self->zstdstream);
66
0
}
67
68
static GConverterResult
69
xb_zstd_decompressor_convert(GConverter *converter,
70
           const void *inbuf,
71
           gsize inbuf_size,
72
           void *outbuf,
73
           gsize outbuf_size,
74
           GConverterFlags flags,
75
           gsize *bytes_read,
76
           gsize *bytes_written,
77
           GError **error)
78
0
{
79
0
  XbZstdDecompressor *self = XB_ZSTD_DECOMPRESSOR(converter);
80
0
  ZSTD_outBuffer output = {
81
0
      .dst = outbuf,
82
0
      .size = outbuf_size,
83
0
      .pos = 0,
84
0
  };
85
0
  ZSTD_inBuffer input = {
86
0
      .src = inbuf,
87
0
      .size = inbuf_size,
88
0
      .pos = 0,
89
0
  };
90
0
  size_t res;
91
92
0
  res = ZSTD_decompressStream(self->zstdstream, &output, &input);
93
0
  if (ZSTD_isError(res)) {
94
0
    g_set_error(error,
95
0
          G_IO_ERROR,
96
0
          G_IO_ERROR_INVALID_DATA,
97
0
          "cannot decompress data: %s",
98
0
          ZSTD_getErrorName(res));
99
0
    return G_CONVERTER_ERROR;
100
0
  }
101
0
  *bytes_read = input.pos;
102
0
  *bytes_written = output.pos;
103
104
  /* success */
105
0
  return res == 0 ? G_CONVERTER_FINISHED : G_CONVERTER_CONVERTED;
106
0
}
107
108
static void
109
xb_zstd_decompressor_iface_init(GConverterIface *iface)
110
0
{
111
0
  iface->convert = xb_zstd_decompressor_convert;
112
0
  iface->reset = xb_zstd_decompressor_reset;
113
0
}