1package glib
2
3// #cgo pkg-config: gio-2.0 glib-2.0 gobject-2.0
4// #include <gio/gio.h>
5// #include <stdlib.h>
6// #include "giostream.go.h"
7import "C"
8import (
9	"bytes"
10	"errors"
11	"unsafe"
12)
13
14func init() {
15
16	tm := []TypeMarshaler{
17		{Type(C.g_io_stream_get_type()), marshalIOStream},
18		{Type(C.g_output_stream_get_type()), marshalOutputStream},
19		{Type(C.g_input_stream_get_type()), marshalInputStream},
20	}
21
22	RegisterGValueMarshalers(tm)
23}
24
25// OutputStreamSpliceFlags is a representation of GTK's GOutputStreamSpliceFlags.
26type OutputStreamSpliceFlags int
27
28const (
29	OUTPUT_STREAM_SPLICE_NONE         OutputStreamSpliceFlags = C.G_OUTPUT_STREAM_SPLICE_NONE
30	OUTPUT_STREAM_SPLICE_CLOSE_SOURCE                         = C.G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE
31	OUTPUT_STREAM_SPLICE_CLOSE_TARGET                         = C.G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET
32)
33
34/*
35 * GIOStream
36 */
37
38// IOStream is a representation of GIO's GIOStream.
39// Base class for implementing read/write streams
40type IOStream struct {
41	*Object
42}
43
44// native returns a pointer to the underlying GIOStream.
45func (v *IOStream) native() *C.GIOStream {
46	if v == nil || v.GObject == nil {
47		return nil
48	}
49	p := unsafe.Pointer(v.GObject)
50	return C.toGIOStream(p)
51}
52
53// NativePrivate: to be used inside Gotk3 only.
54func (v *IOStream) NativePrivate() *C.GIOStream {
55	if v == nil || v.GObject == nil {
56		return nil
57	}
58	p := unsafe.Pointer(v.GObject)
59	return C.toGIOStream(p)
60}
61
62// Native returns a pointer to the underlying GIOStream.
63func (v *IOStream) Native() uintptr {
64	return uintptr(unsafe.Pointer(v.native()))
65}
66
67func marshalIOStream(p uintptr) (interface{}, error) {
68	c := C.g_value_get_object((*C.GValue)(unsafe.Pointer(p)))
69	obj := Take(unsafe.Pointer(c))
70	return wrapIOStream(obj), nil
71}
72
73func wrapIOStream(obj *Object) *IOStream {
74	return &IOStream{obj}
75}
76
77/*
78GInputStream * 	g_io_stream_get_input_stream ()
79GOutputStream * 	g_io_stream_get_output_stream ()
80void 	g_io_stream_splice_async ()
81gboolean 	g_io_stream_splice_finish ()
82*/
83
84// Close is a wrapper around g_io_stream_close().
85func (v *IOStream) Close(cancellable *Cancellable) (bool, error) {
86	var gerr *C.GError
87	ok := gobool(C.g_io_stream_close(
88		v.native(),
89		cancellable.native(),
90		&gerr))
91	if !ok {
92		defer C.g_error_free(gerr)
93		return false, errors.New(goString(gerr.message))
94	}
95	return ok, nil
96}
97
98/*
99void 	g_io_stream_close_async ()
100gboolean 	g_io_stream_close_finish ()
101gboolean 	g_io_stream_is_closed ()
102gboolean 	g_io_stream_has_pending ()
103gboolean 	g_io_stream_set_pending ()
104void 	g_io_stream_clear_pending ()
105*/
106
107/*
108 * GInputStream
109 */
110
111// InputStream is a representation of GIO's GInputStream.
112// Base class for implementing streaming input
113type InputStream struct {
114	*Object
115}
116
117// native returns a pointer to the underlying GInputStream.
118func (v *InputStream) native() *C.GInputStream {
119	if v == nil || v.GObject == nil {
120		return nil
121	}
122	p := unsafe.Pointer(v.GObject)
123	return C.toGInputStream(p)
124}
125
126// NativePrivate: to be used inside Gotk3 only.
127func (v *InputStream) NativePrivate() *C.GInputStream {
128	if v == nil || v.GObject == nil {
129		return nil
130	}
131	p := unsafe.Pointer(v.GObject)
132	return C.toGInputStream(p)
133}
134
135// Native returns a pointer to the underlying GInputStream.
136func (v *InputStream) Native() uintptr {
137	return uintptr(unsafe.Pointer(v.native()))
138}
139
140func marshalInputStream(p uintptr) (interface{}, error) {
141	c := C.g_value_get_object((*C.GValue)(unsafe.Pointer(p)))
142	obj := Take(unsafe.Pointer(c))
143	return wrapInputStream(obj), nil
144}
145
146func wrapInputStream(obj *Object) *InputStream {
147	return &InputStream{obj}
148}
149
150// Read is a wrapper around g_input_stream_read().
151func (v *InputStream) Read(length uint, cancellable *Cancellable) (*bytes.Buffer, int, error) {
152	var gerr *C.GError
153	var buffer = bytes.NewBuffer(make([]byte, length))
154
155	c := C.g_input_stream_read(
156		v.native(),
157		unsafe.Pointer(&buffer.Bytes()[0]),
158		C.gsize(length),
159		cancellable.native(),
160		&gerr)
161	if c == -1 {
162		defer C.g_error_free(gerr)
163		return nil, -1, errors.New(goString(gerr.message))
164	}
165	return buffer, int(c), nil
166}
167
168// TODO find a way to get size to be read without asking for ...
169/*
170gboolean
171g_input_stream_read_all (GInputStream *stream,
172                         void *buffer,
173                         gsize count,
174                         gsize *bytes_read,
175                         GCancellable *cancellable,
176                         GError **error);
177*/
178
179/*
180void 	g_input_stream_read_all_async ()
181gboolean 	g_input_stream_read_all_finish ()
182gssize 	g_input_stream_skip ()
183*/
184
185// Close is a wrapper around g_input_stream_close().
186func (v *InputStream) Close(cancellable *Cancellable) (bool, error) {
187	var gerr *C.GError
188	ok := gobool(C.g_input_stream_close(
189		v.native(),
190		cancellable.native(),
191		&gerr))
192	if !ok {
193		defer C.g_error_free(gerr)
194		return false, errors.New(goString(gerr.message))
195	}
196	return ok, nil
197}
198
199// TODO g_input_stream***
200/*
201void 	g_input_stream_read_async ()
202gssize 	g_input_stream_read_finish ()
203void 	g_input_stream_skip_async ()
204gssize 	g_input_stream_skip_finish ()
205void 	g_input_stream_close_async ()
206gboolean 	g_input_stream_close_finish ()
207*/
208
209// IsClosed is a wrapper around g_input_stream_is_closed().
210func (v *InputStream) IsClosed() bool {
211	return gobool(C.g_input_stream_is_closed(v.native()))
212}
213
214// HasPending is a wrapper around g_input_stream_has_pending().
215func (v *InputStream) HasPending() bool {
216	return gobool(C.g_input_stream_has_pending(v.native()))
217}
218
219// SetPending is a wrapper around g_input_stream_set_pending().
220func (v *InputStream) SetPending() (bool, error) {
221	var gerr *C.GError
222	ok := gobool(C.g_input_stream_set_pending(
223		v.native(),
224		&gerr))
225	if !ok {
226		defer C.g_error_free(gerr)
227		return false, errors.New(goString(gerr.message))
228	}
229	return ok, nil
230}
231
232// ClearPending is a wrapper around g_input_stream_clear_pending().
233func (v *InputStream) ClearPending() {
234	C.g_input_stream_clear_pending(v.native())
235}
236
237/* Useless functions due to Go language specification and actual
238   implementation of (*InputStream).Read that do same thing.
239
240GBytes * 	g_input_stream_read_bytes ()
241void 	g_input_stream_read_bytes_async ()
242GBytes * 	g_input_stream_read_bytes_finish ()
243*/
244
245/*
246 * GOutputStream
247 */
248
249// OutputStream is a representation of GIO's GOutputStream.
250// Base class for implementing streaming output
251type OutputStream struct {
252	*Object
253}
254
255// native returns a pointer to the underlying GOutputStream.
256func (v *OutputStream) native() *C.GOutputStream {
257	if v == nil || v.GObject == nil {
258		return nil
259	}
260	p := unsafe.Pointer(v.GObject)
261	return C.toGOutputStream(p)
262}
263
264// NativePrivate: to be used inside Gotk3 only.
265func (v *OutputStream) NativePrivate() *C.GOutputStream {
266	if v == nil || v.GObject == nil {
267		return nil
268	}
269	p := unsafe.Pointer(v.GObject)
270	return C.toGOutputStream(p)
271}
272
273// Native returns a pointer to the underlying GOutputStream.
274func (v *OutputStream) Native() uintptr {
275	return uintptr(unsafe.Pointer(v.native()))
276}
277
278func marshalOutputStream(p uintptr) (interface{}, error) {
279	c := C.g_value_get_object((*C.GValue)(unsafe.Pointer(p)))
280	obj := Take(unsafe.Pointer(c))
281	return wrapOutputStream(obj), nil
282}
283
284func wrapOutputStream(obj *Object) *OutputStream {
285	return &OutputStream{obj}
286}
287
288/*
289gssize
290g_output_stream_write (GOutputStream *stream,
291                       const void *buffer,
292                       gsize count,
293                       GCancellable *cancellable,
294                       GError **error);
295*/
296
297// Write is a wrapper around g_output_stream_write().
298// buffer := bytes.NewBuffer(make([]byte, length))
299func (v *OutputStream) Write(buffer *bytes.Buffer, cancellable *Cancellable) (int, error) {
300	var gerr *C.GError
301	length := buffer.Len()
302
303	c := C.g_output_stream_write(
304		v.native(),
305		unsafe.Pointer(&buffer.Bytes()[0]),
306		C.gsize(length),
307		cancellable.native(),
308		&gerr)
309	if c == -1 {
310		defer C.g_error_free(gerr)
311		return -1, errors.New(goString(gerr.message))
312	}
313	return int(c), nil
314}
315
316// Write is a wrapper around g_output_stream_write().
317// func (v *OutputStream) Write(buffer *[]byte, cancellable *Cancellable) (int, error) {
318// 	// cdata := C.CString(data)
319// 	// defer C.free(unsafe.Pointer(cdata))
320// 	var gerr *C.GError
321// 	c := C.g_output_stream_write(
322// 		v.native(),
323// 		unsafe.Pointer(buffer),
324// 		C.gsize(len(*buffer)),
325// 		cancellable.native(),
326// 		&gerr)
327// 	if c == -1 {
328// 		defer C.g_error_free(gerr)
329// 		return 0, errors.New(goString(gerr.message))
330// 	}
331// 	return int(c), nil
332// }
333
334/*
335gboolean 	g_output_stream_write_all ()
336*/
337
338// TODO outputStream asynch functions
339/*
340void 	g_output_stream_write_all_async ()
341gboolean 	g_output_stream_write_all_finish ()
342gboolean 	g_output_stream_writev ()
343gboolean 	g_output_stream_writev_all ()
344void 	g_output_stream_writev_async ()
345gboolean 	g_output_stream_writev_finish ()
346void 	g_output_stream_writev_all_async ()
347gboolean 	g_output_stream_writev_all_finish ()
348*/
349/*
350gssize
351g_output_stream_splice (GOutputStream *stream,
352                        GInputStream *source,
353                        GOutputStreamSpliceFlags flags,
354                        GCancellable *cancellable,
355                        GError **error);
356*/
357
358// Flush is a wrapper around g_output_stream_flush().
359func (v *OutputStream) Flush(cancellable *Cancellable) (bool, error) {
360	var gerr *C.GError
361	ok := gobool(C.g_output_stream_flush(
362		v.native(),
363		cancellable.native(),
364		&gerr))
365	if !ok {
366		defer C.g_error_free(gerr)
367		return false, errors.New(goString(gerr.message))
368	}
369	return ok, nil
370}
371
372// Close is a wrapper around g_output_stream_close().
373func (v *OutputStream) Close(cancellable *Cancellable) (bool, error) {
374	var gerr *C.GError
375	ok := gobool(C.g_output_stream_close(
376		v.native(),
377		cancellable.native(),
378		&gerr))
379	if !ok {
380		defer C.g_error_free(gerr)
381		return false, errors.New(goString(gerr.message))
382	}
383	return ok, nil
384}
385
386// TODO outputStream asynch functions
387/*
388void 	g_output_stream_write_async ()
389gssize 	g_output_stream_write_finish ()
390void 	g_output_stream_splice_async ()
391gssize 	g_output_stream_splice_finish ()
392void 	g_output_stream_flush_async ()
393gboolean 	g_output_stream_flush_finish ()
394void 	g_output_stream_close_async ()
395gboolean 	g_output_stream_close_finish ()
396*/
397
398// IsClosing is a wrapper around g_output_stream_is_closing().
399func (v *OutputStream) IsClosing() bool {
400	return gobool(C.g_output_stream_is_closing(v.native()))
401}
402
403// IsClosed is a wrapper around g_output_stream_is_closed().
404func (v *OutputStream) IsClosed() bool {
405	return gobool(C.g_output_stream_is_closed(v.native()))
406}
407
408// HasPending is a wrapper around g_output_stream_has_pending().
409func (v *OutputStream) HasPending() bool {
410	return gobool(C.g_output_stream_has_pending(v.native()))
411}
412
413// SetPending is a wrapper around g_output_stream_set_pending().
414func (v *OutputStream) SetPending() (bool, error) {
415	var gerr *C.GError
416	ok := gobool(C.g_output_stream_set_pending(
417		v.native(),
418		&gerr))
419	if !ok {
420		defer C.g_error_free(gerr)
421		return false, errors.New(goString(gerr.message))
422	}
423	return ok, nil
424}
425
426// ClearPending is a wrapper around g_output_stream_clear_pending().
427func (v *OutputStream) ClearPending() {
428	C.g_output_stream_clear_pending(v.native())
429}
430
431/*
432gssize 	g_output_stream_write_bytes ()
433void 	g_output_stream_write_bytes_async ()
434gssize 	g_output_stream_write_bytes_finish ()
435gboolean 	g_output_stream_printf ()
436gboolean 	g_output_stream_vprintf ()
437*/
438