User Functions
Don't have an account yet? Sign up as a New User
Lost your password?
|
|
Welcome to intermud.org Friday, September 03 2010 @ 05:14 AM GMT+1
| aidil |
 |
August 11 2009 21:50 PM (Read 2805 times) |
|
|

Admin
Status: offline
Registered: 08/10/09
Posts: 13
|
It would be quite feasible to use JSON instead of mudmode for transfer of I3 messages. I can add support for this to the *wpr router if anyone is interested.
visit Way of the Force: http://wotf.org/
|
| |
|
|
| Tricky |
 |
August 26 2009 05:50 AM |
|
|

Newbie
Status: offline
Registered: 08/11/09
Posts: 4
|
I wrote up this piece of code for MudOS/FluffOS to convert from JSON to an LPC variable. I'm not too sure about the regex for NUMBER, however for I3 communications it will work perfectly.
Sorry about the lack of comments.
PHP Formatted Code /*
* json.c
*
* mixed processJSON(string message)
*
* Creates an LPC variable from a JSON message.
*/
#define DEBUG_LEVEL 0
#define D(l,x) if (((l) - (DEBUG_LEVEL)) <= 0) printf("%O\n\n", x)
#define STRING "\"([^\"\n])*\""
#define NUMBER "[-]?[0-9]+([.][0-9]+)?([eE][+-]?[0-9]+)?"
#define LITERAL "(false|null|true)"
#define NAME_SEPARATOR ":"
#define VALUE_SEPARATOR ","
#define ARRAY_BEGIN "[[]"
#define ARRAY_END "[]]"
#define OBJECT_BEGIN "{"
#define OBJECT_END "}"
#define WS "( |\t|\r|\n)+"
#define TOK_DEFAULT 0
#define TOK_STRING 1
#define TOK_NUMBER 2
#define TOK_LITERAL 3
#define TOK_NAME_SEPARATOR 4
#define TOK_VALUE_SEPARATOR 5
#define TOK_ARRAY_BEGIN 6
#define TOK_ARRAY_END 7
#define TOK_OBJECT_BEGIN 8
#define TOK_OBJECT_END 9
#define TOK_WS 10
mixed processJSON (string message )
{
mixed *assoc;
string tmp = "";
int i, sz;
assoc = reg_assoc (
message,
({
STRING,
NUMBER,
LITERAL,
NAME_SEPARATOR,
VALUE_SEPARATOR,
ARRAY_BEGIN,
ARRAY_END,
OBJECT_BEGIN,
OBJECT_END,
WS,
}),
({
TOK_STRING,
TOK_NUMBER,
TOK_LITERAL,
TOK_NAME_SEPARATOR,
TOK_VALUE_SEPARATOR,
TOK_ARRAY_BEGIN,
TOK_ARRAY_END,
TOK_OBJECT_BEGIN,
TOK_OBJECT_END,
TOK_WS,
}),
TOK_DEFAULT
);
D (2, assoc );
sz = sizeof(assoc [0]);
for (i = 0 ; i < sz ; i++ )
{
switch (assoc [1][i ])
{
/* No idea what to do with this currently. */
/* Convert into a string and leave for the programmer to translate. */
case TOK_LITERAL:
assoc [0][i ] = "\"" + assoc [0][i ] + "\"";
break;
case TOK_ARRAY_BEGIN:
assoc [0][i ] = "({";
break;
case TOK_ARRAY_END:
assoc [0][i ] = ",})";
break;
case TOK_OBJECT_BEGIN:
assoc [0][i ] = "([";
break;
case TOK_OBJECT_END:
assoc [0][i ] = ",])";
break;
case TOK_DEFAULT:
/* Basically an illegal literal so we turn it into a string. */
if (assoc [0][i ] != "")
assoc [0][i ] = "\"" + assoc [0][i ] + "\"";
break;
case TOK_WS:
assoc [0][i ] = "";
break;
}
tmp += assoc [0][i ];
}
D (3, assoc );
D (2, tmp );
return restore_variable (tmp );
}
void test ()
{
string msg1 = @JSON_MSG
{
"facebook_url": "http://www.facebook.com/sharer.php?u=http://0.gp/bZO",
"stat_url": "http://0.gp/bZO+",
"twitter_url": "http://twitter.com/home?status=http://0.gp/bZO",
"error":
{
"msg": "OK",
"code": 0
},
"url": "http://0.gp/bZO",
"target_host": "ebspso.dnsalias.org",
"host": "http://0.gp/"
}
JSON_MSG;
string msg2 = @JSON_MSG
{
"Image":
{
"Width": 800,
"Height": 600,
"Title": "View from 15th Floor",
"Thumbnail":
{
"Url": "http://www.example.com/image/481989943",
"Height": 125,
"Width": "100"
},
"IDs": [116, 943, 234, 38793]
}
}
JSON_MSG;
D (1, msg1 );
D (0, processJSON (msg1 ));
D (1, msg2 );
D (0, processJSON (msg2 ));
}
Tricky
|
| |
|
|
| Tricky |
 |
September 08 2009 17:03 PM |
|
|

Newbie
Status: offline
Registered: 08/11/09
Posts: 4
|
This has better integer and real number comparisons.
Licensed as usual: http://0.gp/bZY/lpmuds/LICENSE
PHP Formatted Code /*
* json.c
*
* mixed decodeJSON(string message)
* Creates an LPC variable from a JSON message.
*
* string encodeJSON(mixed lpcvar)
* Creates a JSON message from an LPC variable.
*
*/
#define DEBUG_LEVEL 0
#define D(l,x) if (((l) - (DEBUG_LEVEL)) <= 0) printf("%O\n\n", x)
#define INT "(0|[1-9][0-9]*)"
#define FRAC "[.][0-9]+"
#define EXP "[eE][+-]?[0-9]+"
#define STRING "\"([^\"])*\""
// #define NUMBER "[-]?[0-9]+([.][0-9]+)?([eE][+-]?[0-9]+)?"
#define REAL "[-]?" + INT + "(" + FRAC + ")(" + EXP + ")?"
#define INTEGER "[-]?" + INT + "(" + EXP + ")?"
#define LITERAL "(false|null|true)"
#define NAME_SEPARATOR ":"
#define VALUE_SEPARATOR ","
#define ARRAY_BEGIN "[[]"
#define ARRAY_END "[]]"
#define OBJECT_BEGIN "{"
#define OBJECT_END "}"
#define WS "( |\t|\r|\n)+"
#define TOK_DEFAULT 0
#define TOK_STRING 1
#define TOK_REAL 2
#define TOK_INTEGER 3
#define TOK_LITERAL 4
#define TOK_NAME_SEPARATOR 5
#define TOK_VALUE_SEPARATOR 6
#define TOK_ARRAY_BEGIN 7
#define TOK_ARRAY_END 8
#define TOK_OBJECT_BEGIN 9
#define TOK_OBJECT_END 10
#define TOK_WS 11
mixed decodeJSON (string message )
{
mixed *assoc;
string tmp = "";
int i, sz;
/* Preserve quotes. */
message = replace_string (message, "\\\"", """);
D (2, message );
assoc = reg_assoc (
message,
({
STRING,
REAL,
INTEGER,
LITERAL,
NAME_SEPARATOR,
VALUE_SEPARATOR,
ARRAY_BEGIN,
ARRAY_END,
OBJECT_BEGIN,
OBJECT_END,
WS,
}),
({
TOK_STRING,
TOK_REAL,
TOK_INTEGER,
TOK_LITERAL,
TOK_NAME_SEPARATOR,
TOK_VALUE_SEPARATOR,
TOK_ARRAY_BEGIN,
TOK_ARRAY_END,
TOK_OBJECT_BEGIN,
TOK_OBJECT_END,
TOK_WS,
}),
TOK_DEFAULT
);
D (1, assoc );
for (i = 0, sz = sizeof(assoc [0]) ; i < sz ; i++ )
{
switch (assoc [1][i ])
{
/* Here we try to clean up the integer, specifically with the exponent. */
case TOK_INTEGER:
{
mixed a;
string ts = "";
int l, tsz;
a = reg_assoc (
assoc [0][i ],
({ "-", INT, EXP }),
({ 1, 2, 3 }),
0
);
for (l = 0, tsz = sizeof(a [0]) ; l < tsz ; l++ )
{
if (a [1][l ] == 0) continue;
switch (a [1][l ])
{
case 1:
case 2: break;
case 3:
/* LPC requires a sign for the exponent. */
if (regexp (a [0][l ], "[eE][0-9]+"))
{
a [0][l ] = replace_string (a [0][l ], "e", "e+");
a [0][l ] = replace_string (a [0][l ], "E", "E+");
}
break;
}
ts += a [0][l ];
}
assoc [0][i ] = ts;
break;
}
/* Here we try to clean up the real, specifically with the exponent. */
case TOK_REAL:
{
mixed a;
string ts = "";
int l, tsz, last = 0;
a = reg_assoc (
assoc [0][i ],
({ "-", INT, FRAC, EXP }),
({ 1, 2, 3, 4 }),
0
);
for (l = 0, tsz = sizeof(a [0]) ; l < tsz ; l++ )
{
if (a [1][l ] == 0) continue;
switch (a [1][l ])
{
case 1:
case 2: break;
case 3:
/* This shouldn't trigger. */
if (last != 2) ts += "0";
break;
case 4:
/* LPC requires a sign for the exponent. */
if (regexp (a [0][l ], "[eE][0-9]+"))
{
a [0][l ] = replace_string (a [0][l ], "e", "e+");
a [0][l ] = replace_string (a [0][l ], "E", "E+");
}
break;
}
ts += a [0][l ];
last = a [1][l ];
}
assoc [0][i ] = ts;
break;
}
/* No idea what to do with this currently. */
/* Convert into a string and leave for the programmer to translate. */
case TOK_LITERAL:
assoc [0][i ] = "\"" + assoc [0][i ] + "\"";
break;
case TOK_ARRAY_BEGIN:
assoc [0][i ] = "({";
break;
/* Add a comma to pacify restore_variable() */
case TOK_ARRAY_END:
assoc [0][i ] = ",})";
break;
case TOK_OBJECT_BEGIN:
assoc [0][i ] = "([";
break;
/* Add a comma to pacify restore_variable() */
case TOK_OBJECT_END:
assoc [0][i ] = ",])";
break;
/* Basically an illegal literal so we turn it into a string. */
case TOK_DEFAULT:
if (assoc [0][i ] != "")
assoc [0][i ] = "\"" + assoc [0][i ] + "\"";
break;
/* Strip whitespace. */
case TOK_WS:
assoc [0][i ] = "";
break;
}
tmp += assoc [0][i ];
}
/* Restore quotes. */
tmp = replace_string (tmp, """, "\\\"");
D (2, assoc );
D (1, tmp );
return restore_variable (tmp );
}
string encodeJSON (mixed mixvar )
{
int sz;
string ret;
if (undefinedp (mixvar )) return "null";
if (intp (mixvar ) || floatp (mixvar )) return "" + mixvar;
if (stringp (mixvar ))
{
mixvar = replace_string (mixvar, "\"", "\\\"");
mixvar = "\"" + mixvar + "\"";
mixvar = replace_string (mixvar, "\\", "\\\\");
mixvar = replace_string (mixvar, "\\\"", "\"");
mixvar = replace_string (mixvar, "\b", "\\b");
mixvar = replace_string (mixvar, "" + 0x0c, "\\f");
mixvar = replace_string (mixvar, "\n", "\\n");
mixvar = replace_string (mixvar, "\r", "\\r");
mixvar = replace_string (mixvar, "\t", "\\t");
return mixvar;
}
if (arrayp (mixvar ))
{
ret = "[";
sz = sizeof(mixvar );
for (int i = 0 ; i < sz ; i++ )
{
if (i != 0) ret += ",";
ret += encodeJSON (mixvar [i ]);
}
return ret + "]";
}
if (mapp (mixvar ))
{
mixed ks, vs;
ret = "{";
ks = keys (mixvar );
vs = values (mixvar );
sz = sizeof(ks );
for (int i = 0 ; i < sz ; i++ )
{
if (i != 0) ret += ",";
ret += encodeJSON (ks [i ]) + ":" + encodeJSON (vs [i ]);
}
return ret + "}";
}
if (bufferp (mixvar ))
{
ret = "";
sz = sizeof(mixvar );
for (int i = 0 ; i < sz ; i++ )
{
if (i != 0) ret += ",";
ret += encodeJSON (mixvar [i ]);
}
return ret;
}
if (classp (mixvar ))
{
ret = "";
mixvar = disassemble_class (mixvar );
sz = sizeof(mixvar );
for (int i = 0 ; i < sz ; i++ )
{
if (i != 0) ret += ",";
ret += encodeJSON (mixvar [i ]);
}
return ret;
}
if (objectp (mixvar ))
{
/* What to do?
* return "" or return encodeJSON(save_variable(mixvar))
*
* return "" for now.
*/
return "";
}
if (functionp (mixvar )) return "";
/* Anything weird and we return null.
* It really shouldn't get here, but you never know.
*/
return "null";
}
void test ()
{
mixed mixvar;
string msg;
msg = @JSON_MSG
{
"name": "Jack (\"Bee\") Nimble",
"format": {
"type": "rect",
"width": 1920,
"height": 1080,
"interlace": false,
"frame rate": 24
}
}
JSON_MSG;
printf("%s\n\n", msg );
mixvar = decodeJSON (msg );
D (0, mixvar );
printf("%s\n\n", encodeJSON (mixvar ));
msg = @JSON_MSG
{
"Image":
{
"Width": 800,
"Height": 600,
"Title": "View from 15th Floor",
"Thumbnail":
{
"Url": "http://www.example.com/image/481989943",
"Height": 125,
"Width": "100"
},
"IDs": [116, 943, 234, 38793]
}
}
JSON_MSG;
printf("%s\n\n", msg );
mixvar = decodeJSON (msg );
D (0, mixvar );
printf("%s\n\n", encodeJSON (mixvar ));
msg = @JSON_MSG
{ "x":1e -2, "y": 1.0e2 }
JSON_MSG;
printf("%s\n\n", msg );
mixvar = decodeJSON (msg );
D (0, mixvar );
printf("%s\n\n", encodeJSON (mixvar ));
}
|
| |
|
|
| aidil |
 |
September 08 2009 17:54 PM |
|
|

Admin
Status: offline
Registered: 08/10/09
Posts: 13
|
For those interested, gurbalib (svn://wotf.org/gurbalib) has a JSON serialize/deserialize implemented in /daemons/serialize/json.c
It uses DGD's parse_string for parsing json messages. The code that generates them is very similar in setup to the code Tricky posted.
Because of the widespread support for it, and there being proper formal documentation and such, and being capable of encoding all data that is currently in use on i3, I see it as a good alternative for mudmode for future versions of the i3 protocol. It would allow the kind of structured data that makes i3 such a nice protocol, while removing the obscure mudmode stuff.
Aidil
visit Way of the Force: http://wotf.org/
|
| |
|
|
| Content generated in: 1.23 seconds |
|
|