1 /* gEDA - GPL Electronic Design Automation
2 * libgeda - gEDA's library
3 * Copyright (C) 1998-2010 Ales Hvezda
4 * Copyright (C) 1998-2020 gEDA Contributors (see ChangeLog for details)
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
30 #include "libgeda_priv.h"
43 #define TEXT_BUFFER_LINE_SIZE 1024
45 /*! \brief Create a new managed text buffer.
47 * \par Function description
48 * Allocates and initialises a new TextBuffer to manage the given data
51 * If the size argument is negative, assumes that data is
54 * \param data The address of the buffer to be managed.
55 * \param size The length of the buffer.
56 * \retval Pointer to a new TextBuffer struct.
58 TextBuffer
*s_textbuffer_new (const gchar
*data
, const gint size
)
63 g_return_val_if_fail ((data
!= NULL
),
67 realsize
= strlen(data
);
71 result
= g_new0(TextBuffer
, 1);
73 result
->buffer
= data
;
74 result
->size
= realsize
;
76 result
->linesize
= TEXT_BUFFER_LINE_SIZE
;
77 result
->line
= g_malloc(result
->linesize
);
82 /*! \brief Clean up a managed text buffer
84 * \par Function description
85 * Cleans up all of the resources associated with a given TextBuffer.
87 * Should be called thus:
90 * tb = s_textbuffer_free (tb);
93 TextBuffer
*s_textbuffer_free (TextBuffer
*tb
)
95 if (tb
== NULL
) return NULL
;
103 /*! \brief Fetch a number of characters from a text buffer
105 * \par Function description
106 * Get some number of characters from a TextBuffer, starting at the
107 * current position. If the end of the buffer has been reached (and
108 * thus no more characters remain) returns null. If \a count is -1,
109 * obtains all characters up to and including the next newline.
111 * A newline is detected as '\\n', or '\\r' together with its
112 * immediately following '\\n', or '\\r', in that order. All newlines
113 * are collapsed into a single '\\n'.
115 * The returned character array should be considered highly volatile,
116 * and is only valid until the next call to s_textbuffer_next() or
117 * s_textbuffer_next_line().
119 * \param tb TextBuffer to read from.
120 * \param count Maximum number of characters to read.
121 * \retval Character array, or NULL if no characters left.
124 s_textbuffer_next (TextBuffer
*tb
, const gssize count
)
126 gboolean eol
= FALSE
;
130 g_return_val_if_fail (tb
!= NULL
, NULL
);
132 if (tb
->offset
>= tb
->size
) return NULL
;
134 const gchar
*src
= tb
->buffer
+ tb
->offset
;
135 gchar
*dest
= tb
->line
;
136 const gchar
*buf_end
= tb
->buffer
+ tb
->size
;
139 if (src
>= buf_end
) break;
140 if (count
>= 0 && dest
- tb
->line
>= count
) break;
141 if (count
< 0 && eol
) break;
143 /* Expand line buffer, if necessary, leaving space for a null */
144 len
= dest
- tb
->line
+ 2;
145 if (len
>= tb
->linesize
) {
146 tb
->linesize
+= TEXT_BUFFER_LINE_SIZE
;
147 tb
->line
= g_realloc(tb
->line
, tb
->linesize
);
155 } else if (c
== '\r') {
158 /* Peek ahead to absorb a '\n' */
160 if (src
>= buf_end
|| *src
!= '\n') src
--;
170 tb
->offset
= src
- tb
->buffer
;
174 /*! \brief Fetch the next line from a text buffer
176 * \par Function description
177 * Get the next line of characters from a TextBuffer, starting from
178 * the current position. If the end of the buffer has been reached
179 * (and thus no more characters remain) returns null.
181 * The returned character array should be considered highly volatile,
182 * and is only valid until the next call to s_textbuffer_next() or
183 * s_textbuffer_next_line().
185 * \param tb TextBuffer to read from.
186 * \retval Character array, or NULL if no characters left.
189 s_textbuffer_next_line (TextBuffer
*tb
)
191 return s_textbuffer_next (tb
, -1);