- implemented multi-line response in AsconStdHandler

This commit is contained in:
zolliker
2009-11-10 07:47:32 +00:00
parent b136700f39
commit b8a0936b99
3 changed files with 75 additions and 34 deletions

74
ascon.c
View File

@ -415,55 +415,70 @@ int AsconStdHandler(Ascon * a)
{
int result;
char chr;
int ret;
int ret, l;
char *cmd, *opt;
switch (a->state) {
case AsconWriteStart:
if (strstr(GetCharArray(a->wrBuffer), "@@NOSEND@@") != NULL) {
cmd = GetCharArray(a->wrBuffer);
a->lineCount = 1;
if (a->separator != NULL) { /* multiline mode enabled */
l = strlen(cmd);
if (l> 0 && cmd[l-1] == '}') {
opt = strrchr(cmd, '{');
if (opt != NULL) {
if (sscanf(opt, "{%d}", &a->lineCount) == 1) {
/* remove option */
for (l = strlen(opt); l > 0; l--) {
DynStringBackspace(a->wrBuffer);
}
}
}
}
} else if (strstr(GetCharArray(a->wrBuffer), "@@NOSEND@@") != NULL) {
a->state = AsconWriteDone;
return 1;
}
break; /* go to the base handler */
case AsconWriting:
if (a->readState) { /* last char was CR */
ret = AsconReadChar(a->fd, &chr);
if (ret > 0) {
if (chr == '\n') {
/* swallow LF after CR */
a->readState = 0;
} else {
/* garbage character found -> swallow */
}
}
}
break; /* go to the base handler */
case AsconReading:
if (a->lineCount == 0) {
/* no response expected */
a->state = AsconReadDone;
return 1;
}
result = AsconBaseHandler(a);
if (result == 0)
return 0;
chr = a->lastChar;
if (a->replyTerminator != NULL) {
if (strchr(a->replyTerminator, chr) != NULL) {
DynStringConcatChar(a->rdBuffer, '\0');
a->state = AsconReadDone;
if (chr == '\n' || chr == '\r') {
DynStringBackspace(a->rdBuffer); /* remove LF or CR */
}
}
} else {
if (chr == '\n') {
if (chr == '\n') { /* LF */
DynStringBackspace(a->rdBuffer); /* remove LF */
if (a->readState) { /* last char was CR */
/* swallow LF after CR */
/* LF after CR is not a terminator */
a->readState = 0;
} else {
DynStringBackspace(a->rdBuffer); /* remove LF */
DynStringConcatChar(a->rdBuffer, '\0');
a->state = AsconReadDone;
}
} else if (chr == '\r') {
a->readState = 1; /* set 'last char was CR' */
} else if (chr == '\r') { /* CR */
DynStringBackspace(a->rdBuffer); /* remove CR */
DynStringConcatChar(a->rdBuffer, '\0');
a->readState = 1; /* set 'last char was CR' */
a->state = AsconReadDone;
}
}
if (a->state == AsconReadDone && a->lineCount > 1) {
if (a->separator != NULL) {
DynStringConcat(a->rdBuffer, a->separator);
}
a->lineCount--;
a->state = AsconReading;
}
return 1; /* base handler was already called */
default:
break;
@ -488,6 +503,10 @@ int AsconStdInit(Ascon *a, SConnection *con, int argc, char *argv[])
if (argc > 4 && argv[4][0] != '\0') {
a->replyTerminator = strdup(argv[4]);
}
a->separator = NULL;
if (argc > 5 && argv[5][0] != '\0') {
a->separator = strdup(argv[5]);
}
return 1;
}
@ -516,6 +535,8 @@ Ascon *AsconMake(SConnection * con, int argc, char *argv[])
a->sendTerminator = NULL;
a->hostport = NULL;
a->responseValid = 0;
a->readState = 0;
a->lineCount = 1;
a->handler = AsconSetHandler(a, con, argc, argv);
if (a->handler == NULL) {
@ -545,12 +566,15 @@ void AsconKill(Ascon * a)
if (a->hostport) {
free(a->hostport);
}
if(a->sendTerminator){
if (a->sendTerminator) {
free(a->sendTerminator);
}
if(a->replyTerminator){
if (a->replyTerminator) {
free(a->replyTerminator);
}
if (a->separator) {
free(a->separator);
}
if (a->private != NULL && a->killPrivate != NULL) {
a->killPrivate(a->private);
}