Browse Source

introduce linebuffer.[ch]

master
Olaf Rempel 12 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

all: zyxel-revert compress decompress cfgpatch

zyxel-revert: event.o filedata.o logging.o context.o serial.o statemachine.o xmodem.o zyxel-revert.o
zyxel-revert: event.o filedata.o linebuffer.o logging.o context.o serial.o statemachine.o xmodem.o zyxel-revert.o
$(CC) $(CFLAGS) $^ -o $@

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)

memset(ctx, 0, sizeof(struct context));

ctx->lbuf = create_linebuffer(256);
if (ctx->lbuf == NULL) {
free(ctx);
return NULL;
}

ctx->file = get_filedata(filename);
if (ctx->file == NULL) {
free(ctx->lbuf);
free(ctx);
return NULL;
}
@@ -36,6 +43,7 @@ int destroy_context(struct context *ctx)
ctx->dev_close(ctx);

free(ctx->file);
free(ctx->lbuf);
free(ctx);
return 0;
}

+ 2
- 2
context.h View File

@@ -2,6 +2,7 @@
#define _CONTEXT_H_

#include "filedata.h"
#include "linebuffer.h"
#include "list.h"

struct context {
@@ -21,8 +22,7 @@ struct context {
int state;

/* line buffer */
char linebuf[256];
int linepos;
struct linebuffer *lbuf;

/* xmodem */
int lastpkt;

+ 68
- 0
linebuffer.c View File

@@ -0,0 +1,68 @@
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

#include "linebuffer.h"

struct linebuffer * create_linebuffer(int size)
{
struct linebuffer *retval = malloc(sizeof(struct linebuffer) + size);
if (retval == NULL)
return NULL;

retval->size = size;
retval->pos = 0;
return retval;
}

int linebuffer_read(struct linebuffer *lbuf, int fd)
{
char buf[32];
int len = read(fd, buf, sizeof(buf));
if (len <= 0)
return -1;

int i;
for (i = 0; i < len; i++) {
/* "understand" backspace */
if (buf[i] == 0x08 && lbuf->pos > 0) {
lbuf->pos--;

/* copy */
} else if (buf[i] >= ' ' || buf[i] == '\r') {
lbuf->data[lbuf->pos++] = buf[i];
}

if (lbuf->pos > lbuf->size)
return -1;
}

return 0;
}

char * linebuffer_get(struct linebuffer *lbuf)
{
char *newline = memchr(lbuf->data, '\r', lbuf->pos);
if (newline == NULL)
return NULL;

char *retval = NULL;
*newline = '\0';

int len = newline - lbuf->data;
if (len > 0)
retval = strdup(lbuf->data);

lbuf->pos -= len +1;
memmove(lbuf->data, newline +1, lbuf->pos);

return retval;
}

int linebuffer_clear(struct linebuffer *lbuf)
{
int oldpos = lbuf->pos;
lbuf->pos = 0;
return oldpos;
}

+ 18
- 0
linebuffer.h View File

@@ -0,0 +1,18 @@
#ifndef _LINEBUFFER_H_
#define _LINEBUFFER_H_

struct linebuffer {
int size;
int pos;

char data[0];
};

struct linebuffer * create_linebuffer(int size);

int linebuffer_read(struct linebuffer *lbuf, int fd);
char * linebuffer_get(struct linebuffer *lbuf);

int linebuffer_clear(struct linebuffer *lbuf);

#endif /* _LINEBUFFER_H_ */

+ 0
- 3
serial.c View File

@@ -55,9 +55,6 @@ static int setbaudrate(struct context *ctx, int baudrate)
cfsetispeed(&sdev->newtio, baudrate);
cfsetospeed(&sdev->newtio, baudrate);

/* flush linebuffer */
ctx->linepos = 0;

if (tcsetattr(ctx->fd, TCSANOW, &sdev->newtio) != 0) {
log_print(LOG_WARN, "open_serial(): tcsetattr()");
close(ctx->fd);

+ 8
- 62
statemachine.c View File

@@ -6,6 +6,7 @@
#include <termios.h>

#include "context.h"
#include "linebuffer.h"
#include "logging.h"
#include "xmodem.h"

@@ -39,57 +40,6 @@ enum {
MSG_BAUD_LOW,
};

static int my_readline(int fd, struct context *ctx, char **retval)
{
char *newline = memchr(ctx->linebuf, '\r', ctx->linepos);
if (newline != NULL) {
int len = newline - ctx->linebuf;
*newline = '\0';
if (len > 0)
*retval = strdup(ctx->linebuf);

ctx->linepos -= len +1;
memmove(ctx->linebuf, newline +1, ctx->linepos);

newline = memchr(ctx->linebuf, '\r', ctx->linepos);
return ((*retval != NULL) ? 1 : 0) + ((newline != NULL) ? 1 : 0);
}

char buf[32];
int len = read(fd, buf, sizeof(buf));
if (len <= 0)
return -1;

int i, numlines = 0;
for (i = 0; i < len; i++) {
/* "understand" backspace */
if (buf[i] == 0x08 && ctx->linepos > 0) {
ctx->linepos--;

/* export buffer */
} else if (buf[i] == '\r') {
if (*retval == NULL) {
ctx->linebuf[ctx->linepos] = '\0';

if (ctx->linepos > 0)
*retval = strdup(ctx->linebuf);

ctx->linepos = 0;
numlines = 1;

} else {
ctx->linebuf[ctx->linepos++] = buf[i];
numlines++;
}

/* copy */
} else if (buf[i] >= ' ') {
ctx->linebuf[ctx->linepos++] = buf[i];
}
}
return numlines;
}

int statemachine_read(int fd, void *privdata)
{
struct context *ctx = (struct context *)privdata;
@@ -101,15 +51,11 @@ int statemachine_read(int fd, void *privdata)
return 0;
}

int numlines;
do {
char *line = NULL;
numlines = my_readline(fd, ctx, &line);
if (numlines < 0)
return -1;
if (linebuffer_read(ctx->lbuf, fd) < 0)
return -1;

if (line == NULL)
return 0;
char *line;
while ((line = linebuffer_get(ctx->lbuf)) != NULL) {

log_print(LOG_DEBUG, "%s: '%s'", ctx->devname, line);

@@ -141,7 +87,7 @@ int statemachine_read(int fd, void *privdata)
/* follow device to high baudrate */
} else if (msg == MSG_BAUD_HIGH) {
ctx->dev_setbaudrate(ctx, B115200);
numlines = 0;
linebuffer_clear(ctx->lbuf);

ctx->state = STATE_XMODEM;
write(fd, "ATLC\r\n", 6);
@@ -154,11 +100,11 @@ int statemachine_read(int fd, void *privdata)
/* follow device to low baudrate */
} else if (msg == MSG_BAUD_LOW) {
ctx->dev_setbaudrate(ctx, B9600);
numlines = 0;
linebuffer_clear(ctx->lbuf);
}

free(line);
} while (numlines > 1);
};

return 0;
}

Loading…
Cancel
Save