예제 #1
0
char *redisProtocolToLuaType_Int(lua_State *lua, char *reply) {
    char *p = strchr(reply+1,'\r');
    long long value;

    string2ll(reply+1,p-reply-1,&value);
    lua_pushnumber(lua,(lua_Number)value);
    return p+2;
}
예제 #2
0
파일: object.c 프로젝트: rampage/redis
int isObjectRepresentableAsLongLong(robj *o, long long *llval) {
    redisAssert(o->type == REDIS_STRING);
    if (o->encoding == REDIS_ENCODING_INT) {
        if (llval) *llval = (long) o->ptr;
        return REDIS_OK;
    } else {
        return string2ll(o->ptr,sdslen(o->ptr),llval) ? REDIS_OK : REDIS_ERR;
    }
}
예제 #3
0
int isObjectRepresentableAsLongLong(robj *o, long long *llval) {
    serverAssertWithInfo(NULL,o,o->type == OBJ_STRING);
    if (o->encoding == OBJ_ENCODING_INT) {
        if (llval) *llval = (long) o->ptr;
        return C_OK;
    } else {
        return string2ll(o->ptr,sdslen(o->ptr),llval) ? C_OK : C_ERR;
    }
}
예제 #4
0
//判断对象的ptr指向的值能否转换为long long类型,如果可以保存在llval中
int isObjectRepresentableAsLongLong(robj *o, long long *llval) {
    serverAssertWithInfo(NULL,o,o->type == OBJ_STRING);
    if (o->encoding == OBJ_ENCODING_INT) {      //如果本身就是整数
        if (llval) *llval = (long) o->ptr;
        return C_OK;                            //成功返回0
    } else {
        //字符串转换为longlong类型,成功返回0,失败返回-1
        return string2ll(o->ptr,sdslen(o->ptr),llval) ? C_OK : C_ERR;
    }
}
예제 #5
0
/* Convert a string into a long. Returns 1 if the string could be parsed into a
 * (non-overflowing) long, 0 otherwise. The value will be set to the parsed
 * value when appropriate. */
int string2l(const char *s, size_t slen, long *lval) {
    long long llval;

    if (!string2ll(s,slen,&llval))
        return 0;

    if (llval < LONG_MIN || llval > LONG_MAX)
        return 0;

    *lval = (long)llval;
    return 1;
}
예제 #6
0
파일: util.c 프로젝트: bugou/test
/* Convert a string into a long. Returns 1 if the string could be parsed into a
 * (non-overflowing) long, 0 otherwise. The value will be set to the parsed
 * value when appropriate. */
int string2l(const char *s, size_t slen, PORT_LONG *lval) {
    PORT_LONGLONG llval;

    if (!string2ll(s,slen,&llval))
        return 0;

    if (llval < PORT_LONG_MIN || llval > PORT_LONG_MAX)
        return 0;

    *lval = (PORT_LONG) llval;
    return 1;
}
예제 #7
0
char *redisProtocolToLuaType_Bulk(lua_State *lua, char *reply) {
    char *p = strchr(reply+1,'\r');
    long long bulklen;

    string2ll(reply+1,p-reply-1,&bulklen);
    if (bulklen == -1) {
        lua_pushboolean(lua,0);
        return p+2;
    } else {
        lua_pushlstring(lua,p+2,bulklen);
        return p+2+bulklen+2;
    }
}
int isObjectRepresentableAsLongLong(robj *o, long long *llval) {

    redisAssertWithInfo(NULL,o,o->type == REDIS_STRING);

    // INT 编码的 long 值总是能保存为 long long
    if (o->encoding == REDIS_ENCODING_INT) {
        if (llval) *llval = (long) o->ptr;
        return REDIS_OK;

    // 如果是字符串的话,那么尝试将它转换为 long long
    } else {
        return string2ll(o->ptr,sdslen(o->ptr),llval) ? REDIS_OK : REDIS_ERR;
    }
}
예제 #9
0
int getLongLongFromObject(robj *o, long long *target) {
    long long value;

    if (o == NULL) {
        value = 0;
    } else {
        serverAssertWithInfo(NULL,o,o->type == OBJ_STRING);
        if (sdsEncodedObject(o)) {
            if (string2ll(o->ptr,sdslen(o->ptr),&value) == 0) return C_ERR;
        } else if (o->encoding == OBJ_ENCODING_INT) {
            value = (long)o->ptr;
        } else {
            serverPanic("Unknown string encoding");
        }
    }
    if (target) *target = value;
    return C_OK;
}
예제 #10
0
char *redisProtocolToLuaType_MultiBulk(lua_State *lua, char *reply) {
    char *p = strchr(reply+1,'\r');
    long long mbulklen;
    int j = 0;

    string2ll(reply+1,p-reply-1,&mbulklen);
    p += 2;
    if (mbulklen == -1) {
        lua_pushboolean(lua,0);
        return p;
    }
    lua_newtable(lua);
    for (j = 0; j < mbulklen; j++) {
        lua_pushnumber(lua,j+1);
        p = redisProtocolToLuaType(lua,p);
        lua_settable(lua,-3);
    }
    return p;
}
예제 #11
0
//从对象中将字符串值转换为long long并存储在target中
int getLongLongFromObject(robj *o, long long *target) {
    long long value;

    if (o == NULL) {    //对象不存在
        value = 0;
    } else {
        serverAssertWithInfo(NULL,o,o->type == OBJ_STRING);

         //如果是字符串编码的两种类型
        if (sdsEncodedObject(o)) {
             //转换失败发送-1,成功保存值到value中
            if (string2ll(o->ptr,sdslen(o->ptr),&value) == 0) return C_ERR;
        } else if (o->encoding == OBJ_ENCODING_INT) {   //整型编码
            value = (long)o->ptr;                       //保存整数值
        } else {
            serverPanic("Unknown string encoding");
        }
    }
    if (target) *target = value;        //将值存到传入参数中,返回0成功
    return C_OK;
}
예제 #12
0
static int
processMultiBulk (client_t * c)
{
  char *newline = NULL;
  int pos = 0, ok;
  long long ll;

  if (c->multibulklen == 0)
    {
      newline = strchr (c->querybuf, '\r');
      if (newline == NULL)
	{
	  if (sdslen (c->querybuf) > REDIS_INLINE_MAX_SIZE)
	    {
	      addReplyStr (c,
			   "-ERR Protocol error: too big mbulk count string\r\n");
	      c->flags |= REDIS_CLOSE_AFTER_REPLY;
	    }
	  return -1;
	}
      if (newline - c->querybuf > sdslen (c->querybuf) - 2)
	return -1;

      ok = string2ll (c->querybuf + 1, newline - (c->querybuf + 1), &ll);
      if (!ok || ll > 1024 * 1024)
	{
	  addReplyStr (c,
		       "-ERR Protocol error: invalid multibulk length\r\n");
	  c->flags |= REDIS_CLOSE_AFTER_REPLY;
	  return -1;
	}
      c->multibulklen = ll;
      c->argv = malloc (sizeof (sds) * c->multibulklen);
      c->argvlen = malloc (sizeof (size_t) * c->multibulklen);
      pos = (newline - c->querybuf) + 2;
      if (ll <= 0)
	{
	  sdsrange (c->querybuf, pos, -1);
	  return 0;
	}
    }

  while (c->multibulklen)
    {
      if (c->bulklen == -1)
	{
	  newline = strchr (c->querybuf + pos, '\r');
	  if (newline == NULL)
	    {
	      if (sdslen (c->querybuf) > REDIS_INLINE_MAX_SIZE)
		{
		  addReplyStr (c,
			       "-ERR Protocol error: too big bulk count string\r\n");
		  c->flags |= REDIS_CLOSE_AFTER_REPLY;
		}
	      break;
	    }
	  if (newline - (c->querybuf) > (sdslen (c->querybuf) - 2))
	    break;

	  if (c->querybuf[pos] != '$')
	    {
	      addReplyStr (c, "-ERR Protocol error: expected '$', got '");
	      addReplyStrLen (c, c->querybuf + pos, 1);
	      addReplyStr (c, "'\r\n");
	      c->flags |= REDIS_CLOSE_AFTER_REPLY;
	      return -1;
	    }

	  ok =
	    string2ll (c->querybuf + pos + 1,
		       newline - (c->querybuf + pos + 1), &ll);
	  if (!ok || ll < 0 || ll > 512 * 1024 * 1024)
	    {
	      addReplyStr (c, "-ERR Protocol error: invalid bulk length\r\n");
	      c->flags |= REDIS_CLOSE_AFTER_REPLY;
	      return -1;
	    }

	  pos += newline - (c->querybuf + pos) + 2;
	  c->bulklen = ll;
	}

      if (sdslen (c->querybuf) - pos < (unsigned) (c->bulklen + 2))
	break;
      c->argvlen[c->argc] = c->bulklen;
      c->argv[c->argc++] = sdsnewlen (c->querybuf + pos, c->bulklen);
      pos += c->bulklen + 2;
      c->bulklen = -1;
      c->multibulklen--;
    }

  if (pos)
    sdsrange (c->querybuf, pos, -1);
  if (c->multibulklen)
    return -1;

  if (c->argc == 1 && sdslen (c->argv[0]) == 4
      && !strcasecmp (c->argv[0], "quit"))
    {
      addReplyStrLen (c, "+OK\r\n", 5);
      c->flags |= REDIS_CLOSE_AFTER_REPLY;
      return -1;
    }
  arc_append_commandcv (c->rqst, c->argc, (const char **) c->argv,
			c->argvlen);
  c->total_append_command++;
  return 0;
}
예제 #13
0
파일: robj.c 프로젝트: ncloudioj/rhino-rox
int isSdsRepresentableAsLongLong(sds s, long long *llval) {
    return string2ll(s,sdslen(s),llval) ? RR_OK : RR_ERROR;
}
예제 #14
0
void test_string2ll(void) {
    char buf[32];
    long long v;

    /* May not start with +. */
    strcpy(buf,"+1");
    assert(string2ll(buf,strlen(buf),&v) == 0);

    /* Leading space. */
    strcpy(buf," 1");
    assert(string2ll(buf,strlen(buf),&v) == 0);

    /* Trailing space. */
    strcpy(buf,"1 ");
    assert(string2ll(buf,strlen(buf),&v) == 0);

    /* May not start with 0. */
    strcpy(buf,"01");
    assert(string2ll(buf,strlen(buf),&v) == 0);

    strcpy(buf,"-1");
    assert(string2ll(buf,strlen(buf),&v) == 1);
    assert(v == -1);

    strcpy(buf,"0");
    assert(string2ll(buf,strlen(buf),&v) == 1);
    assert(v == 0);

    strcpy(buf,"1");
    assert(string2ll(buf,strlen(buf),&v) == 1);
    assert(v == 1);

    strcpy(buf,"99");
    assert(string2ll(buf,strlen(buf),&v) == 1);
    assert(v == 99);

    strcpy(buf,"-99");
    assert(string2ll(buf,strlen(buf),&v) == 1);
    assert(v == -99);

    strcpy(buf,"-9223372036854775808");
    assert(string2ll(buf,strlen(buf),&v) == 1);
    assert(v == LLONG_MIN);

    strcpy(buf,"-9223372036854775809"); /* overflow */
    assert(string2ll(buf,strlen(buf),&v) == 0);

    strcpy(buf,"9223372036854775807");
    assert(string2ll(buf,strlen(buf),&v) == 1);
    assert(v == LLONG_MAX);

    strcpy(buf,"9223372036854775808"); /* overflow */
    assert(string2ll(buf,strlen(buf),&v) == 0);
}
예제 #15
0
int processMultibulkBuffer(client *c) {
    char *newline = NULL;
    int pos = 0, ok;
    long long ll;

    if (c->multibulklen == 0) {
        /* The client should have been reset */
        serverAssertWithInfo(c,NULL,c->argc == 0);

        /* Multi bulk length cannot be read without a \r\n */
        newline = strchr(c->querybuf,'\r');
        if (newline == NULL) {
            if (sdslen(c->querybuf) > PROTO_INLINE_MAX_SIZE) {
                addReplyError(c,"Protocol error: too big mbulk count string");
                setProtocolError(c,0);
            }
            return C_ERR;
        }

        /* Buffer should also contain \n */
        if (newline-(c->querybuf) > ((signed)sdslen(c->querybuf)-2))
            return C_ERR;

        /* We know for sure there is a whole line since newline != NULL,
         * so go ahead and find out the multi bulk length. */
        serverAssertWithInfo(c,NULL,c->querybuf[0] == '*');
        ok = string2ll(c->querybuf+1,newline-(c->querybuf+1),&ll);
        if (!ok || ll > 1024*1024) {
            addReplyError(c,"Protocol error: invalid multibulk length");
            setProtocolError(c,pos);
            return C_ERR;
        }

        pos = (newline-c->querybuf)+2;
        if (ll <= 0) {
            sdsrange(c->querybuf,pos,-1);
            return C_OK;
        }

        c->multibulklen = ll;

        /* Setup argv array on client structure */
        if (c->argv) free(c->argv);
        c->argv = malloc(sizeof(sds*)*c->multibulklen);
    }

    serverAssertWithInfo(c,NULL,c->multibulklen > 0);
    while(c->multibulklen) {
        /* Read bulk length if unknown */
        if (c->bulklen == -1) {
            newline = strchr(c->querybuf+pos,'\r');
            if (newline == NULL) {
                if (sdslen(c->querybuf) > PROTO_INLINE_MAX_SIZE) {
                    addReplyError(c,
                        "Protocol error: too big bulk count string");
                    setProtocolError(c,0);
                    return C_ERR;
                }
                break;
            }

            /* Buffer should also contain \n */
            if (newline-(c->querybuf) > ((signed)sdslen(c->querybuf)-2))
                break;

            if (c->querybuf[pos] != '$') {
                addReplyErrorFormat(c,
                    "Protocol error: expected '$', got '%c'",
                    c->querybuf[pos]);
                setProtocolError(c,pos);
                return C_ERR;
            }

            ok = string2ll(c->querybuf+pos+1,newline-(c->querybuf+pos+1),&ll);
            if (!ok || ll < 0 || ll > 512*1024*1024) {
                addReplyError(c,"Protocol error: invalid bulk length");
                setProtocolError(c,pos);
                return C_ERR;
            }

            pos += newline-(c->querybuf+pos)+2;
            if (ll >= PROTO_MBULK_BIG_ARG) {
                size_t qblen;

                /* If we are going to read a large object from network
                 * try to make it likely that it will start at c->querybuf
                 * boundary so that we can optimize object creation
                 * avoiding a large copy of data. */
                sdsrange(c->querybuf,pos,-1);
                pos = 0;
                qblen = sdslen(c->querybuf);
                /* Hint the sds library about the amount of bytes this string is
                 * going to contain. */
                if (qblen < (size_t)ll+2)
                    c->querybuf = sdsMakeRoomFor(c->querybuf,ll+2-qblen);
            }
            c->bulklen = ll;
        }

        /* Read bulk argument */
        if (sdslen(c->querybuf)-pos < (unsigned)(c->bulklen+2)) {
            /* Not enough data (+2 == trailing \r\n) */
            break;
        } else {
            /* Optimization: if the buffer contains JUST our bulk element
             * instead of creating a new object by *copying* the sds we
             * just use the current sds string. */
            if (pos == 0 &&
                c->bulklen >= PROTO_MBULK_BIG_ARG &&
                (signed) sdslen(c->querybuf) == c->bulklen+2)
            {
                c->argv[c->argc++] = c->querybuf;
                sdsIncrLen(c->querybuf,-2); /* remove CRLF */
                c->querybuf = sdsempty();
                /* Assume that if we saw a fat argument we'll see another one
                 * likely... */
                c->querybuf = sdsMakeRoomFor(c->querybuf,c->bulklen+2);
                pos = 0;
            } else {
                c->argv[c->argc++] = sdsnewlen(c->querybuf+pos,c->bulklen);
                pos += c->bulklen+2;
            }
            c->bulklen = -1;
            c->multibulklen--;
        }
    }

    /* Trim to pos */
    if (pos) sdsrange(c->querybuf,pos,-1);

    /* We're done when c->multibulk == 0 */
    if (c->multibulklen == 0) return C_OK;

    /* Still not read to process the command */
    return C_ERR;
}
예제 #16
0
static int process_multibulk_buffer(sub_client *c)
{
    char *newline = NULL;
    int pos = 0, ok;
    long long ll;

    if (c->multi_bulk_len == 0) {
        /* Multi bulk length cannot be read without a \r\n */
        newline = strchr(c->read_buf, '\r');
        if (newline == NULL) {
            if (sdslen(c->read_buf) > MAX_INLINE_READ) {
                srv_log(LOG_ERROR, "protocol error: too big mbulk string");
                set_protocol_err(c, 0);
            }
            return SUBCLI_ERR;
        }

        /* Buffer should also contain \n */
        if (newline-(c->read_buf) > ((signed)sdslen(c->read_buf)-2)) {
            return SUBCLI_ERR;
        }

        ok = string2ll(c->read_buf+1, newline-(c->read_buf+1), &ll);
        if (!ok || ll > SUB_READ_BUF_LEN) {
            srv_log(LOG_ERROR, "protocol error: invalid multibulk length");
            set_protocol_err(c, pos);
            return SUBCLI_ERR;
        }

        pos = (newline - c->read_buf) + 2;
        if (ll <= 0) {
            sdsrange(c->read_buf, pos, -1);
            return SUBCLI_OK;
        }

        c->multi_bulk_len = ll;
        c->argv = malloc(sizeof(sds) * c->multi_bulk_len);
    }

    while (c->multi_bulk_len) {
        /* Read bulk length if unknown */
        if (c->bulk_len == -1) {
            newline = strchr(c->read_buf + pos, '\r');
            if (newline == NULL) {
                if (sdslen(c->read_buf) > MAX_INLINE_READ) {
                    srv_log(LOG_ERROR, "protocol error: too big bulk count string");
                    set_protocol_err(c, 0);
                    return SUBCLI_ERR;
                }
                break;
            }

            /* Buffer should also contain \n */
            if (newline-(c->read_buf) > ((signed)sdslen(c->read_buf)-2)) {
                break;
            }

            if (c->read_buf[pos] != '$') {
                srv_log(LOG_ERROR, "Protocol error: expected '$', got '%c'",
                        c->read_buf[pos]);
                set_protocol_err(c, pos);
                return SUBCLI_ERR;
            }

            ok = string2ll(c->read_buf+pos+1, newline-(c->read_buf+pos+1), &ll);
            if (!ok || ll < 0 || ll > MAX_BULK_LEN) {
                srv_log(LOG_ERROR, "Protocol error: invalid bulk length");
                set_protocol_err(c, pos);
                return SUBCLI_ERR;
            }

            pos += newline - (c->read_buf + pos) + 2;
            c->bulk_len = ll;
        }

        /* Read bulk argument */
        if (sdslen(c->read_buf) - pos < (unsigned)(c->bulk_len + 2)) {
            /* Not enough data (+2 == trailing \r\n) */
            break;
        } else {
            /*c->argv[c->argc++] = create_string_obj(c->read_buf+pos, c->bulk_len);*/
            c->argv[c->argc++] = sdsnewlen(c->read_buf+pos, c->bulk_len);
            pos += c->bulk_len + 2;
        }
        c->bulk_len = -1;
        c->multi_bulk_len--;
    }

    /* Trim to pos */
    if (pos) sdsrange(c->read_buf, pos, -1);

    /* We're done when c->multibulk == 0 */
    if (c->multi_bulk_len == 0) return SUBCLI_OK;

    /* Still not read to process the command */
    return SUBCLI_ERR;
}
예제 #17
0
int
parse_redis_response (char *p, int len, int *size, redis_parse_cb_t * cb,
		      void *ctx)
{
  char *newline = NULL, *bp = NULL;
  int ok = 0;
  long long ll = 0;
  int ret = PARSE_CB_OK_CONTINUE;


  if (len == 0)
    {
      return -1;
    }

  /* Input should be null terminiated string */
  assert (*(p + len) == '\0');

  bp = p;
  while (ret == PARSE_CB_OK_CONTINUE && len > 0)
    {
      char *saved_p;
      char *dsp = NULL;		// binary data start point
      char *dep = NULL;		// binary data end point
      int is_null = 0;

      saved_p = p;
      switch (*p)
	{
	case '-':
	case '+':
	case ':':
	  newline = strchr (p, '\n');
	  if (newline == NULL)
	    {
	      goto resp_need_more;
	    }

	  len -= newline + 1 - p;
	  p = newline + 1;
	  /* callback */
	  if (cb != NULL)
	    {
	      dsp = saved_p;
	      dep = p - 2;	// skip \r\n

	      if (*saved_p == '-')
		{
		  ret = cb->on_error (ctx, dsp, dep - dsp);
		}
	      else if (*saved_p == '+')
		{
		  ret = cb->on_status (ctx, dsp, dep - dsp);
		}
	      else if (*saved_p == ':')
		{
		  ok = string2ll (dsp + 1, dep - dsp - 1, &ll);
		  if (!ok)
		    {
		      return -1;
		    }
		  ret = cb->on_integer (ctx, ll);
		}
	    }
	  break;
	case '$':
	  newline = strchr (p, '\r');
	  if (newline == NULL)
	    {
	      goto resp_need_more;
	    }

	  ok = string2ll (p + 1, newline - p - 1, &ll);

	  /* spec limit: 512M */
	  if (!ok || ll < -1 || ll > 512 * 1024 * 1024)
	    {
	      return -1;
	    }

	  if (ll == -1)
	    {
	      /* Null Bulk String */
	      if (newline + 2 - p > len)
		{
		  goto resp_need_more;
		}
	      len -= newline + 2 - p;
	      p = newline + 2;
	      is_null = 1;
	      /* callback */
	      if (cb != NULL)
		{
		  ret = cb->on_string (ctx, NULL, 0, is_null);
		}
	    }
	  else
	    {
	      /* Normal Case */
	      if (newline + 2 - p + ll + 2 > len)
		{
		  goto resp_need_more;
		}
	      len -= newline + 2 - p + ll + 2;
	      p = newline + 2 + ll + 2;
	      /* callback */
	      if (cb != NULL)
		{
		  ret = cb->on_string (ctx, newline + 2, ll, is_null);
		}
	    }
	  break;
	case '*':
	  newline = strchr (p, '\r');
	  if (newline == NULL || newline + 2 - p > len)
	    {
	      goto resp_need_more;
	    }

	  ok = string2ll (p + 1, newline - p - 1, &ll);

	  if (ll == -1)
	    {
	      is_null = 1;
	      ll = 0;		/* Null Array */
	    }

	  len -= newline + 2 - p;
	  p = newline + 2;
	  /* callback */
	  if (cb != NULL)
	    {
	      ret = cb->on_array (ctx, ll, is_null);
	    }
	  break;
	default:
	  return -1;
	}
    }

resp_need_more:
  *size = p - bp;
  return 0;
}
예제 #18
0
파일: request.c 프로젝트: ybrs/the-giant
static int parse_multi_line_message(Request* request, const char* data, const size_t data_len){  
    char *newline = NULL;
    int pos = 0, ok;
    long long ll;
    int partialdone = 0;

    if (request->parse_phase == RDS_PHASE_CONNECT){
        if (request->multibulklen == 0) {        
            newline = strchr(data,'\r');
            if (newline == NULL) {
                // if (sdslen(c->querybuf) > REDIS_INLINE_MAX_SIZE) {
                //     addReplyError(c,"Protocol error: too big mbulk count string");
                //     setProtocolError(c,0);
                // }

                // we will come back here,                
                return -1;
            }

            ok = string2ll(data+1, newline-(data+1), &ll);
            if (!ok || ll > 1024*1024) {
                puts("couldnt find data length... ");
                return -2;
            }
            pos = (newline - data)+2;

            if (ll <= 0) {
                // TODO: handle *-1\r\n ?
                // c->querybuf = sdsrange(c->querybuf,pos,-1);
                return true;
            }        

            request->cmd_list = PyList_New(ll);

            request->multibulklen = ll;     
            request->arg_cnt = 0;   
            request->parse_phase = RDS_PHASE_START;
            // now send the remainder to start line...
            request->lastpos = pos;                        
        }
    }    
    

    while (request->multibulklen){        
        // since we found the start line, here we parse it...
        if (request->parse_phase == RDS_PHASE_START){      
              if (data[request->lastpos] == '$'){
                      // 
                      newline = strchr(data+request->lastpos,'\r');
                      if (!newline){
                        return -1;
                      }

                      ok = string2ll(data+request->lastpos+1, newline - (data+ request->lastpos+1),&ll);
                      if (!ok || ll < 0 || ll > 512*1024*1024) {
                          return -2;
                      }

                        // now parse data line...            
                        pos = (newline - data)+2;

                        if (ll < 0) {
                            // handle $-1\r\n ?
                            // protocol error !!!
                            // c->querybuf = sdsrange(c->querybuf,pos,-1);                
                            return -2;
                        }

                        // now send the remainder to start line...
                        request->lastpos = pos;                
                        request->parse_phase = RDS_PHASE_DATA;
                        request->bulklen = ll;
              } else {
                puts("ERR: protocol error");
                return -2;
              }
          }
          // 
          if (request->parse_phase == RDS_PHASE_DATA){      

                if ((int)(data_len - request->lastpos) < 0){
                  return -1;
                }

                // do we have enough data ???
                if ( (int)(data_len - request->lastpos) < (int)(request->bulklen+2)) {
                    /* Not enough data (+2 == trailing \r\n) */                    
                    return -1;
                    break;
                } else {                                        
                    char *str2 = malloc(request->bulklen + 1);
                    memcpy(str2, data + request->lastpos, request->bulklen);                  
                    str2[request->bulklen] = '\0';

                    PyObject* str = PyString_FromStringAndSize(str2, request->bulklen);                  
                    PyList_SetItem(request->cmd_list, request->arg_cnt++, str);                   
                    // NOTE: as far as i understand, PyList_SetItem doesnt incref
                    // http://stackoverflow.com/questions/3512414/does-this-pylist-appendlist-py-buildvalue-leak
                    // Py_DECREF(str); <- TODO: why ? if i do this weird things happen
                    free(str2);                  
                }                                

              
              request->lastpos = request->lastpos + request->bulklen + 2;
              request->parse_phase = RDS_PHASE_START;              
              request->multibulklen--;                              
          
          } // if RDS_PHASE_DATA
    } // while bulklen

    if (request->multibulklen == 0){      
        return 1;
    }
    
    return -1;
}
예제 #19
0
/* ----------------- */
static sds
get_bitmap_from_argv (int argc, robj ** argv)
{
  sds bitmap;
  int i;

  bitmap = sdsgrowzero (sdsempty (), ARC_KS_SIZE);

  for (i = 0; i < argc; i++)
    {
      int ok, n, j;
      long long ll, from, to;
      sds *tokens;
      sds from_to = (sds) argv[i]->ptr;

      /* There are two kinds of argument type.
       * 1. <slotNo>                     ex) 1024
       * 2. <slotNo from>-<slotNo to>    ex) 0-2047 */
      tokens = sdssplitlen (from_to, sdslen (from_to), "-", 1, &n);
      if (tokens == NULL)
	{
	  return NULL;
	}

      if (n == 1)
	{
	  /* Type 1 <slotNo> */
	  ok = string2ll (tokens[0], sdslen (tokens[0]), &ll);
	  if (!ok)
	    {
	      sdsfreesplitres (tokens, n);
	      return NULL;
	    }
	  from = ll;
	  to = ll;
	}
      else if (n == 2)
	{
	  /* Type 2 <slotNo from>-<slotNo to> */
	  ok = string2ll (tokens[0], sdslen (tokens[0]), &ll);
	  if (!ok)
	    {
	      sdsfreesplitres (tokens, n);
	      return NULL;
	    }
	  from = ll;

	  ok = string2ll (tokens[1], sdslen (tokens[1]), &ll);
	  if (!ok)
	    {
	      sdsfreesplitres (tokens, n);
	      return NULL;
	    }
	  to = ll;
	}
      else
	{
	  /* not belong to Type 1 or Type 2 */
	  sdsfreesplitres (tokens, n);
	  return NULL;
	}

      sdsfreesplitres (tokens, n);

      /* range check */
      if (from < 0 || to >= ARC_KS_SIZE || from > to)
	{
	  return NULL;
	}

      /* set bit */
      for (j = from; j <= to; j++)
	{
	  bitmapSetBit ((unsigned char *) bitmap, j);
	}
    }
  return bitmap;
}