BITPOS key bit [start [end]] */
| 830 | |
| 831 | /* BITPOS key bit [start [end]] */ |
| 832 | void bitposCommand(client *c) { |
| 833 | robj *o; |
| 834 | long bit, start, end, strlen; |
| 835 | unsigned char *p; |
| 836 | char llbuf[LONG_STR_SIZE]; |
| 837 | int end_given = 0; |
| 838 | |
| 839 | /* Parse the bit argument to understand what we are looking for, set |
| 840 | * or clear bits. */ |
| 841 | if (getLongFromObjectOrReply(c,c->argv[2],&bit,NULL) != C_OK) |
| 842 | return; |
| 843 | if (bit != 0 && bit != 1) { |
| 844 | addReplyError(c, "The bit argument must be 1 or 0."); |
| 845 | return; |
| 846 | } |
| 847 | |
| 848 | /* If the key does not exist, from our point of view it is an infinite |
| 849 | * array of 0 bits. If the user is looking for the fist clear bit return 0, |
| 850 | * If the user is looking for the first set bit, return -1. */ |
| 851 | if ((o = lookupKeyRead(c->db,c->argv[1])) == NULL) { |
| 852 | addReplyLongLong(c, bit ? -1 : 0); |
| 853 | return; |
| 854 | } |
| 855 | if (checkType(c,o,OBJ_STRING)) return; |
| 856 | p = getObjectReadOnlyString(o,&strlen,llbuf); |
| 857 | |
| 858 | /* Parse start/end range if any. */ |
| 859 | if (c->argc == 4 || c->argc == 5) { |
| 860 | if (getLongFromObjectOrReply(c,c->argv[3],&start,NULL) != C_OK) |
| 861 | return; |
| 862 | if (c->argc == 5) { |
| 863 | if (getLongFromObjectOrReply(c,c->argv[4],&end,NULL) != C_OK) |
| 864 | return; |
| 865 | end_given = 1; |
| 866 | } else { |
| 867 | end = strlen-1; |
| 868 | } |
| 869 | /* Convert negative indexes */ |
| 870 | if (start < 0) start = strlen+start; |
| 871 | if (end < 0) end = strlen+end; |
| 872 | if (start < 0) start = 0; |
| 873 | if (end < 0) end = 0; |
| 874 | if (end >= strlen) end = strlen-1; |
| 875 | } else if (c->argc == 3) { |
| 876 | /* The whole string. */ |
| 877 | start = 0; |
| 878 | end = strlen-1; |
| 879 | } else { |
| 880 | /* Syntax error. */ |
| 881 | addReplyErrorObject(c,shared.syntaxerr); |
| 882 | return; |
| 883 | } |
| 884 | |
| 885 | /* For empty ranges (start > end) we return -1 as an empty range does |
| 886 | * not contain a 0 nor a 1. */ |
| 887 | if (start > end) { |
| 888 | addReplyLongLong(c, -1); |
| 889 | } else { |
nothing calls this directly
no test coverage detected