From a22eb8c435194e1c0629a0c10603384fee5910b5 Mon Sep 17 00:00:00 2001 From: Christian Hergert Date: Tue, 9 May 2023 17:18:44 -0700 Subject: [PATCH] libsysprof-analyze: add inlined line reader This is a bit nicer than the allocating form we have elsewhere. --- src/libsysprof-analyze/line-reader-private.h | 94 ++++++++++++++++++++ 1 file changed, 94 insertions(+) create mode 100644 src/libsysprof-analyze/line-reader-private.h diff --git a/src/libsysprof-analyze/line-reader-private.h b/src/libsysprof-analyze/line-reader-private.h new file mode 100644 index 00000000..deea4396 --- /dev/null +++ b/src/libsysprof-analyze/line-reader-private.h @@ -0,0 +1,94 @@ +/* line-reader-private.h + * + * Copyright 2015-2023 Christian Hergert + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +#pragma once + +#include +#include + +G_BEGIN_DECLS + +typedef struct _LineReader +{ + char *contents; + gsize length; + gssize pos; +} LineReader; + +static inline void +line_reader_init (LineReader *reader, + char *contents, + gssize length) +{ + g_assert (reader != NULL); + + if (length < 0) + length = strlen (contents); + + if (contents != NULL) + { + reader->contents = contents; + reader->length = length; + reader->pos = 0; + } + else + { + reader->contents = NULL; + reader->length = 0; + reader->pos = 0; + } +} + +static inline char * +line_reader_next (LineReader *reader, + gsize *length) +{ + char *ret = NULL; + + g_assert (reader != NULL); + g_assert (length != NULL); + + if ((reader->contents == NULL) || (reader->pos >= reader->length)) + { + *length = 0; + return NULL; + } + + ret = &reader->contents [reader->pos]; + + for (; reader->pos < reader->length; reader->pos++) + { + if (reader->contents [reader->pos] == '\n') + { + *length = &reader->contents [reader->pos] - ret; + /* Ingore the \r in \r\n if provided */ + if (*length > 0 && reader->pos > 0 && reader->contents [reader->pos - 1] == '\r') + (*length)--; + reader->pos++; + return ret; + } + } + + *length = &reader->contents [reader->pos] - ret; + + return ret; +} + +G_END_DECLS