2 * Copyright (C) 2006-2007 Red Hat, Inc
3 * Copyright (C) 2016 J. Ali Harlow <ali@juiblex.co.uk>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
23 #include <glib/gi18n.h>
24 #include "plover/inputstream.h"
27 * SECTION:ploverrazorinputstream
28 * @short_description: Streaming input operations on razor files
29 * @include: plover/inputstream.h
30 * @see_also: #GMemoryInputStream
32 * #PloverRazorInputStream provides input streams that get their
33 * content via razor's URI input routines.
36 struct _PloverRazorInputStreamPrivate
43 static gssize plover_razor_input_stream_read(GInputStream *stream,void *buffer,
44 gsize count,GCancellable *cancellable,GError **error);
45 static gssize plover_razor_input_stream_skip(GInputStream *stream,gsize count,
46 GCancellable *cancellable,GError **error);
47 static gboolean plover_razor_input_stream_close(GInputStream *stream,
48 GCancellable *cancellable,GError **error);
49 static void plover_razor_input_stream_skip_async(GInputStream *stream,
50 gsize count,int io_priority,GCancellable *cancellable,
51 GAsyncReadyCallback callback,gpointer data);
52 static gssize plover_razor_input_stream_skip_finish(GInputStream *stream,
53 GAsyncResult *result,GError **error);
54 static void plover_razor_input_stream_close_async(GInputStream *stream,
55 int io_priority,GCancellable *cancellable,GAsyncReadyCallback callback,
57 static gboolean plover_razor_input_stream_close_finish(GInputStream *stream,
58 GAsyncResult *result,GError **error);
60 plover_razor_input_stream_seekable_iface_init(GSeekableIface *iface);
61 static goffset plover_razor_input_stream_tell(GSeekable *seekable);
62 static gboolean plover_razor_input_stream_can_seek(GSeekable *seekable);
63 static gboolean plover_razor_input_stream_seek(GSeekable *seekable,
64 goffset offset,GSeekType type,GCancellable *cancellable,GError **error);
65 static gboolean plover_razor_input_stream_can_truncate(GSeekable *seekable);
66 static gboolean plover_razor_input_stream_truncate(GSeekable *seekable,
67 goffset offset,GCancellable *cancellable,GError **error);
68 static void plover_razor_input_stream_pollable_iface_init(
69 GPollableInputStreamInterface *iface);
71 plover_razor_input_stream_is_readable(GPollableInputStream *stream);
73 plover_razor_input_stream_create_source(GPollableInputStream *stream,
74 GCancellable *cancellable);
75 static void plover_razor_input_stream_finalize(GObject *object);
77 G_DEFINE_TYPE_WITH_CODE(PloverRazorInputStream,plover_razor_input_stream,
79 G_IMPLEMENT_INTERFACE(G_TYPE_SEEKABLE,
80 plover_razor_input_stream_seekable_iface_init);
81 G_IMPLEMENT_INTERFACE(G_TYPE_POLLABLE_INPUT_STREAM,
82 plover_razor_input_stream_pollable_iface_init);
86 plover_razor_input_stream_class_init(PloverRazorInputStreamClass *klass)
88 GObjectClass *object_class;
89 GInputStreamClass *istream_class;
90 g_type_class_add_private(klass,sizeof(PloverRazorInputStreamPrivate));
91 object_class=G_OBJECT_CLASS(klass);
92 object_class->finalize=plover_razor_input_stream_finalize;
93 istream_class=G_INPUT_STREAM_CLASS(klass);
94 istream_class->read_fn=plover_razor_input_stream_read;
95 istream_class->skip=plover_razor_input_stream_skip;
96 istream_class->close_fn=plover_razor_input_stream_close;
97 istream_class->skip_async=plover_razor_input_stream_skip_async;
98 istream_class->skip_finish=plover_razor_input_stream_skip_finish;
99 istream_class->close_async=plover_razor_input_stream_close_async;
100 istream_class->close_finish=plover_razor_input_stream_close_finish;
103 static void plover_razor_input_stream_finalize(GObject *object)
105 PloverRazorInputStream *razor_stream;
106 PloverRazorInputStreamPrivate *priv;
107 razor_stream=PLOVER_RAZOR_INPUT_STREAM(object);
108 priv=razor_stream->priv;
109 razor_uri_free_contents(priv->buf,priv->len);
110 G_OBJECT_CLASS(plover_razor_input_stream_parent_class)->finalize(object);
113 static void plover_razor_input_stream_seekable_iface_init(GSeekableIface *iface)
115 iface->tell=plover_razor_input_stream_tell;
116 iface->can_seek=plover_razor_input_stream_can_seek;
117 iface->seek=plover_razor_input_stream_seek;
118 iface->can_truncate=plover_razor_input_stream_can_truncate;
119 iface->truncate_fn=plover_razor_input_stream_truncate;
122 static void plover_razor_input_stream_pollable_iface_init(
123 GPollableInputStreamInterface *iface)
125 iface->is_readable=plover_razor_input_stream_is_readable;
126 iface->create_source=plover_razor_input_stream_create_source;
129 static void plover_razor_input_stream_init(PloverRazorInputStream *stream)
131 stream->priv=G_TYPE_INSTANCE_GET_PRIVATE(stream,
132 PLOVER_TYPE_RAZOR_INPUT_STREAM,PloverRazorInputStreamPrivate);
135 GInputStream *plover_razor_input_stream_new(const char *uri,GError **error)
139 struct razor_error *tmp_error=NULL;
140 GInputStream *stream;
141 PloverRazorInputStreamPrivate *priv;
142 g_return_val_if_fail(plover__uri_validate(uri),NULL);
143 buf=razor_uri_get_contents(uri,&len,FALSE,&tmp_error);
146 plover_propagate_razor_error(error,tmp_error);
149 stream=g_object_new(PLOVER_TYPE_RAZOR_INPUT_STREAM,NULL);
150 priv=PLOVER_RAZOR_INPUT_STREAM(stream)->priv;
156 static gssize plover_razor_input_stream_read(GInputStream *stream,void *buffer,
157 gsize count,GCancellable *cancellable,GError **error)
159 PloverRazorInputStream *razor_stream;
160 PloverRazorInputStreamPrivate *priv;
161 razor_stream=PLOVER_RAZOR_INPUT_STREAM(stream);
162 priv=razor_stream->priv;
163 count=MIN(count,priv->len-priv->pos);
164 memcpy(buffer,(guint8 *)priv->buf+priv->pos,count);
169 static gssize plover_razor_input_stream_skip(GInputStream *stream,gsize count,
170 GCancellable *cancellable,GError **error)
172 PloverRazorInputStream *razor_stream;
173 PloverRazorInputStreamPrivate *priv;
174 razor_stream=PLOVER_RAZOR_INPUT_STREAM(stream);
175 priv=razor_stream->priv;
176 count=MIN(count,priv->len-priv->pos);
181 static gboolean plover_razor_input_stream_close(GInputStream *stream,
182 GCancellable *cancellable,GError **error)
187 static void plover_razor_input_stream_skip_async(GInputStream *stream,
188 gsize count,int io_priority,GCancellable *cancellable,
189 GAsyncReadyCallback callback,gpointer user_data)
194 nskipped=G_INPUT_STREAM_GET_CLASS(stream)->skip(stream,count,cancellable,
196 task=g_task_new(stream,cancellable,callback,user_data);
198 g_task_return_error(task,error);
200 g_task_return_int(task,nskipped);
201 g_object_unref(task);
204 static gssize plover_razor_input_stream_skip_finish(GInputStream *stream,
205 GAsyncResult *result,GError **error)
207 g_return_val_if_fail(g_task_is_valid(result,stream),-1);
208 return g_task_propagate_int(G_TASK(result),error);
211 static void plover_razor_input_stream_close_async(GInputStream *stream,
212 int io_priority,GCancellable *cancellable,GAsyncReadyCallback callback,
216 task=g_task_new(stream,cancellable,callback,user_data);
217 g_task_return_boolean(task,TRUE);
218 g_object_unref (task);
221 static gboolean plover_razor_input_stream_close_finish(GInputStream *stream,
222 GAsyncResult *result,GError **error)
227 static goffset plover_razor_input_stream_tell(GSeekable *seekable)
229 PloverRazorInputStream *razor_stream;
230 PloverRazorInputStreamPrivate *priv;
231 razor_stream=PLOVER_RAZOR_INPUT_STREAM(seekable);
232 priv=razor_stream->priv;
236 static gboolean plover_razor_input_stream_can_seek(GSeekable *seekable)
241 static gboolean plover_razor_input_stream_seek(GSeekable *seekable,
242 goffset offset,GSeekType type,GCancellable *cancellable,GError **error)
244 PloverRazorInputStream *razor_stream;
245 PloverRazorInputStreamPrivate *priv;
247 razor_stream=PLOVER_RAZOR_INPUT_STREAM(seekable);
248 priv=razor_stream->priv;
252 absolute=priv->pos+offset;
258 absolute=priv->len+offset;
261 g_set_error_literal(error,G_IO_ERROR,G_IO_ERROR_INVALID_ARGUMENT,
262 _("Invalid GSeekType supplied"));
265 if (absolute<0 || absolute>priv->len)
267 g_set_error_literal(error,G_IO_ERROR,G_IO_ERROR_INVALID_ARGUMENT,
268 _("Invalid seek request"));
275 static gboolean plover_razor_input_stream_can_truncate(GSeekable *seekable)
280 static gboolean plover_razor_input_stream_truncate(GSeekable *seekable,
281 goffset offset,GCancellable *cancellable,GError **error)
283 g_set_error_literal(error,G_IO_ERROR,G_IO_ERROR_NOT_SUPPORTED,
284 _("Cannot truncate PloverRazorInputStream"));
289 plover_razor_input_stream_is_readable(GPollableInputStream *stream)
295 plover_razor_input_stream_create_source(GPollableInputStream *stream,
296 GCancellable *cancellable)
298 GSource *base_source,*pollable_source;
299 base_source=g_timeout_source_new(0);
300 pollable_source=g_pollable_source_new_full(stream,base_source,cancellable);
301 g_source_unref(base_source);
302 return pollable_source;