Working with nodes to add protobuf to persist to db

adding a link to a node does a realloc. I believe this is causing
problems. I am going to replace this and see if that fixes the issue.
yamux
jmjatlanta 2016-12-12 15:06:17 -05:00
parent e0b0552b39
commit 4fe768c2c5
8 changed files with 682 additions and 244 deletions

View File

@ -16,26 +16,40 @@ enum WireType ipfs_cid_message_fields[] = { WIRETYPE_VARINT, WIRETYPE_VARINT, WI
size_t ipfs_cid_protobuf_encode_size(struct Cid* cid) { size_t ipfs_cid_protobuf_encode_size(struct Cid* cid) {
return 11+12+cid->hash_length+11; if (cid != NULL)
return 11+12+cid->hash_length+11;
return 0;
} }
int ipfs_cid_protobuf_encode(struct Cid* cid, unsigned char* buffer, size_t buffer_length, size_t* bytes_written) { int ipfs_cid_protobuf_encode(struct Cid* cid, unsigned char* buffer, size_t buffer_length, size_t* bytes_written) {
size_t bytes_used; size_t bytes_used;
*bytes_written = 0; *bytes_written = 0;
int retVal = 0; int retVal = 0;
retVal = protobuf_encode_varint(1, ipfs_cid_message_fields[0], cid->version, buffer, buffer_length, &bytes_used); if (cid != NULL) {
*bytes_written += bytes_used; retVal = protobuf_encode_varint(1, ipfs_cid_message_fields[0], cid->version, buffer, buffer_length, &bytes_used);
retVal = protobuf_encode_varint(2, ipfs_cid_message_fields[1], cid->codec, &buffer[*bytes_written], buffer_length - (*bytes_written), &bytes_used); *bytes_written += bytes_used;
*bytes_written += bytes_used; retVal = protobuf_encode_varint(2, ipfs_cid_message_fields[1], cid->codec, &buffer[*bytes_written], buffer_length - (*bytes_written), &bytes_used);
retVal = protobuf_encode_length_delimited(3, ipfs_cid_message_fields[2], cid->hash, cid->hash_length, &buffer[*bytes_written], buffer_length - (*bytes_written), &bytes_used); *bytes_written += bytes_used;
*bytes_written += bytes_used; retVal = protobuf_encode_length_delimited(3, ipfs_cid_message_fields[2], cid->hash, cid->hash_length, &buffer[*bytes_written], buffer_length - (*bytes_written), &bytes_used);
*bytes_written += bytes_used;
}
return 1; return 1;
} }
int ipfs_cid_protobuf_decode(unsigned char* buffer, size_t buffer_length, struct Cid** output) { int ipfs_cid_protobuf_decode(unsigned char* buffer, size_t buffer_length, struct Cid** output) {
// short cut for nulls
if (buffer_length == 0) {
*output = NULL;
return 1;
}
size_t pos = 0; size_t pos = 0;
struct Cid cid; int version = 0;
unsigned char* hash;
size_t hash_length;
char codec = 0;
int retVal = 0; int retVal = 0;
while(pos < buffer_length) { while(pos < buffer_length) {
size_t bytes_read = 0; size_t bytes_read = 0;
int field_no; int field_no;
@ -46,15 +60,15 @@ int ipfs_cid_protobuf_decode(unsigned char* buffer, size_t buffer_length, struct
pos += bytes_read; pos += bytes_read;
switch(field_no) { switch(field_no) {
case (1): case (1):
cid.version = varint_decode(&buffer[pos], buffer_length - pos, &bytes_read); version = varint_decode(&buffer[pos], buffer_length - pos, &bytes_read);
pos += bytes_read; pos += bytes_read;
break; break;
case (2): case (2):
cid.codec = varint_decode(&buffer[pos], buffer_length - pos, &bytes_read); codec = varint_decode(&buffer[pos], buffer_length - pos, &bytes_read);
pos += bytes_read; pos += bytes_read;
break; break;
case (3): case (3):
retVal = protobuf_decode_length_delimited(&buffer[pos], buffer_length - pos, &cid.hash, &cid.hash_length, &bytes_read); retVal = protobuf_decode_length_delimited(&buffer[pos], buffer_length - pos, &hash, &hash_length, &bytes_read);
if (retVal == 0) if (retVal == 0)
return 0; return 0;
pos += bytes_read; pos += bytes_read;
@ -63,8 +77,8 @@ int ipfs_cid_protobuf_decode(unsigned char* buffer, size_t buffer_length, struct
} }
retVal = ipfs_cid_new(cid.version, cid.hash, cid.hash_length, cid.codec, output); retVal = ipfs_cid_new(version, hash, hash_length, codec, output);
free(cid.hash); free(hash);
return retVal; return retVal;
} }

View File

@ -13,21 +13,20 @@
* *
*===================================================================================*/ *===================================================================================*/
struct Link struct NodeLink
{ {
char * name; char* name;
size_t size; struct Cid * cid;
struct Cid * Lcid;
}; };
struct Node struct Node
{ {
unsigned char * data; unsigned char* data;
size_t data_size; size_t data_size;
unsigned char * encoded; unsigned char* encoded;
struct Cid * cached; struct Cid* cached;
int link_amount; int link_amount;
struct Link * links[]; struct NodeLink* links[];
}; };
/*==================================================================================== /*====================================================================================
@ -42,107 +41,147 @@ struct Node
/* Create_Link /* Create_Link
* @Param name: The name of the link (char *) * @Param name: The name of the link (char *)
* @Param size: Size of the link (size_t)
* @Param ahash: An Qmhash * @Param ahash: An Qmhash
* @param node_link a pointer to the new struct NodeLink
* @returns true(1) on success
*/ */
struct Link * Create_Link(char * name, unsigned char * ahash); int ipfs_node_link_new(char * name, unsigned char * ahash, struct NodeLink** node_link);
/* Free_Link /* ipfs_node_link_free
* @param L: Free the link you have allocated. * @param L: Free the link you have allocated.
*/ */
void Free_Link(struct Link * L); int ipfs_node_link_free(struct NodeLink * node_link);
/***
* Node protobuf functions
*/
/***
* return an approximate size of the encoded node
* @param node the node to examine
* @returns the max size of an encoded stream of bytes, if it were encoded
*/
size_t ipfs_node_protobuf_encode_size(struct Node* node);
/***
* Encode a node into a protobuf byte stream
* @param node the node to encode
* @param buffer where to put it
* @param max_buffer_length the length of buffer
* @param bytes_written how much of buffer was used
* @returns true(1) on success
*/
ipfs_node_protobuf_encode(struct Node* node, unsigned char* buffer, size_t max_buffer_length, size_t* bytes_written);
/***
* Decode a stream of bytes into a Node structure
* @param buffer where to get the bytes from
* @param buffer_length the length of buffer
* @param node pointer to the Node to be created
* @returns true(1) on success
*/
ipfs_node_protobuf_decode(unsigned char* buffer, size_t buffer_length, struct Node** node);
/*==================================================================================== /*====================================================================================
* Node Functions * Node Functions
*===================================================================================*/ *===================================================================================*/
/*Create_Empty_Node /*ipfs_node_new
* Creates an empty node, allocates the required memory * Creates an empty node, allocates the required memory
* Returns a fresh new node with no data set in it. * Returns a fresh new node with no data set in it.
*/ */
struct Node * Create_Empty_Node(); int ipfs_node_new(struct Node** node);
//Node_Set_Cached /**
int Node_Set_Cached(struct Node * N, struct Cid * TheCid); * sets the Cid into the struct element titled cached
* @param node the node to work with
* @param cid the cid
* @returns true(1) on success
*/
int ipfs_node_set_cached(struct Node* node, struct Cid* cid);
/*Node_Set_Data /*ipfs_node_set_data
* Sets the data of a node * Sets the data of a node
* @param Node: The node which you want to set data in. * @param Node: The node which you want to set data in.
* @param Data, the data you want to assign to the node * @param Data, the data you want to assign to the node
* Sets pointers of encoded & cached to NULL /following go method * Sets pointers of encoded & cached to NULL /following go method
* returns 1 on success 0 on failure * returns 1 on success 0 on failure
*/ */
int Node_Set_Data(struct Node * N, unsigned char * Data, size_t data_size); int ipfs_node_set_data(struct Node * N, unsigned char * Data, size_t data_size);
/*Node_Set_Encoded /*ipfs_node_set_encoded
* @param NODE: the node you wish to alter (struct Node *) * @param NODE: the node you wish to alter (struct Node *)
* @param Data: The data you wish to set in encoded.(unsigned char *) * @param Data: The data you wish to set in encoded.(unsigned char *)
* returns 1 on success 0 on failure * returns 1 on success 0 on failure
*/ */
int Node_Set_Encoded(struct Node * N, unsigned char * Data); int ipfs_node_set_encoded(struct Node * N, unsigned char * Data);
/*Node_Get_Data /*ipfs_node_get_data
* Gets data from a node * Gets data from a node
* @param Node: = The node you want to get data from. (unsigned char *) * @param Node: = The node you want to get data from. (unsigned char *)
* Returns data of node. * Returns data of node.
*/ */
unsigned char * Node_Get_Data(struct Node * N); unsigned char * ipfs_node_get_data(struct Node * N);
/*Node_Copy: Returns a copy of the node you input /*ipfs_node_copy: Returns a copy of the node you input
* @param Node: The node you want to copy (struct CP_Node *) * @param Node: The node you want to copy (struct CP_Node *)
* Returns a copy of the node you wanted to copy. * Returns a copy of the node you wanted to copy.
*/ */
struct Node * Node_Copy(struct Node * CP_Node); struct Node * ipfs_node_copy(struct Node * CP_Node);
/*Node_Delete /*ipfs_node_free
* Once you are finished using a node, always delete it using this. * Once you are finished using a node, always delete it using this.
* It will take care of the links inside it. * It will take care of the links inside it.
* @param N: the node you want to free. (struct Node *) * @param N: the node you want to free. (struct Node *)
*/ */
void Node_Delete(struct Node * N); void ipfs_node_free(struct Node * N);
/*Node_Get_Link /*ipfs_node_get_link_by_name
* Returns a copy of the link with given name * Returns a copy of the link with given name
* @param Name: (char * name) searches for link with this name * @param Name: (char * name) searches for link with this name
* Returns the link struct if it's found otherwise returns NULL * Returns the link struct if it's found otherwise returns NULL
*/ */
struct Link * Node_Get_Link(struct Node * N, char * Name); struct NodeLink * ipfs_node_get_link_by_name(struct Node * N, char * Name);
/*Node_Remove_Link /*ipfs_node_remove_link_by_name
* Removes a link from node if found by name. * Removes a link from node if found by name.
* @param name: Name of link (char * name) * @param name: Name of link (char * name)
* returns 1 on success, 0 on failure. * returns 1 on success, 0 on failure.
*/ */
int Node_Remove_Link(char * Name, struct Node * mynode); int ipfs_node_remove_link_by_name(char * Name, struct Node * mynode);
/* N_Add_Link /* ipfs_node_add_link
* Adds a link to your node * Adds a link to your node
* @param mynode: &yournode * @param mynode: &yournode
* @param mylink: the CID you want to create a node from * @param mylink: the CID you want to create a node from
* @param linksz: sizeof(your cid here) * @param linksz: sizeof(your cid here)
* Returns your node with the newly added link * Returns your node with the newly added link
*/ */
struct Node * N_Add_Link(struct Node ** mynode, struct Link * mylink, size_t linksz); struct Node * ipfs_node_add_link(struct Node ** mynode, struct NodeLink * mylink, size_t linksz);
/*N_Create_From_Link /*ipfs_node_new_from_link
* Create a node from a link * Create a node from a link
* @param mylink: the link you want to create it from. (struct Cid *) * @param mylink: the link you want to create it from. (struct Cid *)
* @param linksize: sizeof(the link in mylink) (size_T) * @param node the pointer to the new node
* Returns a fresh new node with the link you specified. Has to be freed with Node_Free preferably. * @returns true(1) on success
*/ */
struct Node * N_Create_From_Link(struct Link * mylink) ; int ipfs_node_new_from_link(struct NodeLink * mylink, struct Node** node);
/*N_Create_From_Data /*ipfs_node_new_from_data
* @param data: bytes buffer you want to create the node from * @param data: bytes buffer you want to create the node from
* returns a node with the data you inputted. * @param data_size the size of the data
* @param node the pointer to the new node
* @returns true(1) on success
*/ */
struct Node * N_Create_From_Data(unsigned char * data, size_t data_size); int ipfs_node_new_from_data(unsigned char * data, size_t data_size, struct Node** node);
/*N_Create_From_Encoded /***
* @param data: encoded bytes buffer you want to create the node from * create a Node struct from encoded data
* returns a node with the encoded data you inputted. * @param data: encoded bytes buffer you want to create the node from. Note: this copies the pointer, not a memcpy
* @param node a pointer to the node that will be created
* @returns true(1) on success
*/ */
struct Node * N_Create_From_Encoded(unsigned char * data); int ipfs_node_new_from_encoded(unsigned char * data, struct Node** node);
/*Node_Resolve_Max_Size /*Node_Resolve_Max_Size
* !!!This shouldn't concern you! * !!!This shouldn't concern you!
@ -179,7 +218,7 @@ struct Link_Proc
{ {
char * remaining_links; // Not your concern. char * remaining_links; // Not your concern.
int ammount; //This will store the ammount of links, so you know what to process. int ammount; //This will store the ammount of links, so you know what to process.
struct Link * links[]; // Link array struct NodeLink * links[]; // Link array
}; };
/*Node_Resolve_Links /*Node_Resolve_Links

View File

@ -13,9 +13,15 @@
int ipfs_merkledag_add(struct Node* node, struct FSRepo* fs_repo) { int ipfs_merkledag_add(struct Node* node, struct FSRepo* fs_repo) {
// taken from merkledag.go line 59 // taken from merkledag.go line 59
// 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 // turn the node into a block
struct Block* block; struct Block* block;
ipfs_blocks_block_new(node->data, node->data_size, &block); ipfs_blocks_block_new(protobuf, bytes_written, &block);
int retVal = fs_repo->config->datastore->datastore_put_block(block, fs_repo->config->datastore); int retVal = fs_repo->config->datastore->datastore_put_block(block, fs_repo->config->datastore);
if (retVal == 0) { if (retVal == 0) {
@ -23,7 +29,7 @@ int ipfs_merkledag_add(struct Node* node, struct FSRepo* fs_repo) {
return 0; return 0;
} }
Node_Set_Cached(node, block->cid); ipfs_node_set_cached(node, block->cid);
ipfs_blocks_block_free(block); ipfs_blocks_block_free(block);
// TODO: call HasBlock (unsure why as yet) // TODO: call HasBlock (unsure why as yet)
@ -47,8 +53,8 @@ int ipfs_merkledag_get(const struct Cid* cid, struct Node** node, const struct F
return 0; return 0;
// we have the block. Fill the node // we have the block. Fill the node
*node = N_Create_From_Data(block->data, block->data_length); ipfs_node_protobuf_decode(block->data, block->data_length, node);
Node_Set_Cached(*node, cid); ipfs_node_set_cached(*node, cid);
ipfs_blocks_block_free(block); ipfs_blocks_block_free(block);

View File

@ -10,74 +10,300 @@
#include "ipfs/node/node.h" #include "ipfs/node/node.h"
// for protobuf Node data & data_size encoded cid link_amount & links
enum WireType ipfs_node_message_fields[] = { WIRETYPE_LENGTH_DELIMITED, WIRETYPE_LENGTH_DELIMITED, WIRETYPE_LENGTH_DELIMITED, WIRETYPE_LENGTH_DELIMITED };
// for protobuf NodeLink name cid
enum WireType ipfs_node_link_message_fields[] = { WIRETYPE_LENGTH_DELIMITED, WIRETYPE_LENGTH_DELIMITED };
/*==================================================================================== /*====================================================================================
* Link Functions * Link Functions
*===================================================================================*/ *===================================================================================*/
/* Create_Link /* ipfs_node_link_new
* @Param name: The name of the link (char *) * @Param name: The name of the link (char *)
* @Param size: Size of the link (size_t) * @Param size: Size of the link (size_t)
* @Param ahash: An Qmhash * @Param ahash: An Qmhash
*/ */
struct Link * Create_Link(char * name, unsigned char * ahash) int ipfs_node_link_new(char * name, unsigned char * ahash, struct NodeLink** node_link)
{ {
struct Link * mylink; *node_link = malloc(sizeof(struct NodeLink));
mylink = malloc(sizeof(struct Link)); if (*node_link == NULL)
mylink->name = name; return 0;
(*node_link)->name = name;
int ver = 0; int ver = 0;
size_t lenhash = strlen((char*)ahash)-1; size_t lenhash = strlen((char*)ahash);
ipfs_cid_new(ver, ahash, lenhash*2, CID_PROTOBUF, &mylink->Lcid); if (ipfs_cid_new(ver, ahash, lenhash, CID_PROTOBUF, &(*node_link)->cid) == 0) {
mylink->size = sizeof(mylink) + mylink->Lcid->hash_length; //Unsure of this free(*node_link);
return mylink; return 0;
}
return 1;
} }
/* Free_Link /* ipfs_node_link_free
* @param L: Free the link you have allocated. * @param node_link: Free the link you have allocated.
*/ */
void Free_Link(struct Link * L) int ipfs_node_link_free(struct NodeLink * node_link)
{ {
ipfs_cid_free(L->Lcid); if (node_link != NULL)
free(L); ipfs_cid_free(node_link->cid);
free(node_link);
return 1;
} }
int ipfs_node_link_protobuf_encode_size(struct NodeLink* link) {
if (link == NULL)
return 0;
size_t size = 0;
size += 11 + strlen(link->name);
size += ipfs_cid_protobuf_encode_size(link->cid);
return size;
}
int ipfs_node_link_protobuf_encode(struct NodeLink* link, unsigned char* buffer, size_t max_buffer_length, size_t* bytes_written) {
size_t bytes_used = 0;
int retVal = 0;
*bytes_written = 0;
retVal = protobuf_encode_length_delimited(1, ipfs_node_link_message_fields[0], link->name, strlen(link->name), &buffer[*bytes_written], max_buffer_length - *bytes_written, &bytes_used);
*bytes_written += bytes_used;
// cid
size_t cid_size = ipfs_cid_protobuf_encode_size(link->cid);
unsigned char cid_buffer[cid_size];
retVal = ipfs_cid_protobuf_encode(link->cid, cid_buffer, cid_size, &bytes_used);
retVal = protobuf_encode_length_delimited(2, ipfs_node_link_message_fields[1], cid_buffer, bytes_used, &buffer[*bytes_written], max_buffer_length - *bytes_written, &bytes_used);
*bytes_written += bytes_used;
return 1;
}
int ipfs_node_link_protobuf_decode(unsigned char* buffer, size_t buffer_length, struct NodeLink** link, size_t* bytes_read) {
size_t pos = 0;
int retVal = 0;
*link = (struct NodeLink*)malloc(sizeof(struct NodeLink));
(*link)->cid = NULL;
(*link)->name = NULL;
unsigned char* temp_buffer = NULL;
size_t temp_size;
if (*link == NULL)
goto exit;
while(pos < buffer_length) {
size_t bytes_read = 0;
int field_no;
enum WireType field_type;
if (protobuf_decode_field_and_type(&buffer[pos], buffer_length, &field_no, &field_type, &bytes_read) == 0) {
goto exit;
}
pos += bytes_read;
switch(field_no) {
case (1):
if (protobuf_decode_string(&buffer[pos], buffer_length - pos, &((*link)->name), &bytes_read) == 0)
goto exit;
pos += bytes_read;
break;
case (2):
if (protobuf_decode_length_delimited(&buffer[pos], buffer_length - pos, (char**)&temp_buffer, &temp_size, &bytes_read) == 0)
goto exit;
ipfs_cid_protobuf_decode(temp_buffer, temp_size, &((*link)->cid));
pos += bytes_read;
free(temp_buffer);
temp_buffer = NULL;
break;
}
}
retVal = 1;
exit:
if (retVal == 0) {
if (link != NULL)
ipfs_node_link_free(*link);
}
if (temp_buffer != NULL)
free(temp_buffer);
return retVal;
}
/***
* return an approximate size of the encoded node
*/
size_t ipfs_node_protobuf_encode_size(struct Node* node) {
size_t size = 0;
// data
size += 11 + node->data_size;
// encoded
size += 11;
if (node->encoded != NULL)
size += strlen((const char*)node->encoded);
// cid (a.k.a. cached)
size += 11 + ipfs_cid_protobuf_encode_size(node->cached);
// links
size += 11;
for(int i = 0; i < node->link_amount; i++) {
size += 11 + strlen(node->links[i]->name) + ipfs_cid_protobuf_encode_size(node->links[i]->cid);
}
return size;
}
/***
* Encode a node into a protobuf byte stream
* @param node the node to encode
* @param buffer where to put it
* @param max_buffer_length the length of buffer
* @param bytes_written how much of buffer was used
* @returns true(1) on success
*/
int ipfs_node_protobuf_encode(struct Node* node, unsigned char* buffer, size_t max_buffer_length, size_t* bytes_written) {
// data & data_size
size_t bytes_used = 0;
*bytes_written = 0;
int retVal = 0;
retVal = protobuf_encode_length_delimited(1, ipfs_node_message_fields[0], node->data, node->data_size, &buffer[*bytes_written], max_buffer_length - *bytes_written, &bytes_used);
*bytes_written += bytes_used;
int sz = 0;
if (node->encoded != NULL)
sz = strlen(node->encoded);
retVal = protobuf_encode_length_delimited(2, ipfs_node_message_fields[1], node->encoded, sz, &buffer[*bytes_written], max_buffer_length - *bytes_written, &bytes_used);
*bytes_written += bytes_used;
// cid
size_t cid_size = ipfs_cid_protobuf_encode_size(node->cached);
unsigned char cid[cid_size];
retVal = ipfs_cid_protobuf_encode(node->cached, cid, cid_size, &cid_size);
retVal = protobuf_encode_length_delimited(3, ipfs_node_message_fields[2], cid, cid_size, &buffer[*bytes_written], max_buffer_length - *bytes_written, &bytes_used);
*bytes_written += bytes_used;
// links
for(int i = 0; i < node->link_amount; i++) {
// size + name + cid
size_t link_buffer_size = 11 + ipfs_node_link_protobuf_encode_size(node->links[i]);
unsigned char link_buffer[link_buffer_size];
retVal = ipfs_node_link_protobuf_encode(node->links[i], link_buffer, link_buffer_size, &link_buffer_size);
protobuf_encode_length_delimited(4, ipfs_node_message_fields[3], link_buffer, link_buffer_size, &buffer[*bytes_written], max_buffer_length - *bytes_written, &bytes_used);
*bytes_written += bytes_used;
}
return 1;
}
/***
* Decode a stream of bytes into a Node structure
* @param buffer where to get the bytes from
* @param buffer_length the length of buffer
* @param node pointer to the Node to be created
* @returns true(1) on success
*/
int ipfs_node_protobuf_decode(unsigned char* buffer, size_t buffer_length, struct Node** node) {
/*
* Field 0: data
* Field 1: encoded
* Field 3: cid
* Field 4: links array
*/
size_t pos = 0;
int retVal = 0;
unsigned char* temp_buffer = NULL;
size_t temp_size;
struct NodeLink* temp_link = NULL;
if (ipfs_node_new(node) == 0)
goto exit;
while(pos < buffer_length) {
size_t bytes_read = 0;
int field_no;
enum WireType field_type;
if (protobuf_decode_field_and_type(&buffer[pos], buffer_length, &field_no, &field_type, &bytes_read) == 0) {
goto exit;
}
pos += bytes_read;
switch(field_no) {
case (1): // data
if (protobuf_decode_length_delimited(&buffer[pos], buffer_length - pos, (char**)&((*node)->data), &((*node)->data_size), &bytes_read) == 0)
goto exit;
pos += bytes_read;
break;
case (2): // encoded
if (protobuf_decode_length_delimited(&buffer[pos], buffer_length - pos, (char**)&((*node)->encoded), &temp_size, &bytes_read) == 0)
goto exit;
pos += bytes_read;
break;
case (3): // cid
if (protobuf_decode_length_delimited(&buffer[pos], buffer_length - pos, (char**)&temp_buffer, &temp_size, &bytes_read) == 0)
goto exit;
pos += bytes_read;
if (ipfs_cid_protobuf_decode(temp_buffer, temp_size, &((*node)->cached)) == 0)
goto exit;
free(temp_buffer);
temp_buffer = NULL;
break;
case (4): // links
if (protobuf_decode_length_delimited(&buffer[pos], buffer_length - pos, (char**)&temp_buffer, &temp_size, &bytes_read) == 0)
goto exit;
pos += bytes_read;
if (ipfs_node_link_protobuf_decode(temp_buffer, temp_size, &temp_link, &bytes_read) == 0)
goto exit;
free(temp_buffer);
temp_buffer = NULL;
*node = ipfs_node_add_link(node, temp_link, sizeof(temp_link));
ipfs_node_link_free(temp_link);
temp_link = NULL;
break;
}
}
retVal = 1;
exit:
if (retVal == 0) {
ipfs_node_free(*node);
}
if (temp_link != NULL)
ipfs_node_link_free(temp_link);
if (temp_buffer != NULL)
free(temp_buffer);
return retVal;
}
/*==================================================================================== /*====================================================================================
* Node Functions * Node Functions
*===================================================================================*/ *===================================================================================*/
/*Create_Empty_Node /*ipfs_node_new
* Creates an empty node, allocates the required memory * Creates an empty node, allocates the required memory
* Returns a fresh new node with no data set in it. * Returns a fresh new node with no data set in it.
*/ */
struct Node * Create_Empty_Node() int ipfs_node_new(struct Node** node)
{ {
struct Node * N; *node = (struct Node *)malloc(sizeof(struct Node));
N = (struct Node *)malloc(sizeof(struct Node)); if (*node == NULL)
N->cached = NULL; return 0;
N->data = NULL; (*node)->cached = NULL;
N->encoded = NULL; (*node)->data = NULL;
N->link_amount = 0; (*node)->encoded = NULL;
return N; (*node)->link_amount = 0;
return 1;
} }
/** /**
* Set the cached struct element * Set the cached struct element
* @param N the node to be modified * @param node the node to be modified
* @param TheCid the Cid to be copied into the Node->cached element * @param cid the Cid to be copied into the Node->cached element
* @returns true(1) on success * @returns true(1) on success
*/ */
int Node_Set_Cached(struct Node * N, struct Cid * TheCid) int ipfs_node_set_cached(struct Node* node, struct Cid* cid)
{ {
if (N->cached != NULL) if (node->cached != NULL)
ipfs_cid_free(N->cached); ipfs_cid_free(node->cached);
return ipfs_cid_new(TheCid->version, TheCid->hash, TheCid->hash_length, TheCid->codec, &(N->cached)); return ipfs_cid_new(cid->version, cid->hash, cid->hash_length, cid->codec, &(node->cached));
} }
/*Node_Set_Data /*ipfs_node_set_data
* Sets the data of a node * Sets the data of a node
* @param Node: The node which you want to set data in. * @param Node: The node which you want to set data in.
* @param Data, the data you want to assign to the node * @param Data, the data you want to assign to the node
* Sets pointers of encoded & cached to NULL /following go method * Sets pointers of encoded & cached to NULL /following go method
* returns 1 on success 0 on failure * returns 1 on success 0 on failure
*/ */
int Node_Set_Data(struct Node * N, unsigned char * Data, size_t data_size) int ipfs_node_set_data(struct Node * N, unsigned char * Data, size_t data_size)
{ {
if(!N || !Data) if(!N || !Data)
{ {
@ -94,12 +320,12 @@ int Node_Set_Data(struct Node * N, unsigned char * Data, size_t data_size)
return 1; return 1;
} }
/*Node_Set_Encoded /*ipfs_node_set_encoded
* @param NODE: the node you wish to alter (struct Node *) * @param NODE: the node you wish to alter (struct Node *)
* @param Data: The data you wish to set in encoded.(unsigned char *) * @param Data: The data you wish to set in encoded.(unsigned char *)
* returns 1 on success 0 on failure * returns 1 on success 0 on failure
*/ */
int Node_Set_Encoded(struct Node * N, unsigned char * Data) int ipfs_node_set_encoded(struct Node * N, unsigned char * Data)
{ {
if(!N || !Data) if(!N || !Data)
{ {
@ -111,43 +337,43 @@ int Node_Set_Encoded(struct Node * N, unsigned char * Data)
//N->data = NULL; //N->data = NULL;
return 1; return 1;
} }
/*Node_Get_Data /*ipfs_node_get_data
* Gets data from a node * Gets data from a node
* @param Node: = The node you want to get data from. (unsigned char *) * @param Node: = The node you want to get data from. (unsigned char *)
* Returns data of node. * Returns data of node.
*/ */
unsigned char * Node_Get_Data(struct Node * N) unsigned char * ipfs_node_get_data(struct Node * N)
{ {
unsigned char * DATA; unsigned char * DATA;
DATA = N->data; DATA = N->data;
return DATA; return DATA;
} }
/*Node_Copy: Returns a copy of the node you input /*ipfs_node_copy: Returns a copy of the node you input
* @param Node: The node you want to copy (struct CP_Node *) * @param Node: The node you want to copy (struct CP_Node *)
* Returns a copy of the node you wanted to copy. * Returns a copy of the node you wanted to copy.
*/ */
struct Node * Node_Copy(struct Node * CP_Node) struct Node * ipfs_node_copy(struct Node * CP_Node)
{ {
struct Node * CN; struct Node * CN;
CN = (struct Node*) malloc(sizeof(struct Node) + sizeof(struct Link) * 2); CN = (struct Node*) malloc(sizeof(struct Node) + sizeof(struct NodeLink) * 2);
if(CP_Node->link_amount != 0) if(CP_Node->link_amount != 0)
{ {
for(int i=0; i<CP_Node->link_amount; i++) for(int i=0; i<CP_Node->link_amount; i++)
{ {
CN->links[i] = malloc(sizeof(struct Link)); CN->links[i] = malloc(sizeof(struct NodeLink));
} }
} }
memcpy(CN, CP_Node, sizeof(struct Node)); memcpy(CN, CP_Node, sizeof(struct Node));
memcpy(CN->links[0],CP_Node->links[0], sizeof(struct Link)); memcpy(CN->links[0],CP_Node->links[0], sizeof(struct NodeLink));
return CN; return CN;
} }
/*Node_Delete /*ipfs_node_free
* Once you are finished using a node, always delete it using this. * Once you are finished using a node, always delete it using this.
* It will take care of the links inside it. * It will take care of the links inside it.
* @param N: the node you want to free. (struct Node *) * @param N: the node you want to free. (struct Node *)
*/ */
void Node_Delete(struct Node * N) void ipfs_node_free(struct Node * N)
{ {
if(N) if(N)
{ {
@ -168,35 +394,35 @@ void Node_Delete(struct Node * N)
free(N); free(N);
} }
} }
/*Node_Get_Link /*ipfs_node_get_link_by_name
* Returns a copy of the link with given name * Returns a copy of the link with given name
* @param Name: (char * name) searches for link with this name * @param Name: (char * name) searches for link with this name
* Returns the link struct if it's found otherwise returns NULL * Returns the link struct if it's found otherwise returns NULL
*/ */
struct Link * Node_Get_Link(struct Node * N, char * Name) struct NodeLink * ipfs_node_get_link_by_name(struct Node * N, char * Name)
{ {
struct Link * L; struct NodeLink * L;
for(int i=0;i<N->link_amount;i++) for(int i=0;i<N->link_amount;i++)
{ {
if(strcmp(N->links[i]->name,Name) == 0) if(strcmp(N->links[i]->name,Name) == 0)
{ {
L = (struct Link *)malloc(sizeof(struct Link)); L = (struct NodeLink *)malloc(sizeof(struct NodeLink));
memcpy(L,N->links[i],sizeof(struct Link)); memcpy(L,N->links[i],sizeof(struct NodeLink));
int ver = L->Lcid->version; int ver = L->cid->version;
unsigned char * ahash = L->Lcid->hash; unsigned char * ahash = L->cid->hash;
size_t lenhash = L->Lcid->hash_length; size_t lenhash = L->cid->hash_length;
ipfs_cid_new(ver, ahash, lenhash, CID_PROTOBUF, &L->Lcid); ipfs_cid_new(ver, ahash, lenhash, CID_PROTOBUF, &L->cid);
return L; return L;
} }
} }
return NULL; return NULL;
} }
/*Node_Remove_Link /*ipfs_node_remove_link_by_name
* Removes a link from node if found by name. * Removes a link from node if found by name.
* @param name: Name of link (char * name) * @param name: Name of link (char * name)
* returns 1 on success, 0 on failure. * returns 1 on success, 0 on failure.
*/ */
int Node_Remove_Link(char * Name, struct Node * mynode) int ipfs_node_remove_link_by_name(char * Name, struct Node * mynode)
{ {
for(int i=0; i<mynode->link_amount; i++) for(int i=0; i<mynode->link_amount; i++)
{ {
@ -204,7 +430,7 @@ int Node_Remove_Link(char * Name, struct Node * mynode)
{ {
for(int x=i;x<mynode->link_amount && x+1 != mynode->link_amount;i++) for(int x=i;x<mynode->link_amount && x+1 != mynode->link_amount;i++)
{ {
memcpy(mynode->links[x],mynode->links[x+1],sizeof(struct Link)); memcpy(mynode->links[x],mynode->links[x+1],sizeof(struct NodeLink));
} }
free(mynode->links[mynode->link_amount-1]); free(mynode->links[mynode->link_amount-1]);
mynode->link_amount--; mynode->link_amount--;
@ -213,14 +439,14 @@ int Node_Remove_Link(char * Name, struct Node * mynode)
} }
return 0; return 0;
} }
/* N_Add_Link /* ipfs_node_add_link
* Adds a link to your nodse * Adds a link to your nodse
* @param mynode: &yournode * @param mynode: &yournode
* @param mylink: the CID you want to create a node from * @param mylink: the CID you want to create a node from
* @param linksz: sizeof(your cid here) * @param linksz: sizeof(your cid here)
* Returns your node with the newly added link * Returns your node with the newly added link
*/ */
struct Node * N_Add_Link(struct Node ** mynode, struct Link * mylink, size_t linksz) struct Node * ipfs_node_add_link(struct Node ** mynode, struct NodeLink * mylink, size_t linksz)
{ {
struct Node * Nl = *mynode; struct Node * Nl = *mynode;
Nl->link_amount++; Nl->link_amount++;
@ -238,64 +464,69 @@ struct Node * N_Add_Link(struct Node ** mynode, struct Link * mylink, size_t lin
{ {
Nl = (struct Node *) malloc(sizeof(struct Node) + linksz); Nl = (struct Node *) malloc(sizeof(struct Node) + linksz);
} }
Nl->links[Nl->link_amount-1] = malloc(sizeof(struct Link)); Nl->links[Nl->link_amount-1] = malloc(sizeof(struct NodeLink));
memcpy(Nl->links[Nl->link_amount-1],mylink,sizeof(struct Link)); memcpy(Nl->links[Nl->link_amount-1],mylink,sizeof(struct NodeLink));
return Nl; return Nl;
} }
/*N_Create_From_Link /*ipfs_node_new_from_link
* Create a node from a link * Create a node from a link
* @param mylink: the link you want to create it from. (struct Cid *) * @param mylink: the link you want to create it from. (struct Cid *)
* @param linksize: sizeof(the link in mylink) (size_T) * @param linksize: sizeof(the link in mylink) (size_T)
* Returns a fresh new node with the link you specified. Has to be freed with Node_Free preferably. * Returns a fresh new node with the link you specified. Has to be freed with Node_Free preferably.
*/ */
struct Node * N_Create_From_Link(struct Link * mylink) int ipfs_node_new_from_link(struct NodeLink * mylink, struct Node** node)
{ {
struct Node * mynode; *node = (struct Node *) malloc(sizeof(struct Node) + sizeof(struct NodeLink));
mynode = (struct Node *) malloc(sizeof(struct Node) + sizeof(struct Link)); if (*node == NULL)
mynode->link_amount = 1; return 0;
mynode->links[0] = malloc(sizeof(struct Link)); (*node)->link_amount = 1;
memcpy(mynode->links[0], mylink, sizeof(struct Link)); (*node)->links[0] = malloc(sizeof(struct NodeLink));
mynode->cached = NULL; if ((*node)->links[0] == NULL) {
mynode->data = NULL; free(*node);
mynode->encoded = NULL; return 0;
return mynode; }
memcpy((*node)->links[0], mylink, sizeof(struct NodeLink));
(*node)->cached = NULL;
(*node)->data = NULL;
(*node)->encoded = NULL;
return 1;
} }
/*N_Create_From_Data
/**
* create a new Node struct with data
* @param data: bytes buffer you want to create the node from * @param data: bytes buffer you want to create the node from
* @param data_size the size of the data buffer
* @param node a pointer to the node to be created
* returns a node with the data you inputted. * returns a node with the data you inputted.
*/ */
struct Node * N_Create_From_Data(unsigned char * data, size_t data_size) int ipfs_node_new_from_data(unsigned char * data, size_t data_size, struct Node** node)
{ {
if(data) if(data)
{ {
struct Node * mynode; if (ipfs_node_new(node) == 0)
mynode = (struct Node *) malloc(sizeof(struct Node)); return 0;
Node_Set_Data(mynode, data, data_size); return ipfs_node_set_data(*node, data, data_size);
mynode->link_amount=0;
mynode->encoded = NULL;
mynode->cached = NULL;
return mynode;
} }
return NULL; return 0;
} }
/*N_Create_From_Encoded
* @param data: encoded bytes buffer you want to create the node from /***
* returns a node with the encoded data you inputted. * create a Node struct from encoded data
* @param data: encoded bytes buffer you want to create the node from. Note: this copies the pointer, not a memcpy
* @param node a pointer to the node that will be created
* @returns true(1) on success
*/ */
struct Node * N_Create_From_Encoded(unsigned char * data) int ipfs_node_new_from_encoded(unsigned char * data, struct Node** node)
{ {
if(data) if(data)
{ {
struct Node * mynode; if (ipfs_node_new(node) == 0)
mynode = (struct Node *) malloc(sizeof(struct Node)); return 0;
mynode->encoded = data; (*node)->encoded = data;
mynode->link_amount = 0; return 1;
mynode->data = NULL;
mynode->cached = NULL;
return mynode;
} }
return NULL; return 0;
} }
/*Node_Resolve_Max_Size /*Node_Resolve_Max_Size
* !!!This shouldn't concern you! * !!!This shouldn't concern you!
@ -364,18 +595,18 @@ struct Link_Proc * Node_Resolve_Links(struct Node * N, char * path)
return NULL; return NULL;
} }
int expected_link_ammount = Node_Resolve_Max_Size(path); int expected_link_ammount = Node_Resolve_Max_Size(path);
struct Link_Proc * LProc = (struct Link_Proc *) malloc(sizeof(struct Link_Proc) + sizeof(struct Link) * expected_link_ammount); struct Link_Proc * LProc = (struct Link_Proc *) malloc(sizeof(struct Link_Proc) + sizeof(struct NodeLink) * expected_link_ammount);
LProc->ammount = 0; LProc->ammount = 0;
char * linknames[expected_link_ammount]; char * linknames[expected_link_ammount];
Node_Resolve(linknames, path); Node_Resolve(linknames, path);
for(int i=0;i<expected_link_ammount; i++) for(int i=0;i<expected_link_ammount; i++)
{ {
struct Link * proclink; struct NodeLink * proclink;
proclink = Node_Get_Link(N, linknames[i]); proclink = ipfs_node_get_link_by_name(N, linknames[i]);
if(proclink) if(proclink)
{ {
LProc->links[i] = (struct Link *)malloc(sizeof(struct Link)); LProc->links[i] = (struct NodeLink *)malloc(sizeof(struct NodeLink));
memcpy(LProc->links[i], proclink, sizeof(struct Link)); memcpy(LProc->links[i], proclink, sizeof(struct NodeLink));
LProc->ammount++; LProc->ammount++;
free(proclink); free(proclink);
} }
@ -397,7 +628,7 @@ void Free_Link_Proc(struct Link_Proc * LPRC)
{ {
for(int i=0;i<LPRC->ammount;i++) for(int i=0;i<LPRC->ammount;i++)
{ {
Free_Link(LPRC->links[i]); ipfs_node_link_free(LPRC->links[i]);
} }
} }
free(LPRC); free(LPRC);

View File

@ -40,11 +40,12 @@ int test_merkledag_get_data() {
} }
// create a node // create a node
struct Node* node1 = N_Create_From_Data(binary_data, binary_data_size); struct Node* node1;
retVal = ipfs_node_new_from_data(binary_data, binary_data_size, &node1);
retVal = ipfs_merkledag_add(node1, fs_repo); retVal = ipfs_merkledag_add(node1, fs_repo);
if (retVal == 0) { if (retVal == 0) {
Node_Delete(node1); ipfs_node_free(node1);
ipfs_repo_fsrepo_free(fs_repo); ipfs_repo_fsrepo_free(fs_repo);
return 0; return 0;
} }
@ -53,15 +54,15 @@ int test_merkledag_get_data() {
struct Node* results_node; struct Node* results_node;
retVal = ipfs_merkledag_get(node1->cached, &results_node, fs_repo); retVal = ipfs_merkledag_get(node1->cached, &results_node, fs_repo);
if (retVal == 0) { if (retVal == 0) {
Node_Delete(node1); ipfs_node_free(node1);
Node_Delete(results_node); ipfs_node_free(results_node);
ipfs_repo_fsrepo_free(fs_repo); ipfs_repo_fsrepo_free(fs_repo);
return 0; return 0;
} }
if (results_node->data_size != 256) { if (results_node->data_size != 256) {
Node_Delete(node1); ipfs_node_free(node1);
Node_Delete(results_node); ipfs_node_free(results_node);
ipfs_repo_fsrepo_free(fs_repo); ipfs_repo_fsrepo_free(fs_repo);
return 0; return 0;
} }
@ -69,15 +70,15 @@ int test_merkledag_get_data() {
// the data should be the same // the data should be the same
for(int i = 0; i < results_node->data_size; i++) { for(int i = 0; i < results_node->data_size; i++) {
if (results_node->data[i] != node1->data[i]) { if (results_node->data[i] != node1->data[i]) {
Node_Delete(node1); ipfs_node_free(node1);
Node_Delete(results_node); ipfs_node_free(results_node);
ipfs_repo_fsrepo_free(fs_repo); ipfs_repo_fsrepo_free(fs_repo);
return 0; return 0;
} }
} }
Node_Delete(node1); ipfs_node_free(node1);
Node_Delete(results_node); ipfs_node_free(results_node);
ipfs_repo_fsrepo_free(fs_repo); ipfs_repo_fsrepo_free(fs_repo);
return retVal; return retVal;
@ -86,7 +87,7 @@ int test_merkledag_get_data() {
int test_merkledag_add_data() { int test_merkledag_add_data() {
int retVal = 0; int retVal = 0;
struct FSRepo* fs_repo = createAndOpenRepo("/tmp.ipfs"); struct FSRepo* fs_repo = createAndOpenRepo("/tmp/.ipfs");
if (fs_repo == NULL) if (fs_repo == NULL)
return 0; return 0;
@ -101,11 +102,12 @@ int test_merkledag_add_data() {
} }
// create a node // create a node
struct Node* node1 = N_Create_From_Data(binary_data, binary_data_size); struct Node* node1;
retVal = ipfs_node_new_from_data(binary_data, binary_data_size, &node1);
retVal = ipfs_merkledag_add(node1, fs_repo); retVal = ipfs_merkledag_add(node1, fs_repo);
if (retVal == 0) { if (retVal == 0) {
Node_Delete(node1); ipfs_node_free(node1);
return 0; return 0;
} }
@ -115,30 +117,31 @@ int test_merkledag_add_data() {
int first_add_size = os_utils_file_size("/tmp/.ipfs/datastore/data.mdb"); int first_add_size = os_utils_file_size("/tmp/.ipfs/datastore/data.mdb");
if (first_add_size == start_file_size) { // uh oh, database should have increased in size if (first_add_size == start_file_size) { // uh oh, database should have increased in size
Node_Delete(node1); ipfs_node_free(node1);
return 0; return 0;
} }
// adding the same binary again should do nothing (the hash should be the same) // adding the same binary again should do nothing (the hash should be the same)
struct Node* node2 = N_Create_From_Data(binary_data, binary_data_size); struct Node* node2;
retVal = ipfs_node_new_from_data(binary_data, binary_data_size, &node2);
retVal = ipfs_merkledag_add(node2, fs_repo); retVal = ipfs_merkledag_add(node2, fs_repo);
if (retVal == 0) { if (retVal == 0) {
Node_Delete(node1); ipfs_node_free(node1);
Node_Delete(node2); ipfs_node_free(node2);
return 0; return 0;
} }
// make sure everything is correct // make sure everything is correct
if (node2->cached == NULL) { if (node2->cached == NULL) {
Node_Delete(node1); ipfs_node_free(node1);
Node_Delete(node2); ipfs_node_free(node2);
return 0; return 0;
} }
for(int i = 0; i < node1->cached->hash_length; i++) { for(int i = 0; i < node1->cached->hash_length; i++) {
if (node1->cached->hash[i] != node2->cached->hash[i]) { if (node1->cached->hash[i] != node2->cached->hash[i]) {
printf("hash of node1 does not match node2 at position %d\n", i); printf("hash of node1 does not match node2 at position %d\n", i);
Node_Delete(node1); ipfs_node_free(node1);
Node_Delete(node2); ipfs_node_free(node2);
return 0; return 0;
} }
} }
@ -146,35 +149,36 @@ int test_merkledag_add_data() {
int second_add_size = os_utils_file_size("/tmp/.ipfs/datastore/data.mdb"); int second_add_size = os_utils_file_size("/tmp/.ipfs/datastore/data.mdb");
if (first_add_size != second_add_size) { // uh oh, the database shouldn't have changed size if (first_add_size != second_add_size) { // uh oh, the database shouldn't have changed size
printf("looks as if a new record was added when it shouldn't have. Old file size: %d, new file size: %d\n", first_add_size, second_add_size); printf("looks as if a new record was added when it shouldn't have. Old file size: %d, new file size: %d\n", first_add_size, second_add_size);
Node_Delete(node1); ipfs_node_free(node1);
Node_Delete(node2); ipfs_node_free(node2);
return 0; return 0;
} }
// now change 1 byte, which should change the hash // now change 1 byte, which should change the hash
binary_data[10] = 0; binary_data[10] = 0;
// create a node // create a node
struct Node* node3 = N_Create_From_Data(binary_data, binary_data_size); struct Node* node3;
retVal = ipfs_node_new_from_data(binary_data, binary_data_size, &node3);
retVal = ipfs_merkledag_add(node3, fs_repo); retVal = ipfs_merkledag_add(node3, fs_repo);
if (retVal == 0) { if (retVal == 0) {
Node_Delete(node1); ipfs_node_free(node1);
Node_Delete(node2); ipfs_node_free(node2);
Node_Delete(node3); ipfs_node_free(node3);
return 0; return 0;
} }
// make sure everything is correct // make sure everything is correct
if (node3->cached == NULL) { if (node3->cached == NULL) {
Node_Delete(node1); ipfs_node_free(node1);
Node_Delete(node2); ipfs_node_free(node2);
Node_Delete(node3); ipfs_node_free(node3);
return 0; return 0;
} }
Node_Delete(node1); ipfs_node_free(node1);
Node_Delete(node2); ipfs_node_free(node2);
Node_Delete(node3); ipfs_node_free(node3);
int third_add_size = os_utils_file_size("/tmp/.ipfs/datastore/data.mdb"); int third_add_size = os_utils_file_size("/tmp/.ipfs/datastore/data.mdb");
if (third_add_size == second_add_size || third_add_size < second_add_size) {// uh oh, it didn't add it if (third_add_size == second_add_size || third_add_size < second_add_size) {// uh oh, it didn't add it
printf("Node 3 should have been added, but the file size did not change from %d.\n", third_add_size); printf("Node 3 should have been added, but the file size did not change from %d.\n", third_add_size);
@ -201,46 +205,47 @@ int test_merkledag_add_node_with_links() {
} }
// make link // make link
link = Create_Link("", "abc123"); retVal = ipfs_node_link_new("", "abc123", &link);
node1 = N_Create_From_Link(link); retVal = ipfs_node_new_from_link(link, &node1);
retVal = ipfs_merkledag_add(node1, fs_repo); retVal = ipfs_merkledag_add(node1, fs_repo);
if (retVal == 0) { if (retVal == 0) {
ipfs_repo_fsrepo_free(fs_repo); ipfs_repo_fsrepo_free(fs_repo);
Node_Delete(node1); ipfs_node_free(node1);
printf("Unable to add node\n"); printf("Unable to add node\n");
return 0; return 0;
} }
// now look for it // now look for it
struct Node* node2 = NULL; struct Node* node2 = NULL;
retVal = ipfs_merkledag_get(node1->cached, &node2, fs_repo); retVal = ipfs_merkledag_get(node1->cached, &node2, fs_repo);
if (retVal == 0) { if (retVal == 0) {
ipfs_repo_fsrepo_free(fs_repo); ipfs_repo_fsrepo_free(fs_repo);
Node_Delete(node1); ipfs_node_free(node1);
return 0; return 0;
} }
if (node2->link_amount != node1->link_amount) { if (node2->link_amount != node1->link_amount) {
printf("Link amount %d does not match %d\n", node2->link_amount, node1->link_amount);
ipfs_repo_fsrepo_free(fs_repo); ipfs_repo_fsrepo_free(fs_repo);
Node_Delete(node1); ipfs_node_free(node1);
Node_Delete(node2); ipfs_node_free(node2);
printf("Link number do not match. Should be %d and are %d\n", node1->link_amount, node2->link_amount);
return 0; return 0;
} }
// make sure hashes match // make sure hashes match
for(int i = 0; i < node1->links[0]->Lcid->hash_length; i++) { for(int i = 0; i < node1->links[0]->cid->hash_length; i++) {
if(node1->links[0]->Lcid->hash[i] != node2->links[0]->Lcid->hash[i]) { if(node1->links[0]->cid->hash[i] != node2->links[0]->cid->hash[i]) {
ipfs_repo_fsrepo_free(fs_repo);
Node_Delete(node1);
Node_Delete(node2);
printf("Hashes do not match\n"); printf("Hashes do not match\n");
ipfs_repo_fsrepo_free(fs_repo);
ipfs_node_free(node1);
ipfs_node_free(node2);
return 0; return 0;
} }
} }
Node_Delete(node1); ipfs_node_free(node1);
Node_Delete(node2); ipfs_node_free(node2);
ipfs_repo_fsrepo_free(fs_repo); ipfs_repo_fsrepo_free(fs_repo);
return 1; return 1;

View File

@ -4,39 +4,173 @@ int test_node() {
//Variables of link: //Variables of link:
char * name = "Alex"; char * name = "Alex";
unsigned char * ahash = "QmYwAPJzv5CZsnA625s3Xf2nemtYgPpHdWEz79ojWnPbdG"; unsigned char * ahash = "QmYwAPJzv5CZsnA625s3Xf2nemtYgPpHdWEz79ojWnPbdG";
struct Link * mylink; struct NodeLink * mylink;
mylink = Create_Link(name,ahash); int retVal = ipfs_node_link_new(name,ahash, &mylink);
printf("===================================\n" \ printf("===================================\n" \
"Node Link:\n" \ "Node Link:\n" \
" -Name: %s\n" \ " -Name: %s\n" \
" -Size: %lu\n" \
"\n Cid Details:\n\n" \ "\n Cid Details:\n\n" \
" -Version: %d\n" \ " -Version: %d\n" \
" -Codec: %c\n" \ " -Codec: %c\n" \
" -Hash: %s\n" \ " -Hash: %s\n" \
" -Hash Length: %lu\n" \ " -Hash Length: %lu\n" \
"====================================\n" \ "====================================\n" \
, mylink->name, mylink->size, mylink->Lcid->version,mylink->Lcid->codec,mylink->Lcid->hash,mylink->Lcid->hash_length); , mylink->name, mylink->cid->version,mylink->cid->codec,mylink->cid->hash,mylink->cid->hash_length);
//Link Two for testing purposes //Link Two for testing purposes
char * name2 = "Simo"; char * name2 = "Simo";
unsigned char * ahash2 = "QmYwAPJzv5CZsnA625s3Xf2nemtYgPpHdWEz79ojWnSimo"; unsigned char * ahash2 = "QmYwAPJzv5CZsnA625s3Xf2nemtYgPpHdWEz79ojWnSimo";
struct Link * mylink2; struct NodeLink * mylink2;
mylink2 = Create_Link(name2,ahash2); retVal = ipfs_node_link_new(name2, ahash2, &mylink2);
//Nodes //Nodes
struct Node * Mynode; struct Node * Mynode;
Mynode = N_Create_From_Link(mylink); retVal = ipfs_node_new_from_link(mylink, &Mynode);
mylink->name = "HAHA";//Testing for valid node creation mylink->name = "HAHA";//Testing for valid node creation
printf("Node Link[0] Name: %s\nHash: %s\n",Mynode->links[0]->name, Mynode->links[0]->Lcid->hash); printf("Node Link[0] Name: %s\nHash: %s\n",Mynode->links[0]->name, Mynode->links[0]->cid->hash);
Mynode = N_Add_Link(&Mynode, mylink2, sizeof(mylink2)); Mynode = ipfs_node_add_link(&Mynode, mylink2, sizeof(mylink2));
mylink2->name = "HAHA";//Testing for valid node creation mylink2->name = "HAHA";//Testing for valid node creation
printf("Node Link[1] Name: %s\nHash: %s\n",Mynode->links[1]->name,Mynode->links[1]->Lcid->hash); printf("Node Link[1] Name: %s\nHash: %s\n",Mynode->links[1]->name,Mynode->links[1]->cid->hash);
struct Link * ResultLink = Node_Get_Link(Mynode, "Simo"); struct NodeLink * ResultLink = ipfs_node_get_link_by_name(Mynode, "Simo");
printf("\nResultLink: \nName: %s\nHash: %s\n", ResultLink->name, ResultLink->Lcid->hash); printf("\nResultLink: \nName: %s\nHash: %s\n", ResultLink->name, ResultLink->cid->hash);
Node_Remove_Link("Simo", Mynode); ipfs_node_remove_link_by_name("Simo", Mynode);
printf("Outlinkamt: %d\n", Mynode->link_amount); printf("Outlinkamt: %d\n", Mynode->link_amount);
Free_Link(mylink); ipfs_node_link_free(mylink);
Free_Link(mylink2); ipfs_node_link_free(mylink2);
Free_Link(ResultLink); ipfs_node_link_free(ResultLink);
Node_Delete(Mynode); ipfs_node_free(Mynode);
return 1; return 1;
} }
int compare_link(struct NodeLink* link1, struct NodeLink* link2) {
if (strcmp(link1->name, link2->name) != 0) {
printf("Link Names are different %s vs. %s\n", link1->name, link2->name);
return 0;
}
if (link1->cid->codec != link2->cid->codec) {
printf("Link cid codecs are different. Expected %02x but got %02x\n", link1->cid->codec, link2->cid->codec);
return 0;
}
if (link1->cid->hash_length != link2->cid->hash_length) {
printf("Link cid hash lengths are different. Expected %d but got %d\n", link1->cid->hash_length, link2->cid->hash_length);
return 0;
}
if (link1->cid->version != link2->cid->version) {
printf("Link cid versions are different. Expected %d but got %d\n", link1->cid->version, link2->cid->version);
return 0;
}
if (memcmp(link1->cid->hash, link2->cid->hash, link1->cid->hash_length) != 0) {
printf("compare_link: The values of the hashes are different\n");
return 0;
}
return 1;
}
int test_node_link_encode_decode() {
struct NodeLink* control = NULL;
struct NodeLink* results = NULL;
size_t nl_size;
unsigned char* buffer = NULL;
int retVal = 0;
// make a NodeLink
if (ipfs_node_link_new("My Name", "QmMyHash", &control) == 0)
goto exit;
// encode it
nl_size = ipfs_node_link_protobuf_encode_size(control);
buffer = malloc(nl_size);
if (buffer == NULL)
goto exit;
if (ipfs_node_link_protobuf_encode(control, buffer, nl_size, &nl_size) == 0) {
goto exit;
}
// decode it
if (ipfs_node_link_protobuf_decode(buffer, nl_size, &results) == 0) {
goto exit;
}
// verify it
if (compare_link(control, results) == 0)
goto exit;
retVal = 1;
exit:
if (control != NULL)
ipfs_node_link_free(control);
if (results != NULL)
ipfs_node_link_free(results);
return retVal;
}
/***
* Test a node with 2 links
*/
int test_node_encode_decode() {
struct Node* control = NULL;
struct Node* results = NULL;
struct NodeLink* link1 = NULL;
struct NodeLink* link2 = NULL;
int retVal = 0;
size_t buffer_length = 0;
unsigned char* buffer = NULL;
// node
if (ipfs_node_new(&control) == 0)
goto exit;
// first link
if (ipfs_node_link_new((char*)"Link1", (unsigned char*)"QmLink1", &link1) == 0)
goto exit;
if ( (control = ipfs_node_add_link(&control, link1, sizeof(link1))) == NULL)
goto exit;
// second link
if (ipfs_node_link_new((char*)"Link2", (unsigned char*)"QmLink2", &link2) == 0)
goto exit;
if ( (control = ipfs_node_add_link(&control, link2, sizeof(link2))) == NULL)
goto exit;
// encode
buffer_length = ipfs_node_protobuf_encode_size(control);
buffer = (unsigned char*)malloc(buffer_length);
if (ipfs_node_protobuf_encode(control, buffer, buffer_length, &buffer_length) == 0)
goto exit;
// decode
if (ipfs_node_protobuf_decode(buffer, buffer_length, &results) == 0)
goto exit;
// compare results
if (control->link_amount != results->link_amount || control->link_amount != 2)
goto exit;
for(int i = 0; i < control->link_amount; i++) {
if (compare_link(control->links[i], results->links[i]) == 0) {
printf("Error was on link %d\n", i);
goto exit;
}
}
if (control->data_size != results->data_size)
goto exit;
if (memcmp(results->data, control->data, control->data_size) != 0) {
goto exit;
}
retVal = 1;
exit:
// clean up
if (control != NULL)
ipfs_node_free(control);
if (results != NULL)
ipfs_node_free(results);
if (link1 != NULL)
ipfs_node_link_free(link1);
if (link2 != NULL)
ipfs_node_link_free(link2);
if (buffer != NULL)
free(buffer);
return retVal;
}

View File

@ -69,21 +69,25 @@ int remove_directory(const char *path)
int make_ipfs_repository(const char* path) { int make_ipfs_repository(const char* path) {
int retVal; int retVal;
char currDirectory[1024];
struct RepoConfig* repo_config; struct RepoConfig* repo_config;
char currDirectory[1024]; if (os_utils_file_exists(path)) {
retVal = os_utils_filepath_join(path, "config", currDirectory, 1024); retVal = os_utils_filepath_join(path, "config", currDirectory, 1024);
if (retVal == 0) if (retVal == 0)
return 0; return 0;
unlink(currDirectory); unlink(currDirectory);
retVal = os_utils_filepath_join(path, "datastore", currDirectory, 1024); retVal = os_utils_filepath_join(path, "datastore", currDirectory, 1024);
if (retVal == 0) if (retVal == 0)
return 0; return 0;
remove_directory(currDirectory); remove_directory(currDirectory);
retVal = os_utils_filepath_join(path, "blockstore", currDirectory, 1024); retVal = os_utils_filepath_join(path, "blockstore", currDirectory, 1024);
if (retVal == 0) if (retVal == 0)
return 0; return 0;
remove_directory(currDirectory); remove_directory(currDirectory);
} else {
mkdir(path, S_IRWXU);
}
// build a default repo config // build a default repo config
retVal = ipfs_repo_config_new(&repo_config); retVal = ipfs_repo_config_new(&repo_config);

View File

@ -25,7 +25,7 @@ const char* names[] = {
"test_cid_new_free", "test_cid_new_free",
"test_cid_cast_multihash", "test_cid_cast_multihash",
"test_cid_cast_non_multihash", "test_cid_cast_non_multihash",
//"test_init_new_installation", "test_cid_protobuf_encode_decode",
"test_repo_config_new", "test_repo_config_new",
"test_repo_config_init", "test_repo_config_init",
"test_repo_config_write", "test_repo_config_write",
@ -41,17 +41,18 @@ const char* names[] = {
"test_repo_bootstrap_peers_init", "test_repo_bootstrap_peers_init",
"test_ipfs_datastore_put", "test_ipfs_datastore_put",
"test_node", "test_node",
"test_node_link_encode_decode",
"test_node_encode_decode",
"test_merkledag_add_data", "test_merkledag_add_data",
"test_merkledag_get_data", "test_merkledag_get_data",
"test_merkledag_add_node_with_links", "test_merkledag_add_node_with_links"
"test_cid_protobuf_encode_decode"
}; };
int (*funcs[])(void) = { int (*funcs[])(void) = {
test_cid_new_free, test_cid_new_free,
test_cid_cast_multihash, test_cid_cast_multihash,
test_cid_cast_non_multihash, test_cid_cast_non_multihash,
//test_init_new_installation, test_cid_protobuf_encode_decode,
test_repo_config_new, test_repo_config_new,
test_repo_config_init, test_repo_config_init,
test_repo_config_write, test_repo_config_write,
@ -67,10 +68,11 @@ int (*funcs[])(void) = {
test_repo_bootstrap_peers_init, test_repo_bootstrap_peers_init,
test_ipfs_datastore_put, test_ipfs_datastore_put,
test_node, test_node,
test_node_link_encode_decode,
test_node_encode_decode,
test_merkledag_add_data, test_merkledag_add_data,
test_merkledag_get_data, test_merkledag_get_data,
test_merkledag_add_node_with_links, test_merkledag_add_node_with_links
test_cid_protobuf_encode_decode,
}; };
/** /**
@ -92,9 +94,12 @@ int main(int argc, char** argv) {
} }
int array_length = sizeof(funcs) / sizeof(funcs[0]); int array_length = sizeof(funcs) / sizeof(funcs[0]);
for (int i = 0; i < array_length; i++) { for (int i = 0; i < array_length; i++) {
if (only_one && strcmp(names[i], test_wanted) == 0) { if (only_one) {
tests_ran++; char* currName = names[i];
counter += testit(names[i], funcs[i]); if (strcmp(currName, test_wanted) == 0) {
tests_ran++;
counter += testit(names[i], funcs[i]);
}
} }
else else
if (!only_one) { if (!only_one) {