mirror of
git://git.psyc.eu/libpsyc
synced 2024-08-15 03:19:02 +00:00
pike changes by fippo
This commit is contained in:
parent
0559cd79a7
commit
2b800e36e1
4 changed files with 393 additions and 57 deletions
|
@ -1,6 +1,6 @@
|
||||||
|
needs latest libpsyc from git://supraverse.net/libpsyc
|
||||||
to compile the cmod:
|
to compile the cmod:
|
||||||
pike -x module
|
pike -x module
|
||||||
|
|
||||||
to run the code:
|
to run the code:
|
||||||
pike -M. rendertest.pike
|
pike -M. parserender.pike
|
||||||
pike -M. parsetest.pike
|
|
||||||
|
|
64
pike/parserender.pike
Normal file
64
pike/parserender.pike
Normal file
|
@ -0,0 +1,64 @@
|
||||||
|
class ParserWithCallback {
|
||||||
|
inherit .Parser;
|
||||||
|
void handle_packet(mapping rvars, mapping evars, string|void method, string|void body) {
|
||||||
|
write("rvars -> %O\n", rvars);
|
||||||
|
write("evars -> %O\n", evars);
|
||||||
|
write("method-> %O\n", method);
|
||||||
|
write("body -> %O\n", body);
|
||||||
|
if (!method) {
|
||||||
|
method = "";
|
||||||
|
}
|
||||||
|
if (!body) {
|
||||||
|
body = "";
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
string re = render(rvars, evars, method, body);
|
||||||
|
write("\n------test:\n%s\n-----rendered:\n%s\n----\n", test, re);
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
void handle_error(int code) {
|
||||||
|
write("error: %d\n", code);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
array(string) testcases = ({
|
||||||
|
"00-length-no-content",
|
||||||
|
"00-length-no-data",
|
||||||
|
"00-length-no-value",
|
||||||
|
"00-method-only",
|
||||||
|
"00-no-content",
|
||||||
|
"00-no-data",
|
||||||
|
"00-no-entity",
|
||||||
|
"00-no-routing",
|
||||||
|
"00-no-value",
|
||||||
|
"01",
|
||||||
|
"01-length",
|
||||||
|
"01-utf8",
|
||||||
|
"02-list",
|
||||||
|
"03-list",
|
||||||
|
"04-circuit",
|
||||||
|
"05-message-private",
|
||||||
|
"06-message-private-remote",
|
||||||
|
"07-dns-fake",
|
||||||
|
"07-dns-invalid",
|
||||||
|
"08-context-enter",
|
||||||
|
"08-context-leave",
|
||||||
|
"err-01-length",
|
||||||
|
"err-02-list"
|
||||||
|
});
|
||||||
|
string basedir = "../test/packets/";
|
||||||
|
|
||||||
|
string test;
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
.Parser p = ParserWithCallback();
|
||||||
|
for (int i = 0; i < sizeof(testcases); i++) {
|
||||||
|
Stdio.File f = Stdio.File(basedir + testcases[i], "r");
|
||||||
|
test = f->read();
|
||||||
|
f->close();
|
||||||
|
write("TEST #%d: %s\n", i, testcases[i]);
|
||||||
|
p->feed(test);
|
||||||
|
write("-----\n");
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
377
pike/psyc.cmod
377
pike/psyc.cmod
|
@ -2,6 +2,7 @@
|
||||||
#include "interpret.h"
|
#include "interpret.h"
|
||||||
#include "stralloc.h"
|
#include "stralloc.h"
|
||||||
#include "mapping.h"
|
#include "mapping.h"
|
||||||
|
#include "array.h"
|
||||||
#include "svalue.h"
|
#include "svalue.h"
|
||||||
#include "operators.h"
|
#include "operators.h"
|
||||||
#include "array.h"
|
#include "array.h"
|
||||||
|
@ -14,36 +15,95 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// libpsyc dependencies
|
// libpsyc dependencies
|
||||||
# include <psyc.h>
|
#include <psyc.h>
|
||||||
# include <psyc/parse.h>
|
#include <psyc/parse.h>
|
||||||
# include <psyc/render.h>
|
#include <psyc/render.h>
|
||||||
|
#include <psyc/text.h>
|
||||||
|
|
||||||
#define MODULE_NAME "PSYC"
|
#define MODULE_NAME "PSYC"
|
||||||
#define MODULE_MAJOR 0
|
#define MODULE_MAJOR 0
|
||||||
#define MODULE_MINOR 1
|
#define MODULE_MINOR 2
|
||||||
#define MODULE_PATCH 0
|
#define MODULE_PATCH 0
|
||||||
|
|
||||||
/*! @module PSYC
|
/*! @module PSYC
|
||||||
*!
|
*!
|
||||||
*! Implements PSYC parsing and rendering based on libpsyc
|
*! Implements PSYC parsing and rendering based on libpsyc
|
||||||
*! FIXME: parser not implemented yet
|
|
||||||
*!
|
*!
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
// psyctext helper
|
||||||
|
psycTextValueRC lookup_value_mapping(const char *name, size_t len, psycString *value, void *extra)
|
||||||
|
{
|
||||||
|
printf("lookup_value_mapping called for %.*s\n", (int) len, name);
|
||||||
|
struct pike_string *key = make_shared_binary_string(name, len);
|
||||||
|
struct mapping *m = (struct mapping *) extra;
|
||||||
|
struct svalue *s = low_mapping_string_lookup(m, key);
|
||||||
|
free_string(key);
|
||||||
|
|
||||||
|
if (s == NULL) {
|
||||||
|
return PSYC_TEXT_VALUE_NOT_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(s->type) {
|
||||||
|
case PIKE_T_STRING:
|
||||||
|
//printf("lookup returned %.*s\n", (int) s->u.string->len, STR0(s->u.string));
|
||||||
|
value->ptr = (char *) STR0(s->u.string);
|
||||||
|
value->length = s->u.string->len;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
printf("lookup did return !string\n");
|
||||||
|
// FIXME
|
||||||
|
value->ptr = "";
|
||||||
|
value->length = 0;
|
||||||
|
}
|
||||||
|
return PSYC_TEXT_VALUE_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*! @decl string psyc_text(string template, mapping vars)
|
||||||
|
*! @param template
|
||||||
|
*! template to be filled
|
||||||
|
*! @param vars
|
||||||
|
*! mapping(string:string) with substituions
|
||||||
|
*! @returns
|
||||||
|
*! rendered string
|
||||||
|
*/
|
||||||
|
PIKEFUN string psyc_text(string template, mapping vars) {
|
||||||
|
psycTextState state;
|
||||||
|
psycTextRC ret;
|
||||||
|
size_t len = 0;
|
||||||
|
// FIXME:
|
||||||
|
char buffer[512];
|
||||||
|
|
||||||
|
psyc_initTextState(&state, (char *) STR0(template), template->len, buffer, 512);
|
||||||
|
do
|
||||||
|
{
|
||||||
|
ret = psyc_text(&state, lookup_value_mapping, vars);
|
||||||
|
len += psyc_getTextBytesWritten(&state);
|
||||||
|
switch (ret) {
|
||||||
|
case PSYC_TEXT_INCOMPLETE: // need to realloc buffer
|
||||||
|
//psyc_setTextBuffer2(&state, buffer + len, BUFSIZE - len);
|
||||||
|
break;
|
||||||
|
case PSYC_TEXT_COMPLETE: // we're done
|
||||||
|
RETURN make_shared_binary_string(buffer, len);
|
||||||
|
case PSYC_TEXT_NO_SUBST: // no substituions, return original string
|
||||||
|
RETURN template;
|
||||||
|
}
|
||||||
|
} while (ret == PSYC_TEXT_INCOMPLETE);
|
||||||
|
}
|
||||||
|
|
||||||
/*! @decl string render(mapping rvars, mapping evars, string method, string|void body)
|
/*! @decl string render(mapping rvars, mapping evars, string method, string|void body)
|
||||||
*! @param rvars
|
*! @param rvars
|
||||||
*! FIXME
|
*! routing vars (mapping string:string)
|
||||||
*! @param evars
|
*! @param evars
|
||||||
*! FIXME
|
*! entity vars (mapping string:mixed
|
||||||
*! @param method
|
*! @param method
|
||||||
*! FIXME
|
*! method name
|
||||||
*! @param data
|
*! @param data
|
||||||
*! FIXME
|
*! body
|
||||||
*! @returns
|
*! @returns
|
||||||
*! serialized packet as a string
|
*! serialized packet as a string
|
||||||
*/
|
*/
|
||||||
PIKEFUN string render(mapping rvars, mapping evars, string method, string|void body) {
|
PIKEFUN string render(mapping rvars, mapping evars, string method, string|void body) {
|
||||||
char buffer[1024*1024]; // static buffer, FIXME
|
|
||||||
psycPacket packet;
|
psycPacket packet;
|
||||||
psycHeader rheaders, eheaders;
|
psycHeader rheaders, eheaders;
|
||||||
|
|
||||||
|
@ -58,12 +118,6 @@ PIKEFUN string render(mapping rvars, mapping evars, string method, string|void b
|
||||||
NEW_MAPPING_LOOP(rvars->data) {
|
NEW_MAPPING_LOOP(rvars->data) {
|
||||||
if (k->ind.type == PIKE_T_STRING) {
|
if (k->ind.type == PIKE_T_STRING) {
|
||||||
switch(k->val.type) {
|
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:
|
case PIKE_T_STRING:
|
||||||
rheaders.modifiers[rheaders.lines++] = psyc_newModifier2(oper,
|
rheaders.modifiers[rheaders.lines++] = psyc_newModifier2(oper,
|
||||||
(char *)STR0(k->ind.u.string),
|
(char *)STR0(k->ind.u.string),
|
||||||
|
@ -72,20 +126,8 @@ PIKEFUN string render(mapping rvars, mapping evars, string method, string|void b
|
||||||
k->val.u.string->len,
|
k->val.u.string->len,
|
||||||
PSYC_MODIFIER_ROUTING);
|
PSYC_MODIFIER_ROUTING);
|
||||||
break;
|
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:
|
default:
|
||||||
|
Pike_error("psyc render: unsupported non-string value in rvars\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -101,35 +143,61 @@ PIKEFUN string render(mapping rvars, mapping evars, string method, string|void b
|
||||||
size_t keylen;
|
size_t keylen;
|
||||||
char *val = NULL;
|
char *val = NULL;
|
||||||
size_t vallen = 0;
|
size_t vallen = 0;
|
||||||
|
struct pike_string *s;
|
||||||
|
|
||||||
key = (char *) STR0(k->ind.u.string);
|
key = (char *) STR0(k->ind.u.string);
|
||||||
keylen = k->ind.u.string->len;
|
keylen = k->ind.u.string->len;
|
||||||
|
|
||||||
switch(k->val.type) {
|
switch(k->val.type) {
|
||||||
case PIKE_T_INT:
|
case PIKE_T_INT:
|
||||||
printf("integer value %ld\n", k->val.u.integer);
|
do {
|
||||||
|
struct string_builder b;
|
||||||
|
init_string_builder(&b, 0);
|
||||||
|
string_builder_append_integer(&b, k->val.u.integer,
|
||||||
|
10, APPEND_SIGNED, 0, 0);
|
||||||
|
s = finish_string_builder(&b);
|
||||||
|
val = (char *) STR0(s);
|
||||||
|
vallen = s->len;
|
||||||
|
free_string(s);
|
||||||
|
} while (0);
|
||||||
break;
|
break;
|
||||||
case PIKE_T_STRING:
|
case PIKE_T_STRING:
|
||||||
val = (char *) STR0(k->ind.u.string);
|
val = (char *) STR0(k->val.u.string);
|
||||||
vallen = k->ind.u.string->len;
|
vallen = k->val.u.string->len;
|
||||||
break;
|
break;
|
||||||
|
/*
|
||||||
case PIKE_T_FLOAT:
|
case PIKE_T_FLOAT:
|
||||||
printf("float value %f\n", k->val.u.float_number);
|
printf("float value %f\n", k->val.u.float_number);
|
||||||
break;
|
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);
|
|
||||||
}
|
|
||||||
*/
|
*/
|
||||||
|
case PIKE_T_ARRAY:
|
||||||
|
do {
|
||||||
|
psycString *elems = xcalloc(k->val.u.array->size, sizeof(psycString));
|
||||||
|
psycList list;
|
||||||
|
// FIXME: check for out of memory
|
||||||
|
for(e = 0; e < k->val.u.array->size; e++) {
|
||||||
|
struct svalue item = k->val.u.array->item[e];
|
||||||
|
switch(item.type) {
|
||||||
|
case PIKE_T_STRING:
|
||||||
|
elems[e] = (psycString) { item.u.string->len, (char *) STR0(item.u.string) };
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// FIXME: xfree(elems) ?
|
||||||
|
Pike_error("psyc_render: unsupported data type in list\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
list = psyc_newList(elems, k->val.u.array->size, PSYC_LIST_CHECK_LENGTH);
|
||||||
|
|
||||||
|
struct pike_string *listbuf = begin_shared_string(list.length);
|
||||||
|
psyc_renderList(&list, (char *) STR0(listbuf), listbuf->len);
|
||||||
|
end_shared_string(listbuf);
|
||||||
|
val = (char *) STR0(listbuf);
|
||||||
|
vallen = listbuf->len;
|
||||||
|
xfree(elems);
|
||||||
|
} while (0);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
Pike_error("psyc_render: unsupported value in evars\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
eheaders.modifiers[eheaders.lines++] = psyc_newModifier2(oper,
|
eheaders.modifiers[eheaders.lines++] = psyc_newModifier2(oper,
|
||||||
|
@ -159,41 +227,240 @@ PIKEFUN string render(mapping rvars, mapping evars, string method, string|void b
|
||||||
PSYC_PACKET_CHECK_LENGTH);
|
PSYC_PACKET_CHECK_LENGTH);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
struct pike_string *s = begin_shared_string(packet.length);
|
||||||
FIXME: how to allocate space and pass it to libpsyc?
|
psyc_render(&packet, (char *) STR0(s), packet.length);
|
||||||
string builder probably
|
|
||||||
*/
|
|
||||||
psyc_render(&packet, buffer, packet.length);
|
|
||||||
// pop_n_elems(args);
|
// pop_n_elems(args);
|
||||||
RETURN make_shared_binary_string(buffer, packet.length);
|
RETURN end_shared_string(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
PIKECLASS Parser {
|
PIKECLASS Parser {
|
||||||
CVAR psycParseState parser;
|
CVAR psycParseState parser;
|
||||||
|
CVAR struct pike_string *buffer;
|
||||||
|
CVAR int handle_packet;
|
||||||
|
CVAR int handle_error;
|
||||||
|
|
||||||
|
// packet state
|
||||||
|
CVAR struct mapping *rvars;
|
||||||
|
CVAR struct mapping *evars;
|
||||||
|
CVAR struct pike_string *method;
|
||||||
|
CVAR struct pike_string *body;
|
||||||
|
|
||||||
|
// for incomplete length prefixed entity var data / body data
|
||||||
|
CVAR struct string_builder incomplete;
|
||||||
|
|
||||||
INIT {
|
INIT {
|
||||||
psyc_initParseState(&THIS->parser);
|
psyc_initParseState(&THIS->parser);
|
||||||
|
THIS->buffer = NULL;
|
||||||
|
THIS->handle_packet = find_identifier("handle_packet", Pike_fp->current_object->prog);
|
||||||
|
THIS->handle_error = find_identifier("handle_error", Pike_fp->current_object->prog);
|
||||||
|
THIS->rvars = allocate_mapping(0);
|
||||||
|
THIS->evars = allocate_mapping(0);
|
||||||
|
THIS->method = NULL;
|
||||||
|
THIS->body = NULL;
|
||||||
|
//THIS->body_buffer = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
EXIT {
|
EXIT {
|
||||||
|
if (THIS->buffer != NULL) {
|
||||||
|
free_string(THIS->buffer);
|
||||||
|
}
|
||||||
|
if (THIS->rvars != NULL) {
|
||||||
|
do_free_mapping(THIS->rvars);
|
||||||
|
}
|
||||||
|
// FIXME: free packet state
|
||||||
}
|
}
|
||||||
|
|
||||||
PIKEFUN void feed(string data) {
|
PIKEFUN void feed(string data) {
|
||||||
char oper;
|
char oper;
|
||||||
psycString name, value;
|
psycString name, value;
|
||||||
int ret;
|
int ret;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
if (THIS->buffer != NULL) {
|
||||||
|
/* we have remaining buffer from previous input */
|
||||||
|
//printf("%d bytes remaining from previous read\n", THIS->buffer->len);
|
||||||
|
struct pike_string *tmp;
|
||||||
|
tmp = add_shared_strings(THIS->buffer, data);
|
||||||
|
free_string(THIS->buffer);
|
||||||
|
data = tmp;
|
||||||
|
THIS->buffer = NULL;
|
||||||
|
}
|
||||||
psyc_setParseBuffer2(&THIS->parser,
|
psyc_setParseBuffer2(&THIS->parser,
|
||||||
(char *) STR0(data), data->len);
|
(char *) STR0(data), data->len);
|
||||||
for (;;) {
|
do {
|
||||||
printf("looping...\n");
|
|
||||||
ret = psyc_parse(&THIS->parser, &oper, &name, &value);
|
ret = psyc_parse(&THIS->parser, &oper, &name, &value);
|
||||||
if (ret == PSYC_PARSE_COMPLETE || ret < 0) {
|
switch(ret) {
|
||||||
|
case PSYC_PARSE_ROUTING:
|
||||||
|
// printf("R %.*s -> %.*s\n", (int)name.length, name.ptr, (int)value.length, value.ptr);
|
||||||
|
mapping_string_insert_string(THIS->rvars,
|
||||||
|
make_shared_binary_string(name.ptr, name.length),
|
||||||
|
make_shared_binary_string(value.ptr, value.length));
|
||||||
break;
|
break;
|
||||||
|
case PSYC_PARSE_ENTITY_START: // entity var with length
|
||||||
|
init_string_builder_alloc(&THIS->incomplete, psyc_getParseValueLength(&THIS->parser), 0);
|
||||||
|
// fall thru
|
||||||
|
case PSYC_PARSE_ENTITY_CONT:
|
||||||
|
string_builder_append(&THIS->incomplete, MKPCHARP(value.ptr, 0), value.length);
|
||||||
|
break;
|
||||||
|
case PSYC_PARSE_ENTITY_END:
|
||||||
|
string_builder_append(&THIS->incomplete, MKPCHARP(value.ptr, 0), value.length);
|
||||||
|
do {
|
||||||
|
struct pike_string *tmp = finish_string_builder(&THIS->incomplete);
|
||||||
|
value.length = tmp->len;
|
||||||
|
value.ptr = (char *) STR0(tmp);
|
||||||
|
// FIXME: not sure if this is really safe
|
||||||
|
free_string(tmp);
|
||||||
|
} while (0);
|
||||||
|
// fall thru
|
||||||
|
case PSYC_PARSE_ENTITY:
|
||||||
|
//printf("E %.*s -> %.*s\n", (int)name.length, name.ptr, (int)value.length, value.ptr);
|
||||||
|
do {
|
||||||
|
err = 0;
|
||||||
|
int type = psyc_getVarType(&name);
|
||||||
|
struct svalue sv;
|
||||||
|
time_t timmy;
|
||||||
|
switch(type) {
|
||||||
|
case PSYC_TYPE_DATE:
|
||||||
|
if (psyc_parseDate(&value, &timmy)) {
|
||||||
|
sv.type = PIKE_T_INT; sv.u.integer = timmy;
|
||||||
|
mapping_string_insert(THIS->evars,
|
||||||
|
make_shared_binary_string(name.ptr, name.length),
|
||||||
|
&sv);
|
||||||
|
} else {
|
||||||
|
err = 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case PSYC_TYPE_TIME:
|
||||||
|
if (psyc_parseTime(&value, &timmy)) {
|
||||||
|
sv.type = PIKE_T_INT; sv.u.integer = timmy;
|
||||||
|
mapping_string_insert(THIS->evars,
|
||||||
|
make_shared_binary_string(name.ptr, name.length),
|
||||||
|
&sv);
|
||||||
|
} else {
|
||||||
|
err = 2;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case PSYC_TYPE_AMOUNT:
|
||||||
|
break;
|
||||||
|
case PSYC_TYPE_DEGREE:
|
||||||
|
if (value.length && value.ptr[0] >= '0' && value.ptr[0] <= '9') {
|
||||||
|
sv.type = PIKE_T_FLOAT; sv.u.float_number = (float) (value.ptr[0] - '0') / 10.0;
|
||||||
|
mapping_string_insert(THIS->evars,
|
||||||
|
make_shared_binary_string(name.ptr, name.length),
|
||||||
|
&sv);
|
||||||
|
} else {
|
||||||
|
err = 3;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case PSYC_TYPE_FLAG:
|
||||||
|
if (value.length && value.ptr[0] >= '0' && value.ptr[0] <= '1') {
|
||||||
|
sv.type = PIKE_T_INT; sv.u.integer = value.ptr[0] - '0';
|
||||||
|
mapping_string_insert(THIS->evars,
|
||||||
|
make_shared_binary_string(name.ptr, name.length),
|
||||||
|
&sv);
|
||||||
|
} else {
|
||||||
|
err = 4;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case PSYC_TYPE_LIST:
|
||||||
|
do {
|
||||||
|
struct array *elems = low_allocate_array(0, 32);
|
||||||
|
if (value.length > 0) {
|
||||||
|
int retl;
|
||||||
|
int count = 0;
|
||||||
|
psycParseListState listState;
|
||||||
|
psycString elem = (psycString) {0, 0};
|
||||||
|
|
||||||
|
psyc_initParseListState(&listState);
|
||||||
|
psyc_setParseListBuffer(&listState, value);
|
||||||
|
do {
|
||||||
|
retl = psyc_parseList(&listState, &elem);
|
||||||
|
switch(retl) {
|
||||||
|
case PSYC_PARSE_LIST_END: // last element
|
||||||
|
retl = 0;
|
||||||
|
case PSYC_PARSE_LIST_ELEM:
|
||||||
|
sv.type = PIKE_T_STRING; sv.u.string = make_shared_binary_string(elem.ptr, elem.length);
|
||||||
|
elems = array_insert(elems, &sv, count++);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
err = 5;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} while (retl > 0 && !err);
|
||||||
|
}
|
||||||
|
if (!err) {
|
||||||
|
sv.type = PIKE_T_ARRAY;
|
||||||
|
sv.u.array = elems;
|
||||||
|
mapping_string_insert(THIS->evars,
|
||||||
|
make_shared_binary_string(name.ptr, name.length),
|
||||||
|
&sv);
|
||||||
|
}
|
||||||
|
free_array(elems);
|
||||||
|
} while (0);
|
||||||
|
break;
|
||||||
|
default: // string
|
||||||
|
mapping_string_insert_string(THIS->evars,
|
||||||
|
make_shared_binary_string(name.ptr, name.length),
|
||||||
|
make_shared_binary_string(value.ptr, value.length));
|
||||||
|
}
|
||||||
|
} while (0);
|
||||||
|
if (err) { // there was an error while
|
||||||
|
// FIXME
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case PSYC_PARSE_BODY_START: // if length was given this is used for body
|
||||||
|
init_string_builder_alloc(&THIS->incomplete, psyc_getParseValueLength(&THIS->parser), 0);
|
||||||
|
case PSYC_PARSE_BODY_CONT:
|
||||||
|
string_builder_append(&THIS->incomplete, MKPCHARP(value.ptr, 0), value.length);
|
||||||
|
break;
|
||||||
|
case PSYC_PARSE_BODY_END:
|
||||||
|
string_builder_append(&THIS->incomplete, MKPCHARP(value.ptr, 0), value.length);
|
||||||
|
do {
|
||||||
|
struct pike_string *tmp = finish_string_builder(&THIS->incomplete);
|
||||||
|
value.length = tmp->len;
|
||||||
|
value.ptr = (char *) STR0(tmp);
|
||||||
|
// FIXME: not sure if this is really safe
|
||||||
|
free_string(tmp);
|
||||||
|
} while (0);
|
||||||
|
// fall thru
|
||||||
|
case PSYC_PARSE_BODY:
|
||||||
|
THIS->method = make_shared_binary_string(name.ptr, name.length);
|
||||||
|
THIS->body = make_shared_binary_string(value.ptr, value.length);
|
||||||
|
break;
|
||||||
|
case PSYC_PARSE_COMPLETE: // apply the callback
|
||||||
|
push_mapping(THIS->rvars);
|
||||||
|
push_mapping(THIS->evars);
|
||||||
|
if (THIS->method == NULL) {
|
||||||
|
apply_low(Pike_fp->current_object, THIS->handle_packet, 2);
|
||||||
|
} else if (THIS->body == NULL) {
|
||||||
|
push_string(THIS->method);
|
||||||
|
apply_low(Pike_fp->current_object, THIS->handle_packet, 3);
|
||||||
|
} else {
|
||||||
|
push_string(THIS->method);
|
||||||
|
push_string(THIS->body);
|
||||||
|
apply_low(Pike_fp->current_object, THIS->handle_packet, 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
// reset packet state
|
||||||
|
THIS->rvars = allocate_mapping(0);
|
||||||
|
THIS->evars = allocate_mapping(0);
|
||||||
|
THIS->method = NULL;
|
||||||
|
THIS->body = NULL;
|
||||||
|
break;
|
||||||
|
case PSYC_PARSE_INSUFFICIENT: // not enough data
|
||||||
|
if (psyc_getParseRemainingBuffer(&THIS->parser) > 0) {
|
||||||
|
THIS->buffer = make_shared_binary_string(psyc_getParseRemainingBuffer(&THIS->parser),
|
||||||
|
psyc_getParseRemainingLength(&THIS->parser));
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
default: // fatal error
|
||||||
|
push_int(ret);
|
||||||
|
apply_low(Pike_fp->current_object, THIS->handle_error, 1);
|
||||||
|
// FIXME: free stuff? or do we kill the socket and parser anyway
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
} while (1);
|
||||||
printf("down here\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
5
pike/text.pike
Normal file
5
pike/text.pike
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
int main() {
|
||||||
|
write("%O\n",
|
||||||
|
psyc_text("some template with a single variable '[_foo_ba]' done.", ([ "_foo" : "abc" ])));
|
||||||
|
//psyc_text("some template [_foo] with a single variable '[_foo_ba]' done.", ([ "_foo" : "abc" ])));
|
||||||
|
}
|
Loading…
Reference in a new issue