int rmsgpack_dom_write(RFILE *fd, const struct rmsgpack_dom_value *obj) { unsigned i; int rv = 0; int written = 0; switch (obj->type) { case RDT_NULL: return rmsgpack_write_nil(fd); case RDT_BOOL: return rmsgpack_write_bool(fd, obj->val.bool_); case RDT_INT: return rmsgpack_write_int(fd, obj->val.int_); case RDT_UINT: return rmsgpack_write_uint(fd, obj->val.uint_); case RDT_STRING: return rmsgpack_write_string(fd, obj->val.string.buff, obj->val.string.len); case RDT_BINARY: return rmsgpack_write_bin(fd, obj->val.binary.buff, obj->val.binary.len); case RDT_MAP: if ((rv = rmsgpack_write_map_header(fd, obj->val.map.len)) < 0) return rv; written += rv; for (i = 0; i < obj->val.map.len; i++) { if ((rv = rmsgpack_dom_write(fd, &obj->val.map.items[i].key)) < 0) return rv; written += rv; if ((rv = rmsgpack_dom_write(fd, &obj->val.map.items[i].value)) < 0) return rv; written += rv; } break; case RDT_ARRAY: if ((rv = rmsgpack_write_array_header(fd, obj->val.array.len)) < 0) return rv; written += rv; for (i = 0; i < obj->val.array.len; i++) { if ((rv = rmsgpack_dom_write(fd, &obj->val.array.items[i])) < 0) return rv; written += rv; } } return written; }
int libretrodb_create(RFILE *fd, libretrodb_value_provider value_provider, void *ctx) { int rv; libretrodb_metadata_t md; struct rmsgpack_dom_value item; uint64_t item_count = 0; libretrodb_header_t header = {{0}}; ssize_t root = filestream_seek(fd, 0, SEEK_CUR); memcpy(header.magic_number, MAGIC_NUMBER, sizeof(MAGIC_NUMBER)-1); /* We write the header in the end because we need to know the size of * the db first */ filestream_seek(fd, sizeof(libretrodb_header_t), SEEK_CUR); item.type = RDT_NULL; while ((rv = value_provider(ctx, &item)) == 0) { if ((rv = libretrodb_validate_document(&item)) < 0) goto clean; if ((rv = rmsgpack_dom_write(fd, &item)) < 0) goto clean; rmsgpack_dom_value_free(&item); item.type = RDT_NULL; item_count++; } if (rv < 0) goto clean; if ((rv = rmsgpack_dom_write(fd, &sentinal)) < 0) goto clean; header.metadata_offset = swap_if_little64(filestream_seek(fd, 0, SEEK_CUR)); md.count = item_count; libretrodb_write_metadata(fd, &md); filestream_seek(fd, root, SEEK_SET); filestream_write(fd, &header, sizeof(header)); clean: rmsgpack_dom_value_free(&item); return rv; }
int libretrodb_create(int fd, libretrodb_value_provider value_provider, void * ctx) { int rv; off_t root; libretrodb_metadata_t md; uint64_t item_count = 0; struct rmsgpack_dom_value item = {}; libretrodb_header_t header = {}; memcpy(header.magic_number, MAGIC_NUMBER, sizeof(MAGIC_NUMBER)-1); root = lseek(fd, 0, SEEK_CUR); /* We write the header in the end because we need to know the size of * the db first */ lseek(fd, sizeof(libretrodb_header_t), SEEK_CUR); while ((rv = value_provider(ctx, &item)) == 0) { if ((rv = validate_document(&item)) < 0) goto clean; if ((rv = rmsgpack_dom_write(fd, &item)) < 0) goto clean; item_count++; } if (rv < 0) goto clean; if ((rv = rmsgpack_dom_write(fd, &sentinal)) < 0) goto clean; header.metadata_offset = httobe64(lseek(fd, 0, SEEK_CUR)); md.count = item_count; libretrodb_write_metadata(fd, &md); lseek(fd, root, SEEK_SET); write(fd, &header, sizeof(header)); clean: rmsgpack_dom_value_free(&item); return rv; }