multichan becomes AsyncQueue and AsyncProtocol
r1957 | dcl | 2007-05-11 17:28:31 +1000 (Fri, 11 May 2007) | 2 lines
This commit is contained in:
154
asyncprotocol.c
Normal file
154
asyncprotocol.c
Normal file
@@ -0,0 +1,154 @@
|
||||
#include <sics.h>
|
||||
#include <asyncprotocol.h>
|
||||
#include <asyncqueue.h>
|
||||
|
||||
int defaultSendCommand(pAsyncProtocol p, pAsyncTxn txn) {
|
||||
txn->txn_state = 0;
|
||||
/* TODO: anything? */
|
||||
return AsyncUnitWrite(txn->unit, txn->out_buf, txn->out_len);
|
||||
}
|
||||
|
||||
int defaultHandleInput(pAsyncProtocol p, pAsyncTxn txn, int ch) {
|
||||
/* TODO: generic terminators */
|
||||
char term[] = { 0x0D, 0x0A, 0x00 };
|
||||
if (ch == term[txn->txn_state])
|
||||
++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 (txn->inp_idx < txn->inp_len)
|
||||
txn->inp_buf[txn->inp_idx] = '\0';
|
||||
return AQU_POP_CMD;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int defaultHandleEvent(pAsyncProtocol p, pAsyncTxn txn, int event) {
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
int defaultPrepareTxn(pAsyncProtocol p, pAsyncTxn txn, const char* cmd, int cmd_len, int rsp_len) {
|
||||
/* TODO: generic terminators */
|
||||
char term[] = { 0x0D, 0x0A, 0x00 };
|
||||
int i;
|
||||
int state;
|
||||
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]) {
|
||||
++state;
|
||||
continue;
|
||||
}
|
||||
state = 0;
|
||||
}
|
||||
if (term[state] == 0) {
|
||||
txn->out_buf = malloc(cmd_len + 1);
|
||||
memcpy(txn->out_buf, cmd, cmd_len + 1);
|
||||
}
|
||||
else {
|
||||
int tlen = strlen(term);
|
||||
txn->out_buf = malloc(cmd_len + tlen + 1);
|
||||
memcpy(txn->out_buf, cmd, cmd_len);
|
||||
memcpy(txn->out_buf + cmd_len, term, tlen + 1);
|
||||
cmd_len += tlen;
|
||||
}
|
||||
txn->out_len = cmd_len;
|
||||
txn->out_idx = 0;
|
||||
txn->inp_buf = malloc(rsp_len);
|
||||
txn->inp_len = rsp_len;
|
||||
txn->inp_idx = 0;
|
||||
txn->txn_state = 0;
|
||||
txn->txn_status = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int AsyncProtocolNoAction(SConnection *pCon, SicsInterp *pSics,
|
||||
void *pData, int argc, char *argv[])
|
||||
{
|
||||
char line[132];
|
||||
pAsyncProtocol self = (pAsyncProtocol) pData;
|
||||
if (argc > 1) {
|
||||
/* TODO: handle parameters like terminators */
|
||||
}
|
||||
snprintf(line, 132, "%s does not understand %s", argv[0], argv[1]);
|
||||
SCWrite(pCon, line, eError);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int AsyncProtocolAction(SConnection *pCon, SicsInterp *pSics,
|
||||
void *pData, int argc, char *argv[])
|
||||
{
|
||||
char line[132];
|
||||
pAsyncProtocol self = (pAsyncProtocol) pData;
|
||||
/* TODO: terminators */
|
||||
snprintf(line, 132, "%s does not understand %s", argv[0], argv[1]);
|
||||
SCWrite(pCon, line, eError);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void defaultKillPrivate(pAsyncProtocol p) {
|
||||
/* TODO: anything? */
|
||||
}
|
||||
|
||||
void AsyncProtocolKill(void *pData) {
|
||||
pAsyncProtocol self = (pAsyncProtocol) pData;
|
||||
DeleteDescriptor(self->pDes);
|
||||
/* TODO: more destruction maybe */
|
||||
if (self->killPrivate)
|
||||
self->killPrivate(self);
|
||||
}
|
||||
|
||||
pAsyncProtocol AsyncProtocolCreate(SicsInterp *pSics, const char* protocolName,
|
||||
ObjectFunc pFunc, KillFunc pKFunc) {
|
||||
int iRet;
|
||||
pAsyncProtocol self = NULL;
|
||||
|
||||
/* try to find an existing queue with this name */
|
||||
self = (pAsyncProtocol) FindCommandData(pServ->pSics, protocolName, "AsyncProtocol");
|
||||
if (self != NULL) {
|
||||
return self;
|
||||
}
|
||||
|
||||
self = (pAsyncProtocol) malloc(sizeof(AsyncProtocol));
|
||||
if (self == NULL) {
|
||||
/* TODO */
|
||||
return NULL;
|
||||
}
|
||||
memset(self, 0, sizeof(AsyncProtocol));
|
||||
self->pDes = CreateDescriptor("AsyncProtocol");
|
||||
if (pFunc == NULL)
|
||||
pFunc = AsyncProtocolNoAction;
|
||||
if (pKFunc == NULL)
|
||||
pKFunc = AsyncProtocolKill;
|
||||
iRet = AddCommand(pSics, protocolName, pFunc, pKFunc, self);
|
||||
if (!iRet ) {
|
||||
/* TODO */
|
||||
AsyncProtocolKill(self);
|
||||
return NULL;
|
||||
}
|
||||
self->sendCommand = defaultSendCommand;
|
||||
self->handleInput = defaultHandleInput;
|
||||
self->handleEvent = defaultHandleEvent;
|
||||
self->prepareTxn = defaultPrepareTxn;
|
||||
self->killPrivate = defaultKillPrivate;
|
||||
return self;
|
||||
}
|
||||
|
||||
int AsyncProtocolFactory(SConnection *pCon, SicsInterp *pSics,
|
||||
void *pData, int argc, char *argv[]) {
|
||||
if (argc < 2) {
|
||||
SCWrite(pCon,"ERROR: insufficient arguments to AsyncProtocolFactory", eError);
|
||||
return 0;
|
||||
}
|
||||
pAsyncProtocol pNew = AsyncProtocolCreate(pSics, argv[1],
|
||||
AsyncProtocolAction, AsyncProtocolKill);
|
||||
/* TODO: handle arguments */
|
||||
pNew->privateData = NULL;
|
||||
return 1;
|
||||
}
|
||||
Reference in New Issue
Block a user