// Generated automatically from src/module/io.wren. Do not edit.
static const char* ioModuleSource =
"import \"scheduler\" for Scheduler\n"
"\n"
"class Directory {\n"
"  // TODO: Copied from File. Figure out good way to share this.\n"
"  static ensurePath_(path) {\n"
"    if (!(path is String)) Fiber.abort(\"Path must be a string.\")\n"
"  }\n"
"\n"
"  static exists(path) {\n"
"    ensurePath_(path)\n"
"    var stat\n"
"    Fiber.new {\n"
"      stat = Stat.path(path)\n"
"    }.try()\n"
"\n"
"    // If we can't stat it, there's nothing there.\n"
"    if (stat == null) return false\n"
"    return stat.isDirectory\n"
"  }\n"
"\n"
"  static list(path) {\n"
"    ensurePath_(path)\n"
"    list_(path, Fiber.current)\n"
"    return Scheduler.runNextScheduled_()\n"
"  }\n"
"\n"
"  foreign static list_(path, fiber)\n"
"}\n"
"\n"
"foreign class File {\n"
"  static create(path) {\n"
"    return openWithFlags(path,\n"
"        FileFlags.writeOnly |\n"
"        FileFlags.create |\n"
"        FileFlags.truncate)\n"
"  }\n"
"\n"
"  static create(path, fn) {\n"
"    return openWithFlags(path,\n"
"        FileFlags.writeOnly |\n"
"        FileFlags.create |\n"
"        FileFlags.truncate, fn)\n"
"  }\n"
"\n"
"  static delete(path) {\n"
"    ensurePath_(path)\n"
"    delete_(path, Fiber.current)\n"
"    return Scheduler.runNextScheduled_()\n"
"  }\n"
"\n"
"  static exists(path) {\n"
"    ensurePath_(path)\n"
"    var stat\n"
"    Fiber.new {\n"
"      stat = Stat.path(path)\n"
"    }.try()\n"
"\n"
"    // If we can't stat it, there's nothing there.\n"
"    if (stat == null) return false\n"
"    return stat.isFile\n"
"  }\n"
"\n"
"  static open(path) { openWithFlags(path, FileFlags.readOnly) }\n"
"\n"
"  static open(path, fn) { openWithFlags(path, FileFlags.readOnly, fn) }\n"
"\n"
"  // TODO: Add named parameters and then call this \"open(_,flags:_)\"?\n"
"  // TODO: Test.\n"
"  static openWithFlags(path, flags) {\n"
"    ensurePath_(path)\n"
"    ensureInt_(flags, \"Flags\")\n"
"    open_(path, flags, Fiber.current)\n"
"    var fd = Scheduler.runNextScheduled_()\n"
"    return new_(fd)\n"
"  }\n"
"\n"
"  static openWithFlags(path, flags, fn) {\n"
"    var file = openWithFlags(path, flags)\n"
"    var fiber = Fiber.new { fn.call(file) }\n"
"\n"
"    // Poor man's finally. Can we make this more elegant?\n"
"    var result = fiber.try()\n"
"    file.close()\n"
"\n"
"    // TODO: Want something like rethrow since now the callstack ends here. :(\n"
"    if (fiber.error != null) Fiber.abort(fiber.error)\n"
"    return result\n"
"  }\n"
"\n"
"  static read(path) {\n"
"    return File.open(path) {|file| file.readBytes(file.size) }\n"
"  }\n"
"\n"
"  // TODO: This works for directories too, so putting it on File is kind of\n"
"  // lame. Consider reorganizing these classes some.\n"
"  static realPath(path) {\n"
"    ensurePath_(path)\n"
"    realPath_(path, Fiber.current)\n"
"    return Scheduler.runNextScheduled_()\n"
"  }\n"
"\n"
"  static size(path) {\n"
"    ensurePath_(path)\n"
"    sizePath_(path, Fiber.current)\n"
"    return Scheduler.runNextScheduled_()\n"
"  }\n"
"\n"
"  construct new_(fd) {}\n"
"\n"
"  close() {\n"
"    if (close_(Fiber.current)) return\n"
"    Scheduler.runNextScheduled_()\n"
"  }\n"
"\n"
"  foreign descriptor\n"
"\n"
"  isOpen { descriptor != -1 }\n"
"\n"
"  size {\n"
"    ensureOpen_()\n"
"    size_(Fiber.current)\n"
"    return Scheduler.runNextScheduled_()\n"
"  }\n"
"\n"
"  stat {\n"
"    ensureOpen_()\n"
"    stat_(Fiber.current)\n"
"    return Scheduler.runNextScheduled_()\n"
"  }\n"
"\n"
"  readBytes(count) { readBytes(count, 0) }\n"
"\n"
"  readBytes(count, offset) {\n"
"    ensureOpen_()\n"
"    File.ensureInt_(count, \"Count\")\n"
"    File.ensureInt_(offset, \"Offset\")\n"
"\n"
"    readBytes_(count, offset, Fiber.current)\n"
"    return Scheduler.runNextScheduled_()\n"
"  }\n"
"\n"
"  writeBytes(bytes) { writeBytes(bytes, size) }\n"
"\n"
"  writeBytes(bytes, offset) {\n"
"    ensureOpen_()\n"
"    if (!(bytes is String)) Fiber.abort(\"Bytes must be a string.\")\n"
"    File.ensureInt_(offset, \"Offset\")\n"
"\n"
"    writeBytes_(bytes, offset, Fiber.current)\n"
"    return Scheduler.runNextScheduled_()\n"
"  }\n"
"\n"
"  ensureOpen_() {\n"
"    if (!isOpen) Fiber.abort(\"File is not open.\")\n"
"  }\n"
"\n"
"  static ensurePath_(path) {\n"
"    if (!(path is String)) Fiber.abort(\"Path must be a string.\")\n"
"  }\n"
"\n"
"  static ensureInt_(value, name) {\n"
"    if (!(value is Num)) Fiber.abort(\"%(name) must be an integer.\")\n"
"    if (!value.isInteger) Fiber.abort(\"%(name) must be an integer.\")\n"
"    if (value < 0) Fiber.abort(\"%(name) cannot be negative.\")\n"
"  }\n"
"\n"
"  foreign static delete_(path, fiber)\n"
"  foreign static open_(path, flags, fiber)\n"
"  foreign static realPath_(path, fiber)\n"
"  foreign static sizePath_(path, fiber)\n"
"\n"
"  foreign close_(fiber)\n"
"  foreign readBytes_(count, offset, fiber)\n"
"  foreign size_(fiber)\n"
"  foreign stat_(fiber)\n"
"  foreign writeBytes_(bytes, offset, fiber)\n"
"}\n"
"\n"
"class FileFlags {\n"
"  // Note: These must be kept in sync with mapFileFlags() in io.c.\n"
"\n"
"  static readOnly  { 0x01 }\n"
"  static writeOnly { 0x02 }\n"
"  static readWrite { 0x04 }\n"
"  static sync      { 0x08 }\n"
"  static create    { 0x10 }\n"
"  static truncate  { 0x20 }\n"
"  static exclusive { 0x40 }\n"
"}\n"
"\n"
"foreign class Stat {\n"
"  static path(path) {\n"
"    if (!(path is String)) Fiber.abort(\"Path must be a string.\")\n"
"\n"
"    path_(path, Fiber.current)\n"
"    return Scheduler.runNextScheduled_()\n"
"  }\n"
"\n"
"  foreign static path_(path, fiber)\n"
"\n"
"  foreign blockCount\n"
"  foreign blockSize\n"
"  foreign device\n"
"  foreign group\n"
"  foreign inode\n"
"  foreign linkCount\n"
"  foreign mode\n"
"  foreign size\n"
"  foreign specialDevice\n"
"  foreign user\n"
"\n"
"  foreign isFile\n"
"  foreign isDirectory\n"
"  // TODO: Other mode checks.\n"
"}\n"
"\n"
"class Stdin {\n"
"  foreign static isRaw\n"
"  foreign static isRaw=(value)\n"
"  foreign static isTerminal\n"
"\n"
"  static readByte() {\n"
"    return read_ {\n"
"      // Peel off the first byte.\n"
"      var byte = __buffered.bytes[0]\n"
"      __buffered = __buffered[1..-1]\n"
"      return byte\n"
"    }\n"
"  }\n"
"\n"
"  static readLine() {\n"
"    return read_ {\n"
"      // TODO: Handle Windows line separators.\n"
"      var lineSeparator = __buffered.indexOf(\"\n\")\n"
"      if (lineSeparator == -1) return null\n"
"\n"
"      // Split the line at the separator.\n"
"      var line = __buffered[0...lineSeparator]\n"
"      __buffered = __buffered[lineSeparator + 1..-1]\n"
"      return line\n"
"    }\n"
"  }\n"
"\n"
"  static read_(handleData) {\n"
"    // See if we're already buffered enough to immediately produce a result.\n"
"    if (__buffered != null && !__buffered.isEmpty) {\n"
"      var result = handleData.call()\n"
"      if (result != null) return result\n"
"    }\n"
"\n"
"    if (__isClosed == true) Fiber.abort(\"Stdin was closed.\")\n"
"\n"
"    // Otherwise, we need to wait for input to come in.\n"
"    __handleData = handleData\n"
"\n"
"    // TODO: Error if other fiber is already waiting.\n"
"    readStart_()\n"
"\n"
"    __waitingFiber = Fiber.current\n"
"    var result = Scheduler.runNextScheduled_()\n"
"\n"
"    readStop_()\n"
"    return result\n"
"  }\n"
"\n"
"  static onData_(data) {\n"
"    // If data is null, it means stdin just closed.\n"
"    if (data == null) {\n"
"      __isClosed = true\n"
"      readStop_()\n"
"\n"
"      if (__buffered != null) {\n"
"        // TODO: Is this correct for readByte()?\n"
"        // Emit the last remaining bytes.\n"
"        var result = __buffered\n"
"        __buffered = null\n"
"        __waitingFiber.transfer(result)\n"
"      } else {\n"
"        __waitingFiber.transferError(\"Stdin was closed.\")\n"
"      }\n"
"    }\n"
"\n"
"    // Append to the buffer.\n"
"    if (__buffered == null) {\n"
"      __buffered = data\n"
"    } else {\n"
"      // TODO: Instead of concatenating strings each time, it's probably faster\n"
"      // to keep a list of buffers and flatten lazily.\n"
"      __buffered = __buffered + data\n"
"    }\n"
"\n"
"    // Ask the data handler if we have a complete result now.\n"
"    var result = __handleData.call()\n"
"    if (result != null) __waitingFiber.transfer(result)\n"
"  }\n"
"\n"
"  foreign static readStart_()\n"
"  foreign static readStop_()\n"
"}\n";
