2 * gsio.c: an IO abstraction
4 * Copyright 2002 - 2005 the Free Software Foundation
6 * Author: Jaka Mocnik <jaka@gnu.org>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 #define CHUNK_SIZE 32768
29 typedef struct _GtkGSDocChunk GtkGSDocChunk;
30 struct _GtkGSDocChunk {
35 struct _GtkGSDocSink {
40 static GtkGSDocChunk *
41 gtk_gs_doc_chunk_new(guint size)
45 c = g_new0(GtkGSDocChunk, 1);
46 if((c->buf = g_malloc(sizeof(gchar) * size)) == NULL) {
58 gtk_gs_doc_chunk_free(GtkGSDocChunk * c)
70 sink = g_new0(GtkGSDocSink, 1);
75 gtk_gs_doc_sink_free(GtkGSDocSink * sink)
81 gtk_gs_doc_chunk_free((GtkGSDocChunk *) node->data);
84 g_slist_free(sink->chunks);
88 gtk_gs_doc_sink_write(GtkGSDocSink * sink, const gchar * buf, int len)
92 if(sink->tail == NULL) {
93 sink->tail = gtk_gs_doc_chunk_new(CHUNK_SIZE);
94 sink->chunks = g_slist_append(sink->chunks, sink->tail);
97 real_len = MIN(sink->tail->max_len - sink->tail->len, len);
99 strncpy(sink->tail->ptr, buf, real_len);
100 sink->tail->ptr += real_len;
101 sink->tail->len += real_len;
106 gtk_gs_doc_sink_write(sink, buf + real_len, len);
111 gtk_gs_doc_sink_printf_v(GtkGSDocSink * sink, const gchar * fmt, va_list ap)
115 if(sink->tail == NULL) {
116 sink->tail = gtk_gs_doc_chunk_new(CHUNK_SIZE);
117 sink->chunks = g_slist_append(sink->chunks, sink->tail);
120 max_len = sink->tail->max_len - sink->tail->len;
122 len = g_vsnprintf(sink->tail->ptr, max_len, fmt, ap);
123 if(len >= max_len - 1) {
124 /* force printf in the next chunk later on */
129 sink->tail->ptr += len;
130 sink->tail->len += len;
134 gtk_gs_doc_sink_printf(sink, fmt, ap);
139 gtk_gs_doc_sink_printf(GtkGSDocSink * sink, const gchar * fmt, ...)
144 gtk_gs_doc_sink_printf_v(sink, fmt, ap);
149 gtk_gs_doc_sink_get_buffer(GtkGSDocSink * sink)
154 for(total = 0, node = sink->chunks; node; node = node->next) {
155 total += ((GtkGSDocChunk *) node->data)->len;
158 gchar *buf = g_malloc(sizeof(gchar) * (total + 1)), *ptr;
161 for(ptr = buf, node = sink->chunks; node; node = node->next) {
163 ((GtkGSDocChunk *) node->data)->buf,
164 ((GtkGSDocChunk *) node->data)->len);
165 ptr += ((GtkGSDocChunk *) node->data)->len;