diff --git a/.cproject b/.cproject
index 9bbebce..d05172c 100644
--- a/.cproject
+++ b/.cproject
@@ -29,6 +29,7 @@
+
diff --git a/include/ipfs/node/Example for this.c b/include/ipfs/node/Example for this.c
new file mode 100644
index 0000000..1cf7d4a
--- /dev/null
+++ b/include/ipfs/node/Example for this.c
@@ -0,0 +1,96 @@
+#include "repo/test_repo_config.h"
+#include "repo/test_repo_identity.h"
+#include "repo/test_repo_bootstrap_peers.h"
+#include "repo/test_repo_fsrepo.h"
+#include "cmd/ipfs/test_init.h"
+#include "cid/test_cid.h"
+#include "flatfs/test_flatfs.h"
+#include "storage/test_ds_helper.h"
+#include "storage/test_datastore.h"
+#include "storage/test_blocks.h"
+#include "ipfs/node/node.h"
+/*TODOS!
+ *Incoroparate protobuf funcs
+ *Incoroparate multihash funcs
+*/
+int main(int argc, char** argv)
+{
+ printf("XETH TESTS\n");
+ ////Links//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ //Variables of link:
+ char * name = "Alex";
+ char * ahash = "QmYwAPJzv5CZsnA625s3Xf2nemtYgPpHdWEz79ojWnPbdG";
+ struct Link * mylink;
+ mylink = Create_Link(name,ahash);
+ printf("===================================\n" \
+ "Node Link:\n" \
+ " -Name: %s\n" \
+ " -Size: %lu\n" \
+ "\n Cid Details:\n\n" \
+ " -Version: %d\n" \
+ " -Codec: %c\n" \
+ " -Hash: %s\n" \
+ " -Hash Length: %lu\n" \
+ "====================================\n" \
+ , mylink->name, mylink->size, mylink->Lcid->version,mylink->Lcid->codec,mylink->Lcid->hash,mylink->Lcid->hash_length);
+
+ //Link Two for testing purposes
+ char * name2 = "Simo";
+ char * ahash2 = "QmYwAPJzv5CZsnA625s3Xf2nemtYgPpHdWEz79ojWnSimo";
+ struct Link * mylink2;
+ mylink2 = Create_Link(name2,ahash2);
+
+ ////Nodes/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ //N_Create_From_Link
+ struct Node * Mynode;
+ Mynode = N_Create_From_Link(mylink);
+ 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);
+
+ //N_Add_Link
+ Mynode = N_Add_Link(&Mynode, mylink2, sizeof(mylink2));
+ 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);
+
+ //Node_Get_Link
+ struct Link * ResultLink = Node_Get_Link(Mynode, "Simo");
+ printf("\nResultLink: \nName: %s\nHash: %s\n\n", ResultLink->name, ResultLink->Lcid->hash);
+
+ //Node_Resolve_Links
+ struct Link_Proc * LPRX = Node_Resolve_Links(Mynode, "Alex/Simo");
+ for(int i=0;iammount;i++)
+ {
+ printf("RESOLVE LINKS-Result: %s\n", LPRX->links[i]->name);
+ }
+ Free_Link_Proc(LPRX);
+
+ //Node_Remove Link
+
+ int StatUs = Node_Remove_Link("Simo", Mynode);
+ printf("Status: %d\n",StatUs);
+ printf("Outlinkamt: %d\n", Mynode->link_ammount);
+
+ //Node Copy
+ struct Node * Node2;
+ Node2 = Node_Copy(Mynode);
+ printf("NODE COPY TEST: [0]: %s\n", Node2->links[0]->Lcid->hash);
+ Node_Delete(Node2);
+
+ //Node_Set_Data
+ Node_Set_Data(Mynode, "DATA_HERE");
+
+ //Node_Get_Data
+ unsigned char * meh;
+ meh = Node_Get_Data(Mynode);
+ printf("NODE DATA: %s", meh);
+
+
+ //Free Everything
+ Free_Link(mylink);
+ Free_Link(mylink2);
+ Free_Link(ResultLink);
+
+ Node_Delete(Mynode);
+ return 0;
+}
diff --git a/include/ipfs/node/node.h b/include/ipfs/node/node.h
index abedfdf..d906dc8 100644
--- a/include/ipfs/node/node.h
+++ b/include/ipfs/node/node.h
@@ -2,13 +2,404 @@
* An implementation of an IPFS node
* Copying the go-ipfs-node project
*/
+#ifndef IPFS_NODE_H
+#define IPFS_NODE_H
+#include
+#include
+#include
+#include "inttypes.h"
+#include "ipfs/cid/cid.h"
-#include
+int debug = 0; // Set to 1 to enable debug mode of this program
+/*====================================================================================
+ *
+ * Structures
+ *
+ *===================================================================================*/
-
-struct Link {
- char* name;
- uint64_t size;
- struct Cid cid; // content id
+struct Link
+{
+ char * name;
+ size_t size;
+ struct Cid * Lcid;
};
+struct Node
+{
+ unsigned char * data;
+ unsigned char * encoded;
+ struct Cid * cached;
+ int link_ammount;
+ struct Link * links[];
+};
+/*====================================================================================
+ *
+ * Functions
+ *
+ *===================================================================================*/
+
+/*====================================================================================
+ * Link Functions
+ *===================================================================================*/
+/* Create_Link
+ * @Param name: The name of the link (char *)
+ * @Param size: Size of the link (size_t)
+ * @Param ahash: An Qmhash
+ */
+struct Link * Create_Link(char * name, unsigned char * ahash)
+{
+ struct Link * mylink;
+ mylink = malloc(sizeof(struct Link));
+ mylink->name = name;
+ int ver = 0;
+ size_t lenhash = strlen(ahash)-1;
+ ipfs_cid_new(ver, ahash, lenhash*2, CID_PROTOBUF, &mylink->Lcid);
+ mylink->size = sizeof(mylink) + mylink->Lcid->hash_length; //Unsure of this
+ return mylink;
+}
+/* Free_Link
+ * @param L: Free the link you have allocated.
+ */
+void Free_Link(struct Link * L)
+{
+ ipfs_cid_free(L->Lcid);
+ free(L);
+}
+/*====================================================================================
+ * Node Functions
+ *===================================================================================*/
+/*Create_Empty_Node
+ * Creates an empty node, allocates the required memory
+ * Returns a fresh new node with no data set in it.
+ */
+struct Node * Create_Empty_Node()
+{
+ struct Node * N;
+ N = (struct Node *)malloc(sizeof(struct Node));
+ return N;
+}
+/*Node_Set_Data
+ * Sets the data of a node
+ * @param Node: The node which you want to set data in.
+ * @param Data, the data you want to assign to the node
+ * returns 1 on success 0 on failure
+ */
+int Node_Set_Data(struct Node * N, unsigned char * Data)
+{
+ if(!N || !Data)
+ {
+ return 0;
+ }
+ N->encoded = NULL;
+ N->cached = NULL;
+ N->data = Data;
+ return 1;
+}
+/*Node_Get_Data
+ * Gets data from a node
+ * @param Node: = The node you want to get data from. (unsigned char *)
+ * Returns data of node.
+ */
+unsigned char * Node_Get_Data(struct Node * N)
+{
+ unsigned char * DATA;
+ DATA = N->data;
+ return DATA;
+}
+
+/*Node_Copy: Returns a copy of the node you input
+ * @param Node: The node you want to copy (struct CP_Node *)
+ * Returns a copy of the node you wanted to copy.
+ */
+struct Node * Node_Copy(struct Node * CP_Node)
+{
+ struct Node * CN;
+ CN = (struct Node*) malloc(sizeof(struct Node) + sizeof(struct Link) * 2);
+ if(CP_Node->link_ammount != 0)
+ {
+ for(int i=0; ilink_ammount; i++)
+ {
+ CN->links[i] = malloc(sizeof(struct Link));
+ }
+ }
+ memcpy(CN, CP_Node, sizeof(struct Node));
+ memcpy(CN->links[0],CP_Node->links[0], sizeof(struct Link));
+ return CN;
+}
+/*Node_Delete
+ * Once you are finished using a node, always delete it using this.
+ * It will take care of the links inside it.
+ * @param N: the node you want to free. (struct Node *)
+ */
+void Node_Delete(struct Node * N)
+{
+ if(N->link_ammount > 0)
+ {
+ for(int i=0; ilink_ammount; i++)
+ {
+ free(N->links[i]);
+ }
+ }
+ free(N);
+}
+/*Node_Get_Link
+ * Returns a copy of the link with given name
+ * @param Name: (char * name) searches for link with this name
+ * Returns the link struct if it's found otherwise returns NULL
+ */
+struct Link * Node_Get_Link(struct Node * N, char * Name)
+{
+ struct Link * L;
+ for(int i=0;ilink_ammount;i++)
+ {
+ if(strcmp(N->links[i]->name,Name) == 0)
+ {
+ L = (struct Link *)malloc(sizeof(struct Link));
+ memcpy(L,N->links[i],sizeof(struct Link));
+ int ver = L->Lcid->version;
+ char * ahash = L->Lcid->hash;
+ size_t lenhash = L->Lcid->hash_length;
+ ipfs_cid_new(ver, ahash, lenhash, CID_PROTOBUF, &L->Lcid);
+ return L;
+ }
+ }
+ return NULL;
+}
+/*Node_Remove_Link
+ * Removes a link from node if found by name.
+ * @param name: Name of link (char * name)
+ * returns 1 on success, 0 on failure.
+ */
+int Node_Remove_Link(char * Name, struct Node * mynode)
+{
+ for(int i=0; ilink_ammount; i++)
+ {
+ if(mynode->links[i]->name == Name)
+ {
+ for(int x=i;xlink_ammount && x+1 != mynode->link_ammount;i++)
+ {
+ memcpy(mynode->links[x],mynode->links[x+1],sizeof(struct Link));
+ }
+ free(mynode->links[mynode->link_ammount-1]);
+ mynode->link_ammount--;
+ return 1;
+ }
+ }
+ return 0;
+}
+/* N_Add_Link
+ * Adds a link to your node
+ * @param mynode: &yournode
+ * @param mylink: the CID you want to create a node from
+ * @param linksz: sizeof(your cid here)
+ * Returns your node with the newly added link
+ */
+struct Node * N_Add_Link(struct Node ** mynode, struct Link * mylink, size_t linksz)
+{
+ struct Node * Nl = *mynode;
+ Nl->link_ammount++;
+ size_t calculatesize = 0;
+ if(Nl->link_ammount != 0)
+ {
+ for(int i=0; ilink_ammount-1;i++)
+ {
+ calculatesize = calculatesize + sizeof(Nl->links[i]);
+ }
+ calculatesize = calculatesize + linksz;
+ Nl = (struct Node *) realloc(Nl, sizeof(struct Node) + calculatesize);
+ }
+ else
+ {
+ Nl = (struct Node *) malloc(sizeof(struct Node) + linksz);
+ }
+ Nl->links[Nl->link_ammount-1] = malloc(sizeof(struct Link));
+ memcpy(Nl->links[Nl->link_ammount-1],mylink,sizeof(struct Link));
+ return Nl;
+}
+
+/*N_Create_From_Link
+ * Create a node from a link
+ * @param mylink: the link you want to create it from. (struct Cid *)
+ * @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.
+ */
+struct Node * N_Create_From_Link(struct Link * mylink)
+{
+ struct Node * mynode;
+ mynode = (struct Node *) malloc(sizeof(struct Node) + sizeof(struct Link));
+ mynode->link_ammount = 0;
+ mynode->link_ammount++;
+ mynode->links[0] = malloc(sizeof(struct Link));
+ memcpy(mynode->links[0], mylink, sizeof(struct Link));
+ return mynode;
+}
+/*N_Create_From_Data
+ * @param data: bytes buffer you want to create the node from
+ * returns a node with the data you inputted.
+ */
+struct Node * N_Create_From_Data(unsigned char * data)
+{
+ struct Node * mynode;
+ mynode = (struct Node *) malloc(sizeof(struct Node));
+ mynode->data = data;
+ return mynode;
+}
+/*Node_Resolve_Max_Size
+ * !!!This shouldn't concern you!
+ *Gets the ammount of words that will be returned by Node_Resolve
+ *@Param1: The string that will be processed (eg: char * sentence = "foo/bar/bin")
+ *Returns either -1 if something went wrong or the ammount of words that would be processed.
+*/
+int Node_Resolve_Max_Size(char * input1)
+{
+ if(!input1)
+ {
+ return -1; // Input is null, therefor nothing can be processed.
+ }
+ char input[strlen(input1)];
+ bzero(input, strlen(input1));
+ strcpy(input, input1);
+ int num = 0;
+ char * tr;
+ char * end;
+ tr=strtok_r(input,"/",&end);
+ for(int i = 0;tr;i++)
+ {
+ tr=strtok_r(NULL,"/",&end);
+ num++;
+ }
+ return num;
+}
+
+/*Node_Resolve Basically stores everything in a pointer array eg: char * bla[Max_Words_]
+ * !!!This shouldn't concern you!!!
+ *@param1: Pointer array(char * foo[x], X=Whatever ammount there is. should be used with the helper function Node_Resolve_Max_Size)
+ *@param2: Sentence to gather words/paths from (Eg: char * meh = "foo/bar/bin")
+ *@Returns 1 or 0, 0 if something went wrong, 1 if everything went smoothly.
+*/
+
+int Node_Resolve(char ** result, char * input1)
+{
+ if(!input1)
+ {
+ return 0; // Input is null, therefor nothing can be processed.
+ }
+ char input[strlen(input1)];
+ bzero(input, strlen(input1));
+ strcpy(input, input1);
+ char * tr;
+ char * end;
+ tr=strtok_r(input,"/",&end);
+ for(int i = 0;tr;i++)
+ {
+ if(debug == 1)
+ {
+ printf("TR: %s\n", tr);
+ }
+ result[i] = (char *) malloc(strlen(tr)+1);
+ strcpy(result[i], tr);
+ tr=strtok_r(NULL,"/",&end);
+ }
+ return 1;
+}
+/**************************************************************************************************************************************
+ *|||||||||||||||||||||||||||||||||||||||| !!!! IMPORTANT !!! ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||*
+ **************************************************************************************************************************************
+ * Not sure where this is used, I'm making something to easen it up for all of you.
+ * This in itself will get all the links for you in a link[] array inside Link_Proc
+ * the memory allocation for storage will be noted in the ammount of links.
+ * After being done with this, you have to free the array for which you will have a function specially made for you.
+ *
+ * What this does:
+ * It searches for links using a path like /foo/bar/bin/, if links with those names are found in the node you specify, it stores them
+ * in a custom struct, Link_Proc; which is what Node_Resolve_Link returns.
+ * Notes:
+ * Use it, free it, it's all already laid out for you.
+ * There will also be a tutorial demonstrating it in the same folder here so everyone can understand this.
+*/
+struct Link_Proc
+{
+ char * remaining_links; // Not your concern.
+ int ammount; //This will store the ammount of links, so you know what to process.
+ struct Link * links[]; // Link array
+};
+/*Node_Resolve_Links
+ * Processes a path returning all links.
+ * @param N: The node you want to get links from
+ * @param path: The "foo/bar/bin" path
+ */
+struct Link_Proc * Node_Resolve_Links(struct Node * N, char * path)
+{
+ if(!N || !path)
+ {
+ return NULL;
+ }
+ 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);
+ LProc->ammount = 0;
+ char * linknames[expected_link_ammount];
+ Node_Resolve(linknames, path);
+ for(int i=0;ilinks[i] = (struct Link *)malloc(sizeof(struct Link));
+ memcpy(LProc->links[i], proclink, sizeof(struct Link));
+ LProc->ammount++;
+ free(proclink);
+ }
+ }
+ //Freeing pointer array
+ for(int i=0;iammount != 0)
+ {
+ for(int i=0;iammount;i++)
+ {
+ Free_Link(LPRC->links[i]);
+ }
+ }
+ free(LPRC);
+}
+
+/*Node_Tree() Basically a unix-like ls
+ *@Param1: Result char * foo[strlen(sentence)]
+ *@Param2: char sentence[] = foo/bar/bin/whatever
+ *Return: 0 if failure, 1 if success
+*/
+int Node_Tree(char * result, char * input1) //I don't know where you use this but here it is.
+{
+ if(!input1)
+ {
+ return 0;
+ }
+ char input[strlen(input1)];
+ bzero(input, strlen(input1));
+ strcpy(input, input1);
+ for(int i=0; i
+
#include "ipfs/cmd/ipfs/init.h"
#include "ipfs/commands/argument.h"
#include "ipfs/commands/request.h"
diff --git a/test/node/test_node.h b/test/node/test_node.h
new file mode 100644
index 0000000..a61c851
--- /dev/null
+++ b/test/node/test_node.h
@@ -0,0 +1,42 @@
+#include "ipfs/node/node.h"
+
+int test_node() {
+ //Variables of link:
+ char * name = "Alex";
+ unsigned char * ahash = "QmYwAPJzv5CZsnA625s3Xf2nemtYgPpHdWEz79ojWnPbdG";
+ struct Link * mylink;
+ mylink = Create_Link(name,ahash);
+ printf("===================================\n" \
+ "Node Link:\n" \
+ " -Name: %s\n" \
+ " -Size: %lu\n" \
+ "\n Cid Details:\n\n" \
+ " -Version: %d\n" \
+ " -Codec: %c\n" \
+ " -Hash: %s\n" \
+ " -Hash Length: %lu\n" \
+ "====================================\n" \
+ , mylink->name, mylink->size, mylink->Lcid->version,mylink->Lcid->codec,mylink->Lcid->hash,mylink->Lcid->hash_length);
+ //Link Two for testing purposes
+ char * name2 = "Simo";
+ unsigned char * ahash2 = "QmYwAPJzv5CZsnA625s3Xf2nemtYgPpHdWEz79ojWnSimo";
+ struct Link * mylink2;
+ mylink2 = Create_Link(name2,ahash2);
+ //Nodes
+ struct Node * Mynode;
+ Mynode = N_Create_From_Link(mylink);
+ 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);
+ Mynode = N_Add_Link(&Mynode, mylink2, sizeof(mylink2));
+ 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);
+ struct Link * ResultLink = Node_Get_Link(Mynode, "Simo");
+ printf("\nResultLink: \nName: %s\nHash: %s\n", ResultLink->name, ResultLink->Lcid->hash);
+ Node_Remove_Link("Simo", Mynode);
+ printf("Outlinkamt: %d\n", Mynode->link_ammount);
+ Free_Link(mylink);
+ Free_Link(mylink2);
+ Free_Link(ResultLink);
+ Node_Delete(Mynode);
+ return 0;
+}
diff --git a/test/testit.c b/test/testit.c
index b455958..119c40b 100644
--- a/test/testit.c
+++ b/test/testit.c
@@ -1,14 +1,15 @@
-#include "repo/test_repo_config.h"
-#include "repo/test_repo_identity.h"
-#include "repo/test_repo_bootstrap_peers.h"
-#include "repo/test_repo_fsrepo.h"
-#include "cmd/ipfs/test_init.h"
#include "cid/test_cid.h"
+#include "cmd/ipfs/test_init.h"
#include "flatfs/test_flatfs.h"
+#include "node/test_node.h"
+#include "repo/test_repo_bootstrap_peers.h"
+#include "repo/test_repo_config.h"
+#include "repo/test_repo_fsrepo.h"
+#include "repo/test_repo_identity.h"
#include "storage/test_ds_helper.h"
#include "storage/test_datastore.h"
#include "storage/test_blocks.h"
-
+
int testit(const char* name, int (*func)(void)) {
printf("Testing %s...\n", name);
int retVal = func();
@@ -37,7 +38,8 @@ const char* names[] = {
"test_ds_key_from_binary",
"test_blocks_new",
"test_repo_bootstrap_peers_init",
- "test_ipfs_datastore_put"
+ "test_ipfs_datastore_put",
+ "test_node"
};
int (*funcs[])(void) = {
@@ -58,7 +60,8 @@ int (*funcs[])(void) = {
test_ds_key_from_binary,
test_blocks_new,
test_repo_bootstrap_peers_init,
- test_ipfs_datastore_put
+ test_ipfs_datastore_put,
+ test_node
};
/**
@@ -72,7 +75,7 @@ int main(int argc, char** argv) {
only_one = 1;
test_wanted = argv[1];
}
- for (int i = 0; i < sizeof(funcs) / sizeof(funcs[0]); i++) {
+ for (int i = 0; i < sizeof(names) / sizeof(names[0]); i++) {
if (only_one && strcmp(names[i], test_wanted) == 0)
counter += testit(names[i], funcs[i]);
else