c-ipfs/merkledag/merkledag.c
jmjatlanta c8fdb084e4 Moving closer to binary compatability with go version of ipfs
The files are now stored in the same format. Now it is necessary to
reverse engineer the directory structure
2016-12-21 06:40:19 -05:00

87 lines
2.3 KiB
C

/**
* A basic storage building block of the IPFS system
*/
#include "ipfs/merkledag/merkledag.h"
/***
* Adds a node to the dagService and blockService
* @param node the node to add
* @param cid the resultant cid that was added
* @returns true(1) on success
*/
int ipfs_merkledag_add(struct Node* node, struct FSRepo* fs_repo) {
// taken from merkledag.go line 59
struct Block* block = NULL;
// protobuf the node
size_t protobuf_len = ipfs_node_protobuf_encode_size(node);
size_t bytes_written = 0;
unsigned char protobuf[protobuf_len];
ipfs_node_protobuf_encode(node, protobuf, protobuf_len, &bytes_written);
// turn the node into a block
ipfs_blocks_block_new(&block);
ipfs_blocks_block_add_data(protobuf, bytes_written, block);
// write to block store & datastore
int retVal = ipfs_repo_fsrepo_block_write(block, fs_repo);
if (retVal == 0) {
ipfs_blocks_block_free(block);
return 0;
}
ipfs_node_set_hash(node, block->cid->hash, block->cid->hash_length);
if (block != NULL)
ipfs_blocks_block_free(block);
// TODO: call HasBlock (unsure why as yet)
return 1;
}
/***
* Retrieves a node from the datastore based on the cid
* @param cid the key to look for
* @param node the node to be created
* @param fs_repo the repository
* @returns true(1) on success
*/
int ipfs_merkledag_get(const unsigned char* hash, size_t hash_size, struct Node** node, const struct FSRepo* fs_repo) {
int retVal = 1;
struct Block* block;
size_t key_length = 100;
unsigned char key[key_length];
// look for the node in the datastore. If it is not there, it is not a node.
// If it exists, it is only a block.
retVal = fs_repo->config->datastore->datastore_get((char*)hash, hash_size, key, key_length, &key_length, fs_repo->config->datastore);
if (retVal == 0)
return 0;
// we have the record from the db. Go get the block from the blockstore
retVal = ipfs_repo_fsrepo_block_read(hash, hash_size, &block, fs_repo);
if (retVal == 0) {
return 0;
}
// now convert the block into a node
if (ipfs_node_protobuf_decode(block->data, block->data_length, node) == 0) {
ipfs_blocks_block_free(block);
return 0;
}
// set the cid on the node
if (ipfs_node_set_hash(*node, hash, hash_size) == 0) {
ipfs_blocks_block_free(block);
ipfs_node_free(*node);
return 0;
}
// free resources
ipfs_blocks_block_free(block);
return 1;
}