Format a command according to the Redis protocol. This function takes the * number of arguments, an array with arguments and an array with their * lengths. If the latter is set to NULL, strlen will be used to compute the * argument lengths. */
| 624 | * argument lengths. |
| 625 | */ |
| 626 | int redisFormatCommandArgv(char **target, int argc, const char **argv, const size_t *argvlen) { |
| 627 | char *cmd = NULL; /* final command */ |
| 628 | int pos; /* position in final command */ |
| 629 | size_t len; |
| 630 | int totlen, j; |
| 631 | |
| 632 | /* Abort on a NULL target */ |
| 633 | if (target == NULL) |
| 634 | return -1; |
| 635 | |
| 636 | /* Calculate number of bytes needed for the command */ |
| 637 | totlen = 1+countDigits(argc)+2; |
| 638 | for (j = 0; j < argc; j++) { |
| 639 | len = argvlen ? argvlen[j] : strlen(argv[j]); |
| 640 | totlen += bulklen(len); |
| 641 | } |
| 642 | |
| 643 | /* Build the command at protocol level */ |
| 644 | cmd = hi_malloc(totlen+1); |
| 645 | if (cmd == NULL) |
| 646 | return -1; |
| 647 | |
| 648 | pos = sprintf(cmd,"*%d\r\n",argc); |
| 649 | for (j = 0; j < argc; j++) { |
| 650 | len = argvlen ? argvlen[j] : strlen(argv[j]); |
| 651 | pos += sprintf(cmd+pos,"$%zu\r\n",len); |
| 652 | memcpy(cmd+pos,argv[j],len); |
| 653 | pos += len; |
| 654 | cmd[pos++] = '\r'; |
| 655 | cmd[pos++] = '\n'; |
| 656 | } |
| 657 | assert(pos == totlen); |
| 658 | cmd[pos] = '\0'; |
| 659 | |
| 660 | *target = cmd; |
| 661 | return totlen; |
| 662 | } |
| 663 | |
| 664 | void redisFreeCommand(char *cmd) { |
| 665 | hi_free(cmd); |