1 /* Copyright (C) 2000-2006 Thomas Bopp, Thorsten Hampel, Ludger Merkens
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation; either version 2 of the License, or
6 * (at your option) any later version.
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 * $Id: serialize.pike,v 1.2 2009/05/02 05:44:39 astra Exp $
19 * made availiable via add_constant. If you really have to inherit this file,
22 #include <attributes.h>
29 * serialization mechanisms for sTeam. They are inherited into _Database and
30 * note that you have to provide an implementation for the prototype
31 * find_object(), see database.pike for an example. Since _Database inherits
32 * serialize.pike, it is compiled without the add_constant on
33 * _Database->find_object(), so you can't rely on the constant. If your Object
34 * knows about _Database you could do
35 * object find_object(int oid) { return _Database->find_object(oid); }
40 object find_object(int id);
41 //object oLocal; // assume this to be this_object()
43 private string serialize_object(object obj);
44 private string serialize_mapping(mapping map);
45 private string serialize_array(array arr);
46 private string serialize_function(function f);
47 string serialize(mixed arg,void|string encoding);
48 private mapping unserialize_map(string stream);
49 private array unserialize_array(string stream);
50 private int unserialize_number(string stream);
51 private function unserialize_function(string stream);
52 mixed unserialize(string stream, void|object oThis);
53 private object unserialize_object(string stream);
55 private Thread.Local fStringSerializer = Thread.Local();
57 #define STRING_CLOSED 1
59 #define STRING_MASKED 4
63 serialize_object(object obj)
65 if ( !functionp(obj->get_object_id) ) {
68 int oid = obj->get_object_id();
76 serialize_function(function f)
81 o = function_object(f);
83 if ( !objectp(o) || !functionp(o->get_object_id) ) return 0;
85 iFOID = o->get_object_id();
86 return "$" + function_name(f) + " " + iFOID;
93 serialize_mapping(mapping map)
100 index = indices(map);
103 for ( i = 0, sz = sizeof(index); i < sz; i++ ) {
104 if ( stringp(index[i]) )
105 composed += "\"" + index[i] + "\":";
106 else if ( objectp(index[i]) )
107 composed += serialize_object(index[i]) + ":";
108 else if ( arrayp(index[i]))
109 composed += serialize_array(index[i]) + ":";
110 else if ( functionp(index[i]))
111 composed += serialize_function(index[i]) + ":";
113 composed += index[i] + ":";
117 composed += serialize_array(val) + ",";
118 else if ( mappingp(val) )
119 composed += serialize_mapping(val) + ",";
120 else if ( stringp(val) )
121 composed += fStringSerializer->get()(val) + ",";
122 else if ( objectp(val) )
123 composed += serialize_object(val) + ",";
124 else if ( functionp(val) )
125 composed += serialize_function(val) + ",";
127 composed += val + ",";
137 serialize_array(array arr)
143 for ( i = 0, sz = sizeof(arr); i < sz; i++ ) {
144 if ( arrayp(arr[i]) )
145 composed += serialize_array(arr[i]) + ",";
146 else if ( mappingp(arr[i]) )
147 composed += serialize_mapping(arr[i]) + ",";
148 else if ( stringp(arr[i]) )
149 // composed += "\"" + replace(arr[i],"\"","\\char34") + "\",";
150 composed += fStringSerializer->get()(arr[i]) + ",";
151 else if ( objectp(arr[i]) )
152 composed += serialize_object(arr[i]) + ",";
153 else if ( functionp(arr[i]) )
154 composed += serialize_function(arr[i]) + ",";
155 else if ( intp(arr[i]) )
156 composed += sprintf("%d,", arr[i]);
158 composed += sprintf("%O,", arr[i]);
167 private string serialize_string(string s)
169 return "\"" + replace(s, "\"", "\\char34") + "\"";
175 private string serialize_utf8(string s)
177 return "\"" + string_to_utf8(replace(s, "\"", "\\char34")) + "\"";
183 serialize(mixed arg, void|string encoding)
185 if (encoding == "utf-8")
186 fStringSerializer->set(serialize_utf8);
188 fStringSerializer->set(serialize_string);
191 return serialize_array(arg);
192 else if ( mappingp(arg) )
193 return serialize_mapping(arg);
194 else if ( stringp(arg) )
195 // return "\"" + replace(arg,"\"", "\\char34") + "\"";
196 return fStringSerializer->get()(arg);
197 else if ( objectp(arg) )
198 return serialize_object(arg);
199 else if ( functionp(arg) )
200 return serialize_function(arg);
208 unserialize_array(string sArray)
219 len = strlen(sArray);
224 open_string = STRING_CLOSED;
227 if ( sArray[i] == '\"' && !(open_string & STRING_MASKED) ) {
228 if ( open_string & STRING_CLOSED )
229 open_string = STRING_OPEN;
231 open_string = STRING_CLOSED;
233 else if ( sArray[i] == '\\' ) {
234 open_string |= STRING_MASKED;
236 else if ( open_string == STRING_CLOSED )
238 if ( sArray[i] == '{' ) {
241 else if ( sArray[i] == '[' ) {
244 else if ( sArray[i] == '}' ) {
247 else if ( sArray[i] == ']' ) {
250 else if ( sArray[i] == ',' &&
251 open_arr_brace == 0 &&
252 open_map_brace == 0 )
254 part = sArray[start..i-1];
255 mixed res = unserialize(part);
259 if ( open_string & STRING_MASKED )
260 open_string -= STRING_MASKED;
262 else if ( open_string & STRING_MASKED )
263 open_string -= STRING_MASKED;
272 #define EXTRACT_MODE_INDEX 1
273 #define EXTRACT_MODE_DATA 2
277 unserialize_map(string map)
296 * first thing expected is an index ...
298 mode = EXTRACT_MODE_INDEX;
299 open_string = STRING_CLOSED;
302 if ( map[i] == '\"' && !(open_string & STRING_MASKED) )
304 if ( open_string & STRING_CLOSED )
305 open_string = STRING_OPEN;
307 open_string = STRING_CLOSED;
309 else if ( map[i] == '\\' ) {
310 open_string |= STRING_MASKED;
312 else if ( open_string == STRING_CLOSED )
314 if ( mode == EXTRACT_MODE_INDEX )
319 part = map[start..i-1];
320 index = unserialize(part);
322 mode = EXTRACT_MODE_DATA;
327 if ( map[i] == '{' ) {
330 else if ( map[i] == '[' ) {
333 else if ( map[i] == '}' ) {
336 else if ( map[i] == ']' ) {
339 else if ( map[i] == ',' &&
340 open_arr_brace == 0 &&
341 open_map_brace == 0 )
343 part = map[start..i-1];
345 /* ASSERTINFO(stringp(index) || intp(index) ||
346 objectp(index) || arrayp(index),
347 "False index, not string, integer, "+
348 "object or array!");*/
349 mapp[index] = unserialize(part);
351 mode = EXTRACT_MODE_INDEX;
355 else if ( open_string & STRING_MASKED )
356 open_string -= STRING_MASKED;
366 unserialize_number(string str)
371 if ( sscanf(str, "%d.%d", a, b) == 2 ) {
372 sscanf(str,"%f", res);
375 sscanf(str, "%d", res);
383 unserialize_object(string stream)
388 sscanf(stream, "%d", res);
390 proxy = find_object(res);
399 unserialize_function(string f)
404 string sFunctionName;
407 if ( sscanf(f, "%s %d", sFunctionName, iOID) == 2 ) {
408 o = find_object(iOID);
415 if ( !functionp(o->get_function) )
417 res = o->get_function(sFunctionName);
420 res = 0;// failed to unserialize function
427 unserialize(string stream, void|object oThis)
429 int len = strlen(stream);
433 if ( stream[0] == '\"' )
434 return replace((string)stream[1..len-2], "\\char34", "\"");
435 else if ( stream[0] == '\{' )
436 return (array)unserialize_array(stream[1..len-2]);
437 else if ( stream[0] == '\[' )
438 return (mapping)unserialize_map(stream[1..len-2]);
439 else if ( stream[0] == '#' )
440 return unserialize_object(stream[1..len-1]);
441 else if ( stream[0] == '%')
442 return unserialize_object(stream[1..len-1]);
443 else if ( stream[0] == '$')
444 return unserialize_function(stream[1..len-1]);
446 return unserialize_number(stream);