mirror of
https://github.com/Ylianst/MeshAgent
synced 2026-01-06 10:34:09 +00:00
1. Added crc32-stream modules
2. Updated flow control for compressed-stream 3. Added newListener even on EventEmitter, that fires event after a lsitener is added 4. Added two new event helper methods 5. Updated fs.read to work with CreateFile on Windows.
This commit is contained in:
@@ -27,8 +27,8 @@ limitations under the License.
|
||||
|
||||
#include "meshcore/zlib/zlib.h"
|
||||
|
||||
#define ILibDuktape_CompressorStream_ptr "\xFF_Duktape_CompressorStream_ptr"
|
||||
|
||||
#define ILibDuktape_CompressorStream_ptr "\xFF_Duktape_CompressorStream_ptr"
|
||||
#define ILibDuktape_CompressorStream_ResumeBuffer "\xFF_Duktape_CompressorStream_ResumeBuffer"
|
||||
typedef struct ILibDuktape_CompressorStream
|
||||
{
|
||||
duk_context *ctx;
|
||||
@@ -48,7 +48,51 @@ void ILibDuktape_Compressor_Pause(ILibDuktape_DuplexStream *sender, void *user)
|
||||
}
|
||||
void ILibDuktape_deCompressor_Resume(ILibDuktape_DuplexStream *sender, void *user)
|
||||
{
|
||||
|
||||
ILibDuktape_CompressorStream *cs = (ILibDuktape_CompressorStream*)user;
|
||||
duk_push_heapptr(cs->ctx, cs->object); // [stream]
|
||||
char *inbuffer = (char*)Duktape_GetBufferProperty(cs->ctx, -1, ILibDuktape_CompressorStream_ResumeBuffer);
|
||||
if (inbuffer == NULL)
|
||||
{
|
||||
ILibDuktape_DuplexStream_Ready(cs->ds);
|
||||
return;
|
||||
}
|
||||
char buffer[16384];
|
||||
size_t avail = 0;
|
||||
int res = 0;
|
||||
cs->Z.avail_in = (uint32_t)ILibMemory_Size(inbuffer);
|
||||
cs->Z.next_in = inbuffer;
|
||||
do
|
||||
{
|
||||
cs->Z.avail_out = sizeof(buffer);
|
||||
cs->Z.next_out = buffer;
|
||||
ignore_result(inflate(&(cs->Z), Z_NO_FLUSH));
|
||||
avail = sizeof(buffer) - cs->Z.avail_out;
|
||||
if (avail > 0)
|
||||
{
|
||||
res = ILibDuktape_DuplexStream_WriteData(cs->ds, buffer, (int)avail); // [stream]
|
||||
if (res == 1)
|
||||
{
|
||||
// Downstream Paused
|
||||
if (cs->Z.avail_in > 0)
|
||||
{
|
||||
char *tmp = (char*)Duktape_PushBuffer(cs->ctx, cs->Z.avail_in); // [stream][buffer]
|
||||
duk_put_prop_string(cs->ctx, -2, ILibDuktape_CompressorStream_ResumeBuffer);// [stream]
|
||||
memcpy_s(tmp, ILibMemory_Size(tmp), cs->Z.next_in, ILibMemory_Size(tmp));
|
||||
}
|
||||
else
|
||||
{
|
||||
duk_del_prop_string(cs->ctx, -1, ILibDuktape_CompressorStream_ResumeBuffer);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
} while (cs->Z.avail_out == 0);
|
||||
if (res == 0) { duk_del_prop_string(cs->ctx, -1, ILibDuktape_CompressorStream_ResumeBuffer); }
|
||||
duk_pop(cs->ctx); // ...
|
||||
if (res == 0)
|
||||
{
|
||||
ILibDuktape_DuplexStream_Ready(cs->ds);
|
||||
}
|
||||
}
|
||||
void ILibDuktape_deCompressor_Pause(ILibDuktape_DuplexStream *sender, void *user)
|
||||
{
|
||||
@@ -69,7 +113,7 @@ void ILibDuktape_Compressor_End(ILibDuktape_DuplexStream *stream, void *user)
|
||||
cs->Z.next_out = (Bytef*)tmp;
|
||||
ignore_result(deflate(&(cs->Z), Z_FINISH));
|
||||
avail = sizeof(tmp) - cs->Z.avail_out;
|
||||
ILibDuktape_DuplexStream_WriteData(cs->ds, tmp, (int)avail);
|
||||
if (avail > 0) { ILibDuktape_DuplexStream_WriteData(cs->ds, tmp, (int)avail); }
|
||||
} while (cs->Z.avail_out == 0);
|
||||
ILibDuktape_DuplexStream_WriteEnd(cs->ds);
|
||||
|
||||
@@ -110,6 +154,14 @@ duk_ret_t ILibDuktape_Compressor_Finalizer(duk_context *ctx)
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
duk_ret_t ILibDuktape_CompressedStream_resume_newListener(duk_context *ctx)
|
||||
{
|
||||
duk_push_this(ctx); // [stream]
|
||||
duk_prepare_method_call(ctx, -1, "resume"); // [stream][resume][this]
|
||||
duk_pcall_method(ctx, 0);
|
||||
return(0);
|
||||
}
|
||||
|
||||
duk_ret_t ILibDuktape_CompressedStream_compressor(duk_context *ctx)
|
||||
{
|
||||
duk_push_object(ctx); // [compressed-stream]
|
||||
@@ -124,6 +176,8 @@ duk_ret_t ILibDuktape_CompressedStream_compressor(duk_context *ctx)
|
||||
cs->Z.opaque = Z_NULL;
|
||||
if (deflateInit(&(cs->Z), Z_DEFAULT_COMPRESSION) != Z_OK) { return(ILibDuktape_Error(ctx, "zlib error")); }
|
||||
ILibDuktape_CreateFinalizer(ctx, ILibDuktape_Compressor_Finalizer);
|
||||
cs->ds->readableStream->paused = 1;
|
||||
duk_events_newListener2(ctx, -1, "data", ILibDuktape_CompressedStream_resume_newListener);
|
||||
|
||||
return(1);
|
||||
}
|
||||
@@ -145,8 +199,33 @@ ILibTransport_DoneState ILibDuktape_deCompressor_Write(ILibDuktape_DuplexStream
|
||||
if (avail > 0)
|
||||
{
|
||||
ret = ILibDuktape_DuplexStream_WriteData(cs->ds, tmp, (int)avail);
|
||||
if (ret == 1)
|
||||
{
|
||||
// Downstream was paused, so we have to save state, so we can resume later
|
||||
duk_push_heapptr(cs->ctx, cs->object); // [stream]
|
||||
if (cs->Z.avail_in > 0)
|
||||
{
|
||||
char *tmp = Duktape_PushBuffer(cs->ctx, cs->Z.avail_in); // [stream][buffer]
|
||||
memcpy_s(tmp, ILibMemory_Size(tmp), cs->Z.next_in, ILibMemory_Size(tmp));
|
||||
duk_put_prop_string(cs->ctx, -2, ILibDuktape_CompressorStream_ResumeBuffer);// [stream]
|
||||
}
|
||||
else
|
||||
{
|
||||
duk_del_prop_string(cs->ctx, -1, ILibDuktape_CompressorStream_ResumeBuffer);
|
||||
}
|
||||
duk_pop(cs->ctx); // ...
|
||||
break;
|
||||
}
|
||||
}
|
||||
} while (cs->Z.avail_out == 0);
|
||||
|
||||
if (ret == 0)
|
||||
{
|
||||
duk_push_heapptr(cs->ctx, cs->object); // [stream]
|
||||
duk_del_prop_string(cs->ctx, -1, ILibDuktape_CompressorStream_ResumeBuffer);
|
||||
duk_pop(cs->ctx); // ...
|
||||
}
|
||||
|
||||
return(ret == 1 ? ILibTransport_DoneState_INCOMPLETE : ILibTransport_DoneState_COMPLETE);
|
||||
}
|
||||
void ILibDuktape_deCompressor_End(ILibDuktape_DuplexStream *stream, void *user)
|
||||
@@ -164,7 +243,10 @@ void ILibDuktape_deCompressor_End(ILibDuktape_DuplexStream *stream, void *user)
|
||||
cs->Z.next_out = (Bytef*)tmp;
|
||||
ignore_result(inflate(&(cs->Z), Z_FINISH));
|
||||
avail = sizeof(tmp) - cs->Z.avail_out;
|
||||
ILibDuktape_DuplexStream_WriteData(cs->ds, tmp, (int)avail);
|
||||
if (avail > 0)
|
||||
{
|
||||
ILibDuktape_DuplexStream_WriteData(cs->ds, tmp, (int)avail);
|
||||
}
|
||||
} while (cs->Z.avail_out == 0);
|
||||
ILibDuktape_DuplexStream_WriteEnd(cs->ds);
|
||||
ignore_result(inflateEnd(&(cs->Z)));
|
||||
@@ -183,6 +265,7 @@ duk_ret_t ILibDuktape_deCompressor_Finalizer(duk_context *ctx)
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
duk_ret_t ILibDuktape_CompressedStream_decompressor(duk_context *ctx)
|
||||
{
|
||||
duk_push_object(ctx); // [compressed-stream]
|
||||
@@ -197,9 +280,18 @@ duk_ret_t ILibDuktape_CompressedStream_decompressor(duk_context *ctx)
|
||||
cs->Z.opaque = Z_NULL;
|
||||
cs->Z.avail_in = 0;
|
||||
cs->Z.next_in = Z_NULL;
|
||||
if (inflateInit(&(cs->Z)) != Z_OK) { return(ILibDuktape_Error(ctx, "zlib error")); }
|
||||
ILibDuktape_CreateFinalizer(ctx, ILibDuktape_deCompressor_Finalizer);
|
||||
if (duk_is_number(ctx, 0) && duk_require_int(ctx, 0)==1)
|
||||
{
|
||||
if (inflateInit2(&(cs->Z), -MAX_WBITS) != Z_OK) { return(ILibDuktape_Error(ctx, "zlib error")); }
|
||||
}
|
||||
else
|
||||
{
|
||||
if (inflateInit(&(cs->Z)) != Z_OK) { return(ILibDuktape_Error(ctx, "zlib error")); }
|
||||
}
|
||||
|
||||
ILibDuktape_CreateFinalizer(ctx, ILibDuktape_deCompressor_Finalizer);
|
||||
cs->ds->readableStream->paused = 1;
|
||||
duk_events_newListener2(ctx, -1, "data", ILibDuktape_CompressedStream_resume_newListener);
|
||||
return(1);
|
||||
}
|
||||
void ILibDuktape_CompressedStream_PUSH(duk_context *ctx, void *chain)
|
||||
|
||||
@@ -96,12 +96,18 @@ void *Duktape_Duplicate_GetBufferPropertyEx(duk_context *ctx, duk_idx_t i, char*
|
||||
char *Duktape_Duplicate_GetStringEx(duk_context *ctx, duk_idx_t i, duk_size_t *len);
|
||||
#define Duktape_Duplicate_GetString(ctx, i) Duktape_Duplicate_GetStringEx(ctx, i, NULL)
|
||||
|
||||
extern duk_ret_t ILibDuktape_EventEmitter_DefaultNewListenerHandler(duk_context *ctx);
|
||||
#define duk_prepare_method_call(ctx, i, name) duk_dup(ctx, i);duk_get_prop_string(ctx, -1, name);duk_swap_top(ctx, -2);
|
||||
#define duk_array_shift(ctx, i) duk_dup(ctx, i);duk_get_prop_string(ctx, -1, "shift");duk_swap_top(ctx, -2);duk_call_method(ctx, 0);
|
||||
#define duk_array_pop(ctx, i) duk_dup(ctx, i);duk_get_prop_string(ctx, -1, "pop");duk_swap_top(ctx, -2);duk_call_method(ctx, 0);
|
||||
#define duk_array_push(ctx, i) duk_dup(ctx, i);duk_get_prop_string(ctx, -1, "push");duk_swap_top(ctx, -2);duk_dup(ctx,-3);duk_pcall_method(ctx, 1);duk_pop_2(ctx);
|
||||
#define duk_array_join(ctx, i, str) duk_dup(ctx, i);duk_get_prop_string(ctx, -1, "join");duk_swap_top(ctx, -2);duk_push_string(ctx, str);duk_pcall_method(ctx, 1);
|
||||
#define duk_array_unshift(ctx, i) duk_dup(ctx, i);duk_get_prop_string(ctx, -1, "unshift");duk_swap_top(ctx, -2);duk_dup(ctx, -3);duk_remove(ctx, -4);duk_pcall_method(ctx, 1);duk_pop(ctx);
|
||||
|
||||
#define duk_events_setup_on(ctx, i, name, func) duk_prepare_method_call(ctx, i, "on");duk_push_string(ctx, name);duk_push_c_function(ctx, func, DUK_VARARGS);
|
||||
#define duk_events_newListener(ctx, i, name, func) duk_events_setup_on(ctx, i, "newListener", ILibDuktape_EventEmitter_DefaultNewListenerHandler);duk_push_string(ctx, name);duk_put_prop_string(ctx, -2, "event_name");duk_push_c_function(ctx, func, DUK_VARARGS);duk_put_prop_string(ctx, -2, "event_callback");if(duk_pcall_method(ctx, 2)!=0){printf("oops\n");ILibDuktape_Process_UncaughtExceptionEx(ctx, "duk_events_newListener (%s,%d)", __FILE__, __LINE__);}duk_pop(ctx);
|
||||
#define duk_events_newListener2(ctx, i, name, func) duk_events_setup_on(ctx, i, "newListener2", ILibDuktape_EventEmitter_DefaultNewListenerHandler);duk_push_string(ctx, name);duk_put_prop_string(ctx, -2, "event_name");duk_push_c_function(ctx, func, DUK_VARARGS);duk_put_prop_string(ctx, -2, "event_callback");if(duk_pcall_method(ctx, 2)!=0){printf("oops\n");ILibDuktape_Process_UncaughtExceptionEx(ctx, "duk_events_newListener (%s,%d)", __FILE__, __LINE__);}duk_pop(ctx);
|
||||
|
||||
#define duk_queue_create(ctx) duk_push_array(ctx)
|
||||
#define duk_queue_enQueue(ctx, i) duk_array_push(ctx, i)
|
||||
#define duk_queue_deQueue(ctx, i) duk_array_shift(ctx, i)
|
||||
@@ -120,6 +126,7 @@ char *Duktape_Duplicate_GetStringEx(duk_context *ctx, duk_idx_t i, duk_size_t *l
|
||||
#define duk_string_concat(ctx, i) duk_dup(ctx, i);duk_get_prop_string(ctx, -1, "concat");duk_swap_top(ctx, -2);duk_dup(ctx, -3);duk_pcall_method(ctx, 1);duk_remove(ctx, -2);
|
||||
#define duk_string_split(ctx, i, delim) duk_dup(ctx, i);duk_get_prop_string(ctx, -1, "split");duk_swap_top(ctx, -2);duk_push_string(ctx, delim);duk_call_method(ctx, 1);
|
||||
|
||||
|
||||
int Duktape_GetBooleanProperty(duk_context *ctx, duk_idx_t i, char *propertyName, int defaultValue);
|
||||
struct sockaddr_in6* Duktape_IPAddress4_FromString(char* address, unsigned short port);
|
||||
struct sockaddr_in6* Duktape_IPAddress6_FromString(char* address, unsigned short port);
|
||||
|
||||
@@ -1108,6 +1108,7 @@ duk_ret_t ILibDuktape_Polyfills_addCompressedModule(duk_context *ctx)
|
||||
duk_eval_string(ctx, "require('compressed-stream').createDecompressor();");
|
||||
void *decoder = duk_get_heapptr(ctx, -1);
|
||||
ILibDuktape_EventEmitter_AddOnEx(ctx, -1, "data", ILibDuktape_Polyfills_addCompressedModule_dataSink);
|
||||
|
||||
duk_dup(ctx, -1); // [stream]
|
||||
duk_get_prop_string(ctx, -1, "end"); // [stream][end]
|
||||
duk_swap_top(ctx, -2); // [end][this]
|
||||
@@ -1598,7 +1599,10 @@ ILibTransport_DoneState ILibDuktape_Stream_Writable_WriteSink(struct ILibDuktape
|
||||
}
|
||||
else
|
||||
{
|
||||
retVal = duk_to_boolean(stream->ctx, -1) ? ILibTransport_DoneState_COMPLETE : ILibTransport_DoneState_INCOMPLETE;
|
||||
if (retVal != ILibTransport_DoneState_COMPLETE)
|
||||
{
|
||||
retVal = duk_to_boolean(stream->ctx, -1) ? ILibTransport_DoneState_COMPLETE : ILibTransport_DoneState_INCOMPLETE;
|
||||
}
|
||||
}
|
||||
duk_pop(stream->ctx); // ...
|
||||
|
||||
@@ -1859,11 +1863,21 @@ void ILibDuktape_PKCS7_Push(duk_context *ctx, void *chain)
|
||||
}
|
||||
|
||||
extern uint32_t crc32c(uint32_t crc, const unsigned char* buf, uint32_t len);
|
||||
extern uint32_t crc32(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_uint(ctx, crc32c(0, (unsigned char*)buffer, (uint32_t)len));
|
||||
uint32_t pre = duk_is_number(ctx, 1) ? duk_require_uint(ctx, 1) : 0;
|
||||
duk_push_uint(ctx, crc32c(pre, (unsigned char*)buffer, (uint32_t)len));
|
||||
return(1);
|
||||
}
|
||||
duk_ret_t ILibDuktape_Polyfills_crc32(duk_context *ctx)
|
||||
{
|
||||
duk_size_t len;
|
||||
char *buffer = Duktape_GetBuffer(ctx, 0, &len);
|
||||
uint32_t pre = duk_is_number(ctx, 1) ? duk_require_uint(ctx, 1) : 0;
|
||||
duk_push_uint(ctx, crc32(pre, (unsigned char*)buffer, (uint32_t)len));
|
||||
return(1);
|
||||
}
|
||||
#endif
|
||||
@@ -2141,6 +2155,9 @@ void ILibDuktape_Polyfills_JS_Init(duk_context *ctx)
|
||||
{
|
||||
// The following can be overriden by calling addModule() or by having a .js file in the module path
|
||||
|
||||
// CRC32-STREAM, refer to /modules/crc32-stream.js for details
|
||||
duk_peval_string_noresult(ctx, "addCompressedModule('crc32-stream', Buffer.from('eJyNVFFv2jAQfo+U/3DihVBlAbE3qmpitNOiVVARuqpPkzGX4C3Yme00RYj/vnMSWtJ10vxi7Pt8933fXRhe+N5MFXstsq2F8Wg8glhazGGmdKE0s0JJ3/O9W8FRGtxAKTeowW4RpgXjtLWREL6jNoSGcTSCwAF6bag3uPS9vSphx/YglYXSIGUQBlKRI+Azx8KCkMDVrsgFkxyhEnZbV2lzRL732GZQa8sIzAhe0Ck9hwGzji3Q2lpbTIbDqqoiVjONlM6GeYMzw9t4djNPbj4QW/fiXuZoDGj8XQpNMtd7YAWR4WxNFHNWgdLAMo0Us8qRrbSwQmYhGJXaimn0vY0wVot1aTs+naiR3nMAOcUk9KYJxEkPPk+TOAl97yFefV3cr+BhulxO56v4JoHFEmaL+XW8ihdzOn2B6fwRvsXz6xCQXKIq+Fxox54oCucgbsiuBLFTPlUNHVMgF6ngJEpmJcsQMvWEWpIWKFDvhHFdNERu43u52AlbD4H5WxEVuRg6856Yhgeyo/bq6mRi0CexyHb9QXQKXjq076Wl5C4ncIpbDGgeZsvZxzEf+N6h6Z5LqdFSNonVS/KgCbp1eP3plusGTuAlc8C3pfwVQpqXZjvoYt88dYuTQJVjlKuseRlZlVCrZBYM3PS+xbvpjX7wUmuUjmRzrkXM4BPp4qTmxKEDHsCkCb8ffadWLSF4GzmG3XMqJMvPDfhP5f/I/no8nmLUjnPJo/PrVvkVvLSSXLC6RFKbstxgC16sfyK30QaJLt5pRQNn9wGlCKH/xPIS+yEcIEN7rmRAVwQptXT/Kx234NjhV0Nod1dHN2k7tSmprfSBKG0N8Tu0MzdpdzgS9A+0jX9v', 'base64'));");
|
||||
|
||||
// http-digest. Refer to /modules/http-digest.js for a human readable version
|
||||
duk_peval_string_noresult(ctx, "addCompressedModule('http-digest', Buffer.from('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', 'base64'));");
|
||||
|
||||
@@ -2934,6 +2951,7 @@ void ILibDuktape_Polyfills_Init(duk_context *ctx)
|
||||
|
||||
#ifndef MICROSTACK_NOTLS
|
||||
ILibDuktape_CreateInstanceMethod(ctx, "crc32c", ILibDuktape_Polyfills_crc32c, DUK_VARARGS);
|
||||
ILibDuktape_CreateInstanceMethod(ctx, "crc32", ILibDuktape_Polyfills_crc32, DUK_VARARGS);
|
||||
#endif
|
||||
ILibDuktape_CreateEventWithGetter(ctx, "global", ILibDuktape_Polyfills_global);
|
||||
duk_pop(ctx); // ...
|
||||
|
||||
@@ -23,6 +23,7 @@ limitations under the License.
|
||||
#include <wchar.h>
|
||||
#include <io.h>
|
||||
#include <fcntl.h>
|
||||
#define WIN_FAKE_O_NONBLOCK 128
|
||||
#endif
|
||||
|
||||
#include "microstack/ILibParsers.h"
|
||||
@@ -71,6 +72,10 @@ limitations under the License.
|
||||
#define FS_EVENT_R_DESCRIPTORS "\xFF_FSEventReadDescriptors"
|
||||
#define FS_EVENT_W_DESCRIPTORS "\xFF_FSEventWriteDescriptors"
|
||||
#define FS_EVENT_DESCRIPTORS_IO "\xFF_FSEventDescriptors_IO"
|
||||
#define FS_WINDOWS_HANDLES "\xFF_FSWindowsHandles"
|
||||
#define FS_WINDOWS_DataPTR "\xFF_FSWindowHandles_DataPTR"
|
||||
#define FS_WINDOWS_ReadCallback "\xFF_FSWindowsHandles_ReadCallback"
|
||||
#define FS_WINDOWS_UserBuffer "\xFF_FSWindowsHandles_UserBuffer"
|
||||
|
||||
#if defined(_POSIX) && !defined(__APPLE__)
|
||||
typedef struct ILibDuktape_fs_linuxWatcher
|
||||
@@ -136,6 +141,17 @@ typedef struct ILibDuktape_fs_readStreamData
|
||||
char buffer[FS_READSTREAM_BUFFERSIZE];
|
||||
}ILibDuktape_fs_readStreamData;
|
||||
|
||||
typedef struct ILibDuktape_WindowsHandle_Data
|
||||
{
|
||||
duk_context *ctx;
|
||||
void *callback;
|
||||
void *userBuffer;
|
||||
HANDLE *H;
|
||||
OVERLAPPED p;
|
||||
char *buffer;
|
||||
size_t bufferSize;
|
||||
}ILibDuktape_WindowsHandle_Data;
|
||||
|
||||
#ifndef _NOFSWATCHER
|
||||
typedef struct ILibDuktape_fs_watcherData
|
||||
{
|
||||
@@ -299,12 +315,40 @@ duk_ret_t ILibDuktape_fs_openSync(duk_context *ctx)
|
||||
}
|
||||
int flags = (int)duk_require_int(ctx, 1);
|
||||
#ifdef WIN32
|
||||
int fd = -1;
|
||||
if (_wsopen_s(&fd, (wchar_t*)ILibDuktape_String_UTF8ToWide(ctx, path), flags, 0, 0) != 0)
|
||||
HANDLE fd = NULL;
|
||||
DWORD dwDesiredAccess = 0;
|
||||
DWORD dwCreationMode = 0;
|
||||
ILibDuktape_WindowsHandle_Data *data;
|
||||
if (((flags & _O_RDONLY) == _O_RDONLY) || ((flags & _O_RDWR) == _O_RDWR)) { dwDesiredAccess |= GENERIC_READ; }
|
||||
if (((flags & _O_WRONLY) == _O_WRONLY) || ((flags & _O_RDWR) == _O_RDWR)) { dwDesiredAccess |= GENERIC_WRITE; }
|
||||
if ((dwDesiredAccess & GENERIC_WRITE) == GENERIC_WRITE)
|
||||
{
|
||||
return(ILibDuktape_Error(ctx, "openSync() Error: %d ", errno));
|
||||
dwCreationMode = OPEN_ALWAYS;
|
||||
}
|
||||
duk_push_int(ctx, fd);
|
||||
else
|
||||
{
|
||||
dwCreationMode = OPEN_EXISTING;
|
||||
}
|
||||
fd = CreateFileW((wchar_t*)ILibDuktape_String_UTF8ToWide(ctx, path), dwDesiredAccess, 0, NULL, dwCreationMode, FILE_FLAG_OVERLAPPED, NULL);
|
||||
if (fd == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
DWORD err = GetLastError();
|
||||
return(ILibDuktape_Error(ctx, "Open Error: %u", err));
|
||||
}
|
||||
|
||||
duk_push_this(ctx); // [fs]
|
||||
duk_get_prop_string(ctx, -1, FS_WINDOWS_HANDLES); // [fs][table]
|
||||
duk_push_pointer(ctx, fd); // [fs][table][HANDLE]
|
||||
duk_push_object(ctx); // [fs][table][HANDLE][container]
|
||||
data = (ILibDuktape_WindowsHandle_Data*)Duktape_PushBuffer(ctx, sizeof(ILibDuktape_WindowsHandle_Data));//..][data]
|
||||
duk_put_prop_string(ctx, -2, FS_WINDOWS_DataPTR); // [fs][table][HANDLE][container]
|
||||
duk_put_prop(ctx, -3); // [fs][table]
|
||||
duk_pop_2(ctx); // ...
|
||||
|
||||
data->ctx = ctx;
|
||||
data->H = fd;
|
||||
data->p.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||
duk_push_uint(ctx, (duk_uint_t)(uintptr_t)fd);
|
||||
#else
|
||||
int fd = open(path, flags);
|
||||
duk_push_int(ctx, fd);
|
||||
@@ -562,6 +606,35 @@ duk_ret_t ILibDuktape_fs_write(duk_context *ctx)
|
||||
duk_call_method(ctx, 4);
|
||||
return(0);
|
||||
}
|
||||
|
||||
#ifdef WIN32
|
||||
BOOL ILibDuktape_fs_read_WindowsSink(void *chain, HANDLE h, ILibWaitHandle_ErrorStatus status, char *buffer, int bytesRead, void* user)
|
||||
{
|
||||
ILibDuktape_WindowsHandle_Data *data = (ILibDuktape_WindowsHandle_Data*)user;
|
||||
if (ILibMemory_CanaryOK(data) && duk_ctx_is_alive(data->ctx))
|
||||
{
|
||||
// Advance the position pointer, because Windows won't do it for us
|
||||
LARGE_INTEGER i64;
|
||||
i64.LowPart = data->p.Offset;
|
||||
i64.HighPart = data->p.OffsetHigh;
|
||||
i64.QuadPart += (int64_t)bytesRead;
|
||||
data->p.Offset = i64.LowPart;
|
||||
data->p.OffsetHigh = i64.HighPart;
|
||||
|
||||
duk_context *ctx = data->ctx;
|
||||
duk_push_heapptr(data->ctx, data->callback); // [callback]
|
||||
duk_eval_string(data->ctx, "require('fs');"); // [callback][this]
|
||||
duk_push_int(data->ctx, status); // [callback][this][err]
|
||||
duk_push_int(data->ctx, bytesRead); // [callback][this][err][bytesRead]
|
||||
duk_push_heapptr(data->ctx, data->userBuffer); // [callback][this][err][bytesRead][buffer]
|
||||
data->callback = NULL;
|
||||
data->userBuffer = NULL;
|
||||
if (duk_pcall_method(data->ctx, 3) != 0) { ILibDuktape_Process_UncaughtExceptionEx(data->ctx, "fs.read.onCallack(): "); }
|
||||
duk_pop(ctx); // ...
|
||||
}
|
||||
return(FALSE);
|
||||
}
|
||||
#endif
|
||||
duk_ret_t ILibDuktape_fs_read(duk_context *ctx)
|
||||
{
|
||||
int top = duk_get_top(ctx);
|
||||
@@ -601,18 +674,54 @@ duk_ret_t ILibDuktape_fs_read(duk_context *ctx)
|
||||
return(1);
|
||||
}
|
||||
if (!(duk_is_number(ctx, 0) && duk_is_object(ctx, 1) && duk_is_function(ctx, 2))) { return(ILibDuktape_Error(ctx, "Invalid Parameters")); }
|
||||
#ifdef WIN32
|
||||
HANDLE H = (HANDLE)(uintptr_t)duk_require_uint(ctx, 0);
|
||||
ILibDuktape_WindowsHandle_Data *data = NULL;
|
||||
#else
|
||||
int fd = (int)duk_require_int(ctx, 0);
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
duk_push_this(ctx); // [fs]
|
||||
duk_get_prop_string(ctx, -1, FS_WINDOWS_HANDLES); // [fs][table]
|
||||
duk_push_pointer(ctx, H); // [fs][table][key]
|
||||
duk_get_prop(ctx, -2); // [fs][table][value]
|
||||
if (duk_is_null_or_undefined(ctx, -1)) { return(ILibDuktape_Error(ctx, "Invalid Descriptor")); }
|
||||
data = (ILibDuktape_WindowsHandle_Data*)Duktape_GetBufferProperty(ctx, -1, FS_WINDOWS_DataPTR);
|
||||
if (data->callback != NULL) { return(ILibDuktape_Error(ctx, "Operation Already in progress")); }
|
||||
duk_dup(ctx, 2); // [fs][table][value][callback]
|
||||
duk_put_prop_string(ctx, -2, FS_WINDOWS_ReadCallback); // [fs][table][value]
|
||||
duk_get_prop_string(ctx, 1, "buffer"); // [fs][table][value][userbuffer]
|
||||
data->userBuffer = duk_get_heapptr(ctx, -1);
|
||||
duk_put_prop_string(ctx, -2, FS_WINDOWS_UserBuffer); // [fs][table][value]
|
||||
data->callback = duk_require_heapptr(ctx, 2);
|
||||
#endif
|
||||
|
||||
// First, we'll attempt to read, and see if it completes or is pending
|
||||
duk_size_t bufferLen;
|
||||
char *buffer = Duktape_GetBufferPropertyEx(ctx, 1, "buffer", &bufferLen);
|
||||
duk_size_t offset = (duk_size_t)Duktape_GetIntPropertyValue(ctx, 1, "offset", 0);
|
||||
duk_size_t length = (duk_size_t)Duktape_GetIntPropertyValue(ctx, 1, "length", (int)bufferLen);
|
||||
int position = Duktape_GetIntPropertyValue(ctx, 1, "position", -1);
|
||||
if (position >= 0)
|
||||
{
|
||||
#ifdef WIN32
|
||||
int bytesRead = _read(fd, buffer + offset, (unsigned int)length);
|
||||
DWORD highorder = 0;
|
||||
DWORD loworder = SetFilePointer(data->H, (LONG)position, (LONG*)&highorder, FILE_BEGIN);
|
||||
if (loworder == INVALID_SET_FILE_POINTER && GetLastError() != NO_ERROR) { return(ILibDuktape_Error(ctx, "Unable to seek to Position")); }
|
||||
data->p.Offset = loworder;
|
||||
data->p.OffsetHigh = highorder;
|
||||
#else
|
||||
if (lseek(fd, (off_t)position, SEEK_SET) < 0) { return(ILibDuktape_Error(ctx, "Unable to seek to Position")); }
|
||||
#endif
|
||||
}
|
||||
#ifdef WIN32
|
||||
data->buffer = buffer + offset;
|
||||
data->bufferSize = length;
|
||||
ILibChain_ReadEx2(duk_ctx_chain(ctx), data->H, &(data->p), data->buffer, (int)data->bufferSize, ILibDuktape_fs_read_WindowsSink, data, "fs.read()");
|
||||
return(0);
|
||||
#else
|
||||
int bytesRead = read(fd, buffer + offset, length);
|
||||
#endif
|
||||
if (bytesRead >= 0 || (errno != EAGAIN && errno != EWOULDBLOCK && errno != EINTR))
|
||||
{
|
||||
// Completed
|
||||
@@ -664,6 +773,7 @@ duk_ret_t ILibDuktape_fs_read(duk_context *ctx)
|
||||
duk_dup(ctx, 2); duk_put_prop_string(ctx, -2, "callback"); // [fs][table][desriptorEvent][pending][options]
|
||||
duk_array_unshift(ctx, -2); // [fs][table][desriptorEvent][pending]
|
||||
return(0);
|
||||
#endif
|
||||
}
|
||||
duk_ret_t ILibDuktape_fs_writeSync(duk_context *ctx)
|
||||
{
|
||||
@@ -2011,6 +2121,9 @@ void ILibDuktape_fs_PUSH(duk_context *ctx, void *chain)
|
||||
duk_push_object(ctx); // [fs][descriptors]
|
||||
duk_put_prop_string(ctx, -2, FS_FDS); // [fs]
|
||||
|
||||
duk_push_object(ctx);
|
||||
duk_put_prop_string(ctx, -2, FS_WINDOWS_HANDLES);
|
||||
|
||||
duk_push_object(ctx);
|
||||
duk_put_prop_string(ctx, -2, FS_EVENT_R_DESCRIPTORS);
|
||||
duk_push_object(ctx);
|
||||
@@ -2051,6 +2164,7 @@ void ILibDuktape_fs_PUSH(duk_context *ctx, void *chain)
|
||||
duk_push_int(ctx, _O_RDONLY); duk_put_prop_string(ctx, -2, "O_RDONLY");
|
||||
duk_push_int(ctx, _O_WRONLY); duk_put_prop_string(ctx, -2, "O_WRONLY");
|
||||
duk_push_int(ctx, _O_RDWR); duk_put_prop_string(ctx, -2, "O_RDWR");
|
||||
duk_push_int(ctx, WIN_FAKE_O_NONBLOCK); duk_put_prop_string(ctx, -2, "O_NONBLOCK");
|
||||
#else
|
||||
duk_push_int(ctx, O_RDONLY); duk_put_prop_string(ctx, -2, "O_RDONLY");
|
||||
duk_push_int(ctx, O_WRONLY); duk_put_prop_string(ctx, -2, "O_WRONLY");
|
||||
|
||||
@@ -148,6 +148,27 @@ int ILibDuktape_EventEmitter_HasListeners2(ILibDuktape_EventEmitter *emitter, ch
|
||||
}
|
||||
return(retVal);
|
||||
}
|
||||
|
||||
duk_ret_t ILibDuktape_EventEmitter_DefaultNewListenerHandler(duk_context *ctx)
|
||||
{
|
||||
char *currentEventName = (char*)duk_require_string(ctx, 0);
|
||||
|
||||
duk_push_current_function(ctx);
|
||||
char *name = Duktape_GetStringPropertyValue(ctx, -1, "event_name", NULL);
|
||||
void *callback = Duktape_GetPointerProperty(ctx, -1, "event_callback");
|
||||
if (strcmp(name, currentEventName) == 0)
|
||||
{
|
||||
duk_push_heapptr(ctx, callback); // [callback]
|
||||
duk_push_this(ctx); // [callback][this]
|
||||
duk_dup(ctx, 0); // [callback][this][name]
|
||||
duk_dup(ctx, 1); // [callback][this][name][handler]
|
||||
if (duk_pcall_method(ctx, 2) != 0) { ILibDuktape_Process_UncaughtExceptionEx(ctx, "EventEmitter.DefaultNewListenerHandler() "); }
|
||||
duk_pop(ctx); // ...
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
duk_ret_t ILibDuktape_EventEmitter_emit(duk_context *ctx)
|
||||
{
|
||||
duk_size_t nameLen;
|
||||
@@ -409,9 +430,9 @@ duk_ret_t ILibDuktape_EventEmitter_on(duk_context *ctx)
|
||||
|
||||
hookHandler = ILibHashtable_Get(data->eventTable, ILibDuktape_EventEmitter_Hook, propName, (int)propNameLen);
|
||||
if (hookHandler != NULL) { hookHandler(data, propName, callback); }
|
||||
if (!(propNameLen == 11 && strncmp(propName, "newListener", 11) == 0))
|
||||
if (!(propNameLen == 11 && strncmp(propName, "newListener", 11) == 0) && !(propNameLen == 12 && strncmp(propName, "newListener2", 12) == 0))
|
||||
{
|
||||
// Only emit 'newListener' when the event itself isn't 'newListener'
|
||||
// Only emit 'newListener' when the event itself isn't 'newListener' or 'newListener2'
|
||||
ILibDuktape_EventEmitter_SetupEmit(ctx, data->object, "newListener"); // [emit][this][newListener]
|
||||
duk_push_lstring(ctx, propName, propNameLen); // [emit][this][newListener][propName]
|
||||
duk_push_heapptr(ctx, callback); // [emit][this][newListener][propName][callback]
|
||||
@@ -422,6 +443,15 @@ duk_ret_t ILibDuktape_EventEmitter_on(duk_context *ctx)
|
||||
((int*)ILibLinkedList_GetExtendedMemory(node))[0] = once;
|
||||
data->totalListeners[0]++;
|
||||
|
||||
if (!(propNameLen == 11 && strncmp(propName, "newListener", 11) == 0) && !(propNameLen == 12 && strncmp(propName, "newListener2", 12) == 0))
|
||||
{
|
||||
// Only emit 'newListener2' when the event itself isn't 'newListener' or 'newListener2'
|
||||
ILibDuktape_EventEmitter_SetupEmit(ctx, data->object, "newListener2"); // [emit][this][newListener2]
|
||||
duk_push_lstring(ctx, propName, propNameLen); // [emit][this][newListener2][propName]
|
||||
duk_push_heapptr(ctx, callback); // [emit][this][newListener2][propName][callback]
|
||||
duk_call_method(ctx, 3); duk_pop(ctx); // ...
|
||||
}
|
||||
|
||||
duk_push_this(ctx);
|
||||
return 1;
|
||||
}
|
||||
@@ -692,6 +722,7 @@ ILibDuktape_EventEmitter* ILibDuktape_EventEmitter_Create(duk_context *ctx)
|
||||
duk_set_finalizer(ctx, -2);
|
||||
|
||||
ILibDuktape_EventEmitter_CreateEventEx(retVal, "newListener");
|
||||
ILibDuktape_EventEmitter_CreateEventEx(retVal, "newListener2");
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user