Make Directory.list() create and return a list from C.

This commit is contained in:
Bob Nystrom
2015-12-29 08:37:47 -08:00
parent e0ac88c22a
commit 2c31985e54
7 changed files with 29 additions and 66 deletions
+5 -20
View File
@@ -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
View File
@@ -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
View File
@@ -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"