1 /* ide-line-reader.c
2 *
3 * Copyright 2015-2019 Christian Hergert <christian@hergert.me>
4 *
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 3 of the License, or
8 * (at your option) any later version.
9 *
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.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 *
18 * SPDX-License-Identifier: GPL-3.0-or-later
19 */
20
21 #define G_LOG_DOMAIN "ide-line-reader"
22
23 #include "config.h"
24
25 #include <string.h>
26
27 #include "ide-line-reader.h"
28
29 void
ide_line_reader_init(IdeLineReader * reader,gchar * contents,gssize length)30 ide_line_reader_init (IdeLineReader *reader,
31 gchar *contents,
32 gssize length)
33 {
34 g_assert (reader);
35
36 if (length < 0)
37 length = strlen (contents);
38
39 if (contents != NULL)
40 {
41 reader->contents = contents;
42 reader->length = length;
43 reader->pos = 0;
44 }
45 else
46 {
47 reader->contents = NULL;
48 reader->length = 0;
49 reader->pos = 0;
50 }
51 }
52
53 /**
54 * ide_line_reader_next:
55 * @reader: the #IdeLineReader
56 * @length: a location for the length of the line in bytes.
57 *
58 * Moves forward to the beginning of the next line in the buffer. No changes to the buffer
59 * are made, and the result is a pointer within the string passed as @contents in
60 * ide_line_reader_init(). Since the line most likely will not be terminated with a NULL byte,
61 * you must provide @length to determine the length of the line.
62 *
63 * Returns: (transfer none): The beginning of the line within the buffer.
64 *
65 * Since: 3.32
66 */
67 gchar *
ide_line_reader_next(IdeLineReader * reader,gsize * length)68 ide_line_reader_next (IdeLineReader *reader,
69 gsize *length)
70 {
71 gchar *ret = NULL;
72
73 g_assert (reader);
74 g_assert (length != NULL);
75
76 if ((reader->contents == NULL) || (reader->pos >= reader->length))
77 {
78 *length = 0;
79 return NULL;
80 }
81
82 ret = &reader->contents [reader->pos];
83
84 for (; reader->pos < reader->length; reader->pos++)
85 {
86 if (reader->contents [reader->pos] == '\n')
87 {
88 *length = &reader->contents [reader->pos] - ret;
89 /* Ingore the \r in \r\n if provided */
90 if (*length > 0 && reader->pos > 0 && reader->contents [reader->pos - 1] == '\r')
91 (*length)--;
92 reader->pos++;
93 return ret;
94 }
95 }
96
97 *length = &reader->contents [reader->pos] - ret;
98
99 return ret;
100 }
101