| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312 |
- //
- // Copyright (c) 2014-2015, THUNDERBEAST GAMES LLC All rights reserved
- //
- // Permission is hereby granted, free of charge, to any person obtaining a copy
- // of this software and associated documentation files (the "Software"), to deal
- // in the Software without restriction, including without limitation the rights
- // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- // copies of the Software, and to permit persons to whom the Software is
- // furnished to do so, subject to the following conditions:
- //
- // The above copyright notice and this permission notice shall be included in
- // all copies or substantial portions of the Software.
- //
- // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- // THE SOFTWARE.
- //
- #include "JSIO.h"
- #include "JSVM.h"
- #include <Atomic/IO/BufferQueue.h>
- #include <Atomic/IO/File.h>
- 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,
- IO_MAGIC_BINARY
- };
- 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! Only File and BufferQueue are supported for now.
- StringHash type(o->GetType());
- if (type == File::GetTypeStatic())
- {
- // Cast it!
- serial = (Serializer*)((File*)o);
- }
- else if (type == BufferQueue::GetTypeStatic())
- {
- // Cast it!
- serial = (Serializer*)((BufferQueue*)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! Only File and BufferQueue are supported for now.
- StringHash type(o->GetType());
- if (type == File::GetTypeStatic())
- {
- // Cast it!
- deserial = (Deserializer*)((File*)o);
- }
- else if (type == BufferQueue::GetTypeStatic())
- {
- // Cast it!
- deserial = (Deserializer*)((BufferQueue*)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;
- case IO_MAGIC_BINARY:
- str = (const char*) duk_require_buffer_data(ctx, 0, &length);
- success = serial->Write(str, length);
- 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;
- }
- char* data;
- 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;
- case IO_MAGIC_BINARY:
- length = deserial->GetSize() - deserial->GetPosition();
- duk_push_fixed_buffer(ctx, length);
- duk_push_buffer_object(ctx, -1, 0, length, DUK_BUFOBJ_UINT8ARRAY);
- duk_replace(ctx, -2);
- data = (char*) duk_require_buffer_data(ctx, 0, &length);
- success = deserial->Read(data, length);
- return 1;
- default:
- break;
- }
- duk_push_undefined(ctx);
- return 1;
- }
- static int Deserializer_GetSize(duk_context* 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;
- }
- duk_push_number(ctx, (double)deserial->GetSize());
- 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_push_c_function(ctx, Serializer_Write, 1);
- duk_set_magic(ctx, -1, (unsigned)IO_MAGIC_BINARY);
- duk_put_prop_string(ctx, -2, "writeBinary");
- 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_push_c_function(ctx, Deserializer_Read, 0);
- duk_set_magic(ctx, -1, (unsigned)IO_MAGIC_BINARY);
- duk_put_prop_string(ctx, -2, "readBinary");
- duk_push_c_function(ctx, Deserializer_GetSize, 0);
- duk_put_prop_string(ctx, -2, "getSize");
- duk_pop(ctx);
- }
- static int File_ReadText(duk_context* ctx)
- {
- duk_push_this(ctx);
- File* file = js_to_class_instance<File>(ctx, -1, 0);
- String text;
- file->ReadText(text);
- duk_push_string(ctx, text.CString());
- return 1;
- }
- void jsapi_init_io(JSVM* vm)
- {
- duk_context* ctx = vm->GetJSContext();
- js_class_get_prototype(ctx, "Atomic", "File");
- duk_push_c_function(ctx, File_ReadText, 0);
- duk_put_prop_string(ctx, -2, "readText");
- duk_pop(ctx);
- AddSerializerMixin(ctx, "Atomic", "File");
- AddDeserializerMixin(ctx, "Atomic", "File");
- AddSerializerMixin(ctx, "Atomic", "BufferQueue");
- AddDeserializerMixin(ctx, "Atomic", "BufferQueue");
- }
- }
|