From a91650fc57077f53eac658d2da452bcf10d14ee6 Mon Sep 17 00:00:00 2001 From: Dvir Volk Date: Wed, 21 Sep 2016 12:30:38 +0300 Subject: added RM_CreateStringPrintf --- src/module.c | 25 +++++++++++++++++++++++-- src/modules/testmodule.c | 26 ++++++++++++++++++++++++++ src/object.c | 2 +- src/redismodule.h | 2 ++ 4 files changed, 52 insertions(+), 3 deletions(-) diff --git a/src/module.c b/src/module.c index 3c757a5cb..b94c98acf 100644 --- a/src/module.c +++ b/src/module.c @@ -681,13 +681,33 @@ void autoMemoryCollect(RedisModuleCtx *ctx) { * * The string is created by copying the `len` bytes starting * at `ptr`. No reference is retained to the passed buffer. */ -RedisModuleString *RM_CreateString(RedisModuleCtx *ctx, const char *ptr, size_t len) -{ +RedisModuleString *RM_CreateString(RedisModuleCtx *ctx, const char *ptr, size_t len) { RedisModuleString *o = createStringObject(ptr,len); autoMemoryAdd(ctx,REDISMODULE_AM_STRING,o); return o; } + +/* Create a new module string object from a printf format and arguments. + * The returned string must be freed with RedisModule_FreeString(), unless automatic + * memory is enabled. + * + * The string is created using the sds formatter function sdscatvprintf() */ +RedisModuleString *RM_CreateStringPrintf(RedisModuleCtx *ctx, const char *fmt, ...) { + sds s = sdsempty(); + + va_list ap; + va_start(ap, fmt); + s = sdscatvprintf(s, fmt, ap); + va_end(ap); + + RedisModuleString *o = createObject(OBJ_STRING, s); + autoMemoryAdd(ctx,REDISMODULE_AM_STRING,o); + + return o; +} + + /* Like RedisModule_CreatString(), but creates a string starting from a long long * integer instead of taking a buffer and its length. * @@ -3194,6 +3214,7 @@ void moduleRegisterCoreAPI(void) { REGISTER_API(CreateString); REGISTER_API(CreateStringFromLongLong); REGISTER_API(CreateStringFromString); + REGISTER_API(CreateStringPrintf); REGISTER_API(FreeString); REGISTER_API(StringPtrLen); REGISTER_API(AutoMemory); diff --git a/src/modules/testmodule.c b/src/modules/testmodule.c index a1a42f43b..db809a8e6 100644 --- a/src/modules/testmodule.c +++ b/src/modules/testmodule.c @@ -93,6 +93,25 @@ int TestStringAppendAM(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) return REDISMODULE_OK; } +/* TEST.STRING.PRINTF -- Test string formatting. */ +int TestStringPrintf(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) { + RedisModule_AutoMemory(ctx); + if (argc < 3) { + return RedisModule_WrongArity(ctx); + } + RedisModuleString *s = RedisModule_CreateStringPrintf(ctx, + "Got %d args. argv[1]: %s, argv[2]: %s", + argc, + RedisModule_StringPtrLen(argv[1], NULL), + RedisModule_StringPtrLen(argv[2], NULL) + ); + + RedisModule_ReplyWithString(ctx,s); + + return REDISMODULE_OK; +} + + /* ----------------------------- Test framework ----------------------------- */ /* Return 1 if the reply matches the specified string, otherwise log errors @@ -163,6 +182,9 @@ int TestIt(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) { T("test.string.append.am",""); if (!TestAssertStringReply(ctx,reply,"foobar",6)) goto fail; + T("test.string.printf", "cc", "foo", "bar"); + if (!TestAssertStringReply(ctx,reply,"Got 3 args. argv[1]: foo, argv[2]: bar",38)) goto fail; + RedisModule_ReplyWithSimpleString(ctx,"ALL TESTS PASSED"); return REDISMODULE_OK; @@ -188,6 +210,10 @@ int RedisModule_OnLoad(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) TestStringAppendAM,"write deny-oom",1,1,1) == REDISMODULE_ERR) return REDISMODULE_ERR; + if (RedisModule_CreateCommand(ctx,"test.string.printf", + TestStringPrintf,"write deny-oom",1,1,1) == REDISMODULE_ERR) + return REDISMODULE_ERR; + if (RedisModule_CreateCommand(ctx,"test.it", TestIt,"readonly",1,1,1) == REDISMODULE_ERR) return REDISMODULE_ERR; diff --git a/src/object.c b/src/object.c index 75839926e..210e980e7 100644 --- a/src/object.c +++ b/src/object.c @@ -75,7 +75,7 @@ robj *makeObjectShared(robj *o) { /* Create a string object with encoding OBJ_ENCODING_RAW, that is a plain * string object where o->ptr points to a proper sds string. */ robj *createRawStringObject(const char *ptr, size_t len) { - return createObject(OBJ_STRING,sdsnewlen(ptr,len)); + return createObject(OBJ_STRING, sdsnewlen(ptr,len)); } /* Create a string object with encoding OBJ_ENCODING_EMBSTR, that is diff --git a/src/redismodule.h b/src/redismodule.h index 0a35cf047..75b13ad52 100644 --- a/src/redismodule.h +++ b/src/redismodule.h @@ -125,6 +125,7 @@ RedisModuleCallReply *REDISMODULE_API_FUNC(RedisModule_CallReplyArrayElement)(Re RedisModuleString *REDISMODULE_API_FUNC(RedisModule_CreateString)(RedisModuleCtx *ctx, const char *ptr, size_t len); RedisModuleString *REDISMODULE_API_FUNC(RedisModule_CreateStringFromLongLong)(RedisModuleCtx *ctx, long long ll); RedisModuleString *REDISMODULE_API_FUNC(RedisModule_CreateStringFromString)(RedisModuleCtx *ctx, const RedisModuleString *str); +RedisModuleString *REDISMODULE_API_FUNC(RedisModule_CreateStringPrintf)(RedisModuleCtx *ctx, const char *fmt, ...); void REDISMODULE_API_FUNC(RedisModule_FreeString)(RedisModuleCtx *ctx, RedisModuleString *str); const char *REDISMODULE_API_FUNC(RedisModule_StringPtrLen)(const RedisModuleString *str, size_t *len); int REDISMODULE_API_FUNC(RedisModule_ReplyWithError)(RedisModuleCtx *ctx, const char *err); @@ -234,6 +235,7 @@ static int RedisModule_Init(RedisModuleCtx *ctx, const char *name, int ver, int REDISMODULE_GET_API(CreateString); REDISMODULE_GET_API(CreateStringFromLongLong); REDISMODULE_GET_API(CreateStringFromString); + REDISMODULE_GET_API(CreateStringPrintf); REDISMODULE_GET_API(FreeString); REDISMODULE_GET_API(StringPtrLen); REDISMODULE_GET_API(AutoMemory); -- cgit v1.2.1