如今咱们开始分析具体的处理函数processInlineBuffer。 c++
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ redis
char *newline = strstr(c->querybuf,"\r\n"); 数组
//查找第一个\r\n的位置 数据结构
int argc;
int j;
//设置两个整型变量
sds *argv;
sds aux;
////将querylen长度的字符串从新初始化成一个sds数据结构体
size_t querylen;
//当前查找\r\n后的长度
//设置若干变量
/* Nothing to do without a \r\n */
if (newline == NULL)
{
if (sdslen(c->querybuf) > REDIS_INLINE_MAX_SIZE) {
addReplyError(c,"Protocol error: too big inline request");
setProtocolError(c,0);
}
return REDIS_ERR;
}
//若是没有找到\r\n,则返回
/* Split the input buffer up to the \r\n */
querylen = newline-(c->querybuf);
//设置为查询到的长度
aux = sdsnewlen(c->querybuf,querylen);
//将querylen长度的字符串从新初始化成一个sds数据结构体 函数
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ token
而后后面的函数是:sdssplitargs 字符串
从字面来理解的话,应该是以某个字符串为分割,结果是返回一个数组。 input
咱们跟进去一窥奥义。 it
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 变量
我稍微看了下这个函数的代码,没有百分百弄清楚,
我看了下
/* add the token to the vector */
vector = zrealloc(vector,((*argc)+1)*sizeof(char*));
vector[*argc] = current;
(*argc)++;
而后知道这个函数的做用是:将这个字符串解析下,分割成若干个字符串数组
vector的每一个成员是一个字符串首地址,argc返回字符串的个数,而后就返回了,
如今的问题是,如何解析字符串,返回的是什么样的形式呢?
下面是个人理解:
1:在双引号中,
1.1 \xab十六进制形式的,转换成一个数字。
1.2 "\n"--->'\n'
1.3 "\r"--->'\r"
1.4"\t"--->'\t'
1.5 "\b"--->'\b'
1.6 "\a"--->'\a'
1.7其它字符,复制进去。
2:在单引号中
2.1 "\'"--->'\''
2.2 其它字符,复制进去。
~~~~~~~~~~~~~~~~~~~~~~~~~~
而后咱们回到processInlineBuffer函数。
下面的代码,咱们来关注sdsrange(c->querybuf,querylen+2,-1);
因为以前咱们已经处理了一部分字符串,如今要把这个字符串从缓冲区里撤走。
/* Setup argv array on client structure */
if (c->argv) zfree(c->argv);
c->argv = zmalloc(sizeof(robj*)*argc);
//释放已经有的缓冲区,而后根据解析结果来从新分配缓冲区。
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/* Create redis objects for all arguments. */
for (c->argc = 0, j = 0; j < argc; j++)
{
if (sdslen(argv[j]))
{
c->argv[c->argc] = createObject(REDIS_STRING,argv[j]);
c->argc++;
}
else
{
sdsfree(argv[j]);
}
}
将解析结果保存起来。
至此,本函数执行完毕。