Make Directory.list() create and return a list from C.
This commit is contained in:
+5
-20
@@ -107,33 +107,18 @@ static void directoryListCallback(uv_fs_t* request)
|
||||
|
||||
uv_dirent_t entry;
|
||||
|
||||
// TODO: Right now, there's no way to create a list using the C API, so
|
||||
// create a buffer containing all of the result paths terminated by '\0'.
|
||||
// We'll split that back into a list in Wren.
|
||||
size_t bufferLength = 0;
|
||||
size_t bufferCapacity = 1024;
|
||||
char* buffer = (char*)malloc(bufferCapacity);
|
||||
WrenVM* vm = getVM();
|
||||
wrenEnsureSlots(vm, 3);
|
||||
wrenSetSlotNewList(vm, 2);
|
||||
|
||||
while (uv_fs_scandir_next(request, &entry) != UV_EOF)
|
||||
{
|
||||
size_t length = strlen(entry.name);
|
||||
|
||||
// Grow the buffer if needed.
|
||||
while (bufferLength + length + 1 > bufferCapacity)
|
||||
{
|
||||
bufferCapacity *= 2;
|
||||
buffer = (char*)realloc(buffer, bufferCapacity);
|
||||
}
|
||||
|
||||
// Copy the path, including the null terminator.
|
||||
memcpy(buffer + bufferLength, entry.name, length + 1);
|
||||
bufferLength += length + 1;
|
||||
wrenSetSlotString(vm, 1, entry.name);
|
||||
wrenInsertInList(vm, 2, -1, 1);
|
||||
}
|
||||
|
||||
schedulerResume(freeRequest(request), true);
|
||||
wrenSetSlotBytes(getVM(), 2, buffer, bufferLength);
|
||||
schedulerFinishResume();
|
||||
free(buffer);
|
||||
}
|
||||
|
||||
void directoryList(WrenVM* vm)
|
||||
|
||||
+1
-22
@@ -5,28 +5,7 @@ class Directory {
|
||||
if (!(path is String)) Fiber.abort("Path must be a string.")
|
||||
|
||||
list_(path, Fiber.current)
|
||||
|
||||
// We get back a byte array containing all of the paths, each terminated by
|
||||
// a zero byte.
|
||||
var entryBuffer = Scheduler.runNextScheduled_()
|
||||
|
||||
// TODO: Add split() to String.
|
||||
// Split it into an array of strings.
|
||||
var entries = []
|
||||
var start = 0
|
||||
var i = 0
|
||||
var bytes = entryBuffer.bytes
|
||||
while (i < bytes.count) {
|
||||
if (bytes[i] == 0) {
|
||||
var entry = entryBuffer[start...i]
|
||||
start = i + 1
|
||||
entries.add(entry)
|
||||
}
|
||||
|
||||
i = i + 1
|
||||
}
|
||||
|
||||
return entries
|
||||
return Scheduler.runNextScheduled_()
|
||||
}
|
||||
|
||||
foreign static list_(path, fiber)
|
||||
|
||||
+1
-22
@@ -7,28 +7,7 @@ static const char* ioModuleSource =
|
||||
" if (!(path is String)) Fiber.abort(\"Path must be a string.\")\n"
|
||||
"\n"
|
||||
" list_(path, Fiber.current)\n"
|
||||
"\n"
|
||||
" // We get back a byte array containing all of the paths, each terminated by\n"
|
||||
" // a zero byte.\n"
|
||||
" var entryBuffer = Scheduler.runNextScheduled_()\n"
|
||||
"\n"
|
||||
" // TODO: Add split() to String.\n"
|
||||
" // Split it into an array of strings.\n"
|
||||
" var entries = []\n"
|
||||
" var start = 0\n"
|
||||
" var i = 0\n"
|
||||
" var bytes = entryBuffer.bytes\n"
|
||||
" while (i < bytes.count) {\n"
|
||||
" if (bytes[i] == 0) {\n"
|
||||
" var entry = entryBuffer[start...i]\n"
|
||||
" start = i + 1\n"
|
||||
" entries.add(entry)\n"
|
||||
" }\n"
|
||||
"\n"
|
||||
" i = i + 1\n"
|
||||
" }\n"
|
||||
"\n"
|
||||
" return entries\n"
|
||||
" return Scheduler.runNextScheduled_()\n"
|
||||
" }\n"
|
||||
"\n"
|
||||
" foreign static list_(path, fiber)\n"
|
||||
|
||||
Reference in New Issue
Block a user