hiredis , MSET using binary safe API

482 views
Skip to first unread message

nept

unread,
May 17, 2017, 4:27:07 AM5/17/17
to Redis DB
Hi,
I have an array of keys and an array of values in byte:
#define  unsigned char byte;
char *key[n];
byte *value[n];
int len[2]

n is variable so I can't use this command (for example with n=2)
redisCommand(r.myRedisConnection,"MSET %b %b %b %b", key[0], (size_t) strlen(key[0]), value[0], (size_t)len[0],key[1], (size_t) strlen(key[1]), value[1], (size_t) len[1]);

Can I do it?
Thanks.

Jan-Erik Rediger

unread,
May 17, 2017, 4:43:01 AM5/17/17
to redi...@googlegroups.com
The easiest way would be to use `redisCommandArgv` and build up your
`argv` array, filling it with keys and values as you need it.

Rough pseudo-code:

argv = malloc(2*n+1);
argv[0] = "MSET";
for (i=0;i<n;i++) {
argv.append(key[i]);
argv.append(value[i]);
}

redisCommandArgv(ctx, 2*n+1, argv, NULL);
> --
> You received this message because you are subscribed to the Google Groups "Redis DB" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to redis-db+u...@googlegroups.com.
> To post to this group, send email to redi...@googlegroups.com.
> Visit this group at https://groups.google.com/group/redis-db.
> For more options, visit https://groups.google.com/d/optout.

Salvatore Aurnia

unread,
May 17, 2017, 5:33:09 AM5/17/17
to redi...@googlegroups.com, Jan-Erik Rediger
Thanks for you replay.

The problem is that the values are bytes, but **argv is **char type,
so I can't set it in argv without problem.
With memcpy I have core dump.

Jan-Erik Rediger

unread,
May 17, 2017, 5:43:36 AM5/17/17
to Salvatore Aurnia, redi...@googlegroups.com
Cast it ¯\_(ツ)_/¯
You're "byte" is laos just a "unsigned char".

You'd still need to allocate the memory in the argv array itself.

Salvatore Aurnia

unread,
May 17, 2017, 8:28:24 AM5/17/17
to Jan-Erik Rediger, Salvatore Aurnia, redi...@googlegroups.com
my problem is that array of byte is createdby matlab, where byte byte
is uint8, so if a byte is 0, char(0)='\0' and

the string is over.

Jan-Erik Rediger

unread,
May 17, 2017, 9:23:07 AM5/17/17
to Salvatore Aurnia, redi...@googlegroups.com
Then pass in the length of these arrays using the last argument to redisCommandArgv.
hiredis can easily handle arbitrary binary data if you give it the
actual length

Salvatore Aurnia

unread,
May 18, 2017, 2:53:06 AM5/18/17
to Jan-Erik Rediger, Salvatore Aurnia, redi...@googlegroups.com
it doesn't work.
if a byte is 0, nothing to do.

Salvatore Aurnia

unread,
May 18, 2017, 3:11:52 AM5/18/17
to Jan-Erik Rediger, Salvatore Aurnia, redi...@googlegroups.com
the null byte is considerated as a terminator and a buffer holding
such is "truncated" at the first zero byte instance.

Jan-Erik Rediger

unread,
May 18, 2017, 3:41:29 AM5/18/17
to Salvatore Aurnia, redi...@googlegroups.com
For strings and related string functions, yes.
For arbitrary binary data that can contain nul bytes, you have to keep
track of the length by yourself. Neither hiredis nor C can do that for
you.

Salvatore Aurnia

unread,
May 18, 2017, 3:55:32 AM5/18/17
to Jan-Erik Rediger, Salvatore Aurnia, redi...@googlegroups.com
It's true.
But if I convert a byte array to *char[], 0 is converted to '\0' so
it's considerated as null char, so my key is not stored.

With command:
redisCommand(r.myRedisConnection,"MSET %b %b %b %b", key[0], (size_t)
strlen(key[0]), value[0], (size_t)len[0],key[1], (size_t)
strlen(key[1]), value[1], (size_t) len[1]);

I haven't problems, but I have a number of arguments, so I don't know
how to fix it.

Jan-Erik Rediger

unread,
May 18, 2017, 4:11:55 AM5/18/17
to Salvatore Aurnia, redi...@googlegroups.com
Again: Neither C nor hiredis do care.
If you _explicitely_ pass the right length it doesn't matter if there
are null bytes in the data, hiredis will use the amount of bytes you
specified by the length parameter.

Salvatore Aurnia

unread,
May 18, 2017, 6:16:24 AM5/18/17
to Jan-Erik Rediger, Salvatore Aurnia, redi...@googlegroups.com
"If you _explicitely_ pass the right length it doesn't matter if there
are null bytes in the data, hiredis will use the amount of bytes you
specified by the length parameter."

I try it, but it doesn't work for me.

Salvatore Aurnia

unread,
May 18, 2017, 6:22:52 AM5/18/17
to Jan-Erik Rediger, Salvatore Aurnia, redi...@googlegroups.com
Sorry, I resolved it.
I used "MSET %b ... %b", where the number of '%b' is equal to size of
array, with "MSET" it works.
Thanks.
Reply all
Reply to author
Forward
0 new messages