about summary refs log tree commit diff
path: root/src/engine/e_linereader.c
diff options
context:
space:
mode:
authorMagnus Auvinen <magnus.auvinen@gmail.com>2008-02-10 21:54:52 +0000
committerMagnus Auvinen <magnus.auvinen@gmail.com>2008-02-10 21:54:52 +0000
commit548a919ea379a3b9d1d9e41cf4dad6b4779fd3e6 (patch)
tree85666198fed3d4803f3ec3373c134d12bde9329b /src/engine/e_linereader.c
parent2f969d9d6fece689e05857580ffb1843439e5fbb (diff)
downloadzcatch-548a919ea379a3b9d1d9e41cf4dad6b4779fd3e6.tar.gz
zcatch-548a919ea379a3b9d1d9e41cf4dad6b4779fd3e6.zip
merged 0.3.4 changes to trunk
Diffstat (limited to 'src/engine/e_linereader.c')
-rw-r--r--src/engine/e_linereader.c62
1 files changed, 62 insertions, 0 deletions
diff --git a/src/engine/e_linereader.c b/src/engine/e_linereader.c
new file mode 100644
index 00000000..57ba9a85
--- /dev/null
+++ b/src/engine/e_linereader.c
@@ -0,0 +1,62 @@
+#include "e_linereader.h"
+
+void linereader_init(LINEREADER *lr, IOHANDLE io)
+{
+	lr->buffer_max_size = 4*1024;
+	lr->buffer_size = 0;
+	lr->buffer_pos = 0;
+	lr->io = io;
+}
+
+char *linereader_get(LINEREADER *lr)
+{
+	unsigned line_start = lr->buffer_pos;
+
+	while(1)
+	{
+		if(lr->buffer_pos >= lr->buffer_size)
+		{
+			/* fetch more */
+
+			/* move the remaining part to the front */
+			unsigned read;
+			unsigned left = lr->buffer_size - line_start;
+
+			if(line_start > lr->buffer_size)
+				left = 0;
+			if(left)
+				mem_move(lr->buffer, &lr->buffer[line_start], left);
+			lr->buffer_pos = left;
+
+			/* fill the buffer */
+			read = io_read(lr->io, &lr->buffer[lr->buffer_pos], lr->buffer_max_size-lr->buffer_pos);
+			lr->buffer_size = left + read;
+			line_start = 0;
+
+			if(!read)
+			{
+				if(left)
+				{
+					lr->buffer[left] = 0; /* return the last line */
+					lr->buffer_pos = left;
+					lr->buffer_size = left;
+					return lr->buffer;
+				}
+				else
+					return 0x0; /* we are done! */
+			}
+		}
+		else
+		{
+			if(lr->buffer[lr->buffer_pos] == '\n' || lr->buffer[lr->buffer_pos] == '\r')
+			{
+				/* line found */
+				lr->buffer[lr->buffer_pos] = 0;
+				lr->buffer_pos++;
+				return &lr->buffer[line_start];
+			}
+			else
+				lr->buffer_pos++;
+		}
+	}
+}