progressive patching
This commit is contained in:
@ -31,16 +31,23 @@ int defaultSendCommand(pAsyncProtocol p, pAsyncTxn txn)
|
||||
int defaultHandleInput(pAsyncProtocol p, pAsyncTxn txn, int ch)
|
||||
{
|
||||
const char *term = "\r\n";
|
||||
if (p->replyTerminator)
|
||||
term = p->replyTerminator;
|
||||
if (ch == term[txn->txn_state])
|
||||
if (txn->txn_state == 0) {
|
||||
int i;
|
||||
for (i = 0; i < 10; ++i)
|
||||
if (p->replyTerminator[i] && ch == p->replyTerminator[i][0]) {
|
||||
txn->txn_state = i << 16;
|
||||
break;
|
||||
}
|
||||
}
|
||||
term = p->replyTerminator[txn->txn_state >> 16];
|
||||
if (ch == term[txn->txn_state & 0xffff])
|
||||
++txn->txn_state;
|
||||
else
|
||||
txn->txn_state = 0;
|
||||
|
||||
if (txn->inp_idx < txn->inp_len)
|
||||
txn->inp_buf[txn->inp_idx++] = ch;
|
||||
if (term[txn->txn_state] == 0) {
|
||||
if (term[txn->txn_state & 0xffff] == 0) {
|
||||
if (txn->inp_idx < txn->inp_len)
|
||||
txn->inp_buf[txn->inp_idx] = '\0';
|
||||
return AQU_POP_CMD;
|
||||
@ -64,10 +71,7 @@ int defaultPrepareTxn(pAsyncProtocol p, pAsyncTxn txn, const char *cmd,
|
||||
term = p->sendTerminator;
|
||||
state = 0;
|
||||
for (i = 0; i < cmd_len; ++i) {
|
||||
if (cmd[i] == 0x00) { /* end of transmission */
|
||||
cmd_len = i;
|
||||
break;
|
||||
} else if (cmd[i] == term[state]) {
|
||||
if (cmd[i] == term[state]) {
|
||||
++state;
|
||||
continue;
|
||||
}
|
||||
@ -100,14 +104,6 @@ int defaultPrepareTxn(pAsyncProtocol p, pAsyncTxn txn, const char *cmd,
|
||||
if (txn->inp_buf != NULL) {
|
||||
free(txn->inp_buf);
|
||||
}
|
||||
txn->inp_buf = malloc(rsp_len);
|
||||
if (txn->inp_buf == NULL) {
|
||||
SICSLogWrite("Out of memory in AsyncProtocol::defaultPrepareTxn",
|
||||
eError);
|
||||
free(txn->out_buf);
|
||||
txn->out_buf = NULL;
|
||||
return 0;
|
||||
}
|
||||
txn->inp_len = rsp_len;
|
||||
txn->inp_idx = 0;
|
||||
txn->txn_state = 0;
|
||||
@ -122,11 +118,15 @@ static void encodeTerminator(char *result, char *terminator)
|
||||
{
|
||||
if (terminator)
|
||||
while (*terminator) {
|
||||
*result++ = '0';
|
||||
*result++ = 'x';
|
||||
*result++ = hex[(*terminator >> 4) & 0xF];
|
||||
*result++ = hex[(*terminator) & 0xF];
|
||||
++terminator;
|
||||
if (*terminator <= 32 || *terminator >= 127) {
|
||||
*result++ = '0';
|
||||
*result++ = 'x';
|
||||
*result++ = hex[(*terminator >> 4) & 0xF];
|
||||
*result++ = hex[(*terminator) & 0xF];
|
||||
++terminator;
|
||||
} else {
|
||||
*result++ = *terminator++;
|
||||
}
|
||||
}
|
||||
*result = '\0';
|
||||
return;
|
||||
@ -208,7 +208,6 @@ int AsyncProtocolNoAction(SConnection * pCon, SicsInterp * pSics,
|
||||
void *pData, int argc, char *argv[])
|
||||
{
|
||||
char line[132];
|
||||
pAsyncProtocol self = (pAsyncProtocol) pData;
|
||||
snprintf(line, 132, "%s does not understand %s", argv[0], argv[1]);
|
||||
SCWrite(pCon, line, eError);
|
||||
return 0;
|
||||
@ -217,7 +216,6 @@ int AsyncProtocolNoAction(SConnection * pCon, SicsInterp * pSics,
|
||||
int AsyncProtocolAction(SConnection * pCon, SicsInterp * pSics,
|
||||
void *pData, int argc, char *argv[])
|
||||
{
|
||||
char line[132];
|
||||
pAsyncProtocol self = (pAsyncProtocol) pData;
|
||||
if (argc > 1) {
|
||||
/* handle genecic parameters like terminators */
|
||||
@ -240,18 +238,34 @@ int AsyncProtocolAction(SConnection * pCon, SicsInterp * pSics,
|
||||
return 1;
|
||||
} else if (strcasecmp(argv[1], "replyterminator") == 0) {
|
||||
if (argc > 2) {
|
||||
char *pPtr = decodeTerminator(argv[2]);
|
||||
if (pPtr) {
|
||||
if (self->replyTerminator)
|
||||
free(self->replyTerminator);
|
||||
self->replyTerminator = pPtr;
|
||||
int i;
|
||||
for (i = 0; i < 10; ++i)
|
||||
if (self->replyTerminator[i]) {
|
||||
free(self->replyTerminator[i]);
|
||||
self->replyTerminator[i] = NULL;
|
||||
}
|
||||
for (i = 0; i < 10 && i < argc - 2; ++i) {
|
||||
char* pPtr = decodeTerminator(argv[i + 2]);
|
||||
if (pPtr) {
|
||||
self->replyTerminator[i] = pPtr;
|
||||
}
|
||||
}
|
||||
SCSendOK(pCon);
|
||||
} else {
|
||||
int i;
|
||||
char term[132];
|
||||
char line[1024];
|
||||
encodeTerminator(term, self->replyTerminator);
|
||||
sprintf(line, "%s.replyTerminator = \"%s\"", argv[0], term);
|
||||
term[0] = '\0';
|
||||
sprintf(line, "%s.replyTerminator =", argv[0]);
|
||||
for (i = 0; i < 10; ++i) {
|
||||
if (self->replyTerminator[i] == NULL)
|
||||
break;
|
||||
term[0] = ' ';
|
||||
term[1] = '"';
|
||||
encodeTerminator(&term[2], self->replyTerminator[i]);
|
||||
strcat(term, "\"");
|
||||
strcat(line, term);
|
||||
}
|
||||
SCWrite(pCon, line, eValue);
|
||||
}
|
||||
return 1;
|
||||
@ -280,12 +294,14 @@ void defaultKillPrivate(pAsyncProtocol p)
|
||||
void AsyncProtocolKill(void *pData)
|
||||
{
|
||||
pAsyncProtocol self = (pAsyncProtocol) pData;
|
||||
int i;
|
||||
if (self->pDes)
|
||||
DeleteDescriptor(self->pDes);
|
||||
if (self->sendTerminator != NULL)
|
||||
free(self->sendTerminator);
|
||||
if (self->replyTerminator != NULL)
|
||||
free(self->replyTerminator);
|
||||
for (i = 0; i < 10; ++i)
|
||||
if (self->replyTerminator[i] != NULL)
|
||||
free(self->replyTerminator[i]);
|
||||
if (self->killPrivate)
|
||||
self->killPrivate(self);
|
||||
}
|
||||
@ -328,7 +344,7 @@ pAsyncProtocol AsyncProtocolCreate(SicsInterp * pSics,
|
||||
self->prepareTxn = defaultPrepareTxn;
|
||||
self->killPrivate = defaultKillPrivate;
|
||||
self->sendTerminator = strdup("\r\n");
|
||||
self->replyTerminator = strdup("\r\n");
|
||||
self->replyTerminator[0] = strdup("\r\n");
|
||||
return self;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user