From fe2eabfc331eda2eb457c86ee845441e0fda56fa Mon Sep 17 00:00:00 2001 From: Douglas Clowes Date: Tue, 15 Jan 2008 12:19:37 +1100 Subject: [PATCH] Adjustments for handling binary protocols and multiple receive terminators r2268 | dcl | 2008-01-15 12:19:37 +1100 (Tue, 15 Jan 2008) | 2 lines --- asyncprotocol.c | 80 ++++++++++++++++++++++++++++++++----------------- asyncqueue.h | 5 ++-- 2 files changed, 56 insertions(+), 29 deletions(-) diff --git a/asyncprotocol.c b/asyncprotocol.c index 81fc4ad2..707e813b 100644 --- a/asyncprotocol.c +++ b/asyncprotocol.c @@ -24,22 +24,29 @@ int defaultSendCommand(pAsyncProtocol p, pAsyncTxn txn) { if (iRet <= 0) return iRet; if (term[state] != 0) - iRet = AsyncUnitWrite(txn->unit, term, strlen(term)); + iRet = AsyncUnitWrite(txn->unit, (void *)term, strlen(term)); return iRet; } 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; @@ -60,11 +67,7 @@ int defaultPrepareTxn(pAsyncProtocol p, pAsyncTxn txn, const char* cmd, int 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; } @@ -114,11 +117,16 @@ 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; @@ -235,20 +243,36 @@ int AsyncProtocolAction(SConnection *pCon, SicsInterp *pSics, } 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; @@ -276,12 +300,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); } @@ -292,7 +318,7 @@ pAsyncProtocol AsyncProtocolCreate(SicsInterp *pSics, const char* protocolName, pAsyncProtocol self = NULL; /* try to find an existing queue with this name */ - self = (pAsyncProtocol) FindCommandData(pServ->pSics, protocolName, "AsyncProtocol"); + self = (pAsyncProtocol) FindCommandData(pServ->pSics, (char *)protocolName, "AsyncProtocol"); if (self != NULL) { return self; } @@ -308,7 +334,7 @@ pAsyncProtocol AsyncProtocolCreate(SicsInterp *pSics, const char* protocolName, pFunc = AsyncProtocolNoAction; if (pKFunc == NULL) pKFunc = AsyncProtocolKill; - iRet = AddCommand(pSics, protocolName, pFunc, pKFunc, self); + iRet = AddCommand(pSics, (char *)protocolName, pFunc, pKFunc, self); if (!iRet ) { SICSLogWrite("AddCommand failed in AsyncProtocolCreate", eError); AsyncProtocolKill(self); @@ -320,7 +346,7 @@ pAsyncProtocol AsyncProtocolCreate(SicsInterp *pSics, const char* protocolName, self->prepareTxn = defaultPrepareTxn; self->killPrivate = defaultKillPrivate; self->sendTerminator = strdup("\r\n"); - self->replyTerminator = strdup("\r\n"); + self->replyTerminator[0] = strdup("\r\n"); return self; } diff --git a/asyncqueue.h b/asyncqueue.h index f27e16f8..e847c685 100644 --- a/asyncqueue.h +++ b/asyncqueue.h @@ -91,11 +91,12 @@ int AsyncUnitSendTxn(pAsyncUnit unit, * \param cmd_len length of data in command * \param responseHandler function to handle the response * \param context to be used by handler function - * \param resp_len maximum length to be allowed for response + * \param resp_len [in] maximum length to be allowed for response + * [out] actual length returned */ int AsyncUnitTransact(pAsyncUnit unit, const char* command, int cmd_len, - char* response, int rsp_len); + char* response, int *rsp_len); /** \brief write to the AsyncQueue file descriptor *