diff options
Diffstat (limited to 'src/core/basetypes/MCObject.cc')
-rw-r--r-- | src/core/basetypes/MCObject.cc | 58 |
1 files changed, 58 insertions, 0 deletions
diff --git a/src/core/basetypes/MCObject.cc b/src/core/basetypes/MCObject.cc index 527b0c71..fff2055d 100644 --- a/src/core/basetypes/MCObject.cc +++ b/src/core/basetypes/MCObject.cc @@ -4,6 +4,7 @@ #include <typeinfo> #include <cxxabi.h> #include <libetpan/libetpan.h> +#include <string.h> #include "MCAutoreleasePool.h" #include "MCString.h" @@ -13,6 +14,7 @@ #include "MCAssert.h" #include "MCMainThread.h" #include "MCLog.h" +#include "MCHashMap.h" using namespace mailcore; @@ -250,3 +252,59 @@ void Object::cancelDelayedPerformMethod(Method method, void * context) cancelDelayedCall(data->caller); free(data); } + +HashMap * Object::serializable() +{ + HashMap * result = HashMap::hashMap(); + result->setObjectForKey(MCSTR("class"), className()); + return result; +} + +void Object::importSerializable(HashMap * serializable) +{ + MCAssert(0); +} + +static chash * constructors = NULL; + +void Object::initObjectConstructors() +{ + constructors = chash_new(CHASH_DEFAULTSIZE, CHASH_COPYKEY); +} + +void Object::registerObjectConstructor(char * className, void * (* objectConstructor)(void)) +{ + static pthread_once_t once = PTHREAD_ONCE_INIT; + pthread_once(&once, initObjectConstructors); + + chashdatum key; + chashdatum value; + key.data = className; + key.len = strlen(className); + value.data = (void *) objectConstructor; + value.len = 0; + chash_set(constructors, &key, &value, NULL); +} + +Object * Object::objectWithSerializable(HashMap * serializable) +{ + if (serializable == NULL) + return NULL; + + void * (* objectConstructor)(void) = NULL; + + chashdatum key; + chashdatum value; + const char * className = ((String *) serializable->objectForKey(MCSTR("class")))->UTF8Characters(); + key.data = (void *) className; + key.len = strlen(className); + int r = chash_get(constructors, &key, &value); + if (r < 0) + return NULL; + + objectConstructor = (void * (*)()) value.data; + Object * obj = (Object *) objectConstructor(); + obj->importSerializable(serializable); + return obj->autorelease(); +} + |