pike.git/
src/
builtin.cmod
Branch:
Tag:
Non-build tags
All tags
No tags
2011-01-21
2011-01-21 16:22:23 by Henrik Grubbström (Grubba) <grubba@grubba.org>
10313643fd3afce82bc6fa89812947693b9a89b7 (
204
lines) (+
204
/-
0
)
[
Show
|
Annotate
]
Branch:
7.9
Serializer: First implementation of the Serializer interface.
3762:
/*! @endmodule */
+
/*! @module Serializer
+
*/
+
+
/*! @class Serializable
+
*!
+
*! The base class for serializable objects.
+
*!
+
*! Inherit this class in classes that need to be serializable.
+
*!
+
*! @seealso
+
*! @[Serializer.serialize()], @[Serializer.deserialize()]
+
*/
+
PIKECLASS Serializable
+
{
+
static void low_serialize(int i, struct svalue *fun, int use_setter)
+
{
+
struct inherit *inh;
+
struct program *p = Pike_fp->current_object->prog;
+
struct svalue *save_sp = Pike_sp;
+
+
inh = p->inherits + i;
+
p = inh->prog;
+
+
for (i = 0; i < p->num_identifier_references; i++) {
+
struct reference *ref = PTR_FROM_INT(p, i);
+
struct identifier *id;
+
if ((ref->id_flags & ID_HIDDEN) ||
+
((ref->id_flags & (ID_PRIVATE|ID_INHERITED)) ==
+
(ID_PRIVATE|ID_INHERITED))) {
+
continue;
+
}
+
id = ID_FROM_PTR(p, ref);
+
if (!IDENTIFIER_IS_VARIABLE(id->identifier_flags)) {
+
continue;
+
}
+
ref_push_string(id->name);
+
ref_push_type_value(id->type);
+
if (use_setter) {
+
push_function(get_setter(Pike_fp->current_object,
+
i + inh->identifier_level),
+
f_Setter_cq__backtick_28_29_fun_num);
+
} else {
+
low_object_index_no_free(Pike_sp, Pike_fp->current_object,
+
i + inh->identifier_level);
+
Pike_sp++;
+
}
+
apply_svalue(fun, 3);
+
pop_stack();
+
}
+
if (Pike_sp != save_sp) {
+
/* Not likely, but... */
+
pop_n_elems(Pike_sp - save_sp);
+
}
+
}
+
+
/*! @decl void _serialize(object o, @
+
*! function(string, type, mixed:void) serializer)
+
*!
+
*! Dispatch function for serialization.
+
*!
+
*! @param o
+
*! Object to serialize. Always a context of the current object.
+
*!
+
*! @param serializer
+
*! Function to be called once for every variable
+
*! in the inheriting class.
+
*!
+
*! The @[serializer] function will be called with three arguments:
+
*! @dl
+
*! @item
+
*! @tt{symbol@} - The symbol name.
+
*! @item
+
*! @tt{symbol_type@} - The type of the symbol.
+
*! @item
+
*! @tt{value@} - The value of the symbol.
+
*! @enddl
+
*!
+
*! @note
+
*! The symbols will be listed in the order they were defined
+
*! in the class.
+
*!
+
*! @note
+
*! This function is typically called via @[Serializer.serialize()].
+
*/
+
PIKEFUN void _serialize(object o,
+
function(string, type, mixed:void) serializer)
+
flags ID_PROTECTED;
+
rawtype tFunc(tObj tFunc(tStr tType(tMix) tMix, tVoid), tVoid);
+
{
+
if (o != Pike_fp->current_object) {
+
SIMPLE_BAD_ARG_ERROR("_serialize", 1, "this");
+
}
+
low_serialize(Pike_sp[-args].subtype, serializer, 0);
+
pop_n_elems(args);
+
push_int(0);
+
}
+
+
/*! @decl _deserialize(object o, @
+
*! function(string, type, @
+
*! function(mixed:void): mixed) deserializer)
+
*!
+
*! Dispatch function for deserialization.
+
*!
+
*! @param o
+
*! Object to serialize. Always a context of the current object.
+
*!
+
*! @param deserializer
+
*! Function to be called once for every variable
+
*! in the inheriting class.
+
*!
+
*! The @[deserializer] function will be called with three arguments:
+
*! @dl
+
*! @item
+
*! @tt{symbol@} - The symbol name.
+
*! @item
+
*! @tt{symbol_type@} - The type of the symbol.
+
*! @item
+
*! @tt{setter@} - Function that sets the symbol value.
+
*! @enddl
+
*!
+
*! @note
+
*! The symbols will be listed in the order they were defined
+
*! in the class.
+
*!
+
*! @note
+
*! This function is typically called via @[Serializer.deserialize()].
+
*/
+
PIKEFUN void _deserialize(object o,
+
function(string, type,
+
function(mixed:void): mixed) deserializer)
+
flags ID_PROTECTED;
+
rawtype tFunc(tObj tFunc(tStr tType(tMix) tFunc(tMix, tVoid), tVoid), tVoid);
+
{
+
if (o != Pike_fp->current_object) {
+
SIMPLE_BAD_ARG_ERROR("_serialize", 1, "this");
+
}
+
low_serialize(Pike_sp[-args].subtype, deserializer, 1);
+
pop_n_elems(args);
+
push_int(0);
+
}
+
}
+
/*! @endclass
+
*/
+
+
/*! @decl void serialize(object o, @
+
*! function(string, type, mixed:void) serializer)
+
*!
+
*! Call @[LFUN::_serialize()] in @[o].
+
*!
+
*! @seealso
+
*! @[deserialize()], @[LFUN::_serialize()],
+
*! @[Serializable()->_serialize()]
+
*/
+
PIKEFUN void serialize(object o,
+
function(string, type, mixed:void) serializer)
+
rawtype tFunc(tObj tFunc(tStr tType(tMix) tMix, tVoid), tVoid);
+
{
+
struct inherit *inh;
+
struct program *p;
+
ptrdiff_t fun;
+
if (!(p = o->prog)) {
+
Pike_error("Indexing a destructed object.\n");
+
}
+
inh = p->inherits + Pike_sp[-args].subtype;
+
p = inh->prog;
+
if ((fun = low_find_lfun(p, LFUN__SERIALIZE)) == -1) {
+
Pike_error("Serialization not supported by object.\n");
+
}
+
apply_low(o, fun + inh->identifier_level, args);
+
}
+
+
/*! @decl void deserialize(object o, @
+
*! function(string, type,
+
*! function(mixed:void):void) deserializer)
+
*!
+
*! Call @[LFUN::_deserialize()] in @[o].
+
*!
+
*! @seealso
+
*! @[serialize()], @[LFUN::_deserialize()],
+
*! @[Serializable()->_deserialize()]
+
*/
+
PIKEFUN void deserialize(object o,
+
function(string, type,
+
function(mixed:void):void) deserializer)
+
rawtype tFunc(tObj tFunc(tStr tType(tMix) tFunc(tMix, tVoid), tVoid), tVoid);
+
{
+
struct inherit *inh;
+
struct program *p;
+
ptrdiff_t fun;
+
if (!(p = o->prog)) {
+
Pike_error("Indexing a destructed object.\n");
+
}
+
inh = p->inherits + Pike_sp[-args].subtype;
+
p = inh->prog;
+
if ((fun = low_find_lfun(p, LFUN__DESERIALIZE)) == -1) {
+
Pike_error("Deserialization not supported by object.\n");
+
}
+
apply_low(o, fun + inh->identifier_level, args);
+
}
+
+
/*! @endmodule
+
*/
+
/*! @module ADT */