1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * Copyright (C) 2009 Red Hat, Inc.
4 * Copyright (C) 2009 Shaun McCance <shaunm@gnome.org>
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General
17 * Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
19 * Author: Shaun McCance <shaunm@gnome.org>
24 #include "yelp-lzma-decompressor.h"
31 #include <glib/gi18n.h>
35 static void yelp_lzma_decompressor_iface_init (GConverterIface
*iface
);
37 struct _YelpLzmaDecompressor
39 GObject parent_instance
;
41 lzma_stream lzmastream
;
44 G_DEFINE_TYPE_WITH_CODE (YelpLzmaDecompressor
, yelp_lzma_decompressor
, G_TYPE_OBJECT
,
45 G_IMPLEMENT_INTERFACE (G_TYPE_CONVERTER
,
46 yelp_lzma_decompressor_iface_init
))
49 yelp_lzma_decompressor_finalize (GObject
*object
)
51 YelpLzmaDecompressor
*decompressor
;
53 decompressor
= YELP_LZMA_DECOMPRESSOR (object
);
55 lzma_end (&decompressor
->lzmastream
);
57 G_OBJECT_CLASS (yelp_lzma_decompressor_parent_class
)->finalize (object
);
61 yelp_lzma_decompressor_init (YelpLzmaDecompressor
*decompressor
)
66 yelp_lzma_decompressor_constructed (GObject
*object
)
68 YelpLzmaDecompressor
*decompressor
;
69 lzma_stream tmp
= LZMA_STREAM_INIT
;
72 decompressor
= YELP_LZMA_DECOMPRESSOR (object
);
74 decompressor
->lzmastream
= tmp
;
75 res
= lzma_auto_decoder (&decompressor
->lzmastream
, SIZE_MAX
, 0);
77 if (res
== LZMA_MEM_ERROR
)
78 g_error ("YelpLzmaDecompressor: Not enough memory for lzma use");
80 if (res
== LZMA_OPTIONS_ERROR
)
81 g_error ("YelpLzmaDecompressor: Unsupported flags");
84 g_error ("YelpLzmaDecompressor: Unexpected lzma error");
88 yelp_lzma_decompressor_class_init (YelpLzmaDecompressorClass
*klass
)
90 GObjectClass
*gobject_class
= G_OBJECT_CLASS (klass
);
92 gobject_class
->finalize
= yelp_lzma_decompressor_finalize
;
93 gobject_class
->constructed
= yelp_lzma_decompressor_constructed
;
96 YelpLzmaDecompressor
*
97 yelp_lzma_decompressor_new (void)
99 YelpLzmaDecompressor
*decompressor
;
101 decompressor
= g_object_new (YELP_TYPE_LZMA_DECOMPRESSOR
, NULL
);
107 yelp_lzma_decompressor_reset (GConverter
*converter
)
109 YelpLzmaDecompressor
*decompressor
= YELP_LZMA_DECOMPRESSOR (converter
);
112 /* lzma doesn't have a reset function. Ending and reiniting
113 * might do the trick. But this is untested. If reset matters
116 lzma_end (&decompressor
->lzmastream
);
117 res
= lzma_code (&decompressor
->lzmastream
, LZMA_RUN
);
119 if (res
== LZMA_MEM_ERROR
)
120 g_error ("YelpLzmaDecompressor: Not enough memory for lzma use");
123 g_error ("YelpLzmaDecompressor: Unexpected lzma error");
126 static GConverterResult
127 yelp_lzma_decompressor_convert (GConverter
*converter
,
132 GConverterFlags flags
,
134 gsize
*bytes_written
,
137 YelpLzmaDecompressor
*decompressor
;
140 decompressor
= YELP_LZMA_DECOMPRESSOR (converter
);
142 decompressor
->lzmastream
.next_in
= (void *)inbuf
;
143 decompressor
->lzmastream
.avail_in
= inbuf_size
;
145 decompressor
->lzmastream
.next_out
= outbuf
;
146 decompressor
->lzmastream
.avail_out
= outbuf_size
;
148 res
= lzma_code (&decompressor
->lzmastream
, LZMA_RUN
);
150 if (res
== LZMA_DATA_ERROR
) {
151 g_set_error_literal (error
, G_IO_ERROR
, G_IO_ERROR_INVALID_DATA
,
152 _("Invalid compressed data"));
153 return G_CONVERTER_ERROR
;
156 if (res
== LZMA_MEM_ERROR
) {
157 g_set_error_literal (error
, G_IO_ERROR
, G_IO_ERROR_FAILED
,
158 _("Not enough memory"));
159 return G_CONVERTER_ERROR
;
162 if (res
== LZMA_OK
|| res
== LZMA_STREAM_END
) {
163 *bytes_read
= inbuf_size
- decompressor
->lzmastream
.avail_in
;
164 *bytes_written
= outbuf_size
- decompressor
->lzmastream
.avail_out
;
166 if (res
== LZMA_STREAM_END
)
167 return G_CONVERTER_FINISHED
;
168 return G_CONVERTER_CONVERTED
;
171 g_assert_not_reached ();
175 yelp_lzma_decompressor_iface_init (GConverterIface
*iface
)
177 iface
->convert
= yelp_lzma_decompressor_convert
;
178 iface
->reset
= yelp_lzma_decompressor_reset
;