MCPcopy Create free account
hub / github.com/Snapchat/KeyDB / moduleCreateArgvFromUserFormat

Function moduleCreateArgvFromUserFormat

src/module.cpp:4062–4130  ·  view source on GitHub ↗

Returns an array of robj pointers, and populates *argc with the number * of items, by parsing the format specifier "fmt" as described for * the RM_Call(), RM_Replicate() and other module APIs. * * The integer pointed by 'flags' is populated with flags according * to special modifiers in "fmt". For now only one exists: * * "!" -> REDISMODULE_ARGV_REPLICATE * "A" -> REDISMODULE_ARGV_

Source from the content-addressed store, hash-verified

4060 * On error (format specifier error) NULL is returned and nothing is
4061 * allocated. On success the argument vector is returned. */
4062robj **moduleCreateArgvFromUserFormat(const char *cmdname, const char *fmt, int *argcp, int *flags, va_list ap) {
4063 int argc = 0, argv_size, j;
4064 robj **argv = NULL;
4065
4066 /* As a first guess to avoid useless reallocations, size argv to
4067 * hold one argument for each char specifier in 'fmt'. */
4068 argv_size = strlen(fmt)+1; /* +1 because of the command name. */
4069 argv = (robj**)zrealloc(argv,sizeof(robj*)*argv_size, MALLOC_LOCAL);
4070
4071 /* Build the arguments vector based on the format specifier. */
4072 argv[0] = createStringObject(cmdname,strlen(cmdname));
4073 argc++;
4074
4075 /* Create the client and dispatch the command. */
4076 const char *p = fmt;
4077 while(*p) {
4078 if (*p == 'c') {
4079 char *cstr = va_arg(ap,char*);
4080 argv[argc++] = createStringObject(cstr,strlen(cstr));
4081 } else if (*p == 's') {
4082 robj *obj = (robj*)va_arg(ap,void*);
4083 if (obj->getrefcount(std::memory_order_relaxed) == OBJ_STATIC_REFCOUNT)
4084 obj = createStringObject(szFromObj(obj),sdslen(szFromObj(obj)));
4085 else
4086 incrRefCount(obj);
4087 argv[argc++] = obj;
4088 } else if (*p == 'b') {
4089 char *buf = va_arg(ap,char*);
4090 size_t len = va_arg(ap,size_t);
4091 argv[argc++] = createStringObject(buf,len);
4092 } else if (*p == 'l') {
4093 long long ll = va_arg(ap,long long);
4094 argv[argc++] = createObject(OBJ_STRING,sdsfromlonglong(ll));
4095 } else if (*p == 'v') {
4096 /* A vector of strings */
4097 robj **v = (robj**)va_arg(ap, void*);
4098 size_t vlen = va_arg(ap, size_t);
4099
4100 /* We need to grow argv to hold the vector's elements.
4101 * We resize by vector_len-1 elements, because we held
4102 * one element in argv for the vector already */
4103 argv_size += vlen-1;
4104 argv = (robj**)zrealloc(argv,sizeof(robj*)*argv_size, MALLOC_LOCAL);
4105
4106 size_t i = 0;
4107 for (i = 0; i < vlen; i++) {
4108 incrRefCount(v[i]);
4109 argv[argc++] = v[i];
4110 }
4111 } else if (*p == '!') {
4112 if (flags) (*flags) |= REDISMODULE_ARGV_REPLICATE;
4113 } else if (*p == 'A') {
4114 if (flags) (*flags) |= REDISMODULE_ARGV_NO_AOF;
4115 } else if (*p == 'R') {
4116 if (flags) (*flags) |= REDISMODULE_ARGV_NO_REPLICAS;
4117 } else {
4118 goto fmterr;
4119 }

Callers 3

RM_ReplicateFunction · 0.85
RM_CallFunction · 0.85
RM_EmitAOFFunction · 0.85

Calls 10

zreallocFunction · 0.85
szFromObjFunction · 0.85
sdslenFunction · 0.85
incrRefCountFunction · 0.85
createObjectFunction · 0.85
sdsfromlonglongFunction · 0.85
decrRefCountFunction · 0.85
zfreeFunction · 0.85
getrefcountMethod · 0.80
createStringObjectFunction · 0.70

Tested by

no test coverage detected