diff --git a/pike/Makefile b/pike/Makefile new file mode 100644 index 0000000..8e114cb --- /dev/null +++ b/pike/Makefile @@ -0,0 +1,14 @@ +CC=gcc +CFLAGS := -O9 -shared -Wall -fPIC -I/usr/include/pike $(CFLAGS) $(shell $(PIKE) -x cflags) +LD=$(CC) -shared -lpsyc + +all: module.so + +module.so: module.o + $(LD) -o module.so module.o $(LDFLAGS) + +module.o: module.c + $(CC) $(CFLAGS) -c module.c + +module.c: psyc.cmod + $(PIKE) -x precompile $< > $@ diff --git a/pike/README b/pike/README new file mode 100644 index 0000000..ab3db07 --- /dev/null +++ b/pike/README @@ -0,0 +1,6 @@ +to compile the cmod: +pike -x module + +to run the code: +pike -M. rendertest.pike +pike -M. parsetest.pike diff --git a/pike/parsetest.pike b/pike/parsetest.pike new file mode 100644 index 0000000..0ae9ae3 --- /dev/null +++ b/pike/parsetest.pike @@ -0,0 +1,11 @@ +int main() { + .Parser p = Parser(); + p->feed(":_source\tpsyc://test.psyc.eu/~foo\n" + ":_target\tpsyc://test2.psyc.eu/~bar\n" + ":_tag\tf00b4rb4z\n" + "\n" + ":_foo\tbar\n" + "_message_private\n" + "OHAI\n" + "|\n"); +} diff --git a/pike/psyc.cmod b/pike/psyc.cmod new file mode 100644 index 0000000..d29b67c --- /dev/null +++ b/pike/psyc.cmod @@ -0,0 +1,209 @@ +#include "global.h" +#include "interpret.h" +#include "stralloc.h" +#include "mapping.h" +#include "svalue.h" +#include "operators.h" +#include "array.h" +#include "builtin_functions.h" +#include "module.h" + +#include +#ifndef DEFAULT_CMOD_STORAGE +#define DEFAULT_CMOD_STORAGE +#endif + +// libpsyc dependencies +# include +# include +# include + +#define MODULE_NAME "PSYC" +#define MODULE_MAJOR 0 +#define MODULE_MINOR 1 +#define MODULE_PATCH 0 + +/*! @module PSYC + *! + *! Implements PSYC parsing and rendering based on libpsyc + *! FIXME: parser not implemented yet + *! + */ + +/*! @decl string render(mapping rvars, mapping evars, string method, string|void body) + *! @param rvars + *! FIXME + *! @param evars + *! FIXME + *! @param method + *! FIXME + *! @param data + *! FIXME + *! @returns + *! serialized packet as a string + */ +PIKEFUN string render(mapping rvars, mapping evars, string method, string|void body) { + char buffer[1024*1024]; // static buffer, FIXME + psycPacket packet; + psycHeader rheaders, eheaders; + + struct keypair *k; // for mappings + INT32 e; + + char oper = C_GLYPH_OPERATOR_SET; + + // fill headers + rheaders.lines = 0; + rheaders.modifiers = malloc(sizeof(psycModifier) * rvars->data->size); + NEW_MAPPING_LOOP(rvars->data) { + if (k->ind.type == PIKE_T_STRING) { + switch(k->val.type) { + case PIKE_T_INT: + printf("integer value %ld\n", k->val.u.integer); + break; + case PIKE_T_FLOAT: + printf("float value %f\n", k->val.u.float_number); + break; + case PIKE_T_STRING: + rheaders.modifiers[rheaders.lines++] = psyc_newModifier2(oper, + (char *)STR0(k->ind.u.string), + k->ind.u.string->len, + (char *)STR0(k->val.u.string), + k->val.u.string->len, + PSYC_MODIFIER_ROUTING); + break; + case PIKE_T_MAPPING: + printf("mapping value length %d\n", k->val.u.mapping->data->size); + // another walk_mapping? + break; + case PIKE_T_ARRAY: + printf("array value length %d\n", k->val.u.array->size); + /* + for(e = 0; e < data->u.array->size; e++) { + struct svalue item = data->u.array->item[e]; + inner_serialize2(&item, sb); + } + */ + break; + default: + break; + } + } else { + Pike_error("psyc render: unsupported non-string key in rvars\n"); + } + } + + eheaders.lines = 0; + eheaders.modifiers = malloc(sizeof(psycModifier) * evars->data->size); + NEW_MAPPING_LOOP(evars->data) { + if (k->ind.type == PIKE_T_STRING) { + char *key; + size_t keylen; + char *val = NULL; + size_t vallen = 0; + + key = (char *) STR0(k->ind.u.string); + keylen = k->ind.u.string->len; + + switch(k->val.type) { + case PIKE_T_INT: + printf("integer value %ld\n", k->val.u.integer); + break; + case PIKE_T_STRING: + val = (char *) STR0(k->ind.u.string); + vallen = k->ind.u.string->len; + break; + case PIKE_T_FLOAT: + printf("float value %f\n", k->val.u.float_number); + break; + case PIKE_T_MAPPING: + printf("mapping value length %d\n", k->val.u.mapping->data->size); + // another walk_mapping? + break; + case PIKE_T_ARRAY: + printf("array value length %d\n", k->val.u.array->size); + /* + for(e = 0; e < data->u.array->size; e++) { + struct svalue item = data->u.array->item[e]; + inner_serialize2(&item, sb); + } + */ + break; + default: + break; + } + eheaders.modifiers[eheaders.lines++] = psyc_newModifier2(oper, + key, keylen, + val, vallen, + PSYC_MODIFIER_CHECK_LENGTH); + } else { + Pike_error("psyc render: unsupported non-string key in evars\n"); + } + } + + if (body != NULL) { + packet = psyc_newPacket2(rheaders.modifiers, + rheaders.lines, + eheaders.modifiers, + eheaders.lines, + (const char *)STR0(method), method->len, + (const char *)STR0(body), body->len, + PSYC_PACKET_CHECK_LENGTH); + } else { // body arg was not given + packet = psyc_newPacket2(rheaders.modifiers, + rheaders.lines, + eheaders.modifiers, + eheaders.lines, + (const char *)STR0(method), method->len, + NULL, 0, + PSYC_PACKET_CHECK_LENGTH); + } + + /* + FIXME: how to allocate space and pass it to libpsyc? + string builder probably + */ + psyc_render(&packet, buffer, packet.length); + // pop_n_elems(args); + RETURN make_shared_binary_string(buffer, packet.length); +} + +PIKECLASS Parser { + CVAR psycParseState parser; + + INIT { + psyc_initParseState(&THIS->parser); + } + + EXIT { + + } + + PIKEFUN void feed(string data) { + char oper; + psycString name, value; + int ret; + + psyc_setParseBuffer2(&THIS->parser, + (char *) STR0(data), data->len); + for (;;) { + printf("looping...\n"); + ret = psyc_parse(&THIS->parser, &oper, &name, &value); + if (ret == PSYC_PARSE_COMPLETE || ret < 0) { + break; + } + } + printf("down here\n"); + } + +} + +INIT { + +} + +EXTRA { + add_integer_constant("__version_major", MODULE_MAJOR, 0); + add_integer_constant("__version_minor", MODULE_MAJOR, 0); + add_integer_constant("__version_patch", MODULE_MAJOR, 0); +} diff --git a/pike/rendertest.pike b/pike/rendertest.pike new file mode 100644 index 0000000..cb5c5cd --- /dev/null +++ b/pike/rendertest.pike @@ -0,0 +1,8 @@ +int main() { + werror("render:\n%s\---\n", + render( ([ "_context" : "psyc://denmark.lit/~hamlet#_follow" ]), + ([ "_type_content" : "text/plain", "_subject" : "to be or not to be ?", + "_bla" : 123 ]), + "_message", + "to be or not to be ?")); +}