mirror of
https://github.com/Ylianst/MeshAgent
synced 2025-12-16 16:23:25 +00:00
Updated documentation
This commit is contained in:
36
docs/Files.md
Normal file
36
docs/Files.md
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
## Project Files
|
||||||
|
|
||||||
|
### Abstract
|
||||||
|
This document highlights what each of the files in the project are, and what they do at a higher level.
|
||||||
|
|
||||||
|
### Microstack
|
||||||
|
The files in this folder makeup the native core of the Mesh Agent. It is what provides the underlying plumbing as well
|
||||||
|
as the main event loop. It is inherently single threaded using Asynchronous I/O throughout.
|
||||||
|
|
||||||
|
- **[ILibAsyncSocket](files/ILibAsyncSocket.md)**
|
||||||
|
Provides the underyling TCP socket functionality
|
||||||
|
- **ILibAsyncUDPSocket**
|
||||||
|
Provides the underlying UDP socket functionality
|
||||||
|
- **ILibAsyncServerSocket**
|
||||||
|
Provides the underlying TCP Server functionality
|
||||||
|
- ILibCrypto
|
||||||
|
- **ILibIPAddressMonitor**
|
||||||
|
Provides events for Network state changes
|
||||||
|
- **ILibMulticastSocket**
|
||||||
|
Provides UDP Multicast/Broadcast functionality
|
||||||
|
- **[ILibParsers](files/ILibParsers.md)**
|
||||||
|
Provides the core event loop implementation, as well as some helper methods
|
||||||
|
- **ILibProcessPipe**
|
||||||
|
Provides child process dispatching functionality
|
||||||
|
- **ILibRemoteLogging**
|
||||||
|
Provides a web based logging mechanism, for native components
|
||||||
|
- **ILibSimpleDataStore**
|
||||||
|
Provides a lightweight data store for use by the agent
|
||||||
|
- **ILibWebClient**
|
||||||
|
Provides a lightweight HTTP/1.1 client implementation
|
||||||
|
- **ILibWebRTC**
|
||||||
|
Provides lightweight WebRTC Data Channel implementation
|
||||||
|
- **ILibWebServer**
|
||||||
|
Provides a lightweight HTTP/1.1 server implementation
|
||||||
|
- **ILibWrapperWebRTC**
|
||||||
|
Provides a pseudo object oriented abstraction for WebRTC Data Channel Setup/Creation
|
||||||
7
docs/files/ILibAsyncSocket.md
Normal file
7
docs/files/ILibAsyncSocket.md
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
## ILibAsyncSocket.c
|
||||||
|
|
||||||
|
### Abstract
|
||||||
|
ILibAsyncSocket provides the underyling TCP socket implementation for the Mesh Agent.
|
||||||
|
|
||||||
|
### Functions
|
||||||
|
|
||||||
1
docs/files/ILibParsers.md
Normal file
1
docs/files/ILibParsers.md
Normal file
@@ -0,0 +1 @@
|
|||||||
|
## ILibParsers.c
|
||||||
@@ -1711,6 +1711,7 @@ duk_ret_t ILibDuktape_fs_watcher_close(duk_context *ctx)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
|
// Windows Callback for file watcher
|
||||||
BOOL ILibDuktape_fs_watch_iocompletion(void *chain, HANDLE h, ILibWaitHandle_ErrorStatus errors, void *user)
|
BOOL ILibDuktape_fs_watch_iocompletion(void *chain, HANDLE h, ILibWaitHandle_ErrorStatus errors, void *user)
|
||||||
{
|
{
|
||||||
if (errors != ILibWaitHandle_ErrorStatus_NONE || !ILibMemory_CanaryOK(user)) { return(FALSE); }
|
if (errors != ILibWaitHandle_ErrorStatus_NONE || !ILibMemory_CanaryOK(user)) { return(FALSE); }
|
||||||
@@ -1762,7 +1763,7 @@ BOOL ILibDuktape_fs_watch_iocompletion(void *chain, HANDLE h, ILibWaitHandle_Err
|
|||||||
n = (n->NextEntryOffset != 0) ? ((FILE_NOTIFY_INFORMATION*)((char*)n + n->NextEntryOffset)) : NULL;
|
n = (n->NextEntryOffset != 0) ? ((FILE_NOTIFY_INFORMATION*)((char*)n + n->NextEntryOffset)) : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Emit change event
|
||||||
duk_push_heapptr(data->ctx, data->object); // [detail][fsWatcher]
|
duk_push_heapptr(data->ctx, data->object); // [detail][fsWatcher]
|
||||||
duk_get_prop_string(data->ctx, -1, "emit"); // [detail][fsWatcher][emit]
|
duk_get_prop_string(data->ctx, -1, "emit"); // [detail][fsWatcher][emit]
|
||||||
duk_swap_top(data->ctx, -2); // [detail][emit][this]
|
duk_swap_top(data->ctx, -2); // [detail][emit][this]
|
||||||
@@ -1799,6 +1800,7 @@ BOOL ILibDuktape_fs_watch_iocompletion(void *chain, HANDLE h, ILibWaitHandle_Err
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef _NOFSWATCHER
|
#ifndef _NOFSWATCHER
|
||||||
|
// Called by Garbage Collector
|
||||||
duk_ret_t ILibDuktape_fs_watcher_finalizer(duk_context *ctx)
|
duk_ret_t ILibDuktape_fs_watcher_finalizer(duk_context *ctx)
|
||||||
{
|
{
|
||||||
duk_get_prop_string(ctx, 0, "close"); // [close]
|
duk_get_prop_string(ctx, 0, "close"); // [close]
|
||||||
@@ -1808,8 +1810,10 @@ duk_ret_t ILibDuktape_fs_watcher_finalizer(duk_context *ctx)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This a helper function that is indirectly called by the Microstack Event loop, to query metadata
|
||||||
void ILibDuktape_fs_notifyDispatcher_QueryEx(ILibHashtable sender, void *Key1, char* Key2, int Key2Len, void *Data, void *user)
|
void ILibDuktape_fs_notifyDispatcher_QueryEx(ILibHashtable sender, void *Key1, char* Key2, int Key2Len, void *Data, void *user)
|
||||||
{
|
{
|
||||||
|
// We're going to push the metadata into the supplied array
|
||||||
ILibDuktape_fs_watcherData *data = (ILibDuktape_fs_watcherData*)Data;
|
ILibDuktape_fs_watcherData *data = (ILibDuktape_fs_watcherData*)Data;
|
||||||
duk_push_heapptr(data->ctx, user); // [array]
|
duk_push_heapptr(data->ctx, user); // [array]
|
||||||
duk_push_heapptr(data->ctx, data->object); // [array][watcher]
|
duk_push_heapptr(data->ctx, data->object); // [array][watcher]
|
||||||
@@ -1820,12 +1824,14 @@ void ILibDuktape_fs_notifyDispatcher_QueryEx(ILibHashtable sender, void *Key1, c
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if defined(_POSIX) && !defined(__APPLE__) && !defined(_FREEBSD)
|
#if defined(_POSIX) && !defined(__APPLE__) && !defined(_FREEBSD)
|
||||||
|
// This function is called by the Microstack Event loop, to query metadata about a descriptor
|
||||||
char* ILibDuktape_fs_notifyDispatcher_Query(void* chain, void *object, int fd, size_t *dataLen)
|
char* ILibDuktape_fs_notifyDispatcher_Query(void* chain, void *object, int fd, size_t *dataLen)
|
||||||
{
|
{
|
||||||
ILibDuktape_fs_linuxWatcher *data = (ILibDuktape_fs_linuxWatcher*)object;
|
ILibDuktape_fs_linuxWatcher *data = (ILibDuktape_fs_linuxWatcher*)object;
|
||||||
|
|
||||||
if (duk_ctx_is_alive(data->ctx) == 0)
|
if (duk_ctx_is_alive(data->ctx) == 0)
|
||||||
{
|
{
|
||||||
|
// Context isn't valid, so just return generic metadata
|
||||||
return(" (ILibDuktape_fs_linuxWatcher)");
|
return(" (ILibDuktape_fs_linuxWatcher)");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1838,15 +1844,19 @@ char* ILibDuktape_fs_notifyDispatcher_Query(void* chain, void *object, int fd, s
|
|||||||
duk_size_t tmpLen;
|
duk_size_t tmpLen;
|
||||||
char *tmp = (char*)duk_get_lstring(data->ctx, -1, &tmpLen);
|
char *tmp = (char*)duk_get_lstring(data->ctx, -1, &tmpLen);
|
||||||
char *tmp2 = ILibMemory_AllocateTemp(chain, tmpLen + 12);
|
char *tmp2 = ILibMemory_AllocateTemp(chain, tmpLen + 12);
|
||||||
*dataLen = sprintf_s(tmp2, tmpLen + 12, "fs.watch(%s)", tmp);
|
*dataLen = sprintf_s(tmp2, tmpLen + 12, "fs.watch(%s)", tmp); // Populate metadata with what we are watching
|
||||||
duk_set_top(data->ctx, top);
|
duk_set_top(data->ctx, top);
|
||||||
return tmp2;
|
return tmp2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Called by Microstack event loop, to add our descriptors
|
||||||
void ILibDuktape_fs_notifyDispatcher_PreSelect(void* object, fd_set *readset, fd_set *writeset, fd_set *errorset, int* blocktime)
|
void ILibDuktape_fs_notifyDispatcher_PreSelect(void* object, fd_set *readset, fd_set *writeset, fd_set *errorset, int* blocktime)
|
||||||
{
|
{
|
||||||
ILibDuktape_fs_linuxWatcher *data = (ILibDuktape_fs_linuxWatcher*)object;
|
ILibDuktape_fs_linuxWatcher *data = (ILibDuktape_fs_linuxWatcher*)object;
|
||||||
FD_SET(data->fd, readset);
|
FD_SET(data->fd, readset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Called by Microstack event loop, to check our descriptors
|
||||||
void ILibDuktape_fs_notifyDispatcher_PostSelect(void* object, int slct, fd_set *readset, fd_set *writeset, fd_set *errorset)
|
void ILibDuktape_fs_notifyDispatcher_PostSelect(void* object, int slct, fd_set *readset, fd_set *writeset, fd_set *errorset)
|
||||||
{
|
{
|
||||||
struct inotify_event *evt;
|
struct inotify_event *evt;
|
||||||
@@ -1859,6 +1869,7 @@ void ILibDuktape_fs_notifyDispatcher_PostSelect(void* object, int slct, fd_set *
|
|||||||
|
|
||||||
if (!FD_ISSET(data->fd, readset)) { return; }
|
if (!FD_ISSET(data->fd, readset)) { return; }
|
||||||
|
|
||||||
|
// We were signaled that data is available, so let's get it
|
||||||
while ((len = read(data->fd, buffer, sizeof(buffer))) > 0)
|
while ((len = read(data->fd, buffer, sizeof(buffer))) > 0)
|
||||||
{
|
{
|
||||||
while (i < len)
|
while (i < len)
|
||||||
@@ -1870,7 +1881,7 @@ void ILibDuktape_fs_notifyDispatcher_PostSelect(void* object, int slct, fd_set *
|
|||||||
wd.p = NULL;
|
wd.p = NULL;
|
||||||
wd.i = evt->wd;
|
wd.i = evt->wd;
|
||||||
watcher = (ILibDuktape_fs_watcherData*)ILibHashtable_Get(data->watchTable, wd.p, NULL, 0);
|
watcher = (ILibDuktape_fs_watcherData*)ILibHashtable_Get(data->watchTable, wd.p, NULL, 0);
|
||||||
if (watcher == NULL || ILibDuktape_EventEmitter_HasListeners(watcher->emitter, "change") == 0) { continue; }
|
if (watcher == NULL || ILibDuktape_EventEmitter_HasListeners(watcher->emitter, "change") == 0) { continue; } // If nobody is listening for this event, no need to waste cycles processing it
|
||||||
|
|
||||||
duk_push_object(watcher->ctx); // [detail]
|
duk_push_object(watcher->ctx); // [detail]
|
||||||
|
|
||||||
@@ -1890,6 +1901,8 @@ void ILibDuktape_fs_notifyDispatcher_PostSelect(void* object, int slct, fd_set *
|
|||||||
duk_push_string(watcher->ctx, evt->name);
|
duk_push_string(watcher->ctx, evt->name);
|
||||||
duk_put_prop_string(watcher->ctx, -2, "\xFF_FileName");
|
duk_put_prop_string(watcher->ctx, -2, "\xFF_FileName");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// emit the event
|
||||||
ILibDuktape_EventEmitter_SetupEmit(watcher->ctx, watcher->object, "change");// [detail][emit][this][change]
|
ILibDuktape_EventEmitter_SetupEmit(watcher->ctx, watcher->object, "change");// [detail][emit][this][change]
|
||||||
duk_push_string(watcher->ctx, changed == 0 ? "rename" : "change"); // [detail][emit][this][change][type]
|
duk_push_string(watcher->ctx, changed == 0 ? "rename" : "change"); // [detail][emit][this][change][type]
|
||||||
if (changed == 0)
|
if (changed == 0)
|
||||||
@@ -1906,6 +1919,8 @@ void ILibDuktape_fs_notifyDispatcher_PostSelect(void* object, int slct, fd_set *
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Called by the microstack event loop to cleanup
|
||||||
void ILibDuktape_fs_notifyDispatcher_Destroy(void *object)
|
void ILibDuktape_fs_notifyDispatcher_Destroy(void *object)
|
||||||
{
|
{
|
||||||
ILibHashtable_Destroy(((ILibDuktape_fs_linuxWatcher*)object)->watchTable);
|
ILibHashtable_Destroy(((ILibDuktape_fs_linuxWatcher*)object)->watchTable);
|
||||||
@@ -1913,6 +1928,7 @@ void ILibDuktape_fs_notifyDispatcher_Destroy(void *object)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
|
// Dispatched callback from kevent(), to be emitted on JS event loop
|
||||||
void ILibduktape_fs_watch_appleWorker_MODIFIED(void *chain, void *user, char *changeType)
|
void ILibduktape_fs_watch_appleWorker_MODIFIED(void *chain, void *user, char *changeType)
|
||||||
{
|
{
|
||||||
ILibDuktape_fs_watcherData *data = (ILibDuktape_fs_watcherData*)user;
|
ILibDuktape_fs_watcherData *data = (ILibDuktape_fs_watcherData*)user;
|
||||||
@@ -1978,6 +1994,8 @@ void ILibduktape_fs_watch_appleWorker_LINK(void *chain, void *user)
|
|||||||
{
|
{
|
||||||
ILibduktape_fs_watch_appleWorker_MODIFIED(chain, user, "MODIFIED_LINK");
|
ILibduktape_fs_watch_appleWorker_MODIFIED(chain, user, "MODIFIED_LINK");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// macOS kevent loop
|
||||||
void ILibduktape_fs_watch_appleWorker(void *obj)
|
void ILibduktape_fs_watch_appleWorker(void *obj)
|
||||||
{
|
{
|
||||||
ILibDuktape_fs_appleWatcher *watcher = (ILibDuktape_fs_appleWatcher*)obj;
|
ILibDuktape_fs_appleWatcher *watcher = (ILibDuktape_fs_appleWatcher*)obj;
|
||||||
@@ -1993,7 +2011,7 @@ void ILibduktape_fs_watch_appleWorker(void *obj)
|
|||||||
n = kevent(watcher->kq, change, inCount, &event, 1, NULL); inCount = 0;
|
n = kevent(watcher->kq, change, inCount, &event, 1, NULL); inCount = 0;
|
||||||
if (n > 0)
|
if (n > 0)
|
||||||
{
|
{
|
||||||
if (event.ident == watcher->unblocker[0])
|
if (event.ident == watcher->unblocker[0]) // Check our 'wakeup' descriptor, which we use to force unblock, so we can add other descriptors
|
||||||
{
|
{
|
||||||
// Force Unblock
|
// Force Unblock
|
||||||
read(watcher->unblocker[0], tmp, event.data < sizeof(tmp) ? event.data : sizeof(tmp));
|
read(watcher->unblocker[0], tmp, event.data < sizeof(tmp) ? event.data : sizeof(tmp));
|
||||||
@@ -2077,6 +2095,8 @@ duk_ret_t ILibDuktape_fs_watch(duk_context *ctx)
|
|||||||
#if defined(WIN32)
|
#if defined(WIN32)
|
||||||
int recursive = 0;
|
int recursive = 0;
|
||||||
ILibProcessPipe_Manager pipeMgr;
|
ILibProcessPipe_Manager pipeMgr;
|
||||||
|
|
||||||
|
// Setup an ILibProcessPipe_Manager object, that we can use for dispatching if necessary
|
||||||
duk_push_this(ctx); // [fs]
|
duk_push_this(ctx); // [fs]
|
||||||
if (duk_has_prop_string(ctx, -1, FS_PIPEMANAGER_PTR))
|
if (duk_has_prop_string(ctx, -1, FS_PIPEMANAGER_PTR))
|
||||||
{
|
{
|
||||||
@@ -2104,6 +2124,7 @@ duk_ret_t ILibDuktape_fs_watch(duk_context *ctx)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
// if a notifyDispatcher wasn't setup, let's setup a new one and hook it up to the event loop, so we can add descriptors
|
||||||
notifyDispatcher = ILibMemory_Allocate(sizeof(ILibDuktape_fs_linuxWatcher), 0, NULL, NULL);
|
notifyDispatcher = ILibMemory_Allocate(sizeof(ILibDuktape_fs_linuxWatcher), 0, NULL, NULL);
|
||||||
notifyDispatcher->chainLink.MetaData = ILibMemory_SmartAllocate_FromString("ILibDuktape_fs_linuxWatcher");
|
notifyDispatcher->chainLink.MetaData = ILibMemory_SmartAllocate_FromString("ILibDuktape_fs_linuxWatcher");
|
||||||
notifyDispatcher->chainLink.PreSelectHandler = ILibDuktape_fs_notifyDispatcher_PreSelect;
|
notifyDispatcher->chainLink.PreSelectHandler = ILibDuktape_fs_notifyDispatcher_PreSelect;
|
||||||
@@ -2146,9 +2167,9 @@ duk_ret_t ILibDuktape_fs_watch(duk_context *ctx)
|
|||||||
}
|
}
|
||||||
sem_init(&(watcher->exitWaiter), 0, 0);
|
sem_init(&(watcher->exitWaiter), 0, 0);
|
||||||
sem_init(&(watcher->inputWaiter), 0, 0);
|
sem_init(&(watcher->inputWaiter), 0, 0);
|
||||||
pipe(watcher->unblocker);
|
pipe(watcher->unblocker); // Setup a pipe, so we can use it to force unblock the child, so it can add descriptors
|
||||||
watcher->chain = Duktape_GetChain(ctx);
|
watcher->chain = Duktape_GetChain(ctx);
|
||||||
watcher->kthread = ILibSpawnNormalThread(ILibduktape_fs_watch_appleWorker, watcher);
|
watcher->kthread = ILibSpawnNormalThread(ILibduktape_fs_watch_appleWorker, watcher); // Spawn a thread to act as the kevent loop
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
@@ -2188,7 +2209,7 @@ duk_ret_t ILibDuktape_fs_watch(duk_context *ctx)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Setup the file system watcher
|
||||||
#if defined(WIN32)
|
#if defined(WIN32)
|
||||||
if ((data->overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL)) == NULL) { return(ILibDuktape_Error(ctx, "Could not create handle")); }
|
if ((data->overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL)) == NULL) { return(ILibDuktape_Error(ctx, "Could not create handle")); }
|
||||||
data->h = CreateFileW(path, FILE_LIST_DIRECTORY, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED, NULL);
|
data->h = CreateFileW(path, FILE_LIST_DIRECTORY, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED, NULL);
|
||||||
@@ -2232,6 +2253,7 @@ duk_ret_t ILibDuktape_fs_watch(duk_context *ctx)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// fs.renameSync() to rename a file
|
||||||
duk_ret_t ILibDuktape_fs_rename(duk_context *ctx)
|
duk_ret_t ILibDuktape_fs_rename(duk_context *ctx)
|
||||||
{
|
{
|
||||||
char *oldPath = (char*)duk_require_string(ctx, 0);
|
char *oldPath = (char*)duk_require_string(ctx, 0);
|
||||||
@@ -2248,6 +2270,8 @@ duk_ret_t ILibDuktape_fs_rename(duk_context *ctx)
|
|||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// fs.unlinkSync() to delete a file
|
||||||
duk_ret_t ILibDuktape_fs_unlink(duk_context *ctx)
|
duk_ret_t ILibDuktape_fs_unlink(duk_context *ctx)
|
||||||
{
|
{
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
@@ -2270,6 +2294,8 @@ duk_ret_t ILibDuktape_fs_unlink(duk_context *ctx)
|
|||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// fs.rmdirSync() to delete a folder
|
||||||
duk_ret_t ILibDuktape_fs_rmdirSync(duk_context *ctx)
|
duk_ret_t ILibDuktape_fs_rmdirSync(duk_context *ctx)
|
||||||
{
|
{
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
@@ -2285,6 +2311,8 @@ duk_ret_t ILibDuktape_fs_rmdirSync(duk_context *ctx)
|
|||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// fs.mkdirSync() to create a folder
|
||||||
duk_ret_t ILibDuktape_fs_mkdirSync(duk_context *ctx)
|
duk_ret_t ILibDuktape_fs_mkdirSync(duk_context *ctx)
|
||||||
{
|
{
|
||||||
//int nargs = duk_get_top(ctx);
|
//int nargs = duk_get_top(ctx);
|
||||||
@@ -2302,6 +2330,8 @@ duk_ret_t ILibDuktape_fs_mkdirSync(duk_context *ctx)
|
|||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// fs.readFileSync() to read an entire file into a buffer
|
||||||
duk_ret_t ILibDuktape_fs_readFileSync(duk_context *ctx)
|
duk_ret_t ILibDuktape_fs_readFileSync(duk_context *ctx)
|
||||||
{
|
{
|
||||||
char *filePath = (char*)duk_require_string(ctx, 0);
|
char *filePath = (char*)duk_require_string(ctx, 0);
|
||||||
@@ -2332,6 +2362,7 @@ duk_ret_t ILibDuktape_fs_readFileSync(duk_context *ctx)
|
|||||||
fseek(f, 0, SEEK_SET);
|
fseek(f, 0, SEEK_SET);
|
||||||
if(fileLen > 0)
|
if(fileLen > 0)
|
||||||
{
|
{
|
||||||
|
// If the filesystem gives us the file length, we'll allocate the buffer first, and then fill it up
|
||||||
duk_push_fixed_buffer(ctx, (duk_size_t)fileLen);
|
duk_push_fixed_buffer(ctx, (duk_size_t)fileLen);
|
||||||
ignore_result(fread(Duktape_GetBuffer(ctx, -1, NULL), 1, (size_t)fileLen, f));
|
ignore_result(fread(Duktape_GetBuffer(ctx, -1, NULL), 1, (size_t)fileLen, f));
|
||||||
fclose(f);
|
fclose(f);
|
||||||
@@ -2339,6 +2370,7 @@ duk_ret_t ILibDuktape_fs_readFileSync(duk_context *ctx)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
// If the filesystem can't tell us the file length, we'll need to use a dynamic buffer, so it will just realloc as we go along
|
||||||
duk_size_t bufferSize = 1024;
|
duk_size_t bufferSize = 1024;
|
||||||
char *buffer = (char*)duk_push_dynamic_buffer(ctx, bufferSize); // [dynamicBuffer]
|
char *buffer = (char*)duk_push_dynamic_buffer(ctx, bufferSize); // [dynamicBuffer]
|
||||||
size_t bytesRead = 0;
|
size_t bytesRead = 0;
|
||||||
@@ -2358,6 +2390,8 @@ duk_ret_t ILibDuktape_fs_readFileSync(duk_context *ctx)
|
|||||||
|
|
||||||
return(1);
|
return(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// fs.existsSync() to determine if a path exists
|
||||||
duk_ret_t ILibDuktape_fs_existsSync(duk_context *ctx)
|
duk_ret_t ILibDuktape_fs_existsSync(duk_context *ctx)
|
||||||
{
|
{
|
||||||
duk_push_this(ctx); // [fs]
|
duk_push_this(ctx); // [fs]
|
||||||
@@ -2375,6 +2409,7 @@ duk_ret_t ILibDuktape_fs_existsSync(duk_context *ctx)
|
|||||||
return(1);
|
return(1);
|
||||||
}
|
}
|
||||||
#ifdef _POSIX
|
#ifdef _POSIX
|
||||||
|
// fs.chmodSync()
|
||||||
duk_ret_t ILibduktape_fs_chmodSync(duk_context *ctx)
|
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)
|
if(chmod((char*)duk_require_string(ctx, 0), (mode_t)duk_require_int(ctx, 1)) != 0)
|
||||||
@@ -2386,6 +2421,7 @@ duk_ret_t ILibduktape_fs_chmodSync(duk_context *ctx)
|
|||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// fs.chownSync()
|
||||||
duk_ret_t ILibDuktape_fs_chownSync(duk_context *ctx)
|
duk_ret_t ILibDuktape_fs_chownSync(duk_context *ctx)
|
||||||
{
|
{
|
||||||
if (chown((char*)duk_require_string(ctx, 0), (uid_t)duk_require_int(ctx, 1), (gid_t)duk_require_int(ctx, 2)) != 0)
|
if (chown((char*)duk_require_string(ctx, 0), (uid_t)duk_require_int(ctx, 1), (gid_t)duk_require_int(ctx, 2)) != 0)
|
||||||
@@ -2399,6 +2435,7 @@ duk_ret_t ILibDuktape_fs_chownSync(duk_context *ctx)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
|
// Windows helper to convert file time to system time
|
||||||
duk_ret_t ILibDuktape_fs_convertFileTime(duk_context *ctx)
|
duk_ret_t ILibDuktape_fs_convertFileTime(duk_context *ctx)
|
||||||
{
|
{
|
||||||
if (!(duk_is_object(ctx, 0) && duk_has_prop_string(ctx, -1, "_ptr"))) { return(ILibDuktape_Error(ctx, "Invalid Input Parameters")); }
|
if (!(duk_is_object(ctx, 0) && duk_has_prop_string(ctx, -1, "_ptr"))) { return(ILibDuktape_Error(ctx, "Invalid Input Parameters")); }
|
||||||
@@ -2488,6 +2525,7 @@ void ILibDuktape_fs_PUSH(duk_context *ctx, void *chain)
|
|||||||
|
|
||||||
ILibDuktape_CreateFinalizer(ctx, ILibDuktape_fs_Finalizer);
|
ILibDuktape_CreateFinalizer(ctx, ILibDuktape_fs_Finalizer);
|
||||||
|
|
||||||
|
// JavaScript Polyfills
|
||||||
char copyFile[] = "exports.copyFile = function copyFile(src, dest)\
|
char copyFile[] = "exports.copyFile = function copyFile(src, dest)\
|
||||||
{\
|
{\
|
||||||
var ss = this.createReadStream(src, {flags: 'rb'});\
|
var ss = this.createReadStream(src, {flags: 'rb'});\
|
||||||
|
|||||||
Reference in New Issue
Block a user