static int processBulkItem(redisReader *r) { redisReadTask *cur = &(r->rstack[r->ridx]); void *obj = NULL; char *p, *s; #ifdef _WIN32 long long len; #else long len; #endif unsigned long bytelen; int success = 0; p = r->buf+r->pos; s = seekNewline(p,r->len-r->pos); if (s != NULL) { p = r->buf+r->pos; bytelen = (int)(s-(r->buf+r->pos)+2); /* include \r\n */ len = readLongLong(p); if (len < 0) { /* The nil object can always be created. */ if (r->fn && r->fn->createNil) obj = r->fn->createNil(cur); else obj = (void*)REDIS_REPLY_NIL; success = 1; } else { /* Only continue when the buffer contains the entire bulk item. */ bytelen += (unsigned long)len+2; /* include \r\n */ if (r->pos+bytelen <= r->len) { if (r->fn && r->fn->createString) obj = r->fn->createString(cur,s+2,(size_t)len); else obj = (void*)REDIS_REPLY_STRING; success = 1; } } /* Proceed when obj was created. */ if (success) { if (obj == NULL) { __redisReaderSetErrorOOM(r); return REDIS_ERR; } r->pos += bytelen; /* Set reply if this is the root object. */ if (r->ridx == 0) r->reply = obj; moveToNextTask(r); return REDIS_OK; } } return REDIS_ERR; }
static char *readLine(redisReader *r, int *_len) { char *p, *s; int len; p = r->buf+r->pos; s = seekNewline(p,(r->len-r->pos)); if (s != NULL) { len = s-(r->buf+r->pos); r->pos += len+2; /* skip \r\n */ if (_len) *_len = len; return p; } return NULL; }
static int get_reply(mcContext *c, unsigned int *value ) { char msg[256] = {'\0'}; int buflen = 0; int ret = 0; do { ret = recv(c->fd, msg + buflen, sizeof( msg ) - 1 - buflen, 0); if (0 < ret) { // recv data buflen += ret; c->srtimes = 0; c->err = 0; if (seekNewline(msg, buflen)) { break; } } else if (0 == ret) { c->srtimes = c->maxsrtimes; return MEM_SYSTEM_ERROR; } else { __mcErrorErrorno(c, "read"); if ( errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK) { c->srtimes += 1; } else { // connect abnormal, please reconnect c->srtimes = c->maxsrtimes; } return MEM_SYSTEM_ERROR; } } while (1); msg[buflen] = '\0'; CHECK_REPLY(msg, "ERROR\r\n", MEM_ERROR); CHECK_REPLY(msg, "CLIENT_ERROR\r\n", MEM_CLIENT_ERROR); CHECK_REPLY(msg, "SERVER_ERROR\r\n", MEM_SERVER_ERROR); CHECK_REPLY(msg, "STORED\r\n", MEM_STORED); CHECK_REPLY(msg, "NOT_STORED\r\n", MEM_NOT_STORED); CHECK_REPLY(msg, "EXISTS\r\n", MEM_EXISTS); CHECK_REPLY(msg, "NOT_FOUND\r\n", MEM_NOT_FOUND); CHECK_REPLY(msg, "DELETED\r\n", MEM_DELETED); CHECK_REPLY(msg, "OK\r\n", MEM_OK); if (value != 0) { *value = atoi(msg); } return MEM_OK; }
static int processBulkItem(redisReader *r) { redisReadTask *cur = &(r->rstack[r->ridx]); void *obj = NULL; char *p, *s; long len; unsigned long bytelen; int success = 0; p = r->buf+r->pos; s = seekNewline(p,r->len-r->pos); if (s != NULL) { p = r->buf+r->pos; bytelen = s-(r->buf+r->pos)+2; /* include \r\n */ len = readLongLong(p); if (len < 0) { /* The nil object can always be created. */ obj = r->fn ? r->fn->createNil(cur) : (void*)REDIS_REPLY_NIL; success = 1; } else { /* Only continue when the buffer contains the entire bulk item. */ bytelen += len+2; /* include \r\n */ if (r->pos+bytelen <= r->len) { obj = r->fn ? r->fn->createString(cur,s+2,len) : (void*)REDIS_REPLY_STRING; success = 1; } } /* Proceed when obj was created. */ if (success) { r->pos += bytelen; /* Set reply if this is the root object. */ if (r->ridx == 0) r->reply = obj; moveToNextTask(r); return 0; } } return -1; }
static int getValue(const char *key, mcContext *c, void **reply) { char *start = NULL; switch (c->m_parseflag) { case 0: //prase head tag //seek \r\n start = seekNewline(c->m_recvbuf, (size_t)c->m_currpos); if (start) { /*check key*/ char *p = strstr(c->m_recvbuf, " "); if (p == NULL) { return MCCLI_ERR; } if (strncmp(p + 1, key, strlen(key)) != 0) { return MCCLI_ERR; } /*get flag*/ p = strstr(p + 1, " "); if (p == NULL) { return MCCLI_ERR; } c->m_flag = atoi(p); /*get length*/ p = strstr(p + 1, " "); if (p == NULL) { return MCCLI_ERR; } c->m_size = atoi(p); //set head parse ok c->m_parseflag = 1; //set datablock pos c->m_datapos = start - c->m_recvbuf + 2; //continue to prase datablock } else { //wait recv buffer to prase head return MCCLI_OK; } case 1: //prase datablock if (((c->m_currpos - c->m_datapos) >= c->m_size) && (seekNewline(c->m_recvbuf + c->m_datapos + c->m_size, (size_t)c->m_currpos))) { item_data *data = malloc(sizeof(item_data)); if (data == NULL) { return MCCLI_ERR; } strncpy(data->_key, key, sizeof(data->_key)); //assert key <256 data->_buffer = malloc(c->m_size); if (data->_buffer == NULL) { free(data); data = NULL; return MCCLI_ERR; } memcpy(data->_buffer, c->m_recvbuf + c->m_datapos, c->m_size); data->_flag = c->m_flag; data->_size = c->m_size; data->_buffer[data->_size] = '\0'; *reply = data; c->m_parseflag = 2; //continue to prase end tag } else { return MCCLI_OK; } case 2: //prase end tag //get the last line[="END \r\n"] of reply start = seekNewline(c->m_recvbuf + c->m_datapos + c->m_size + 2, (size_t)c->m_currpos); if (start) { c->m_parseflag = 3; } return MCCLI_OK; case 3: default: return MCCLI_ERR; break; } }