Browse Source

introduce linebuffer.[ch]

Olaf Rempel 11 years ago
parent
commit
b0532dd7b1
7 changed files with 105 additions and 68 deletions
  1. 1
    1
      Makefile
  2. 8
    0
      context.c
  3. 2
    2
      context.h
  4. 68
    0
      linebuffer.c
  5. 18
    0
      linebuffer.h
  6. 0
    3
      serial.c
  7. 8
    62
      statemachine.c

+ 1
- 1
Makefile View File

@@ -2,7 +2,7 @@ CFLAGS := -O2 -pipe -Wall
2 2
 
3 3
 all: zyxel-revert compress decompress cfgpatch
4 4
 
5
-zyxel-revert: event.o filedata.o logging.o context.o serial.o statemachine.o xmodem.o zyxel-revert.o
5
+zyxel-revert: event.o filedata.o linebuffer.o logging.o context.o serial.o statemachine.o xmodem.o zyxel-revert.o
6 6
 	$(CC) $(CFLAGS) $^ -o $@
7 7
 
8 8
 compress: filedata.o lzsc.o romfile.o compress.o

+ 8
- 0
context.c View File

@@ -18,8 +18,15 @@ struct context * create_context(const char *filename)
18 18
 
19 19
 	memset(ctx, 0, sizeof(struct context));
20 20
 
21
+	ctx->lbuf = create_linebuffer(256);
22
+	if (ctx->lbuf == NULL) {
23
+		free(ctx);
24
+		return NULL;
25
+	}
26
+
21 27
 	ctx->file = get_filedata(filename);
22 28
 	if (ctx->file == NULL) {
29
+		free(ctx->lbuf);
23 30
 		free(ctx);
24 31
 		return NULL;
25 32
 	}
@@ -36,6 +43,7 @@ int destroy_context(struct context *ctx)
36 43
 		ctx->dev_close(ctx);
37 44
 
38 45
 	free(ctx->file);
46
+	free(ctx->lbuf);
39 47
 	free(ctx);
40 48
 	return 0;
41 49
 }

+ 2
- 2
context.h View File

@@ -2,6 +2,7 @@
2 2
 #define _CONTEXT_H_
3 3
 
4 4
 #include "filedata.h"
5
+#include "linebuffer.h"
5 6
 #include "list.h"
6 7
 
7 8
 struct context {
@@ -21,8 +22,7 @@ struct context {
21 22
 	int state;
22 23
 
23 24
 	/* line buffer */
24
-	char linebuf[256];
25
-	int linepos;
25
+	struct linebuffer *lbuf;
26 26
 
27 27
 	/* xmodem */
28 28
 	int lastpkt;

+ 68
- 0
linebuffer.c View File

@@ -0,0 +1,68 @@
1
+#include <stdio.h>
2
+#include <stdlib.h>
3
+#include <unistd.h>
4
+#include <string.h>
5
+
6
+#include "linebuffer.h"
7
+
8
+struct linebuffer * create_linebuffer(int size)
9
+{
10
+	struct linebuffer *retval = malloc(sizeof(struct linebuffer) + size);
11
+	if (retval == NULL)
12
+		return NULL;
13
+
14
+	retval->size = size;
15
+	retval->pos = 0;
16
+	return retval;
17
+}
18
+
19
+int linebuffer_read(struct linebuffer *lbuf, int fd)
20
+{
21
+	char buf[32];
22
+	int len = read(fd, buf, sizeof(buf));
23
+	if (len <= 0)
24
+		return -1;
25
+
26
+	int i;
27
+	for (i = 0; i < len; i++) {
28
+		/* "understand" backspace */
29
+		if (buf[i] == 0x08 && lbuf->pos > 0) {
30
+			lbuf->pos--;
31
+
32
+		/* copy */
33
+		} else if (buf[i] >= ' ' || buf[i] == '\r') {
34
+			lbuf->data[lbuf->pos++] = buf[i];
35
+		}
36
+
37
+		if (lbuf->pos > lbuf->size)
38
+			return -1;
39
+	}
40
+
41
+	return 0;
42
+}
43
+
44
+char * linebuffer_get(struct linebuffer *lbuf)
45
+{
46
+	char *newline = memchr(lbuf->data, '\r', lbuf->pos);
47
+	if (newline == NULL)
48
+		return NULL;
49
+
50
+	char *retval = NULL;
51
+	*newline = '\0';
52
+
53
+	int len = newline - lbuf->data;
54
+	if (len > 0)
55
+		retval = strdup(lbuf->data);
56
+
57
+	lbuf->pos -= len +1;
58
+	memmove(lbuf->data, newline +1, lbuf->pos);
59
+
60
+	return retval;
61
+}
62
+
63
+int linebuffer_clear(struct linebuffer *lbuf)
64
+{
65
+	int oldpos = lbuf->pos;
66
+	lbuf->pos = 0;
67
+	return oldpos;
68
+}

+ 18
- 0
linebuffer.h View File

@@ -0,0 +1,18 @@
1
+#ifndef _LINEBUFFER_H_
2
+#define _LINEBUFFER_H_
3
+
4
+struct linebuffer {
5
+	int size;
6
+	int pos;
7
+
8
+	char data[0];
9
+};
10
+
11
+struct linebuffer * create_linebuffer(int size);
12
+
13
+int linebuffer_read(struct linebuffer *lbuf, int fd);
14
+char * linebuffer_get(struct linebuffer *lbuf);
15
+
16
+int linebuffer_clear(struct linebuffer *lbuf);
17
+
18
+#endif /* _LINEBUFFER_H_ */

+ 0
- 3
serial.c View File

@@ -55,9 +55,6 @@ static int setbaudrate(struct context *ctx, int baudrate)
55 55
 	cfsetispeed(&sdev->newtio, baudrate);
56 56
 	cfsetospeed(&sdev->newtio, baudrate);
57 57
 
58
-	/* flush linebuffer */
59
-	ctx->linepos = 0;
60
-
61 58
 	if (tcsetattr(ctx->fd, TCSANOW, &sdev->newtio) != 0) {
62 59
 		log_print(LOG_WARN, "open_serial(): tcsetattr()");
63 60
 		close(ctx->fd);

+ 8
- 62
statemachine.c View File

@@ -6,6 +6,7 @@
6 6
 #include <termios.h>
7 7
 
8 8
 #include "context.h"
9
+#include "linebuffer.h"
9 10
 #include "logging.h"
10 11
 #include "xmodem.h"
11 12
 
@@ -39,57 +40,6 @@ enum {
39 40
 	MSG_BAUD_LOW,
40 41
 };
41 42
 
42
-static int my_readline(int fd, struct context *ctx, char **retval)
43
-{
44
-	char *newline = memchr(ctx->linebuf, '\r', ctx->linepos);
45
-	if (newline != NULL) {
46
-		int len = newline - ctx->linebuf;
47
-		*newline = '\0';
48
-		if (len > 0)
49
-			*retval = strdup(ctx->linebuf);
50
-
51
-		ctx->linepos -= len +1;
52
-		memmove(ctx->linebuf, newline +1, ctx->linepos);
53
-
54
-		newline = memchr(ctx->linebuf, '\r', ctx->linepos);
55
-		return ((*retval != NULL) ? 1 : 0) + ((newline != NULL) ? 1 : 0);
56
-	}
57
-
58
-	char buf[32];
59
-	int len = read(fd, buf, sizeof(buf));
60
-	if (len <= 0)
61
-		return -1;
62
-
63
-	int i, numlines = 0;
64
-	for (i = 0; i < len; i++) {
65
-		/* "understand" backspace */
66
-		if (buf[i] == 0x08 && ctx->linepos > 0) {
67
-			ctx->linepos--;
68
-
69
-		/* export buffer */
70
-		} else if (buf[i] == '\r') {
71
-			if (*retval == NULL) {
72
-				ctx->linebuf[ctx->linepos] = '\0';
73
-
74
-				if (ctx->linepos > 0)
75
-					*retval = strdup(ctx->linebuf);
76
-
77
-				ctx->linepos = 0;
78
-				numlines = 1;
79
-
80
-			} else {
81
-				ctx->linebuf[ctx->linepos++] = buf[i];
82
-				numlines++;
83
-			}
84
-
85
-		/* copy */
86
-		} else if (buf[i] >= ' ') {
87
-			ctx->linebuf[ctx->linepos++] = buf[i];
88
-		}
89
-	}
90
-	return numlines;
91
-}
92
-
93 43
 int statemachine_read(int fd, void *privdata)
94 44
 {
95 45
 	struct context *ctx = (struct context *)privdata;
@@ -101,15 +51,11 @@ int statemachine_read(int fd, void *privdata)
101 51
 		return 0;
102 52
 	}
103 53
 
104
-	int numlines;
105
-	do {
106
-		char *line = NULL;
107
-		numlines = my_readline(fd, ctx, &line);
108
-		if (numlines < 0)
109
-			return -1;
54
+	if (linebuffer_read(ctx->lbuf, fd) < 0)
55
+		return -1;
110 56
 
111
-		if (line == NULL)
112
-			return 0;
57
+	char *line;
58
+	while ((line = linebuffer_get(ctx->lbuf)) != NULL) {
113 59
 
114 60
 		log_print(LOG_DEBUG, "%s: '%s'", ctx->devname, line);
115 61
 
@@ -141,7 +87,7 @@ int statemachine_read(int fd, void *privdata)
141 87
 		/* follow device to high baudrate */
142 88
 		} else if (msg == MSG_BAUD_HIGH) {
143 89
 			ctx->dev_setbaudrate(ctx, B115200);
144
-			numlines = 0;
90
+			linebuffer_clear(ctx->lbuf);
145 91
 
146 92
 			ctx->state = STATE_XMODEM;
147 93
 			write(fd, "ATLC\r\n", 6);
@@ -154,11 +100,11 @@ int statemachine_read(int fd, void *privdata)
154 100
 		/* follow device to low baudrate */
155 101
 		} else if (msg == MSG_BAUD_LOW) {
156 102
 			ctx->dev_setbaudrate(ctx, B9600);
157
-			numlines = 0;
103
+			linebuffer_clear(ctx->lbuf);
158 104
 		}
159 105
 
160 106
 		free(line);
161
-	} while (numlines > 1);
107
+	};
162 108
 
163 109
 	return 0;
164 110
 }

Loading…
Cancel
Save