static couchstore_error_t by_seq_read_docinfo(DocInfo **pInfo, sized_buf *k, sized_buf *v) { const raw_seq_index_value *raw = (const raw_seq_index_value*)v->buf; ssize_t extraSize = v->size - sizeof(*raw); if (extraSize < 0) { return COUCHSTORE_ERROR_CORRUPT; } uint32_t idsize, datasize; decode_kv_length(&raw->sizes, &idsize, &datasize); uint64_t bp = decode_raw48(raw->bp); int deleted = (bp & BP_DELETED_FLAG) != 0; bp &= ~BP_DELETED_FLAG; uint8_t content_meta = decode_raw08(raw->content_meta); uint64_t rev_seq = decode_raw48(raw->rev_seq); uint64_t db_seq = decode_sequence_key(k); sized_buf id = {v->buf + sizeof(*raw), idsize}; sized_buf rev_meta = {id.buf + idsize, extraSize - id.size}; DocInfo* docInfo = couchstore_alloc_docinfo(&id, &rev_meta); if (!docInfo) { return COUCHSTORE_ERROR_ALLOC_FAIL; } docInfo->db_seq = db_seq; docInfo->rev_seq = rev_seq; docInfo->deleted = deleted; docInfo->bp = bp; docInfo->size = datasize; docInfo->content_meta = content_meta; *pInfo = docInfo; return COUCHSTORE_SUCCESS; }
size_t read_kv(const void *buf, sized_buf *key, sized_buf *value) { const raw_kv_length* kvlen = buf; uint32_t klen, vlen; decode_kv_length(kvlen, &klen, &vlen); key->size = klen; key->buf = (char*)(kvlen + 1); value->size = vlen; value->buf = key->buf + klen; return sizeof(raw_kv_length) + klen + vlen; }
static void test_bitfield_fns(void) { uint8_t expected1[8] = {0x12, 0x34, 0x56, 0x78, 0x90}; uint8_t expected2[8] = {0x09, 0x87, 0x65, 0x43, 0x21}; uint8_t expected3[8] = {0x12, 0x34, 0x56, 0x78, 0x90, 0xAB}; uint8_t expected4[8] = {0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}; struct { raw_08 a; raw_48 b; raw_16 c; raw_40 d; raw_32 e; raw_08 f; } packed; raw_kv_length kv; uint32_t klen, vlen; assert(sizeof(cs_off_t) == 8); assert(sizeof(raw_08) == 1); assert(sizeof(raw_16) == 2); assert(sizeof(raw_32) == 4); assert(sizeof(raw_40) == 5); assert(sizeof(raw_48) == 6); assert(sizeof(packed) == 19); assert(sizeof(kv) == 5); kv = encode_kv_length(1234, 123456); decode_kv_length(&kv, &klen, &vlen); assert(klen == 1234); assert(vlen == 123456); test_raw_08(0); test_raw_08(UINT8_MAX); test_raw_16(0); test_raw_16(12345); test_raw_16(UINT16_MAX); test_raw_32(0); test_raw_32(12345678); test_raw_32(UINT32_MAX); test_raw_40(INT64_C(0x1234567890), expected1); test_raw_40(INT64_C(0x0987654321), expected2); test_raw_48(INT64_C(0x1234567890AB), expected3); test_raw_48(INT64_C(0xBA9876543210), expected4); }
static int by_seq_read_docinfo(DocInfo **pInfo, sized_buf *k, sized_buf *v) { const raw_seq_index_value *raw = (const raw_seq_index_value*)v->buf; ssize_t extraSize = v->size - sizeof(*raw); if (extraSize < 0) { return COUCHSTORE_ERROR_CORRUPT; } uint32_t idsize, datasize; decode_kv_length(&raw->sizes, &idsize, &datasize); uint64_t bp = decode_raw48(raw->bp); int deleted = (bp & BP_DELETED_FLAG) != 0; bp &= ~BP_DELETED_FLAG; uint8_t content_meta = decode_raw08(raw->content_meta); uint64_t rev_seq = decode_raw48(raw->rev_seq); uint64_t db_seq = decode_sequence_key(k); DocInfo* docInfo = malloc(sizeof(DocInfo) + extraSize); if (!docInfo) { return COUCHSTORE_ERROR_ALLOC_FAIL; } char *rbuf = (char *) docInfo; memcpy(rbuf + sizeof(DocInfo), v->buf + sizeof(*raw), extraSize); *pInfo = docInfo; docInfo->db_seq = db_seq; docInfo->rev_seq = rev_seq; docInfo->deleted = deleted; docInfo->bp = bp; docInfo->size = datasize; docInfo->content_meta = content_meta; docInfo->id.buf = rbuf + sizeof(DocInfo); docInfo->id.size = idsize; docInfo->rev_meta.buf = rbuf + sizeof(DocInfo) + idsize; docInfo->rev_meta.size = extraSize - idsize; return 0; }