Serialise.c

From Organic Design wiki
Legacy.svg Legacy: This article describes a concept that has been superseded in the course of ongoing development on the Organic Design wiki. Please do not develop this any further or base work on this concept, this is only useful for a historic record of work done. You may find a link to the currently used concept or function in this article, if not you can contact the author to find out what has taken the place of this legacy item.
// [[[[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);
	}