Difference between revisions of "Serialise.c"
From Organic Design wiki
m |
m (Nad moved page Serialise.h to Serialise.c) |
||
(41 intermediate revisions by the same user not shown) | |||
Line 1: | Line 1: | ||
+ | {{legacy}} | ||
+ | <source lang="c"> | ||
+ | // [[[[http://www.organicdesign.co.nz/peerd|peerd]]]] - nodal p2p wiki daemon | ||
// This article and all its includes are licenced under LGPL | // This article and all its includes are licenced under LGPL | ||
− | // http://www.gnu.org/copyleft/lesser.html | + | // GPL: [[[[http://www.gnu.org/copyleft/lesser.html]]]] |
+ | // SRC: [[[[http://www.organicdesign.co.nz/serialise.c]]]] | ||
+ | // included in [[[[http://www.organicdesign.co.nz/category:peerd/files/C|peerd]]]][[[[http://www.organicdesign.co.nz/peerd.c|/peerd.c]]]] | ||
// - used for storing and communicating nodal structure as plain text | // - used for storing and communicating nodal structure as plain text | ||
// - rather than XML we've used a simple wiki-link format for easy human editing | // - rather than XML we've used a simple wiki-link format for easy human editing | ||
+ | item processNodeNames(char*); | ||
+ | char *serialise(node); | ||
+ | void deserialise(char*); | ||
+ | |||
+ | // ----------------------------------------------------------------------------------------- // | ||
+ | // serialise.c | ||
// Process passed string of pipe-separated names (ext GUID's are just alias's) | // Process passed string of pipe-separated names (ext GUID's are just alias's) | ||
Line 10: | Line 21: | ||
// - returns index as item not node because nodal storage functions are active | // - returns index as item not node because nodal storage functions are active | ||
// - later: if its a number, convert to a binary-coded-string of \x00's and \x01's | // - later: if its a number, convert to a binary-coded-string of \x00's and \x01's | ||
− | item processNodeNames(char * | + | item processNodeNames(char *link) { |
− | + | char **links = split('|',link); | |
− | + | ||
− | + | // Create a new node unless root or already created | |
− | + | node subject = 0; | |
− | char * | + | if (strcmp(*links,"0") && (subject = trieGetValue(*links)) == 0) |
− | while( | + | subject = (node)listInsert(); |
− | + | ||
− | + | // Make node accessible by its names using trie | |
− | + | int i = 0; | |
− | + | char *key; | |
− | + | while (key = links[i++]) { | |
− | + | trieSetValue(key,subject); | |
+ | // need to store name as nodal attribute of node too | ||
} | } | ||
− | free( | + | |
+ | free(*links); | ||
+ | free(links); | ||
return subject; | return subject; | ||
+ | } | ||
+ | |||
+ | // Recursive-sub-function | ||
+ | // - for each position, check 0,1 for more assocs, 2 for assoc-found-here | ||
+ | void keySearch(int *keys, item subject,int path,int level) { | ||
+ | logAdd(" search(ptr,%d,%d,%d)",subject,path,level); | ||
+ | item i,s=subject+(subject<<1); | ||
+ | |||
+ | // If the current path continues on (has 0 and/or 1 links) then search those too | ||
+ | if (i=space[s++]) keySearch(keys,i,path,level+1); | ||
+ | if (i=space[s++]) keySearch(keys,i,path|(1<<level),level+1); | ||
+ | |||
+ | // If the current location has a value or a state, then this path is a complete key | ||
+ | if (space[s] || *nodeState(subject,0)) { | ||
+ | *keys++; | ||
+ | path = (path|(2<<level))-2; | ||
+ | insertPointer(&path); | ||
+ | logAdd(" %d:%d",subject,path); | ||
+ | } | ||
} | } | ||
Line 31: | Line 64: | ||
// - needs to do a binary traversal into the passed node to build association list | // - needs to do a binary traversal into the passed node to build association list | ||
char *serialise(node subject) { | char *serialise(node subject) { | ||
+ | |||
+ | // create list of keys contained within subject node | ||
+ | int keys = 0; | ||
+ | keySearch(&keys,subject,0,0); | ||
+ | |||
char *text; | char *text; | ||
+ | while (keys--) { | ||
+ | // add returned key info as text | ||
+ | } | ||
return text; | return text; | ||
} | } | ||
− | |||
− | |||
− | |||
− | |||
// Convert textual represntation of one or more nodes and associations to nodal change | // Convert textual represntation of one or more nodes and associations to nodal change | ||
void deserialise(char *text) { | void deserialise(char *text) { | ||
− | + | item subject = 0; | |
− | + | int key, val, loop, i, j = 1, linkStart; | |
− | item subject = | ||
− | int key, val, i, j = | ||
char *link1 = malloc(100), *link2 = link1+50; | char *link1 = malloc(100), *link2 = link1+50; | ||
for (i = 0; i < strlen(text); i++) { | for (i = 0; i < strlen(text); i++) { | ||
Line 50: | Line 85: | ||
if (*s < 32) j = 1; | if (*s < 32) j = 1; | ||
else switch (j) { | else switch (j) { | ||
− | |||
case 1: // starting new line - if not starting with *[[ then wait for next line | case 1: // starting new line - if not starting with *[[ then wait for next line | ||
− | if (strncmp(s, "*[[", 3) == 0) { | + | if (strncmp(s,"*[[",3) == 0) { j = 2; linkStart = i+3; } else j = 0; |
− | |||
− | |||
− | |||
break; | break; | ||
case 2: // processing first link | case 2: // processing first link | ||
− | if (strncmp(s, "]]", 2) == 0) { | + | if (strncmp(s,"]]",2) == 0) { |
− | if (strncmp(s, "]]:[[", 5) == 0) j = 3; // link 1 of 2 | + | if (strncmp(s,"]];",3) == 0) { |
+ | loop = 0; // forces first loop to stand alone | ||
+ | j = 4; // processing loop | ||
+ | i--; // go back one so that case 4 gets the ]]; again | ||
+ | } | ||
+ | else if (strncmp(s,"]]:[[",5) == 0) j = 3; // done link 1 of 2 (assoc) | ||
else { | else { | ||
− | // link 1 of 1 | + | // done link 1 of 1 (context) |
− | + | strncpy(link1,text+linkStart,i-linkStart); | |
− | link1[i-linkStart | + | link1[i-linkStart] = '\0'; |
subject = processNodeNames(link1); | subject = processNodeNames(link1); | ||
− | |||
j = 0; // wait for new line | j = 0; // wait for new line | ||
} | } | ||
} | } | ||
break; | break; | ||
− | case 3: // processing | + | case 3: // processing link 2 of an association statement |
− | if (strncmp(s, "]]", 2) == 0) { | + | if (strncmp(s,"]]",2) == 0) { |
− | + | strncpy(link1,text+linkStart,i-linkStart); | |
− | + | link2 = strchr(link1,'[')+2; | |
− | link2 = strchr(link1, '[')+2; | + | link1[i-linkStart] = '\0'; |
− | link1[i-linkStart | + | link1[i-linkStart-strlen(link2)-5] = '\0'; |
− | link1[i-linkStart-strlen(link2)- | ||
key = processNodeNames(link1); | key = processNodeNames(link1); | ||
val = processNodeNames(link2); | val = processNodeNames(link2); | ||
listSetValue(listTraverse(subject,key),val); | listSetValue(listTraverse(subject,key),val); | ||
− | |||
j = 0; | j = 0; | ||
+ | } | ||
+ | break; | ||
+ | case 4: // processing link n of a loop statement | ||
+ | if (strncmp(s,"[[",2) == 0) linkStart = i+2; | ||
+ | if (strncmp(s,"]]",2) == 0) { | ||
+ | strncpy(link1,text+linkStart,i-linkStart); | ||
+ | link1[i-linkStart] = '\0'; | ||
+ | nodeLoopInsert(subject,processNodeNames(link1)); | ||
+ | if (strncmp(s,"]];[[",5)) j = 0; | ||
} | } | ||
break; | break; | ||
} | } | ||
} | } | ||
− | + | free(link1); | |
} | } | ||
+ | </source> | ||
+ | [[Category:C]] |
Latest revision as of 13:12, 13 December 2019
// [[[[http://www.organicdesign.co.nz/peerd|peerd]]]] - nodal p2p wiki daemon
// This article and all its includes are licenced under LGPL
// GPL: [[[[http://www.gnu.org/copyleft/lesser.html]]]]
// SRC: [[[[http://www.organicdesign.co.nz/serialise.c]]]]
// included in [[[[http://www.organicdesign.co.nz/category:peerd/files/C|peerd]]]][[[[http://www.organicdesign.co.nz/peerd.c|/peerd.c]]]]
// - used for storing and communicating nodal structure as plain text
// - rather than XML we've used a simple wiki-link format for easy human editing
item processNodeNames(char*);
char *serialise(node);
void deserialise(char*);
// ----------------------------------------------------------------------------------------- //
// serialise.c
// Process passed string of pipe-separated names (ext GUID's are just alias's)
// - returns index of a newly created internal node to which the passed names map
// - returns index as item not node because nodal storage functions are active
// - later: if its a number, convert to a binary-coded-string of \x00's and \x01's
item processNodeNames(char *link) {
char **links = split('|',link);
// Create a new node unless root or already created
node subject = 0;
if (strcmp(*links,"0") && (subject = trieGetValue(*links)) == 0)
subject = (node)listInsert();
// Make node accessible by its names using trie
int i = 0;
char *key;
while (key = links[i++]) {
trieSetValue(key,subject);
// need to store name as nodal attribute of node too
}
free(*links);
free(links);
return subject;
}
// Recursive-sub-function
// - for each position, check 0,1 for more assocs, 2 for assoc-found-here
void keySearch(int *keys, item subject,int path,int level) {
logAdd(" search(ptr,%d,%d,%d)",subject,path,level);
item i,s=subject+(subject<<1);
// If the current path continues on (has 0 and/or 1 links) then search those too
if (i=space[s++]) keySearch(keys,i,path,level+1);
if (i=space[s++]) keySearch(keys,i,path|(1<<level),level+1);
// If the current location has a value or a state, then this path is a complete key
if (space[s] || *nodeState(subject,0)) {
*keys++;
path = (path|(2<<level))-2;
insertPointer(&path);
logAdd(" %d:%d",subject,path);
}
}
// Convert a node to text for storage or transport
// - needs to do a binary traversal into the passed node to build association list
char *serialise(node subject) {
// create list of keys contained within subject node
int keys = 0;
keySearch(&keys,subject,0,0);
char *text;
while (keys--) {
// add returned key info as text
}
return text;
}
// Convert textual represntation of one or more nodes and associations to nodal change
void deserialise(char *text) {
item subject = 0;
int key, val, loop, i, j = 1, linkStart;
char *link1 = malloc(100), *link2 = link1+50;
for (i = 0; i < strlen(text); i++) {
char *s = text+i;
if (*s < 32) j = 1;
else switch (j) {
case 1: // starting new line - if not starting with *[[ then wait for next line
if (strncmp(s,"*[[",3) == 0) { j = 2; linkStart = i+3; } else j = 0;
break;
case 2: // processing first link
if (strncmp(s,"]]",2) == 0) {
if (strncmp(s,"]];",3) == 0) {
loop = 0; // forces first loop to stand alone
j = 4; // processing loop
i--; // go back one so that case 4 gets the ]]; again
}
else if (strncmp(s,"]]:[[",5) == 0) j = 3; // done link 1 of 2 (assoc)
else {
// done link 1 of 1 (context)
strncpy(link1,text+linkStart,i-linkStart);
link1[i-linkStart] = '\0';
subject = processNodeNames(link1);
j = 0; // wait for new line
}
}
break;
case 3: // processing link 2 of an association statement
if (strncmp(s,"]]",2) == 0) {
strncpy(link1,text+linkStart,i-linkStart);
link2 = strchr(link1,'[')+2;
link1[i-linkStart] = '\0';
link1[i-linkStart-strlen(link2)-5] = '\0';
key = processNodeNames(link1);
val = processNodeNames(link2);
listSetValue(listTraverse(subject,key),val);
j = 0;
}
break;
case 4: // processing link n of a loop statement
if (strncmp(s,"[[",2) == 0) linkStart = i+2;
if (strncmp(s,"]]",2) == 0) {
strncpy(link1,text+linkStart,i-linkStart);
link1[i-linkStart] = '\0';
nodeLoopInsert(subject,processNodeNames(link1));
if (strncmp(s,"]];[[",5)) j = 0;
}
break;
}
}
free(link1);
}