MCPcopy Create free account
hub / github.com/apache/brpc / RedisCommandFormatV

Function RedisCommandFormatV

src/brpc/redis_command.cpp:84–279  ·  view source on GitHub ↗

Support hiredis-style format, namely everything is same with printf except that %b corresponds to binary-data + length. Notice that we can't use %.*s (printf built-in) which ends scaning at \0 and is not binary-safe. Some code is copied or modified from redisvFormatCommand() in https://github.com/redis/hiredis/blob/master/hiredis.c to keep close compatibility with hiredis.

Source from the content-addressed store, hash-verified

82// https://github.com/redis/hiredis/blob/master/hiredis.c to keep close
83// compatibility with hiredis.
84butil::Status
85RedisCommandFormatV(butil::IOBuf* outbuf, const char* fmt, va_list ap) {
86 if (outbuf == NULL || fmt == NULL) {
87 return butil::Status(EINVAL, "Param[outbuf] or [fmt] is NULL");
88 }
89 const size_t fmt_len = strlen(fmt);
90 std::string nocount_buf;
91 nocount_buf.reserve(fmt_len * 3 / 2 + 16);
92 std::string compbuf; // A component
93 compbuf.reserve(fmt_len + 16);
94 const char* c = fmt;
95 int ncomponent = 0;
96 char quote_char = 0;
97 const char* quote_pos = fmt;
98 int nargs = 0;
99 for (; *c; ++c) {
100 if (*c != '%' || c[1] == '\0') {
101 if (*c == ' ') {
102 if (quote_char) {
103 compbuf.push_back(*c);
104 } else if (!compbuf.empty()) {
105 FlushComponent(&nocount_buf, &compbuf, &ncomponent);
106 }
107 } else if (*c == '"' || *c == '\'') { // Check quotation.
108 if (!quote_char) { // begin quote
109 quote_char = *c;
110 quote_pos = c;
111 if (!compbuf.empty()) {
112 FlushComponent(&nocount_buf, &compbuf, &ncomponent);
113 }
114 } else if (quote_char == *c) {
115 const char last_char = (compbuf.empty() ? 0 : compbuf.back());
116 if (last_char == '\\') {
117 // Even if the preceding chars are two consecutive backslashes
118 // (\\), still do the escaping, which is the behavior of
119 // official redis-cli.
120 compbuf.pop_back();
121 compbuf.push_back(*c);
122 } else { // end quote
123 quote_char = 0;
124 FlushComponent(&nocount_buf, &compbuf, &ncomponent);
125 }
126 } else {
127 compbuf.push_back(*c);
128 }
129 } else {
130 compbuf.push_back(*c);
131 }
132 } else {
133 char *arg;
134 size_t size;
135
136 switch(c[1]) {
137 case 's':
138 arg = va_arg(ap, char*);
139 size = strlen(arg);
140 if (size > 0) {
141 compbuf.append(arg, size);

Callers 3

RedisCommandFormatFunction · 0.85
AddCommandWithArgsMethod · 0.85
AddCommandVMethod · 0.85

Calls 10

FlushComponentFunction · 0.85
vsnprintfFunction · 0.85
AppendHeaderFunction · 0.85
StatusEnum · 0.70
reserveMethod · 0.45
push_backMethod · 0.45
emptyMethod · 0.45
backMethod · 0.45
pop_backMethod · 0.45
appendMethod · 0.45

Tested by

no test coverage detected