mirror of
https://github.com/Ylianst/MeshAgent
synced 2026-02-25 00:53:02 +00:00
Major agent update.
This commit is contained in:
@@ -30,7 +30,92 @@ limitations under the License.
|
||||
#endif
|
||||
|
||||
#define ILibDuktape_ModSearch_ModuleFile (void*)0xFF
|
||||
#define ILibDuktape_ModSearch_ModuleObject (void*)0xFE
|
||||
#define ILibDuktape_ModSearch_JSInclude "\xFF_ModSearch_JSINCLUDE"
|
||||
#define ILibDuktape_ModSearch_ModulePath "\xFF_ModSearch_Path"
|
||||
|
||||
duk_ret_t ILibDuktape_ModSearch_GetJSModule(duk_context *ctx, char *id)
|
||||
{
|
||||
ILibHashtable table = NULL;
|
||||
int idLen = (int)strnlen_s(id, 1024);
|
||||
char *retVal = NULL;
|
||||
|
||||
duk_push_heap_stash(ctx); // [stash]
|
||||
if (duk_has_prop_string(ctx, -1, "ModSearchTable"))
|
||||
{
|
||||
duk_get_prop_string(ctx, -1, "ModSearchTable"); // [stash][ptr]
|
||||
table = (ILibHashtable)duk_to_pointer(ctx, -1);
|
||||
duk_pop(ctx); // [stash]
|
||||
}
|
||||
else
|
||||
{
|
||||
table = ILibHashtable_Create();
|
||||
duk_push_pointer(ctx, table); // [stash][ptr]
|
||||
duk_put_prop_string(ctx, -2, "ModSearchTable"); // [stash]
|
||||
}
|
||||
duk_pop(ctx); // ...
|
||||
|
||||
retVal = ILibHashtable_Get(table, ILibDuktape_ModSearch_ModuleFile, id, idLen);
|
||||
if (retVal == NULL)
|
||||
{
|
||||
duk_push_heap_stash(ctx);
|
||||
char *mpath;
|
||||
duk_size_t mpathLen;
|
||||
mpath = Duktape_GetStringPropertyValueEx(ctx, -1, ILibDuktape_ModSearch_ModulePath, NULL, &mpathLen);
|
||||
duk_pop(ctx);
|
||||
|
||||
char *fileName = ILibMemory_AllocateA(idLen + 4 + mpathLen + 1);
|
||||
if (mpath == NULL)
|
||||
{
|
||||
sprintf_s(fileName, idLen + 4, "%s.js", id);
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf_s(fileName, idLen + 5 + mpathLen, "%s/%s.js", mpath, id);
|
||||
}
|
||||
int dataLen = ILibReadFileFromDiskEx(&retVal, fileName);
|
||||
if (dataLen > 0) { duk_push_lstring(ctx, retVal, dataLen); free(retVal); }
|
||||
else
|
||||
{
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
duk_push_string(ctx, retVal);
|
||||
}
|
||||
return(1);
|
||||
}
|
||||
void ILibDuktape_ModSearch_AddModuleObject(duk_context *ctx, char *id, void *heapptr)
|
||||
{
|
||||
int idLen = (int)strnlen_s(id, 1024);
|
||||
ILibHashtable table = NULL;
|
||||
|
||||
duk_push_heap_stash(ctx); // [stash]
|
||||
if (duk_has_prop_string(ctx, -1, "ModSearchTable"))
|
||||
{
|
||||
duk_get_prop_string(ctx, -1, "ModSearchTable"); // [stash][ptr]
|
||||
table = (ILibHashtable)duk_to_pointer(ctx, -1);
|
||||
duk_pop(ctx); // [stash]
|
||||
}
|
||||
else
|
||||
{
|
||||
table = ILibHashtable_Create();
|
||||
duk_push_pointer(ctx, table); // [stash][ptr]
|
||||
duk_put_prop_string(ctx, -2, "ModSearchTable"); // [stash]
|
||||
}
|
||||
|
||||
duk_push_heapptr(ctx, heapptr);
|
||||
duk_put_prop_string(ctx, -2, Duktape_GetStashKey(heapptr));
|
||||
heapptr = ILibHashtable_Put(table, ILibDuktape_ModSearch_ModuleObject, id, idLen, heapptr);
|
||||
|
||||
if (heapptr != NULL)
|
||||
{
|
||||
// Remove the old object that was in the table
|
||||
duk_del_prop_string(ctx, -1, Duktape_GetStashKey(heapptr));
|
||||
}
|
||||
duk_pop(ctx); // ...
|
||||
}
|
||||
int ILibDuktape_ModSearch_AddModule(duk_context *ctx, char *id, char *module, int moduleLen)
|
||||
{
|
||||
ILibHashtable table = NULL;
|
||||
@@ -89,8 +174,20 @@ duk_ret_t mod_Search_Files(duk_context *ctx, char* id)
|
||||
char fileName[255];
|
||||
char *data;
|
||||
int dataLen;
|
||||
char *mpath = NULL;
|
||||
|
||||
sprintf_s(fileName, sizeof(fileName), "%s.js", id);
|
||||
duk_push_heap_stash(ctx);
|
||||
mpath = Duktape_GetStringPropertyValue(ctx, -1, ILibDuktape_ModSearch_ModulePath, NULL);
|
||||
duk_pop(ctx);
|
||||
|
||||
if (mpath == NULL)
|
||||
{
|
||||
sprintf_s(fileName, sizeof(fileName), "%s.js", id);
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf_s(fileName, sizeof(fileName), "%s/%s.js", mpath, id);
|
||||
}
|
||||
dataLen = ILibReadFileFromDiskEx(&data, fileName);
|
||||
if (dataLen > 0)
|
||||
{
|
||||
@@ -118,6 +215,13 @@ duk_ret_t mod_Search_Files(duk_context *ctx, char* id)
|
||||
return DUK_RET_ERROR;
|
||||
}
|
||||
}
|
||||
void ILibDuktape_ModSearch_AddHandler_AlsoIncludeJS(duk_context *ctx, char *js, size_t jsLen)
|
||||
{
|
||||
duk_push_heap_stash(ctx); // [stash]
|
||||
duk_push_lstring(ctx, js, jsLen); // [stash][str]
|
||||
duk_put_prop_string(ctx, -2, ILibDuktape_ModSearch_JSInclude); // [stash]
|
||||
duk_pop(ctx); // ...
|
||||
}
|
||||
|
||||
duk_ret_t mod_Search(duk_context *ctx)
|
||||
{
|
||||
@@ -128,6 +232,7 @@ duk_ret_t mod_Search(duk_context *ctx)
|
||||
void *chain;
|
||||
ILibSimpleDataStore mDS = NULL;
|
||||
char *module;
|
||||
void *j;
|
||||
|
||||
if (!duk_is_string(ctx, 0)) { return ILibDuktape_Error(ctx, "mod_search(): Invalid 'ID' parameter"); }
|
||||
id = (char*)duk_get_lstring(ctx, 0, &idLen);
|
||||
@@ -142,8 +247,17 @@ duk_ret_t mod_Search(duk_context *ctx)
|
||||
duk_push_heap_stash(ctx);
|
||||
duk_get_prop_string(ctx, -1, "ModSearchTable");
|
||||
table = (ILibHashtable)duk_to_pointer(ctx, -1);
|
||||
func = (ILibDuktape_ModSearch_PUSH_Object)ILibHashtable_Get(table, NULL, id, (int)idLen);
|
||||
|
||||
// First check if there is a JS override
|
||||
j = ILibHashtable_Get(table, ILibDuktape_ModSearch_ModuleObject, id, (int)idLen);
|
||||
if (j != NULL)
|
||||
{
|
||||
duk_push_heapptr(ctx, j);
|
||||
duk_put_prop_string(ctx, 3, "exports");
|
||||
return(0);
|
||||
}
|
||||
|
||||
func = (ILibDuktape_ModSearch_PUSH_Object)ILibHashtable_Get(table, NULL, id, (int)idLen);
|
||||
if (func == NULL)
|
||||
{
|
||||
if ((module = (char*)ILibHashtable_Get(table, ILibDuktape_ModSearch_ModuleFile, id, (int)idLen)) != NULL)
|
||||
@@ -173,18 +287,30 @@ duk_ret_t mod_Search(duk_context *ctx)
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf_s(key, sizeof(key), "Module: %s (NOT FOUND in DB)", id);
|
||||
duk_push_string(ctx, key);
|
||||
duk_throw(ctx);
|
||||
return DUK_RET_ERROR;
|
||||
return mod_Search_Files(ctx, id);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Init this temp value, to detect if the module wants to add JS code
|
||||
duk_push_heap_stash(ctx);
|
||||
duk_del_prop_string(ctx, -1, ILibDuktape_ModSearch_JSInclude);
|
||||
duk_pop(ctx);
|
||||
|
||||
func(ctx, chain);
|
||||
duk_put_prop_string(ctx, 3, "exports");
|
||||
return 0;
|
||||
|
||||
duk_push_heap_stash(ctx);
|
||||
if (duk_has_prop_string(ctx, -1, ILibDuktape_ModSearch_JSInclude))
|
||||
{
|
||||
duk_get_prop_string(ctx, -1, ILibDuktape_ModSearch_JSInclude);
|
||||
return(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
void ILibDuktape_ModSearch_Destroy(duk_context *ctx, void *user)
|
||||
@@ -202,6 +328,23 @@ void ILibDuktape_ModSearch_Destroy(duk_context *ctx, void *user)
|
||||
duk_pop(ctx);
|
||||
}
|
||||
}
|
||||
|
||||
duk_ret_t ILibDuktape_ModSearch_setModulePath(duk_context *ctx)
|
||||
{
|
||||
if (duk_is_string(ctx, 0))
|
||||
{
|
||||
duk_push_heap_stash(ctx);
|
||||
duk_dup(ctx, 0);
|
||||
duk_put_prop_string(ctx, -2, ILibDuktape_ModSearch_ModulePath);
|
||||
}
|
||||
else
|
||||
{
|
||||
return(ILibDuktape_Error(ctx, "Invalid Path"));
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
void ILibDuktape_ModSearch_Init(duk_context * ctx, void * chain, ILibSimpleDataStore mDB)
|
||||
{
|
||||
duk_module_duktape_init(ctx);
|
||||
@@ -225,5 +368,10 @@ void ILibDuktape_ModSearch_Init(duk_context * ctx, void * chain, ILibSimpleDataS
|
||||
duk_put_prop_string(ctx, -2, "modSearch"); // [globalString]
|
||||
duk_pop(ctx); // ...
|
||||
|
||||
duk_push_global_object(ctx); // [g]
|
||||
ILibDuktape_CreateInstanceMethod(ctx, "setModulePath", ILibDuktape_ModSearch_setModulePath, 1);
|
||||
duk_pop(ctx); // ...
|
||||
|
||||
|
||||
ILibDuktape_Helper_AddHeapFinalizer(ctx, ILibDuktape_ModSearch_Destroy, NULL);
|
||||
}
|
||||
|
||||
@@ -23,7 +23,10 @@ limitations under the License.
|
||||
typedef void (*ILibDuktape_ModSearch_PUSH_Object)(duk_context *ctx, void *chain);
|
||||
|
||||
int ILibDuktape_ModSearch_AddHandler(duk_context *ctx, char *id, ILibDuktape_ModSearch_PUSH_Object handler);
|
||||
void ILibDuktape_ModSearch_AddHandler_AlsoIncludeJS(duk_context *ctx, char *js, size_t jsLen);
|
||||
int ILibDuktape_ModSearch_AddModule(duk_context *ctx, char *id, char *module, int moduleLen);
|
||||
void ILibDuktape_ModSearch_AddModuleObject(duk_context *ctx, char *id, void *heapptr);
|
||||
duk_ret_t ILibDuktape_ModSearch_GetJSModule(duk_context *ctx, char *id);
|
||||
void ILibDuktape_ModSearch_Init(duk_context *ctx, void *chain, ILibSimpleDataStore mDB);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -137,34 +137,40 @@ ILibDuktape_ChildProcess_SubProcess* ILibDuktape_ChildProcess_SpawnedProcess_PUS
|
||||
|
||||
ILibDuktape_CreateInstanceMethod(ctx, "kill", ILibDuktape_ChildProcess_Kill, 0);
|
||||
|
||||
duk_push_object(ctx);
|
||||
ILibDuktape_WriteID(ctx, "childProcess.subProcess.stdout");
|
||||
duk_dup(ctx, -2);
|
||||
ILibDuktape_CreateReadonlyProperty(ctx, "parent");
|
||||
retVal->stdOut = ILibDuktape_ReadableStream_Init(ctx, ILibDuktape_ChildProcess_SubProcess_StdOut_OnPause, ILibDuktape_ChildProcess_SubProcess_StdOut_OnResume, retVal);
|
||||
ILibDuktape_CreateReadonlyProperty(ctx, "stdout");
|
||||
if (ILibProcessPipe_Process_IsDetached(mProcess) == 0)
|
||||
{
|
||||
duk_push_object(ctx);
|
||||
ILibDuktape_WriteID(ctx, "childProcess.subProcess.stdout");
|
||||
duk_dup(ctx, -2);
|
||||
ILibDuktape_CreateReadonlyProperty(ctx, "parent");
|
||||
retVal->stdOut = ILibDuktape_ReadableStream_Init(ctx, ILibDuktape_ChildProcess_SubProcess_StdOut_OnPause, ILibDuktape_ChildProcess_SubProcess_StdOut_OnResume, retVal);
|
||||
ILibDuktape_CreateReadonlyProperty(ctx, "stdout");
|
||||
|
||||
duk_push_object(ctx);
|
||||
ILibDuktape_WriteID(ctx, "childProcess.subProcess.stderr");
|
||||
duk_dup(ctx, -2);
|
||||
ILibDuktape_CreateReadonlyProperty(ctx, "parent");
|
||||
retVal->stdErr = ILibDuktape_ReadableStream_Init(ctx, ILibDuktape_ChildProcess_SubProcess_StdErr_OnPause, ILibDuktape_ChildProcess_SubProcess_StdErr_OnResume, retVal);
|
||||
ILibDuktape_CreateReadonlyProperty(ctx, "stderr");
|
||||
duk_push_object(ctx);
|
||||
ILibDuktape_WriteID(ctx, "childProcess.subProcess.stderr");
|
||||
duk_dup(ctx, -2);
|
||||
ILibDuktape_CreateReadonlyProperty(ctx, "parent");
|
||||
retVal->stdErr = ILibDuktape_ReadableStream_Init(ctx, ILibDuktape_ChildProcess_SubProcess_StdErr_OnPause, ILibDuktape_ChildProcess_SubProcess_StdErr_OnResume, retVal);
|
||||
ILibDuktape_CreateReadonlyProperty(ctx, "stderr");
|
||||
|
||||
duk_push_object(ctx);
|
||||
ILibDuktape_WriteID(ctx, "childProcess.subProcess.stdin");
|
||||
duk_dup(ctx, -2);
|
||||
ILibDuktape_CreateReadonlyProperty(ctx, "parent");
|
||||
retVal->stdIn = ILibDuktape_WritableStream_Init(ctx, ILibDuktape_ChildProcess_SubProcess_StdIn_WriteHandler, ILibDuktape_ChildProcess_SubProcess_StdIn_EndHandler, retVal);
|
||||
ILibDuktape_CreateReadonlyProperty(ctx, "stdin");
|
||||
duk_push_object(ctx);
|
||||
ILibDuktape_WriteID(ctx, "childProcess.subProcess.stdin");
|
||||
duk_dup(ctx, -2);
|
||||
ILibDuktape_CreateReadonlyProperty(ctx, "parent");
|
||||
retVal->stdIn = ILibDuktape_WritableStream_Init(ctx, ILibDuktape_ChildProcess_SubProcess_StdIn_WriteHandler, ILibDuktape_ChildProcess_SubProcess_StdIn_EndHandler, retVal);
|
||||
ILibDuktape_CreateReadonlyProperty(ctx, "stdin");
|
||||
|
||||
if (callback != NULL) { ILibDuktape_EventEmitter_AddOnce(emitter, "exit", callback); }
|
||||
|
||||
ILibProcessPipe_Process_AddHandlers(mProcess, 4096, ILibDuktape_ChildProcess_SubProcess_ExitHandler,
|
||||
ILibDuktape_ChildProcess_SubProcess_StdOutHandler,
|
||||
ILibDuktape_ChildProcess_SubProcess_StdErrHandler,
|
||||
ILibDuktape_ChildProcess_SubProcess_SendOK, retVal);
|
||||
if (callback != NULL) { ILibDuktape_EventEmitter_AddOnce(emitter, "exit", callback); }
|
||||
|
||||
ILibProcessPipe_Process_AddHandlers(mProcess, 4096, ILibDuktape_ChildProcess_SubProcess_ExitHandler,
|
||||
ILibDuktape_ChildProcess_SubProcess_StdOutHandler,
|
||||
ILibDuktape_ChildProcess_SubProcess_StdErrHandler,
|
||||
ILibDuktape_ChildProcess_SubProcess_SendOK, retVal);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (callback != NULL) { ILibDuktape_EventEmitter_AddOnce(emitter, "exit", callback); }
|
||||
}
|
||||
return(retVal);
|
||||
}
|
||||
|
||||
@@ -189,6 +195,10 @@ duk_ret_t ILibDuktape_ChildProcess_execFile(duk_context *ctx)
|
||||
void *callback = NULL;
|
||||
ILibProcessPipe_Process p = NULL;
|
||||
ILibProcessPipe_SpawnTypes spawnType = ILibProcessPipe_SpawnTypes_DEFAULT;
|
||||
#ifndef WIN32
|
||||
int uid = -1;
|
||||
#endif
|
||||
|
||||
|
||||
for (i = 0; i < nargs; ++i)
|
||||
{
|
||||
@@ -215,6 +225,9 @@ duk_ret_t ILibDuktape_ChildProcess_execFile(duk_context *ctx)
|
||||
{
|
||||
// Options
|
||||
spawnType = (ILibProcessPipe_SpawnTypes)Duktape_GetIntPropertyValue(ctx, i, "type", (int)ILibProcessPipe_SpawnTypes_DEFAULT);
|
||||
#ifndef WIN32
|
||||
uid = Duktape_GetIntPropertyValue(ctx, i, "uid", -1);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -237,7 +250,11 @@ duk_ret_t ILibDuktape_ChildProcess_execFile(duk_context *ctx)
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
p = ILibProcessPipe_Manager_SpawnProcessEx2(manager, target, args, spawnType, 0);
|
||||
#else
|
||||
p = ILibProcessPipe_Manager_SpawnProcessEx3(manager, target, args, spawnType, (void*)(uint64_t)uid, 0);
|
||||
#endif
|
||||
if (p == NULL)
|
||||
{
|
||||
return(ILibDuktape_Error(ctx, "child_process.execFile(): Could not exec [%s]", target));
|
||||
@@ -263,6 +280,8 @@ void ILibDuktape_ChildProcess_PUSH(duk_context *ctx, void *chain)
|
||||
duk_put_prop_string(ctx, -2, "WINLOGON");
|
||||
duk_push_int(ctx, 3);
|
||||
duk_put_prop_string(ctx, -2, "TERM");
|
||||
duk_push_int(ctx, 4);
|
||||
duk_put_prop_string(ctx, -2, "DETACHED");
|
||||
duk_put_prop_string(ctx, -2, "SpawnTypes");
|
||||
}
|
||||
void ILibDuktape_ChildProcess_Init(duk_context *ctx)
|
||||
@@ -324,4 +343,4 @@ public:
|
||||
WritableStream stdin;
|
||||
|
||||
};
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -21,14 +21,34 @@ limitations under the License.
|
||||
|
||||
#include "microstack/ILibParsers.h"
|
||||
#include "microstack/ILibAsyncServerSocket.h"
|
||||
#include "microstack/ILibSimpleDataStore.h"
|
||||
#include "ILibDuktape_Helpers.h"
|
||||
#include "duktape.h"
|
||||
#include "ILibDuktape_ScriptContainer.h"
|
||||
#include "ILibDuktape_Debugger.h"
|
||||
#include "ILibDuktapeModSearch.h"
|
||||
|
||||
|
||||
#define ILibDuktape_Debugger_SCRIPT_SOURCE "_scriptSourceForDebugger"
|
||||
#define ILibDuktape_Debugger_SCRIPT_PATH "_scriptPathForDebugger"
|
||||
#define ILibDuktape_Debugger_AttachOptions "\xFF_debugger_attachOptions"
|
||||
#define ILibDuktape_Debugger_Options_Rejector "\xFF_rejector"
|
||||
#define ILibDuktape_Debugger_Options_Resolver "\xFF_resolver"
|
||||
#define ILibDuktape_Debugger_DebugObject "_DbgObj"
|
||||
#define ILibDuktape_Debugger_HostChain "_HostChain"
|
||||
#define ILibDuktape_Debugger_MemoryReportInterval "_Debugger_MemoryReporting"
|
||||
extern size_t ILibDuktape_ScriptContainer_TotalAllocations;
|
||||
|
||||
typedef struct ILibDuktape_Debugger
|
||||
{
|
||||
ILibChain_Link *chainedObject;
|
||||
duk_context *ctx;
|
||||
duk_thread_state hoststate;
|
||||
sem_t hostlock;
|
||||
int waitConnection;
|
||||
void *debugThread;
|
||||
int webport;
|
||||
void *interval;
|
||||
char data[sizeof(char*)];
|
||||
#ifdef WIN32
|
||||
SOCKET listener;
|
||||
SOCKET client;
|
||||
@@ -38,7 +58,130 @@ typedef struct ILibDuktape_Debugger
|
||||
#endif
|
||||
}ILibDuktape_Debugger;
|
||||
|
||||
void *DebugWebEngine_Context;
|
||||
void *DebugWebEngine_Chain;
|
||||
void *DebugWebEngine_Thread;
|
||||
|
||||
void ILibDuktape_Debugger_AsyncWaitConn(ILibDuktape_Debugger *dbg);
|
||||
duk_ret_t ILibDuktape_Debugger_MemoryReportingSink(duk_context *ctx)
|
||||
{
|
||||
duk_push_string(ctx, "MemoryAllocations");
|
||||
duk_push_int(ctx, (duk_int_t)ILibDuktape_ScriptContainer_TotalAllocations);
|
||||
duk_debugger_notify(ctx, 2);
|
||||
return(0);
|
||||
}
|
||||
void ILibDuktape_Debugger_StartMemoryReporting(duk_context *ctx)
|
||||
{
|
||||
duk_push_global_object(ctx); // [g]
|
||||
duk_get_prop_string(ctx, -1, "setInterval"); // [g][setInterval]
|
||||
duk_swap_top(ctx, -2); // [setInterVal][this]
|
||||
duk_push_c_function(ctx, ILibDuktape_Debugger_MemoryReportingSink, 0); // [setInterVal][this][func]
|
||||
duk_push_int(ctx, 5000); // [setInterVal][this][func][delay]
|
||||
if (duk_pcall_method(ctx, 2) != 0) { duk_pop(ctx); return; } // [interval]
|
||||
duk_push_heap_stash(ctx); // [interval][stash]
|
||||
duk_swap_top(ctx, -2); // [stash][interval]
|
||||
duk_put_prop_string(ctx, -2, ILibDuktape_Debugger_MemoryReportInterval);// [stash]
|
||||
duk_pop(ctx); // ...
|
||||
}
|
||||
void ILibDuktape_Debugger_StopMemoryReporting(duk_context *ctx)
|
||||
{
|
||||
duk_push_heap_stash(ctx);
|
||||
duk_del_prop_string(ctx, -1, ILibDuktape_Debugger_MemoryReportInterval);
|
||||
duk_pop(ctx);
|
||||
}
|
||||
|
||||
void ILibDuktape_Debugger_Socket_finish(void *udata)
|
||||
{
|
||||
ILibDuktape_Debugger *dbg = (ILibDuktape_Debugger*)udata;
|
||||
|
||||
if (dbg->client != ~0)
|
||||
{
|
||||
#ifdef WIN32
|
||||
closesocket(dbg->client);
|
||||
#else
|
||||
shutdown(dbg->client, SHUT_RDWR);
|
||||
close(dbg->client);
|
||||
#endif
|
||||
dbg->client = ~0;
|
||||
}
|
||||
|
||||
ILibDuktape_Debugger_StopMemoryReporting(dbg->ctx);
|
||||
}
|
||||
|
||||
void ILibDuktape_Debugger_Socket_waitconn(void *udata)
|
||||
{
|
||||
ILibDuktape_Debugger *dbg = (ILibDuktape_Debugger*)udata;
|
||||
if (!ILibMemory_CanaryOK(dbg))
|
||||
{
|
||||
printf("INVALID CANARY\n");
|
||||
}
|
||||
|
||||
|
||||
dbg->client = accept(dbg->listener, NULL, NULL);
|
||||
((void**)dbg->data)[0] = dbg;
|
||||
|
||||
if (dbg->client == ~0)
|
||||
{
|
||||
#ifdef WIN32
|
||||
printf("Ooops, invalid socket: %d\n", WSAGetLastError());
|
||||
#else
|
||||
printf("Ooops, invalid socket: %d\n", errno);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
duk_size_t ILibDuktape_Debugger_PeekCB(void *udata)
|
||||
{
|
||||
ILibDuktape_Debugger *dbg = (ILibDuktape_Debugger*)udata;
|
||||
int bytes = 0;
|
||||
#ifndef WIN32
|
||||
char tmp[8];
|
||||
#endif
|
||||
|
||||
// Set the socket to non-blocking mode, because we need to play nice and share the MicroStack thread
|
||||
#if defined(WIN32)
|
||||
|
||||
if (dbg->client == ~0)
|
||||
{
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
//// On Windows must set NON_BLOCK to check this
|
||||
//int flags = 1;
|
||||
//ioctlsocket(dbg->client, FIONBIO, (u_long *)(&flags));
|
||||
|
||||
//bytes = recv(dbg->client, tmp, sizeof(tmp), MSG_PEEK);
|
||||
|
||||
//flags = 0;
|
||||
//ioctlsocket(dbg->client, FIONBIO, (u_long *)(&flags));
|
||||
u_long avail = 0;
|
||||
int rc = ioctlsocket(dbg->client, FIONREAD, &avail);
|
||||
if (rc != 0)
|
||||
{
|
||||
fprintf(stderr, "%s: ioctlsocket() returned %d, closing connection\n",
|
||||
__FILE__, rc);
|
||||
fflush(stderr);
|
||||
return(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (avail == 0)
|
||||
{
|
||||
return 0; /* nothing to read */
|
||||
}
|
||||
else
|
||||
{
|
||||
return 1; /* something to read */
|
||||
}
|
||||
}
|
||||
#else
|
||||
// Everything else, use MSG_DONTWAIT
|
||||
bytes = recv(dbg->client, tmp, sizeof(tmp), MSG_PEEK | MSG_DONTWAIT);
|
||||
#endif
|
||||
|
||||
return(bytes > 0 ? 1 : 0);
|
||||
}
|
||||
duk_size_t ILibDuktape_Debugger_ReadCB(void *udata, char *buffer, duk_size_t length)
|
||||
{
|
||||
ILibDuktape_Debugger *dbg = (ILibDuktape_Debugger*)udata;
|
||||
@@ -50,41 +193,554 @@ duk_size_t ILibDuktape_Debugger_WriteCB(void *udata, const char *buffer, duk_siz
|
||||
ILibDuktape_Debugger *dbg = (ILibDuktape_Debugger*)udata;
|
||||
return (duk_size_t)send(dbg->client, buffer, (int)length, 0);
|
||||
}
|
||||
void ILibDuktape_Debugger_DetachCB(void *udata)
|
||||
void ILibDuktape_Debugger_DetachCB(duk_context *ctx, void *udata)
|
||||
{
|
||||
ILibDuktape_Debugger_Socket_finish(udata);
|
||||
ILibDuktape_Debugger_AsyncWaitConn((ILibDuktape_Debugger*)udata);
|
||||
UNREFERENCED_PARAMETER(ctx);
|
||||
}
|
||||
|
||||
void ILibDuktape_Debugger_AsyncWaitConn_PreSelect(void* object, fd_set *readset, fd_set *writeset, fd_set *errorset, int* blocktime)
|
||||
{
|
||||
ILibDuktape_Debugger *dbg = (ILibDuktape_Debugger*)((void**)((ILibChain_Link*)object)->ExtraMemoryPtr)[0];
|
||||
if (dbg == NULL || !ILibMemory_CanaryOK(dbg))
|
||||
{
|
||||
((void**)((ILibChain_Link*)object)->ExtraMemoryPtr)[0] = NULL;
|
||||
ILibChain_SafeRemove(((ILibChain_Link*)object)->ParentChain, object);
|
||||
return;
|
||||
}
|
||||
|
||||
if (dbg->waitConnection != 0 && dbg->listener != (SOCKET)~0)
|
||||
{
|
||||
FD_SET(dbg->listener, readset);
|
||||
}
|
||||
}
|
||||
|
||||
void ILibDuktape_Debugger_AsyncWaitConn_PostSelect(void* object, int slct, fd_set *readset, fd_set *writeset, fd_set *errorset)
|
||||
{
|
||||
ILibDuktape_Debugger *dbg = (ILibDuktape_Debugger*)((void**)((ILibChain_Link*)object)->ExtraMemoryPtr)[0];
|
||||
if (dbg == NULL || !ILibMemory_CanaryOK(dbg)) { return; }
|
||||
|
||||
if (dbg->waitConnection != 0 && dbg->listener != (SOCKET)~0 && FD_ISSET(dbg->listener, readset))
|
||||
{
|
||||
dbg->waitConnection = 0;
|
||||
dbg->client = accept(dbg->listener, NULL, NULL);
|
||||
((void**)dbg->data)[0] = dbg;
|
||||
|
||||
if (dbg->client != ~0)
|
||||
{
|
||||
ILibDuktape_Debugger_StartMemoryReporting(dbg->ctx);
|
||||
duk_debugger_attach(dbg->ctx, ILibDuktape_Debugger_ReadCB, ILibDuktape_Debugger_WriteCB, ILibDuktape_Debugger_PeekCB, NULL, NULL, NULL, ILibDuktape_Debugger_DetachCB, (void*)dbg);
|
||||
}
|
||||
}
|
||||
}
|
||||
void ILibDuktape_Debugger_AsyncWaitConn(ILibDuktape_Debugger *dbg)
|
||||
{
|
||||
if (dbg->chainedObject == NULL)
|
||||
{
|
||||
dbg->chainedObject = ILibChain_Link_Allocate(sizeof(ILibChain_Link), sizeof(void*));
|
||||
((void**)dbg->chainedObject->ExtraMemoryPtr)[0] = dbg;
|
||||
dbg->chainedObject->PreSelectHandler = ILibDuktape_Debugger_AsyncWaitConn_PreSelect;
|
||||
dbg->chainedObject->PostSelectHandler = ILibDuktape_Debugger_AsyncWaitConn_PostSelect;
|
||||
ILibChain_SafeAdd(Duktape_GetChain(dbg->ctx), dbg->chainedObject);
|
||||
}
|
||||
else
|
||||
{
|
||||
ILibForceUnBlockChain(Duktape_GetChain(dbg->ctx));
|
||||
}
|
||||
dbg->waitConnection = 1;
|
||||
}
|
||||
|
||||
void ILibDuktape_Debugger_DestroyEx(void *chain, void *user)
|
||||
{
|
||||
duk_destroy_heap(DebugWebEngine_Context);
|
||||
}
|
||||
|
||||
void DebugWebEngine_RunEx(void *chain, void *user)
|
||||
{
|
||||
ILibChain_OnDestroyEvent_AddHandler(chain, ILibDuktape_Debugger_DestroyEx, NULL);
|
||||
if (duk_peval_string(DebugWebEngine_Context, "process.on('uncaughtException', function(e){console.log('Uncaught:', e);}); var duktape_debugger = require('duktape-debugger'); var dbg = new duktape_debugger(); dbg.run();") == 0)
|
||||
{
|
||||
printf("Debugger Initialized...\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Unable to launch debugger client: %s\n", duk_safe_to_string(DebugWebEngine_Context, -1));
|
||||
}
|
||||
duk_pop(DebugWebEngine_Context);
|
||||
}
|
||||
|
||||
void DebugWebEngine_Run(void *obj)
|
||||
{
|
||||
ILibChain_RunOnMicrostackThreadEx(DebugWebEngine_Chain, DebugWebEngine_RunEx, NULL);
|
||||
ILibStartChain(DebugWebEngine_Chain);
|
||||
}
|
||||
void ILibDuktape_Debugger_Destroy(void *chain, void *user)
|
||||
{
|
||||
ILibStopChain(DebugWebEngine_Chain);
|
||||
#ifdef WIN32
|
||||
WaitForSingleObject(DebugWebEngine_Thread, INFINITE);
|
||||
#endif
|
||||
}
|
||||
|
||||
duk_ret_t ILibDuktape_Debugger_StartEngine_UpdatePort(duk_context *ctx)
|
||||
{
|
||||
duk_push_current_function(ctx);
|
||||
ILibDuktape_Debugger *dbg = (ILibDuktape_Debugger*)Duktape_GetPointerProperty(ctx, -1, ILibDuktape_Debugger_DebugObject);
|
||||
int port = duk_require_int(ctx, 0);
|
||||
if (dbg != NULL && ILibMemory_CanaryOK(dbg))
|
||||
{
|
||||
dbg->webport = port;
|
||||
sem_post(&(dbg->hostlock));
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
void ILibDuktape_Debugger_hostCooperate_Sink(void *chain, void *user)
|
||||
{
|
||||
ILibDuktape_Debugger *dbg = (ILibDuktape_Debugger*)user;
|
||||
if (ILibMemory_CanaryOK(dbg))
|
||||
{
|
||||
duk_debugger_cooperate(dbg->ctx);
|
||||
}
|
||||
}
|
||||
duk_ret_t ILibDuktape_Debugger_hostCooperate(duk_context *ctx)
|
||||
{
|
||||
duk_push_current_function(ctx);
|
||||
ILibDuktape_Debugger *dbg = (ILibDuktape_Debugger*)Duktape_GetPointerProperty(ctx, -1, ILibDuktape_Debugger_DebugObject);
|
||||
void *chain = Duktape_GetPointerProperty(ctx, -1, ILibDuktape_Debugger_HostChain);
|
||||
if (chain != NULL && dbg != NULL && ILibMemory_CanaryOK(dbg))
|
||||
{
|
||||
ILibChain_RunOnMicrostackThreadEx(chain, ILibDuktape_Debugger_hostCooperate_Sink, dbg);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
void ILibDuktape_Debugger_detachCleanup_Sink(void *chain, void *user)
|
||||
{
|
||||
ILibDuktape_Debugger *dbg = (ILibDuktape_Debugger*)user;
|
||||
if (ILibMemory_CanaryOK(dbg))
|
||||
{
|
||||
if (dbg->client != (SOCKET)~0 && dbg->waitConnection==0)
|
||||
{
|
||||
ILibDuktape_Debugger_Socket_finish((void*)dbg);
|
||||
ILibDuktape_Debugger_AsyncWaitConn(dbg);
|
||||
}
|
||||
}
|
||||
}
|
||||
duk_ret_t ILibDuktape_Debugger_detachCleanup(duk_context *ctx)
|
||||
{
|
||||
duk_push_current_function(ctx);
|
||||
ILibDuktape_Debugger *dbg = (ILibDuktape_Debugger*)Duktape_GetPointerProperty(ctx, -1, ILibDuktape_Debugger_DebugObject);
|
||||
void *chain = Duktape_GetPointerProperty(ctx, -1, ILibDuktape_Debugger_HostChain);
|
||||
if (chain != NULL && dbg != NULL && ILibMemory_CanaryOK(dbg))
|
||||
{
|
||||
ILibChain_RunOnMicrostackThreadEx(chain, ILibDuktape_Debugger_detachCleanup_Sink, dbg);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
void ILibDuktape_Debugger_hostGC_sink(void *chain, void *user)
|
||||
{
|
||||
ILibDuktape_Debugger *dbg = (ILibDuktape_Debugger*)user;
|
||||
if (ILibMemory_CanaryOK(dbg))
|
||||
{
|
||||
duk_peval_string(dbg->ctx, "_debugGC();"); duk_pop(dbg->ctx);
|
||||
duk_push_string(dbg->ctx, "MemoryAllocations");
|
||||
duk_push_int(dbg->ctx, (duk_int_t)ILibDuktape_ScriptContainer_TotalAllocations);
|
||||
duk_debugger_notify(dbg->ctx, 2);
|
||||
}
|
||||
}
|
||||
duk_ret_t ILibDuktape_Debugger_hostGC(duk_context *ctx)
|
||||
{
|
||||
duk_push_current_function(ctx);
|
||||
ILibDuktape_Debugger *dbg = (ILibDuktape_Debugger*)Duktape_GetPointerProperty(ctx, -1, ILibDuktape_Debugger_DebugObject);
|
||||
void *chain = Duktape_GetPointerProperty(ctx, -1, ILibDuktape_Debugger_HostChain);
|
||||
if (chain != NULL && dbg != NULL && ILibMemory_CanaryOK(dbg))
|
||||
{
|
||||
ILibChain_RunOnMicrostackThreadEx(chain, ILibDuktape_Debugger_hostGC_sink, dbg);
|
||||
}
|
||||
return(0);
|
||||
|
||||
}
|
||||
void ILibDuktape_Debugger_Start(duk_context *ctx, unsigned short debugPort)
|
||||
void* ILibDuktape_Debugger_StartEngine(duk_context *ctx, int transport, int webport)
|
||||
{
|
||||
ILibDuktape_Debugger *dbg;
|
||||
struct sockaddr_in6 local_int;
|
||||
struct sockaddr_in6 remote_int;
|
||||
int remote_int_size = sizeof(struct sockaddr_in6);
|
||||
char *promise = NULL, *duktapeDebugger = NULL;
|
||||
duk_size_t promiseLen, duktapeDebuggerLen;
|
||||
ILibDuktape_Debugger *retVal = NULL;
|
||||
|
||||
memset(&local_int, 0, sizeof(struct sockaddr_in6));
|
||||
local_int.sin6_family = AF_INET;
|
||||
((struct sockaddr_in*)&local_int)->sin_addr.s_addr = INADDR_ANY;
|
||||
local_int.sin6_port = htons(debugPort);
|
||||
if (ILibDuktape_ScriptContainer_DebuggingOK(ctx) != 0)
|
||||
{
|
||||
// Check to made sure we have the debugger dependencies
|
||||
int argTop = duk_get_top(ctx);
|
||||
if (duk_peval_string(ctx, "getJSModule('promise');") == 0 && duk_peval_string(ctx, "getJSModule('duktape-debugger');") == 0)
|
||||
{
|
||||
promise = (char*)duk_to_lstring(ctx, -2, &promiseLen);
|
||||
duktapeDebugger = (char*)duk_to_lstring(ctx, -1, &duktapeDebuggerLen);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Missing Dependencies, so cannot continue with setup
|
||||
duk_peval_string(ctx, "process.emit('uncaughtException', 'Cannot setup debugger, missing promise and/or duktape-debugger');");
|
||||
duk_set_top(ctx, argTop);
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
duk_push_global_object(ctx); // [obj]
|
||||
duk_push_fixed_buffer(ctx, sizeof(ILibDuktape_Debugger)); // [obj][buf]
|
||||
dbg = (ILibDuktape_Debugger*)Duktape_GetBuffer(ctx, -1, NULL);
|
||||
duk_put_prop_string(ctx, -2, "_DbgObj"); // [obj]
|
||||
duk_pop(ctx); // ...
|
||||
// Setup WebEngine
|
||||
DebugWebEngine_Chain = ILibCreateChain();
|
||||
DebugWebEngine_Context = ILibDuktape_ScriptContainer_InitializeJavaScriptEngineEx(SCRIPT_ENGINE_NO_DEBUGGER | SCRIPT_ENGINE_NO_MESH_AGENT_ACCESS | SCRIPT_ENGINE_NO_GENERIC_MARSHAL_ACCESS | SCRIPT_ENGINE_NO_PROCESS_SPAWNING, 0, DebugWebEngine_Chain, NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
ILibChain_OnDestroyEvent_AddHandler(Duktape_GetChain(ctx), ILibDuktape_Debugger_Destroy, NULL);
|
||||
|
||||
ILibDuktape_ModSearch_AddModule(DebugWebEngine_Context, "promise", promise, (int)promiseLen);
|
||||
ILibDuktape_ModSearch_AddModule(DebugWebEngine_Context, "duktape-debugger", duktapeDebugger, (int)duktapeDebuggerLen);
|
||||
|
||||
duk_push_heap_stash(ctx);
|
||||
char *src = Duktape_GetStringPropertyValue(ctx, -1, ILibDuktape_Debugger_SCRIPT_SOURCE, NULL);
|
||||
char *srcPath = Duktape_GetStringPropertyValue(ctx, -1, ILibDuktape_Debugger_SCRIPT_PATH, NULL);
|
||||
duk_pop(ctx);
|
||||
|
||||
if (src != NULL)
|
||||
{
|
||||
if (srcPath == NULL)
|
||||
{
|
||||
duk_push_global_object(ctx); // [g]
|
||||
duk_get_prop_string(ctx, -1, "process"); // [g][process]
|
||||
duk_get_prop_string(ctx, -1, "argv0"); // [g][process][argv0]
|
||||
srcPath = (char*)duk_get_string(ctx, -1);
|
||||
duk_pop_n(ctx, 3); // ...
|
||||
}
|
||||
duk_push_global_object(DebugWebEngine_Context); // [g]
|
||||
duk_push_string(DebugWebEngine_Context, src); // [g][str]
|
||||
duk_get_prop_string(DebugWebEngine_Context, -1, "split"); // [g][str][split]
|
||||
duk_swap_top(DebugWebEngine_Context, -2); // [g][split][this]
|
||||
duk_push_string(DebugWebEngine_Context, "\n"); // [g][split][this][\n]
|
||||
duk_pcall_method(DebugWebEngine_Context, 1); // [g][tokens]
|
||||
duk_put_prop_string(DebugWebEngine_Context, -2, "_scriptTokens"); // [g]
|
||||
duk_push_string(DebugWebEngine_Context, srcPath); // [g][path]
|
||||
duk_put_prop_string(DebugWebEngine_Context, -2, "_scriptPath"); // [g]
|
||||
duk_pop(DebugWebEngine_Context); // ...
|
||||
}
|
||||
|
||||
duk_push_heap_stash(ctx); // [stash]
|
||||
retVal = (ILibDuktape_Debugger*)Duktape_PushBuffer(ctx, sizeof(ILibDuktape_Debugger)); // [stash][dbgobj]
|
||||
duk_put_prop_string(ctx, -2, ILibDuktape_Debugger_DebugObject); // [stash]
|
||||
duk_pop(ctx); // ...
|
||||
|
||||
duk_push_global_object(DebugWebEngine_Context); // [g]
|
||||
duk_push_c_function(DebugWebEngine_Context, ILibDuktape_Debugger_StartEngine_UpdatePort, 1); // [g][func]
|
||||
duk_push_pointer(DebugWebEngine_Context, retVal); // [g][func][ptr]
|
||||
duk_put_prop_string(DebugWebEngine_Context, -2, ILibDuktape_Debugger_DebugObject); // [g][func]
|
||||
duk_put_prop_string(DebugWebEngine_Context, -2, "updateWebPort"); // [g]
|
||||
|
||||
duk_push_c_function(DebugWebEngine_Context, ILibDuktape_Debugger_hostCooperate, 0); // [g][func]
|
||||
duk_push_pointer(DebugWebEngine_Context, retVal); // [g][func][ptr]
|
||||
duk_put_prop_string(DebugWebEngine_Context, -2, ILibDuktape_Debugger_DebugObject); // [g][func]
|
||||
duk_push_pointer(DebugWebEngine_Context, Duktape_GetChain(ctx)); // [g][func][ptr]
|
||||
duk_put_prop_string(DebugWebEngine_Context, -2, ILibDuktape_Debugger_HostChain); // [g][func]
|
||||
duk_put_prop_string(DebugWebEngine_Context, -2, "hostCooperate"); // [g]
|
||||
|
||||
duk_push_c_function(DebugWebEngine_Context, ILibDuktape_Debugger_hostGC, 0); // [g][func]
|
||||
duk_push_pointer(DebugWebEngine_Context, retVal); // [g][func][ptr]
|
||||
duk_put_prop_string(DebugWebEngine_Context, -2, ILibDuktape_Debugger_DebugObject); // [g][func]
|
||||
duk_push_pointer(DebugWebEngine_Context, Duktape_GetChain(ctx)); // [g][func][ptr]
|
||||
duk_put_prop_string(DebugWebEngine_Context, -2, ILibDuktape_Debugger_HostChain); // [g][func]
|
||||
duk_put_prop_string(DebugWebEngine_Context, -2, "hostGC"); // [g]
|
||||
|
||||
|
||||
duk_push_c_function(DebugWebEngine_Context, ILibDuktape_Debugger_detachCleanup, 0); // [g][func]
|
||||
duk_push_pointer(DebugWebEngine_Context, retVal); // [g][func][ptr]
|
||||
duk_put_prop_string(DebugWebEngine_Context, -2, ILibDuktape_Debugger_DebugObject); // [g][func]
|
||||
duk_push_pointer(DebugWebEngine_Context, Duktape_GetChain(ctx)); // [g][func][ptr]
|
||||
duk_put_prop_string(DebugWebEngine_Context, -2, ILibDuktape_Debugger_HostChain); // [g][func]
|
||||
duk_put_prop_string(DebugWebEngine_Context, -2, "detachCleanup"); // [g]
|
||||
|
||||
|
||||
duk_push_int(DebugWebEngine_Context, transport);
|
||||
duk_put_prop_string(DebugWebEngine_Context, -2, "transport");
|
||||
duk_push_int(DebugWebEngine_Context, webport);
|
||||
duk_put_prop_string(DebugWebEngine_Context, -2, "webport");
|
||||
duk_pop(DebugWebEngine_Context); // ...
|
||||
|
||||
retVal->ctx = ctx;
|
||||
sem_init(&(retVal->hostlock), 0, 0);
|
||||
retVal->webport = webport;
|
||||
|
||||
DebugWebEngine_Thread = ILibSpawnNormalThread(DebugWebEngine_Run, NULL);
|
||||
}
|
||||
return(retVal);
|
||||
}
|
||||
duk_ret_t ILibDuktape_Debugger_JSAttach_promise_wait(duk_context *ctx)
|
||||
{
|
||||
char *eventName = (char*)duk_require_string(ctx, 0);
|
||||
if (strcmp(eventName, "resolved") != 0) { return(0); }
|
||||
|
||||
duk_push_heap_stash(ctx);
|
||||
duk_get_prop_string(ctx, -1, ILibDuktape_Debugger_DebugObject);
|
||||
ILibDuktape_Debugger *dbg = (ILibDuktape_Debugger*)Duktape_GetBuffer(ctx, -1, NULL);
|
||||
|
||||
memset(dbg, 0, sizeof(ILibDuktape_Debugger));
|
||||
dbg->ctx = ctx;
|
||||
if((dbg->listener = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1) { dbg->listener = (SOCKET)~0; return; }
|
||||
|
||||
bind(dbg->listener, (struct sockaddr*)&local_int, sizeof(struct sockaddr_in6));
|
||||
listen(dbg->listener, 1);
|
||||
dbg->client = accept(dbg->listener, (struct sockaddr*)&remote_int, &remote_int_size);
|
||||
ILibDuktape_Debugger_Socket_waitconn(dbg);
|
||||
ILibDuktape_Debugger_StartMemoryReporting(dbg->ctx);
|
||||
duk_debugger_attach(dbg->ctx, ILibDuktape_Debugger_ReadCB, ILibDuktape_Debugger_WriteCB, ILibDuktape_Debugger_PeekCB, NULL, NULL, NULL, ILibDuktape_Debugger_DetachCB, (void*)dbg);
|
||||
|
||||
duk_debugger_attach(ctx, ILibDuktape_Debugger_ReadCB, ILibDuktape_Debugger_WriteCB, NULL, NULL, NULL, ILibDuktape_Debugger_DetachCB, (void*)dbg);
|
||||
return(0);
|
||||
}
|
||||
|
||||
void ILibDuktape_Debugger_Stop(duk_context *ctx)
|
||||
void ILibDuktape_Debugger_JSAttach_PopulateSource(duk_context *ctx, char *source)
|
||||
{
|
||||
if (source != NULL)
|
||||
{
|
||||
duk_push_heap_stash(ctx); // [stash]
|
||||
duk_push_string(ctx, source); // [stash][src]
|
||||
duk_put_prop_string(ctx, -2, ILibDuktape_Debugger_SCRIPT_SOURCE); // [stash]
|
||||
duk_pop(ctx); // ...
|
||||
}
|
||||
else
|
||||
{
|
||||
char *script, *scriptPath;
|
||||
int scriptLen;
|
||||
|
||||
duk_push_global_object(ctx); // [g]
|
||||
duk_get_prop_string(ctx, -1, "process"); // [g][process]
|
||||
duk_get_prop_string(ctx, -1, "argv0"); // [g][process][argv0]
|
||||
scriptPath = (char*)duk_to_string(ctx, -1);
|
||||
ILibDuktape_ScriptContainer_CheckEmbeddedEx(scriptPath, &script, &scriptLen);
|
||||
duk_pop_3(ctx); // ...
|
||||
|
||||
if (script != NULL)
|
||||
{
|
||||
duk_push_heap_stash(ctx); // [stash]
|
||||
duk_push_lstring(ctx, script, (duk_size_t)scriptLen); // [stash][src]
|
||||
duk_put_prop_string(ctx, -2, ILibDuktape_Debugger_SCRIPT_SOURCE); // [stash]
|
||||
duk_push_string(ctx, "[embedded].js");
|
||||
duk_put_prop_string(ctx, -2, ILibDuktape_Debugger_SCRIPT_PATH); // [stash]
|
||||
|
||||
duk_pop(ctx); // ...
|
||||
free(script);
|
||||
}
|
||||
else
|
||||
{
|
||||
duk_push_global_object(ctx); // [g]
|
||||
duk_get_prop_string(ctx, -1, "process"); // [g][process]
|
||||
duk_get_prop_string(ctx, -1, "argv0"); // [g][process][argv0]
|
||||
if (duk_get_length(ctx, -1) == 0)
|
||||
{
|
||||
// JS was not specified on command line
|
||||
if (duk_peval_string(ctx, "require('MeshAgent');") == 0)
|
||||
{
|
||||
int CoreModuleLen = 0;
|
||||
ILibSimpleDataStore *db = (ILibSimpleDataStore*)Duktape_GetPointerProperty(ctx, -1, "\xFF_MasterDB");
|
||||
if (db == NULL || (CoreModuleLen = ILibSimpleDataStore_Get(db, "CoreModule", NULL, 0)) <= 0)
|
||||
{
|
||||
ILibDuktape_Error(ctx, "Could Not retrive CoreModule from MeshAgent"); return;
|
||||
}
|
||||
// [g][process][argv0][MeshAgent]
|
||||
char* CoreModule = ILibMemory_Allocate(CoreModuleLen, 0, NULL, NULL);
|
||||
ILibSimpleDataStore_Get(db, "CoreModule", CoreModule, CoreModuleLen);
|
||||
duk_push_lstring(ctx, CoreModule + 4, CoreModuleLen - 4); // [g][process][argv0][MeshAgent][CoreModule]
|
||||
duk_push_heap_stash(ctx);
|
||||
duk_swap_top(ctx, -2);
|
||||
duk_put_prop_string(ctx, -2, ILibDuktape_Debugger_SCRIPT_SOURCE);
|
||||
duk_push_string(ctx, "CoreModule.js");
|
||||
duk_put_prop_string(ctx, -2, ILibDuktape_Debugger_SCRIPT_PATH);
|
||||
free(CoreModule);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
ILibDuktape_Error(ctx, "Unable to retrive running java script"); return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
duk_eval_string(ctx, "require('fs');"); // [g][process][argv0][fs]
|
||||
duk_get_prop_string(ctx, -1, "readFileSync"); // [g][process][argv0][fs][rfs]
|
||||
duk_swap_top(ctx, -2); // [g][process][argv0][rfs][this]
|
||||
duk_dup(ctx, -3); // [g][process][argv0][rfs][this][path]
|
||||
duk_call_method(ctx, 1); // [g][process][argv0][sourceBuffer]
|
||||
}
|
||||
duk_get_prop_string(ctx, -1, "toString"); // [g][process][argv0][sourceBuffer][toString]
|
||||
duk_swap_top(ctx, -2); // [g][process][argv0][toString][this]
|
||||
duk_call_method(ctx, 0); // [g][process][argv0][sourceBuffer]
|
||||
duk_push_heap_stash(ctx); // [g][process][argv0][source][stash]
|
||||
duk_dup(ctx, -2); // [g][process][argv0][source][stash][source]
|
||||
duk_put_prop_string(ctx, -2, ILibDuktape_Debugger_SCRIPT_SOURCE); // [g][process][argv0][source][stash]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
duk_ret_t ILibDuktape_Debugger_JSAttach_promise(duk_context *ctx)
|
||||
{
|
||||
int needWait = 0;
|
||||
#ifndef DUK_USE_DEBUGGER_SUPPORT
|
||||
duk_dup(ctx, 1); // [rejector]
|
||||
duk_push_this(ctx); // [rejector][this]
|
||||
duk_push_string(ctx, "No debugger support"); // [rejector][this][err]
|
||||
duk_call_method(ctx, 1); // [ret]
|
||||
return(0);
|
||||
#endif
|
||||
#ifdef WIN32
|
||||
SOCKET listenerSocket;
|
||||
#else
|
||||
int listenerSocket;
|
||||
#endif
|
||||
struct sockaddr_in6 *local_int;
|
||||
struct sockaddr_in6 localBounded;
|
||||
int localBoundedSize = sizeof(struct sockaddr_in6);
|
||||
|
||||
duk_push_heap_stash(ctx); // [stash]
|
||||
if (duk_has_prop_string(ctx, -1, ILibDuktape_Debugger_AttachOptions))
|
||||
{
|
||||
duk_dup(ctx, 1); // [stash][rejector]
|
||||
duk_push_this(ctx); // [stash][rejector][this]
|
||||
duk_push_string(ctx, "attachDebugger() already called"); // [stash][rejector][this][err]
|
||||
duk_call_method(ctx, 1); // [stash][ret]
|
||||
return(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
duk_push_current_function(ctx); // [stash][func]
|
||||
duk_get_prop_string(ctx, -1, "options"); // [stash][func][options]
|
||||
duk_remove(ctx, -2); // [stash][options]
|
||||
duk_dup(ctx, -1); // [stash][options][options]
|
||||
duk_put_prop_string(ctx, -3, ILibDuktape_Debugger_AttachOptions); // [stash][options]
|
||||
duk_dup(ctx, 0); duk_put_prop_string(ctx, -2, ILibDuktape_Debugger_Options_Resolver);
|
||||
duk_dup(ctx, 1); duk_put_prop_string(ctx, -2, ILibDuktape_Debugger_Options_Rejector);
|
||||
}
|
||||
|
||||
int transport = Duktape_GetIntPropertyValue(ctx, -1, "transport", 0);
|
||||
int webport = Duktape_GetIntPropertyValue(ctx, -1, "webport", 0);
|
||||
char *source = Duktape_GetStringPropertyValue(ctx, -1, "source", NULL);
|
||||
|
||||
local_int = Duktape_IPAddress4_FromString("127.0.0.1", transport);
|
||||
#ifdef WIN32
|
||||
if ((listenerSocket = WSASocketW(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, WSA_FLAG_NO_HANDLE_INHERIT)) == -1) { listenerSocket = (SOCKET)~0; }
|
||||
#else
|
||||
if ((listenerSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1) { listenerSocket = (SOCKET)~0; }
|
||||
#endif
|
||||
if (listenerSocket == (SOCKET)~0)
|
||||
{
|
||||
// Error creating socket
|
||||
duk_dup(ctx, 1); // [rejector]
|
||||
duk_push_this(ctx); // [rejector][this]
|
||||
duk_push_string(ctx, "Error Creating Debug Transport Socket"); // [rejector][this][err]
|
||||
duk_call_method(ctx, 1);
|
||||
return(0);
|
||||
}
|
||||
bind(listenerSocket, (struct sockaddr*)local_int, sizeof(struct sockaddr_in6));
|
||||
#if defined(WINSOCK2)
|
||||
getsockname(listenerSocket, (struct sockaddr*)&localBounded, (int*)&localBoundedSize);
|
||||
#else
|
||||
getsockname(listenerSocket, (struct sockaddr*)&localBounded, (socklen_t*)&localBoundedSize);
|
||||
#endif
|
||||
transport = (int)ntohs(localBounded.sin6_port);
|
||||
|
||||
if (Duktape_GetIntPropertyValue(ctx, -1, "wait", 0) == 1)
|
||||
{
|
||||
needWait = 1;
|
||||
|
||||
// WaitForDebugger... We'll hookup an event hook, so we can be notified when somebody calls 'then'
|
||||
duk_push_this(ctx); // [promise]
|
||||
duk_get_prop_string(ctx, -1, "_internal"); // [promise][internal]
|
||||
duk_get_prop_string(ctx, -1, "once"); // [promise][internal][once]
|
||||
duk_swap_top(ctx, -2); // [promise][on][this]
|
||||
duk_push_string(ctx, "_eventHook"); // [promise][on][this][eventHook]
|
||||
duk_push_c_function(ctx, ILibDuktape_Debugger_JSAttach_promise_wait, 2);// [promise][on][this][eventHook][func]
|
||||
duk_call_method(ctx, 2);
|
||||
}
|
||||
|
||||
// Before we do anything, we need to setup the source
|
||||
ILibDuktape_Debugger_JSAttach_PopulateSource(ctx, source);
|
||||
|
||||
ILibDuktape_Debugger *dbg;
|
||||
if ((dbg = ILibDuktape_Debugger_StartEngine(ctx, transport, webport)) == NULL)
|
||||
{
|
||||
// error
|
||||
duk_dup(ctx, 1); // [rejector]
|
||||
duk_push_this(ctx); // [rejector][this]
|
||||
duk_push_string(ctx, "Error Starting Debug Engine");// [rejector][this][err]
|
||||
duk_call_method(ctx, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
// success
|
||||
duk_suspend(ctx, &(dbg->hoststate));
|
||||
dbg->listener = listenerSocket;
|
||||
sem_wait(&(dbg->hostlock));
|
||||
sem_destroy(&(dbg->hostlock));
|
||||
duk_resume(ctx, &(dbg->hoststate));
|
||||
|
||||
if (needWait == 0)
|
||||
{
|
||||
listen(dbg->listener, 1);
|
||||
ILibDuktape_Debugger_AsyncWaitConn(dbg);
|
||||
}
|
||||
|
||||
// Resolve the promise with the bounded WebPort
|
||||
duk_dup(ctx, 0); // [resolver]
|
||||
duk_push_this(ctx); // [resolver][this]
|
||||
duk_push_int(ctx, dbg->webport); // [resolver][this][webport]
|
||||
duk_call_method(ctx, 1);
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
duk_ret_t ILibDuktape_Debugger_JSAttach(duk_context *ctx)
|
||||
{
|
||||
int nargs = duk_get_top(ctx);
|
||||
duk_eval_string(ctx, "require('promise');"); // [promisectr]
|
||||
duk_push_c_function(ctx, ILibDuktape_Debugger_JSAttach_promise, 2); // [promisectr][func]
|
||||
if (nargs > 0 && duk_is_object(ctx, 0))
|
||||
{
|
||||
duk_dup(ctx, 0); duk_put_prop_string(ctx, -2, "options");
|
||||
}
|
||||
else
|
||||
{
|
||||
duk_push_object(ctx); duk_put_prop_string(ctx, -2, "options");
|
||||
}
|
||||
duk_new(ctx, 1); // [promise]
|
||||
return(1);
|
||||
}
|
||||
void ILibDuktape_Debugger_Init(duk_context *ctx, unsigned short debugPort)
|
||||
{
|
||||
duk_push_global_object(ctx);
|
||||
ILibDuktape_CreateInstanceMethod(ctx, "attachDebugger", ILibDuktape_Debugger_JSAttach, DUK_VARARGS);
|
||||
duk_pop(ctx);
|
||||
}
|
||||
void ILibDuktape_Debugger_SetScriptEx(void *chain, void *user)
|
||||
{
|
||||
if (ILibMemory_CanaryOK(user))
|
||||
{
|
||||
duk_push_global_object(DebugWebEngine_Context);
|
||||
duk_push_lstring(DebugWebEngine_Context, ILibMemory_Extra(user), ILibMemory_ExtraSize(user));
|
||||
duk_put_prop_string(DebugWebEngine_Context, -2, "_scriptPath");
|
||||
duk_pop(DebugWebEngine_Context);
|
||||
|
||||
duk_push_lstring(DebugWebEngine_Context, (char*)user, (duk_size_t)ILibMemory_Size(user)); // [str]
|
||||
duk_get_prop_string(DebugWebEngine_Context, -1, "split"); // [str][split]
|
||||
duk_swap_top(DebugWebEngine_Context, -2); // [split][this]
|
||||
duk_push_string(DebugWebEngine_Context, "\n"); // [split][this][\n]
|
||||
if (duk_pcall_method(DebugWebEngine_Context, 1) == 0)
|
||||
{ // [tokens]
|
||||
duk_push_global_object(DebugWebEngine_Context); // [tokens][g]
|
||||
duk_swap_top(DebugWebEngine_Context, -2); // [g][tokens]
|
||||
duk_put_prop_string(DebugWebEngine_Context, -2, "_scriptTokens"); // [g]
|
||||
}
|
||||
duk_pop(DebugWebEngine_Context);
|
||||
ILibMemory_Free(user);
|
||||
}
|
||||
}
|
||||
void ILibDuktape_Debugger_SetScript(char *js, int jsLen, char *fileName, int fileNameLen)
|
||||
{
|
||||
if (DebugWebEngine_Chain != NULL)
|
||||
{
|
||||
if (fileNameLen <= 0 && fileName != NULL)
|
||||
{
|
||||
fileNameLen = (int)strnlen_s(fileName, _MAX_PATH);
|
||||
}
|
||||
char *jsRef = (char*)ILibMemory_SmartAllocateEx(jsLen, fileNameLen);
|
||||
memcpy_s(jsRef, jsLen, js, jsLen);
|
||||
if (fileNameLen > 0)
|
||||
{
|
||||
memcpy_s(ILibMemory_Extra(jsRef), ILibMemory_ExtraSize(jsRef), fileName, fileNameLen);
|
||||
}
|
||||
ILibChain_RunOnMicrostackThreadEx(DebugWebEngine_Chain, ILibDuktape_Debugger_SetScriptEx, jsRef);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,8 +19,7 @@ limitations under the License.
|
||||
|
||||
#include "duktape.h"
|
||||
|
||||
|
||||
void ILibDuktape_Debugger_Start(duk_context *ctx, unsigned short debugPort);
|
||||
|
||||
void ILibDuktape_Debugger_Init(duk_context *ctx, unsigned short debugPort);
|
||||
void ILibDuktape_Debugger_SetScript(char *js, int jsLen, char *fileName, int fileNameLen);
|
||||
|
||||
#endif
|
||||
@@ -610,4 +610,4 @@ public:
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -70,11 +70,9 @@ ILibDuktape_DuplexStream * ILibDuktape_DuplexStream_InitEx(duk_context * ctx, IL
|
||||
{
|
||||
ILibDuktape_DuplexStream *retVal;
|
||||
|
||||
duk_push_fixed_buffer(ctx, sizeof(ILibDuktape_DuplexStream)); // [obj][buffer]
|
||||
retVal = (ILibDuktape_DuplexStream*)Duktape_GetBuffer(ctx, -1, NULL); // [obj][buffer]
|
||||
duk_put_prop_string(ctx, -2, ILibDuktape_DuplexStream_bufferPtr); // [obj]
|
||||
retVal = (ILibDuktape_DuplexStream*)Duktape_PushBuffer(ctx, sizeof(ILibDuktape_DuplexStream)); // [obj][buffer]
|
||||
duk_put_prop_string(ctx, -2, ILibDuktape_DuplexStream_bufferPtr); // [obj]
|
||||
|
||||
memset(retVal, 0, sizeof(ILibDuktape_DuplexStream));
|
||||
retVal->user = user;
|
||||
retVal->readableStream = ILibDuktape_ReadableStream_InitEx(ctx, ILibDuktape_DuplexStream_OnPause, ILibDuktape_DuplexStream_OnResume, UnshiftHandler != NULL ? ILibDuktape_DuplexStream_OnUnshift : NULL, retVal);
|
||||
retVal->writableStream = ILibDuktape_WritableStream_Init(ctx, ILibDuktape_DuplexStream_OnWrite, ILibDuktape_DuplexStream_OnEnd, retVal);
|
||||
@@ -166,4 +164,4 @@ ILibDuktape_WritableStream *ILibDuktape_DuplexStream_GetNativeWritable(duk_conte
|
||||
}
|
||||
duk_pop(ctx); // ...
|
||||
return(retVal);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -66,11 +66,11 @@ typedef void(*ILibDuktape_DuplexStream_EndHandler)(ILibDuktape_DuplexStream *str
|
||||
typedef void(*ILibDuktape_DuplexStream_PauseResumeHandler)(ILibDuktape_DuplexStream *sender, void *user);
|
||||
typedef int(*ILibDuktape_DuplexStream_UnshiftHandler)(ILibDuktape_DuplexStream *sender, int unshiftBytes, void *user);
|
||||
|
||||
#define ILibDuktape_DuplexStream_Ready(duplexStream) ILibDuktape_WritableStream_Ready((duplexStream)->writableStream)
|
||||
#define ILibDuktape_DuplexStream_WriteData(duplexStream, buffer, bufferLen) ILibDuktape_readableStream_WriteData((duplexStream)->readableStream, buffer, bufferLen)
|
||||
#define ILibDuktape_DuplexStream_WriteDataEx(duplexStream, streamReserved, buffer, bufferLen) ILibDuktape_readableStream_WriteDataEx((duplexStream)->readableStream, streamReserved, buffer, bufferLen)
|
||||
#define ILibDuktape_DuplexStream_WriteEnd(duplexStream) ILibDuktape_readableStream_WriteEnd((duplexStream)->readableStream)
|
||||
#define ILibDuktape_DuplexStream_Closed(duplexStream) ILibDuktape_readableStream_Closed((duplexStream)->readableStream)
|
||||
#define ILibDuktape_DuplexStream_Ready(duplexStream) if(ILibMemory_CanaryOK(duplexStream)){ILibDuktape_WritableStream_Ready((duplexStream)->writableStream);}
|
||||
#define ILibDuktape_DuplexStream_WriteData(duplexStream, buffer, bufferLen) (ILibMemory_CanaryOK(duplexStream)?(ILibDuktape_readableStream_WriteData((duplexStream)!=NULL?((duplexStream)->readableStream):NULL, buffer, bufferLen)):1)
|
||||
#define ILibDuktape_DuplexStream_WriteDataEx(duplexStream, streamReserved, buffer, bufferLen) (ILibMemory_CanaryOK(duplexStream)?(ILibDuktape_readableStream_WriteDataEx((duplexStream)!=NULL?((duplexStream)->readableStream):NULL, streamReserved, buffer, bufferLen)):1)
|
||||
#define ILibDuktape_DuplexStream_WriteEnd(duplexStream) (ILibMemory_CanaryOK(duplexStream)?ILibDuktape_readableStream_WriteEnd((duplexStream)->readableStream):1)
|
||||
#define ILibDuktape_DuplexStream_Closed(duplexStream) if(ILibMemory_CanaryOK(duplexStream)){ILibDuktape_readableStream_Closed((duplexStream)->readableStream);}
|
||||
|
||||
ILibDuktape_DuplexStream* ILibDuktape_DuplexStream_InitEx(duk_context *ctx, ILibDuktape_DuplexStream_WriteHandler WriteHandler, ILibDuktape_DuplexStream_EndHandler EndHandler, ILibDuktape_DuplexStream_PauseResumeHandler PauseHandler, ILibDuktape_DuplexStream_PauseResumeHandler ResumeHandler, ILibDuktape_DuplexStream_UnshiftHandler UnshiftHandler, void *user);
|
||||
#define ILibDuktape_DuplexStream_Init(ctx, WriteHandler, EndHandler, PauseHandler, ResumeHandler, user) ILibDuktape_DuplexStream_InitEx(ctx, WriteHandler, EndHandler, PauseHandler, ResumeHandler, NULL, user)
|
||||
|
||||
@@ -266,4 +266,4 @@ public:
|
||||
*/
|
||||
DuplexStream decryptedStream;
|
||||
};
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -20,13 +20,22 @@ limitations under the License.
|
||||
#include "duktape.h"
|
||||
#include "microstack/ILibParsers.h"
|
||||
|
||||
typedef enum ILibDuktape_EventEmitter_Types
|
||||
{
|
||||
ILibDuktape_EventEmitter_Type_EXPLICIT = 0,
|
||||
ILibDuktape_EventEmitter_Type_IMPLICIT = 1
|
||||
}ILibDuktape_EventEmitter_Types;
|
||||
|
||||
typedef void(*ILibDuktape_EventEmitter_Handler)(duk_context *ctx, void *object, char *eventName, void *duk_eventArgs);
|
||||
typedef struct ILibDuktape_EventEmitter
|
||||
{
|
||||
duk_context *ctx;
|
||||
void *object;
|
||||
void *tmpObject;
|
||||
void *lastReturnValue;
|
||||
void *retValTable;
|
||||
unsigned int *totalListeners;
|
||||
ILibDuktape_EventEmitter_Types eventType;
|
||||
ILibHashtable eventTable;
|
||||
}ILibDuktape_EventEmitter;
|
||||
typedef void(*ILibDuktape_EventEmitter_HookHandler)(ILibDuktape_EventEmitter *sender, char *eventName, void *hookedCallback);
|
||||
@@ -50,11 +59,16 @@ int ILibDuktape_EventEmitter_HasListeners(ILibDuktape_EventEmitter *emitter, cha
|
||||
|
||||
#define ILibDuktape_EventEmitter_AddOnceEx2(ctx, idx, eventName, func, argCount) ILibDuktape_EventEmitter_AddOnceEx3(ctx, idx, eventName, func)
|
||||
#define ILibDuktape_EventEmitter_SetupEmit(ctx, heapptr, eventName) duk_push_heapptr((ctx), heapptr);duk_get_prop_string((ctx), -1, "emit");duk_swap_top((ctx), -2);duk_push_string((ctx), eventName)
|
||||
#define ILibDuktape_EventEmitter_SetupOn(ctx, heapptr, eventName) duk_push_heapptr((ctx), heapptr);duk_get_prop_string((ctx), -1, "on");duk_swap_top((ctx), -2);duk_push_string((ctx), eventName)
|
||||
#define ILibDuktape_EventEmitter_SetupPrependOnce(ctx, heapptr, eventName) duk_push_heapptr((ctx), heapptr);duk_get_prop_string((ctx), -1, "prependOnceListener");duk_swap_top((ctx), -2);duk_push_string((ctx), eventName)
|
||||
|
||||
int ILibDuktape_EventEmitter_AddOn(ILibDuktape_EventEmitter *emitter, char *eventName, void *heapptr); // Add native event handler
|
||||
int ILibDuktape_EventEmitter_AddOnEx(duk_context *ctx, duk_idx_t idx, char *eventName, duk_c_function func);
|
||||
|
||||
void ILibDuktape_EventEmitter_AddHook(ILibDuktape_EventEmitter *emitter, char *eventName, ILibDuktape_EventEmitter_HookHandler handler);
|
||||
void ILibDuktape_EventEmitter_ClearHook(ILibDuktape_EventEmitter *emitter, char *eventName);
|
||||
|
||||
void ILibDuktape_EventEmitter_ForwardEvent(duk_context *ctx, duk_idx_t eventSourceIndex, char *sourceEventName, duk_idx_t eventTargetIndex, char *targetEventName);
|
||||
void ILibDuktape_EventEmitter_DeleteForwardEvent(duk_context *ctx, duk_idx_t eventSourceIndex, char *sourceEventName);
|
||||
|
||||
#endif
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -23,4 +23,4 @@ limitations under the License.
|
||||
void ILibDuktape_GenericMarshal_init(duk_context *ctx);
|
||||
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -120,6 +120,7 @@ typedef struct ILibDuktape_HECI_Session
|
||||
OVERLAPPED wv;
|
||||
ILibProcessPipe_Manager mgr;
|
||||
HANDLE descriptor;
|
||||
DWORD bytesRead;
|
||||
#else
|
||||
int descriptor;
|
||||
#endif
|
||||
@@ -230,6 +231,13 @@ int ILibDuktape_HECI_linuxInit()
|
||||
|
||||
duk_ret_t ILibDuktape_HECI_SessionFinalizer(duk_context *ctx)
|
||||
{
|
||||
if (duk_has_prop_string(ctx, 0, ILibDuktape_HECI_SessionMemPtr))
|
||||
{
|
||||
duk_get_prop_string(ctx, 0, ILibDuktape_HECI_SessionMemPtr);
|
||||
ILibDuktape_HECI_Session *s = (ILibDuktape_HECI_Session*)Duktape_GetBuffer(ctx, -1, NULL);
|
||||
if (s != NULL && s->PendingWrites != NULL) { ILibQueue_Destroy(s->PendingWrites); } // ToDo: If there is anything pending, we need to clear that too
|
||||
if (s != NULL) { s->stream = NULL; }
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
@@ -297,7 +305,7 @@ ILibTransport_DoneState ILibDuktape_HECI_Session_WriteHandler_Process(ILibDuktap
|
||||
ssize_t bytesWritten;
|
||||
#endif
|
||||
|
||||
while (ILibQueue_GetCount(session->PendingWrites) > 0)
|
||||
while (session->noPipelining || ILibQueue_GetCount(session->PendingWrites) > 0)
|
||||
{
|
||||
ILibDuktape_HECI_WriteState *state = (ILibDuktape_HECI_WriteState*)ILibQueue_PeekQueue(session->PendingWrites);
|
||||
returnIgnored = state->returnIgnored;
|
||||
@@ -469,15 +477,19 @@ ILibTransport_DoneState ILibDuktape_HECI_Session_WriteSink(ILibDuktape_DuplexStr
|
||||
}
|
||||
void ILibDuktape_HECI_Session_EndSink(ILibDuktape_DuplexStream *stream, void *user)
|
||||
{
|
||||
|
||||
duk_context *ctx = stream->readableStream->ctx;
|
||||
duk_push_this(ctx);
|
||||
duk_get_prop_string(ctx, -1, "disconnect");
|
||||
duk_swap_top(ctx, -2);
|
||||
if (duk_pcall_method(ctx, 0) != 0) { ILibDuktape_Process_UncaughtException(ctx); }
|
||||
duk_pop(ctx);
|
||||
}
|
||||
void ILibDuktape_HECI_Session_PauseSink(ILibDuktape_DuplexStream *sender, void *user)
|
||||
{
|
||||
#ifdef WIN32
|
||||
ILibDuktape_HECI_Session *session = (ILibDuktape_HECI_Session*)user;
|
||||
|
||||
// To Pause, all we need to do is remove our handle
|
||||
ILibProcessPipe_WaitHandle_Remove(session->mgr, session->v.hEvent);
|
||||
// NO-OP Because we are already PAUSED, since we context switched
|
||||
UNREFERENCED_PARAMETER(sender);
|
||||
UNREFERENCED_PARAMETER(user);
|
||||
#else
|
||||
UNREFERENCED_PARAMETER(sender);
|
||||
UNREFERENCED_PARAMETER(user);
|
||||
@@ -485,6 +497,15 @@ void ILibDuktape_HECI_Session_PauseSink(ILibDuktape_DuplexStream *sender, void *
|
||||
}
|
||||
#ifdef WIN32
|
||||
BOOL ILibDuktape_HECI_Session_ReceiveSink(HANDLE event, void* user);
|
||||
void __stdcall ILibDuktape_HECI_Session_ResumeSink2(ULONG_PTR obj)
|
||||
{
|
||||
ILibDuktape_HECI_Session *session = (ILibDuktape_HECI_Session*)obj;
|
||||
BOOL result = ReadFile(session->descriptor, session->buffer, (DWORD)session->bufferSize, &(session->bytesRead), &(session->v));
|
||||
if (result == TRUE || GetLastError() == ERROR_IO_PENDING)
|
||||
{
|
||||
ILibProcessPipe_WaitHandle_Add(session->mgr, session->v.hEvent, session, ILibDuktape_HECI_Session_ReceiveSink);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
void ILibDuktape_HECI_Session_ResumeSink_NoPipeline(void *chain, void *user)
|
||||
{
|
||||
@@ -508,37 +529,34 @@ void ILibDuktape_HECI_Session_ResumeSink(ILibDuktape_DuplexStream *sender, void
|
||||
if (session->noPipelining != 0)
|
||||
{
|
||||
ILibChain_RunOnMicrostackThread(sender->readableStream->chain, ILibDuktape_HECI_Session_ResumeSink_NoPipeline, session);
|
||||
// Note: DO NOT 'return' here, because we still need to QueueUserAPC, to resume the stream on Windows
|
||||
}
|
||||
|
||||
#ifdef WIN32
|
||||
DWORD bytesRead;
|
||||
|
||||
// To Resume, we need to ReadFile, then re-add our waithandle
|
||||
BOOL result = ReadFile(session->descriptor, session->buffer, (DWORD)session->bufferSize, &bytesRead, &(session->v));
|
||||
if (result == TRUE || GetLastError() == ERROR_IO_PENDING)
|
||||
{
|
||||
ILibProcessPipe_WaitHandle_Add(session->mgr, session->v.hEvent, session, ILibDuktape_HECI_Session_ReceiveSink);
|
||||
}
|
||||
// To Resume, we need to first context switch to the Windows Thread
|
||||
QueueUserAPC((PAPCFUNC)ILibDuktape_HECI_Session_ResumeSink2, ILibProcessPipe_Manager_GetWorkerThread(session->mgr), (ULONG_PTR)session);
|
||||
#endif
|
||||
}
|
||||
#ifdef WIN32
|
||||
void ILibDuktape_HECI_Session_ReceiveSink2(void *chain, void *user)
|
||||
{
|
||||
ILibDuktape_HECI_Session *session = (ILibDuktape_HECI_Session*)user;
|
||||
if (!ILibMemory_CanaryOK(session)) { return; }
|
||||
|
||||
ILibDuktape_DuplexStream_WriteData(session->stream, session->buffer, session->bytesRead);
|
||||
if (session->stream != NULL && !session->stream->readableStream->paused)
|
||||
{
|
||||
ILibDuktape_HECI_Session_ResumeSink(session->stream, session->stream->user);
|
||||
}
|
||||
}
|
||||
BOOL ILibDuktape_HECI_Session_ReceiveSink(HANDLE event, void* user)
|
||||
{
|
||||
ILibDuktape_HECI_Session *session = (ILibDuktape_HECI_Session*)user;
|
||||
DWORD bytesRead;
|
||||
|
||||
do
|
||||
if (ILibMemory_CanaryOK(session))
|
||||
{
|
||||
if (GetOverlappedResult(session->descriptor, &(session->v), &bytesRead, FALSE) == FALSE) { break; }
|
||||
ILibDuktape_DuplexStream_WriteData(session->stream, session->buffer, bytesRead);
|
||||
} while (session->stream->readableStream->paused == 0 && ReadFile(session->descriptor, session->buffer, (DWORD)session->bufferSize, &bytesRead, &(session->v)) == TRUE);
|
||||
if (session->stream->readableStream->paused == 0 && GetLastError() != ERROR_IO_PENDING)
|
||||
{
|
||||
// Broken Connection
|
||||
ILibProcessPipe_WaitHandle_Remove(session->mgr, session->v.hEvent); // Remove ourselves from processing loop
|
||||
ILibDuktape_DuplexStream_WriteEnd(session->stream);
|
||||
if (GetOverlappedResult(session->descriptor, &(session->v), &(session->bytesRead), FALSE) == TRUE) { ILibChain_RunOnMicrostackThreadEx(session->chain, ILibDuktape_HECI_Session_ReceiveSink2, session); }
|
||||
}
|
||||
return(TRUE);
|
||||
return(FALSE);
|
||||
}
|
||||
void __stdcall ILibDuktape_HECI_Session_Start(ULONG_PTR obj)
|
||||
{
|
||||
@@ -560,6 +578,7 @@ duk_ret_t ILibDuktape_HECI_create_OnClientConnect(duk_context *ctx)
|
||||
duk_swap_top(ctx, -2); // [emit][this]
|
||||
duk_push_string(ctx, "error"); // [emit][this][error]
|
||||
duk_push_error_object(ctx, DUK_ERR_ERROR, "HECI Connection Error [%d]", statusCode); // [emit][this][error][err]
|
||||
duk_push_int(ctx, statusCode); duk_put_prop_string(ctx, -2, "errno");
|
||||
if (duk_pcall_method(ctx, 2) != 0) { ILibDuktape_Process_UncaughtExceptionEx(ctx, "HECI.session.onError(): "); }
|
||||
duk_pop(ctx); // ...
|
||||
}
|
||||
@@ -570,12 +589,10 @@ duk_ret_t ILibDuktape_HECI_create_OnClientConnect(duk_context *ctx)
|
||||
if (bufferLen > 4)
|
||||
{
|
||||
duk_push_int(ctx, ((int*)buffer)[0]);
|
||||
duk_put_prop_string(ctx, -2, ILibDuktape_HECI_MaxBufferSize); // [session]
|
||||
duk_put_prop_string(ctx, -2, ILibDuktape_HECI_MaxBufferSize); // [session]
|
||||
|
||||
duk_push_fixed_buffer(ctx, sizeof(ILibDuktape_HECI_Session) + ((int*)buffer)[0]); // [session][buffer]
|
||||
session = (ILibDuktape_HECI_Session*)Duktape_GetBuffer(ctx, -1, NULL);
|
||||
memset(session, 0, sizeof(ILibDuktape_HECI_Session) + ((int*)buffer)[0]);
|
||||
duk_put_prop_string(ctx, -2, ILibDuktape_HECI_SessionMemPtr); // [session]
|
||||
session = (ILibDuktape_HECI_Session*)Duktape_PushBuffer(ctx, sizeof(ILibDuktape_HECI_Session) + ((int*)buffer)[0]); // [session][buffer]
|
||||
duk_put_prop_string(ctx, -2, ILibDuktape_HECI_SessionMemPtr); // [session]
|
||||
#ifdef WIN32
|
||||
session->v.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||
session->wv.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||
@@ -590,7 +607,6 @@ duk_ret_t ILibDuktape_HECI_create_OnClientConnect(duk_context *ctx)
|
||||
duk_push_current_function(ctx);
|
||||
session->noPipelining = Duktape_GetIntPropertyValue(ctx, -1, ILibDuktape_HECI_Session_NoPipeline, 0);
|
||||
duk_pop(ctx);
|
||||
|
||||
#ifdef _POSIX
|
||||
//printf("Session: %p\n", session);
|
||||
duk_get_prop_string(ctx, -1, ILibDuktape_HECI_Child); // [session][heci]
|
||||
@@ -675,6 +691,51 @@ duk_ret_t ILibDuktape_HECI_Session_connect(duk_context *ctx)
|
||||
duk_pop(ctx); // ...
|
||||
return(0);
|
||||
}
|
||||
#ifdef WIN32
|
||||
void __stdcall ILibDuktape_HECI_Session_CloseSink2(ULONG_PTR obj)
|
||||
{
|
||||
HANDLE h = (HANDLE)obj;
|
||||
CloseHandle(h);
|
||||
}
|
||||
#endif
|
||||
duk_ret_t ILibDuktape_HECI_Session_close(duk_context *ctx)
|
||||
{
|
||||
duk_push_this(ctx); // [session]
|
||||
|
||||
if (duk_has_prop_string(ctx, -1, ILibDuktape_HECI_Child))
|
||||
{
|
||||
duk_get_prop_string(ctx, -1, ILibDuktape_HECI_Child); // [session][heci]
|
||||
duk_get_prop_string(ctx, -1, "disconnect"); // [session][heci][close]
|
||||
duk_swap_top(ctx, -2); // [session][close][this]
|
||||
duk_call_method(ctx, 0);
|
||||
}
|
||||
|
||||
duk_push_this(ctx);
|
||||
#ifdef WIN32
|
||||
ILibDuktape_HECI_Session *session = NULL;
|
||||
if (duk_has_prop_string(ctx, -1, ILibDuktape_HECI_SessionMemPtr))
|
||||
{
|
||||
duk_get_prop_string(ctx, -1, ILibDuktape_HECI_SessionMemPtr); // [HECI][SESSION]
|
||||
session = (ILibDuktape_HECI_Session*)Duktape_GetBuffer(ctx, -1, NULL);
|
||||
|
||||
ILibProcessPipe_WaitHandle_Remove(session->mgr, session->v.hEvent);
|
||||
ILibProcessPipe_WaitHandle_Remove(session->mgr, session->wv.hEvent);
|
||||
session->stream = NULL;
|
||||
QueueUserAPC((PAPCFUNC)ILibDuktape_HECI_Session_CloseSink2, ILibProcessPipe_Manager_GetWorkerThread(session->mgr), (ULONG_PTR)session->descriptor);
|
||||
}
|
||||
#else
|
||||
int d = Duktape_GetIntPropertyValue(ctx, -1, ILibDuktape_HECI_Descriptor, -1);
|
||||
HECI_chainLink *hcl = (HECI_chainLink*)Duktape_GetPointerProperty(ctx, -1, ILibDuktape_HECI_ChainLink);
|
||||
if (hcl != NULL)
|
||||
{
|
||||
hcl->descriptor = -1;
|
||||
if (d != -1) { close(d); };
|
||||
duk_del_prop_string(ctx, -1, ILibDuktape_HECI_Descriptor);
|
||||
}
|
||||
#endif
|
||||
|
||||
return(0);
|
||||
}
|
||||
duk_ret_t ILibDuktape_HECI_create(duk_context *ctx)
|
||||
{
|
||||
duk_push_object(ctx); // [Session]
|
||||
@@ -689,6 +750,7 @@ duk_ret_t ILibDuktape_HECI_create(duk_context *ctx)
|
||||
ILibDuktape_EventEmitter_CreateEventEx(emitter, "error");
|
||||
ILibDuktape_CreateProperty_InstanceMethod(ctx, "connect", ILibDuktape_HECI_Session_connect, DUK_VARARGS);
|
||||
ILibDuktape_CreateFinalizer(ctx, ILibDuktape_HECI_SessionFinalizer);
|
||||
ILibDuktape_CreateInstanceMethod(ctx, "disconnect", ILibDuktape_HECI_Session_close, 0);
|
||||
return(1);
|
||||
}
|
||||
|
||||
@@ -743,6 +805,8 @@ void ILibDuktape_HECI_NextIoctl(ILibQueue q)
|
||||
{
|
||||
ILibDuktape_HECI_ioctl_data *data = (ILibDuktape_HECI_ioctl_data*)ILibQueue_PeekQueue(q);
|
||||
int res;
|
||||
if (data == NULL) { return; } // This line is unnecessary, because this method is only called on a non-empty Queue, but to satisfy Klockwork...
|
||||
|
||||
data->bytesReceived = 0;
|
||||
|
||||
ResetEvent(data->v.hEvent);
|
||||
@@ -817,9 +881,7 @@ duk_ret_t ILibDuktape_HECI_doIoctl(duk_context *ctx)
|
||||
ILibDuktape_Push_ObjectStash(ctx); // [heci][stash]
|
||||
duk_push_array(ctx); // [heci][stash][array]
|
||||
ILibDuktape_HECI_ioctl_data *data;
|
||||
duk_push_fixed_buffer(ctx, bufferLen + sizeof(ILibDuktape_HECI_ioctl_data)); // [heci][stash][array][state]
|
||||
data = (ILibDuktape_HECI_ioctl_data*)Duktape_GetBuffer(ctx, -1, NULL);
|
||||
memset(data, 0, sizeof(ILibDuktape_HECI_ioctl_data));
|
||||
data = (ILibDuktape_HECI_ioctl_data*)Duktape_PushBuffer(ctx, bufferLen + sizeof(ILibDuktape_HECI_ioctl_data));
|
||||
duk_put_prop_index(ctx, -2, 0); // [heci][stash][array]
|
||||
if (outBufferLen > 0)
|
||||
{ // [heci][stash][array][buffer]
|
||||
@@ -954,6 +1016,7 @@ void ILibDuktape_HECI_PostSelect(void* object, int slct, fd_set *readset, fd_set
|
||||
ILibDuktape_DuplexStream_WriteEnd(h->session->stream);
|
||||
}
|
||||
}
|
||||
if (h->descriptor <= 0) { return; }
|
||||
if (FD_ISSET(h->descriptor, writeset))
|
||||
{
|
||||
ILibDuktape_HECI_Session_WriteHandler_Process(h->session);
|
||||
@@ -971,6 +1034,7 @@ void ILibDuktape_HECI_Destroy(void *object)
|
||||
close(h->descriptor);
|
||||
}
|
||||
#endif
|
||||
|
||||
void ILibDuktape_HECI_Push(duk_context *ctx, void *chain)
|
||||
{
|
||||
duk_push_object(ctx); // [HECI]
|
||||
@@ -1011,6 +1075,7 @@ void ILibDuktape_HECI_Push(duk_context *ctx, void *chain)
|
||||
#endif
|
||||
if (chain != NULL) { ILibDuktape_CreateInstanceMethod(ctx, "create", ILibDuktape_HECI_create, 0); }
|
||||
ILibDuktape_CreateInstanceMethod(ctx, "doIoctl", ILibDuktape_HECI_doIoctl, DUK_VARARGS);
|
||||
ILibDuktape_CreateInstanceMethod(ctx, "disconnect", ILibDuktape_HECI_Session_close, 0);
|
||||
#ifdef _POSIX
|
||||
duk_push_pointer(ctx, hlink->Q); // [HECI][Q]
|
||||
#else
|
||||
@@ -1038,4 +1103,4 @@ void ILibDuktape_HECI_Push(duk_context *ctx, void *chain)
|
||||
void ILibDuktape_HECI_Init(duk_context *ctx)
|
||||
{
|
||||
ILibDuktape_ModSearch_AddHandler(ctx, "heci", ILibDuktape_HECI_Push);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,4 +22,4 @@ limitations under the License.
|
||||
void ILibDuktape_HECI_Init(duk_context *ctx);
|
||||
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -112,7 +112,7 @@ void *Duktape_GetPointerProperty(duk_context *ctx, duk_idx_t i, char* propertyNa
|
||||
char* Duktape_GetStringPropertyValueEx(duk_context *ctx, duk_idx_t i, char* propertyName, char* defaultValue, duk_size_t *len)
|
||||
{
|
||||
char *retVal = defaultValue;
|
||||
if (duk_has_prop_string(ctx, i, propertyName))
|
||||
if (ctx != NULL && duk_has_prop_string(ctx, i, propertyName))
|
||||
{
|
||||
duk_get_prop_string(ctx, i, propertyName);
|
||||
retVal = (char*)duk_get_lstring(ctx, -1, len);
|
||||
@@ -127,7 +127,7 @@ char* Duktape_GetStringPropertyValueEx(duk_context *ctx, duk_idx_t i, char* prop
|
||||
int Duktape_GetIntPropertyValue(duk_context *ctx, duk_idx_t i, char* propertyName, int defaultValue)
|
||||
{
|
||||
int retVal = defaultValue;
|
||||
if (duk_has_prop_string(ctx, i, propertyName))
|
||||
if (ctx!=NULL && duk_has_prop_string(ctx, i, propertyName))
|
||||
{
|
||||
duk_get_prop_string(ctx, i, propertyName);
|
||||
retVal = duk_to_int(ctx, -1);
|
||||
@@ -159,6 +159,7 @@ char *Duktape_GetStashKey(void* value)
|
||||
char* Duktape_GetBuffer(duk_context *ctx, duk_idx_t i, duk_size_t *bufLen)
|
||||
{
|
||||
char *retVal = NULL;
|
||||
duk_size_t len = 0;
|
||||
if (bufLen != NULL) { *bufLen = 0; }
|
||||
|
||||
if (duk_is_string(ctx, i))
|
||||
@@ -167,11 +168,29 @@ char* Duktape_GetBuffer(duk_context *ctx, duk_idx_t i, duk_size_t *bufLen)
|
||||
}
|
||||
else if (duk_is_buffer(ctx, i))
|
||||
{
|
||||
retVal = (char*)duk_require_buffer(ctx, i,bufLen);
|
||||
retVal = (char*)duk_require_buffer(ctx, i, &len);
|
||||
if (ILibMemory_CanaryOK(ILibMemory_FromRaw(retVal)) && ILibMemory_RawSize(ILibMemory_FromRaw(retVal)) == len)
|
||||
{
|
||||
retVal = ILibMemory_FromRaw(retVal);
|
||||
if (bufLen != NULL) { *bufLen = ILibMemory_Size(retVal); }
|
||||
}
|
||||
else if (bufLen != NULL)
|
||||
{
|
||||
*bufLen = len;
|
||||
}
|
||||
}
|
||||
else if(duk_is_buffer_data(ctx, i))
|
||||
{
|
||||
retVal = (char*)duk_require_buffer_data(ctx, i, bufLen);
|
||||
retVal = (char*)duk_require_buffer_data(ctx, i, &len);
|
||||
if (ILibMemory_CanaryOK(ILibMemory_FromRaw(retVal)) && ILibMemory_RawSize(ILibMemory_FromRaw(retVal)) == len)
|
||||
{
|
||||
retVal = ILibMemory_FromRaw(retVal);
|
||||
if (bufLen != NULL) { *bufLen = ILibMemory_Size(retVal); }
|
||||
}
|
||||
else if (bufLen != NULL)
|
||||
{
|
||||
*bufLen = len;
|
||||
}
|
||||
}
|
||||
else if (duk_is_object(ctx, i))
|
||||
{
|
||||
@@ -607,37 +626,7 @@ void *ILibDuktape_Memory_AllocEx(duk_context *ctx, duk_idx_t index, duk_size_t s
|
||||
duk_pop_2(ctx); // ...
|
||||
return(retVal);
|
||||
}
|
||||
void ILibDuktape_ValidatePointer(void *chain, void *ptr)
|
||||
{
|
||||
ILibHashtable_Put(ILibChain_GetBaseHashtable(chain), ptr, NULL, 0, (void*)0xFFFF);
|
||||
}
|
||||
void ILibDuktape_InValidatePointer(void *chain, void *ptr)
|
||||
{
|
||||
ILibHashtable_Remove(ILibChain_GetBaseHashtable(chain), ptr, NULL, 0);
|
||||
}
|
||||
int ILibDuktape_IsPointerValid(void *chain, void *ptr)
|
||||
{
|
||||
return(ILibHashtable_Get(ILibChain_GetBaseHashtable(chain), ptr, NULL, 0) == NULL ? 0 : 1);
|
||||
}
|
||||
duk_ret_t ILibDuktape_PointerValidation_Finalizer(duk_context *ctx)
|
||||
{
|
||||
duk_push_this(ctx);
|
||||
void *chain = Duktape_GetChain(ctx);
|
||||
void *obj = duk_get_heapptr(ctx, -1);
|
||||
ILibDuktape_InValidatePointer(chain, obj);
|
||||
duk_pop(ctx);
|
||||
return(0);
|
||||
}
|
||||
void ILibDuktape_PointerValidation_Init(duk_context *ctx)
|
||||
{
|
||||
void *chain = Duktape_GetChain(ctx);
|
||||
if (!ILibDuktape_IsPointerValid(chain, duk_get_heapptr(ctx, -1)))
|
||||
{
|
||||
// Not set up yet, so set it up
|
||||
ILibDuktape_ValidatePointer(chain, duk_get_heapptr(ctx, -1));
|
||||
ILibDuktape_CreateFinalizer(ctx, ILibDuktape_PointerValidation_Finalizer);
|
||||
}
|
||||
}
|
||||
|
||||
duk_ret_t ILibDuktape_Immediate_Sink(duk_context *ctx)
|
||||
{
|
||||
ILibDuktape_ImmediateHandler userCallback = (ILibDuktape_ImmediateHandler)duk_get_pointer(ctx, 0);
|
||||
@@ -689,6 +678,61 @@ void* ILibDuktape_Immediate(duk_context *ctx, void ** args, int argsLen, ILibDuk
|
||||
if (duk_pcall_method(ctx, 3) != 0) { ILibDuktape_Process_UncaughtExceptionEx(ctx, "ILibDuktape_Immediate => immediate(): "); duk_pop(ctx); return(NULL); }
|
||||
|
||||
|
||||
retval = duk_get_heapptr(ctx, -1); // [immediate]
|
||||
duk_push_heap_stash(ctx); // [immediate][stash]
|
||||
duk_swap_top(ctx, -2); // [stash][immediate]
|
||||
duk_put_prop_string(ctx, -2, Duktape_GetStashKey(retval)); // [stash]
|
||||
duk_pop(ctx); // ...
|
||||
return(retval);
|
||||
}
|
||||
duk_ret_t ILibDuktape_Interval_Sink(duk_context *ctx)
|
||||
{
|
||||
ILibDuktape_ImmediateHandler userCallback = (ILibDuktape_ImmediateHandler)duk_get_pointer(ctx, 0);
|
||||
void **args = NULL;
|
||||
int argsLen, i;
|
||||
|
||||
duk_push_this(ctx); // [immediate]
|
||||
duk_dup(ctx, 1); // [immediate][array]
|
||||
if ((argsLen = (int)duk_get_length(ctx, -1)) > 0)
|
||||
{
|
||||
args = ILibMemory_AllocateA(sizeof(void*)*argsLen);
|
||||
for (i = 0; i < argsLen; ++i)
|
||||
{
|
||||
duk_get_prop_index(ctx, -1, i); // [immediate][array][arg]
|
||||
args[i] = duk_get_pointer(ctx, -1);
|
||||
duk_pop(ctx); // [immediate][array]
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (userCallback != NULL) { userCallback(ctx, args, argsLen); }
|
||||
return(0);
|
||||
}
|
||||
void* ILibDuktape_Interval(duk_context *ctx, void **args, int argsLen, int delay, ILibDuktape_IntervalHandler callback)
|
||||
{
|
||||
void *retval = NULL;
|
||||
int i = 0;
|
||||
duk_push_global_object(ctx); // [g]
|
||||
duk_get_prop_string(ctx, -1, "setInterval"); // [g][setInterval]
|
||||
duk_swap_top(ctx, -2); // [setInterval][this]
|
||||
duk_push_c_function(ctx, ILibDuktape_Interval_Sink, DUK_VARARGS); // [setInterval][this][func]
|
||||
duk_push_int(ctx, delay); // [setInterval][this][func][delay]
|
||||
duk_push_pointer(ctx, callback); // [setInterval][this][func][delay][userFunc]
|
||||
duk_push_array(ctx); // [setInterval][this][func][delay][userFunc][array]
|
||||
|
||||
while (args[i] != NULL && i < argsLen)
|
||||
{
|
||||
duk_get_prop_string(ctx, -1, "push"); // [setInterval][this][func][delay][userFunc][array][push]
|
||||
duk_dup(ctx, -2); // [setInterval][this][func][delay][userFunc][array][push][this]
|
||||
duk_push_pointer(ctx, args[i]); // [setInterval][this][func][delay][userFunc][array][push][this][val]
|
||||
if (duk_pcall_method(ctx, 1) != 0) { ILibDuktape_Process_UncaughtExceptionEx(ctx, "ILibDuktape_Immediate => Array.push(): "); }
|
||||
duk_pop(ctx); // [setInterval][this][func][delay][userFunc][array]
|
||||
++i;
|
||||
}
|
||||
|
||||
if (duk_pcall_method(ctx, 4) != 0) { ILibDuktape_Process_UncaughtExceptionEx(ctx, "ILibDuktape_Interval => interval(): "); duk_pop(ctx); return(NULL); }
|
||||
|
||||
|
||||
retval = duk_get_heapptr(ctx, -1); // [immediate]
|
||||
duk_push_heap_stash(ctx); // [immediate][stash]
|
||||
duk_swap_top(ctx, -2); // [stash][immediate]
|
||||
@@ -725,6 +769,142 @@ duk_idx_t duk_push_int_ex(duk_context *ctx, duk_int_t val)
|
||||
return(duk_push_int(ctx, val), duk_get_top_index(ctx));
|
||||
}
|
||||
|
||||
void Duktape_Console_Log_ChainEx(duk_context *ctx, ILibDuktape_LogTypes logType, char *msg, duk_size_t msgLen)
|
||||
{
|
||||
duk_push_global_object(ctx); // [g]
|
||||
duk_get_prop_string(ctx, -1, "console"); // [g][console]
|
||||
switch (logType)
|
||||
{
|
||||
case ILibDuktape_LogType_Error:
|
||||
duk_get_prop_string(ctx, -1, "error"); // [g][console][error]
|
||||
break;
|
||||
case ILibDuktape_LogType_Warn:
|
||||
duk_get_prop_string(ctx, -1, "warn"); // [g][console][warn]
|
||||
break;
|
||||
default:
|
||||
duk_get_prop_string(ctx, -1, "log"); // [g][console][log]
|
||||
break;
|
||||
}
|
||||
duk_swap_top(ctx, -2); // [g][log][this]
|
||||
duk_push_lstring(ctx, msg, msgLen); // [g][log][this][str]
|
||||
duk_pcall_method(ctx, 1); duk_pop(ctx); // [g]
|
||||
duk_pop(ctx); // ...
|
||||
}
|
||||
|
||||
typedef struct Duktape_Console_Log_data
|
||||
{
|
||||
duk_context *ctx;
|
||||
ILibDuktape_LogTypes logType;
|
||||
}Duktape_Console_Log_data;
|
||||
|
||||
void Duktape_Console_Log_Chain(void *chain, void *user)
|
||||
{
|
||||
Duktape_Console_Log_data *data = (Duktape_Console_Log_data*)user;
|
||||
char *msg = (char*)ILibMemory_Extra(data);
|
||||
|
||||
Duktape_Console_Log_ChainEx(data->ctx, data->logType, msg, ILibMemory_Size(msg));
|
||||
|
||||
ILibMemory_Free(user);
|
||||
}
|
||||
void Duktape_Console_Log(duk_context *ctx, void *chain, ILibDuktape_LogTypes logType, char *msg, duk_size_t msgLen)
|
||||
{
|
||||
if (ILibIsRunningOnChainThread(chain))
|
||||
{
|
||||
Duktape_Console_Log_ChainEx(ctx, logType, msg, msgLen);
|
||||
}
|
||||
else
|
||||
{
|
||||
Duktape_Console_Log_data *data = (Duktape_Console_Log_data*)ILibMemory_SmartAllocateEx(sizeof(Duktape_Console_Log_data), msgLen);
|
||||
data->ctx = ctx;
|
||||
data->logType = logType;
|
||||
memcpy_s(ILibMemory_Extra(data), ILibMemory_ExtraSize(data), msg, msgLen);
|
||||
|
||||
ILibChain_RunOnMicrostackThreadEx(chain, Duktape_Console_Log_Chain, data);
|
||||
}
|
||||
}
|
||||
|
||||
char* ILibDuktape_String_AsWide(duk_context *ctx, duk_idx_t idx, duk_size_t *len)
|
||||
{
|
||||
char *src;
|
||||
src = (char*)duk_require_string(ctx, idx);
|
||||
|
||||
#ifdef WIN32
|
||||
size_t inBufferLen = 2 + (2 * MultiByteToWideChar(CP_UTF8, 0, (LPCCH)src, -1, NULL, 0));
|
||||
LPWSTR inBuffer = (LPWSTR)ILibMemory_AllocateTemp(Duktape_GetChain(ctx), inBufferLen);
|
||||
|
||||
int r = MultiByteToWideChar(CP_UTF8, 0, (LPCCH)src, -1, inBuffer, (int)inBufferLen);
|
||||
if (len != NULL)
|
||||
{
|
||||
*len = (duk_size_t)r;
|
||||
}
|
||||
return(r == 0 ? NULL : (char*)inBuffer);
|
||||
#else
|
||||
return(src);
|
||||
#endif
|
||||
}
|
||||
void ILibDuktape_String_PushWideString(duk_context *ctx, char *wstr, size_t wstrlen)
|
||||
{
|
||||
#ifdef WIN32
|
||||
char *tmp;
|
||||
size_t tmpLen;
|
||||
|
||||
tmpLen = 2 + (size_t)WideCharToMultiByte(CP_UTF8, 0, (LPCWCH)wstr, (int)(wstrlen > 0 ? wstrlen : -1), NULL, 0, NULL, NULL);
|
||||
tmp = (char*)ILibMemory_AllocateTemp(Duktape_GetChain(ctx), tmpLen);
|
||||
|
||||
if (WideCharToMultiByte(CP_UTF8, 0, (LPCWCH)wstr, (int)(wstrlen > 0 ? wstrlen : -1), (LPSTR)tmp, (int)tmpLen, NULL, NULL) != 0)
|
||||
{
|
||||
duk_push_string(ctx, tmp);
|
||||
}
|
||||
else
|
||||
{
|
||||
ILibDuktape_Error(ctx, "String_PushWideString() Error: %u", GetLastError());
|
||||
}
|
||||
#else
|
||||
if (wstrlen == 0)
|
||||
{
|
||||
duk_push_string(ctx, wstr);
|
||||
}
|
||||
else
|
||||
{
|
||||
duk_push_lstring(ctx, wstr, wstrlen);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
char *ILibDuktape_String_WideToUTF8(duk_context *ctx, char *wstr)
|
||||
{
|
||||
#ifdef WIN32
|
||||
char *tmp;
|
||||
size_t tmpLen;
|
||||
|
||||
tmpLen = 2 + (size_t)WideCharToMultiByte(CP_UTF8, 0, (LPCWCH)wstr, -1, NULL, 0, NULL, NULL);
|
||||
tmp = (char*)ILibMemory_AllocateTemp(Duktape_GetChain(ctx), tmpLen);
|
||||
WideCharToMultiByte(CP_UTF8, 0, (LPCWCH)wstr, -1, tmp, (int)tmpLen, NULL, NULL);
|
||||
return(tmp);
|
||||
#else
|
||||
// NOP for non-Windows, because should already be UTF8
|
||||
return(wstr);
|
||||
#endif
|
||||
}
|
||||
char *ILibDuktape_String_UTF8ToWide(duk_context *ctx, char *str)
|
||||
{
|
||||
#ifdef WIN32
|
||||
size_t tmpLen = 2 + (2 * MultiByteToWideChar(CP_UTF8, 0, (LPCCH)str, -1, NULL, 0));
|
||||
LPWSTR retVal = (LPWSTR)ILibMemory_AllocateTemp(Duktape_GetChain(ctx), tmpLen);
|
||||
MultiByteToWideChar(CP_UTF8, 0, (LPCCH)str, -1, retVal, (int)tmpLen);
|
||||
return((char*)retVal);
|
||||
#else
|
||||
// NOP on non-Windows, as strings should always be UTF-8 by default
|
||||
return(str);
|
||||
#endif
|
||||
}
|
||||
void ILibDuktape_Log_Object(duk_context *ctx, duk_idx_t i, char *meta)
|
||||
{
|
||||
void *h = duk_get_heapptr(ctx, i);
|
||||
duk_enum(ctx, i, DUK_ENUM_INCLUDE_HIDDEN | DUK_ENUM_INCLUDE_SYMBOLS);
|
||||
while (duk_next(ctx, -1, 1))
|
||||
{
|
||||
printf(" [%s: %p] => %s (%p)\n", (meta==NULL?"OBJ":meta), h, (char*)duk_get_string(ctx, -2), duk_get_heapptr(ctx, -1));
|
||||
duk_pop_2(ctx);
|
||||
}
|
||||
duk_pop(ctx);
|
||||
}
|
||||
@@ -37,6 +37,17 @@ typedef void(*ILibDuktape_HelperEvent)(duk_context *ctx, void *user);
|
||||
#define ILibDuktape_CR2HTTP "\xFF_CR2HTTP"
|
||||
#define ILibDuktape_CR2Options "\xFF_CR2Options"
|
||||
|
||||
typedef enum ILibDuktape_LogTypes
|
||||
{
|
||||
ILibDuktape_LogType_Normal = 0,
|
||||
ILibDuktape_LogType_Warn,
|
||||
ILibDuktape_LogType_Error,
|
||||
ILibDuktape_LogType_Info1,
|
||||
ILibDuktape_LogType_Info2,
|
||||
ILibDuktape_LogType_Info3
|
||||
}ILibDuktape_LogTypes;
|
||||
|
||||
void ILibDuktape_Log_Object(duk_context *ctx, duk_idx_t i, char *meta);
|
||||
char* Duktape_GetContextGuidHex(duk_context *ctx);
|
||||
void *Duktape_GetChain(duk_context *ctx);
|
||||
char *Duktape_GetStashKey(void* value);
|
||||
@@ -53,6 +64,14 @@ struct sockaddr_in6* Duktape_IPAddress6_FromString(char* address, unsigned short
|
||||
void ILibDuktape_SockAddrToOptions(duk_context *ctx, struct sockaddr_in6 *addr);
|
||||
void *ILibDuktape_GetProcessObject(duk_context *ctx);
|
||||
|
||||
char* ILibDuktape_String_AsWide(duk_context *ctx, duk_idx_t idx, duk_size_t *len);
|
||||
void ILibDuktape_String_PushWideString(duk_context *ctx, char *wstr, size_t wstrlen);
|
||||
char *ILibDuktape_String_WideToUTF8(duk_context *ctx, char *wstr);
|
||||
char *ILibDuktape_String_UTF8ToWide(duk_context *ctx, char *str);
|
||||
|
||||
#define Duktape_PushBuffer(ctx, bufSize) ILibMemory_Init(duk_push_fixed_buffer(ctx, (duk_size_t)(bufSize) + sizeof(ILibMemory_Header)), (bufSize), 0, ILibMemory_Types_OTHER)
|
||||
void Duktape_Console_Log(duk_context *ctx, void *chain, ILibDuktape_LogTypes logType, char *msg, duk_size_t msgLen);
|
||||
|
||||
typedef void(*ILibDuktape_NativeUncaughtExceptionHandler)(duk_context *ctx, char *msg, void *user);
|
||||
void ILibDuktape_SetNativeUncaughtExceptionHandler(duk_context *ctx, ILibDuktape_NativeUncaughtExceptionHandler handler, void *user);
|
||||
|
||||
@@ -93,17 +112,13 @@ void ILibDuktape_Helper_AddHeapFinalizer(duk_context *ctx, ILibDuktape_HelperEve
|
||||
|
||||
void ILibDuktape_Push_ObjectStash(duk_context *ctx);
|
||||
|
||||
void ILibDuktape_PointerValidation_Init(duk_context *ctx);
|
||||
void ILibDuktape_ValidatePointer(void *chain, void *ptr);
|
||||
void ILibDuktape_InValidatePointer(void *chain, void *ptr);
|
||||
int ILibDuktape_IsPointerValid(void *chain, void *ptr);
|
||||
#define ILibDuktape_ValidateHeapPointer(ctx, objIdx) ILibDuktape_ValidatePointer(Duktape_GetChain(ctx), duk_get_heapptr(ctx, objIdx))
|
||||
#define ILibDuktape_InValidateHeapPointer(ctx, objIdx) ILibDuktape_InValidatePointer(Duktape_GetChain(ctx), duk_get_heapptr(ctx, objIdx))
|
||||
|
||||
typedef void(*ILibDuktape_ImmediateHandler)(duk_context *ctx, void ** args, int argsLen);
|
||||
typedef ILibDuktape_ImmediateHandler ILibDuktape_IntervalHandler;
|
||||
|
||||
void* ILibDuktape_Immediate(duk_context *ctx, void ** args, int argsLen, ILibDuktape_ImmediateHandler callback);
|
||||
void* ILibDuktape_Interval(duk_context *ctx, void **args, int argsLen, int delay, ILibDuktape_IntervalHandler callback);
|
||||
int ILibDuktape_GetReferenceCount(duk_context *ctx, duk_idx_t i);
|
||||
|
||||
#define ILibDuktape_WriteID(ctx, id) duk_push_string(ctx, id);duk_put_prop_string(ctx, -2, ILibDuktape_OBJID)
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -57,6 +57,7 @@ extern void ILibWebClient_ResetWCDO(struct ILibWebClientDataObject *wcdo);
|
||||
#define ILibDuktape_HTTP2PipedWritable "\xFF_HTTP2PipedWritable"
|
||||
#define ILibDuktape_HTTPStream2Data "\xFF_HTTPStream2Data"
|
||||
#define ILibDuktape_HTTPStream2HTTP "\xFF_HTTPStream2HTTP"
|
||||
#define ILibDuktape_HTTPStream2IMSG "\xFF_HTTPStream2IMSG"
|
||||
#define ILibDuktape_HTTPStream2Socket "\xFF_HTTPStream2Socket"
|
||||
#define ILibDuktape_IMSG2HttpStream "\xFF_IMSG2HttpStream"
|
||||
#define ILibDuktape_IMSG2Ptr "\xFF_IMSG2Ptr"
|
||||
@@ -130,6 +131,7 @@ typedef struct ILibDuktape_HttpStream_ServerResponse_BufferedImplicit_State
|
||||
void *ctx;
|
||||
void *writeStream;
|
||||
void *serverResponseObj;
|
||||
void *serverResponseStream;
|
||||
int endBytes;
|
||||
int chunk;
|
||||
size_t bufferLen;
|
||||
@@ -514,6 +516,9 @@ duk_ret_t ILibDuktape_HttpStream_http_onUpgrade(duk_context *ctx)
|
||||
duk_ret_t ILibDuktape_HttpStream_http_endResponseSink(duk_context *ctx)
|
||||
{
|
||||
duk_push_this(ctx); // [imsg]
|
||||
//ILibDuktape_Log_Object(ctx, -1, "IMSG");
|
||||
|
||||
duk_del_prop_string(ctx, -1, ILibDuktape_IMSG2Ptr);
|
||||
duk_get_prop_string(ctx, -1, ILibDuktape_IMSG2HttpStream); // [imsg][httpstream]
|
||||
duk_get_prop_string(ctx, -1, ILibDuktape_HTTP2CR); // [imsg][httpstream][CR]
|
||||
|
||||
@@ -543,6 +548,24 @@ duk_ret_t ILibDuktape_HttpStream_http_endResponseSink(duk_context *ctx)
|
||||
duk_get_prop_string(ctx, -1, "keepSocketAlive"); // [socket][imsg][httpstream][CR][Agent][keepSocketAlive]
|
||||
duk_swap_top(ctx, -2); // [socket][imsg][httpstream][CR][keepSocketAlive][this]
|
||||
duk_dup(ctx, -6); // [socket][imsg][httpstream][CR][keepSocketAlive][this][socket]
|
||||
|
||||
//printf("End Response -->\n");
|
||||
//if (duk_has_prop_string(ctx, -1, ILibDuktape_Socket2HttpStream))
|
||||
//{
|
||||
// duk_get_prop_string(ctx, -1, ILibDuktape_Socket2HttpStream);
|
||||
// printf(" [Socket: %p] => [HTTPStream: %p]\n", duk_get_heapptr(ctx, -2), duk_get_heapptr(ctx, -1));
|
||||
// ILibDuktape_Log_Object(ctx, -1, "HTTPStream");
|
||||
// duk_pop(ctx);
|
||||
//}
|
||||
//if (duk_has_prop_string(ctx, -1, ILibDuktape_SOCKET2OPTIONS))
|
||||
//{
|
||||
// duk_get_prop_string(ctx, -1, ILibDuktape_SOCKET2OPTIONS);
|
||||
// ILibDuktape_Log_Object(ctx, -1, "OPTIONS");
|
||||
// duk_pop(ctx);
|
||||
//}
|
||||
//ILibDuktape_Log_Object(ctx, -1, "SOCKET");
|
||||
//printf("\n");
|
||||
|
||||
duk_call_method(ctx, 1); duk_pop(ctx); // [socket][imsg][httpstream][CR]
|
||||
return(0);
|
||||
}
|
||||
@@ -671,6 +694,9 @@ duk_ret_t ILibDuktape_HttpStream_http_OnSocketReady(duk_context *ctx)
|
||||
if (data->bodyStream != NULL) { ILibDuktape_readableStream_WriteEnd(data->bodyStream); data->bodyStream = NULL; }
|
||||
duk_pop(ctx); // [socket][clientRequest][HTTPStream]
|
||||
|
||||
ILibDuktape_EventEmitter_DeleteForwardEvent(ctx, -1, "response");
|
||||
ILibDuktape_EventEmitter_DeleteForwardEvent(ctx, -1, "continue");
|
||||
|
||||
// We need to change the events to propagate to the new clientRequest instead of the old one
|
||||
duk_get_prop_string(ctx, -1, "removeAllListeners"); // [socket][clientRequest][HTTPStream][remove]
|
||||
duk_dup(ctx, -2); // [socket][clientRequest][HTTPStream][remove][this]
|
||||
@@ -684,6 +710,8 @@ duk_ret_t ILibDuktape_HttpStream_http_OnSocketReady(duk_context *ctx)
|
||||
duk_dup(ctx, -2); // [socket][clientRequest][HTTPStream][remove][this]
|
||||
duk_push_string(ctx, "upgrade"); // [socket][clientRequest][HTTPStream][remove][this][upgrade]
|
||||
duk_call_method(ctx, 1); duk_pop(ctx); // [socket][clientRequest][HTTPStream]
|
||||
|
||||
|
||||
duk_push_this(ctx); // [socket][clientRequest][HTTPStream][clientRequest]
|
||||
duk_put_prop_string(ctx, -2, ILibDuktape_HTTP2CR); // [socket][clientRequest][HTTPStream]
|
||||
|
||||
@@ -996,7 +1024,20 @@ void ILibDuktape_HttpStream_http_request_transform(struct ILibDuktape_Transform
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
duk_ret_t ILibDuktape_ClientRequest_Finalizer(duk_context *ctx)
|
||||
{
|
||||
if (duk_has_prop_string(ctx, 0, ILibDuktape_CR_RequestBuffer))
|
||||
{
|
||||
duk_get_prop_string(ctx, 0, ILibDuktape_CR_RequestBuffer);
|
||||
ILibDuktape_Http_ClientRequest_WriteData *data = (ILibDuktape_Http_ClientRequest_WriteData*)Duktape_GetBuffer(ctx, -1, NULL);
|
||||
if (data->buffer != NULL)
|
||||
{
|
||||
free(data->buffer);
|
||||
data->buffer = NULL;
|
||||
}
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
duk_ret_t ILibDuktape_HttpStream_http_request(duk_context *ctx)
|
||||
{
|
||||
char *proto;
|
||||
@@ -1086,7 +1127,7 @@ duk_ret_t ILibDuktape_HttpStream_http_request(duk_context *ctx)
|
||||
ILibDuktape_EventEmitter_CreateEventEx(emitter, "upgrade");
|
||||
ILibDuktape_EventEmitter_CreateEventEx(emitter, "error");
|
||||
ILibDuktape_EventEmitter_AddOnEx(ctx, -1, "socket", ILibDuktape_HttpStream_http_OnSocketReady);
|
||||
|
||||
ILibDuktape_EventEmitter_AddOnEx(ctx, -1, "~", ILibDuktape_ClientRequest_Finalizer);
|
||||
|
||||
|
||||
if (nargs > 1 && duk_is_function(ctx, 1))
|
||||
@@ -1465,7 +1506,7 @@ duk_ret_t ILibDuktape_HttpStream_http_server_onConnection(duk_context *ctx)
|
||||
duk_get_prop_string(ctx, -1, "pipe"); // [NS][socket][pipe]
|
||||
duk_dup(ctx, -2); // [NS][socket][pipe][this]
|
||||
|
||||
duk_eval_string(ctx, "require('http').createStream();"); // [NS][socket][pipe][this][httpStream]
|
||||
duk_eval_string(ctx, "require('http').createStream();"); // [NS][socket][pipe][this][httpStream]
|
||||
duk_get_prop_string(ctx, -5, ILibDuktape_NS2HttpServer); // [NS][socket][pipe][this][httpStream][httpServer]
|
||||
duk_dup(ctx, -1); // [NS][socket][pipe][this][httpStream][httpServer][dup]
|
||||
duk_put_prop_string(ctx, -3, ILibduktape_HttpStream2HttpServer); // [NS][socket][pipe][this][httpStream][httpServer]
|
||||
@@ -1813,7 +1854,7 @@ void ILibDuktape_HttpStream_ServerResponse_WriteImplicitHeaders(void *chain, voi
|
||||
{
|
||||
int retVal;
|
||||
ILibDuktape_HttpStream_ServerResponse_BufferedImplicit_State *state = (ILibDuktape_HttpStream_ServerResponse_BufferedImplicit_State*)user;
|
||||
if (chain != NULL && !ILibDuktape_IsPointerValid(chain, state->serverResponseObj)) { free(user); }
|
||||
if (!ILibMemory_CanaryOK(state->serverResponseStream)) { free(user); return; }
|
||||
|
||||
// We are on Microstack Thread, so we can access the JS object, and write the implicit headers
|
||||
duk_push_heapptr(state->ctx, state->serverResponseObj); // [SR]
|
||||
@@ -1956,6 +1997,7 @@ ILibTransport_DoneState ILibDuktape_HttpStream_ServerResponse_WriteSink(struct I
|
||||
memset(tmp, 0, sizeof(ILibDuktape_HttpStream_ServerResponse_BufferedImplicit_State));
|
||||
tmp->ctx = stream->ctx;
|
||||
tmp->serverResponseObj = stream->obj;
|
||||
tmp->serverResponseStream = stream;
|
||||
tmp->writeStream = state->writeStream;
|
||||
tmp->endBytes = stream->endBytes;
|
||||
tmp->chunk = state->chunkSupported;
|
||||
@@ -1970,6 +2012,7 @@ ILibTransport_DoneState ILibDuktape_HttpStream_ServerResponse_WriteSink(struct I
|
||||
memset(buffered, 0, sizeof(ILibDuktape_HttpStream_ServerResponse_BufferedImplicit_State));
|
||||
buffered->ctx = stream->ctx;
|
||||
buffered->serverResponseObj = stream->obj;
|
||||
buffered->serverResponseStream = stream;
|
||||
buffered->writeStream = state->writeStream;
|
||||
buffered->bufferLen = bufferLen;
|
||||
buffered->endBytes = stream->endBytes;
|
||||
@@ -2059,6 +2102,7 @@ ILibTransport_DoneState ILibDuktape_HttpStream_ServerResponse_WriteSink(struct I
|
||||
data->ctx = stream->ctx;
|
||||
data->endBytes = stream->endBytes;
|
||||
data->serverResponseObj = stream->obj;
|
||||
data->serverResponseStream = stream;
|
||||
data->writeStream = state->writeStream;
|
||||
data->bufferLen = bufferLen;
|
||||
memcpy_s(data->buffer, bufferLen, buffer, bufferLen);
|
||||
@@ -2403,8 +2447,6 @@ void ILibDuktape_HttpStream_ServerResponse_PUSH(duk_context *ctx, void* writeStr
|
||||
duk_remove(ctx, -2); // [resp][http/s.serverResponse]
|
||||
duk_put_prop_string(ctx, -2, ILibDuktape_OBJID); // [resp]
|
||||
|
||||
|
||||
ILibDuktape_PointerValidation_Init(ctx);
|
||||
ILibDuktape_WriteID(ctx, "http.serverResponse");
|
||||
duk_push_fixed_buffer(ctx, sizeof(ILibDuktape_HttpStream_ServerResponse_State)); // [resp][state]
|
||||
state = (ILibDuktape_HttpStream_ServerResponse_State*)Duktape_GetBuffer(ctx, -1, NULL);
|
||||
@@ -2666,10 +2708,11 @@ int ILibDuktape_HttpStream_IncomingMessage_UnshiftBytes(ILibDuktape_readableStre
|
||||
}
|
||||
void ILibDuktape_HttpStream_DispatchEnd(void *chain, void *user)
|
||||
{
|
||||
if (ILibDuktape_IsPointerValid(chain, ((void**)user)[1]) != 0)
|
||||
if(ILibMemory_CanaryOK(((void**)user)[1]))
|
||||
{
|
||||
duk_context *ctx = (duk_context*)((void**)user)[0];
|
||||
void *heapPtr = ((void**)user)[1];
|
||||
void *heapPtr = ((ILibDuktape_DuplexStream*)((void**)user)[1])->ParentObject;
|
||||
((ILibDuktape_HttpStream_Data*)((void**)user)[2])->bodyStream = NULL;
|
||||
|
||||
duk_push_heapptr(ctx, heapPtr); // [httpStream]
|
||||
duk_get_prop_string(ctx, -1, "emit"); // [httpStream][emit]
|
||||
@@ -2694,7 +2737,7 @@ duk_ret_t ILibDuktape_HttpStream_OnReceive_bodyStreamFinalized(duk_context *ctx)
|
||||
ILibDuktape_HttpStream_Data *data = (ILibDuktape_HttpStream_Data*)Duktape_GetPointerProperty(ctx, 0, ILibDuktape_IMSG2Ptr);
|
||||
if (data != NULL)
|
||||
{
|
||||
if (data->endPropagated == 0) { ILibDuktape_readableStream_WriteEnd(data->bodyStream); }
|
||||
if ((data->endPropagated == 0) && (data->bodyStream != NULL)) { ILibDuktape_readableStream_WriteEnd(data->bodyStream); }
|
||||
data->endPropagated = 1;
|
||||
data->bodyStream = NULL;
|
||||
}
|
||||
@@ -2773,28 +2816,38 @@ void ILibDuktape_HttpStream_OnReceive(ILibWebClient_StateObject WebStateObject,
|
||||
{
|
||||
if (valLen == 12 && strncasecmp(val, "100-Continue", 12) == 0)
|
||||
{
|
||||
duk_push_string(ctx, "checkContinue"); // [emit][this][checkContinue]
|
||||
ILibDuktape_HttpStream_IncomingMessage_PUSH(ctx, header, data->DS->ParentObject); // [emit][this][checkContinue][imsg]
|
||||
data->bodyStream = ILibDuktape_ReadableStream_InitEx(ctx, ILibDuktape_HttpStream_IncomingMessage_PauseSink, ILibDuktape_HttpStream_IncomingMessage_ResumeSink, ILibDuktape_HttpStream_IncomingMessage_UnshiftBytes, data);
|
||||
ILibDuktape_HttpStream_ServerResponse_PUSH(ctx, data->DS->writableStream->pipedReadable, header, data->DS->ParentObject); // [emit][this][checkContinue][imsg][rsp]
|
||||
duk_dup(ctx, -1); // [emit][this][checkContinue][imsg][rsp][rsp]
|
||||
duk_insert(ctx, -6); // [rsp][emit][this][checkContinue][imsg][rsp]
|
||||
if (duk_pcall_method(ctx, 3) != 0) { ILibDuktape_Process_UncaughtExceptionEx(ctx, "http.httpStream.onReceive->checkContinue(): "); } // [rsp][hadListener]
|
||||
// Is there a listener for 'checkContinue'?
|
||||
if (ILibDuktape_EventEmitter_HasListenersEx(ctx, -1, "checkContinue"))
|
||||
{
|
||||
duk_push_string(ctx, "checkContinue"); // [emit][this][checkContinue]
|
||||
ILibDuktape_HttpStream_IncomingMessage_PUSH(ctx, header, data->DS->ParentObject); // [emit][this][checkContinue][imsg]
|
||||
data->bodyStream = ILibDuktape_ReadableStream_InitEx(ctx, ILibDuktape_HttpStream_IncomingMessage_PauseSink, ILibDuktape_HttpStream_IncomingMessage_ResumeSink, ILibDuktape_HttpStream_IncomingMessage_UnshiftBytes, data);
|
||||
duk_dup(ctx, -3); duk_dup(ctx, -2); // [emit][this][checkContinue][imsg][httpstream][imsg]
|
||||
duk_put_prop_string(ctx, -2, ILibDuktape_HTTPStream2IMSG); duk_pop(ctx); // [emit][this][checkContinue][imsg]
|
||||
|
||||
ILibDuktape_HttpStream_ServerResponse_PUSH(ctx, data->DS->writableStream->pipedReadable, header, data->DS->ParentObject); // [emit][this][checkContinue][imsg][rsp]
|
||||
if (duk_pcall_method(ctx, 3) != 0) { ILibDuktape_Process_UncaughtExceptionEx(ctx, "http.httpStream.onReceive->checkContinue(): "); } // [rsp][hadListener]
|
||||
duk_pop(ctx); // ...
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!duk_get_boolean(ctx, -1))
|
||||
{
|
||||
// No listener, so we must immediately send '100 Continue'
|
||||
duk_get_prop_string(ctx, -2, "writeContinue"); // [rsp][hadListener][writeContinue]
|
||||
duk_dup(ctx, -3); // [rsp][hadListener][writeContinue][this]
|
||||
duk_call_method(ctx, 0); duk_pop(ctx); // [rsp][hadListener]
|
||||
}
|
||||
}
|
||||
duk_pop_2(ctx); // ...
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
// Nobody listening for 'checkContinue', so we need to respond with 100 Continue
|
||||
ILibDuktape_HttpStream_ServerResponse_PUSH(ctx, data->DS->writableStream->pipedReadable, header, data->DS->ParentObject); // [emit][this][rsp]
|
||||
duk_get_prop_string(ctx, -1, "writeContinue"); // [emit][this][rsp][writeContinue]
|
||||
duk_swap_top(ctx, -2); // [emit][this][writeContinue][this]
|
||||
duk_call_method(ctx, 0); duk_pop(ctx); // [emit][this]
|
||||
|
||||
// Since nobody was listening for 'checkContinue', need to process this as a 'request'
|
||||
duk_push_string(ctx, "request"); // [emit][this][request]
|
||||
ILibDuktape_HttpStream_IncomingMessage_PUSH(ctx, header, data->DS->ParentObject); // [emit][this][request][imsg]
|
||||
data->bodyStream = ILibDuktape_ReadableStream_InitEx(ctx, ILibDuktape_HttpStream_IncomingMessage_PauseSink, ILibDuktape_HttpStream_IncomingMessage_ResumeSink, ILibDuktape_HttpStream_IncomingMessage_UnshiftBytes, data);
|
||||
duk_dup(ctx, -3); duk_dup(ctx, -2); // [emit][this][request][imsg][httpstream][imsg]
|
||||
duk_put_prop_string(ctx, -2, ILibDuktape_HTTPStream2IMSG); duk_pop(ctx); // [emit][this][request][imsg]
|
||||
|
||||
ILibDuktape_HttpStream_ServerResponse_PUSH(ctx, data->DS->writableStream->pipedReadable, header, data->DS->ParentObject); // [emit][this][request][imsg][rsp]
|
||||
if (duk_pcall_method(ctx, 3) != 0) { ILibDuktape_Process_UncaughtExceptionEx(ctx, "http.httpStream.onReceive->request(): "); }
|
||||
duk_pop(ctx); // ...
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -2852,6 +2905,11 @@ void ILibDuktape_HttpStream_OnReceive(ILibWebClient_StateObject WebStateObject,
|
||||
data->bodyStream = ILibDuktape_ReadableStream_InitEx(ctx, ILibDuktape_HttpStream_IncomingMessage_PauseSink, ILibDuktape_HttpStream_IncomingMessage_ResumeSink, ILibDuktape_HttpStream_IncomingMessage_UnshiftBytes, data);
|
||||
duk_push_pointer(ctx, data);
|
||||
duk_put_prop_string(ctx, -2, ILibDuktape_IMSG2Ptr);
|
||||
duk_dup(ctx, -3); // [emit][this][response][imsg][httpstream]
|
||||
duk_dup(ctx, -2); // [emit][this][response][imsg][httpstream][imsg]
|
||||
duk_put_prop_string(ctx, -2, ILibDuktape_HTTPStream2IMSG); // [emit][this][response][imsg][httpstream]
|
||||
duk_pop(ctx); // [emit][this][response][imsg]
|
||||
|
||||
ILibDuktape_EventEmitter_AddOnEx(ctx, -1, "~", ILibDuktape_HttpStream_OnReceive_bodyStreamFinalized);
|
||||
if (duk_pcall_method(ctx, 2) != 0) { ILibDuktape_Process_UncaughtExceptionEx(ctx, "http.httpStream.onReceive->response(): "); }
|
||||
duk_pop(ctx);
|
||||
@@ -2874,6 +2932,8 @@ void ILibDuktape_HttpStream_OnReceive(ILibWebClient_StateObject WebStateObject,
|
||||
if (ILibIsRunningOnChainThread(data->chain) != 0)
|
||||
{
|
||||
// We're on the Chain Thread, so we can directly emit the 'end' event
|
||||
data->bodyStream = NULL;
|
||||
|
||||
duk_push_heapptr(ctx, data->DS->ParentObject); // [httpStream]
|
||||
duk_get_prop_string(ctx, -1, "emit"); // [httpStream][emit]
|
||||
duk_swap_top(ctx, -2); // [emit][this]
|
||||
@@ -2884,19 +2944,19 @@ void ILibDuktape_HttpStream_OnReceive(ILibWebClient_StateObject WebStateObject,
|
||||
else
|
||||
{
|
||||
// We're on the wrong thread to dispatch the 'end' event, so we have to context switch
|
||||
void **tmp = (void**)ILibMemory_Allocate(2 * sizeof(void*), 0, NULL, NULL);
|
||||
void **tmp = (void**)ILibMemory_Allocate(3 * sizeof(void*), 0, NULL, NULL);
|
||||
tmp[0] = ctx;
|
||||
tmp[1] = data->DS->ParentObject;
|
||||
tmp[1] = data->DS;
|
||||
tmp[2] = data;
|
||||
ILibChain_RunOnMicrostackThread(data->chain, ILibDuktape_HttpStream_DispatchEnd, tmp);
|
||||
}
|
||||
}
|
||||
}
|
||||
duk_ret_t ILibDuktape_HttpStream_Finalizer(duk_context *ctx)
|
||||
{
|
||||
duk_del_prop_string(ctx, 0, ILibDuktape_HTTPStream2IMSG);
|
||||
duk_get_prop_string(ctx, 0, ILibDuktape_HTTPStream2Data);
|
||||
ILibDuktape_HttpStream_Data *data = (ILibDuktape_HttpStream_Data*)Duktape_GetBuffer(ctx, -1, NULL);
|
||||
ILibDuktape_InValidatePointer(Duktape_GetChain(ctx), data);
|
||||
ILibDuktape_InValidateHeapPointer(ctx, 0);
|
||||
|
||||
ILibWebClient_DestroyWebClientDataObject(data->WCDO);
|
||||
return(0);
|
||||
@@ -2934,9 +2994,7 @@ duk_ret_t ILibduktape_HttpStream_create(duk_context *ctx)
|
||||
duk_put_prop_string(ctx, -2, ILibDuktape_HTTPStream2HTTP); // [httpStream]
|
||||
ILibDuktape_WriteID(ctx, "http.httpStream");
|
||||
ILibDuktape_EventEmitter *emitter = ILibDuktape_EventEmitter_Create(ctx);
|
||||
duk_push_fixed_buffer(ctx, sizeof(ILibDuktape_HttpStream_Data)); // [httpStream][buffer]
|
||||
data = (ILibDuktape_HttpStream_Data*)Duktape_GetBuffer(ctx, -1, NULL);
|
||||
memset(data, 0, sizeof(ILibDuktape_HttpStream_Data));
|
||||
data = (ILibDuktape_HttpStream_Data*)Duktape_PushBuffer(ctx, sizeof(ILibDuktape_HttpStream_Data));
|
||||
duk_put_prop_string(ctx, -2, ILibDuktape_HTTPStream2Data); // [httpStream]
|
||||
|
||||
ILibDuktape_EventEmitter_CreateEventEx(emitter, "end");
|
||||
@@ -2960,10 +3018,7 @@ duk_ret_t ILibduktape_HttpStream_create(duk_context *ctx)
|
||||
ILibDuktape_EventEmitter_AddOnEx(ctx, -1, "pipe", ILibDuktape_HttpStream_pipeEvent);
|
||||
|
||||
ILibDuktape_CreateEventWithGetter(ctx, "connectionCloseSpecified", ILibDuktape_HttpStream_connectionCloseSpecified);
|
||||
|
||||
ILibDuktape_CreateFinalizer(ctx, ILibDuktape_HttpStream_Finalizer);
|
||||
ILibDuktape_ValidatePointer(Duktape_GetChain(ctx), data);
|
||||
ILibDuktape_ValidateHeapPointer(ctx, -1);
|
||||
return(1);
|
||||
}
|
||||
duk_ret_t ILibDuktape_HttpStream_Agent_getName(duk_context *ctx)
|
||||
@@ -3113,10 +3168,14 @@ duk_ret_t ILibDuktape_HttpStream_Agent_keepSocketAlive(duk_context *ctx)
|
||||
|
||||
|
||||
duk_get_prop_string(ctx, -1, "requests"); // [key][Agent][requests]
|
||||
//ILibDuktape_Log_Object(ctx, -1, "Agent/Requests");
|
||||
|
||||
if (duk_has_prop_string(ctx, -1, key))
|
||||
{
|
||||
// Has Key, check the Array
|
||||
duk_get_prop_string(ctx, -1, key); // [key][Agent][requests][Array]
|
||||
//ILibDuktape_Log_Object(ctx, -1, "Agent/Request/ArrayIndex");
|
||||
|
||||
duk_get_prop_string(ctx, -1, "shift"); // [key][Agent][requests][Array][shift]
|
||||
duk_swap_top(ctx, -2); // [key][Agent][requests][shift][this]
|
||||
duk_call_method(ctx, 0); // [key][Agent][requests][request]
|
||||
@@ -3485,8 +3544,11 @@ ILibTransport_DoneState ILibDuktape_httpStream_webSocket_EncodedWriteSink(ILibDu
|
||||
char* maskingKey = NULL;
|
||||
int FIN;
|
||||
unsigned char OPCODE;
|
||||
unsigned char RSV;
|
||||
ILibDuktape_WebSocket_State *state = (ILibDuktape_WebSocket_State*)user;
|
||||
|
||||
if (!ILibMemory_CanaryOK(state)) { return(ILibTransport_DoneState_ERROR); }
|
||||
|
||||
if (bufferLen < 2)
|
||||
{
|
||||
// We need at least 2 bytes to read enough of the headers to know how long the frame is
|
||||
@@ -3496,6 +3558,14 @@ ILibTransport_DoneState ILibDuktape_httpStream_webSocket_EncodedWriteSink(ILibDu
|
||||
hdr = ntohs(((unsigned short*)(buffer))[0]);
|
||||
FIN = (hdr & WEBSOCKET_FIN) != 0;
|
||||
OPCODE = (hdr & WEBSOCKET_OPCODE) >> 8;
|
||||
RSV = (hdr & WEBSOCKET_RSV) >> 8;
|
||||
|
||||
if (RSV != 0)
|
||||
{
|
||||
char msg[] = "Reserved Field of Websocket was not ZERO";
|
||||
Duktape_Console_Log(state->ctx, state->chain, ILibDuktape_LogType_Error, msg, sizeof(msg) - 1);
|
||||
return(ILibTransport_DoneState_ERROR);
|
||||
}
|
||||
|
||||
plen = (unsigned char)(hdr & WEBSOCKET_PLEN);
|
||||
if (plen == 126)
|
||||
@@ -3636,7 +3706,8 @@ void ILibDuktape_httpStream_webSocket_EncodedEndSink(ILibDuktape_DuplexStream *s
|
||||
}
|
||||
void ILibDuktape_httpStream_webSocket_EncodedPauseSink_Chain(void *chain, void *user)
|
||||
{
|
||||
if (chain != NULL && !ILibDuktape_IsPointerValid(chain, user)) { return; }
|
||||
if (!ILibMemory_CanaryOK(user)) { return; }
|
||||
|
||||
ILibDuktape_WebSocket_State *state = (ILibDuktape_WebSocket_State*)user;
|
||||
duk_context *ctx = state->decodedStream->writableStream->ctx;
|
||||
|
||||
@@ -3648,7 +3719,7 @@ void ILibDuktape_httpStream_webSocket_EncodedPauseSink_Chain(void *chain, void *
|
||||
}
|
||||
void ILibDuktape_httpStream_webSocket_EncodedPauseSink(ILibDuktape_DuplexStream *sender, void *user)
|
||||
{
|
||||
printf("WebSocket.Encoded.Pause();\n");
|
||||
//printf("WebSocket.Encoded.Pause();\n");
|
||||
ILibDuktape_WebSocket_State *state = (ILibDuktape_WebSocket_State*)user;
|
||||
if (state->decodedStream->writableStream->pipedReadable_native != NULL && state->decodedStream->writableStream->pipedReadable_native->PauseHandler != NULL)
|
||||
{
|
||||
@@ -3669,10 +3740,12 @@ void ILibDuktape_httpStream_webSocket_EncodedPauseSink(ILibDuktape_DuplexStream
|
||||
}
|
||||
void ILibDuktape_httpStream_webSocket_EncodedResumeSink_Chain(void *chain, void *user)
|
||||
{
|
||||
if (chain != NULL && !ILibDuktape_IsPointerValid(chain, user)) { return; }
|
||||
if (!ILibMemory_CanaryOK(user)) { return; }
|
||||
|
||||
ILibDuktape_WebSocket_State *state = (ILibDuktape_WebSocket_State*)user;
|
||||
duk_context *ctx = state->decodedStream->writableStream->ctx;
|
||||
|
||||
if (state->decodedStream->writableStream->pipedReadable == NULL) { return; }
|
||||
duk_push_heapptr(ctx, state->decodedStream->writableStream->pipedReadable); // [readable]
|
||||
duk_get_prop_string(ctx, -1, "resume"); // [readable][resume]
|
||||
duk_swap_top(ctx, -2); // [resume][this]
|
||||
@@ -3681,7 +3754,7 @@ void ILibDuktape_httpStream_webSocket_EncodedResumeSink_Chain(void *chain, void
|
||||
}
|
||||
void ILibDuktape_httpStream_webSocket_EncodedResumeSink(ILibDuktape_DuplexStream *sender, void *user)
|
||||
{
|
||||
printf("WebSocket.Encoded.Resume();\n");
|
||||
//printf("WebSocket.Encoded.Resume();\n");
|
||||
ILibDuktape_WebSocket_State *state = (ILibDuktape_WebSocket_State*)user;
|
||||
if (state->decodedStream->writableStream->pipedReadable_native != NULL && state->decodedStream->writableStream->pipedReadable_native->ResumeHandler != NULL)
|
||||
{
|
||||
@@ -3718,7 +3791,8 @@ void ILibDuktape_httpStream_webSocket_DecodedEndSink(ILibDuktape_DuplexStream *s
|
||||
}
|
||||
void ILibDuktape_httpStream_webSocket_DecodedPauseSink_Chain(void *chain, void *user)
|
||||
{
|
||||
if (chain != NULL && !ILibDuktape_IsPointerValid(chain, user)) { return; }
|
||||
if (!ILibMemory_CanaryOK(user)) { return; }
|
||||
|
||||
ILibDuktape_WebSocket_State *state = (ILibDuktape_WebSocket_State*)user;
|
||||
duk_context *ctx = state->encodedStream->writableStream->ctx;
|
||||
|
||||
@@ -3758,7 +3832,7 @@ void ILibDuktape_httpStream_webSocket_DecodedPauseSink(ILibDuktape_DuplexStream
|
||||
}
|
||||
void ILibDuktape_httpStream_webSocket_DecodedResumeSink_Chain(void *chain, void *user)
|
||||
{
|
||||
if (chain != NULL && !ILibDuktape_IsPointerValid(chain, user)) { return; }
|
||||
if (!ILibMemory_CanaryOK(user)) { return; }
|
||||
ILibDuktape_WebSocket_State *state = (ILibDuktape_WebSocket_State*)user;
|
||||
duk_context *ctx = state->encodedStream->writableStream->ctx;
|
||||
|
||||
@@ -3802,11 +3876,10 @@ int ILibDuktape_httpStream_webSocket_DecodedUnshiftSink(ILibDuktape_DuplexStream
|
||||
|
||||
duk_ret_t ILibDuktape_httpStream_webSocketStream_finalizer(duk_context *ctx)
|
||||
{
|
||||
void *chain = Duktape_GetChain(ctx);
|
||||
duk_get_prop_string(ctx, 0, ILibDuktape_WebSocket_StatePtr);
|
||||
ILibDuktape_WebSocket_State *state = (ILibDuktape_WebSocket_State*)Duktape_GetBuffer(ctx, -1, NULL);
|
||||
|
||||
if (state->encodedStream->writableStream->pipedReadable != NULL)
|
||||
|
||||
if (state->encodedStream != NULL && state->encodedStream->writableStream->pipedReadable != NULL)
|
||||
{
|
||||
duk_push_heapptr(ctx, state->encodedStream->writableStream->pipedReadable); // [readable]
|
||||
duk_get_prop_string(ctx, -1, "unpipe"); // [readable][unpipe]
|
||||
@@ -3815,7 +3888,6 @@ duk_ret_t ILibDuktape_httpStream_webSocketStream_finalizer(duk_context *ctx)
|
||||
duk_call_method(ctx, 1); duk_pop(ctx); // ...
|
||||
}
|
||||
|
||||
ILibDuktape_InValidatePointer(chain, Duktape_GetBuffer(ctx, -1, NULL));
|
||||
return(0);
|
||||
}
|
||||
duk_ret_t ILibDuktape_httpStream_webSocketStream_sendPing(duk_context *ctx)
|
||||
@@ -3856,17 +3928,24 @@ duk_ret_t ILibDuktape_httpStream_webSocketStream_encodedPiped(duk_context *ctx)
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
duk_ret_t ILibDuktape_httpStream_webSocketStream_encoded_Finalizer(duk_context *ctx)
|
||||
{
|
||||
duk_get_prop_string(ctx, 0, ILibDuktape_WSENC2WS);
|
||||
duk_get_prop_string(ctx, -1, ILibDuktape_WebSocket_StatePtr);
|
||||
ILibDuktape_WebSocket_State *state = (ILibDuktape_WebSocket_State*)Duktape_GetBuffer(ctx, -1, NULL);
|
||||
|
||||
state->encodedStream = NULL;
|
||||
|
||||
return(0);
|
||||
}
|
||||
duk_ret_t ILibDuktape_httpStream_webSocketStream_new(duk_context *ctx)
|
||||
{
|
||||
ILibDuktape_WebSocket_State *state;
|
||||
duk_push_object(ctx); // [WebSocket]
|
||||
duk_push_object(ctx); // [WebSocket]
|
||||
ILibDuktape_WriteID(ctx, "http.WebSocketStream");
|
||||
duk_push_fixed_buffer(ctx, sizeof(ILibDuktape_WebSocket_State)); // [WebSocket][data]
|
||||
state = (ILibDuktape_WebSocket_State*)Duktape_GetBuffer(ctx, -1, NULL);
|
||||
memset(state, 0, sizeof(ILibDuktape_WebSocket_State));
|
||||
duk_put_prop_string(ctx, -2, ILibDuktape_WebSocket_StatePtr); // [WebSocket]
|
||||
ILibDuktape_ValidatePointer(Duktape_GetChain(ctx), state);
|
||||
state = (ILibDuktape_WebSocket_State*)Duktape_PushBuffer(ctx, sizeof(ILibDuktape_WebSocket_State)); // [WebSocket][data]
|
||||
duk_put_prop_string(ctx, -2, ILibDuktape_WebSocket_StatePtr); // [WebSocket]
|
||||
|
||||
state->ctx = ctx;
|
||||
state->ObjectPtr = duk_get_heapptr(ctx, -1);
|
||||
state->chain = Duktape_GetChain(ctx);
|
||||
@@ -3877,6 +3956,7 @@ duk_ret_t ILibDuktape_httpStream_webSocketStream_new(duk_context *ctx)
|
||||
ILibDuktape_EventEmitter_AddOnEx(ctx, -1, "pipe", ILibDuktape_httpStream_webSocketStream_encodedPiped);
|
||||
duk_dup(ctx, -2); // [WebSocket][Encoded][WebSocket]
|
||||
duk_put_prop_string(ctx, -2, ILibDuktape_WSENC2WS); // [WebSocket][Encoded]
|
||||
ILibDuktape_EventEmitter_AddOnceEx3(ctx, -1, "~", ILibDuktape_httpStream_webSocketStream_encoded_Finalizer);
|
||||
|
||||
ILibDuktape_CreateReadonlyProperty(ctx, "encoded"); // [WebSocket]
|
||||
duk_push_object(ctx); // [WebSocket][Decoded]
|
||||
@@ -3925,6 +4005,3 @@ void ILibDuktape_HttpStream_Init(duk_context *ctx)
|
||||
ILibDuktape_ModSearch_AddHandler(ctx, "http", ILibDuktape_HttpStream_http_PUSH);
|
||||
ILibDuktape_ModSearch_AddHandler(ctx, "https", ILibDuktape_HttpStream_https_PUSH);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -153,9 +153,8 @@ duk_ret_t ILibDuktape_MemoryStream_new(duk_context *ctx)
|
||||
|
||||
ILibDuktape_MemoryStream *ms;
|
||||
duk_push_object(ctx); // [ms]
|
||||
duk_push_fixed_buffer(ctx, sizeof(ILibDuktape_MemoryStream)); // [ms][internal]
|
||||
ms = (ILibDuktape_MemoryStream*)Duktape_GetBuffer(ctx, -1, NULL);
|
||||
memset(ms, 0, sizeof(ILibDuktape_MemoryStream));
|
||||
ILibDuktape_WriteID(ctx, "memoryStream");
|
||||
ms = (ILibDuktape_MemoryStream*)Duktape_PushBuffer(ctx, sizeof(ILibDuktape_MemoryStream));
|
||||
duk_put_prop_string(ctx, -2, ILibDuktape_MemoryStream_Internal); // [ms]
|
||||
ms->buffer = (char*)ILibMemory_Allocate(initial, 0, NULL, NULL);
|
||||
ms->bufferSize = (size_t)initial;
|
||||
|
||||
@@ -45,4 +45,4 @@ public:
|
||||
|
||||
void ILibDuktape_NetworkMonitor_Init(duk_context *ctx);
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -19,14 +19,33 @@ limitations under the License.
|
||||
#include "ILibDuktapeModSearch.h"
|
||||
#include "ILibDuktape_DuplexStream.h"
|
||||
#include "ILibDuktape_EventEmitter.h"
|
||||
#include "ILibDuktape_Debugger.h"
|
||||
#include "../microstack/ILibParsers.h"
|
||||
#include "../microstack/ILibCrypto.h"
|
||||
#include "../microstack/ILibRemoteLogging.h"
|
||||
|
||||
|
||||
#define ILibDuktape_Timer_Ptrs "\xFF_DuktapeTimer_PTRS"
|
||||
#define ILibDuktape_Queue_Ptr "\xFF_Queue"
|
||||
#define ILibDuktape_Stream_Buffer "\xFF_BUFFER"
|
||||
#define ILibDuktape_Stream_ReadablePtr "\xFF_ReadablePtr"
|
||||
#define ILibDuktape_Timer_Ptrs "\xFF_DuktapeTimer_PTRS"
|
||||
#define ILibDuktape_Queue_Ptr "\xFF_Queue"
|
||||
#define ILibDuktape_Stream_Buffer "\xFF_BUFFER"
|
||||
#define ILibDuktape_Stream_ReadablePtr "\xFF_ReadablePtr"
|
||||
#define ILibDuktape_Stream_WritablePtr "\xFF_WritablePtr"
|
||||
#define ILibDuktape_Console_Destination "\xFF_Console_Destination"
|
||||
#define ILibDuktape_Console_LOG_Destination "\xFF_Console_Destination"
|
||||
#define ILibDuktape_Console_WARN_Destination "\xFF_Console_WARN_Destination"
|
||||
#define ILibDuktape_Console_ERROR_Destination "\xFF_Console_ERROR_Destination"
|
||||
#define ILibDuktape_Console_INFO_Level "\xFF_Console_INFO_Level"
|
||||
#define ILibDuktape_Console_SessionID "\xFF_Console_SessionID"
|
||||
|
||||
typedef enum ILibDuktape_Console_DestinationFlags
|
||||
{
|
||||
ILibDuktape_Console_DestinationFlags_DISABLED = 0,
|
||||
ILibDuktape_Console_DestinationFlags_StdOut = 1,
|
||||
ILibDuktape_Console_DestinationFlags_ServerConsole = 2,
|
||||
ILibDuktape_Console_DestinationFlags_WebLog = 4,
|
||||
ILibDuktape_Console_DestinationFlags_LogFile = 8
|
||||
}ILibDuktape_Console_DestinationFlags;
|
||||
|
||||
int g_displayStreamPipeMessages = 0;
|
||||
int g_displayFinalizerMessages = 0;
|
||||
|
||||
@@ -176,24 +195,21 @@ duk_ret_t ILibDuktape_Polyfills_Buffer_alloc(duk_context *ctx)
|
||||
}
|
||||
void ILibDuktape_Polyfills_Buffer(duk_context *ctx)
|
||||
{
|
||||
//// Polyfill 'Buffer.slice'
|
||||
//duk_get_prop_string(ctx, -1, "Duktape"); // [g][Duktape]
|
||||
//duk_get_prop_string(ctx, -1, "Buffer"); // [g][Duktape][Buffer]
|
||||
//duk_get_prop_string(ctx, -1, "prototype"); // [g][Duktape][Buffer][prototype]
|
||||
//duk_push_c_function(ctx, ILibDuktape_Pollyfills_Buffer_slice, DUK_VARARGS); // [g][Duktape][Buffer][prototype][func]
|
||||
//duk_put_prop_string(ctx, -2, "slice"); // [g][Duktape][Buffer][prototype]
|
||||
//duk_push_c_function(ctx, ILibDuktape_Polyfills_Buffer_readInt32BE, DUK_VARARGS);// [g][Duktape][Buffer][prototype][func]
|
||||
//duk_put_prop_string(ctx, -2, "readInt32BE"); // [g][Duktape][Buffer][prototype]
|
||||
//duk_pop_3(ctx); // [g]
|
||||
char extras[] =
|
||||
"Object.defineProperty(Buffer.prototype, \"swap32\",\
|
||||
{\
|
||||
value: function swap32()\
|
||||
{\
|
||||
var a = this.readUInt16BE(0);\
|
||||
var b = this.readUInt16BE(2);\
|
||||
this.writeUInt16LE(a, 2);\
|
||||
this.writeUInt16LE(b, 0);\
|
||||
return(this);\
|
||||
}\
|
||||
});";
|
||||
|
||||
duk_eval_string(ctx, extras); duk_pop(ctx);
|
||||
|
||||
//// Polyfill 'Buffer.toString()
|
||||
//duk_get_prop_string(ctx, -1, "Duktape"); // [g][Duktape]
|
||||
//duk_get_prop_string(ctx, -1, "Buffer"); // [g][Duktape][Buffer]
|
||||
//duk_get_prop_string(ctx, -1, "prototype"); // [g][Duktape][Buffer][prototype]
|
||||
//duk_push_c_function(ctx, ILibDuktape_Polyfills_Buffer_toString, DUK_VARARGS); // [g][Duktape][Buffer][prototype][func]
|
||||
//duk_put_prop_string(ctx, -2, "toString"); // [g][Duktape][Buffer][prototype]
|
||||
//duk_pop_3(ctx); // [g]
|
||||
|
||||
// Polyfill Buffer.from()
|
||||
duk_get_prop_string(ctx, -1, "Buffer"); // [g][Buffer]
|
||||
duk_push_c_function(ctx, ILibDuktape_Polyfills_Buffer_from, DUK_VARARGS); // [g][Buffer][func]
|
||||
@@ -271,13 +287,55 @@ void ILibDuktape_Polyfills_String(duk_context *ctx)
|
||||
duk_ret_t ILibDuktape_Polyfills_Console_log(duk_context *ctx)
|
||||
{
|
||||
int numargs = duk_get_top(ctx);
|
||||
int i;
|
||||
int i, x;
|
||||
int len = 0;
|
||||
duk_size_t strLen;
|
||||
char *str;
|
||||
char *PREFIX = NULL;
|
||||
char *DESTINATION = NULL;
|
||||
duk_push_current_function(ctx);
|
||||
ILibDuktape_LogTypes logType = (ILibDuktape_LogTypes)Duktape_GetIntPropertyValue(ctx, -1, "logType", ILibDuktape_LogType_Normal);
|
||||
switch (logType)
|
||||
{
|
||||
case ILibDuktape_LogType_Warn:
|
||||
PREFIX = (char*)"WARNING: "; // LENGTH MUST BE <= 9
|
||||
DESTINATION = ILibDuktape_Console_WARN_Destination;
|
||||
break;
|
||||
case ILibDuktape_LogType_Error:
|
||||
PREFIX = (char*)"ERROR: "; // LENGTH MUST BE <= 9
|
||||
DESTINATION = ILibDuktape_Console_ERROR_Destination;
|
||||
break;
|
||||
case ILibDuktape_LogType_Info1:
|
||||
case ILibDuktape_LogType_Info2:
|
||||
case ILibDuktape_LogType_Info3:
|
||||
duk_push_this(ctx);
|
||||
i = Duktape_GetIntPropertyValue(ctx, -1, ILibDuktape_Console_INFO_Level, 0);
|
||||
duk_pop(ctx);
|
||||
PREFIX = NULL;
|
||||
if (i >= (((int)logType + 1) - (int)ILibDuktape_LogType_Info1))
|
||||
{
|
||||
DESTINATION = ILibDuktape_Console_LOG_Destination;
|
||||
}
|
||||
else
|
||||
{
|
||||
return(0);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
PREFIX = NULL;
|
||||
DESTINATION = ILibDuktape_Console_LOG_Destination;
|
||||
break;
|
||||
}
|
||||
duk_pop(ctx);
|
||||
|
||||
// Calculate total length of string
|
||||
for (i = 0; i < numargs; ++i)
|
||||
{
|
||||
if (duk_is_string(ctx, i))
|
||||
{
|
||||
printf("%s%s", (i == 0 ? "" : ", "), duk_require_string(ctx, i));
|
||||
len += (i == 0 ? 0 : 2);
|
||||
duk_get_lstring(ctx, i, &strLen);
|
||||
len += (int)strLen;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -286,24 +344,140 @@ duk_ret_t ILibDuktape_Polyfills_Console_log(duk_context *ctx)
|
||||
{
|
||||
duk_pop(ctx);
|
||||
duk_dup(ctx, i);
|
||||
printf("%s", (i == 0 ? "{" : ", {"));
|
||||
len += (i == 0 ? 1 : 3);
|
||||
duk_enum(ctx, -1, DUK_ENUM_OWN_PROPERTIES_ONLY);
|
||||
int propNum = 0;
|
||||
while (duk_next(ctx, -1, 1))
|
||||
{
|
||||
printf("%s%s: %s", ((propNum++ == 0) ? " " : ", "), (char*)duk_to_string(ctx, -2), (char*)duk_to_string(ctx, -1));
|
||||
len += 2;
|
||||
len += (propNum++ == 0 ? 1 : 2);
|
||||
duk_to_lstring(ctx, -2, &strLen); len += (int)strLen;
|
||||
duk_to_lstring(ctx, -1, &strLen); len += (int)strLen;
|
||||
duk_pop_2(ctx);
|
||||
}
|
||||
duk_pop(ctx);
|
||||
printf(" }");
|
||||
len += 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("%s%s", (i == 0 ? "" : ", "), duk_to_string(ctx, -1));
|
||||
len += (i == 0 ? 0 : 2);
|
||||
duk_get_lstring(ctx, -1, &strLen); len += (int)strLen;
|
||||
}
|
||||
}
|
||||
}
|
||||
printf("\n");
|
||||
len += 2; // NULL Terminator and final carriage return
|
||||
strLen = len;
|
||||
|
||||
str = ILibMemory_AllocateA(strLen + ((PREFIX != NULL) ? strnlen_s(PREFIX, 9) : 0));
|
||||
x = (int)(ILibMemory_AllocateA_Size(str) - strLen);
|
||||
if (x != 0)
|
||||
{
|
||||
strLen += sprintf_s(str, strLen, PREFIX);
|
||||
}
|
||||
for (i = 0; i < numargs; ++i)
|
||||
{
|
||||
if (duk_is_string(ctx, i))
|
||||
{
|
||||
x += sprintf_s(str + x, strLen - x, "%s%s", (i == 0 ? "" : ", "), duk_require_string(ctx, i));
|
||||
}
|
||||
else
|
||||
{
|
||||
duk_dup(ctx, i);
|
||||
if (strcmp("[object Object]", duk_to_string(ctx, -1)) == 0)
|
||||
{
|
||||
duk_pop(ctx);
|
||||
duk_dup(ctx, i);
|
||||
x += sprintf_s(str+x, strLen - x, "%s", (i == 0 ? "{" : ", {"));
|
||||
duk_enum(ctx, -1, DUK_ENUM_OWN_PROPERTIES_ONLY);
|
||||
int propNum = 0;
|
||||
while (duk_next(ctx, -1, 1))
|
||||
{
|
||||
x += sprintf_s(str + x, strLen - x, "%s%s: %s", ((propNum++ == 0) ? " " : ", "), (char*)duk_to_string(ctx, -2), (char*)duk_to_string(ctx, -1));
|
||||
duk_pop_2(ctx);
|
||||
}
|
||||
duk_pop(ctx);
|
||||
x += sprintf_s(str + x, strLen - x, " }");
|
||||
}
|
||||
else
|
||||
{
|
||||
x += sprintf_s(str + x, strLen - x, "%s%s", (i == 0 ? "" : ", "), duk_to_string(ctx, -1));
|
||||
}
|
||||
}
|
||||
}
|
||||
x += sprintf_s(str + x, strLen - x, "\n");
|
||||
|
||||
duk_push_this(ctx); // [console]
|
||||
int dest = Duktape_GetIntPropertyValue(ctx, -1, DESTINATION, ILibDuktape_Console_DestinationFlags_StdOut);
|
||||
|
||||
if ((dest & ILibDuktape_Console_DestinationFlags_StdOut) == ILibDuktape_Console_DestinationFlags_StdOut)
|
||||
{
|
||||
#ifdef WIN32
|
||||
DWORD writeLen;
|
||||
WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), (void*)str, x, &writeLen, NULL);
|
||||
#else
|
||||
ignore_result(write(STDOUT_FILENO, str, x));
|
||||
#endif
|
||||
}
|
||||
if ((dest & ILibDuktape_Console_DestinationFlags_WebLog) == ILibDuktape_Console_DestinationFlags_WebLog)
|
||||
{
|
||||
ILibRemoteLogging_printf(ILibChainGetLogger(Duktape_GetChain(ctx)), ILibRemoteLogging_Modules_Microstack_Generic, ILibRemoteLogging_Flags_VerbosityLevel_1, "%s", str);
|
||||
}
|
||||
if ((dest & ILibDuktape_Console_DestinationFlags_ServerConsole) == ILibDuktape_Console_DestinationFlags_ServerConsole)
|
||||
{
|
||||
if (duk_peval_string(ctx, "require('MeshAgent');") == 0)
|
||||
{
|
||||
duk_get_prop_string(ctx, -1, "SendCommand"); // [console][agent][SendCommand]
|
||||
duk_swap_top(ctx, -2); // [console][SendCommand][this]
|
||||
duk_push_object(ctx); // [console][SendCommand][this][options]
|
||||
duk_push_string(ctx, "msg"); duk_put_prop_string(ctx, -2, "action");
|
||||
duk_push_string(ctx, "console"); duk_put_prop_string(ctx, -2, "type");
|
||||
duk_push_string(ctx, str); duk_put_prop_string(ctx, -2, "value");
|
||||
if (duk_has_prop_string(ctx, -4, ILibDuktape_Console_SessionID))
|
||||
{
|
||||
duk_get_prop_string(ctx, -4, ILibDuktape_Console_SessionID);
|
||||
duk_put_prop_string(ctx, -2, "sessionid");
|
||||
}
|
||||
duk_call_method(ctx, 1);
|
||||
}
|
||||
}
|
||||
if ((dest & ILibDuktape_Console_DestinationFlags_LogFile) == ILibDuktape_Console_DestinationFlags_LogFile)
|
||||
{
|
||||
duk_size_t pathLen;
|
||||
char *path;
|
||||
char *tmp = ILibMemory_AllocateA(x + 32);
|
||||
int tmpx = ILibGetLocalTime(tmp + 1, (int)ILibMemory_AllocateA_Size(tmp) - 1) + 1;
|
||||
tmp[0] = '[';
|
||||
tmp[tmpx] = ']';
|
||||
tmp[tmpx + 1] = ':';
|
||||
tmp[tmpx + 2] = ' ';
|
||||
memcpy_s(tmp + tmpx + 3, ILibMemory_AllocateA_Size(tmp) - tmpx - 3, str, x);
|
||||
duk_eval_string(ctx, "require('fs');");
|
||||
duk_get_prop_string(ctx, -1, "writeFileSync"); // [fs][writeFileSync]
|
||||
duk_swap_top(ctx, -2); // [writeFileSync][this]
|
||||
duk_push_heapptr(ctx, ILibDuktape_GetProcessObject(ctx)); // [writeFileSync][this][process]
|
||||
duk_get_prop_string(ctx, -1, "execPath"); // [writeFileSync][this][process][execPath]
|
||||
path = (char*)duk_get_lstring(ctx, -1, &pathLen);
|
||||
if (path != NULL)
|
||||
{
|
||||
if (ILibString_EndsWithEx(path, (int)pathLen, ".exe", 4, 0))
|
||||
{
|
||||
duk_get_prop_string(ctx, -1, "substring"); // [writeFileSync][this][process][execPath][substring]
|
||||
duk_swap_top(ctx, -2); // [writeFileSync][this][process][substring][this]
|
||||
duk_push_int(ctx, 0); // [writeFileSync][this][process][substring][this][0]
|
||||
duk_push_int(ctx, (int)(pathLen - 4)); // [writeFileSync][this][process][substring][this][0][len]
|
||||
duk_call_method(ctx, 2); // [writeFileSync][this][process][path]
|
||||
}
|
||||
duk_get_prop_string(ctx, -1, "concat"); // [writeFileSync][this][process][path][concat]
|
||||
duk_swap_top(ctx, -2); // [writeFileSync][this][process][concat][this]
|
||||
duk_push_string(ctx, ".jlog"); // [writeFileSync][this][process][concat][this][.jlog]
|
||||
duk_call_method(ctx, 1); // [writeFileSync][this][process][logPath]
|
||||
duk_remove(ctx, -2); // [writeFileSync][this][logPath]
|
||||
duk_push_string(ctx, tmp); // [writeFileSync][this][logPath][log]
|
||||
duk_push_object(ctx); // [writeFileSync][this][logPath][log][options]
|
||||
duk_push_string(ctx, "a"); duk_put_prop_string(ctx, -2, "flags");
|
||||
duk_call_method(ctx, 3);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
duk_ret_t ILibDuktape_Polyfills_Console_enableWebLog(duk_context *ctx)
|
||||
@@ -357,9 +531,49 @@ duk_ret_t ILibDuktape_Polyfills_Console_logRefCount(duk_context *ctx)
|
||||
printf("Reference Count => %s[%p]:%d\n", Duktape_GetStringPropertyValue(ctx, 0, ILibDuktape_OBJID, "UNKNOWN"), duk_require_heapptr(ctx, 0), ILibDuktape_GetReferenceCount(ctx, 0) - 1);
|
||||
return(0);
|
||||
}
|
||||
duk_ret_t ILibDuktape_Polyfills_Console_setDestination(duk_context *ctx)
|
||||
{
|
||||
int nargs = duk_get_top(ctx);
|
||||
int dest = duk_require_int(ctx, 0);
|
||||
|
||||
duk_push_this(ctx); // console
|
||||
if ((dest & ILibDuktape_Console_DestinationFlags_ServerConsole) == ILibDuktape_Console_DestinationFlags_ServerConsole)
|
||||
{
|
||||
// Mesh Server Console
|
||||
if (duk_peval_string(ctx, "require('MeshAgent');") != 0) { return(ILibDuktape_Error(ctx, "Unable to set destination to Mesh Console ")); }
|
||||
duk_pop(ctx);
|
||||
if (nargs > 1)
|
||||
{
|
||||
duk_dup(ctx, 1);
|
||||
duk_put_prop_string(ctx, -2, ILibDuktape_Console_SessionID);
|
||||
}
|
||||
else
|
||||
{
|
||||
duk_del_prop_string(ctx, -1, ILibDuktape_Console_SessionID);
|
||||
}
|
||||
}
|
||||
duk_dup(ctx, 0);
|
||||
duk_put_prop_string(ctx, -2, ILibDuktape_Console_Destination);
|
||||
return(0);
|
||||
}
|
||||
duk_ret_t ILibDuktape_Polyfills_Console_setInfoLevel(duk_context *ctx)
|
||||
{
|
||||
int val = duk_require_int(ctx, 0);
|
||||
if (val < 0) { return(ILibDuktape_Error(ctx, "Invalid Info Level: %d", val)); }
|
||||
|
||||
duk_push_this(ctx);
|
||||
duk_push_int(ctx, val);
|
||||
duk_put_prop_string(ctx, -2, ILibDuktape_Console_INFO_Level);
|
||||
|
||||
return(0);
|
||||
}
|
||||
void ILibDuktape_Polyfills_Console(duk_context *ctx)
|
||||
{
|
||||
// Polyfill console.log()
|
||||
#ifdef WIN32
|
||||
SetConsoleOutputCP(CP_UTF8);
|
||||
#endif
|
||||
|
||||
if (duk_has_prop_string(ctx, -1, "console"))
|
||||
{
|
||||
duk_get_prop_string(ctx, -1, "console"); // [g][console]
|
||||
@@ -371,11 +585,38 @@ void ILibDuktape_Polyfills_Console(duk_context *ctx)
|
||||
duk_put_prop_string(ctx, -3, "console"); // [g][console]
|
||||
}
|
||||
|
||||
ILibDuktape_CreateInstanceMethod(ctx, "log", ILibDuktape_Polyfills_Console_log, DUK_VARARGS);
|
||||
ILibDuktape_CreateInstanceMethodWithIntProperty(ctx, "logType", (int)ILibDuktape_LogType_Normal, "log", ILibDuktape_Polyfills_Console_log, DUK_VARARGS);
|
||||
ILibDuktape_CreateInstanceMethodWithIntProperty(ctx, "logType", (int)ILibDuktape_LogType_Warn, "warn", ILibDuktape_Polyfills_Console_log, DUK_VARARGS);
|
||||
ILibDuktape_CreateInstanceMethodWithIntProperty(ctx, "logType", (int)ILibDuktape_LogType_Error, "error", ILibDuktape_Polyfills_Console_log, DUK_VARARGS);
|
||||
ILibDuktape_CreateInstanceMethodWithIntProperty(ctx, "logType", (int)ILibDuktape_LogType_Info1, "info1", ILibDuktape_Polyfills_Console_log, DUK_VARARGS);
|
||||
ILibDuktape_CreateInstanceMethodWithIntProperty(ctx, "logType", (int)ILibDuktape_LogType_Info2, "info2", ILibDuktape_Polyfills_Console_log, DUK_VARARGS);
|
||||
ILibDuktape_CreateInstanceMethodWithIntProperty(ctx, "logType", (int)ILibDuktape_LogType_Info3, "info3", ILibDuktape_Polyfills_Console_log, DUK_VARARGS);
|
||||
|
||||
|
||||
ILibDuktape_CreateInstanceMethod(ctx, "enableWebLog", ILibDuktape_Polyfills_Console_enableWebLog, 1);
|
||||
ILibDuktape_CreateEventWithGetterAndSetterEx(ctx, "displayStreamPipeMessages", ILibDuktape_Polyfills_Console_displayStreamPipe_getter, ILibDuktape_Polyfills_Console_displayStreamPipe_setter);
|
||||
ILibDuktape_CreateEventWithGetterAndSetterEx(ctx, "displayFinalizerMessages", ILibDuktape_Polyfills_Console_displayFinalizer_getter, ILibDuktape_Polyfills_Console_displayFinalizer_setter);
|
||||
ILibDuktape_CreateInstanceMethod(ctx, "logReferenceCount", ILibDuktape_Polyfills_Console_logRefCount, 1);
|
||||
|
||||
ILibDuktape_CreateInstanceMethod(ctx, "setDestination", ILibDuktape_Polyfills_Console_setDestination, DUK_VARARGS);
|
||||
ILibDuktape_CreateInstanceMethod(ctx, "setInfoLevel", ILibDuktape_Polyfills_Console_setInfoLevel, 1);
|
||||
|
||||
duk_push_object(ctx);
|
||||
duk_push_int(ctx, ILibDuktape_Console_DestinationFlags_DISABLED); duk_put_prop_string(ctx, -2, "DISABLED");
|
||||
duk_push_int(ctx, ILibDuktape_Console_DestinationFlags_StdOut); duk_put_prop_string(ctx, -2, "STDOUT");
|
||||
duk_push_int(ctx, ILibDuktape_Console_DestinationFlags_ServerConsole); duk_put_prop_string(ctx, -2, "SERVERCONSOLE");
|
||||
duk_push_int(ctx, ILibDuktape_Console_DestinationFlags_WebLog); duk_put_prop_string(ctx, -2, "WEBLOG");
|
||||
duk_push_int(ctx, ILibDuktape_Console_DestinationFlags_LogFile); duk_put_prop_string(ctx, -2, "LOGFILE");
|
||||
ILibDuktape_CreateReadonlyProperty(ctx, "Destinations");
|
||||
|
||||
duk_push_int(ctx, ILibDuktape_Console_DestinationFlags_StdOut | ILibDuktape_Console_DestinationFlags_LogFile);
|
||||
duk_put_prop_string(ctx, -2, ILibDuktape_Console_ERROR_Destination);
|
||||
|
||||
duk_push_int(ctx, ILibDuktape_Console_DestinationFlags_StdOut | ILibDuktape_Console_DestinationFlags_LogFile);
|
||||
duk_put_prop_string(ctx, -2, ILibDuktape_Console_WARN_Destination);
|
||||
|
||||
duk_push_int(ctx, 0); duk_put_prop_string(ctx, -2, ILibDuktape_Console_INFO_Level);
|
||||
|
||||
duk_pop(ctx); // [g]
|
||||
}
|
||||
duk_ret_t ILibDuktape_ntohl(duk_context *ctx)
|
||||
@@ -448,18 +689,21 @@ duk_ret_t ILibDuktape_Polyfills_timer_finalizer(duk_context *ctx)
|
||||
{
|
||||
// Make sure we remove any timers just in case, so we don't leak resources
|
||||
ILibDuktape_Timer *ptrs;
|
||||
duk_get_prop_string(ctx, 0, ILibDuktape_Timer_Ptrs);
|
||||
if (duk_has_prop_string(ctx, 0, "\xFF_callback"))
|
||||
if (duk_has_prop_string(ctx, 0, ILibDuktape_Timer_Ptrs))
|
||||
{
|
||||
duk_del_prop_string(ctx, 0, "\xFF_callback");
|
||||
}
|
||||
if (duk_has_prop_string(ctx, 0, "\xFF_argArray"))
|
||||
{
|
||||
duk_del_prop_string(ctx, 0, "\xFF_argArray");
|
||||
}
|
||||
ptrs = (ILibDuktape_Timer*)Duktape_GetBuffer(ctx, -1, NULL);
|
||||
duk_get_prop_string(ctx, 0, ILibDuktape_Timer_Ptrs);
|
||||
if (duk_has_prop_string(ctx, 0, "\xFF_callback"))
|
||||
{
|
||||
duk_del_prop_string(ctx, 0, "\xFF_callback");
|
||||
}
|
||||
if (duk_has_prop_string(ctx, 0, "\xFF_argArray"))
|
||||
{
|
||||
duk_del_prop_string(ctx, 0, "\xFF_argArray");
|
||||
}
|
||||
ptrs = (ILibDuktape_Timer*)Duktape_GetBuffer(ctx, -1, NULL);
|
||||
|
||||
ILibLifeTime_Remove(ILibGetBaseTimer(Duktape_GetChain(ctx)), ptrs);
|
||||
ILibLifeTime_Remove(ILibGetBaseTimer(Duktape_GetChain(ctx)), ptrs);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
void ILibDuktape_Polyfills_timer_elapsed(void *obj)
|
||||
@@ -467,8 +711,10 @@ void ILibDuktape_Polyfills_timer_elapsed(void *obj)
|
||||
ILibDuktape_Timer *ptrs = (ILibDuktape_Timer*)obj;
|
||||
int argCount, i;
|
||||
duk_context *ctx = ptrs->ctx;
|
||||
char *funcName;
|
||||
|
||||
duk_push_heapptr(ctx, ptrs->callback); // [func]
|
||||
funcName = Duktape_GetStringPropertyValue(ctx, -1, "name", "unknown_method");
|
||||
duk_push_heapptr(ctx, ptrs->object); // [func][this]
|
||||
duk_push_heapptr(ctx, ptrs->args); // [func][this][argArray]
|
||||
|
||||
@@ -480,6 +726,7 @@ void ILibDuktape_Polyfills_timer_elapsed(void *obj)
|
||||
{
|
||||
duk_del_prop_string(ctx, -2, "\xFF_callback");
|
||||
duk_del_prop_string(ctx, -2, "\xFF_argArray");
|
||||
duk_del_prop_string(ctx, -2, ILibDuktape_Timer_Ptrs);
|
||||
}
|
||||
|
||||
argCount = (int)duk_get_length(ctx, -1);
|
||||
@@ -489,7 +736,7 @@ void ILibDuktape_Polyfills_timer_elapsed(void *obj)
|
||||
duk_swap_top(ctx, -2); // [func][this][arg][argArray]
|
||||
}
|
||||
duk_pop(ctx); // [func][this][...arg...]
|
||||
if (duk_pcall_method(ctx, argCount) != 0) { ILibDuktape_Process_UncaughtExceptionEx(ctx, "timers.onElapsed() callback handler"); }
|
||||
if (duk_pcall_method(ctx, argCount) != 0) { ILibDuktape_Process_UncaughtExceptionEx(ctx, "timers.onElapsed() callback handler on '%s()' ", funcName); }
|
||||
duk_pop(ctx); // ...
|
||||
}
|
||||
duk_ret_t ILibDuktape_Polyfills_timer_set(duk_context *ctx)
|
||||
@@ -582,7 +829,14 @@ void ILibDuktape_Polyfills_timer(duk_context *ctx)
|
||||
ILibDuktape_CreateInstanceMethodWithIntProperty(ctx, "type", ILibDuktape_Timer_Type_INTERVAL, "clearInterval", ILibDuktape_Polyfills_timer_clear, 1);
|
||||
ILibDuktape_CreateInstanceMethodWithIntProperty(ctx, "type", ILibDuktape_Timer_Type_IMMEDIATE, "clearImmediate", ILibDuktape_Polyfills_timer_clear, 1);
|
||||
}
|
||||
|
||||
duk_ret_t ILibDuktape_Polyfills_getJSModule(duk_context *ctx)
|
||||
{
|
||||
if (ILibDuktape_ModSearch_GetJSModule(ctx, (char*)duk_require_string(ctx, 0)) == 0)
|
||||
{
|
||||
return(ILibDuktape_Error(ctx, "getJSModule(): (%s) not found", (char*)duk_require_string(ctx, 0)));
|
||||
}
|
||||
return(1);
|
||||
}
|
||||
duk_ret_t ILibDuktape_Polyfills_addModule(duk_context *ctx)
|
||||
{
|
||||
duk_size_t moduleLen;
|
||||
@@ -595,6 +849,14 @@ duk_ret_t ILibDuktape_Polyfills_addModule(duk_context *ctx)
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
duk_ret_t ILibDuktape_Polyfills_addModuleObject(duk_context *ctx)
|
||||
{
|
||||
void *module = duk_require_heapptr(ctx, 1);
|
||||
char *moduleName = (char*)duk_require_string(ctx, 0);
|
||||
|
||||
ILibDuktape_ModSearch_AddModuleObject(ctx, moduleName, module);
|
||||
return(0);
|
||||
}
|
||||
duk_ret_t ILibDuktape_Queue_Finalizer(duk_context *ctx)
|
||||
{
|
||||
duk_get_prop_string(ctx, 0, ILibDuktape_Queue_Ptr);
|
||||
@@ -645,7 +907,12 @@ duk_ret_t ILibDuktape_Queue_DeQueue(duk_context *ctx)
|
||||
if (peek == 0) { duk_del_prop_string(ctx, -length - 2, Duktape_GetStashKey(h)); }
|
||||
return(length);
|
||||
}
|
||||
|
||||
duk_ret_t ILibDuktape_Queue_isEmpty(duk_context *ctx)
|
||||
{
|
||||
duk_push_this(ctx);
|
||||
duk_push_boolean(ctx, ILibQueue_IsEmpty((ILibQueue)Duktape_GetPointerProperty(ctx, -1, ILibDuktape_Queue_Ptr)));
|
||||
return(1);
|
||||
}
|
||||
duk_ret_t ILibDuktape_Queue_new(duk_context *ctx)
|
||||
{
|
||||
duk_push_object(ctx); // [queue]
|
||||
@@ -656,6 +923,7 @@ duk_ret_t ILibDuktape_Queue_new(duk_context *ctx)
|
||||
ILibDuktape_CreateInstanceMethod(ctx, "enQueue", ILibDuktape_Queue_EnQueue, DUK_VARARGS);
|
||||
ILibDuktape_CreateInstanceMethodWithIntProperty(ctx, "peek", 0, "deQueue", ILibDuktape_Queue_DeQueue, DUK_VARARGS);
|
||||
ILibDuktape_CreateInstanceMethodWithIntProperty(ctx, "peek", 1, "peekQueue", ILibDuktape_Queue_DeQueue, DUK_VARARGS);
|
||||
ILibDuktape_CreateInstanceMethod(ctx, "isEmpty", ILibDuktape_Queue_isEmpty, 0);
|
||||
|
||||
return(1);
|
||||
}
|
||||
@@ -687,7 +955,7 @@ ILibTransport_DoneState ILibDuktape_DynamicBuffer_WriteSink(ILibDuktape_DuplexSt
|
||||
void ILibDuktape_DynamicBuffer_WriteSink_ChainThread(void *chain, void *user)
|
||||
{
|
||||
ILibDuktape_DynamicBuffer_ContextSwitchData *data = (ILibDuktape_DynamicBuffer_ContextSwitchData*)user;
|
||||
if (ILibDuktape_IsPointerValid(chain, data->heapptr) != 0)
|
||||
if(ILibMemory_CanaryOK(data->stream))
|
||||
{
|
||||
ILibDuktape_DynamicBuffer_WriteSink(data->stream, data->buffer, data->bufferLen, data->data);
|
||||
ILibDuktape_DuplexStream_Ready(data->stream);
|
||||
@@ -727,7 +995,7 @@ ILibTransport_DoneState ILibDuktape_DynamicBuffer_WriteSink(ILibDuktape_DuplexSt
|
||||
{
|
||||
tmpSize += 4096;
|
||||
}
|
||||
data->buffer = (char*)realloc(data->buffer, tmpSize);
|
||||
if ((data->buffer = (char*)realloc(data->buffer, tmpSize)) == NULL) { ILIBCRITICALEXIT(254); }
|
||||
data->bufferLen = tmpSize;
|
||||
}
|
||||
}
|
||||
@@ -772,7 +1040,6 @@ void ILibDuktape_DynamicBuffer_EndSink(ILibDuktape_DuplexStream *stream, void *u
|
||||
}
|
||||
duk_ret_t ILibDuktape_DynamicBuffer_Finalizer(duk_context *ctx)
|
||||
{
|
||||
ILibDuktape_InValidateHeapPointer(ctx, 0);
|
||||
duk_get_prop_string(ctx, 0, "\xFF_buffer");
|
||||
ILibDuktape_DynamicBuffer_data *data = (ILibDuktape_DynamicBuffer_data*)Duktape_GetBuffer(ctx, -1, NULL);
|
||||
free(data->buffer);
|
||||
@@ -818,7 +1085,6 @@ duk_ret_t ILibDuktape_DynamicBuffer_new(duk_context *ctx)
|
||||
ILibDuktape_EventEmitter_CreateEventEx(ILibDuktape_EventEmitter_GetEmitter(ctx, -1), "readable");
|
||||
ILibDuktape_CreateInstanceMethod(ctx, "read", ILibDuktape_DynamicBuffer_read, DUK_VARARGS);
|
||||
ILibDuktape_CreateFinalizer(ctx, ILibDuktape_DynamicBuffer_Finalizer);
|
||||
ILibDuktape_ValidateHeapPointer(ctx, -1);
|
||||
|
||||
return(1);
|
||||
}
|
||||
@@ -934,11 +1200,9 @@ duk_ret_t ILibDuktape_Stream_Push(duk_context *ctx)
|
||||
{
|
||||
duk_push_this(ctx); // [stream]
|
||||
ILibDuktape_readableStream *RS = (ILibDuktape_readableStream*)Duktape_GetPointerProperty(ctx, -1, ILibDuktape_Stream_ReadablePtr);
|
||||
duk_get_prop_string(ctx, -1, ILibDuktape_Stream_Buffer); // [stream][buffer]
|
||||
duk_del_prop_string(ctx, -2, ILibDuktape_Stream_Buffer); // (Deleting here, because unshift will save it again, if necessary)
|
||||
|
||||
duk_size_t bufferLen;
|
||||
char *buffer = (char*)Duktape_GetBuffer(ctx, -1, &bufferLen);
|
||||
char *buffer = (char*)Duktape_GetBuffer(ctx, 0, &bufferLen);
|
||||
|
||||
duk_push_boolean(ctx, !ILibDuktape_readableStream_WriteDataEx(RS, 0, buffer, (int)bufferLen)); // [stream][buffer][retVal]
|
||||
return(1);
|
||||
@@ -970,11 +1234,148 @@ duk_idx_t ILibDuktape_Stream_newReadable(duk_context *ctx)
|
||||
}
|
||||
return(1);
|
||||
}
|
||||
duk_ret_t ILibDuktape_Stream_Writable_WriteSink_Flush(duk_context *ctx)
|
||||
{
|
||||
duk_push_current_function(ctx);
|
||||
ILibTransport_DoneState *retVal = (ILibTransport_DoneState*)Duktape_GetPointerProperty(ctx, -1, "retval");
|
||||
if (retVal != NULL)
|
||||
{
|
||||
*retVal = ILibTransport_DoneState_COMPLETE;
|
||||
}
|
||||
else
|
||||
{
|
||||
duk_push_this(ctx);
|
||||
ILibDuktape_WritableStream *WS = (ILibDuktape_WritableStream*)Duktape_GetPointerProperty(ctx, -1, ILibDuktape_Stream_WritablePtr);
|
||||
ILibDuktape_WritableStream_Ready(WS);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
ILibTransport_DoneState ILibDuktape_Stream_Writable_WriteSink(struct ILibDuktape_WritableStream *stream, char *buffer, int bufferLen, void *user)
|
||||
{
|
||||
void *h;
|
||||
ILibTransport_DoneState retVal = ILibTransport_DoneState_INCOMPLETE;
|
||||
|
||||
duk_push_this(stream->ctx); // [writable]
|
||||
duk_get_prop_string(stream->ctx, -1, "_write"); // [writable][_write]
|
||||
duk_swap_top(stream->ctx, -2); // [_write][this]
|
||||
if (stream->Reserved)
|
||||
{
|
||||
duk_push_external_buffer(stream->ctx); // [_write][this][extBuffer]
|
||||
duk_insert(stream->ctx, -3); // [extBuffer][_write][this]
|
||||
duk_config_buffer(stream->ctx, -3, buffer, (duk_size_t)bufferLen);
|
||||
duk_push_buffer_object(stream->ctx, -3, 0, (duk_size_t)bufferLen, DUK_BUFOBJ_NODEJS_BUFFER);// [extBuffer][_write][this][buffer]
|
||||
}
|
||||
else
|
||||
{
|
||||
duk_push_lstring(stream->ctx, buffer, (duk_size_t)bufferLen); // [_write][this][string]
|
||||
}
|
||||
duk_push_c_function(stream->ctx, ILibDuktape_Stream_Writable_WriteSink_Flush, DUK_VARARGS); // [_write][this][string/buffer][callback]
|
||||
h = duk_get_heapptr(stream->ctx, -1);
|
||||
duk_push_heap_stash(stream->ctx); // [_write][this][string/buffer][callback][stash]
|
||||
duk_dup(stream->ctx, -2); // [_write][this][string/buffer][callback][stash][callback]
|
||||
duk_put_prop_string(stream->ctx, -2, Duktape_GetStashKey(h)); // [_write][this][string/buffer][callback][stash]
|
||||
duk_pop(stream->ctx); // [_write][this][string/buffer][callback]
|
||||
|
||||
duk_push_pointer(stream->ctx, &retVal); // [_write][this][string/buffer][callback][retval]
|
||||
duk_put_prop_string(stream->ctx, -2, "retval"); // [_write][this][string/buffer][callback]
|
||||
if (duk_pcall_method(stream->ctx, 2) != 0)
|
||||
{
|
||||
ILibDuktape_Process_UncaughtExceptionEx(stream->ctx, "stream.writable.write(): "); retVal = ILibTransport_DoneState_ERROR;
|
||||
}
|
||||
duk_pop(stream->ctx); // ...
|
||||
|
||||
duk_push_heapptr(stream->ctx, h); // [callback]
|
||||
duk_del_prop_string(stream->ctx, -1, "retval");
|
||||
duk_pop(stream->ctx); // ...
|
||||
|
||||
duk_push_heap_stash(stream->ctx);
|
||||
duk_del_prop_string(stream->ctx, -1, Duktape_GetStashKey(h));
|
||||
duk_pop(stream->ctx);
|
||||
|
||||
return(retVal);
|
||||
}
|
||||
void ILibDuktape_Stream_Writable_EndSink(struct ILibDuktape_WritableStream *stream, void *user)
|
||||
{
|
||||
duk_push_this(stream->ctx); // [writable]
|
||||
duk_get_prop_string(stream->ctx, -1, "_final"); // [writable][_final]
|
||||
duk_swap_top(stream->ctx, -2); // [_final][this]
|
||||
if (duk_pcall_method(stream->ctx, 0) != 0) { ILibDuktape_Process_UncaughtExceptionEx(stream->ctx, "stream.writable._final(): "); }
|
||||
duk_pop(stream->ctx); // ...
|
||||
}
|
||||
duk_ret_t ILibDuktape_Stream_newWritable(duk_context *ctx)
|
||||
{
|
||||
ILibDuktape_WritableStream *WS;
|
||||
duk_push_object(ctx); // [Writable]
|
||||
ILibDuktape_WriteID(ctx, "stream.writable");
|
||||
WS = ILibDuktape_WritableStream_Init(ctx, ILibDuktape_Stream_Writable_WriteSink, ILibDuktape_Stream_Writable_EndSink, NULL);
|
||||
WS->JSCreated = 1;
|
||||
|
||||
duk_push_pointer(ctx, WS);
|
||||
duk_put_prop_string(ctx, -2, ILibDuktape_Stream_WritablePtr);
|
||||
|
||||
if (duk_is_object(ctx, 0))
|
||||
{
|
||||
void *h = Duktape_GetHeapptrProperty(ctx, 0, "write");
|
||||
if (h != NULL) { duk_push_heapptr(ctx, h); duk_put_prop_string(ctx, -2, "_write"); }
|
||||
h = Duktape_GetHeapptrProperty(ctx, 0, "final");
|
||||
if (h != NULL) { duk_push_heapptr(ctx, h); duk_put_prop_string(ctx, -2, "_final"); }
|
||||
}
|
||||
return(1);
|
||||
}
|
||||
void ILibDuktape_Stream_Duplex_PauseSink(ILibDuktape_DuplexStream *stream, void *user)
|
||||
{
|
||||
ILibDuktape_Stream_PauseSink(stream->readableStream, user);
|
||||
}
|
||||
void ILibDuktape_Stream_Duplex_ResumeSink(ILibDuktape_DuplexStream *stream, void *user)
|
||||
{
|
||||
ILibDuktape_Stream_ResumeSink(stream->readableStream, user);
|
||||
}
|
||||
int ILibDuktape_Stream_Duplex_UnshiftSink(ILibDuktape_DuplexStream *stream, int unshiftBytes, void *user)
|
||||
{
|
||||
return(ILibDuktape_Stream_UnshiftSink(stream->readableStream, unshiftBytes, user));
|
||||
}
|
||||
ILibTransport_DoneState ILibDuktape_Stream_Duplex_WriteSink(ILibDuktape_DuplexStream *stream, char *buffer, int bufferLen, void *user)
|
||||
{
|
||||
return(ILibDuktape_Stream_Writable_WriteSink(stream->writableStream, buffer, bufferLen, user));
|
||||
}
|
||||
void ILibDuktape_Stream_Duplex_EndSink(ILibDuktape_DuplexStream *stream, void *user)
|
||||
{
|
||||
ILibDuktape_Stream_Writable_EndSink(stream->writableStream, user);
|
||||
}
|
||||
duk_ret_t ILibDuktape_Stream_newDuplex(duk_context *ctx)
|
||||
{
|
||||
ILibDuktape_DuplexStream *DS;
|
||||
duk_push_object(ctx); // [Duplex]
|
||||
ILibDuktape_WriteID(ctx, "stream.Duplex");
|
||||
DS = ILibDuktape_DuplexStream_InitEx(ctx, ILibDuktape_Stream_Duplex_WriteSink, ILibDuktape_Stream_Duplex_EndSink, ILibDuktape_Stream_Duplex_PauseSink, ILibDuktape_Stream_Duplex_ResumeSink, ILibDuktape_Stream_Duplex_UnshiftSink, NULL);
|
||||
DS->writableStream->JSCreated = 1;
|
||||
|
||||
duk_push_pointer(ctx, DS->writableStream);
|
||||
duk_put_prop_string(ctx, -2, ILibDuktape_Stream_WritablePtr);
|
||||
|
||||
duk_push_pointer(ctx, DS->readableStream);
|
||||
duk_put_prop_string(ctx, -2, ILibDuktape_Stream_ReadablePtr);
|
||||
ILibDuktape_CreateInstanceMethod(ctx, "push", ILibDuktape_Stream_Push, DUK_VARARGS);
|
||||
ILibDuktape_EventEmitter_AddOnceEx3(ctx, -1, "end", ILibDuktape_Stream_EndSink);
|
||||
|
||||
if (duk_is_object(ctx, 0))
|
||||
{
|
||||
void *h = Duktape_GetHeapptrProperty(ctx, 0, "write");
|
||||
if (h != NULL) { duk_push_heapptr(ctx, h); duk_put_prop_string(ctx, -2, "_write"); }
|
||||
h = Duktape_GetHeapptrProperty(ctx, 0, "final");
|
||||
if (h != NULL) { duk_push_heapptr(ctx, h); duk_put_prop_string(ctx, -2, "_final"); }
|
||||
h = Duktape_GetHeapptrProperty(ctx, 0, "read");
|
||||
if (h != NULL) { duk_push_heapptr(ctx, h); duk_put_prop_string(ctx, -2, "_read"); }
|
||||
}
|
||||
return(1);
|
||||
}
|
||||
void ILibDuktape_Stream_Init(duk_context *ctx, void *chain)
|
||||
{
|
||||
duk_push_object(ctx); // [stream
|
||||
ILibDuktape_WriteID(ctx, "stream");
|
||||
ILibDuktape_CreateInstanceMethod(ctx, "Readable", ILibDuktape_Stream_newReadable, DUK_VARARGS);
|
||||
ILibDuktape_CreateInstanceMethod(ctx, "Writable", ILibDuktape_Stream_newWritable, DUK_VARARGS);
|
||||
ILibDuktape_CreateInstanceMethod(ctx, "Duplex", ILibDuktape_Stream_newDuplex, DUK_VARARGS);
|
||||
}
|
||||
void ILibDuktape_Polyfills_debugGC2(duk_context *ctx, void ** args, int argsLen)
|
||||
{
|
||||
@@ -996,11 +1397,157 @@ duk_ret_t ILibDuktape_Polyfills_debug(duk_context *ctx)
|
||||
#endif
|
||||
return(0);
|
||||
}
|
||||
#ifndef MICROSTACK_NOTLS
|
||||
duk_ret_t ILibDuktape_PKCS7_getSignedDataBlock(duk_context *ctx)
|
||||
{
|
||||
char *hash = ILibMemory_AllocateA(UTIL_SHA256_HASHSIZE);
|
||||
char *pkeyHash = ILibMemory_AllocateA(UTIL_SHA256_HASHSIZE);
|
||||
unsigned int size, r;
|
||||
BIO *out = NULL;
|
||||
PKCS7 *message = NULL;
|
||||
char* data2 = NULL;
|
||||
STACK_OF(X509) *st = NULL;
|
||||
|
||||
duk_size_t bufferLen;
|
||||
char *buffer = Duktape_GetBuffer(ctx, 0, &bufferLen);
|
||||
|
||||
message = d2i_PKCS7(NULL, (const unsigned char**)&buffer, (long)bufferLen);
|
||||
if (message == NULL) { return(ILibDuktape_Error(ctx, "PKCS7 Error")); }
|
||||
|
||||
// Lets rebuild the original message and check the size
|
||||
size = i2d_PKCS7(message, NULL);
|
||||
if (size < (unsigned int)bufferLen) { PKCS7_free(message); return(ILibDuktape_Error(ctx, "PKCS7 Error")); }
|
||||
|
||||
out = BIO_new(BIO_s_mem());
|
||||
|
||||
// Check the PKCS7 signature, but not the certificate chain.
|
||||
r = PKCS7_verify(message, NULL, NULL, NULL, out, PKCS7_NOVERIFY);
|
||||
if (r == 0) { PKCS7_free(message); BIO_free(out); return(ILibDuktape_Error(ctx, "PKCS7 Verify Error")); }
|
||||
|
||||
// If data block contains less than 32 bytes, fail.
|
||||
size = (unsigned int)BIO_get_mem_data(out, &data2);
|
||||
if (size <= ILibMemory_AllocateA_Size(hash)) { PKCS7_free(message); BIO_free(out); return(ILibDuktape_Error(ctx, "PKCS7 Size Mismatch Error")); }
|
||||
|
||||
|
||||
duk_push_object(ctx); // [val]
|
||||
duk_push_fixed_buffer(ctx, size); // [val][fbuffer]
|
||||
duk_dup(ctx, -1); // [val][fbuffer][dup]
|
||||
duk_put_prop_string(ctx, -3, "\xFF_fixedbuffer"); // [val][fbuffer]
|
||||
duk_swap_top(ctx, -2); // [fbuffer][val]
|
||||
duk_push_buffer_object(ctx, -2, 0, size, DUK_BUFOBJ_NODEJS_BUFFER); // [fbuffer][val][buffer]
|
||||
ILibDuktape_CreateReadonlyProperty(ctx, "data"); // [fbuffer][val]
|
||||
memcpy_s(Duktape_GetBuffer(ctx, -2, NULL), size, data2, size);
|
||||
|
||||
|
||||
// Get the certificate signer
|
||||
st = PKCS7_get0_signers(message, NULL, PKCS7_NOVERIFY);
|
||||
|
||||
// Get a full certificate hash of the signer
|
||||
X509_digest(sk_X509_value(st, 0), EVP_sha256(), (unsigned char*)hash, NULL);
|
||||
X509_pubkey_digest(sk_X509_value(st, 0), EVP_sha256(), (unsigned char*)pkeyHash, NULL);
|
||||
|
||||
sk_X509_free(st);
|
||||
|
||||
// Check certificate hash with first 32 bytes of data.
|
||||
if (memcmp(hash, Duktape_GetBuffer(ctx, -2, NULL), ILibMemory_AllocateA_Size(hash)) != 0) { PKCS7_free(message); BIO_free(out); return(ILibDuktape_Error(ctx, "PKCS7 Certificate Hash Mismatch Error")); }
|
||||
char *tmp = ILibMemory_AllocateA(1 + (ILibMemory_AllocateA_Size(hash) * 2));
|
||||
util_tohex(hash, (int)ILibMemory_AllocateA_Size(hash), tmp);
|
||||
duk_push_object(ctx); // [fbuffer][val][cert]
|
||||
ILibDuktape_WriteID(ctx, "certificate");
|
||||
duk_push_string(ctx, tmp); // [fbuffer][val][cert][fingerprint]
|
||||
ILibDuktape_CreateReadonlyProperty(ctx, "fingerprint"); // [fbuffer][val][cert]
|
||||
util_tohex(pkeyHash, (int)ILibMemory_AllocateA_Size(pkeyHash), tmp);
|
||||
duk_push_string(ctx, tmp); // [fbuffer][val][cert][publickeyhash]
|
||||
ILibDuktape_CreateReadonlyProperty(ctx, "publicKeyHash"); // [fbuffer][val][cert]
|
||||
|
||||
ILibDuktape_CreateReadonlyProperty(ctx, "signingCertificate"); // [fbuffer][val]
|
||||
|
||||
// Approved, cleanup and return.
|
||||
BIO_free(out);
|
||||
PKCS7_free(message);
|
||||
|
||||
return(1);
|
||||
}
|
||||
duk_ret_t ILibDuktape_PKCS7_signDataBlockFinalizer(duk_context *ctx)
|
||||
{
|
||||
char *buffer = Duktape_GetPointerProperty(ctx, 0, "\xFF_signature");
|
||||
if (buffer != NULL) { free(buffer); }
|
||||
return(0);
|
||||
}
|
||||
duk_ret_t ILibDuktape_PKCS7_signDataBlock(duk_context *ctx)
|
||||
{
|
||||
duk_get_prop_string(ctx, 1, "secureContext");
|
||||
duk_get_prop_string(ctx, -1, "\xFF_SecureContext2CertBuffer");
|
||||
struct util_cert *cert = (struct util_cert*)Duktape_GetBuffer(ctx, -1, NULL);
|
||||
duk_size_t bufferLen;
|
||||
char *buffer = (char*)Duktape_GetBuffer(ctx, 0, &bufferLen);
|
||||
|
||||
BIO *in = NULL;
|
||||
PKCS7 *message = NULL;
|
||||
char *signature = NULL;
|
||||
int signatureLength = 0;
|
||||
|
||||
// Sign the block
|
||||
in = BIO_new_mem_buf(buffer, (int)bufferLen);
|
||||
message = PKCS7_sign(cert->x509, cert->pkey, NULL, in, PKCS7_BINARY);
|
||||
if (message != NULL)
|
||||
{
|
||||
signatureLength = i2d_PKCS7(message, (unsigned char**)&signature);
|
||||
PKCS7_free(message);
|
||||
}
|
||||
if (in != NULL) BIO_free(in);
|
||||
if (signatureLength <= 0) { return(ILibDuktape_Error(ctx, "PKCS7_signDataBlockError: ")); }
|
||||
|
||||
duk_push_external_buffer(ctx);
|
||||
duk_config_buffer(ctx, -1, signature, signatureLength);
|
||||
duk_push_buffer_object(ctx, -1, 0, signatureLength, DUK_BUFOBJ_NODEJS_BUFFER);
|
||||
duk_push_pointer(ctx, signature);
|
||||
duk_put_prop_string(ctx, -2, "\xFF_signature");
|
||||
ILibDuktape_CreateFinalizer(ctx, ILibDuktape_PKCS7_signDataBlockFinalizer);
|
||||
|
||||
return(1);
|
||||
}
|
||||
void ILibDuktape_PKCS7_Push(duk_context *ctx, void *chain)
|
||||
{
|
||||
duk_push_object(ctx);
|
||||
ILibDuktape_CreateInstanceMethod(ctx, "getSignedDataBlock", ILibDuktape_PKCS7_getSignedDataBlock, 1);
|
||||
ILibDuktape_CreateInstanceMethod(ctx, "signDataBlock", ILibDuktape_PKCS7_signDataBlock, DUK_VARARGS);
|
||||
}
|
||||
|
||||
extern uint32_t crc32c(uint32_t crc, const unsigned char* buf, uint32_t len);
|
||||
duk_ret_t ILibDuktape_Polyfills_crc32c(duk_context *ctx)
|
||||
{
|
||||
duk_size_t len;
|
||||
char *buffer = Duktape_GetBuffer(ctx, 0, &len);
|
||||
duk_push_int(ctx, crc32c(0, (unsigned char*)buffer, (uint32_t)len));
|
||||
return(1);
|
||||
}
|
||||
#endif
|
||||
duk_ret_t ILibDuktape_Polyfills_Object_hashCode(duk_context *ctx)
|
||||
{
|
||||
duk_push_this(ctx);
|
||||
duk_push_string(ctx, Duktape_GetStashKey(duk_get_heapptr(ctx, -1)));
|
||||
return(1);
|
||||
}
|
||||
void ILibDuktape_Polyfills_object(duk_context *ctx)
|
||||
{
|
||||
// Polyfill Object._hashCode()
|
||||
duk_get_prop_string(ctx, -1, "Object"); // [g][Object]
|
||||
duk_get_prop_string(ctx, -1, "prototype"); // [g][Object][prototype]
|
||||
duk_push_c_function(ctx, ILibDuktape_Polyfills_Object_hashCode, 0); // [g][Object][prototype][func]
|
||||
ILibDuktape_CreateReadonlyProperty(ctx, "_hashCode"); // [g][Object][prototype]
|
||||
duk_pop_2(ctx); // [g]
|
||||
}
|
||||
|
||||
|
||||
void ILibDuktape_Polyfills_Init(duk_context *ctx)
|
||||
{
|
||||
ILibDuktape_ModSearch_AddHandler(ctx, "queue", ILibDuktape_Queue_Push);
|
||||
ILibDuktape_ModSearch_AddHandler(ctx, "DynamicBuffer", ILibDuktape_DynamicBuffer_Push);
|
||||
ILibDuktape_ModSearch_AddHandler(ctx, "stream", ILibDuktape_Stream_Init);
|
||||
#ifndef MICROSTACK_NOTLS
|
||||
ILibDuktape_ModSearch_AddHandler(ctx, "pkcs7", ILibDuktape_PKCS7_Push);
|
||||
#endif
|
||||
|
||||
// Global Polyfills
|
||||
duk_push_global_object(ctx); // [g]
|
||||
@@ -1010,13 +1557,20 @@ void ILibDuktape_Polyfills_Init(duk_context *ctx)
|
||||
ILibDuktape_Polyfills_Console(ctx);
|
||||
ILibDuktape_Polyfills_byte_ordering(ctx);
|
||||
ILibDuktape_Polyfills_timer(ctx);
|
||||
ILibDuktape_Polyfills_object(ctx);
|
||||
|
||||
ILibDuktape_CreateInstanceMethod(ctx, "addModuleObject", ILibDuktape_Polyfills_addModuleObject, 2);
|
||||
ILibDuktape_CreateInstanceMethod(ctx, "addModule", ILibDuktape_Polyfills_addModule, 2);
|
||||
ILibDuktape_CreateInstanceMethod(ctx, "getJSModule", ILibDuktape_Polyfills_getJSModule, 1);
|
||||
ILibDuktape_CreateInstanceMethod(ctx, "_debugCrash", ILibDuktape_Polyfills_debugCrash, 0);
|
||||
ILibDuktape_CreateInstanceMethod(ctx, "_debugGC", ILibDuktape_Polyfills_debugGC, 0);
|
||||
ILibDuktape_CreateInstanceMethod(ctx, "_debug", ILibDuktape_Polyfills_debug, 0);
|
||||
|
||||
#ifndef MICROSTACK_NOTLS
|
||||
ILibDuktape_CreateInstanceMethod(ctx, "crc32c", ILibDuktape_Polyfills_crc32c, DUK_VARARGS);
|
||||
#endif
|
||||
duk_pop(ctx); // ...
|
||||
|
||||
ILibDuktape_Debugger_Init(ctx, 9091);
|
||||
}
|
||||
|
||||
#ifdef __DOXY__
|
||||
@@ -1207,4 +1761,4 @@ public:
|
||||
*/
|
||||
static void htonl(buffer, offset, val);
|
||||
};
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -23,4 +23,4 @@ extern int g_displayStreamPipeMessages;
|
||||
extern int g_displayFinalizerMessages;
|
||||
void ILibDuktape_Polyfills_Init(duk_context *ctx);
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -1,256 +0,0 @@
|
||||
#include "duktape.h"
|
||||
|
||||
#if defined(WINSOCK2)
|
||||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
#endif
|
||||
|
||||
#include "microstack/ILibParsers.h"
|
||||
#include "microstack/ILibProcessPipe.h"
|
||||
#include "ILibDuktape_ProcessPipe.h"
|
||||
#include "ILibDuktape_Helpers.h"
|
||||
#include "ILibDuktape_DuplexStream.h"
|
||||
#include "ILibDuktapeModSearch.h"
|
||||
|
||||
#define ILibDuktape_ProcessPipe_Process_ErrorStreamPtr "\xFF_ErrorStreamPtr"
|
||||
#define ILibDuktape_ProcessPipe_Process_ErrorStreamPtrNative "\xFF_ErrorStreamPtrNative"
|
||||
#define ILibDuktape_ProcessPipe_Process_PTR "\xFFProcessPtr"
|
||||
|
||||
ILibTransport_DoneState ILibDuktape_ProcessPipe_Process_JSOnWrite(ILibDuktape_DuplexStream *stream, char *buffer, int bufferLen, void *user)
|
||||
{
|
||||
// Called when JavaScript has written bytes to this object
|
||||
|
||||
ILibProcessPipe_Process mProcess = (ILibProcessPipe_Process)user;
|
||||
return(ILibProcessPipe_Process_WriteStdIn(mProcess, buffer, bufferLen, ILibTransport_MemoryOwnership_USER));
|
||||
}
|
||||
void ILibDuktape_ProcessPipe_Process_JSOnEnd(ILibDuktape_DuplexStream *stream, void *user)
|
||||
{
|
||||
// Called when JavaScript has specified that it will no longer write data
|
||||
|
||||
ILibProcessPipe_Process mProcess = (ILibProcessPipe_Process)user;
|
||||
|
||||
if (mProcess != NULL)
|
||||
{
|
||||
ILibProcessPipe_Process_KillEx(mProcess);
|
||||
|
||||
duk_push_heapptr(stream->readableStream->ctx, stream->ParentObject); // [process]
|
||||
duk_del_prop_string(stream->readableStream->ctx, -1, ILibDuktape_ProcessPipe_Process_PTR);
|
||||
duk_pop(stream->readableStream->ctx);
|
||||
ILibProcessPipe_Process_UpdateUserObject(mProcess, NULL);
|
||||
stream->user = NULL;
|
||||
}
|
||||
}
|
||||
void ILibDuktape_ProcessPipe_Process_JSPause(ILibDuktape_DuplexStream *sender, void *user)
|
||||
{
|
||||
// Called when either JavaScript called Pause, or JavaScript has not attached a reader yet
|
||||
|
||||
ILibProcessPipe_Process mProcess = (ILibProcessPipe_Process)user;
|
||||
ILibProcessPipe_Pipe_Pause(ILibProcessPipe_Process_GetStdOut(mProcess));
|
||||
}
|
||||
void ILibDuktape_ProcessPipe_Process_JSResume(ILibDuktape_DuplexStream *sender, void *user)
|
||||
{
|
||||
// Called when JavaScript called Resume
|
||||
|
||||
ILibProcessPipe_Process mProcess = (ILibProcessPipe_Process)user;
|
||||
ILibProcessPipe_Pipe_Resume(ILibProcessPipe_Process_GetStdOut(mProcess));
|
||||
}
|
||||
|
||||
void ILibDuktape_ProcessPipe_Process_OnExit(ILibProcessPipe_Process sender, int exitCode, void* user)
|
||||
{
|
||||
if (user == NULL) { return; }
|
||||
|
||||
// Called when process has exited
|
||||
ILibDuktape_DuplexStream* stream = (ILibDuktape_DuplexStream*)user;
|
||||
ILibProcessPipe_Process_UpdateUserObject(sender, NULL);
|
||||
|
||||
ILibDuktape_DuplexStream_WriteEnd(stream);
|
||||
duk_push_heapptr(stream->readableStream->ctx, stream->ParentObject); // [process]
|
||||
duk_del_prop_string(stream->readableStream->ctx, -1, ILibDuktape_ProcessPipe_Process_PTR);
|
||||
duk_pop(stream->readableStream->ctx);
|
||||
|
||||
}
|
||||
void ILibDuktape_ProcessPipe_Process_OnStdOut(ILibProcessPipe_Process sender, char *buffer, int bufferLen, int* bytesConsumed, void* user)
|
||||
{
|
||||
if (user == NULL) { return; }
|
||||
|
||||
// Called when process has written data
|
||||
ILibDuktape_DuplexStream* ds = (ILibDuktape_DuplexStream*)user;
|
||||
ILibDuktape_DuplexStream_WriteData(ds, buffer, bufferLen);
|
||||
*bytesConsumed = bufferLen;
|
||||
}
|
||||
void ILibDuktape_ProcessPipe_Process_OnStdErr(ILibProcessPipe_Process sender, char *buffer, int bufferLen, int* bytesConsumed, void* user)
|
||||
{
|
||||
if (user == NULL) { return; }
|
||||
|
||||
// Called when process has written error data
|
||||
ILibDuktape_DuplexStream* ds = (ILibDuktape_DuplexStream*)user;
|
||||
ILibDuktape_readableStream *rs;
|
||||
duk_push_heapptr(ds->readableStream->ctx, ds->ParentObject); // [process]
|
||||
duk_get_prop_string(ds->readableStream->ctx, -1, ILibDuktape_ProcessPipe_Process_ErrorStreamPtrNative); // [process][error]
|
||||
rs = (ILibDuktape_readableStream*)duk_get_pointer(ds->readableStream->ctx, -1);
|
||||
|
||||
ILibDuktape_readableStream_WriteData(rs, buffer, bufferLen);
|
||||
*bytesConsumed = bufferLen;
|
||||
}
|
||||
void ILibDuktape_ProcessPipe_Process_OnSendOK(ILibProcessPipe_Process sender, void* user)
|
||||
{
|
||||
if (user == NULL) { return; }
|
||||
//ToDo: Finish this
|
||||
}
|
||||
duk_ret_t ILibDuktape_ProcessPipe_Process_Finalizer(duk_context *ctx)
|
||||
{
|
||||
ILibProcessPipe_Process mProcess;
|
||||
|
||||
duk_dup(ctx, 0);
|
||||
duk_get_prop_string(ctx, -1, ILibDuktape_ProcessPipe_Process_PTR);
|
||||
mProcess = (ILibProcessPipe_Process)duk_get_pointer(ctx, -1);
|
||||
|
||||
if (mProcess != NULL)
|
||||
{
|
||||
ILibProcessPipe_Process_UpdateUserObject(mProcess, NULL);
|
||||
ILibProcessPipe_Process_KillEx(mProcess);
|
||||
}
|
||||
|
||||
if (duk_has_prop_string(ctx, 0, ILibDuktape_DuplexStream_bufferPtr))
|
||||
{
|
||||
duk_get_prop_string(ctx, 0, ILibDuktape_DuplexStream_bufferPtr);
|
||||
memset(Duktape_GetBuffer(ctx, -1, NULL), 0, sizeof(ILibDuktape_DuplexStream));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
void ILibDuktape_ProcessPipe_ErrorStream_Pause(struct ILibDuktape_readableStream *sender, void *user)
|
||||
{
|
||||
ILibProcessPipe_Process mProcess = (ILibProcessPipe_Process)user;
|
||||
ILibProcessPipe_Pipe_Pause(ILibProcessPipe_Process_GetStdErr(mProcess));
|
||||
}
|
||||
void ILibDuktape_ProcessPipe_ErrorStream_Resume(struct ILibDuktape_readableStream *sender, void *user)
|
||||
{
|
||||
ILibProcessPipe_Process mProcess = (ILibProcessPipe_Process)user;
|
||||
ILibProcessPipe_Pipe_Resume(ILibProcessPipe_Process_GetStdErr(mProcess));
|
||||
}
|
||||
duk_ret_t ILibDuktape_ProcessPipe_ErrorStream_Getter(duk_context *ctx)
|
||||
{
|
||||
duk_push_this(ctx);
|
||||
duk_get_prop_string(ctx, -1, ILibDuktape_ProcessPipe_Process_ErrorStreamPtr);
|
||||
return 1;
|
||||
}
|
||||
duk_ret_t ILibDuktape_ProcessPipe_CreateProcess(duk_context *ctx)
|
||||
{
|
||||
ILibProcessPipe_Manager pipeManager;
|
||||
ILibProcessPipe_Process mProcess;
|
||||
ILibDuktape_DuplexStream* ds;
|
||||
ILibDuktape_readableStream *rs;
|
||||
duk_size_t targetLen;
|
||||
int nargs = duk_get_top(ctx);
|
||||
char *target;
|
||||
char **params = NULL;
|
||||
int i, x;
|
||||
ILibProcessPipe_SpawnTypes asUser = ILibProcessPipe_SpawnTypes_DEFAULT;
|
||||
|
||||
if (nargs < 1) { duk_push_string(ctx, "ProcessPipe.CreateProcess: Invalid number of args"); duk_throw(ctx); return(DUK_RET_ERROR); }
|
||||
|
||||
// Parse Parameters
|
||||
target = (char*)duk_get_lstring(ctx, 0, &targetLen);
|
||||
#ifdef WIN32
|
||||
if (target[0] == '%')
|
||||
{
|
||||
size_t evsize;
|
||||
int pctx = ILibString_IndexOf(target + 1, (int)targetLen - 1, "%", 1);
|
||||
if (pctx > 0)
|
||||
{
|
||||
memcpy_s(ILibScratchPad, sizeof(ILibScratchPad), target + 1, pctx);
|
||||
ILibScratchPad[pctx] = 0;
|
||||
getenv_s(&evsize, ILibScratchPad2, sizeof(ILibScratchPad2), ILibScratchPad);
|
||||
if (evsize > 0)
|
||||
{
|
||||
strncpy_s(ILibScratchPad2 + evsize - 1, sizeof(ILibScratchPad2) - evsize, target + pctx + 2, targetLen - pctx - 2);
|
||||
target = ILibScratchPad2;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (nargs > 1)
|
||||
{
|
||||
x = 0;
|
||||
params = (char**)ILibMemory_Allocate((nargs * sizeof(char*)), 0, NULL, NULL);
|
||||
for (i = 1; i < nargs; ++i)
|
||||
{
|
||||
if (duk_is_number(ctx, i))
|
||||
{
|
||||
asUser = (ILibProcessPipe_SpawnTypes)duk_require_int(ctx, i);
|
||||
}
|
||||
else
|
||||
{
|
||||
params[x++] = (char*)duk_require_string(ctx, i);
|
||||
}
|
||||
}
|
||||
params[x] = NULL;
|
||||
}
|
||||
|
||||
duk_push_this(ctx); // [manager]
|
||||
duk_get_prop_string(ctx, -1, "\xFFPipeManager"); // [manager][pipeManager]
|
||||
pipeManager = (ILibProcessPipe_Manager)duk_get_pointer(ctx, -1);
|
||||
|
||||
mProcess = ILibProcessPipe_Manager_SpawnProcessEx(pipeManager, target, params, asUser);
|
||||
if (params != NULL) { free(params); }
|
||||
if (mProcess != NULL)
|
||||
{
|
||||
duk_push_object(ctx); // [manager][pipeManager][retVal]
|
||||
duk_push_pointer(ctx, mProcess); // [manager][pipeManager][retVal][process]
|
||||
duk_put_prop_string(ctx, -2, ILibDuktape_ProcessPipe_Process_PTR); // [manager][pipeManager][retVal]
|
||||
ILibDuktape_CreateReadonlyProperty_int(ctx, "pid", ILibProcessPipe_Process_GetPID(mProcess));
|
||||
|
||||
|
||||
ds = ILibDuktape_DuplexStream_Init(ctx, ILibDuktape_ProcessPipe_Process_JSOnWrite,
|
||||
ILibDuktape_ProcessPipe_Process_JSOnEnd, ILibDuktape_ProcessPipe_Process_JSPause,
|
||||
ILibDuktape_ProcessPipe_Process_JSResume, mProcess);
|
||||
ILibDuktape_CreateFinalizer(ctx, ILibDuktape_ProcessPipe_Process_Finalizer);
|
||||
|
||||
ILibProcessPipe_Process_AddHandlers(mProcess, 4096, ILibDuktape_ProcessPipe_Process_OnExit,
|
||||
ILibDuktape_ProcessPipe_Process_OnStdOut, ILibDuktape_ProcessPipe_Process_OnStdErr,
|
||||
ILibDuktape_ProcessPipe_Process_OnSendOK, ds);
|
||||
|
||||
duk_push_object(ctx); // [manager][pipeManager][retVal][error]
|
||||
ILibDuktape_CreateEventWithGetterEx(ctx, "parent", duk_get_heapptr(ctx, -2));
|
||||
rs = ILibDuktape_ReadableStream_Init(ctx, ILibDuktape_ProcessPipe_ErrorStream_Pause, ILibDuktape_ProcessPipe_ErrorStream_Resume, mProcess);
|
||||
duk_put_prop_string(ctx, -2, ILibDuktape_ProcessPipe_Process_ErrorStreamPtr); // [manager][pipeManager][retVal]
|
||||
ILibDuktape_CreateEventWithGetter(ctx, "error", ILibDuktape_ProcessPipe_ErrorStream_Getter);
|
||||
duk_push_pointer(ctx, rs); // [manager][pipeManager][retVal][ptr]
|
||||
duk_put_prop_string(ctx, -2, ILibDuktape_ProcessPipe_Process_ErrorStreamPtrNative); // [manager][pipeManager][retVal]
|
||||
}
|
||||
else
|
||||
{
|
||||
duk_push_null(ctx);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
duk_ret_t ILibDuktape_ProcessPipe_Finalizer(duk_context *ctx)
|
||||
{
|
||||
ILibProcessPipe_Manager *pipeManager;
|
||||
|
||||
duk_dup(ctx, 0); // [obj]
|
||||
duk_get_prop_string(ctx, -1, "\xFFPipeManager"); // [obj][manager]
|
||||
pipeManager = (ILibProcessPipe_Manager)duk_get_pointer(ctx, -1);
|
||||
|
||||
ILibChain_SafeRemove(((ILibChain_Link*)pipeManager)->ParentChain, pipeManager);
|
||||
|
||||
return 0;
|
||||
}
|
||||
void ILibDuktape_ProcessPipe_PUSH(duk_context *ctx, void *chain)
|
||||
{
|
||||
ILibProcessPipe_Manager pipeManager = ILibProcessPipe_Manager_Create(chain);
|
||||
|
||||
duk_push_object(ctx); // [obj]
|
||||
duk_push_pointer(ctx, pipeManager); // [obj][pipeManager]
|
||||
duk_put_prop_string(ctx, -2, "\xFFPipeManager"); // [obj]
|
||||
ILibDuktape_CreateInstanceMethod(ctx, "CreateProcess", ILibDuktape_ProcessPipe_CreateProcess, DUK_VARARGS);
|
||||
ILibDuktape_CreateFinalizer(ctx, ILibDuktape_ProcessPipe_Finalizer);
|
||||
Duktape_CreateEnum(ctx, "ILibProcessPipe_SpawnTypes", (char*[]) { "DEFAULT", "USER", "WINLOGON", "TERM" }, (int[]) { 0, 1, 2, 3 }, 4);
|
||||
}
|
||||
void ILibDuktape_ProcessPipe_Init(duk_context * ctx, void * chain)
|
||||
{
|
||||
ILibDuktape_ModSearch_AddHandler(ctx, "ILibProcessPipe", ILibDuktape_ProcessPipe_PUSH);
|
||||
}
|
||||
@@ -1,71 +0,0 @@
|
||||
#ifndef __DUKTAPE_PROCESSPIPE__
|
||||
#define __DUKTAPE_PROCESSPIPE__
|
||||
|
||||
#include "duktape.h"
|
||||
|
||||
#ifdef __DOXY__
|
||||
/*!
|
||||
\brief An object that is used to spawn child processes to perform various tasks. <b>Note:</b> To use, must <b>require('ILibProcessPipe')</b>
|
||||
*/
|
||||
class ILibProcessPipe
|
||||
{
|
||||
public:
|
||||
/*!
|
||||
\brief Spawns a child process
|
||||
*
|
||||
ILibProcessPipe_Process CreateProcess(target[, spawnType][, ...args]);
|
||||
\param target \<String\> The target module to execute
|
||||
\param spawnType <ILibProcessPipe_SpawnTypes> The optional process type to spawn
|
||||
\param args \<String\> optional paramaters to pass to target on the command line. The first one is argv0, the second is argv1, etc.
|
||||
\returns \<ILibProcessPipe_Process\> stream attached to child process. NULL if the process could not be spawned.
|
||||
*/
|
||||
ILibProcessPipe_Process CreateProcess(target[, spawnType][, ...args]);
|
||||
|
||||
/*!
|
||||
\brief Specifies the type of child process to spawn
|
||||
*/
|
||||
enum class ILibProcessPipe_SpawnTypes
|
||||
{
|
||||
DEFAULT, /*!< Same as parent*/
|
||||
USER, /*!< Currently logged on user*/
|
||||
WINLOGON, /*!< Windows Logon Screen*/
|
||||
TERM /*!< Terminal*/
|
||||
};
|
||||
/*!
|
||||
\implements DuplexStream
|
||||
\brief Stream abstraction for a child process of ILibProcessPipe.
|
||||
*
|
||||
The underyling ReadableStream is attached to the child process's <b>stdIn</b>. \n
|
||||
The underlying WritableStream is attached tot he child process's <b>stdOut</b>.
|
||||
*/
|
||||
class ILibProcessPipe_Process
|
||||
{
|
||||
public:
|
||||
/*!
|
||||
\brief The Child's Process ID
|
||||
*/
|
||||
int pid;
|
||||
/*!
|
||||
\brief The ReadableStream that is attached to the child process's <b>StdErr</b>
|
||||
*/
|
||||
ReadableStream error;
|
||||
|
||||
|
||||
/*!
|
||||
\brief The 'data' event is emitted data is available from the child process's <b>StdOut</b>.
|
||||
\param chunk A chunk of data. Can be a Buffer or a string.
|
||||
*/
|
||||
void data;
|
||||
/*!
|
||||
\brief The 'end' event is emitted when the child process has exited.
|
||||
*/
|
||||
void end;
|
||||
};
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
void ILibDuktape_ProcessPipe_Init(duk_context *ctx, void *chain);
|
||||
|
||||
|
||||
#endif
|
||||
@@ -192,6 +192,8 @@ int ILibDuktape_readableStream_WriteData_Flush(struct ILibDuktape_WritableStream
|
||||
if(stream->pipe_pendingCount == 0)
|
||||
#endif
|
||||
{
|
||||
if (stream->emitter->ctx == NULL) { return(1); }
|
||||
|
||||
sem_wait(&(stream->pipeLock));
|
||||
stream->pipeInProgress = 0;
|
||||
unpipeInProgress = stream->unpipeInProgress;
|
||||
@@ -259,7 +261,7 @@ int ILibDuktape_readableStream_WriteDataEx(ILibDuktape_readableStream *stream, i
|
||||
int dispatched = 0;
|
||||
int needPause = 0;
|
||||
|
||||
if (stream == NULL) { return(1); }
|
||||
if (stream == NULL || !ILibMemory_CanaryOK(stream)) { return(1); }
|
||||
|
||||
if (stream->paused != 0)
|
||||
{
|
||||
@@ -416,6 +418,7 @@ void ILibDuktape_readableStream_WriteEnd_ChainSink(void *chain, void *user)
|
||||
int ILibDuktape_readableStream_WriteEnd(ILibDuktape_readableStream *stream)
|
||||
{
|
||||
int retVal = 1;
|
||||
if (!ILibMemory_CanaryOK(stream)) { return(retVal); }
|
||||
|
||||
if (ILibIsRunningOnChainThread(stream->chain) == 0)
|
||||
{
|
||||
@@ -531,7 +534,7 @@ duk_ret_t ILibDuktape_readableStream_resume(duk_context *ctx)
|
||||
ptr = (ILibDuktape_readableStream*)Duktape_GetBuffer(ctx, -1, NULL);
|
||||
duk_pop(ctx); // [stream]
|
||||
if (ptr->ResumeHandler == NULL) { return(ILibDuktape_Error(ctx, "Resume not supported")); }
|
||||
|
||||
if (!ptr->paused) { return(0); }
|
||||
if (ILibDuktape_readableStream_resume_flush(ptr) == 0 && ptr->ResumeHandler != NULL) { ptr->paused = 0; ptr->ResumeHandler(ptr, ptr->user); }
|
||||
return 1;
|
||||
}
|
||||
@@ -545,21 +548,20 @@ void ILibDuktape_ReadableStream_pipe_ResumeLater(duk_context *ctx, void **args,
|
||||
}
|
||||
void ILibDuktape_readableStream_pipe_later(duk_context *ctx, void **args, int argsLen)
|
||||
{
|
||||
duk_push_heapptr(ctx, args[0]); // [readable]
|
||||
duk_get_prop_string(ctx, -1, ILibDuktape_readableStream_RSPTRS);
|
||||
ILibDuktape_readableStream *rs = (ILibDuktape_readableStream*)Duktape_GetBuffer(ctx, -1, NULL);
|
||||
duk_pop(ctx);
|
||||
|
||||
duk_push_heapptr(ctx, rs->pipeImmediate);
|
||||
duk_del_prop_string(ctx, -1, "dest");
|
||||
duk_pop(ctx);
|
||||
rs->pipeImmediate = NULL;
|
||||
|
||||
ILibDuktape_readableStream *rs = (ILibDuktape_readableStream*)args[0];
|
||||
if (!ILibMemory_CanaryOK(rs)) { return; }
|
||||
|
||||
duk_push_heapptr(ctx, rs->object); // [readable]
|
||||
duk_get_prop_string(ctx, -1, "pipe"); // [readable][pipe]
|
||||
duk_swap_top(ctx, -2); // [pipe][this]
|
||||
duk_push_heapptr(ctx, args[1]); // [pipe][this][writable]
|
||||
if (argsLen > 2) { duk_push_heapptr(ctx, args[2]); } // [pipe][this][writable][options]
|
||||
|
||||
duk_push_heapptr(ctx, rs->pipeImmediate); // [pipe][this][writable][options][immediate]
|
||||
duk_del_prop_string(ctx, -1, "dest");
|
||||
duk_pop(ctx); // [pipe][this][writable][options]
|
||||
rs->pipeImmediate = NULL;
|
||||
|
||||
if (duk_pcall_method(ctx, argsLen - 1) != 0) { ILibDuktape_Process_UncaughtExceptionEx(ctx, "readableStream.pipeLater(): "); }
|
||||
duk_pop(ctx); // ...
|
||||
}
|
||||
@@ -578,11 +580,15 @@ duk_ret_t ILibDuktape_readableStream_pipe(duk_context *ctx)
|
||||
if (rstream->pipeInProgress != 0)
|
||||
{
|
||||
// We must YIELD and try again later, becuase there is an active dispatch going on
|
||||
duk_push_this(ctx);
|
||||
rstream->pipeImmediate = ILibDuktape_Immediate(ctx, (void*[]) { duk_get_heapptr(ctx, -1), duk_get_heapptr(ctx, 0), nargs > 1 ? duk_get_heapptr(ctx, 1) : NULL }, 1 + nargs, ILibDuktape_readableStream_pipe_later);
|
||||
rstream->pipeImmediate = ILibDuktape_Immediate(ctx, (void*[]) { rstream, duk_get_heapptr(ctx, 0), nargs > 1 ? duk_get_heapptr(ctx, 1) : NULL }, 1 + nargs, ILibDuktape_readableStream_pipe_later);
|
||||
duk_push_heapptr(ctx, rstream->pipeImmediate); // [immediate]
|
||||
duk_dup(ctx, 0); // [immediate][ws]
|
||||
duk_put_prop_string(ctx, -2, "dest"); // [immediate]
|
||||
if (nargs > 1)
|
||||
{
|
||||
duk_dup(ctx, 1);
|
||||
duk_put_prop_string(ctx, -2, "opt");
|
||||
}
|
||||
duk_dup(ctx, 0);
|
||||
sem_post(&(rstream->pipeLock));
|
||||
return(1);
|
||||
@@ -668,6 +674,7 @@ void ILibDuktape_readableStream_unpipe_later(duk_context *ctx, void ** args, int
|
||||
data = (ILibDuktape_readableStream*)Duktape_GetBuffer(ctx, -1, NULL);
|
||||
duk_pop_2(ctx); // ...
|
||||
|
||||
if (data->emitter->ctx == NULL) { return; }
|
||||
sem_wait(&(data->pipeLock));
|
||||
if (data->pipeInProgress != 0)
|
||||
{
|
||||
@@ -726,8 +733,11 @@ void ILibDuktape_readableStream_unpipe_later(duk_context *ctx, void ** args, int
|
||||
duk_call_method(ctx, 2); // [undefined]
|
||||
duk_pop(ctx); // ...
|
||||
break;
|
||||
}
|
||||
duk_pop_2(ctx); // [array]
|
||||
}
|
||||
else
|
||||
{
|
||||
duk_pop(ctx); // [array]
|
||||
}
|
||||
}
|
||||
duk_pop(ctx); // ...
|
||||
break;
|
||||
@@ -765,6 +775,7 @@ void ILibDuktape_readableStream_unpipe_later(duk_context *ctx, void ** args, int
|
||||
duk_ret_t ILibDuktape_readableStream_unpipe(duk_context *ctx)
|
||||
{
|
||||
int nargs = duk_get_top(ctx);
|
||||
int onlyItem = 0;
|
||||
ILibDuktape_readableStream *data;
|
||||
|
||||
duk_push_this(ctx); // [readable]
|
||||
@@ -772,15 +783,35 @@ duk_ret_t ILibDuktape_readableStream_unpipe(duk_context *ctx)
|
||||
data = (ILibDuktape_readableStream*)Duktape_GetBuffer(ctx, -1, NULL);
|
||||
duk_pop(ctx); // [readable]
|
||||
|
||||
if (data->emitter->ctx == NULL) { return(0); }
|
||||
|
||||
sem_wait(&(data->pipeLock));
|
||||
data->unpipeInProgress = 1;
|
||||
if (nargs == 1 && duk_is_object(ctx, 0))
|
||||
{
|
||||
void *w = duk_require_heapptr(ctx, 0);
|
||||
duk_push_heapptr(ctx, data->pipeArray); // [readable][array]
|
||||
int wcount = (int)duk_get_length(ctx, -1);
|
||||
duk_enum(ctx, -1, DUK_ENUM_OWN_PROPERTIES_ONLY); // [readable][array][enum]
|
||||
while (duk_next(ctx, -1, 1))
|
||||
{ // [readable][array][enum][key][val]
|
||||
if (duk_get_heapptr(ctx, -1) == w) { onlyItem = 1; }
|
||||
duk_pop_2(ctx); // [readable][array][enum]
|
||||
if (onlyItem) { break; }
|
||||
}
|
||||
if (onlyItem && wcount > 1) { onlyItem = 0; }
|
||||
duk_pop_2(ctx); // [readable]
|
||||
}
|
||||
sem_post(&(data->pipeLock));
|
||||
|
||||
// We need to pause first
|
||||
duk_push_this(ctx); // [readable]
|
||||
duk_get_prop_string(ctx, -1, "pause"); // [readable][pause]
|
||||
duk_dup(ctx, -2); // [readable][pause][this]
|
||||
duk_call_method(ctx, 0); duk_pop(ctx); // [readable]
|
||||
if (nargs == 0 || onlyItem != 0)
|
||||
{
|
||||
// We need to pause first
|
||||
duk_push_this(ctx); // [readable]
|
||||
duk_get_prop_string(ctx, -1, "pause"); // [readable][pause]
|
||||
duk_dup(ctx, -2); // [readable][pause][this]
|
||||
duk_call_method(ctx, 0); duk_pop(ctx); // [readable]
|
||||
}
|
||||
|
||||
// We must yield, and do this on the next event loop, because we can't unpipe if we're called from a pipe'ed call
|
||||
void *imm = ILibDuktape_Immediate(ctx, (void*[]) { duk_get_heapptr(ctx, -1), nargs == 1 ? duk_get_heapptr(ctx, 0) : NULL }, nargs + 1, ILibDuktape_readableStream_unpipe_later);
|
||||
@@ -867,17 +898,12 @@ ILibDuktape_readableStream* ILibDuktape_ReadableStream_InitEx(duk_context *ctx,
|
||||
ILibDuktape_readableStream *retVal;
|
||||
ILibDuktape_EventEmitter *emitter;
|
||||
|
||||
ILibDuktape_PointerValidation_Init(ctx);
|
||||
duk_push_fixed_buffer(ctx, sizeof(ILibDuktape_readableStream)); // [obj][buffer]
|
||||
duk_dup(ctx, -1); // [obj][buffer][buffer]
|
||||
duk_put_prop_string(ctx, -3, ILibDuktape_readableStream_RSPTRS); // [obj][buffer]
|
||||
retVal = (ILibDuktape_readableStream*)Duktape_GetBuffer(ctx, -1, NULL); // [obj][buffer]
|
||||
memset(retVal, 0, sizeof(ILibDuktape_readableStream));
|
||||
retVal = (ILibDuktape_readableStream*)Duktape_PushBuffer(ctx, sizeof(ILibDuktape_readableStream)); // [obj][buffer]
|
||||
duk_put_prop_string(ctx, -2, ILibDuktape_readableStream_RSPTRS); // [obj]
|
||||
|
||||
duk_pop(ctx); // [obj]
|
||||
duk_push_array(ctx); // [obj][array]
|
||||
duk_push_array(ctx); // [obj][array]
|
||||
retVal->pipeArray = duk_get_heapptr(ctx, -1);
|
||||
duk_put_prop_string(ctx, -2, ILibDuktape_readableStream_PipeArray); // [obj]
|
||||
duk_put_prop_string(ctx, -2, ILibDuktape_readableStream_PipeArray); // [obj]
|
||||
|
||||
retVal->ctx = ctx;
|
||||
retVal->chain = Duktape_GetChain(ctx);
|
||||
|
||||
@@ -80,4 +80,3 @@ int ILibDuktape_readableStream_WriteEnd(ILibDuktape_readableStream *stream);
|
||||
void ILibDuktape_readableStream_Closed(ILibDuktape_readableStream *stream);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@ limitations under the License.
|
||||
#include "../microstack/ILibCrypto.h"
|
||||
|
||||
#define ILibDuktape_MD5_PTR "\xFF_MD5PTR"
|
||||
#define ILibDuktape_SHA1_PTR "\xFF_SHA1PTR"
|
||||
#define ILibDuktape_SHA256_PTR "\xFF_SHA256PTR"
|
||||
#define ILibDuktape_SHA512_PTR "\xFF_SHA512PTR"
|
||||
#define ILibDuktape_SHA256_SIGNER_PTR "\xFF_SHA256_SIGNER_PTR"
|
||||
@@ -30,14 +31,12 @@ limitations under the License.
|
||||
#define ILibDuktape_SHA256_SIGNER_CERT_ALLOC "\xFF_SHA256_SIGNER_CERT_ALLOC"
|
||||
#define ILibDuktape_SHA256_SIGNER_SIGBUFFER "\xFF_SHA256_SIGNER_SIG_BUFFER"
|
||||
|
||||
#ifndef MICROSTACK_NOTLS
|
||||
|
||||
typedef struct ILibDuktape_SHA256_Data
|
||||
{
|
||||
duk_context *ctx;
|
||||
|
||||
void *object;
|
||||
char buffer[33];
|
||||
char buffer[UTIL_SHA256_HASHSIZE];
|
||||
SHA256_CTX shctx;
|
||||
}ILibDuktape_SHA256_Data;
|
||||
typedef struct ILibDuktape_SHA512_Data
|
||||
@@ -45,7 +44,7 @@ typedef struct ILibDuktape_SHA512_Data
|
||||
duk_context *ctx;
|
||||
|
||||
void *object;
|
||||
char buffer[65];
|
||||
char buffer[UTIL_SHA512_HASHSIZE];
|
||||
SHA512_CTX shctx;
|
||||
}ILibDuktape_SHA512_Data;
|
||||
typedef struct ILibDuktape_MD5_Data
|
||||
@@ -53,10 +52,20 @@ typedef struct ILibDuktape_MD5_Data
|
||||
duk_context *ctx;
|
||||
|
||||
void *object;
|
||||
char buffer[33];
|
||||
char buffer[UTIL_MD5_HASHSIZE];
|
||||
MD5_CTX mctx;
|
||||
}ILibDuktape_MD5_Data;
|
||||
|
||||
typedef struct ILibDuktape_SHA1_Data
|
||||
{
|
||||
duk_context *ctx;
|
||||
|
||||
void *object;
|
||||
char buffer[UTIL_SHA1_HASHSIZE];
|
||||
SHA_CTX sctx;
|
||||
}ILibDuktape_SHA1_Data;
|
||||
|
||||
#ifndef MICROSTACK_NOTLS
|
||||
typedef struct ILibDuktape_SHA256_Signer_Data
|
||||
{
|
||||
duk_context *ctx;
|
||||
@@ -67,6 +76,7 @@ typedef struct ILibDuktape_SHA256_Signer_Data
|
||||
void *OnSignature;
|
||||
void *OnSignatureString;
|
||||
}ILibDuktape_SHA256_Signer_Data;
|
||||
#endif
|
||||
|
||||
duk_ret_t ILibDuktape_SHA256_Finalizer(duk_context *ctx)
|
||||
{
|
||||
@@ -93,39 +103,29 @@ ILibTransport_DoneState ILibDuktape_SHA384_Write(struct ILibDuktape_WritableStre
|
||||
void ILibDuktape_SHA256_End(struct ILibDuktape_WritableStream *stream, void *user)
|
||||
{
|
||||
ILibDuktape_SHA256_Data *data = (ILibDuktape_SHA256_Data*)user;
|
||||
data->buffer[32] = 0;
|
||||
SHA256_Final((unsigned char*)data->buffer, &(data->shctx));
|
||||
|
||||
duk_push_external_buffer(data->ctx); // [extBuffer]
|
||||
duk_config_buffer(data->ctx, -1, data->buffer, 32);
|
||||
ILibDuktape_EventEmitter_SetupEmit(data->ctx, data->object, "hash"); // [extBuffer][emit][this]['hash']
|
||||
duk_push_buffer_object(data->ctx, -4, 0, 32, DUK_BUFOBJ_NODEJS_BUFFER); // [extBuffer][emit][this]['hash'][hash]
|
||||
duk_push_external_buffer(data->ctx); // [extBuffer]
|
||||
duk_config_buffer(data->ctx, -1, data->buffer, UTIL_SHA256_HASHSIZE);
|
||||
ILibDuktape_EventEmitter_SetupEmit(data->ctx, data->object, "hash"); // [extBuffer][emit][this]['hash']
|
||||
duk_push_buffer_object(data->ctx, -4, 0, UTIL_SHA256_HASHSIZE, DUK_BUFOBJ_NODEJS_BUFFER); // [extBuffer][emit][this]['hash'][hash]
|
||||
if (duk_pcall_method(data->ctx, 2) != 0) { ILibDuktape_Process_UncaughtException(data->ctx); }
|
||||
duk_pop_2(data->ctx); // ...
|
||||
|
||||
ILibDuktape_EventEmitter_SetupEmit(data->ctx, data->object, "hashString"); // [emit][this]['hash']
|
||||
duk_push_string(data->ctx, util_tohex(data->buffer, 32, ILibScratchPad)); // [emit][this]['hash'][hashString]
|
||||
if (duk_pcall_method(data->ctx, 1) != 0) { ILibDuktape_Process_UncaughtException(data->ctx); }
|
||||
duk_pop(data->ctx); // ...
|
||||
duk_pop_2(data->ctx); // ...
|
||||
}
|
||||
void ILibDuktape_SHA384_End(struct ILibDuktape_WritableStream *stream, void *user)
|
||||
{
|
||||
ILibDuktape_SHA512_Data *data = (ILibDuktape_SHA512_Data*)user;
|
||||
data->buffer[48] = 0;
|
||||
SHA384_Final((unsigned char*)data->buffer, &(data->shctx));
|
||||
|
||||
duk_push_external_buffer(data->ctx); // [extBuffer]
|
||||
duk_config_buffer(data->ctx, -1, data->buffer, 48);
|
||||
ILibDuktape_EventEmitter_SetupEmit(data->ctx, data->object, "hash"); // [extBuffer][emit][this]['hash']
|
||||
duk_push_buffer_object(data->ctx, -4, 0, 48, DUK_BUFOBJ_NODEJS_BUFFER); // [extBuffer][emit][this]['hash'][hash]
|
||||
duk_push_external_buffer(data->ctx); // [extBuffer]
|
||||
duk_config_buffer(data->ctx, -1, data->buffer, UTIL_SHA384_HASHSIZE);
|
||||
ILibDuktape_EventEmitter_SetupEmit(data->ctx, data->object, "hash"); // [extBuffer][emit][this]['hash']
|
||||
duk_push_buffer_object(data->ctx, -4, 0, UTIL_SHA384_HASHSIZE, DUK_BUFOBJ_NODEJS_BUFFER); // [extBuffer][emit][this]['hash'][hash]
|
||||
if (duk_pcall_method(data->ctx, 2) != 0) { ILibDuktape_Process_UncaughtException(data->ctx); }
|
||||
duk_pop_2(data->ctx); // ...
|
||||
|
||||
ILibDuktape_EventEmitter_SetupEmit(data->ctx, data->object, "hashString"); // [emit][this]['hashString']
|
||||
duk_push_string(data->ctx, util_tohex(data->buffer, 48, ILibScratchPad)); // [emit][this]['hashString'][hashString]
|
||||
if (duk_pcall_method(data->ctx, 2) != 0) { ILibDuktape_Process_UncaughtException(data->ctx); }
|
||||
duk_pop(data->ctx); // ...
|
||||
duk_pop_2(data->ctx); // ...
|
||||
}
|
||||
|
||||
#ifndef MICROSTACK_NOTLS
|
||||
duk_ret_t ILibDuktape_SHA256_SIGNER_Finalizer(duk_context *ctx)
|
||||
{
|
||||
ILibDuktape_SHA256_Signer_Data *data;
|
||||
@@ -254,11 +254,8 @@ void ILibDuktape_SHA256_SIGNER_PUSH(duk_context *ctx, void *chain)
|
||||
{
|
||||
ILibDuktape_SHA256_Signer_Data* data;
|
||||
duk_push_object(ctx); // [signer]
|
||||
duk_push_fixed_buffer(ctx, sizeof(ILibDuktape_SHA256_Signer_Data)); // [signer][data]
|
||||
data = (ILibDuktape_SHA256_Signer_Data*)Duktape_GetBuffer(ctx, -1, NULL);
|
||||
data = (ILibDuktape_SHA256_Signer_Data*)Duktape_PushBuffer(ctx, sizeof(ILibDuktape_SHA256_Signer_Data));
|
||||
duk_put_prop_string(ctx, -2, ILibDuktape_SHA256_SIGNER_PTR); // [signer]
|
||||
|
||||
memset(data, 0, sizeof(ILibDuktape_SHA256_Signer_Data));
|
||||
data->obj = duk_get_heapptr(ctx, -1);
|
||||
data->ctx = ctx;
|
||||
ILibDuktape_CreateInstanceMethod(ctx, "Create", ILibDuktape_SHA256_SIGNER_Create, 1);
|
||||
@@ -267,15 +264,14 @@ void ILibDuktape_SHA256_VERIFY_PUSH(duk_context *ctx, void *chain)
|
||||
{
|
||||
ILibDuktape_SHA256_Signer_Data* data;
|
||||
duk_push_object(ctx); // [signer]
|
||||
duk_push_fixed_buffer(ctx, sizeof(ILibDuktape_SHA256_Signer_Data)); // [signer][data]
|
||||
data = (ILibDuktape_SHA256_Signer_Data*)Duktape_GetBuffer(ctx, -1, NULL);
|
||||
data = (ILibDuktape_SHA256_Signer_Data*)Duktape_PushBuffer(ctx, sizeof(ILibDuktape_SHA256_Signer_Data));
|
||||
duk_put_prop_string(ctx, -2, ILibDuktape_SHA256_SIGNER_PTR); // [signer]
|
||||
|
||||
memset(data, 0, sizeof(ILibDuktape_SHA256_Signer_Data));
|
||||
data->obj = duk_get_heapptr(ctx, -1);
|
||||
data->ctx = ctx;
|
||||
ILibDuktape_CreateInstanceMethod(ctx, "Create", ILibDuktape_SHA256_VERIFIER_Create, 1);
|
||||
}
|
||||
#endif
|
||||
|
||||
duk_ret_t ILibDuktape_SHA256_syncHash(duk_context *ctx)
|
||||
{
|
||||
ILibDuktape_SHA256_Data *data;
|
||||
@@ -289,20 +285,11 @@ duk_ret_t ILibDuktape_SHA256_syncHash(duk_context *ctx)
|
||||
SHA256_Init(&(data->shctx));
|
||||
SHA256_Update(&(data->shctx), buffer, bufferLen);
|
||||
SHA256_Final((unsigned char*)data->buffer, &(data->shctx));
|
||||
data->buffer[32] = 0;
|
||||
|
||||
duk_push_current_function(ctx);
|
||||
duk_get_prop_string(ctx, -1, "strRet");
|
||||
if (duk_get_boolean(ctx, -1) == 0)
|
||||
{
|
||||
duk_push_external_buffer(ctx);
|
||||
duk_config_buffer(ctx, -1, data->buffer, 32);
|
||||
}
|
||||
else
|
||||
{
|
||||
util_tohex(data->buffer, 32, ILibScratchPad);
|
||||
duk_push_string(ctx, ILibScratchPad);
|
||||
}
|
||||
duk_push_external_buffer(ctx);
|
||||
duk_config_buffer(ctx, -1, data->buffer, UTIL_SHA256_HASHSIZE);
|
||||
duk_push_buffer_object(ctx, -1, 0, UTIL_SHA256_HASHSIZE, DUK_BUFOBJ_NODEJS_BUFFER);
|
||||
|
||||
return(1);
|
||||
}
|
||||
duk_ret_t ILibDuktape_SHA384_syncHash(duk_context *ctx)
|
||||
@@ -318,20 +305,11 @@ duk_ret_t ILibDuktape_SHA384_syncHash(duk_context *ctx)
|
||||
SHA384_Init(&(data->shctx));
|
||||
SHA384_Update(&(data->shctx), buffer, bufferLen);
|
||||
SHA384_Final((unsigned char*)data->buffer, &(data->shctx));
|
||||
data->buffer[48] = 0;
|
||||
|
||||
duk_push_current_function(ctx);
|
||||
duk_get_prop_string(ctx, -1, "strRet");
|
||||
if (duk_get_boolean(ctx, -1) == 0)
|
||||
{
|
||||
duk_push_external_buffer(ctx);
|
||||
duk_config_buffer(ctx, -1, data->buffer, 48);
|
||||
}
|
||||
else
|
||||
{
|
||||
util_tohex(data->buffer, 48, ILibScratchPad);
|
||||
duk_push_string(ctx, ILibScratchPad);
|
||||
}
|
||||
duk_push_external_buffer(ctx);
|
||||
duk_config_buffer(ctx, -1, data->buffer, UTIL_SHA384_HASHSIZE);
|
||||
duk_push_buffer_object(ctx, -1, 0, UTIL_SHA384_HASHSIZE, DUK_BUFOBJ_NODEJS_BUFFER);
|
||||
|
||||
return(1);
|
||||
}
|
||||
|
||||
@@ -345,26 +323,17 @@ ILibTransport_DoneState ILibDuktape_MD5_Write(struct ILibDuktape_WritableStream
|
||||
void ILibDuktape_MD5_End(struct ILibDuktape_WritableStream *stream, void *user)
|
||||
{
|
||||
ILibDuktape_MD5_Data *data = (ILibDuktape_MD5_Data*)user;
|
||||
data->buffer[32] = 0;
|
||||
MD5_Final((unsigned char*)data->buffer, &(data->mctx));
|
||||
|
||||
duk_push_external_buffer(data->ctx); // [extBuffer]
|
||||
duk_config_buffer(data->ctx, -1, data->buffer, 32);
|
||||
ILibDuktape_EventEmitter_SetupEmit(data->ctx, data->object, "hash"); // [extBuffer][emit][this]["hash"]
|
||||
duk_push_buffer_object(data->ctx, -4, 0, 32, DUK_BUFOBJ_NODEJS_BUFFER); // [extBuffer][emit][this]["hash"][buffer]
|
||||
if (duk_pcall_method(data->ctx, 2) != 0) // [retVal]
|
||||
duk_push_external_buffer(data->ctx); // [extBuffer]
|
||||
duk_config_buffer(data->ctx, -1, data->buffer, UTIL_MD5_HASHSIZE);
|
||||
ILibDuktape_EventEmitter_SetupEmit(data->ctx, data->object, "hash"); // [extBuffer][emit][this]["hash"]
|
||||
duk_push_buffer_object(data->ctx, -4, 0, UTIL_MD5_HASHSIZE, DUK_BUFOBJ_NODEJS_BUFFER); // [extBuffer][emit][this]["hash"][buffer]
|
||||
if (duk_pcall_method(data->ctx, 2) != 0) // [extBuffer][retVal]
|
||||
{
|
||||
ILibDuktape_Process_UncaughtException(data->ctx);
|
||||
}
|
||||
duk_pop_2(data->ctx); // ...
|
||||
|
||||
ILibDuktape_EventEmitter_SetupEmit(data->ctx, data->object, "hashString"); // [emit][this]["hashString"]
|
||||
duk_push_string(data->ctx, util_tohex(data->buffer, 32, ILibScratchPad)); // [emit][this]["hashString"][hashString]
|
||||
if (duk_pcall_method(data->ctx, 2) != 0) // [retVal]
|
||||
{
|
||||
ILibDuktape_Process_UncaughtException(data->ctx);
|
||||
}
|
||||
duk_pop(data->ctx); // ...
|
||||
duk_pop_2(data->ctx); // ...
|
||||
}
|
||||
duk_ret_t ILibDuktape_MD5_syncHash(duk_context *ctx)
|
||||
{
|
||||
@@ -379,20 +348,11 @@ duk_ret_t ILibDuktape_MD5_syncHash(duk_context *ctx)
|
||||
MD5_Init(&(data->mctx));
|
||||
MD5_Update(&(data->mctx), buffer, bufferLen);
|
||||
MD5_Final((unsigned char*)data->buffer, &(data->mctx));
|
||||
data->buffer[32] = 0;
|
||||
|
||||
duk_push_current_function(ctx);
|
||||
duk_get_prop_string(ctx, -1, "strRet");
|
||||
if (duk_get_boolean(ctx, -1) == 0)
|
||||
{
|
||||
duk_push_external_buffer(ctx);
|
||||
duk_config_buffer(ctx, -1, data->buffer, 32);
|
||||
}
|
||||
else
|
||||
{
|
||||
util_tohex(data->buffer, 32, ILibScratchPad);
|
||||
duk_push_string(ctx, ILibScratchPad);
|
||||
}
|
||||
duk_push_external_buffer(ctx);
|
||||
duk_config_buffer(ctx, -1, data->buffer, UTIL_MD5_HASHSIZE);
|
||||
duk_push_buffer_object(ctx, -1, 0, UTIL_MD5_HASHSIZE, DUK_BUFOBJ_NODEJS_BUFFER);
|
||||
|
||||
return(1);
|
||||
}
|
||||
|
||||
@@ -402,16 +362,14 @@ duk_ret_t ILibDuktape_MD5_Create(duk_context *ctx)
|
||||
ILibDuktape_EventEmitter *emitter;
|
||||
|
||||
duk_push_object(ctx); // [md5]
|
||||
ILibDuktape_WriteID(ctx, "MD5Stream");
|
||||
duk_push_fixed_buffer(ctx, sizeof(ILibDuktape_MD5_Data)); // [md5][buffer]
|
||||
data = (ILibDuktape_MD5_Data*)Duktape_GetBuffer(ctx, -1, NULL);
|
||||
duk_put_prop_string(ctx, -2, ILibDuktape_MD5_PTR); // [md5]
|
||||
emitter = ILibDuktape_EventEmitter_Create(ctx);
|
||||
|
||||
ILibDuktape_CreateInstanceMethodWithBooleanProperty(ctx, "strRet", 0, "syncHash", ILibDuktape_MD5_syncHash, 1);
|
||||
ILibDuktape_CreateInstanceMethodWithBooleanProperty(ctx, "strRet", 1, "syncHashString", ILibDuktape_MD5_syncHash, 1);
|
||||
|
||||
ILibDuktape_EventEmitter_CreateEventEx(emitter, "hash");
|
||||
ILibDuktape_EventEmitter_CreateEventEx(emitter, "hashString");
|
||||
|
||||
data->ctx = ctx;
|
||||
data->object = duk_get_heapptr(ctx, -1);
|
||||
@@ -426,6 +384,7 @@ duk_ret_t ILibDuktape_SHA256_Create(duk_context *ctx)
|
||||
ILibDuktape_EventEmitter *emitter;
|
||||
|
||||
duk_push_object(ctx); // [sha]
|
||||
ILibDuktape_WriteID(ctx, "SHA256Stream");
|
||||
duk_push_fixed_buffer(ctx, sizeof(ILibDuktape_SHA256_Data)); // [sha][buffer]
|
||||
data = (ILibDuktape_SHA256_Data*)Duktape_GetBuffer(ctx, -1, NULL);
|
||||
duk_put_prop_string(ctx, -2, ILibDuktape_SHA256_PTR); // [sha]
|
||||
@@ -433,11 +392,8 @@ duk_ret_t ILibDuktape_SHA256_Create(duk_context *ctx)
|
||||
|
||||
ILibDuktape_CreateFinalizer(ctx, ILibDuktape_SHA256_Finalizer);
|
||||
|
||||
ILibDuktape_CreateInstanceMethodWithBooleanProperty(ctx, "strRet", 0, "syncHash", ILibDuktape_SHA256_syncHash, 1);
|
||||
ILibDuktape_CreateInstanceMethodWithBooleanProperty(ctx, "strRet", 1, "syncHashString", ILibDuktape_SHA256_syncHash, 1);
|
||||
|
||||
ILibDuktape_CreateInstanceMethod(ctx, "syncHash", ILibDuktape_SHA256_syncHash, 1);
|
||||
ILibDuktape_EventEmitter_CreateEventEx(emitter, "hash");
|
||||
ILibDuktape_EventEmitter_CreateEventEx(emitter, "hashString");
|
||||
|
||||
data->ctx = ctx;
|
||||
data->object = duk_get_heapptr(ctx, -1);
|
||||
@@ -447,6 +403,70 @@ duk_ret_t ILibDuktape_SHA256_Create(duk_context *ctx)
|
||||
|
||||
return(1);
|
||||
}
|
||||
ILibTransport_DoneState ILibDuktape_SHA512_Write(struct ILibDuktape_WritableStream *stream, char *buffer, int bufferLen, void *user)
|
||||
{
|
||||
ILibDuktape_SHA512_Data *data = (ILibDuktape_SHA512_Data*)user;
|
||||
|
||||
SHA512_Update(&(data->shctx), buffer, bufferLen);
|
||||
return(ILibTransport_DoneState_COMPLETE);
|
||||
}
|
||||
void ILibDuktape_SHA512_End(struct ILibDuktape_WritableStream *stream, void *user)
|
||||
{
|
||||
ILibDuktape_SHA512_Data *data = (ILibDuktape_SHA512_Data*)user;
|
||||
SHA512_Final((unsigned char*)data->buffer, &(data->shctx));
|
||||
|
||||
duk_push_external_buffer(data->ctx); // [extBuffer]
|
||||
duk_config_buffer(data->ctx, -1, data->buffer, UTIL_SHA512_HASHSIZE);
|
||||
ILibDuktape_EventEmitter_SetupEmit(data->ctx, data->object, "hash"); // [extBuffer][emit][this]['hash']
|
||||
duk_push_buffer_object(data->ctx, -4, 0, UTIL_SHA512_HASHSIZE, DUK_BUFOBJ_NODEJS_BUFFER); // [extBuffer][emit][this]['hash'][hash]
|
||||
if (duk_pcall_method(data->ctx, 2) != 0) { ILibDuktape_Process_UncaughtException(data->ctx); }
|
||||
duk_pop_2(data->ctx); // ...
|
||||
}
|
||||
duk_ret_t ILibDuktape_SHA512_syncHash(duk_context *ctx)
|
||||
{
|
||||
ILibDuktape_SHA512_Data *data;
|
||||
duk_size_t bufferLen;
|
||||
char *buffer = Duktape_GetBuffer(ctx, 0, &bufferLen);
|
||||
|
||||
duk_push_this(ctx); // [sha]
|
||||
duk_get_prop_string(ctx, -1, ILibDuktape_SHA512_PTR);
|
||||
data = (ILibDuktape_SHA512_Data*)Duktape_GetBuffer(ctx, -1, NULL);
|
||||
|
||||
SHA512_Init(&(data->shctx));
|
||||
SHA512_Update(&(data->shctx), buffer, bufferLen);
|
||||
SHA512_Final((unsigned char*)data->buffer, &(data->shctx));
|
||||
|
||||
duk_push_external_buffer(ctx);
|
||||
duk_config_buffer(ctx, -1, data->buffer, UTIL_SHA512_HASHSIZE);
|
||||
duk_push_buffer_object(ctx, -1, 0, UTIL_SHA512_HASHSIZE, DUK_BUFOBJ_NODEJS_BUFFER);
|
||||
|
||||
return(1);
|
||||
}
|
||||
duk_ret_t ILibDuktape_SHA512_Create(duk_context *ctx)
|
||||
{
|
||||
ILibDuktape_SHA512_Data *data;
|
||||
ILibDuktape_EventEmitter *emitter;
|
||||
|
||||
duk_push_object(ctx); // [sha]
|
||||
ILibDuktape_WriteID(ctx, "SHA512Stream");
|
||||
duk_push_fixed_buffer(ctx, sizeof(ILibDuktape_SHA512_Data)); // [sha][buffer]
|
||||
data = (ILibDuktape_SHA512_Data*)Duktape_GetBuffer(ctx, -1, NULL);
|
||||
duk_put_prop_string(ctx, -2, ILibDuktape_SHA512_PTR); // [sha]
|
||||
emitter = ILibDuktape_EventEmitter_Create(ctx);
|
||||
|
||||
ILibDuktape_CreateFinalizer(ctx, ILibDuktape_SHA384_Finalizer);
|
||||
|
||||
ILibDuktape_CreateInstanceMethod(ctx, "syncHash", ILibDuktape_SHA512_syncHash, 1);
|
||||
ILibDuktape_EventEmitter_CreateEventEx(emitter, "hash");
|
||||
|
||||
data->ctx = ctx;
|
||||
data->object = duk_get_heapptr(ctx, -1);
|
||||
SHA512_Init(&(data->shctx));
|
||||
|
||||
ILibDuktape_WritableStream_Init(ctx, ILibDuktape_SHA512_Write, ILibDuktape_SHA512_End, data);
|
||||
|
||||
return(1);
|
||||
}
|
||||
duk_ret_t ILibDuktape_SHA384_Create(duk_context *ctx)
|
||||
{
|
||||
ILibDuktape_SHA512_Data *data;
|
||||
@@ -461,11 +481,8 @@ duk_ret_t ILibDuktape_SHA384_Create(duk_context *ctx)
|
||||
|
||||
ILibDuktape_CreateFinalizer(ctx, ILibDuktape_SHA384_Finalizer);
|
||||
|
||||
ILibDuktape_CreateInstanceMethodWithBooleanProperty(ctx, "strRet", 0, "syncHash", ILibDuktape_SHA384_syncHash, 1);
|
||||
ILibDuktape_CreateInstanceMethodWithBooleanProperty(ctx, "strRet", 1, "syncHashString", ILibDuktape_SHA384_syncHash, 1);
|
||||
|
||||
ILibDuktape_CreateInstanceMethod(ctx, "syncHash", ILibDuktape_SHA384_syncHash, 1);
|
||||
ILibDuktape_EventEmitter_CreateEventEx(emitter, "hash");
|
||||
ILibDuktape_EventEmitter_CreateEventEx(emitter, "hashString");
|
||||
|
||||
data->ctx = ctx;
|
||||
data->object = duk_get_heapptr(ctx, -1);
|
||||
@@ -475,6 +492,70 @@ duk_ret_t ILibDuktape_SHA384_Create(duk_context *ctx)
|
||||
|
||||
return(1);
|
||||
}
|
||||
ILibTransport_DoneState ILibDuktape_SHA1_Write(struct ILibDuktape_WritableStream *stream, char *buffer, int bufferLen, void *user)
|
||||
{
|
||||
ILibDuktape_SHA1_Data *data = (ILibDuktape_SHA1_Data*)user;
|
||||
|
||||
SHA1_Update(&(data->sctx), buffer, bufferLen);
|
||||
return(ILibTransport_DoneState_COMPLETE);
|
||||
}
|
||||
void ILibDuktape_SHA1_End(struct ILibDuktape_WritableStream *stream, void *user)
|
||||
{
|
||||
ILibDuktape_SHA1_Data *data = (ILibDuktape_SHA1_Data*)user;
|
||||
SHA1_Final((unsigned char*)data->buffer, &(data->sctx));
|
||||
|
||||
duk_push_external_buffer(data->ctx); // [extBuffer]
|
||||
duk_config_buffer(data->ctx, -1, data->buffer, UTIL_SHA1_HASHSIZE);
|
||||
ILibDuktape_EventEmitter_SetupEmit(data->ctx, data->object, "hash"); // [extBuffer][emit][this]["hash"]
|
||||
duk_push_buffer_object(data->ctx, -4, 0, UTIL_SHA1_HASHSIZE, DUK_BUFOBJ_NODEJS_BUFFER); // [extBuffer][emit][this]["hash"][buffer]
|
||||
if (duk_pcall_method(data->ctx, 2) != 0) // [extBuffer][retVal]
|
||||
{
|
||||
ILibDuktape_Process_UncaughtException(data->ctx);
|
||||
}
|
||||
duk_pop_2(data->ctx); // ...
|
||||
}
|
||||
duk_ret_t ILibDuktape_SHA1_syncHash(duk_context *ctx)
|
||||
{
|
||||
ILibDuktape_SHA1_Data *data;
|
||||
duk_size_t bufferLen;
|
||||
char *buffer = Duktape_GetBuffer(ctx, 0, &bufferLen);
|
||||
|
||||
duk_push_this(ctx); // [sha]
|
||||
duk_get_prop_string(ctx, -1, ILibDuktape_SHA1_PTR);
|
||||
data = (ILibDuktape_SHA1_Data*)Duktape_GetBuffer(ctx, -1, NULL);
|
||||
|
||||
SHA1_Init(&(data->sctx));
|
||||
SHA1_Update(&(data->sctx), buffer, bufferLen);
|
||||
SHA1_Final((unsigned char*)data->buffer, &(data->sctx));
|
||||
|
||||
duk_push_external_buffer(ctx);
|
||||
duk_config_buffer(ctx, -1, data->buffer, UTIL_SHA1_HASHSIZE);
|
||||
duk_push_buffer_object(ctx, -1, 0, UTIL_SHA1_HASHSIZE, DUK_BUFOBJ_NODEJS_BUFFER);
|
||||
|
||||
return(1);
|
||||
}
|
||||
duk_ret_t ILibDuktape_SHA1_Create(duk_context *ctx)
|
||||
{
|
||||
ILibDuktape_SHA1_Data *data;
|
||||
ILibDuktape_EventEmitter *emitter;
|
||||
|
||||
duk_push_object(ctx); // [SHA]
|
||||
ILibDuktape_WriteID(ctx, "SHA1Stream");
|
||||
duk_push_fixed_buffer(ctx, sizeof(ILibDuktape_SHA1_Data)); // [SHA][buffer]
|
||||
data = (ILibDuktape_SHA1_Data*)Duktape_GetBuffer(ctx, -1, NULL);
|
||||
duk_put_prop_string(ctx, -2, ILibDuktape_SHA1_PTR); // [SHA]
|
||||
emitter = ILibDuktape_EventEmitter_Create(ctx);
|
||||
|
||||
ILibDuktape_CreateInstanceMethod(ctx, "syncHash", ILibDuktape_SHA1_syncHash, 1);
|
||||
ILibDuktape_EventEmitter_CreateEventEx(emitter, "hash");
|
||||
|
||||
data->ctx = ctx;
|
||||
data->object = duk_get_heapptr(ctx, -1);
|
||||
SHA1_Init(&(data->sctx));
|
||||
|
||||
ILibDuktape_WritableStream_Init(ctx, ILibDuktape_SHA1_Write, ILibDuktape_SHA1_End, data);
|
||||
return(1);
|
||||
}
|
||||
void ILibDuktape_SHA256_PUSH(duk_context *ctx, void *chain)
|
||||
{
|
||||
duk_push_object(ctx); // [sha]
|
||||
@@ -485,21 +566,34 @@ void ILibDuktape_SHA384_PUSH(duk_context *ctx, void *chain)
|
||||
duk_push_object(ctx); // [sha]
|
||||
ILibDuktape_CreateInstanceMethod(ctx, "create", ILibDuktape_SHA384_Create, 0);
|
||||
}
|
||||
void ILibDuktape_SHA512_PUSH(duk_context *ctx, void *chain)
|
||||
{
|
||||
duk_push_object(ctx); // [sha]
|
||||
ILibDuktape_CreateInstanceMethod(ctx, "create", ILibDuktape_SHA512_Create, 0);
|
||||
}
|
||||
void ILibDuktape_MD5_PUSH(duk_context *ctx, void *chain)
|
||||
{
|
||||
duk_push_object(ctx); // [md5]
|
||||
ILibDuktape_CreateInstanceMethod(ctx, "create", ILibDuktape_MD5_Create, 0);
|
||||
}
|
||||
#endif
|
||||
void ILibDuktape_SHA1_PUSH(duk_context *ctx, void *chain)
|
||||
{
|
||||
duk_push_object(ctx); // [md5]
|
||||
ILibDuktape_CreateInstanceMethod(ctx, "create", ILibDuktape_SHA1_Create, 0);
|
||||
}
|
||||
|
||||
void ILibDuktape_SHA256_Init(duk_context * ctx)
|
||||
{
|
||||
#ifndef MICROSTACK_NOTLS
|
||||
ILibDuktape_ModSearch_AddHandler(ctx, "SHA256Stream_Signer", ILibDuktape_SHA256_SIGNER_PUSH);
|
||||
ILibDuktape_ModSearch_AddHandler(ctx, "SHA256Stream_Verifier", ILibDuktape_SHA256_VERIFY_PUSH);
|
||||
#endif
|
||||
ILibDuktape_ModSearch_AddHandler(ctx, "SHA512Stream", ILibDuktape_SHA512_PUSH);
|
||||
ILibDuktape_ModSearch_AddHandler(ctx, "SHA384Stream", ILibDuktape_SHA384_PUSH);
|
||||
ILibDuktape_ModSearch_AddHandler(ctx, "SHA256Stream", ILibDuktape_SHA256_PUSH);
|
||||
ILibDuktape_ModSearch_AddHandler(ctx, "MD5Stream", ILibDuktape_MD5_PUSH);
|
||||
#endif
|
||||
ILibDuktape_ModSearch_AddHandler(ctx, "SHA1Stream", ILibDuktape_SHA1_PUSH);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -567,4 +661,4 @@ public:
|
||||
*/
|
||||
void hashString;
|
||||
};
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -23,4 +23,4 @@ limitations under the License.
|
||||
void ILibDuktape_SHA256_Init(duk_context *ctx);
|
||||
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -114,6 +114,7 @@ public:
|
||||
|
||||
typedef enum SCRIPT_ENGINE_SECURITY_FLAGS
|
||||
{
|
||||
SCRIPT_ENGINE_NO_DEBUGGER = 0x20000000,
|
||||
SCRIPT_ENGINE_NO_MESH_AGENT_ACCESS = 0x10000000,
|
||||
SCRIPT_ENGINE_NO_GENERIC_MARSHAL_ACCESS = 0x08000000,
|
||||
SCRIPT_ENGINE_NO_PROCESS_SPAWNING = 0x04000000,
|
||||
@@ -140,7 +141,9 @@ typedef struct SCRIPT_ENGINE_SETTINGS
|
||||
}SCRIPT_ENGINE_SETTINGS;
|
||||
|
||||
|
||||
void ILibDuktape_ScriptContainer_CheckEmbedded(char **argv, char **script, int *scriptLen);
|
||||
void ILibDuktape_ScriptContainer_CheckEmbedded(char **script, int *scriptLen);
|
||||
void ILibDuktape_ScriptContainer_CheckEmbeddedEx(char *exePath, char **script, int *scriptLen);
|
||||
|
||||
void ILibDuktape_ScriptContainer_InitMaster(void *chain, char *exePath, ILibProcessPipe_Manager manager);
|
||||
int ILibDuktape_ScriptContainer_StartSlave(void *chain, ILibProcessPipe_Manager manager);
|
||||
|
||||
@@ -149,12 +152,12 @@ duk_context *ILibDuktape_ScriptContainer_InitializeJavaScriptEngineEx3(duk_conte
|
||||
duk_context *ILibDuktape_ScriptContainer_InitializeJavaScriptEngineEx2(SCRIPT_ENGINE_SETTINGS *settings);
|
||||
#define ILibDuktape_ScriptContainer_InitializeJavaScriptEngineEx(securityFlags, executionTimeout, chain, argList, db, exePath, pipeManager, exitHandler, exitUser) ILibDuktape_ScriptContainer_InitializeJavaScriptEngineEx3(ILibDuktape_ScriptContainer_InitializeJavaScriptEngine_minimal(), (securityFlags), (executionTimeout), (chain), (argList), (db), (exePath), (pipeManager), (exitHandler), (exitUser))
|
||||
#define ILibDuktape_ScriptContainer_InitializeJavaScriptEngine(securityFlags, executionTimeout, chain, pp_argList, db, exitHandler, exitUser) ILibDuktape_ScriptContainer_InitializeJavaScriptEngineEx((securityFlags), (executionTimeout), (chain), (pp_argList), (db), NULL, NULL, (exitHandler), (exitUser))
|
||||
int ILibDuktape_ScriptContainer_DebuggingOK(duk_context *ctx);
|
||||
|
||||
SCRIPT_ENGINE_SETTINGS *ILibDuktape_ScriptContainer_GetSettings(duk_context *ctx);
|
||||
|
||||
int ILibDuktape_ScriptContainer_CompileJavaScript(duk_context *ctx, char *payload, int payloadLen);
|
||||
int ILibDuktape_ScriptContainer_CompileJavaScript_FromFile(duk_context *ctx, char *path, int pathLen);
|
||||
int ILibDuktape_ScriptContainer_CompileJavaScriptEx(duk_context *ctx, char *payload, int payloadLen, char *filename, int filenameLen);
|
||||
#define ILibDuktape_ScriptContainer_CompileJavaScript(ctx, payload, payloadLen) ILibDuktape_ScriptContainer_CompileJavaScriptEx(ctx, payload, payloadLen, NULL, 0)
|
||||
int ILibDuktape_ScriptContainer_ExecuteByteCode(duk_context *ctx);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -125,6 +125,10 @@ duk_ret_t ILibDuktape_SimpleDataStore_Get(duk_context *ctx)
|
||||
duk_push_string(ctx, buffer);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
duk_push_buffer_object(ctx, -1, 0, bufferSize, DUK_BUFOBJ_NODEJS_BUFFER);
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
@@ -295,4 +299,4 @@ public:
|
||||
*/
|
||||
static SimpleDataStore Shared();
|
||||
};
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -24,4 +24,4 @@ limitations under the License.
|
||||
void ILibDuktape_SimpleDataStore_init(duk_context *ctx, ILibSimpleDataStore sharedDb);
|
||||
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -91,9 +91,9 @@ duk_idx_t ILibWebRTC_Duktape_Connection_AddRemoteCandidate(duk_context *ctx)
|
||||
if (strcmp(Duktape_GetStringPropertyValue(ctx, 0, "Family", "IPv4"), "IPv4") == 0)
|
||||
{
|
||||
candidate = Duktape_IPAddress4_FromString(Duktape_GetStringPropertyValue(ctx, 0, "Address", "127.0.0.1"), (unsigned short)Duktape_GetIntPropertyValue(ctx, 0, "Port", 65535));
|
||||
username = ILibWrapper_WebRTC_Connection_GetLocalUsername(connection);
|
||||
ILibORTC_AddRemoteCandidate(ILibWrapper_WebRTC_Connection_GetStunModule(connection), username, candidate);
|
||||
}
|
||||
username = ILibWrapper_WebRTC_Connection_GetLocalUsername(connection);
|
||||
ILibORTC_AddRemoteCandidate(ILibWrapper_WebRTC_Connection_GetStunModule(connection), username, candidate);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -115,7 +115,7 @@ ILibTransport_DoneState ILibDuktape_WebRTC_DataChannel_Stream_WriteSink(ILibDukt
|
||||
ILibDuktape_WebRTC_DataChannel *ptrs = (ILibDuktape_WebRTC_DataChannel*)user;
|
||||
if (ptrs->dataChannel != NULL)
|
||||
{
|
||||
return(ILibWrapper_WebRTC_DataChannel_Send(ptrs->dataChannel, buffer, bufferLen));
|
||||
return(ILibWrapper_WebRTC_DataChannel_SendEx(ptrs->dataChannel, buffer, bufferLen, stream->writableStream->Reserved == 1 ? 51 : 53));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -174,7 +174,7 @@ duk_ret_t ILibDuktape_WebRTC_DataChannel_Finalizer(duk_context *ctx)
|
||||
ILibDuktape_WebRTC_DataChannel *ptrs = (ILibDuktape_WebRTC_DataChannel*)Duktape_GetBuffer(ctx, -1, NULL);
|
||||
if (ptrs->dataChannel != NULL)
|
||||
{
|
||||
printf("WebRTC Data Channel Finalizer on Connection: %p\n", ptrs->dataChannel->parent);
|
||||
//printf("WebRTC Data Channel Finalizer on Connection: %p\n", ptrs->dataChannel->parent);
|
||||
ptrs->dataChannel->userData = NULL;
|
||||
ILibWrapper_WebRTC_DataChannel_Close(ptrs->dataChannel);
|
||||
}
|
||||
@@ -221,7 +221,7 @@ duk_ret_t ILibDuktape_WebRTC_ConnectionFactory_Finalizer(duk_context *ctx)
|
||||
duk_get_prop_string(ctx, 0, ILibDuktape_WebRTC_ConnectionFactoryPtr);
|
||||
factory = (ILibWrapper_WebRTC_ConnectionFactory)duk_get_pointer(ctx, -1);
|
||||
|
||||
printf("WebRTC Factory Finalizer: %p\n", factory);
|
||||
//printf("WebRTC Factory Finalizer: %p\n", factory);
|
||||
|
||||
if (factory != NULL && ILibIsChainBeingDestroyed(chain) == 0)
|
||||
{
|
||||
@@ -299,7 +299,9 @@ void ILibDuktape_WebRTC_Connection_Debug(void* dtlsSession, char* debugField, in
|
||||
#endif
|
||||
void ILibDuktape_WebRTC_OnConnection(ILibWrapper_WebRTC_Connection connection, int connected)
|
||||
{
|
||||
ILibWebRTC_Duktape_Handlers *ptrs = (ILibWebRTC_Duktape_Handlers*)ILibMemory_GetExtraMemory(connection, ILibMemory_WebRTC_Connection_CONTAINERSIZE);
|
||||
ILibWebRTC_Duktape_Handlers *ptrs = (ILibWebRTC_Duktape_Handlers*)ILibMemory_Extra(connection);
|
||||
if (!ILibMemory_CanaryOK(ptrs->emitter)) { return; }
|
||||
|
||||
if (connected == 0)
|
||||
{
|
||||
ILibDuktape_EventEmitter_SetupEmit(ptrs->ctx, ptrs->ConnectionObject, "disconnected"); // [emit][this][disconnected]
|
||||
@@ -348,23 +350,28 @@ void ILibDuktape_WebRTC_OnConnection(ILibWrapper_WebRTC_Connection connection, i
|
||||
|
||||
void ILibDuktape_WebRTC_OnDataChannel(ILibWrapper_WebRTC_Connection connection, ILibWrapper_WebRTC_DataChannel *dataChannel)
|
||||
{
|
||||
ILibWebRTC_Duktape_Handlers *ptrs = (ILibWebRTC_Duktape_Handlers*)ILibMemory_GetExtraMemory(connection, ILibMemory_WebRTC_Connection_CONTAINERSIZE);
|
||||
|
||||
ILibDuktape_EventEmitter_SetupEmit(ptrs->ctx, ptrs->ConnectionObject, "dataChannel"); // [emit][this][dataChannel]
|
||||
ILibDuktape_WebRTC_DataChannel_PUSH(ptrs->ctx, dataChannel); // [emit][this][dataChannel][dc]
|
||||
if (duk_pcall_method(ptrs->ctx, 2) != 0) { ILibDuktape_Process_UncaughtExceptionEx(ptrs->ctx, "webrtc.connection.onDataChannel(): "); }
|
||||
duk_pop(ptrs->ctx); // ...
|
||||
ILibWebRTC_Duktape_Handlers *ptrs = (ILibWebRTC_Duktape_Handlers*)ILibMemory_Extra(connection);
|
||||
if (ILibMemory_CanaryOK(ptrs->emitter))
|
||||
{
|
||||
ILibDuktape_EventEmitter_SetupEmit(ptrs->ctx, ptrs->ConnectionObject, "dataChannel"); // [emit][this][dataChannel]
|
||||
ILibDuktape_WebRTC_DataChannel_PUSH(ptrs->ctx, dataChannel); // [emit][this][dataChannel][dc]
|
||||
if (duk_pcall_method(ptrs->ctx, 2) != 0) { ILibDuktape_Process_UncaughtExceptionEx(ptrs->ctx, "webrtc.connection.onDataChannel(): "); }
|
||||
duk_pop(ptrs->ctx); // ...
|
||||
}
|
||||
}
|
||||
|
||||
void ILibDuktape_WebRTC_offer_onCandidate(ILibWrapper_WebRTC_Connection connection, struct sockaddr_in6* candidate)
|
||||
{
|
||||
if (candidate != NULL)
|
||||
{
|
||||
ILibWebRTC_Duktape_Handlers *ptrs = (ILibWebRTC_Duktape_Handlers*)ILibMemory_GetExtraMemory(connection, ILibMemory_WebRTC_Connection_CONTAINERSIZE);
|
||||
ILibDuktape_EventEmitter_SetupEmit(ptrs->ctx, ptrs->ConnectionObject, "candidate"); // [emit][this][candidate]
|
||||
ILibDuktape_SockAddrToOptions(ptrs->ctx, candidate); // [emit][this][candidate][options]
|
||||
if (duk_pcall_method(ptrs->ctx, 2) != 0) { ILibDuktape_Process_UncaughtExceptionEx(ptrs->ctx, "webrtc.connection.onCandidate(): "); }
|
||||
duk_pop(ptrs->ctx); // ...
|
||||
ILibWebRTC_Duktape_Handlers *ptrs = (ILibWebRTC_Duktape_Handlers*)ILibMemory_Extra(connection);
|
||||
if (ILibMemory_CanaryOK(ptrs->emitter))
|
||||
{
|
||||
ILibDuktape_EventEmitter_SetupEmit(ptrs->ctx, ptrs->ConnectionObject, "candidate"); // [emit][this][candidate]
|
||||
ILibDuktape_SockAddrToOptions(ptrs->ctx, candidate); // [emit][this][candidate][options]
|
||||
if (duk_pcall_method(ptrs->ctx, 2) != 0) { ILibDuktape_Process_UncaughtExceptionEx(ptrs->ctx, "webrtc.connection.onCandidate(): "); }
|
||||
duk_pop(ptrs->ctx); // ...
|
||||
}
|
||||
}
|
||||
}
|
||||
duk_ret_t ILibDuktape_WebRTC_generateOffer(duk_context *ctx)
|
||||
@@ -468,7 +475,7 @@ duk_ret_t ILibDuktape_WebRTC_Connection_Finalizer(duk_context *ctx)
|
||||
ILibWrapper_WebRTC_Connection connection;
|
||||
duk_get_prop_string(ctx, 0, ILibDuktape_WebRTC_ConnectionPtr);
|
||||
connection = (ILibWrapper_WebRTC_Connection)duk_get_pointer(ctx, -1);
|
||||
printf("WebRTCConnection Finalizer on %p\n", (void*)connection);
|
||||
//printf("WebRTCConnection Finalizer on %p\n", (void*)connection);
|
||||
if (connection == NULL) { return 0; }
|
||||
|
||||
#ifdef _WEBRTCDEBUG
|
||||
@@ -495,7 +502,7 @@ duk_ret_t ILibDuktape_WebRTC_CreateConnection(duk_context *ctx)
|
||||
duk_push_object(ctx); // [factory][connection]
|
||||
ILibDuktape_WriteID(ctx, "webRTC.peerConnection");
|
||||
connection = ILibWrapper_WebRTC_ConnectionFactory_CreateConnection2(factory, ILibDuktape_WebRTC_OnConnection, ILibDuktape_WebRTC_OnDataChannel, NULL, sizeof(ILibWebRTC_Duktape_Handlers));
|
||||
ptrs = (ILibWebRTC_Duktape_Handlers*)ILibMemory_GetExtraMemory(connection, ILibMemory_WebRTC_Connection_CONTAINERSIZE);
|
||||
ptrs = (ILibWebRTC_Duktape_Handlers*)ILibMemory_Extra(connection);
|
||||
ptrs->ctx = ctx;
|
||||
ptrs->ConnectionObject = duk_get_heapptr(ctx, -1);
|
||||
ptrs->emitter = ILibDuktape_EventEmitter_Create(ctx);
|
||||
@@ -645,4 +652,4 @@ public:
|
||||
void ack;
|
||||
};
|
||||
};
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -304,12 +304,8 @@ ILibDuktape_WritableStream* ILibDuktape_WritableStream_Init(duk_context *ctx, IL
|
||||
ILibDuktape_WritableStream *retVal;
|
||||
ILibDuktape_EventEmitter *emitter;
|
||||
|
||||
ILibDuktape_PointerValidation_Init(ctx);
|
||||
duk_push_fixed_buffer(ctx, sizeof(ILibDuktape_WritableStream)); // [obj][buffer]
|
||||
retVal = (ILibDuktape_WritableStream*)Duktape_GetBuffer(ctx, -1, NULL); // [obj][buffer]
|
||||
memset(retVal, 0, sizeof(ILibDuktape_WritableStream));
|
||||
|
||||
duk_put_prop_string(ctx, -2, ILibDuktape_WritableStream_WSPTRS); // [obj]
|
||||
retVal = (ILibDuktape_WritableStream*)Duktape_PushBuffer(ctx, sizeof(ILibDuktape_WritableStream)); // [obj][buffer]
|
||||
duk_put_prop_string(ctx, -2, ILibDuktape_WritableStream_WSPTRS); // [obj]
|
||||
|
||||
retVal->ctx = ctx;
|
||||
retVal->obj = duk_get_heapptr(ctx, -1);
|
||||
|
||||
@@ -55,5 +55,4 @@ typedef struct ILibDuktape_WritableStream
|
||||
ILibDuktape_WritableStream* ILibDuktape_WritableStream_Init(duk_context *ctx, ILibDuktape_WritableStream_WriteHandler WriteHandler, ILibDuktape_WritableStream_EndHandler EndHandler, void *user);
|
||||
void ILibDuktape_WritableStream_Ready(ILibDuktape_WritableStream *stream);
|
||||
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -20,6 +20,7 @@ limitations under the License.
|
||||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
#include <direct.h>
|
||||
#include <wchar.h>
|
||||
#endif
|
||||
|
||||
#include "microstack/ILibParsers.h"
|
||||
@@ -88,6 +89,7 @@ typedef struct ILibDuktape_fs_readStreamData
|
||||
int bytesRead;
|
||||
int bytesLeft;
|
||||
int readLoopActive;
|
||||
int unshiftedBytes;
|
||||
char buffer[FS_READSTREAM_BUFFERSIZE];
|
||||
}ILibDuktape_fs_readStreamData;
|
||||
|
||||
@@ -194,7 +196,7 @@ int ILibDuktape_fs_openSyncEx(duk_context *ctx, char *path, char *flags, char *m
|
||||
|
||||
sprintf_s(ILibScratchPad, sizeof(ILibScratchPad), "%d", retVal);
|
||||
#ifdef WIN32
|
||||
fopen_s(&f, path, flags);
|
||||
_wfopen_s(&f, (const wchar_t*)ILibDuktape_String_UTF8ToWide(ctx, path), (const wchar_t*)ILibDuktape_String_UTF8ToWide(ctx, flags));
|
||||
#else
|
||||
f = fopen(path, flags);
|
||||
#endif
|
||||
@@ -439,6 +441,8 @@ void ILibDuktape_fs_readStream_Pause(struct ILibDuktape_readableStream *sender,
|
||||
}
|
||||
void ILibDuktape_fs_readStream_Resume(struct ILibDuktape_readableStream *sender, void *user)
|
||||
{
|
||||
if (!ILibMemory_CanaryOK(user)) { return; }
|
||||
|
||||
ILibDuktape_fs_readStreamData *data = (ILibDuktape_fs_readStreamData*)user;
|
||||
int bytesToRead;
|
||||
|
||||
@@ -447,14 +451,22 @@ void ILibDuktape_fs_readStream_Resume(struct ILibDuktape_readableStream *sender,
|
||||
sender->paused = 0;
|
||||
|
||||
if (data->bytesRead == -1) { data->bytesRead = 1; }
|
||||
data->unshiftedBytes = 0;
|
||||
while (sender->paused == 0 && data->bytesRead > 0 && (data->bytesLeft < 0 || data->bytesLeft > 0))
|
||||
{
|
||||
bytesToRead = data->bytesLeft < 0 ? sizeof(data->buffer) : (data->bytesLeft > sizeof(data->buffer) ? sizeof(data->buffer) : data->bytesLeft);
|
||||
data->bytesRead = (int)fread(data->buffer, 1, bytesToRead, data->fPtr);
|
||||
bytesToRead = data->bytesLeft < 0 ? (int)sizeof(data->buffer) : (data->bytesLeft > ((int)sizeof(data->buffer) - data->unshiftedBytes) ? (int)sizeof(data->buffer) - data->unshiftedBytes : data->bytesLeft);
|
||||
data->bytesRead = (int)fread(data->buffer + data->unshiftedBytes, 1, bytesToRead, data->fPtr);
|
||||
if (data->bytesRead > 0)
|
||||
{
|
||||
if (data->bytesLeft > 0) { data->bytesLeft -= data->bytesRead; }
|
||||
ILibDuktape_readableStream_WriteData(sender, data->buffer, data->bytesRead);
|
||||
data->bytesRead += data->unshiftedBytes; data->unshiftedBytes = 0;
|
||||
do
|
||||
{
|
||||
int preshift = data->unshiftedBytes == 0 ? data->bytesRead : data->unshiftedBytes;
|
||||
ILibDuktape_readableStream_WriteData(sender, data->buffer, data->unshiftedBytes>0 ? data->unshiftedBytes : data->bytesRead);
|
||||
if (data->unshiftedBytes > 0 && data->unshiftedBytes != preshift) { memmove(data->buffer, data->buffer + (preshift - data->unshiftedBytes), data->unshiftedBytes); }
|
||||
} while (data->unshiftedBytes != 0 && data->unshiftedBytes != data->bytesRead);
|
||||
data->unshiftedBytes = 0;
|
||||
if (data->bytesLeft == 0) { data->bytesRead = 0; }
|
||||
}
|
||||
}
|
||||
@@ -502,6 +514,13 @@ duk_ret_t ILibDuktape_fs_readStream_finalizer(duk_context *ctx)
|
||||
|
||||
return 0;
|
||||
}
|
||||
int ILibDuktape_fs_readStream_unshift(struct ILibDuktape_readableStream *sender, int unshiftBytes, void *user)
|
||||
{
|
||||
if (!ILibMemory_CanaryOK(user)) { return(unshiftBytes); }
|
||||
ILibDuktape_fs_readStreamData *data = (ILibDuktape_fs_readStreamData*)user;
|
||||
data->unshiftedBytes = unshiftBytes;
|
||||
return(unshiftBytes);
|
||||
}
|
||||
duk_ret_t ILibDuktape_fs_createReadStream(duk_context *ctx)
|
||||
{
|
||||
int nargs = duk_get_top(ctx);
|
||||
@@ -545,9 +564,7 @@ duk_ret_t ILibDuktape_fs_createReadStream(duk_context *ctx)
|
||||
|
||||
duk_push_object(ctx); // [readStream]
|
||||
ILibDuktape_WriteID(ctx, "fs.readStream");
|
||||
duk_push_fixed_buffer(ctx, sizeof(ILibDuktape_fs_readStreamData)); // [readStream][buffer]
|
||||
data = (ILibDuktape_fs_readStreamData*)Duktape_GetBuffer(ctx, -1, NULL);
|
||||
memset(data, 0, sizeof(ILibDuktape_fs_readStreamData));
|
||||
data = (ILibDuktape_fs_readStreamData*)Duktape_PushBuffer(ctx, sizeof(ILibDuktape_fs_readStreamData));
|
||||
duk_put_prop_string(ctx, -2, FS_READSTREAM); // [readStream]
|
||||
duk_push_this(ctx); // [readStream][fs]
|
||||
data->fsObject = duk_get_heapptr(ctx, -1);
|
||||
@@ -560,7 +577,8 @@ duk_ret_t ILibDuktape_fs_createReadStream(duk_context *ctx)
|
||||
data->ReadStreamObject = duk_get_heapptr(ctx, -1);
|
||||
data->bytesLeft = end < 0 ? end : (end - start + 1);
|
||||
data->bytesRead = -1;
|
||||
data->stream = ILibDuktape_ReadableStream_Init(ctx, ILibDuktape_fs_readStream_Pause, ILibDuktape_fs_readStream_Resume, data);
|
||||
//data->stream = ILibDuktape_ReadableStream_Init(ctx, ILibDuktape_fs_readStream_Pause, ILibDuktape_fs_readStream_Resume, data);
|
||||
data->stream = ILibDuktape_ReadableStream_InitEx(ctx, ILibDuktape_fs_readStream_Pause, ILibDuktape_fs_readStream_Resume, ILibDuktape_fs_readStream_unshift, data);
|
||||
data->stream->paused = 1;
|
||||
|
||||
//printf("readStream [start: %d, end: %d\n", start, end);
|
||||
@@ -591,8 +609,11 @@ duk_ret_t ILibDuktape_fs_readdirSync(duk_context *ctx)
|
||||
int i = 0;
|
||||
#ifdef WIN32
|
||||
HANDLE h;
|
||||
WIN32_FIND_DATA data;
|
||||
char *path = (char*)duk_require_string(ctx, 0);
|
||||
WIN32_FIND_DATAW data;
|
||||
duk_size_t pathLen;
|
||||
char *path = (char*)ILibDuktape_String_AsWide(ctx, 0, &pathLen);
|
||||
//char *path = (char*)duk_require_string(ctx, 0);
|
||||
|
||||
#else
|
||||
char *path = ILibDuktape_fs_fixLinuxPath((char*)duk_require_string(ctx, 0));
|
||||
struct dirent *dir;
|
||||
@@ -602,20 +623,22 @@ duk_ret_t ILibDuktape_fs_readdirSync(duk_context *ctx)
|
||||
duk_push_array(ctx); // [retVal]
|
||||
|
||||
#ifdef WIN32
|
||||
h = FindFirstFile(path, &data);
|
||||
h = FindFirstFileW((LPCWSTR)path, &data);
|
||||
if (h != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
if (strcmp(data.cFileName, ".") != 0)
|
||||
if (wcscmp(data.cFileName, L".") != 0)
|
||||
{
|
||||
duk_push_string(ctx, data.cFileName); // [retVal][val]
|
||||
ILibDuktape_String_PushWideString(ctx, (char*)data.cFileName, 0); // [retVal][val]
|
||||
//duk_push_string(ctx, data.cFileName); // [retVal][val]
|
||||
duk_put_prop_index(ctx, -2, i++); // [retVal]
|
||||
}
|
||||
while (FindNextFile(h, &data))
|
||||
while (FindNextFileW(h, &data))
|
||||
{
|
||||
if (strcmp(data.cFileName, "..") != 0)
|
||||
if (wcscmp(data.cFileName, L"..") != 0)
|
||||
{
|
||||
duk_push_string(ctx, data.cFileName); // [retVal][val]
|
||||
duk_put_prop_index(ctx, -2, i++); // [retVal]
|
||||
ILibDuktape_String_PushWideString(ctx, (char*)data.cFileName, 0); // [retVal][val]
|
||||
//duk_push_string(ctx, data.cFileName); // [retVal][val]
|
||||
duk_put_prop_index(ctx, -2, i++); // [retVal]
|
||||
}
|
||||
}
|
||||
FindClose(h);
|
||||
@@ -627,8 +650,11 @@ duk_ret_t ILibDuktape_fs_readdirSync(duk_context *ctx)
|
||||
{
|
||||
while ((dir = readdir(d)) != NULL)
|
||||
{
|
||||
duk_push_string(ctx, dir->d_name);
|
||||
duk_put_prop_index(ctx, -2, i++);
|
||||
if (strcmp(dir->d_name, ".") != 0 && strcmp(dir->d_name, "..") != 0)
|
||||
{
|
||||
duk_push_string(ctx, dir->d_name);
|
||||
duk_put_prop_index(ctx, -2, i++);
|
||||
}
|
||||
}
|
||||
closedir(d);
|
||||
}
|
||||
@@ -671,13 +697,13 @@ char *ILibDuktape_fs_convertTime(uint64_t st, char *dest, int destLen)
|
||||
|
||||
duk_ret_t ILibDuktape_fs_statSync(duk_context *ctx)
|
||||
{
|
||||
#ifdef WIN32
|
||||
char *path = (char*)duk_require_string(ctx, 0);
|
||||
#ifdef WIN32
|
||||
char *path = ILibDuktape_String_AsWide(ctx, 0, NULL);
|
||||
char data[4096];
|
||||
WIN32_FILE_ATTRIBUTE_DATA *attr = (WIN32_FILE_ATTRIBUTE_DATA*)data;
|
||||
SYSTEMTIME stime;
|
||||
|
||||
if(GetFileAttributesEx(path, GetFileExInfoStandard, (void*)data) == 0)
|
||||
if(GetFileAttributesExW((LPCWSTR)path, GetFileExInfoStandard, (void*)data) == 0)
|
||||
{
|
||||
duk_push_string(ctx, "fs.statSync(): Invalid path");
|
||||
duk_throw(ctx);
|
||||
@@ -726,6 +752,9 @@ duk_ret_t ILibDuktape_fs_statSync(duk_context *ctx)
|
||||
duk_push_string(ctx, ILibDuktape_fs_convertTime(result.st_atime, ILibScratchPad, sizeof(ILibScratchPad)));
|
||||
duk_put_prop_string(ctx, -2, "atime");
|
||||
|
||||
duk_push_int(ctx, result.st_mode);
|
||||
ILibDuktape_CreateReadonlyProperty(ctx, "mode");
|
||||
|
||||
ILibDuktape_CreateInstanceMethodWithBooleanProperty(ctx, FS_STAT_METHOD_RETVAL, S_ISDIR(result.st_mode) || S_ISBLK(result.st_mode) ? 1 : 0, "isDirectory", ILibDuktape_fs_statSyncEx, 0);
|
||||
ILibDuktape_CreateInstanceMethodWithBooleanProperty(ctx, FS_STAT_METHOD_RETVAL, S_ISREG(result.st_mode) ? 1 : 0, "isFile", ILibDuktape_fs_statSyncEx, 0);
|
||||
|
||||
@@ -1093,10 +1122,8 @@ duk_ret_t ILibDuktape_fs_watch(duk_context *ctx)
|
||||
|
||||
duk_push_object(ctx); // [FSWatcher]
|
||||
ILibDuktape_WriteID(ctx, "fs.fsWatcher");
|
||||
duk_push_fixed_buffer(ctx, sizeof(ILibDuktape_fs_watcherData)); // [FSWatcher][data]
|
||||
data = (ILibDuktape_fs_watcherData*)Duktape_GetBuffer(ctx, -1, NULL);
|
||||
data = (ILibDuktape_fs_watcherData*)Duktape_PushBuffer(ctx, sizeof(ILibDuktape_fs_watcherData));
|
||||
duk_put_prop_string(ctx, -2, FS_WATCHER_DATA_PTR); // [FSWatcher]
|
||||
memset(data, 0, sizeof(ILibDuktape_fs_watcherData));
|
||||
|
||||
data->emitter = ILibDuktape_EventEmitter_Create(ctx);
|
||||
data->ctx = ctx;
|
||||
@@ -1156,7 +1183,11 @@ duk_ret_t ILibDuktape_fs_rename(duk_context *ctx)
|
||||
char *oldPath = (char*)duk_require_string(ctx, 0);
|
||||
char *newPath = (char*)duk_require_string(ctx, 1);
|
||||
|
||||
#ifdef WIN32
|
||||
if (_wrename((LPCWSTR)ILibDuktape_String_UTF8ToWide(ctx, oldPath), (LPCWSTR)ILibDuktape_String_UTF8ToWide(ctx, newPath)) != 0)
|
||||
#else
|
||||
if (rename(oldPath, newPath) != 0)
|
||||
#endif
|
||||
{
|
||||
sprintf_s(ILibScratchPad, sizeof(ILibScratchPad), "fs.renameSync(): Error renaming %s to %s", oldPath, newPath);
|
||||
duk_push_string(ctx, ILibScratchPad);
|
||||
@@ -1168,16 +1199,21 @@ duk_ret_t ILibDuktape_fs_rename(duk_context *ctx)
|
||||
duk_ret_t ILibDuktape_fs_unlink(duk_context *ctx)
|
||||
{
|
||||
#ifdef WIN32
|
||||
char *path = (char*)duk_require_string(ctx, 0);
|
||||
char *path = ILibDuktape_String_AsWide(ctx, 0, NULL);
|
||||
#else
|
||||
char *path = ILibDuktape_fs_fixLinuxPath((char*)duk_require_string(ctx, 0));
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
if(_wremove((const wchar_t*)path) != 0)
|
||||
#else
|
||||
if (remove(path) != 0)
|
||||
#endif
|
||||
{
|
||||
#ifdef WIN32
|
||||
if (RemoveDirectory(path) != 0) { return 0; }
|
||||
if (RemoveDirectoryW((LPCWSTR)path) != 0) { return 0; }
|
||||
#endif
|
||||
sprintf_s(ILibScratchPad, sizeof(ILibScratchPad), "fs.unlinkSync(): Error trying to unlink: %s", path);
|
||||
sprintf_s(ILibScratchPad, sizeof(ILibScratchPad), "fs.unlinkSync(): Error trying to unlink: %s", ILibDuktape_String_WideToUTF8(ctx, path));
|
||||
duk_push_string(ctx, ILibScratchPad);
|
||||
duk_throw(ctx);
|
||||
return(DUK_RET_ERROR);
|
||||
@@ -1189,16 +1225,15 @@ duk_ret_t ILibDuktape_fs_mkdirSync(duk_context *ctx)
|
||||
//int nargs = duk_get_top(ctx);
|
||||
|
||||
#ifdef WIN32
|
||||
char *path = (char*)duk_require_string(ctx, 0);
|
||||
if (_mkdir(path) != 0)
|
||||
char *path = ILibDuktape_String_AsWide(ctx, 0, NULL);
|
||||
ILibDuktape_String_WideToUTF8(ctx, path);
|
||||
if (_wmkdir((const wchar_t*)path) != 0)
|
||||
#else
|
||||
char *path = ILibDuktape_fs_fixLinuxPath((char*)duk_require_string(ctx, 0));
|
||||
if (mkdir(path, 0777) != 0)
|
||||
#endif
|
||||
{
|
||||
sprintf_s(ILibScratchPad, sizeof(ILibScratchPad), "fs.mkdirSync(): Unable to create dir: %s", path);
|
||||
duk_throw(ctx);
|
||||
return(DUK_RET_ERROR);
|
||||
return(ILibDuktape_Error(ctx, "fs.mkdirSync(): Unable to create dir: %s", ILibDuktape_String_WideToUTF8(ctx, path)));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -1209,9 +1244,20 @@ duk_ret_t ILibDuktape_fs_readFileSync(duk_context *ctx)
|
||||
long fileLen;
|
||||
|
||||
#ifdef WIN32
|
||||
fopen_s(&f, filePath, "rbN");
|
||||
char *flags = "rbN";
|
||||
#else
|
||||
f = fopen(filePath, "rb");
|
||||
char *flags = "rb";
|
||||
#endif
|
||||
|
||||
if (duk_is_object(ctx, 1))
|
||||
{
|
||||
flags = Duktape_GetStringPropertyValue(ctx, 1, "flags", flags);
|
||||
}
|
||||
|
||||
#ifdef WIN32
|
||||
_wfopen_s(&f, (const wchar_t*)ILibDuktape_String_UTF8ToWide(ctx, filePath), (const wchar_t*)ILibDuktape_String_UTF8ToWide(ctx, flags));
|
||||
#else
|
||||
f = fopen(filePath, flags);
|
||||
#endif
|
||||
|
||||
if (f == NULL) { return(ILibDuktape_Error(ctx, "fs.readFileSync(): File [%s] not found", filePath)); }
|
||||
@@ -1219,11 +1265,31 @@ duk_ret_t ILibDuktape_fs_readFileSync(duk_context *ctx)
|
||||
fseek(f, 0, SEEK_END);
|
||||
fileLen = ftell(f);
|
||||
fseek(f, 0, SEEK_SET);
|
||||
|
||||
duk_push_fixed_buffer(ctx, (duk_size_t)fileLen);
|
||||
ignore_result(fread(Duktape_GetBuffer(ctx, -1, NULL), 1, (size_t)fileLen, f));
|
||||
fclose(f);
|
||||
duk_push_buffer_object(ctx, -1, 0, (duk_size_t)fileLen, DUK_BUFOBJ_NODEJS_BUFFER);
|
||||
if(fileLen > 0)
|
||||
{
|
||||
duk_push_fixed_buffer(ctx, (duk_size_t)fileLen);
|
||||
ignore_result(fread(Duktape_GetBuffer(ctx, -1, NULL), 1, (size_t)fileLen, f));
|
||||
fclose(f);
|
||||
duk_push_buffer_object(ctx, -1, 0, (duk_size_t)fileLen, DUK_BUFOBJ_NODEJS_BUFFER);
|
||||
}
|
||||
else
|
||||
{
|
||||
duk_size_t bufferSize = 1024;
|
||||
char *buffer = (char*)duk_push_dynamic_buffer(ctx, bufferSize); // [dynamicBuffer]
|
||||
size_t bytesRead = 0;
|
||||
size_t len = 0;
|
||||
while ((bytesRead = fread(buffer + len, 1, 1024, f)) > 0)
|
||||
{
|
||||
len += bytesRead;
|
||||
if (bytesRead == 1024)
|
||||
{
|
||||
buffer = duk_resize_buffer(ctx, -1, bufferSize + 1024);
|
||||
bufferSize += 1024;
|
||||
}
|
||||
}
|
||||
fclose(f);
|
||||
duk_push_buffer_object(ctx, -1, 0, (duk_size_t)len, DUK_BUFOBJ_NODEJS_BUFFER);
|
||||
}
|
||||
|
||||
return(1);
|
||||
}
|
||||
@@ -1243,6 +1309,19 @@ duk_ret_t ILibDuktape_fs_existsSync(duk_context *ctx)
|
||||
}
|
||||
return(1);
|
||||
}
|
||||
#ifdef _POSIX
|
||||
duk_ret_t ILibduktape_fs_chmodSync(duk_context *ctx)
|
||||
{
|
||||
if(chmod((char*)duk_require_string(ctx, 0), (mode_t)duk_require_int(ctx, 1)) != 0)
|
||||
{
|
||||
return(ILibDuktape_Error(ctx, "Error calling chmod()"));
|
||||
}
|
||||
else
|
||||
{
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
void ILibDuktape_fs_PUSH(duk_context *ctx, void *chain)
|
||||
{
|
||||
duk_push_object(ctx); // [fs]
|
||||
@@ -1267,6 +1346,9 @@ void ILibDuktape_fs_PUSH(duk_context *ctx, void *chain)
|
||||
ILibDuktape_CreateInstanceMethod(ctx, "readDrivesSync", ILibDuktape_fs_readDrivesSync, 0);
|
||||
ILibDuktape_CreateInstanceMethod(ctx, "readFileSync", ILibDuktape_fs_readFileSync, DUK_VARARGS);
|
||||
ILibDuktape_CreateInstanceMethod(ctx, "existsSync", ILibDuktape_fs_existsSync, 1);
|
||||
#ifdef _POSIX
|
||||
ILibDuktape_CreateInstanceMethod(ctx, "chmodSync", ILibduktape_fs_chmodSync, 2);
|
||||
#endif
|
||||
#ifndef _NOFSWATCHER
|
||||
ILibDuktape_CreateInstanceMethod(ctx, "watch", ILibDuktape_fs_watch, DUK_VARARGS);
|
||||
#endif
|
||||
@@ -1275,6 +1357,41 @@ void ILibDuktape_fs_PUSH(duk_context *ctx, void *chain)
|
||||
ILibDuktape_CreateInstanceMethod(ctx, "mkdirSync", ILibDuktape_fs_mkdirSync, DUK_VARARGS);
|
||||
|
||||
ILibDuktape_CreateFinalizer(ctx, ILibDuktape_fs_Finalizer);
|
||||
|
||||
char copyFile[] = "exports.copyFile = function copyFile(src, dest)\
|
||||
{\
|
||||
var ss = this.createReadStream(src, {flags: 'rb'});\
|
||||
var ds = this.createWriteStream(dest, {flags: 'wb'});\
|
||||
ss.fs = this;\
|
||||
ss.pipe(ds);\
|
||||
ds.ss = ss;\
|
||||
if(!this._copyStreams){this._copyStreams = {};this._copyStreamID = 0;}\
|
||||
ss.id = this._copyStreamID++;\
|
||||
this._copyStreams[ss.id] = ss;\
|
||||
if(arguments.length == 3 && typeof arguments[2] === 'function')\
|
||||
{\
|
||||
ds.on('close', arguments[2]);\
|
||||
}\
|
||||
else if(arguments.length == 4 && typeof arguments[3] === 'function')\
|
||||
{\
|
||||
ds.on('close', arguments[3]);\
|
||||
}\
|
||||
ds.on('close', function onCopyFileDone(){delete this.ss.fs._copyStreams[this.ss.id];});\
|
||||
};\
|
||||
exports.copyFileSync = function copyFileSync(src, dest)\
|
||||
{\
|
||||
var buffer = this.readFileSync(src, {flags: 'rb'});\
|
||||
this.writeFileSync(dest, buffer, {flags: 'wb'});\
|
||||
};\
|
||||
exports.writeFileSync = function writeFileSync(dest, data, options)\
|
||||
{\
|
||||
var fd = this.openSync(dest, options?options.flags:'wb');\
|
||||
this.writeSync(fd, data);\
|
||||
this.closeSync(fd);\
|
||||
};\
|
||||
exports.CHMOD_MODES = {S_IRUSR: 0o400, S_IWUSR: 0o200, S_IXUSR: 0o100, S_IRGRP: 0o40, S_IWGRP: 0o20, S_IXGRP: 0o10, S_IROTH: 0o4, S_IWOTH: 0o2, S_IXOTH: 0o1};\
|
||||
";
|
||||
ILibDuktape_ModSearch_AddHandler_AlsoIncludeJS(ctx, copyFile, sizeof(copyFile) - 1);
|
||||
}
|
||||
|
||||
void ILibDuktape_fs_init(duk_context * ctx)
|
||||
@@ -1452,4 +1569,4 @@ public:
|
||||
void close();
|
||||
};
|
||||
};
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -22,4 +22,4 @@ limitations under the License.
|
||||
void ILibDuktape_fs_init(duk_context *ctx);
|
||||
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -24,6 +24,7 @@ limitations under the License.
|
||||
|
||||
#define DIGEST_USERNAME "\xFF_DigestUsername"
|
||||
#define DIGEST_PASSWORD "\xFF_DigestPassword"
|
||||
#define DIGEST_AUTHTOKEN "\xFF_DigestAuthToken"
|
||||
#define HTTP_DIGEST "\xFF_HTTP_DIGEST"
|
||||
#define DIGEST_CLIENT_REQUEST "\xFF_DIGEST_CLIENT_REQUEST"
|
||||
#define HTTP_CLIENTREQUEST_DATAPTR "\xFF_CLIENTREQUEST_DATAPTR"
|
||||
@@ -158,8 +159,10 @@ char *ILibDuktape_httpDigest_generateAuthenticationHeader(duk_context *ctx, void
|
||||
wwwauth = (char*)Duktape_GetStringPropertyValueEx(ctx, -1, DIGEST2WWWAUTH, NULL, &wwwauthLen);
|
||||
username = (char*)Duktape_GetStringPropertyValue(ctx, -1, DIGEST_USERNAME, NULL);
|
||||
password = (char*)Duktape_GetStringPropertyValue(ctx, -1, DIGEST_PASSWORD, NULL);
|
||||
if (wwwauth == NULL || username == NULL || password == NULL) { duk_pop(ctx); return(NULL); }
|
||||
|
||||
if (!duk_has_prop_string(ctx, -1, DIGEST_AUTHTOKEN))
|
||||
{
|
||||
if (wwwauth == NULL || username == NULL || password == NULL) { duk_pop(ctx); return(NULL); }
|
||||
}
|
||||
duk_push_heapptr(ctx, optionsObj); // [digest][options]
|
||||
method = (char*)Duktape_GetStringPropertyValue(ctx, -1, "method", NULL);
|
||||
path = (char*)Duktape_GetStringPropertyValue(ctx, -1, "path", NULL);
|
||||
@@ -174,9 +177,24 @@ char *ILibDuktape_httpDigest_generateAuthenticationHeader(duk_context *ctx, void
|
||||
ILibGetEntryEx(table, "opaque", 6, (void**)&opaque, &opaqueLen); if (opaqueLen > 0) { opaque[opaqueLen] = 0; }
|
||||
ILibGetEntryEx(table, "qop", 3, (void**)&qop, &qopLen); if (qopLen > 0) { qop[qopLen] = 0; }
|
||||
|
||||
tmpLen = sprintf_s(ILibScratchPad2, sizeof(ILibScratchPad2), "%s:%s:%s", username, realm, password);
|
||||
util_md5hex(ILibScratchPad2, tmpLen, result1);
|
||||
|
||||
if (duk_has_prop_string(ctx, -1, DIGEST_AUTHTOKEN))
|
||||
{
|
||||
duk_size_t authTokenLen;
|
||||
char *authToken = Duktape_GetStringPropertyValueEx(ctx, -1, DIGEST_AUTHTOKEN, NULL, &authTokenLen);
|
||||
|
||||
if (authTokenLen < sizeof(result1))
|
||||
{
|
||||
memcpy_s(result1, sizeof(result1), authToken, authTokenLen);
|
||||
result1[32] = 0;
|
||||
username = "admin";
|
||||
tmpLen = (int)authTokenLen;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
tmpLen = sprintf_s(ILibScratchPad2, sizeof(ILibScratchPad2), "%s:%s:%s", username, realm, password);
|
||||
util_md5hex(ILibScratchPad2, tmpLen, result1);
|
||||
}
|
||||
tmpLen = sprintf_s(ILibScratchPad2, sizeof(ILibScratchPad2), "%s:%s", method, path);
|
||||
util_md5hex(ILibScratchPad2, tmpLen, result2);
|
||||
|
||||
@@ -325,6 +343,11 @@ duk_ret_t ILibDuktape_httpDigest_clientRequest_response(duk_context *ctx)
|
||||
else
|
||||
{
|
||||
duk_push_heapptr(ctx, digestClientPtr); // [digestClientRequest]
|
||||
duk_del_prop_string(ctx, -1, DIGEST_CLIENT_REQUEST);
|
||||
duk_push_this(ctx);
|
||||
duk_del_prop_string(ctx, -1, DIGEST_CLIENT_REQUEST);
|
||||
duk_pop(ctx);
|
||||
|
||||
duk_get_prop_string(ctx, -1, "emit"); // [digestClientRequest][emit]
|
||||
duk_swap_top(ctx, -2); // [emit][this]
|
||||
duk_push_string(ctx, "response"); // [emit][this][response]
|
||||
@@ -579,9 +602,18 @@ duk_ret_t ILibDuktape_httpDigest_http_request(duk_context *ctx)
|
||||
}
|
||||
duk_ret_t ILibduktape_httpDigest_create(duk_context *ctx)
|
||||
{
|
||||
duk_size_t usernameLen, passwordLen;
|
||||
char *username = (char*)duk_require_lstring(ctx, 0, &usernameLen), *password = (char*)duk_require_lstring(ctx, 1, &passwordLen);
|
||||
duk_size_t usernameLen, passwordLen, authTokenLen;
|
||||
ILibDuktape_EventEmitter *emitter;
|
||||
char *username = NULL, *password = NULL, *authToken = NULL;
|
||||
|
||||
if (duk_get_top(ctx) == 1 && duk_is_object(ctx, 0))
|
||||
{
|
||||
if ((authToken = Duktape_GetStringPropertyValueEx(ctx, 0, "authToken", NULL, &authTokenLen)) == NULL) { return(ILibDuktape_Error(ctx, "authToken Required")); }
|
||||
}
|
||||
else
|
||||
{
|
||||
username = (char*)duk_require_lstring(ctx, 0, &usernameLen), password = (char*)duk_require_lstring(ctx, 1, &passwordLen);
|
||||
}
|
||||
|
||||
duk_push_object(ctx); // [obj]
|
||||
ILibDuktape_WriteID(ctx, "httpDigest");
|
||||
@@ -593,10 +625,19 @@ duk_ret_t ILibduktape_httpDigest_create(duk_context *ctx)
|
||||
ILibDuktape_EventEmitter_CreateEventEx(emitter, "upgrade");
|
||||
ILibDuktape_CreateInstanceMethodWithIntProperty(ctx, "isGet", 1, "get", ILibDuktape_httpDigest_http_request, DUK_VARARGS);
|
||||
ILibDuktape_CreateInstanceMethodWithIntProperty(ctx, "isGet", 0, "request", ILibDuktape_httpDigest_http_request, DUK_VARARGS);
|
||||
duk_push_string(ctx, username);
|
||||
duk_put_prop_string(ctx, -2, DIGEST_USERNAME);
|
||||
duk_push_string(ctx, password);
|
||||
duk_put_prop_string(ctx, -2, DIGEST_PASSWORD);
|
||||
|
||||
if (authToken == NULL)
|
||||
{
|
||||
duk_push_string(ctx, username);
|
||||
duk_put_prop_string(ctx, -2, DIGEST_USERNAME);
|
||||
duk_push_string(ctx, password);
|
||||
duk_put_prop_string(ctx, -2, DIGEST_PASSWORD);
|
||||
}
|
||||
else
|
||||
{
|
||||
duk_push_lstring(ctx, authToken, authTokenLen);
|
||||
duk_put_prop_string(ctx, -2, DIGEST_AUTHTOKEN);
|
||||
}
|
||||
duk_push_fixed_buffer(ctx, 16);
|
||||
util_randomtext(16, (char*)Duktape_GetBuffer(ctx, -1, NULL));
|
||||
((char*)Duktape_GetBuffer(ctx, -1, NULL))[15] = 0;
|
||||
@@ -610,7 +651,7 @@ duk_ret_t ILibduktape_httpDigest_create(duk_context *ctx)
|
||||
void ILibDuktape_httpDigest_PUSH(duk_context *ctx, void *chain)
|
||||
{
|
||||
duk_push_object(ctx);
|
||||
ILibDuktape_CreateInstanceMethod(ctx, "create", ILibduktape_httpDigest_create, 2);
|
||||
ILibDuktape_CreateInstanceMethod(ctx, "create", ILibduktape_httpDigest_create, DUK_VARARGS);
|
||||
}
|
||||
duk_ret_t ILibDuktape_httpHeaders(duk_context *ctx)
|
||||
{
|
||||
@@ -1087,4 +1128,4 @@ public:
|
||||
public String minor;
|
||||
};
|
||||
};
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -22,4 +22,3 @@ limitations under the License.
|
||||
void ILibDuktape_http_init(duk_context *ctx, void *chain);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -100,6 +100,7 @@ void ILibDuktape_net_socket_OnConnect(ILibAsyncSocket_SocketModule socketModule,
|
||||
{
|
||||
ILibDuktape_net_socket *ptrs = (ILibDuktape_net_socket*)((ILibChain_Link*)socketModule)->ExtraMemoryPtr;
|
||||
struct sockaddr_in6 local;
|
||||
if (ptrs->ctx == NULL) { return; }
|
||||
|
||||
duk_push_heapptr(ptrs->ctx, ptrs->object); // [sockat]
|
||||
duk_push_false(ptrs->ctx); // [socket][connecting]
|
||||
@@ -164,14 +165,13 @@ void ILibDuktape_net_socket_OnConnect(ILibAsyncSocket_SocketModule socketModule,
|
||||
#endif
|
||||
duk_put_prop_string(ptrs->ctx, -2, "message"); // [emit][this][error][errorObj]
|
||||
if (duk_pcall_method(ptrs->ctx, 2) != 0) { ILibDuktape_Process_UncaughtException(ptrs->ctx); }
|
||||
duk_pop(ptrs->ctx); // ...
|
||||
if (ptrs->ctx != NULL) { duk_pop(ptrs->ctx); } // ...
|
||||
}
|
||||
}
|
||||
void ILibDuktape_net_socket_OnDisconnect(ILibAsyncSocket_SocketModule socketModule, void *user)
|
||||
{
|
||||
ILibDuktape_net_socket *ptrs = (ILibDuktape_net_socket*)((ILibChain_Link*)socketModule)->ExtraMemoryPtr;
|
||||
|
||||
if (ILibDuktape_IsPointerValid(ptrs->chain, ptrs->object))
|
||||
if (ILibMemory_CanaryOK(ptrs->emitter))
|
||||
{
|
||||
duk_push_heapptr(ptrs->ctx, ptrs->object); // [sock]
|
||||
duk_push_string(ptrs->ctx, "0.0.0.0"); // [sock][localAddr]
|
||||
@@ -379,7 +379,7 @@ duk_ret_t ILibDuktape_net_socket_finalizer(duk_context *ctx)
|
||||
if (ILibAsyncSocket_IsConnected(ptrs->socketModule) != 0) { ILibAsyncSocket_Disconnect(ptrs->socketModule); }
|
||||
ILibChain_SafeRemove(chain, ptrs->socketModule);
|
||||
}
|
||||
|
||||
ptrs->ctx = NULL;
|
||||
return 0;
|
||||
}
|
||||
int ILibDuktape_net_socket_unshift(ILibDuktape_DuplexStream *sender, int unshiftBytes, void *user)
|
||||
@@ -399,7 +399,6 @@ void ILibDuktape_net_socket_PUSH(duk_context *ctx, ILibAsyncSocket_SocketModule
|
||||
|
||||
duk_push_object(ctx); // [obj]
|
||||
ILibDuktape_WriteID(ctx, "net.socket");
|
||||
ILibDuktape_PointerValidation_Init(ctx);
|
||||
ptrs->ctx = ctx;
|
||||
ptrs->chain = ((ILibChain_Link*)module)->ParentChain;
|
||||
ptrs->object = duk_get_heapptr(ctx, -1);
|
||||
@@ -493,21 +492,29 @@ duk_ret_t ILibDuktape_net_createConnection(duk_context *ctx)
|
||||
ILibTransport_DoneState ILibDuktape_net_server_WriteSink(ILibDuktape_DuplexStream *stream, char *buffer, int bufferLen, void *user)
|
||||
{
|
||||
ILibDuktape_net_server_session *session = (ILibDuktape_net_server_session*)user;
|
||||
if (!ILibMemory_CanaryOK(session)) { return(ILibTransport_DoneState_ERROR); }
|
||||
|
||||
return((ILibTransport_DoneState)ILibAsyncServerSocket_Send(NULL, session->connection, buffer, bufferLen, ILibAsyncSocket_MemoryOwnership_USER));
|
||||
}
|
||||
void ILibDuktape_net_server_EndSink(ILibDuktape_DuplexStream *stream, void *user)
|
||||
{
|
||||
ILibDuktape_net_server_session *session = (ILibDuktape_net_server_session*)user;
|
||||
ILibAsyncServerSocket_Disconnect(NULL, session->connection);
|
||||
if (!ILibMemory_CanaryOK(session)) { return; }
|
||||
|
||||
if (session->connection != NULL) { ILibAsyncServerSocket_Disconnect(NULL, session->connection); }
|
||||
}
|
||||
void ILibDuktape_net_server_PauseSink(ILibDuktape_DuplexStream *sender, void *user)
|
||||
{
|
||||
ILibDuktape_net_server_session *session = (ILibDuktape_net_server_session*)user;
|
||||
if (!ILibMemory_CanaryOK(session)) { return; }
|
||||
|
||||
ILibAsyncSocket_Pause(session->connection);
|
||||
}
|
||||
void ILibDuktape_net_server_ResumeSink(ILibDuktape_DuplexStream *sender, void *user)
|
||||
{
|
||||
ILibDuktape_net_server_session *session = (ILibDuktape_net_server_session*)user;
|
||||
if (!ILibMemory_CanaryOK(session)) { return; }
|
||||
|
||||
ILibAsyncSocket_Resume(session->connection);
|
||||
}
|
||||
duk_ret_t ILibDuktape_net_server_socket_Finalizer(duk_context *ctx)
|
||||
@@ -527,6 +534,8 @@ duk_ret_t ILibDuktape_net_server_socket_Finalizer(duk_context *ctx)
|
||||
int ILibDuktape_net_server_unshiftSink(ILibDuktape_DuplexStream *sender, int unshiftBytes, void *user)
|
||||
{
|
||||
ILibDuktape_net_server_session *session = (ILibDuktape_net_server_session*)user;
|
||||
if (!ILibMemory_CanaryOK(session)) { return(unshiftBytes); }
|
||||
|
||||
session->unshiftBytes = unshiftBytes;
|
||||
return(unshiftBytes);
|
||||
}
|
||||
@@ -534,7 +543,12 @@ void ILibDuktape_net_server_OnConnect(ILibAsyncServerSocket_ServerModule AsyncSe
|
||||
{
|
||||
ILibDuktape_net_server *ptr = (ILibDuktape_net_server*)((void**)ILibMemory_GetExtraMemory(AsyncServerSocketModule, ILibMemory_ASYNCSERVERSOCKET_CONTAINERSIZE))[0];
|
||||
ILibDuktape_net_server_session *session;
|
||||
#ifndef MICROSTACK_NOTLS
|
||||
int isTLS = ILibAsyncSocket_IsUsingTls(ConnectionToken);
|
||||
#else
|
||||
int isTLS = 0;
|
||||
#endif
|
||||
if (!ILibMemory_CanaryOK(ptr)) { return; }
|
||||
|
||||
duk_push_heapptr(ptr->ctx, ptr->self); // [server]
|
||||
|
||||
@@ -545,9 +559,7 @@ void ILibDuktape_net_server_OnConnect(ILibAsyncServerSocket_ServerModule AsyncSe
|
||||
duk_push_object(ptr->ctx); // [emit][this][connection][socket]
|
||||
ILibDuktape_WriteID(ptr->ctx, isTLS ? "tls.serverSocketConnection" : "net.serverSocketConnection");
|
||||
ILibDuktape_CreateFinalizer(ptr->ctx, ILibDuktape_net_server_socket_Finalizer);
|
||||
duk_push_fixed_buffer(ptr->ctx, sizeof(ILibDuktape_net_server_session)); // [emit][this][connection][socket][buffer]
|
||||
session = (ILibDuktape_net_server_session*)Duktape_GetBuffer(ptr->ctx, -1, NULL);
|
||||
memset(session, 0, sizeof(ILibDuktape_net_server_session));
|
||||
session = Duktape_PushBuffer(ptr->ctx, sizeof(ILibDuktape_net_server_session)); // [emit][this][connection][socket][buffer]
|
||||
duk_put_prop_string(ptr->ctx, -2, ILibDuktape_net_Server_Session_buffer); // [emit][this][connection][socket]
|
||||
|
||||
struct sockaddr_in6 local;
|
||||
@@ -583,12 +595,19 @@ void ILibDuktape_net_server_OnConnect(ILibAsyncServerSocket_ServerModule AsyncSe
|
||||
void ILibDuktape_net_server_OnDisconnect(ILibAsyncServerSocket_ServerModule AsyncServerSocketModule, ILibAsyncServerSocket_ConnectionToken ConnectionToken, void *user)
|
||||
{
|
||||
ILibDuktape_net_server_session *session = (ILibDuktape_net_server_session*)user;
|
||||
ILibDuktape_DuplexStream_Closed(session->stream);
|
||||
if (!ILibMemory_CanaryOK(session)) { return; }
|
||||
|
||||
if (session->connection != NULL)
|
||||
{
|
||||
ILibDuktape_DuplexStream_Closed(session->stream);
|
||||
session->connection = NULL;
|
||||
}
|
||||
}
|
||||
void ILibDuktape_net_server_OnReceive(ILibAsyncServerSocket_ServerModule AsyncServerSocketModule, ILibAsyncServerSocket_ConnectionToken ConnectionToken, char* buffer, int *p_beginPointer, int endPointer, ILibAsyncServerSocket_OnInterrupt *OnInterrupt, void **user, int *PAUSE)
|
||||
{
|
||||
ILibDuktape_net_server_session *session = (ILibDuktape_net_server_session*)*user;
|
||||
|
||||
if (!ILibMemory_CanaryOK(session)) { *p_beginPointer = endPointer; return; }
|
||||
|
||||
session->unshiftBytes = 0;
|
||||
ILibDuktape_DuplexStream_WriteData(session->stream, buffer + *p_beginPointer, endPointer);
|
||||
*p_beginPointer = endPointer - session->unshiftBytes;
|
||||
@@ -599,6 +618,8 @@ void ILibDuktape_net_server_OnInterrupt(ILibAsyncServerSocket_ServerModule Async
|
||||
void ILibDuktape_net_server_OnSendOK(ILibAsyncServerSocket_ServerModule AsyncServerSocketModule, ILibAsyncServerSocket_ConnectionToken ConnectionToken, void *user)
|
||||
{
|
||||
ILibDuktape_net_server_session *session = (ILibDuktape_net_server_session*)user;
|
||||
if (!ILibMemory_CanaryOK(session)) { return; }
|
||||
|
||||
ILibDuktape_DuplexStream_Ready(session->stream);
|
||||
}
|
||||
duk_ret_t ILibDuktape_net_server_listen(duk_context *ctx)
|
||||
@@ -777,10 +798,7 @@ duk_ret_t ILibDuktape_net_createServer(duk_context *ctx)
|
||||
duk_dup(ctx, 0); // [server][Options]
|
||||
duk_put_prop_string(ctx, -2, ILibDuktape_SERVER2OPTIONS); // [server]
|
||||
}
|
||||
|
||||
duk_push_fixed_buffer(ctx, sizeof(ILibDuktape_net_server)); // [server][fbuffer]
|
||||
server = (ILibDuktape_net_server*)Duktape_GetBuffer(ctx, -1, NULL);
|
||||
memset(server, 0, sizeof(ILibDuktape_net_server));
|
||||
server = Duktape_PushBuffer(ctx, sizeof(ILibDuktape_net_server)); // [server][fbuffer]
|
||||
duk_put_prop_string(ctx, -2, ILibDuktape_net_Server_buffer); // [server]
|
||||
|
||||
server->isTLS = isTLS;
|
||||
@@ -828,6 +846,20 @@ duk_ret_t ILibDuktape_net_createServer(duk_context *ctx)
|
||||
|
||||
return 1;
|
||||
}
|
||||
duk_ret_t ILibDuktape_net_addr2int(duk_context *ctx)
|
||||
{
|
||||
struct sockaddr_in6 addr6;
|
||||
ILibResolveEx((char*)duk_require_string(ctx, 0), 0, &addr6);
|
||||
if (addr6.sin6_family == AF_INET)
|
||||
{
|
||||
duk_push_int(ctx, ((struct sockaddr_in*)&addr6)->sin_addr.s_addr);
|
||||
return(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
return(ILibDuktape_Error(ctx, "Error converting address"));
|
||||
}
|
||||
}
|
||||
void ILibDuktape_net_PUSH_net(duk_context *ctx, void *chain)
|
||||
{
|
||||
duk_push_object(ctx); // [net]
|
||||
@@ -843,6 +875,7 @@ void ILibDuktape_net_PUSH_net(duk_context *ctx, void *chain)
|
||||
ILibDuktape_CreateInstanceMethodWithIntProperty(ctx, "tls", 0, "createServer", ILibDuktape_net_createServer, DUK_VARARGS);
|
||||
ILibDuktape_CreateInstanceMethod(ctx, "createConnection", ILibDuktape_net_createConnection, DUK_VARARGS);
|
||||
ILibDuktape_CreateInstanceMethod(ctx, "connect", ILibDuktape_net_createConnection, DUK_VARARGS);
|
||||
ILibDuktape_CreateInstanceMethod(ctx, "addr2int", ILibDuktape_net_addr2int, 1);
|
||||
}
|
||||
duk_ret_t ILibDuktape_globalTunnel_end(duk_context *ctx)
|
||||
{
|
||||
@@ -1003,6 +1036,8 @@ int ILibDuktape_TLS_server_verify(int preverify_ok, X509_STORE_CTX *storectx)
|
||||
|
||||
int i;
|
||||
int retVal = 0;
|
||||
if (!ILibMemory_CanaryOK(data)) { return(0); }
|
||||
|
||||
|
||||
duk_push_heapptr(data->ctx, data->self); // [Server]
|
||||
duk_get_prop_string(data->ctx, -1, ILibDuktape_SERVER2OPTIONS); // [Server][Options]
|
||||
@@ -1026,6 +1061,7 @@ int ILibDuktape_TLS_server_verify(int preverify_ok, X509_STORE_CTX *storectx)
|
||||
void ILibDuktape_tls_server_OnSSL(ILibAsyncServerSocket_ServerModule AsyncServerSocketModule, void *ConnectionToken, SSL* ctx, void **user)
|
||||
{
|
||||
ILibDuktape_net_server *server = (ILibDuktape_net_server*)ILibAsyncServerSocket_GetTag(AsyncServerSocketModule);
|
||||
if (!ILibMemory_CanaryOK(server)) { return; }
|
||||
|
||||
if (ctx != NULL && ILibDuktape_TLS_ctx2server)
|
||||
{
|
||||
@@ -1036,6 +1072,7 @@ static int ILibDuktape_tls_server_sniCallback(SSL *s, int *ad, void *arg)
|
||||
{
|
||||
const char *servername = SSL_get_servername(s, TLSEXT_NAMETYPE_host_name);
|
||||
ILibDuktape_net_server *data = (ILibDuktape_net_server*)SSL_get_ex_data(s, ILibDuktape_TLS_ctx2server);
|
||||
if (!ILibMemory_CanaryOK(data)) { return(SSL_TLSEXT_ERR_OK); }
|
||||
|
||||
duk_push_heapptr(data->ctx, data->self); // [server]
|
||||
duk_get_prop_string(data->ctx, -1, ILibDuktape_SERVER2ContextTable); // [server][table]
|
||||
@@ -1471,4 +1508,4 @@ public:
|
||||
*/
|
||||
void setTimeout(milliseconds[, timeout]);
|
||||
};
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -40,4 +40,4 @@ ILibDuktape_globalTunnel_data* ILibDuktape_GetGlobalTunnel(duk_context *ctx);
|
||||
ILibDuktape_globalTunnel_data* ILibDuktape_GetNewGlobalTunnelEx(duk_context *ctx, int native);
|
||||
#define ILibDuktape_GetNewGlobalTunnel(ctx) ILibDuktape_GetNewGlobalTunnelEx(ctx, 1)
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -714,4 +714,4 @@ void ILibWebServer_DukTape_Init(duk_context* ctx, void *chain)
|
||||
Duktape_CreateEnum(ctx, "WebServer_DoneFlags", (char* []) { "NOTDONE", "DONE", "PARTIAL", "LASTPARTIAL" }, (int[]) { 0, 1, 10, 11 }, 4);
|
||||
|
||||
duk_pop(ctx); // ...
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,4 +21,4 @@ limitations under the License.
|
||||
|
||||
void ILibWebServer_DukTape_Init(duk_context *ctx, void * chain);
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -27,12 +27,18 @@ limitations under the License.
|
||||
|
||||
#define ILibDuktape_EventEmitter_MaxEventNameLen 255
|
||||
#define ILibDuktape_EventEmitter_Data "\xFF_EventEmitter_Data"
|
||||
#define ILibDuktape_EventEmitter_RetVal "\xFF_EventEmitter_RetVal"
|
||||
#define ILibDuktape_EventEmitter_TempObject "\xFF_EventEmitter_TempObject"
|
||||
#define ILibDuktape_EventEmitter_DispatcherFunc "\xFF_EventEmitter_DispatcherFunc"
|
||||
#define ILibDuktape_EventEmitter_SetterFunc ((void*)0xFFFF)
|
||||
#define ILibDuktape_EventEmitter_HPTR_LIST "\xFF_EventEmitter_HPTR_LIST"
|
||||
#define ILibDuktape_EventEmitter_Hook ((void*)0xEEEE)
|
||||
#define ILibDuktape_EventEmitter_LastRetValueTable "\xFF_EventEmitter_LastRetValueTable"
|
||||
#define ILibDuktape_EventEmitter_GlobalListenerCount "\xFF_EventEmitter_GlobalListenerCount"
|
||||
#define ILibDuktape_EventEmitter_Forward_SourceName "\xFF_EventEmitter_SourceName"
|
||||
#define ILibDuktape_EventEmitter_Forward_TargetName "\xFF_EventEmitter_TargetName"
|
||||
#define ILibDuktape_EventEmitter_Forward_SourceObject "\xFF_EventEmitter_SourceObject"
|
||||
#define ILibDuktape_EventEmitter_ForwardTable "\xFF_EventEmitter_ForwardTable"
|
||||
|
||||
#ifdef __DOXY__
|
||||
|
||||
@@ -148,7 +154,7 @@ void ILibDuktape_EventEmitter_FinalizerEx(ILibHashtable sender, void *Key1, char
|
||||
int ILibDuktape_EventEmitter_HasListeners(ILibDuktape_EventEmitter *emitter, char *eventName)
|
||||
{
|
||||
int retVal = 0;
|
||||
if (emitter->eventTable != NULL)
|
||||
if(emitter!=NULL && emitter->eventTable != NULL)
|
||||
{
|
||||
ILibLinkedList eventList = ILibHashtable_Get(emitter->eventTable, NULL, eventName, (int)strnlen_s(eventName, 255));
|
||||
if (eventList != NULL)
|
||||
@@ -171,6 +177,9 @@ duk_ret_t ILibDuktape_EventEmitter_emit(duk_context *ctx)
|
||||
int i, j;
|
||||
void **emitList;
|
||||
char *objid;
|
||||
int wasReturnSpecified = 0;
|
||||
|
||||
duk_require_stack(ctx, 3); // This will make sure we have enough stack space to get the emitter object
|
||||
|
||||
duk_push_this(ctx); // [this]
|
||||
objid = Duktape_GetStringPropertyValue(ctx, -1, ILibDuktape_OBJID, "unknown");
|
||||
@@ -184,7 +193,17 @@ duk_ret_t ILibDuktape_EventEmitter_emit(duk_context *ctx)
|
||||
if (data->eventTable == NULL) { duk_push_false(ctx); return(1); } // This probably means the finalizer was already run on the eventEmitter
|
||||
|
||||
eventList = ILibHashtable_Get(data->eventTable, NULL, name, (int)nameLen);
|
||||
if (eventList == NULL) { return ILibDuktape_Error(ctx, "EventEmitter.emit(): Event '%s' not found on object '%s'", name, objid); }
|
||||
if (eventList == NULL)
|
||||
{
|
||||
if (data->eventType == ILibDuktape_EventEmitter_Type_IMPLICIT)
|
||||
{
|
||||
duk_push_false(ctx); return(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
return ILibDuktape_Error(ctx, "EventEmitter.emit(): Event '%s' not found on object '%s'", name, objid);
|
||||
}
|
||||
}
|
||||
|
||||
// Copy the list, so we can enumerate with local memory, so the list can be manipulated while we are dispatching
|
||||
#ifdef WIN32
|
||||
@@ -209,10 +228,18 @@ duk_ret_t ILibDuktape_EventEmitter_emit(duk_context *ctx)
|
||||
}
|
||||
emitList[i] = NULL;
|
||||
|
||||
|
||||
// Before we dispatch, lets clear our last return values for this event
|
||||
duk_push_heapptr(ctx, data->retValTable); // [table]
|
||||
duk_del_prop_lstring(ctx, -1, name, nameLen);
|
||||
duk_pop(ctx); // ...
|
||||
|
||||
// Now that we have all the housekeeping stuff out of the way, we can actually dispatch our events
|
||||
i = 0;
|
||||
while ((func = emitList[i++]) != NULL)
|
||||
{
|
||||
duk_require_stack(ctx, nargs + 1); // This will make sure that we have enough stack space to make the method call
|
||||
|
||||
duk_push_heapptr(ctx, func); // [func]
|
||||
duk_push_heapptr(ctx, self); // [func][this]
|
||||
for (j = 1; j < nargs; ++j)
|
||||
@@ -221,10 +248,39 @@ duk_ret_t ILibDuktape_EventEmitter_emit(duk_context *ctx)
|
||||
}
|
||||
if (duk_pcall_method(ctx, nargs - 1) != 0)
|
||||
{
|
||||
return(ILibDuktape_Error(ctx, "EventEmitter.emit(): Event dispatch for '%s' on '%s' threw an exception: %s", name, objid, duk_safe_to_string(ctx, -1)));
|
||||
duk_push_heapptr(ctx, func); // [func]
|
||||
return(ILibDuktape_Error(ctx, "EventEmitter.emit(): Event dispatch for '%s' on '%s' threw an exception: %s in method '%s()'", name, objid, duk_safe_to_string(ctx, -2), Duktape_GetStringPropertyValue(ctx, -1, "name", "unknown_method")));
|
||||
}
|
||||
|
||||
// Check for return value
|
||||
if (!duk_is_undefined(ctx, -1))
|
||||
{
|
||||
duk_push_heapptr(ctx, data->retValTable); // [retVal][table]
|
||||
duk_dup(ctx, -2); // [retVal][table][retVal]
|
||||
duk_put_prop_lstring(ctx, -2, name, nameLen); // [retVal][table]
|
||||
duk_pop(ctx); // [retVal]
|
||||
|
||||
duk_push_heapptr(ctx, self); // [retVal][this]
|
||||
duk_swap_top(ctx, -2); // [this][retVal]
|
||||
data->lastReturnValue = duk_get_heapptr(ctx, -1);
|
||||
duk_put_prop_string(ctx, -2, ILibDuktape_EventEmitter_RetVal); // [this]
|
||||
duk_pop(ctx); // ...
|
||||
wasReturnSpecified = 1;
|
||||
}
|
||||
duk_pop(ctx); // ...
|
||||
}
|
||||
|
||||
if (wasReturnSpecified == 0)
|
||||
{
|
||||
data->lastReturnValue = NULL;
|
||||
duk_push_heapptr(ctx, self); // [this]
|
||||
duk_del_prop_string(ctx, -1, ILibDuktape_EventEmitter_RetVal); // [this]
|
||||
duk_pop(ctx); // ...
|
||||
|
||||
duk_push_heapptr(ctx, data->retValTable); // [table]
|
||||
duk_del_prop_lstring(ctx, -1, name, nameLen);
|
||||
duk_pop(ctx); // ...
|
||||
}
|
||||
|
||||
duk_push_boolean(ctx, i > 1 ? 1 : 0);
|
||||
return(1);
|
||||
}
|
||||
@@ -326,7 +382,15 @@ duk_ret_t ILibDuktape_EventEmitter_on(duk_context *ctx)
|
||||
eventList = ILibHashtable_Get(data->eventTable, NULL, propName, (int)propNameLen);
|
||||
if (eventList == NULL)
|
||||
{
|
||||
return(ILibDuktape_Error(ctx, "EventEmitter.on(): Event '%s' not found", propName));
|
||||
if (data->eventType == ILibDuktape_EventEmitter_Type_IMPLICIT)
|
||||
{
|
||||
ILibDuktape_EventEmitter_CreateEventEx(data, propName);
|
||||
eventList = ILibHashtable_Get(data->eventTable, NULL, propName, (int)propNameLen);
|
||||
}
|
||||
else
|
||||
{
|
||||
return(ILibDuktape_Error(ctx, "EventEmitter.on(): Event '%s' not found", propName));
|
||||
}
|
||||
}
|
||||
hookHandler = ILibHashtable_Get(data->eventTable, ILibDuktape_EventEmitter_Hook, propName, (int)propNameLen);
|
||||
|
||||
@@ -339,6 +403,14 @@ duk_ret_t ILibDuktape_EventEmitter_on(duk_context *ctx)
|
||||
duk_put_prop_string(ctx, -2, Duktape_GetStashKey(callback)); // Save the callback to the tmp object, so it won't get GC'ed
|
||||
|
||||
if (hookHandler != NULL) { hookHandler(data, propName, callback); }
|
||||
if (!(propNameLen == 10 && strncmp(propName, "_eventHook", 10) == 0))
|
||||
{
|
||||
// Only emit '_eventHook' when the event itself isn't '_eventHook'
|
||||
ILibDuktape_EventEmitter_SetupEmit(ctx, data->object, "_eventHook"); // [emit][this][_eventHook]
|
||||
duk_push_lstring(ctx, propName, propNameLen); // [emit][this][_eventHook][propName]
|
||||
duk_push_heapptr(ctx, callback); // [emit][this][_eventHook][propName][callback]
|
||||
duk_call_method(ctx, 3); duk_pop(ctx); // ...
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
ILibDuktape_EventEmitter* ILibDuktape_EventEmitter_GetEmitter_fromThis(duk_context *ctx)
|
||||
@@ -453,6 +525,38 @@ duk_ret_t ILibDuktape_EventEmitter_EmbeddedFinalizer(duk_context *ctx)
|
||||
memset(data, 0, sizeof(ILibDuktape_EventEmitter));
|
||||
return(0);
|
||||
}
|
||||
duk_ret_t ILibDuktape_EventEmitter_emitReturnValue(duk_context *ctx)
|
||||
{
|
||||
int retVal = 1;
|
||||
int nargs = duk_get_top(ctx);
|
||||
duk_push_this(ctx); // [this]
|
||||
|
||||
switch (nargs)
|
||||
{
|
||||
case 0:
|
||||
duk_get_prop_string(ctx, -1, ILibDuktape_EventEmitter_RetVal); // [this][retVal]
|
||||
break;
|
||||
case 1:
|
||||
duk_get_prop_string(ctx, -1, ILibDuktape_EventEmitter_TempObject); // [this][tmp]
|
||||
duk_get_prop_string(ctx, -1, ILibDuktape_EventEmitter_LastRetValueTable); // [this][tmp][table]
|
||||
duk_dup(ctx, 0); // [this][tmp][table][key]
|
||||
duk_get_prop(ctx, -2); // [this][tmp][table][val]
|
||||
break;
|
||||
case 2:
|
||||
duk_get_prop_string(ctx, -1, ILibDuktape_EventEmitter_TempObject); // [this][tmp]
|
||||
duk_get_prop_string(ctx, -1, ILibDuktape_EventEmitter_LastRetValueTable); // [this][tmp][table]
|
||||
duk_dup(ctx, 0); // [this][tmp][table][key]
|
||||
duk_dup(ctx, 1); // [this][tmp][table][key][value]
|
||||
duk_put_prop(ctx, -3);
|
||||
retVal = 0;
|
||||
break;
|
||||
default:
|
||||
retVal = ILibDuktape_Error(ctx, "INVALID Parameter Count");
|
||||
break;
|
||||
}
|
||||
|
||||
return(retVal);
|
||||
}
|
||||
ILibDuktape_EventEmitter* ILibDuktape_EventEmitter_Create(duk_context *ctx)
|
||||
{
|
||||
ILibDuktape_EventEmitter *retVal;
|
||||
@@ -466,14 +570,15 @@ ILibDuktape_EventEmitter* ILibDuktape_EventEmitter_Create(duk_context *ctx)
|
||||
return retVal;
|
||||
}
|
||||
|
||||
duk_push_object(ctx); // [emitterTmp]
|
||||
duk_push_fixed_buffer(ctx, sizeof(ILibDuktape_EventEmitter)); // [emitterTmp][data]
|
||||
retVal = (ILibDuktape_EventEmitter*)Duktape_GetBuffer(ctx, -1, NULL);
|
||||
memset(retVal, 0, sizeof(ILibDuktape_EventEmitter));
|
||||
duk_push_object(ctx); // [emitterTmp]
|
||||
retVal = (ILibDuktape_EventEmitter*)Duktape_PushBuffer(ctx, sizeof(ILibDuktape_EventEmitter)); // [emitterTmp][data]
|
||||
retVal->tmpObject = duk_get_heapptr(ctx, -2);
|
||||
|
||||
duk_put_prop_string(ctx, -2, ILibDuktape_EventEmitter_Data); // [emitterTmp]
|
||||
duk_put_prop_string(ctx, -2, ILibDuktape_EventEmitter_TempObject); // [...parent...]
|
||||
duk_put_prop_string(ctx, -2, ILibDuktape_EventEmitter_Data); // [emitterTmp]
|
||||
duk_push_object(ctx); // [emitterTmp][retValTable]
|
||||
retVal->retValTable = duk_get_heapptr(ctx, -1);
|
||||
duk_put_prop_string(ctx, -2, ILibDuktape_EventEmitter_LastRetValueTable); // [emitterTmp]
|
||||
duk_put_prop_string(ctx, -2, ILibDuktape_EventEmitter_TempObject); // [...parent...]
|
||||
|
||||
retVal->ctx = ctx;
|
||||
retVal->object = duk_get_heapptr(ctx, -1);
|
||||
@@ -487,6 +592,7 @@ ILibDuktape_EventEmitter* ILibDuktape_EventEmitter_Create(duk_context *ctx)
|
||||
ILibDuktape_CreateInstanceMethod(ctx, "removeListener", ILibDuktape_EventEmitter_removeListener, 2);
|
||||
ILibDuktape_CreateInstanceMethod(ctx, "removeAllListeners", ILibDuktape_EventEmitter_removeAllListeners, DUK_VARARGS);
|
||||
ILibDuktape_CreateInstanceMethod(ctx, "emit", ILibDuktape_EventEmitter_emit, DUK_VARARGS);
|
||||
ILibDuktape_CreateInstanceMethod(ctx, "emit_returnValue", ILibDuktape_EventEmitter_emitReturnValue, DUK_VARARGS);
|
||||
|
||||
duk_push_heap_stash(ctx);
|
||||
if (duk_has_prop_string(ctx, -1, ILibDuktape_EventEmitter_GlobalListenerCount))
|
||||
@@ -508,6 +614,8 @@ ILibDuktape_EventEmitter* ILibDuktape_EventEmitter_Create(duk_context *ctx)
|
||||
duk_push_c_function(ctx, ILibDuktape_EventEmitter_EmbeddedFinalizer, 1);
|
||||
duk_set_finalizer(ctx, -2);
|
||||
|
||||
ILibDuktape_EventEmitter_CreateEventEx(retVal, "_eventHook");
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
@@ -518,6 +626,10 @@ void ILibDuktape_EventEmitter_AddHook(ILibDuktape_EventEmitter *emitter, char *e
|
||||
ILibHashtable_Put(emitter->eventTable, ILibDuktape_EventEmitter_Hook, eventName, (int)strnlen_s(eventName, 255), handler);
|
||||
}
|
||||
}
|
||||
void ILibDuktape_EventEmitter_ClearHook(ILibDuktape_EventEmitter *emitter, char *eventName)
|
||||
{
|
||||
ILibHashtable_Remove(emitter->eventTable, ILibDuktape_EventEmitter_Hook, eventName, (int)strnlen_s(eventName, 255));
|
||||
}
|
||||
duk_ret_t ILibDuktape_EventEmitter_SetEvent(duk_context *ctx)
|
||||
{
|
||||
char *propName;
|
||||
@@ -617,7 +729,7 @@ duk_ret_t ILibDuktape_EventEmitter_Inherits_createEvent(duk_context *ctx)
|
||||
duk_pop(ctx); // [emitterUtils]
|
||||
|
||||
ILibDuktape_EventEmitter_CreateEventEx(emitter, name);
|
||||
return 0;
|
||||
return(1);
|
||||
}
|
||||
duk_ret_t ILibDuktape_EventEmitter_Inherits_addMethod(duk_context *ctx)
|
||||
{
|
||||
@@ -658,10 +770,45 @@ duk_ret_t ILibDuktape_EventEmitter_Inherits(duk_context *ctx)
|
||||
ILibDuktape_EventEmitter_CreateEventEx(emitter, "~");
|
||||
return 1;
|
||||
}
|
||||
duk_ret_t ILibDuktape_EventEmitter_EventEmitter(duk_context *ctx)
|
||||
{
|
||||
ILibDuktape_EventEmitter *emitter;
|
||||
int nargs = duk_get_top(ctx);
|
||||
int retVal = 0;
|
||||
|
||||
duk_push_this(ctx); // [target]
|
||||
emitter = ILibDuktape_EventEmitter_Create(ctx);
|
||||
duk_push_object(ctx); // [target][emitterUtils]
|
||||
duk_dup(ctx, -2); // [target][emitterUtils][target]
|
||||
duk_put_prop_string(ctx, -2, "\xFF_MainObject"); // [target][emitterUtils]
|
||||
duk_dup(ctx, -1); // [target][emitterUtils][dup]
|
||||
duk_put_prop_string(ctx, -3, "\xFF_emitterUtils"); // [target][emitterUtils]
|
||||
duk_push_pointer(ctx, emitter); // [target][emitterUtils][ptr]
|
||||
duk_put_prop_string(ctx, -2, "emitter"); // [target][emitterUtils]
|
||||
ILibDuktape_CreateFinalizer(ctx, ILibDuktape_EventEmitter_EmitterUtils_Finalizer);
|
||||
|
||||
if (nargs == 1 && duk_require_boolean(ctx, 0))
|
||||
{
|
||||
// Explicit Events
|
||||
ILibDuktape_CreateInstanceMethod(ctx, "createEvent", ILibDuktape_EventEmitter_Inherits_createEvent, 1);
|
||||
ILibDuktape_CreateInstanceMethod(ctx, "addMethod", ILibDuktape_EventEmitter_Inherits_addMethod, 2);
|
||||
retVal = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Implicit Events
|
||||
emitter->eventType = ILibDuktape_EventEmitter_Type_IMPLICIT;
|
||||
}
|
||||
|
||||
ILibDuktape_EventEmitter_CreateEventEx(emitter, "~");
|
||||
|
||||
return(retVal);
|
||||
}
|
||||
void ILibDuktape_EventEmitter_PUSH(duk_context *ctx, void *chain)
|
||||
{
|
||||
duk_push_object(ctx); // [emitter]
|
||||
ILibDuktape_CreateInstanceMethod(ctx, "inherits", ILibDuktape_EventEmitter_Inherits, 1);
|
||||
ILibDuktape_CreateInstanceMethod(ctx, "EventEmitter", ILibDuktape_EventEmitter_EventEmitter, DUK_VARARGS);
|
||||
}
|
||||
void ILibDuktape_EventEmitter_Init(duk_context *ctx)
|
||||
{
|
||||
@@ -690,48 +837,195 @@ duk_ret_t ILibDuktape_EventEmitter_ForwardEvent_Sink(duk_context *ctx)
|
||||
|
||||
duk_ret_t ILibDuktape_EventEmitter_ForwardEvent_Finalizer(duk_context *ctx)
|
||||
{
|
||||
duk_push_current_function(ctx); // [func]
|
||||
duk_get_prop_string(ctx, -1, "fptr"); // [func][fptr]
|
||||
duk_get_prop_string(ctx, -1, "targetObject"); // [func][fptr][target]
|
||||
duk_del_prop_string(ctx, -2, "targetObject");
|
||||
if (g_displayFinalizerMessages) { printf("EventEmitter.Forwarder[%s]: Deleted reference to [%s] RC=%d\n", Duktape_GetStringPropertyValue(ctx, -3, "targetName", "UNKNOWN"), Duktape_GetStringPropertyValue(ctx, -1, ILibDuktape_OBJID, "UNKNOWN"), ILibDuktape_GetReferenceCount(ctx, -1) - 1); }
|
||||
duk_pop_n(ctx, 3);
|
||||
void *src = NULL;
|
||||
char *srcName = NULL;
|
||||
|
||||
if (g_displayFinalizerMessages)
|
||||
{
|
||||
duk_push_this(ctx);
|
||||
src = duk_get_heapptr(ctx, -1);
|
||||
srcName = Duktape_GetStringPropertyValue(ctx, -1, ILibDuktape_OBJID, "UNKNOWN");
|
||||
duk_pop(ctx);
|
||||
}
|
||||
duk_push_current_function(ctx); // [func]
|
||||
if (duk_has_prop_string(ctx, -1, "fptr"))
|
||||
{
|
||||
duk_get_prop_string(ctx, -1, "fptr"); // [func][fptr]
|
||||
if (duk_has_prop_string(ctx, -1, "targetObject"))
|
||||
{
|
||||
duk_get_prop_string(ctx, -1, "targetObject"); // [func][fptr][target]
|
||||
duk_del_prop_string(ctx, -2, "targetObject");
|
||||
if (g_displayFinalizerMessages) { printf("EventEmitter.Forwarder[%s]: Deleted reference to [%s/%p] RC=%d from [%s/%p]\n", Duktape_GetStringPropertyValue(ctx, -3, "targetName", "UNKNOWN"), Duktape_GetStringPropertyValue(ctx, -1, ILibDuktape_OBJID, "UNKNOWN"), duk_get_heapptr(ctx, -1), ILibDuktape_GetReferenceCount(ctx, -1) - 1, srcName, src); }
|
||||
duk_pop_n(ctx, 3);
|
||||
}
|
||||
}
|
||||
if (g_displayFinalizerMessages) { duk_eval_string(ctx, "_debugGC();"); duk_pop(ctx); }
|
||||
return(0);
|
||||
}
|
||||
duk_ret_t ILibDuktape_EventEmitter_ForwardEvent_HookSink(duk_context *ctx)
|
||||
{
|
||||
duk_push_current_function(ctx);
|
||||
duk_size_t sourceLen, targetLen, hookLen;
|
||||
char *source, *target, *hook;
|
||||
void *sourceObject, *fptr;
|
||||
|
||||
source = Duktape_GetStringPropertyValueEx(ctx, -1, ILibDuktape_EventEmitter_Forward_SourceName, NULL, &sourceLen);
|
||||
target = Duktape_GetStringPropertyValueEx(ctx, -1, ILibDuktape_EventEmitter_Forward_TargetName, NULL, &targetLen);
|
||||
sourceObject = Duktape_GetHeapptrProperty(ctx, -1, ILibDuktape_EventEmitter_Forward_SourceObject);
|
||||
|
||||
if (source != NULL && target != NULL && sourceObject != NULL)
|
||||
{
|
||||
hook = (char*)duk_get_lstring(ctx, 0, &hookLen);
|
||||
if (!(hookLen == targetLen && strncmp(target, hook, hookLen) == 0))
|
||||
{
|
||||
// This hooked event wasn't for us, so let's rehook this logic up for next time
|
||||
duk_push_this(ctx); // [this]
|
||||
duk_get_prop_string(ctx, -1, "once"); // [this][once]
|
||||
duk_swap_top(ctx, -2); // [once][this]
|
||||
duk_push_string(ctx, "_eventHook"); // [once][this][_eventHook]
|
||||
duk_push_c_function(ctx, ILibDuktape_EventEmitter_ForwardEvent_HookSink, DUK_VARARGS); // [once][this][_eventHook][func]
|
||||
duk_push_lstring(ctx, source, sourceLen); duk_put_prop_string(ctx, -2, ILibDuktape_EventEmitter_Forward_SourceName);
|
||||
duk_push_lstring(ctx, target, targetLen); duk_put_prop_string(ctx, -2, ILibDuktape_EventEmitter_Forward_TargetName);
|
||||
duk_push_heapptr(ctx, sourceObject); duk_put_prop_string(ctx, -2, ILibDuktape_EventEmitter_Forward_SourceObject);
|
||||
duk_call_method(ctx, 2); duk_pop(ctx); // ...
|
||||
}
|
||||
else
|
||||
{
|
||||
// This hooked event is for us
|
||||
ILibDuktape_EventEmitter_SetupOn(ctx, sourceObject, source); // [on][this][source]
|
||||
duk_push_c_function(ctx, ILibDuktape_EventEmitter_ForwardEvent_Sink, DUK_VARARGS); // [on][this][source][sink]
|
||||
fptr = duk_get_heapptr(ctx, -1);
|
||||
duk_push_this(ctx); duk_put_prop_string(ctx, -2, "targetObject");
|
||||
duk_push_lstring(ctx, target, targetLen); duk_put_prop_string(ctx, -2, "targetName");
|
||||
if (duk_pcall_method(ctx, 2) != 0) { ILibDuktape_Process_UncaughtExceptionEx(ctx, "EventEmitter_ForwardEvent(): "); }
|
||||
duk_pop(ctx); // ...
|
||||
|
||||
ILibDuktape_EventEmitter_SetupPrependOnce(ctx, sourceObject, "~"); // [prependOnce][this][~]
|
||||
duk_push_c_function(ctx, ILibDuktape_EventEmitter_ForwardEvent_Finalizer, DUK_VARARGS); // [prependOnce][this]['~'][func]
|
||||
duk_push_heapptr(ctx, fptr); duk_put_prop_string(ctx, -2, "fptr");
|
||||
duk_push_lstring(ctx, target, targetLen); duk_put_prop_string(ctx, -2, "targetName");
|
||||
if (duk_pcall_method(ctx, 2) != 0) { ILibDuktape_Process_UncaughtExceptionEx(ctx, "EventEmitter_ForwardEvent_SetFinalizer(): "); }
|
||||
duk_pop(ctx); // ...
|
||||
}
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
void ILibDuktape_EventEmitter_DeleteForwardEvent(duk_context *ctx, duk_idx_t eventSourceIndex, char *sourceEventName)
|
||||
{
|
||||
duk_dup(ctx, eventSourceIndex); // [source]
|
||||
if (duk_has_prop_string(ctx, -1, ILibDuktape_EventEmitter_ForwardTable))
|
||||
{
|
||||
duk_get_prop_string(ctx, -1, ILibDuktape_EventEmitter_ForwardTable); // [source][table]
|
||||
if (duk_has_prop_string(ctx, -1, sourceEventName))
|
||||
{
|
||||
duk_get_prop_string(ctx, -1, sourceEventName); // [source][table][sink]
|
||||
duk_del_prop_string(ctx, -1, "targetObject");
|
||||
duk_get_prop_string(ctx, -3, "removeListener"); // [source][table][sink][removeListener]
|
||||
duk_dup(ctx, -4); // [source][table][sink][removeListener][this]
|
||||
duk_push_string(ctx, sourceEventName); // [source][table][sink][removeListener][this][name]
|
||||
duk_dup(ctx, -4); // [source][table][sink][removeListener][this][name][sink]
|
||||
duk_call_method(ctx, 2); duk_pop_2(ctx); // [source][table]
|
||||
if (duk_has_prop_string(ctx, -1, "~"))
|
||||
{
|
||||
duk_get_prop_string(ctx, -1, "~"); // [source][table][sink]
|
||||
duk_del_prop_string(ctx, -1, "fptr");
|
||||
duk_get_prop_string(ctx, -3, "removeListener"); // [source][table][sink][removeListener]
|
||||
duk_dup(ctx, -4); // [source][table][sink][removeListener][this]
|
||||
duk_push_string(ctx, "~"); // [source][table][sink][removeListener][this][name]
|
||||
duk_dup(ctx, -4); // [source][table][sink][removeListener][this][name][sink]
|
||||
duk_call_method(ctx, 2); duk_pop_2(ctx); // [source][table]
|
||||
}
|
||||
if (duk_has_prop_string(ctx, -1, "_eventHook"))
|
||||
{
|
||||
duk_get_prop_string(ctx, -1, "_eventHook"); // [source][table][sink]
|
||||
duk_get_prop_string(ctx, -3, "removeListener"); // [source][table][sink][removeListener]
|
||||
duk_dup(ctx, -4); // [source][table][sink][removeListener][this]
|
||||
duk_push_string(ctx, "_eventHook"); // [source][table][sink][removeListener][this][name]
|
||||
duk_dup(ctx, -4); // [source][table][sink][removeListener][this][name][sink]
|
||||
duk_call_method(ctx, 2); duk_pop_2(ctx); // [source][table]
|
||||
}
|
||||
}
|
||||
duk_pop(ctx); // [source]
|
||||
}
|
||||
duk_pop(ctx); // ...
|
||||
}
|
||||
void ILibDuktape_EventEmitter_ForwardEvent(duk_context *ctx, duk_idx_t eventSourceIndex, char *sourceEventName, duk_idx_t eventTargetIndex, char *targetEventName)
|
||||
{
|
||||
void *fptr;
|
||||
void *source;
|
||||
void *target;
|
||||
duk_dup(ctx, eventTargetIndex); // [targetObject]
|
||||
void *table = NULL;
|
||||
duk_dup(ctx, eventTargetIndex); // [targetObject]
|
||||
target = duk_get_heapptr(ctx, -1);
|
||||
duk_pop(ctx); // ...
|
||||
duk_dup(ctx, eventSourceIndex); // [sourceObject]
|
||||
duk_get_prop_string(ctx, -1, "on"); // [sourceObject][on]
|
||||
duk_swap_top(ctx, -2); // [on][this]
|
||||
duk_push_string(ctx, sourceEventName); // [on][this][name]
|
||||
duk_push_c_function(ctx, ILibDuktape_EventEmitter_ForwardEvent_Sink, DUK_VARARGS); // [on][this][name][sink]
|
||||
fptr = duk_get_heapptr(ctx, -1);
|
||||
duk_push_heapptr(ctx, target); // [on][this][name][sink][targetObject]
|
||||
duk_put_prop_string(ctx, -2, "targetObject"); // [on][this][name][sink]
|
||||
duk_push_string(ctx, targetEventName); // [on][this][name][sink][targetName]
|
||||
duk_put_prop_string(ctx, -2, "targetName"); // [on][this][name][sink]
|
||||
if (duk_pcall_method(ctx, 2) != 0) { ILibDuktape_Process_UncaughtExceptionEx(ctx, "EventEmitter_ForwardEvent(): "); }
|
||||
duk_pop(ctx); // ...
|
||||
|
||||
duk_dup(ctx, eventSourceIndex); // [sourceObject]
|
||||
duk_get_prop_string(ctx, -1, "prependOnceListener"); // [sourceObject][prependOnce]
|
||||
duk_swap_top(ctx, -2); // [prependOnce][this]
|
||||
duk_push_string(ctx, "~"); // [prependOnce][this]['~']
|
||||
duk_push_c_function(ctx, ILibDuktape_EventEmitter_ForwardEvent_Finalizer, DUK_VARARGS); // [prependOnce][this]['~'][func]
|
||||
duk_push_heapptr(ctx, fptr); // [prependOnce][this]['~'][func][fptr]
|
||||
duk_put_prop_string(ctx, -2, "fptr"); // [prependOnce][this]['~'][func]
|
||||
duk_push_string(ctx, targetEventName); // [prependOnce][this]['~'][func][name]
|
||||
duk_put_prop_string(ctx, -2, "targetName"); // [prependOnce][this]['~'][func]
|
||||
|
||||
if (duk_pcall_method(ctx, 2) != 0) { ILibDuktape_Process_UncaughtExceptionEx(ctx, "EventEmitter_ForwardEvent_SetFinalizer(): "); }
|
||||
duk_pop(ctx); // ...
|
||||
duk_dup(ctx, eventSourceIndex); // [sourceObject]
|
||||
source = duk_get_heapptr(ctx, -1);
|
||||
duk_pop(ctx); // ...
|
||||
|
||||
|
||||
duk_push_heapptr(ctx, source); // [source]
|
||||
ILibDuktape_EventEmitter_DeleteForwardEvent(ctx, -1, sourceEventName);
|
||||
if (duk_has_prop_string(ctx, -1, ILibDuktape_EventEmitter_ForwardTable))
|
||||
{
|
||||
duk_get_prop_string(ctx, -1, ILibDuktape_EventEmitter_ForwardTable); // [source][table]
|
||||
table = duk_get_heapptr(ctx, -1);
|
||||
duk_pop(ctx); // [source]
|
||||
}
|
||||
else
|
||||
{
|
||||
duk_push_object(ctx); // [source][table]
|
||||
table = duk_get_heapptr(ctx, -1);
|
||||
duk_put_prop_string(ctx, -2, ILibDuktape_EventEmitter_ForwardTable); // [source]
|
||||
}
|
||||
duk_pop(ctx); // ...
|
||||
|
||||
|
||||
duk_push_heapptr(ctx, target); // [target]
|
||||
if (ILibDuktape_EventEmitter_HasListeners(ILibDuktape_EventEmitter_GetEmitter(ctx, -1), targetEventName) > 0)
|
||||
{
|
||||
// Target already has listeners, so we can go ahead and forward events
|
||||
duk_pop(ctx); // ...
|
||||
|
||||
ILibDuktape_EventEmitter_SetupOn(ctx, source, sourceEventName); // [on][this][source]
|
||||
duk_push_c_function(ctx, ILibDuktape_EventEmitter_ForwardEvent_Sink, DUK_VARARGS); // [on][this][source][sink]
|
||||
fptr = duk_get_heapptr(ctx, -1);
|
||||
duk_push_heapptr(ctx, target); duk_put_prop_string(ctx, -2, "targetObject");
|
||||
duk_push_string(ctx, targetEventName); duk_put_prop_string(ctx, -2, "targetName");
|
||||
if (duk_pcall_method(ctx, 2) != 0) { ILibDuktape_Process_UncaughtExceptionEx(ctx, "EventEmitter_ForwardEvent(): "); }
|
||||
duk_pop(ctx); // ...
|
||||
|
||||
duk_push_heapptr(ctx, table); // [table]
|
||||
duk_push_heapptr(ctx, fptr); // [table][func]
|
||||
duk_put_prop_string(ctx, -2, sourceEventName); // [table]
|
||||
duk_pop(ctx); // ...
|
||||
|
||||
ILibDuktape_EventEmitter_SetupPrependOnce(ctx, source, "~"); // [prependOnce][this][~]
|
||||
duk_push_c_function(ctx, ILibDuktape_EventEmitter_ForwardEvent_Finalizer, DUK_VARARGS); // [prependOnce][this]['~'][func]
|
||||
|
||||
duk_push_heapptr(ctx, table); // [prependOnce][this]['~'][func][table]
|
||||
duk_dup(ctx, -2); // [prependOnce][this]['~'][func][table][func]
|
||||
duk_put_prop_string(ctx, -2, "~"); // [prependOnce][this]['~'][func][table]
|
||||
duk_pop(ctx); // [prependOnce][this]['~'][func]
|
||||
|
||||
duk_push_heapptr(ctx, fptr); duk_put_prop_string(ctx, -2, "fptr");
|
||||
duk_push_string(ctx, targetEventName); duk_put_prop_string(ctx, -2, "targetName");
|
||||
if (duk_pcall_method(ctx, 2) != 0) { ILibDuktape_Process_UncaughtExceptionEx(ctx, "EventEmitter_ForwardEvent_SetFinalizer(): "); }
|
||||
duk_pop(ctx); // ...
|
||||
}
|
||||
else
|
||||
{
|
||||
// Target has no listeners, so only forward events if someone adds a listener
|
||||
duk_get_prop_string(ctx, -1, "once"); // [target][once]
|
||||
duk_swap_top(ctx, -2); // [once][this]
|
||||
duk_push_string(ctx, "_eventHook"); // [once][this][_eventHook]
|
||||
duk_push_c_function(ctx, ILibDuktape_EventEmitter_ForwardEvent_HookSink, DUK_VARARGS); // [once][this][_eventHook][func]
|
||||
duk_push_string(ctx, sourceEventName); duk_put_prop_string(ctx, -2, ILibDuktape_EventEmitter_Forward_SourceName);
|
||||
duk_push_string(ctx, targetEventName); duk_put_prop_string(ctx, -2, ILibDuktape_EventEmitter_Forward_TargetName);
|
||||
duk_push_heapptr(ctx, source); duk_put_prop_string(ctx, -2, ILibDuktape_EventEmitter_Forward_SourceObject);
|
||||
if (duk_pcall_method(ctx, 2) != 0) { ILibDuktape_Process_UncaughtExceptionEx(ctx, "Error hooking event: %s ", targetEventName); }
|
||||
duk_pop(ctx); // ...
|
||||
}
|
||||
}
|
||||
int ILibDuktape_EventEmitter_AddOnEx(duk_context *ctx, duk_idx_t idx, char *eventName, duk_c_function func)
|
||||
{
|
||||
|
||||
@@ -2845,16 +2845,16 @@ typedef struct duk_hthread duk_context;
|
||||
#undef DUK_USE_DATE_GET_NOW
|
||||
#undef DUK_USE_DATE_PARSE_STRING
|
||||
#undef DUK_USE_DATE_PRS_GETDATE
|
||||
#undef DUK_USE_DEBUG
|
||||
#undef DUK_USE_DEBUGGER_DUMPHEAP
|
||||
#undef DUK_USE_DEBUGGER_INSPECT
|
||||
#undef DUK_USE_DEBUGGER_PAUSE_UNCAUGHT
|
||||
#undef DUK_USE_DEBUGGER_SUPPORT
|
||||
//#undef DUK_USE_DEBUG
|
||||
//#undef DUK_USE_DEBUGGER_DUMPHEAP
|
||||
//#undef DUK_USE_DEBUGGER_INSPECT
|
||||
//#undef DUK_USE_DEBUGGER_PAUSE_UNCAUGHT
|
||||
//#undef DUK_USE_DEBUGGER_SUPPORT
|
||||
#define DUK_USE_DEBUGGER_THROW_NOTIFY
|
||||
#undef DUK_USE_DEBUGGER_TRANSPORT_TORTURE
|
||||
#define DUK_USE_DEBUG_BUFSIZE 65536L
|
||||
#define DUK_USE_DEBUG_LEVEL 0
|
||||
#undef DUK_USE_DEBUG_WRITE
|
||||
//#undef DUK_USE_DEBUG_WRITE
|
||||
#define DUK_USE_DOUBLE_LINKED_HEAP
|
||||
#define DUK_USE_DUKTAPE_BUILTIN
|
||||
#define DUK_USE_ENCODING_BUILTINS
|
||||
@@ -2917,8 +2917,8 @@ typedef struct duk_hthread duk_context;
|
||||
#define DUK_USE_HTML_COMMENTS
|
||||
#define DUK_USE_IDCHAR_FASTPATH
|
||||
#undef DUK_USE_INJECT_HEAP_ALLOC_ERROR
|
||||
#undef DUK_USE_INTERRUPT_COUNTER
|
||||
#undef DUK_USE_INTERRUPT_DEBUG_FIXUP
|
||||
//#undef DUK_USE_INTERRUPT_COUNTER
|
||||
//#undef DUK_USE_INTERRUPT_DEBUG_FIXUP
|
||||
#define DUK_USE_JC
|
||||
#define DUK_USE_JSON_BUILTIN
|
||||
#define DUK_USE_JSON_DECNUMBER_FASTPATH
|
||||
|
||||
27
microscript/s.h
Normal file
27
microscript/s.h
Normal file
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
Copyright 2006 - 2018 Intel Corporation
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef __DUKTAPE_SIMPLEDATASTORE__
|
||||
#define __DUKTAPE_SIMPLEDATASTORE__
|
||||
|
||||
|
||||
#include "duktape.h"
|
||||
#include "microstack/ILibSimpleDataStore.h"
|
||||
|
||||
void ILibDuktape_SimpleDataStore_init(duk_context *ctx, ILibSimpleDataStore sharedDb);
|
||||
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user