Browse Source

Serializer/Deserializer Mixin for File

Josh Engebretson 10 years ago
parent
commit
b369fe31da
2 changed files with 204 additions and 0 deletions
  1. 202 0
      Source/AtomicJS/Javascript/JSIO.cpp
  2. 2 0
      Source/ToolCoreJS/CMakeLists.txt

+ 202 - 0
Source/AtomicJS/Javascript/JSIO.cpp

@@ -9,6 +9,205 @@
 namespace Atomic
 {
 
+enum IO_MAGIC_TYPE
+{
+    IO_MAGIC_NONE = 0,
+    IO_MAGIC_INT,
+    IO_MAGIC_BOOL,
+    IO_MAGIC_FLOAT,
+    IO_MAGIC_STRING,
+    IO_MAGIC_ZEROSTRING
+};
+
+
+static Serializer* CastToSerializer(duk_context* ctx, int index)
+{
+    Object* o = js_to_class_instance<Object>(ctx, index, 0);
+    Serializer* serial = NULL;
+
+    if (!o)
+        return NULL;
+
+    // type check! file supported for now
+    if (o->GetType() == File::GetTypeStatic())
+    {
+        // cast it!
+        serial = (Serializer*) ((File*)o);
+    }
+
+    return serial;
+
+}
+
+static Deserializer* CastToDeserializer(duk_context* ctx, int index)
+{
+    Object* o = js_to_class_instance<Object>(ctx, index, 0);
+    Deserializer* deserial = NULL;
+
+    if (!o)
+        return NULL;
+
+    // type check! file supported for now
+    if (o->GetType() == File::GetTypeStatic())
+    {
+        // cast it!
+        deserial = (Deserializer*) ((File*)o);
+    }
+
+    return deserial;
+
+}
+
+
+static int Serializer_Write(duk_context* ctx)
+{
+    duk_int_t magic = duk_get_current_magic(ctx);
+
+    duk_push_this(ctx);
+
+    // safe cast based on type check above
+    Serializer* serial = CastToSerializer(ctx, duk_get_top_index(ctx));
+
+    duk_pop(ctx);
+
+    if (!serial)
+    {
+        duk_push_boolean(ctx, 0);
+        return 1;
+    }
+
+    const char* str;
+    size_t length;
+
+    IO_MAGIC_TYPE v = (IO_MAGIC_TYPE) magic;
+
+    bool success = false;
+
+    switch(v)
+    {
+        case IO_MAGIC_INT:
+            success = serial->WriteInt((int) duk_require_number(ctx, 0));
+            break;
+        case IO_MAGIC_STRING:
+             str = duk_require_string(ctx, 0);
+             length = strlen(str);
+             success = serial->Write(str, length);
+             /*
+             if (length)
+             {
+                buffer.Resize(length);
+
+                for (size_t i = 0; i < length; i++)
+                    buffer[i] = str[i];
+
+                serial->WriteBuffer(buffer);
+             }
+             */
+            break;
+        case IO_MAGIC_ZEROSTRING:
+            success = serial->WriteString(duk_require_string(ctx, 0));
+            break;
+        default:
+            break;
+    }
+
+    duk_push_boolean(ctx, success ? 1 : 0);
+
+    return 1;
+
+}
+
+static int Deserializer_Read(duk_context* ctx)
+{
+    duk_int_t magic = duk_get_current_magic(ctx);
+
+    duk_push_this(ctx);
+
+    // safe cast based on type check above
+    Deserializer* deserial = CastToDeserializer(ctx, duk_get_top_index(ctx));
+
+    duk_pop(ctx);
+
+    if (!deserial)
+    {
+        duk_push_boolean(ctx, 0);
+        return 1;
+    }
+
+    PODVector<unsigned char> buffer;
+    String str;
+    size_t length;
+
+    IO_MAGIC_TYPE v = (IO_MAGIC_TYPE) magic;
+
+    bool success = false;
+
+    switch(v)
+    {
+        case IO_MAGIC_INT:
+            duk_push_number(ctx, (double) deserial->ReadInt());
+            return 1;
+        case IO_MAGIC_STRING:
+            length = deserial->GetSize() - deserial->GetPosition();
+            str.Resize(length + 1);
+            deserial->Read(&str[0], length);
+            str[length] = '\0';
+            duk_push_string(ctx, str.CString());
+            return 1;
+        case IO_MAGIC_ZEROSTRING:
+            success = duk_push_string(ctx, deserial->ReadString().CString());
+            return 1;
+        default:
+            break;
+    }
+
+    duk_push_undefined(ctx);
+
+    return 1;
+
+}
+
+static void AddSerializerMixin(duk_context* ctx, const String& package, const String& classname)
+{
+    js_class_get_prototype(ctx, package.CString(), classname.CString());
+
+    duk_push_c_function(ctx, Serializer_Write, 1);
+    duk_set_magic(ctx, -1, (unsigned) VAR_INT);
+    duk_put_prop_string(ctx, -2, "writeInt");
+
+    duk_push_c_function(ctx, Serializer_Write, 1);
+    duk_set_magic(ctx, -1, (unsigned) IO_MAGIC_STRING);
+    duk_put_prop_string(ctx, -2, "writeString");
+
+    duk_push_c_function(ctx, Serializer_Write, 1);
+    duk_set_magic(ctx, -1, (unsigned) IO_MAGIC_ZEROSTRING);
+    duk_put_prop_string(ctx, -2, "writeZeroString");
+
+    duk_pop(ctx);
+
+}
+
+static void AddDeserializerMixin(duk_context* ctx, const String& package, const String& classname)
+{
+    js_class_get_prototype(ctx, package.CString(), classname.CString());
+
+    duk_push_c_function(ctx, Deserializer_Read, 0);
+    duk_set_magic(ctx, -1, (unsigned) VAR_INT);
+    duk_put_prop_string(ctx, -2, "readInt");
+
+    duk_push_c_function(ctx, Deserializer_Read, 0);
+    duk_set_magic(ctx, -1, (unsigned) IO_MAGIC_STRING);
+    duk_put_prop_string(ctx, -2, "readString");
+
+    duk_push_c_function(ctx, Deserializer_Read, 0);
+    duk_set_magic(ctx, -1, (unsigned) IO_MAGIC_ZEROSTRING);
+    duk_put_prop_string(ctx, -2, "readZeroString");
+
+    duk_pop(ctx);
+
+}
+
+
 static int File_ReadText(duk_context* ctx)
 {
     duk_push_this(ctx);
@@ -31,6 +230,9 @@ void jsapi_init_io(JSVM* vm)
     duk_put_prop_string(ctx, -2, "readText");
     duk_pop(ctx);
 
+    AddSerializerMixin(ctx, "Atomic", "File");
+    AddDeserializerMixin(ctx, "Atomic", "File");
+
 }
 
 }

+ 2 - 0
Source/ToolCoreJS/CMakeLists.txt

@@ -22,3 +22,5 @@ set (SOURCE_FILES ${SOURCE_FILES} ${JAVASCRIPT_BINDINGS_SOURCE} )
 add_library(ToolCoreJS ${SOURCE_FILES})
 
 target_link_libraries(ToolCoreJS ToolCore)
+
+add_dependencies(ToolCoreJS AtomicTool)