Serialise.c
From Organic Design wiki
Revision as of 13:12, 13 December 2019 by Nad (talk | contribs) (Nad moved page Serialise.h to Serialise.c)
// [[[[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);
}