Skip to content

Commit 0a97c9f

Browse files
elmarcobonzini
authored andcommitted
record: add set_stream() and get_stream() using GIO
Use GInputStream for record stream manipulation
1 parent 880b901 commit 0a97c9f

11 files changed

+387
-135
lines changed

TODO

-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
statement in the passed string
66
- add a SQL tool with readline
77
- add API to import from a string
8-
- add API to write a stream field to a GIO stream or back
98
- split regression tests into many smaller harnesses, possibly using
109
gtester
1110
- add tests for msiinfo

configure.ac

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ AC_PROG_CC
1616
AC_PROG_YACC
1717

1818
AM_PATH_GLIB_2_0([2.12.0])
19-
PKG_CHECK_MODULES([GOBJECT], [gobject-2.0])
19+
PKG_CHECK_MODULES([GOBJECT], [gobject-2.0 gio-2.0 >= 2.14])
2020
PKG_CHECK_MODULES([GSF], [libgsf-1])
2121
PKG_CHECK_MODULES([UUID], [uuid], [uuid=yes], [uuid=no])
2222
AS_IF([test "$uuid" = yes],

include/libmsi-record.h

+8-3
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#define _LIBMSI_RECORD_H
2121

2222
#include <glib-object.h>
23+
#include <gio/gio.h>
2324

2425
#include "libmsi-types.h"
2526

@@ -59,10 +60,14 @@ gchar * libmsi_record_get_string (const LibmsiRecord *record,
5960
gboolean libmsi_record_load_stream (LibmsiRecord *record,
6061
guint field,
6162
const gchar *filename);
62-
gboolean libmsi_record_save_stream (LibmsiRecord *rec,
63+
gboolean libmsi_record_set_stream (LibmsiRecord *record,
6364
guint field,
64-
gchar *buf,
65-
guint *sz);
65+
GInputStream *input,
66+
gsize count,
67+
GCancellable *cancellable,
68+
GError **error);
69+
GInputStream * libmsi_record_get_stream (LibmsiRecord *record,
70+
guint field);
6671

6772
G_END_DECLS
6873

libmsi/Makefile.am

+1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ libmsi_la_SOURCES = \
1717
drop.c \
1818
insert.c \
1919
libmsi-database.c \
20+
libmsi-istream.c \
2021
libmsi-query.c \
2122
libmsi-record.c \
2223
libmsi-summary-info.c \

libmsi/libmsi-istream.c

+155
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
/*
2+
* This library is free software; you can redistribute it and/or
3+
* modify it under the terms of the GNU Lesser General Public
4+
* License as published by the Free Software Foundation; either
5+
* version 2.1 of the License, or (at your option) any later version.
6+
*
7+
* This library is distributed in the hope that it will be useful,
8+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
9+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
10+
* Lesser General Public License for more details.
11+
*
12+
* You should have received a copy of the GNU Lesser General Public
13+
* License along with this library; if not, write to the Free Software
14+
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
15+
*/
16+
17+
#include "msipriv.h"
18+
#include "libmsi-istream.h"
19+
20+
struct _LibmsiIStream
21+
{
22+
GInputStream parent;
23+
24+
GsfInput *input;
25+
};
26+
27+
static void libmsi_seekable_iface_init (GSeekableIface *iface);
28+
29+
G_DEFINE_TYPE_WITH_CODE (LibmsiIStream, libmsi_istream, G_TYPE_INPUT_STREAM,
30+
G_IMPLEMENT_INTERFACE (G_TYPE_SEEKABLE,
31+
libmsi_seekable_iface_init);
32+
)
33+
34+
static goffset
35+
libmsi_tell (GSeekable *seekable)
36+
{
37+
g_return_val_if_fail (LIBMSI_IS_ISTREAM(seekable), FALSE);
38+
39+
return gsf_input_tell (LIBMSI_ISTREAM(seekable)->input);
40+
}
41+
42+
static gboolean
43+
libmsi_can_seek (GSeekable *seekable)
44+
{
45+
return TRUE;
46+
}
47+
48+
static gboolean
49+
libmsi_seek (GSeekable *seekable, goffset offset,
50+
GSeekType type, GCancellable *cancellable)
51+
{
52+
g_return_val_if_fail (LIBMSI_IS_ISTREAM(seekable), FALSE);
53+
54+
return !gsf_input_seek (LIBMSI_ISTREAM(seekable)->input, offset, type);
55+
}
56+
57+
static gboolean
58+
libmsi_can_truncate (GSeekable *seekable)
59+
{
60+
return FALSE;
61+
}
62+
63+
static void
64+
libmsi_seekable_iface_init (GSeekableIface *iface)
65+
{
66+
iface->tell = libmsi_tell;
67+
iface->can_seek = libmsi_can_seek;
68+
iface->seek = libmsi_seek;
69+
iface->can_truncate = libmsi_can_truncate;
70+
}
71+
72+
static void
73+
libmsi_istream_init (LibmsiIStream *self)
74+
{
75+
}
76+
77+
static void
78+
libmsi_istream_finalize (GObject *object)
79+
{
80+
LibmsiIStream *self = LIBMSI_ISTREAM (object);
81+
82+
if (self->input)
83+
g_object_unref (self->input);
84+
85+
G_OBJECT_CLASS (libmsi_istream_parent_class)->finalize (object);
86+
}
87+
88+
static gssize
89+
input_stream_read (GInputStream *stream,
90+
void *buffer,
91+
gsize count,
92+
GCancellable *cancellable,
93+
GError **error)
94+
{
95+
LibmsiIStream *self = LIBMSI_ISTREAM (stream);
96+
gssize remaining = gsf_input_remaining (self->input);
97+
98+
if (remaining == 0)
99+
return 0;
100+
101+
count = MIN(count, remaining);
102+
if (!gsf_input_read (self->input, count, buffer))
103+
return -1;
104+
105+
return count;
106+
}
107+
108+
static gssize
109+
input_stream_skip (GInputStream *stream,
110+
gsize count,
111+
GCancellable *cancellable,
112+
GError **error)
113+
{
114+
LibmsiIStream *self = LIBMSI_ISTREAM (stream);
115+
116+
count = MIN (count, gsf_input_remaining (self->input));
117+
if (!gsf_input_seek (self->input, count, G_SEEK_CUR))
118+
return -1;
119+
120+
return count;
121+
}
122+
123+
static gboolean
124+
input_stream_close (GInputStream *stream,
125+
GCancellable *cancellable,
126+
GError **error)
127+
{
128+
return TRUE;
129+
}
130+
131+
static void
132+
libmsi_istream_class_init (LibmsiIStreamClass *klass)
133+
{
134+
GObjectClass* object_class = G_OBJECT_CLASS (klass);
135+
GInputStreamClass *istream_class;
136+
137+
object_class->finalize = libmsi_istream_finalize;
138+
139+
istream_class = G_INPUT_STREAM_CLASS (klass);
140+
istream_class->read_fn = input_stream_read;
141+
istream_class->skip = input_stream_skip;
142+
istream_class->close_fn = input_stream_close;
143+
}
144+
145+
G_GNUC_INTERNAL LibmsiIStream *
146+
libmsi_istream_new (GsfInput *input)
147+
{
148+
GsfInput *dup = gsf_input_dup (input, NULL);
149+
g_return_val_if_fail (dup, NULL);
150+
151+
LibmsiIStream *self = g_object_new (LIBMSI_TYPE_ISTREAM, NULL);
152+
self->input = dup;
153+
154+
return self;
155+
}

libmsi/libmsi-istream.h

+47
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/*
2+
* This library is free software; you can redistribute it and/or
3+
* modify it under the terms of the GNU Lesser General Public
4+
* License as published by the Free Software Foundation; either
5+
* version 2.1 of the License, or (at your option) any later version.
6+
*
7+
* This library is distributed in the hope that it will be useful,
8+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
9+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
10+
* Lesser General Public License for more details.
11+
*
12+
* You should have received a copy of the GNU Lesser General Public
13+
* License along with this library; if not, write to the Free Software
14+
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
15+
*/
16+
17+
#ifndef _LIBMSI_ISTREAM_H
18+
#define _LIBMSI_ISTREAM_H
19+
20+
#include <glib-object.h>
21+
#include <gio/gio.h>
22+
23+
#include "libmsi-types.h"
24+
25+
G_BEGIN_DECLS
26+
27+
#define LIBMSI_TYPE_ISTREAM (libmsi_istream_get_type ())
28+
#define LIBMSI_ISTREAM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), LIBMSI_TYPE_ISTREAM, LibmsiIStream))
29+
#define LIBMSI_ISTREAM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), LIBMSI_TYPE_ISTREAM, LibmsiIStreamClass))
30+
#define LIBMSI_IS_ISTREAM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), LIBMSI_TYPE_ISTREAM))
31+
#define LIBMSI_IS_ISTREAM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), LIBMSI_TYPE_ISTREAM))
32+
#define LIBMSI_ISTREAM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), LIBMSI_TYPE_ISTREAM, LibmsiIStreamClass))
33+
34+
typedef struct _LibmsiIStreamClass LibmsiIStreamClass;
35+
36+
struct _LibmsiIStreamClass
37+
{
38+
GOutputStreamClass parent_class;
39+
};
40+
41+
GType libmsi_istream_get_type (void) G_GNUC_CONST;
42+
43+
gssize libmsi_istream_get_size (LibmsiIStream *ostream);
44+
45+
G_END_DECLS
46+
47+
#endif /* _LIBMSI_ISTREAM_H */

0 commit comments

Comments
 (0)