SETBIT key offset bitvalue */
| 525 | |
| 526 | /* SETBIT key offset bitvalue */ |
| 527 | void setbitCommand(client *c) { |
| 528 | robj *o; |
| 529 | char *err = "bit is not an integer or out of range"; |
| 530 | uint64_t bitoffset; |
| 531 | ssize_t byte, bit; |
| 532 | int byteval, bitval; |
| 533 | long on; |
| 534 | |
| 535 | if (getBitOffsetFromArgument(c,c->argv[2],&bitoffset,0,0) != C_OK) |
| 536 | return; |
| 537 | |
| 538 | if (getLongFromObjectOrReply(c,c->argv[3],&on,err) != C_OK) |
| 539 | return; |
| 540 | |
| 541 | /* Bits can only be set or cleared... */ |
| 542 | if (on & ~1) { |
| 543 | addReplyError(c,err); |
| 544 | return; |
| 545 | } |
| 546 | |
| 547 | if ((o = lookupStringForBitCommand(c,bitoffset)) == NULL) return; |
| 548 | |
| 549 | /* Get current values */ |
| 550 | byte = bitoffset >> 3; |
| 551 | byteval = ((uint8_t*)o->ptr)[byte]; |
| 552 | bit = 7 - (bitoffset & 0x7); |
| 553 | bitval = byteval & (1 << bit); |
| 554 | |
| 555 | /* Update byte with new bit value and return original value */ |
| 556 | byteval &= ~(1 << bit); |
| 557 | byteval |= ((on & 0x1) << bit); |
| 558 | ((uint8_t*)o->ptr)[byte] = byteval; |
| 559 | signalModifiedKey(c,c->db,c->argv[1]); |
| 560 | notifyKeyspaceEvent(NOTIFY_STRING,"setbit",c->argv[1],c->db->id); |
| 561 | server.dirty++; |
| 562 | addReply(c, bitval ? shared.cone : shared.czero); |
| 563 | } |
| 564 | |
| 565 | /* GETBIT key offset */ |
| 566 | void getbitCommand(client *c) { |
nothing calls this directly
no test coverage detected