libgeda

s_textbuffer.c

Go to the documentation of this file.
00001 /* gEDA - GPL Electronic Design Automation
00002  * libgeda - gEDA's library
00003  * Copyright (C) 1998-2010 Ales Hvezda
00004  * Copyright (C) 1998-2010 gEDA Contributors (see ChangeLog for details)
00005  *
00006  * This program is free software; you can redistribute it and/or modify
00007  * it under the terms of the GNU General Public License as published by
00008  * the Free Software Foundation; either version 2 of the License, or
00009  * (at your option) any later version.
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License
00017  * along with this program; if not, write to the Free Software
00018  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
00019  */
00020 
00021 #include <config.h>
00022 
00023 #include <stdio.h>
00024 #include <glib.h>
00025 
00026 #ifdef HAVE_STRING_H
00027 #include <string.h>
00028 #endif
00029 
00030 #ifdef HAVE_LIBDMALLOC
00031 #include <dmalloc.h>
00032 #endif
00033 
00034 #include "libgeda_priv.h"
00035 
00036 struct _TextBuffer
00037 {
00038   const gchar *buffer;
00039   gsize size;
00040 
00041   gchar *line;
00042   gsize linesize;
00043 
00044   gsize offset;
00045 };
00046 
00047 #define TEXT_BUFFER_LINE_SIZE 1024
00048 
00062 TextBuffer *s_textbuffer_new (const gchar *data, const gint size)
00063 {
00064   TextBuffer *result;
00065   gsize realsize;
00066 
00067   g_return_val_if_fail ((data != NULL),
00068                         NULL);
00069 
00070   if (size < 0)
00071     realsize = strlen(data);
00072   else
00073     realsize = size;
00074 
00075   result = g_new0(TextBuffer, 1);
00076 
00077   result->buffer = data;
00078   result->size = realsize;
00079 
00080   result->linesize = TEXT_BUFFER_LINE_SIZE;
00081   result->line = g_malloc(result->linesize);
00082 
00083   return result;
00084 }
00085 
00097 TextBuffer *s_textbuffer_free (TextBuffer *tb)
00098 {
00099   if (tb == NULL) return NULL;
00100 
00101   g_free (tb->line);
00102   tb->line = NULL;
00103   g_free (tb);
00104   return NULL;
00105 }
00106 
00127 const gchar *
00128 s_textbuffer_next (TextBuffer *tb, const gssize count)
00129 {
00130   gboolean eol = FALSE;
00131   gchar c;
00132   gsize len;
00133 
00134   g_return_val_if_fail (tb != NULL, NULL);
00135 
00136   if (tb->offset >= tb->size) return NULL;
00137 
00138   const gchar *src = tb->buffer + tb->offset;
00139   gchar *dest = tb->line;
00140   const gchar *buf_end = tb->buffer + tb->size;
00141 
00142   while (1) {
00143     if (src >= buf_end) break;
00144     if (count >= 0 && dest - tb->line >= count) break;
00145     if (count < 0 && eol) break;
00146 
00147     /* Expand line buffer, if necessary, leaving space for a null */
00148     len = dest - tb->line + 2;
00149     if (len >= tb->linesize) {
00150       tb->linesize += TEXT_BUFFER_LINE_SIZE;
00151       tb->line = g_realloc(tb->line, tb->linesize);
00152     }
00153 
00154     eol = FALSE;
00155     c = *src;
00156     if (c == '\n') {
00157       *dest = '\n';
00158       eol = TRUE;
00159     } else if (c == '\r') {
00160       *dest = '\n';
00161       eol = TRUE;
00162       /* Peek ahead to absorb a '\n' */
00163       src++;
00164       if (src >= buf_end || *src != '\n') src--;
00165     } else {
00166       *dest = c;
00167     }
00168 
00169     src++;
00170     dest++;
00171   }
00172 
00173   *dest = 0;
00174   tb->offset = src - tb->buffer;
00175 
00176   return tb->line;
00177 }
00192 const gchar *
00193 s_textbuffer_next_line (TextBuffer *tb)
00194 {
00195   return s_textbuffer_next (tb, -1);
00196 }
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines