summaryrefslogtreecommitdiff
path: root/libarchive_fe
diff options
context:
space:
mode:
authorJoerg Sonnenberger <joerg.sonnenberger@gmail.com>2010-02-20 17:59:56 -0500
committerJoerg Sonnenberger <joerg.sonnenberger@gmail.com>2010-02-20 17:59:56 -0500
commit6e6394c499c9c8268986dc14f048f36d3e50fe48 (patch)
treeaa7fa994b8568f60e0aa61aa49b4aa82ddddd70a /libarchive_fe
parent32630958d2ec3775e649840ab4730d9fcdb02383 (diff)
downloadlibarchive-6e6394c499c9c8268986dc14f048f36d3e50fe48.tar.gz
Simplify the line reader:
- Do not allocate a buffer in advance, it will be reallocated on the first round anyway. - Allocate one more byte to allow always terminating the buffer. - Use strcpsn to compute the end of line. This slightly changes the behavior for NUL in text lines as they are no longer truncated. SVN-Revision: 1929
Diffstat (limited to 'libarchive_fe')
-rw-r--r--libarchive_fe/line_reader.c60
1 files changed, 29 insertions, 31 deletions
diff --git a/libarchive_fe/line_reader.c b/libarchive_fe/line_reader.c
index 4af60de4..2d197d3d 100644
--- a/libarchive_fe/line_reader.c
+++ b/libarchive_fe/line_reader.c
@@ -1,5 +1,6 @@
/*-
* Copyright (c) 2008 Tim Kientzle
+ * Copyright (c) 2010 Joerg Sonnenberger
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -74,14 +75,20 @@ lafe_line_reader(const char *pathname, int nullSeparator)
if (lr->f == NULL)
lafe_errc(1, errno, "Couldn't open %s", pathname);
lr->buff_length = 8192;
- lr->buff = malloc(lr->buff_length);
- if (lr->buff == NULL)
- lafe_errc(1, ENOMEM, "Can't read %s", pathname);
- lr->line_start = lr->line_end = lr->buff_end = lr->buff;
+ lr->line_start = lr->line_end = lr->buff_end = lr->buff = NULL;
return (lr);
}
+static void
+lafe_line_reader_find_eol(struct lafe_line_reader *lr)
+{
+
+ lr->line_end += strcspn(lr->line_end,
+ lr->nullSeparator ? "" : "\x0d\x0a");
+ *lr->line_end = '\0'; /* Noop if line_end == buff_end */
+}
+
const char *
lafe_line_reader_next(struct lafe_line_reader *lr)
{
@@ -91,36 +98,21 @@ lafe_line_reader_next(struct lafe_line_reader *lr)
for (;;) {
/* If there's a line in the buffer, return it immediately. */
while (lr->line_end < lr->buff_end) {
- if (lr->nullSeparator) {
- if (*lr->line_end == '\0') {
- line_start = lr->line_start;
- lr->line_start = lr->line_end + 1;
- lr->line_end = lr->line_start;
- return (line_start);
- }
- } else if (*lr->line_end == '\x0a' || *lr->line_end == '\x0d') {
- *lr->line_end = '\0';
- line_start = lr->line_start;
- lr->line_start = lr->line_end + 1;
- lr->line_end = lr->line_start;
- if (line_start[0] != '\0')
- return (line_start);
- }
- lr->line_end++;
+ line_start = lr->line_start;
+ lr->line_start = ++lr->line_end;
+ lafe_line_reader_find_eol(lr);
+
+ if (lr->nullSeparator || line_start[0] != '\0')
+ return (line_start);
}
/* If we're at end-of-file, process the final data. */
if (lr->f == NULL) {
- /* If there's more text, return one last line. */
- if (lr->line_end > lr->line_start) {
- *lr->line_end = '\0';
- line_start = lr->line_start;
- lr->line_start = lr->line_end + 1;
- lr->line_end = lr->line_start;
- return (line_start);
- }
- /* Otherwise, we're done. */
- return (NULL);
+ if (lr->line_start == lr->buff_end)
+ return (NULL); /* No more text */
+ line_start = lr->line_start;
+ lr->line_start = lr->buff_end;
+ return (line_start);
}
/* Buffer only has part of a line. */
@@ -138,7 +130,11 @@ lafe_line_reader_next(struct lafe_line_reader *lr)
lafe_errc(1, ENOMEM,
"Line too long in %s", lr->pathname);
lr->buff_length = new_buff_size;
- p = realloc(lr->buff, new_buff_size);
+ /*
+ * Allocate one extra byte to allow terminating
+ * the buffer.
+ */
+ p = realloc(lr->buff, new_buff_size + 1);
if (p == NULL)
lafe_errc(1, ENOMEM,
"Line too long in %s", lr->pathname);
@@ -151,6 +147,8 @@ lafe_line_reader_next(struct lafe_line_reader *lr)
bytes_wanted = lr->buff + lr->buff_length - lr->buff_end;
bytes_read = fread(lr->buff_end, 1, bytes_wanted, lr->f);
lr->buff_end += bytes_read;
+ *lr->buff_end = '\0'; /* Always terminate buffer */
+ lafe_line_reader_find_eol(lr);
if (ferror(lr->f))
lafe_errc(1, errno, "Can't read %s", lr->pathname);