// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

#include "bin/file.h"

#include <stdio.h>

#include "bin/builtin.h"
#include "bin/dartutils.h"
#include "bin/io_buffer.h"
#include "bin/namespace.h"
#include "bin/utils.h"
#include "include/bin/dart_io_api.h"
#include "include/dart_api.h"
#include "include/dart_tools_api.h"
#include "platform/globals.h"

namespace dart {
namespace bin {

static constexpr int kFileNativeFieldIndex = 0;

#if !defined(PRODUCT)
static bool IsFile(Dart_Handle file_obj) {
  Dart_Handle file_type = ThrowIfError(
      DartUtils::GetDartType("dart:io", "_RandomAccessFileOpsImpl"));
  bool isinstance = false;
  ThrowIfError(Dart_ObjectIsType(file_obj, file_type, &isinstance));
  return isinstance;
}
#endif

// The file pointer has been passed into Dart as an intptr_t and it is safe
// to pull it out of Dart as a 64-bit integer, cast it to an intptr_t and
// from there to a File pointer.
static File* GetFile(Dart_NativeArguments args) {
  File* file;
  Dart_Handle dart_this = ThrowIfError(Dart_GetNativeArgument(args, 0));
  DEBUG_ASSERT(IsFile(dart_this));
  Dart_Handle result = Dart_GetNativeInstanceField(
      dart_this, kFileNativeFieldIndex, reinterpret_cast<intptr_t*>(&file));
  ASSERT(!Dart_IsError(result));
  if (file == nullptr) {
    Dart_PropagateError(Dart_NewUnhandledExceptionError(
        DartUtils::NewInternalError("No native peer")));
  }
  return file;
}

static void SetFile(Dart_Handle dart_this, intptr_t file_pointer) {
  DEBUG_ASSERT(IsFile(dart_this));
  Dart_Handle result = Dart_SetNativeInstanceField(
      dart_this, kFileNativeFieldIndex, file_pointer);
  ThrowIfError(result);
}

void FUNCTION_NAME(File_GetPointer)(Dart_NativeArguments args) {
  File* file = GetFile(args);
  // If the file is already closed, GetFile() will return nullptr.
  if (file != nullptr) {
    // Increment file's reference count. File_GetPointer() should only be called
    // when we are about to send the File* to the IO Service.
    file->Retain();
  }
  intptr_t file_pointer = reinterpret_cast<intptr_t>(file);
  Dart_SetIntegerReturnValue(args, file_pointer);
}

void FUNCTION_NAME(File_GetFD)(Dart_NativeArguments args) {
  Dart_SetIntegerReturnValue(args, GetFile(args)->GetFD());
}

static void ReleaseFile(void* isolate_callback_data, void* peer) {
  File* file = reinterpret_cast<File*>(peer);
  file->Release();
}

void FUNCTION_NAME(File_SetPointer)(Dart_NativeArguments args) {
  Dart_Handle dart_this = ThrowIfError(Dart_GetNativeArgument(args, 0));
  intptr_t file_pointer = DartUtils::GetNativeIntptrArgument(args, 1);
  File* file = reinterpret_cast<File*>(file_pointer);
  Dart_FinalizableHandle handle = Dart_NewFinalizableHandle(
      dart_this, reinterpret_cast<void*>(file), sizeof(*file), ReleaseFile);
  file->SetFinalizableHandle(handle);
  SetFile(dart_this, file_pointer);
}

void FUNCTION_NAME(File_Open)(Dart_NativeArguments args) {
  Namespace* namespc = Namespace::GetNamespace(args, 0);
  const char* filename = DartUtils::GetNativeTypedDataArgument(args, 1);
  int64_t mode = DartUtils::GetNativeIntegerArgument(args, 2);
  File::DartFileOpenMode dart_file_mode =
      static_cast<File::DartFileOpenMode>(mode);
  File::FileOpenMode file_mode = File::DartModeToFileMode(dart_file_mode);
  // Check that the file exists before opening it only for
  // reading. This is to prevent the opening of directories as
  // files. Directories can be opened for reading using the posix
  // 'open' call.
  File* file = File::Open(namespc, filename, file_mode);
  if (file != nullptr) {
    Dart_SetIntegerReturnValue(args, reinterpret_cast<intptr_t>(file));
  } else {
    Dart_SetReturnValue(args, DartUtils::NewDartOSError());
  }
}

void FUNCTION_NAME(File_Exists)(Dart_NativeArguments args) {
  Namespace* namespc = Namespace::GetNamespace(args, 0);
  const char* filename = DartUtils::GetNativeTypedDataArgument(args, 1);
  bool exists = File::Exists(namespc, filename);
  Dart_SetBooleanReturnValue(args, exists);
}

void FUNCTION_NAME(File_Close)(Dart_NativeArguments args) {
  // TODO(zra): The bots are hitting a crash in this function, so we include
  // some checks here that are normally only in a Debug build. When the crash
  // is gone, this can go back to using GetFile and SetFile.
  Dart_Handle dart_this = ThrowIfError(Dart_GetNativeArgument(args, 0));
#if !defined(PRODUCT)
  if (!IsFile(dart_this)) {
    Dart_PropagateError(DartUtils::NewInternalError(
        "File_Close expects the receiver to be a _RandomAccessFileOpsImpl."));
  }
#endif
  File* file;
  ThrowIfError(Dart_GetNativeInstanceField(dart_this, kFileNativeFieldIndex,
                                           reinterpret_cast<intptr_t*>(&file)));
  if (file == nullptr) {
    Dart_SetIntegerReturnValue(args, -1);
    return;
  }
  file->Close();
  file->DeleteFinalizableHandle(Dart_CurrentIsolate(), dart_this);
  file->Release();

  ThrowIfError(
      Dart_SetNativeInstanceField(dart_this, kFileNativeFieldIndex, 0));
  Dart_SetIntegerReturnValue(args, 0);
}

void FUNCTION_NAME(File_ReadByte)(Dart_NativeArguments args) {
  File* file = GetFile(args);
  ASSERT(file != nullptr);
  uint8_t buffer;
  int64_t bytes_read = file->Read(reinterpret_cast<void*>(&buffer), 1);
  if (bytes_read == 1) {
    Dart_SetIntegerReturnValue(args, buffer);
  } else if (bytes_read == 0) {
    Dart_SetIntegerReturnValue(args, -1);
  } else {
    Dart_SetReturnValue(args, DartUtils::NewDartOSError());
  }
}

void FUNCTION_NAME(File_WriteByte)(Dart_NativeArguments args) {
  File* file = GetFile(args);
  ASSERT(file != nullptr);
  int64_t byte = 0;
  if (DartUtils::GetInt64Value(Dart_GetNativeArgument(args, 1), &byte)) {
    uint8_t buffer = static_cast<uint8_t>(byte & 0xff);
    bool success = file->WriteFully(reinterpret_cast<void*>(&buffer), 1);
    if (success) {
      Dart_SetIntegerReturnValue(args, 1);
    } else {
      Dart_SetReturnValue(args, DartUtils::NewDartOSError());
    }
  } else {
    OSError os_error(-1, "Invalid argument", OSError::kUnknown);
    Dart_SetReturnValue(args, DartUtils::NewDartOSError(&os_error));
  }
}

void FUNCTION_NAME(File_Read)(Dart_NativeArguments args) {
  File* file = GetFile(args);
  ASSERT(file != nullptr);
  Dart_Handle length_object = Dart_GetNativeArgument(args, 1);
  int64_t length = 0;
  if (!DartUtils::GetInt64Value(length_object, &length) || (length < 0)) {
    OSError os_error(-1, "Invalid argument", OSError::kUnknown);
    Dart_SetReturnValue(args, DartUtils::NewDartOSError(&os_error));
    return;
  }
  uint8_t* buffer = nullptr;
  Dart_Handle external_array = IOBuffer::Allocate(length, &buffer);
  if (Dart_IsNull(external_array)) {
    OSError os_error(-1, "Failed to allocate buffer", OSError::kUnknown);
    Dart_SetReturnValue(args, DartUtils::NewDartOSError(&os_error));
    return;
  }
  int64_t bytes_read = file->Read(reinterpret_cast<void*>(buffer), length);
  if (bytes_read < 0) {
    Dart_SetReturnValue(args, DartUtils::NewDartOSError());
    return;
  }
  if (bytes_read < length) {
    const int kNumArgs = 3;
    Dart_Handle dart_args[kNumArgs];
    dart_args[0] = external_array;
    dart_args[1] = Dart_NewInteger(0);
    dart_args[2] = Dart_NewInteger(bytes_read);
    // TODO(sgjesse): Cache the _makeUint8ListView function somewhere.
    Dart_Handle io_lib = Dart_LookupLibrary(DartUtils::NewString("dart:io"));
    ThrowIfError(io_lib);
    Dart_Handle array_view =
        Dart_Invoke(io_lib, DartUtils::NewString("_makeUint8ListView"),
                    kNumArgs, dart_args);
    Dart_SetReturnValue(args, array_view);
  } else {
    Dart_SetReturnValue(args, external_array);
  }
}

void FUNCTION_NAME(File_ReadInto)(Dart_NativeArguments args) {
  File* file = GetFile(args);
  ASSERT(file != nullptr);
  Dart_Handle buffer_obj = Dart_GetNativeArgument(args, 1);
  ASSERT(Dart_IsList(buffer_obj));
  // start and end arguments are checked in Dart code to be
  // integers and have the property that end <=
  // list.length. Therefore, it is safe to extract their value as
  // intptr_t.
  intptr_t start = DartUtils::GetNativeIntptrArgument(args, 2);
  intptr_t end = DartUtils::GetNativeIntptrArgument(args, 3);
  intptr_t length = end - start;
  intptr_t array_len = 0;
  Dart_Handle result = Dart_ListLength(buffer_obj, &array_len);
  ThrowIfError(result);
  ASSERT(end <= array_len);

  uint8_t* buffer;
  bool is_byte_data = false;

  if (Dart_IsTypedData(buffer_obj)) {
    // Avoid a memory copy if the input List<int> is an UInt8List.
    Dart_TypedData_Type data_type;
    intptr_t bytes_count;
    ThrowIfError(Dart_TypedDataAcquireData(buffer_obj, &data_type,
                                           reinterpret_cast<void**>(&buffer),
                                           &bytes_count));
    if (data_type == Dart_TypedData_kUint8) {
      is_byte_data = true;
      buffer += start;
      ASSERT(bytes_count == array_len);
    } else {
      ThrowIfError(Dart_TypedDataReleaseData(buffer_obj));
    }
  }

  if (!is_byte_data) {
    buffer = Dart_ScopeAllocate(length);
  }

  int64_t bytes_read = file->Read(reinterpret_cast<void*>(buffer), length);
  OSError* os_error = new OSError();  // capture error if any
  if (is_byte_data) {
    Dart_Handle handle = Dart_TypedDataReleaseData(buffer_obj);
    if (Dart_IsError(handle)) {
      delete os_error;
      Dart_PropagateError(handle);
    }
  }
  if (bytes_read >= 0) {
    if (!is_byte_data) {
      Dart_Handle handle =
          Dart_ListSetAsBytes(buffer_obj, start, buffer, bytes_read);
      if (Dart_IsError(handle)) {
        delete os_error;
        Dart_PropagateError(handle);
      }
    }
    Dart_SetIntegerReturnValue(args, bytes_read);
  } else {
    Dart_SetReturnValue(args, DartUtils::NewDartOSError(os_error));
  }
  delete os_error;
}

void FUNCTION_NAME(File_WriteFrom)(Dart_NativeArguments args) {
  File* file = GetFile(args);
  ASSERT(file != nullptr);

  Dart_Handle buffer_obj = Dart_GetNativeArgument(args, 1);

  // Offset and length arguments are checked in Dart code to be
  // integers and have the property that (offset + length) <=
  // list.length. Therefore, it is safe to extract their value as
  // intptr_t.
  intptr_t start = DartUtils::GetNativeIntptrArgument(args, 2);
  intptr_t end = DartUtils::GetNativeIntptrArgument(args, 3);

  // The buffer object passed in has to be an Int8List or Uint8List object.
  // Acquire a direct pointer to the data area of the buffer object.
  Dart_TypedData_Type type;
  intptr_t length = end - start;
  intptr_t buffer_len = 0;
  void* buffer = nullptr;
  Dart_Handle result =
      Dart_TypedDataAcquireData(buffer_obj, &type, &buffer, &buffer_len);
  ThrowIfError(result);

  ASSERT(type == Dart_TypedData_kUint8 || type == Dart_TypedData_kInt8);
  ASSERT(end <= buffer_len);
  ASSERT(buffer != nullptr);

  // Write all the data out into the file.
  char* byte_buffer = reinterpret_cast<char*>(buffer);
  bool success = file->WriteFully(byte_buffer + start, length);
  OSError* os_error = new OSError();  // capture error if any

  // Release the direct pointer acquired above.
  result = Dart_TypedDataReleaseData(buffer_obj);
  if (Dart_IsError(result)) {
    delete os_error;
    Dart_PropagateError(result);
  }
  if (!success) {
    Dart_SetReturnValue(args, DartUtils::NewDartOSError(os_error));
  } else {
    Dart_SetReturnValue(args, Dart_Null());
  }
  delete os_error;
}

void FUNCTION_NAME(File_Position)(Dart_NativeArguments args) {
  File* file = GetFile(args);
  ASSERT(file != nullptr);
  intptr_t return_value = file->Position();
  if (return_value >= 0) {
    Dart_SetIntegerReturnValue(args, return_value);
  } else {
    Dart_SetReturnValue(args, DartUtils::NewDartOSError());
  }
}

void FUNCTION_NAME(File_SetPosition)(Dart_NativeArguments args) {
  File* file = GetFile(args);
  ASSERT(file != nullptr);
  int64_t position = 0;
  if (DartUtils::GetInt64Value(Dart_GetNativeArgument(args, 1), &position)) {
    if (file->SetPosition(position)) {
      Dart_SetBooleanReturnValue(args, true);
    } else {
      Dart_SetReturnValue(args, DartUtils::NewDartOSError());
    }
  } else {
    OSError os_error(-1, "Invalid argument", OSError::kUnknown);
    Dart_SetReturnValue(args, DartUtils::NewDartOSError(&os_error));
  }
}

void FUNCTION_NAME(File_Truncate)(Dart_NativeArguments args) {
  File* file = GetFile(args);
  ASSERT(file != nullptr);
  int64_t length = 0;
  if (DartUtils::GetInt64Value(Dart_GetNativeArgument(args, 1), &length)) {
    if (file->Truncate(length)) {
      Dart_SetBooleanReturnValue(args, true);
    } else {
      Dart_SetReturnValue(args, DartUtils::NewDartOSError());
    }
  } else {
    OSError os_error(-1, "Invalid argument", OSError::kUnknown);
    Dart_SetReturnValue(args, DartUtils::NewDartOSError(&os_error));
  }
}

void FUNCTION_NAME(File_Length)(Dart_NativeArguments args) {
  File* file = GetFile(args);
  ASSERT(file != nullptr);
  int64_t return_value = file->Length();
  if (return_value >= 0) {
    Dart_SetIntegerReturnValue(args, return_value);
  } else {
    Dart_SetReturnValue(args, DartUtils::NewDartOSError());
  }
}

void FUNCTION_NAME(File_LengthFromPath)(Dart_NativeArguments args) {
  Namespace* namespc = Namespace::GetNamespace(args, 0);
  const char* path = DartUtils::GetNativeTypedDataArgument(args, 1);
  int64_t return_value = File::LengthFromPath(namespc, path);
  if (return_value >= 0) {
    Dart_SetIntegerReturnValue(args, return_value);
  } else {
    Dart_SetReturnValue(args, DartUtils::NewDartOSError());
  }
}

void FUNCTION_NAME(File_LastModified)(Dart_NativeArguments args) {
  Namespace* namespc = Namespace::GetNamespace(args, 0);
  const char* raw_name = DartUtils::GetNativeTypedDataArgument(args, 1);
  int64_t return_value = File::LastModified(namespc, raw_name);
  if (return_value >= 0) {
    Dart_SetIntegerReturnValue(args, return_value * kMillisecondsPerSecond);
  } else {
    Dart_SetReturnValue(args, DartUtils::NewDartOSError());
  }
}

void FUNCTION_NAME(File_SetLastModified)(Dart_NativeArguments args) {
  Namespace* namespc = Namespace::GetNamespace(args, 0);
  int64_t millis;
  if (!DartUtils::GetInt64Value(Dart_GetNativeArgument(args, 2), &millis)) {
    Dart_ThrowException(DartUtils::NewDartArgumentError(
        "The second argument must be a 64-bit int."));
  }
  const char* name = DartUtils::GetNativeTypedDataArgument(args, 1);
  bool result = File::SetLastModified(namespc, name, millis);
  if (!result) {
    Dart_SetReturnValue(args, DartUtils::NewDartOSError());
  }
}

void FUNCTION_NAME(File_LastAccessed)(Dart_NativeArguments args) {
  Namespace* namespc = Namespace::GetNamespace(args, 0);
  const char* name = DartUtils::GetNativeTypedDataArgument(args, 1);
  int64_t return_value = File::LastAccessed(namespc, name);
  if (return_value >= 0) {
    Dart_SetIntegerReturnValue(args, return_value * kMillisecondsPerSecond);
  } else {
    Dart_SetReturnValue(args, DartUtils::NewDartOSError());
  }
}

void FUNCTION_NAME(File_SetLastAccessed)(Dart_NativeArguments args) {
  Namespace* namespc = Namespace::GetNamespace(args, 0);
  int64_t millis;
  if (!DartUtils::GetInt64Value(Dart_GetNativeArgument(args, 2), &millis)) {
    Dart_ThrowException(DartUtils::NewDartArgumentError(
        "The second argument must be a 64-bit int."));
  }
  const char* name = DartUtils::GetNativeTypedDataArgument(args, 1);
  bool result = File::SetLastAccessed(namespc, name, millis);
  if (!result) {
    Dart_SetReturnValue(args, DartUtils::NewDartOSError());
  }
}

void FUNCTION_NAME(File_Flush)(Dart_NativeArguments args) {
  File* file = GetFile(args);
  ASSERT(file != nullptr);
  if (file->Flush()) {
    Dart_SetBooleanReturnValue(args, true);
  } else {
    Dart_SetReturnValue(args, DartUtils::NewDartOSError());
  }
}

void FUNCTION_NAME(File_Lock)(Dart_NativeArguments args) {
  File* file = GetFile(args);
  ASSERT(file != nullptr);
  int64_t lock;
  int64_t start;
  int64_t end;
  if (DartUtils::GetInt64Value(Dart_GetNativeArgument(args, 1), &lock) &&
      DartUtils::GetInt64Value(Dart_GetNativeArgument(args, 2), &start) &&
      DartUtils::GetInt64Value(Dart_GetNativeArgument(args, 3), &end)) {
    if ((lock >= File::kLockMin) && (lock <= File::kLockMax) && (start >= 0) &&
        (end == -1 || end > start)) {
      if (file->Lock(static_cast<File::LockType>(lock), start, end)) {
        Dart_SetBooleanReturnValue(args, true);
      } else {
        Dart_SetReturnValue(args, DartUtils::NewDartOSError());
      }
      return;
    }
  }
  OSError os_error(-1, "Invalid argument", OSError::kUnknown);
  Dart_SetReturnValue(args, DartUtils::NewDartOSError(&os_error));
}

void FUNCTION_NAME(File_Create)(Dart_NativeArguments args) {
  Namespace* namespc = Namespace::GetNamespace(args, 0);
  Dart_Handle exclusive_handle = Dart_GetNativeArgument(args, 2);
  const char* path = DartUtils::GetNativeTypedDataArgument(args, 1);
  bool exclusive = DartUtils::GetBooleanValue(exclusive_handle);
  bool result = File::Create(namespc, path, exclusive);
  if (result) {
    Dart_SetBooleanReturnValue(args, result);
  } else {
    Dart_SetReturnValue(args, DartUtils::NewDartOSError());
  }
}

void FUNCTION_NAME(File_CreateLink)(Dart_NativeArguments args) {
  Namespace* namespc = Namespace::GetNamespace(args, 0);
  const char* name = DartUtils::GetNativeTypedDataArgument(args, 1);
  const char* target = DartUtils::GetNativeStringArgument(args, 2);
  bool result = File::CreateLink(namespc, name, target);
  if (!result) {
    Dart_SetReturnValue(args, DartUtils::NewDartOSError());
  }
}

void FUNCTION_NAME(File_CreatePipe)(Dart_NativeArguments args) {
  Namespace* namespc = Namespace::GetNamespace(args, 0);

  File* readPipe;
  File* writePipe;
  if (File::CreatePipe(namespc, &readPipe, &writePipe)) {
    Dart_Handle pipes = ThrowIfError(Dart_NewList(2));
    Dart_Handle readHandle =
        ThrowIfError(Dart_NewInteger(reinterpret_cast<intptr_t>(readPipe)));
    Dart_Handle writeHandle =
        ThrowIfError(Dart_NewInteger(reinterpret_cast<intptr_t>(writePipe)));
    ThrowIfError(Dart_ListSetAt(pipes, 0, readHandle));
    ThrowIfError(Dart_ListSetAt(pipes, 1, writeHandle));
    Dart_SetReturnValue(args, pipes);
  } else {
    Dart_SetReturnValue(args, DartUtils::NewDartOSError());
  }
}

void FUNCTION_NAME(File_LinkTarget)(Dart_NativeArguments args) {
  Namespace* namespc = Namespace::GetNamespace(args, 0);
  const char* name = DartUtils::GetNativeTypedDataArgument(args, 1);
  const char* target = File::LinkTarget(namespc, name);
  if (target == nullptr) {
    Dart_SetReturnValue(args, DartUtils::NewDartOSError());
  } else {
    Dart_Handle str = ThrowIfError(DartUtils::NewString(target));
    Dart_SetReturnValue(args, str);
  }
}

void FUNCTION_NAME(File_Delete)(Dart_NativeArguments args) {
  Namespace* namespc = Namespace::GetNamespace(args, 0);
  const char* path = DartUtils::GetNativeTypedDataArgument(args, 1);
  bool result = File::Delete(namespc, path);
  if (result) {
    Dart_SetBooleanReturnValue(args, result);
  } else {
    Dart_SetReturnValue(args, DartUtils::NewDartOSError());
  }
}

void FUNCTION_NAME(File_DeleteLink)(Dart_NativeArguments args) {
  Namespace* namespc = Namespace::GetNamespace(args, 0);
  const char* path = DartUtils::GetNativeTypedDataArgument(args, 1);
  bool result = File::DeleteLink(namespc, path);
  if (result) {
    Dart_SetBooleanReturnValue(args, result);
  } else {
    Dart_SetReturnValue(args, DartUtils::NewDartOSError());
  }
}

void FUNCTION_NAME(File_Rename)(Dart_NativeArguments args) {
  Namespace* namespc = Namespace::GetNamespace(args, 0);
  const char* old_path = DartUtils::GetNativeTypedDataArgument(args, 1);
  const char* new_path = DartUtils::GetNativeStringArgument(args, 2);
  bool result = File::Rename(namespc, old_path, new_path);
  if (result) {
    Dart_SetBooleanReturnValue(args, result);
  } else {
    Dart_SetReturnValue(args, DartUtils::NewDartOSError());
  }
}

void FUNCTION_NAME(File_RenameLink)(Dart_NativeArguments args) {
  Namespace* namespc = Namespace::GetNamespace(args, 0);
  const char* old_path = DartUtils::GetNativeTypedDataArgument(args, 1);
  const char* new_path = DartUtils::GetNativeStringArgument(args, 2);
  bool result = File::RenameLink(namespc, old_path, new_path);
  if (result) {
    Dart_SetBooleanReturnValue(args, result);
  } else {
    Dart_SetReturnValue(args, DartUtils::NewDartOSError());
  }
}

void FUNCTION_NAME(File_Copy)(Dart_NativeArguments args) {
  Namespace* namespc = Namespace::GetNamespace(args, 0);
  const char* old_path = DartUtils::GetNativeTypedDataArgument(args, 1);
  const char* new_path = DartUtils::GetNativeStringArgument(args, 2);
  bool result = File::Copy(namespc, old_path, new_path);
  if (result) {
    Dart_SetBooleanReturnValue(args, result);
  } else {
    Dart_SetReturnValue(args, DartUtils::NewDartOSError());
  }
}

void FUNCTION_NAME(File_ResolveSymbolicLinks)(Dart_NativeArguments args) {
  Namespace* namespc = Namespace::GetNamespace(args, 0);
  const char* path = nullptr;
  const char* str = DartUtils::GetNativeTypedDataArgument(args, 1);
  path = File::GetCanonicalPath(namespc, str);
  if (path != nullptr) {
    Dart_Handle str = ThrowIfError(DartUtils::NewString(path));
    Dart_SetReturnValue(args, str);
  } else {
    Dart_SetReturnValue(args, DartUtils::NewDartOSError());
  }
}

void FUNCTION_NAME(File_OpenStdio)(Dart_NativeArguments args) {
  const int64_t fd = DartUtils::GetNativeIntegerArgument(args, 0);
  File* file = File::OpenStdio(static_cast<int>(fd));
  Dart_SetIntegerReturnValue(args, reinterpret_cast<intptr_t>(file));
}

void FUNCTION_NAME(File_GetStdioHandleType)(Dart_NativeArguments args) {
  int64_t fd = DartUtils::GetNativeIntegerArgument(args, 0);
  ASSERT((fd == STDIN_FILENO) || (fd == STDOUT_FILENO) ||
         (fd == STDERR_FILENO));
  File::StdioHandleType type = File::GetStdioHandleType(static_cast<int>(fd));
  if (type == File::StdioHandleType::kTypeError) {
    Dart_SetReturnValue(args, DartUtils::NewDartOSError());
  } else {
    Dart_SetIntegerReturnValue(args, type);
  }
}

void FUNCTION_NAME(File_GetType)(Dart_NativeArguments args) {
  Namespace* namespc = Namespace::GetNamespace(args, 0);
  const char* path = DartUtils::GetNativeTypedDataArgument(args, 1);
  bool follow_links = DartUtils::GetNativeBooleanArgument(args, 2);
  File::Type type = File::GetType(namespc, path, follow_links);
  Dart_SetIntegerReturnValue(args, static_cast<int>(type));
}

void FUNCTION_NAME(File_Stat)(Dart_NativeArguments args) {
  Namespace* namespc = Namespace::GetNamespace(args, 0);
  const char* path = DartUtils::GetNativeStringArgument(args, 1);

  int64_t stat_data[File::kStatSize];
  File::Stat(namespc, path, stat_data);
  if (stat_data[File::kType] == File::kDoesNotExist) {
    Dart_SetReturnValue(args, DartUtils::NewDartOSError());
    return;
  }
  Dart_Handle returned_data =
      Dart_NewTypedData(Dart_TypedData_kInt64, File::kStatSize);
  ThrowIfError(returned_data);
  Dart_TypedData_Type data_type_unused;
  void* data_location;
  intptr_t data_length_unused;
  Dart_Handle status = Dart_TypedDataAcquireData(
      returned_data, &data_type_unused, &data_location, &data_length_unused);
  ThrowIfError(status);
  memmove(data_location, stat_data, File::kStatSize * sizeof(int64_t));
  status = Dart_TypedDataReleaseData(returned_data);
  ThrowIfError(status);
  Dart_SetReturnValue(args, returned_data);
}

void FUNCTION_NAME(File_AreIdentical)(Dart_NativeArguments args) {
  Namespace* namespc = Namespace::GetNamespace(args, 0);
  const char* path_1 = DartUtils::GetNativeStringArgument(args, 1);
  const char* path_2 = DartUtils::GetNativeStringArgument(args, 2);
  File::Identical result = File::AreIdentical(namespc, path_1, namespc, path_2);
  if (result == File::kError) {
    Dart_SetReturnValue(args, DartUtils::NewDartOSError());
  } else {
    Dart_SetBooleanReturnValue(args, result == File::kIdentical);
  }
}

#define IS_SEPARATOR(c) ((c) == '/' || (c) == 0)

// Checks that if we increment this index forward, we'll still have enough space
// for a null terminator within PATH_MAX bytes.
#define CHECK_CAN_INCREMENT(i)                                                 \
  if ((i) + 1 >= outlen) {                                                     \
    return -1;                                                                 \
  }

intptr_t File::CleanUnixPath(const char* in, char* out, intptr_t outlen) {
  if (in[0] == 0) {
    snprintf(out, outlen, ".");
    return 1;
  }

  const bool rooted = (in[0] == '/');
  intptr_t in_index = 0;   // Index of the next byte to read.
  intptr_t out_index = 0;  // Index of the next byte to write.

  if (rooted) {
    out[out_index++] = '/';
    in_index++;
  }
  // The output index at which '..' cannot be cleaned further.
  intptr_t dotdot = out_index;

  while (in[in_index] != 0) {
    if (in[in_index] == '/') {
      // 1. Reduce multiple slashes to a single slash.
      CHECK_CAN_INCREMENT(in_index);
      in_index++;
    } else if ((in[in_index] == '.') && IS_SEPARATOR(in[in_index + 1])) {
      // 2. Eliminate . path name elements (the current directory).
      CHECK_CAN_INCREMENT(in_index);
      in_index++;
    } else if ((in[in_index] == '.') && (in[in_index + 1] == '.') &&
               IS_SEPARATOR(in[in_index + 2])) {
      CHECK_CAN_INCREMENT(in_index + 1);
      in_index += 2;
      if (out_index > dotdot) {
        // 3. Eliminate .. path elements (the parent directory) and the element
        // that precedes them.
        out_index--;
        while ((out_index > dotdot) && (out[out_index] != '/')) {
          out_index--;
        }
      } else if (rooted) {
        // 4. Eliminate .. elements that begin a rooted path, that is, replace
        // /.. by / at the beginning of a path.
        continue;
      } else if (!rooted) {
        if (out_index > 0) {
          out[out_index++] = '/';
        }
        // 5. Leave intact .. elements that begin a non-rooted path.
        out[out_index++] = '.';
        out[out_index++] = '.';
        dotdot = out_index;
      }
    } else {
      if ((rooted && out_index != 1) || (!rooted && out_index != 0)) {
        // Add '/' before normal path component, for non-root components.
        out[out_index++] = '/';
      }

      while (!IS_SEPARATOR(in[in_index])) {
        CHECK_CAN_INCREMENT(in_index);
        out[out_index++] = in[in_index++];
      }
    }
  }

  if (out_index == 0) {
    snprintf(out, outlen, ".");
    return 1;
  }

  // Append null character.
  out[out_index] = 0;
  return out_index;
}

static int64_t CObjectInt32OrInt64ToInt64(CObject* cobject) {
  ASSERT(cobject->IsInt32OrInt64());
  int64_t result;
  if (cobject->IsInt32()) {
    CObjectInt32 value(cobject);
    result = value.Value();
  } else {
    CObjectInt64 value(cobject);
    result = value.Value();
  }
  return result;
}

static File* CObjectToFilePointer(CObject* cobject) {
  CObjectIntptr value(cobject);
  return reinterpret_cast<File*>(value.Value());
}

static Namespace* CObjectToNamespacePointer(CObject* cobject) {
  CObjectIntptr value(cobject);
  return reinterpret_cast<Namespace*>(value.Value());
}

CObject* File::ExistsRequest(const CObjectArray& request) {
  if ((request.Length() < 1) || !request[0]->IsIntptr()) {
    return CObject::IllegalArgumentError();
  }
  Namespace* namespc = CObjectToNamespacePointer(request[0]);
  RefCntReleaseScope<Namespace> rs(namespc);
  if ((request.Length() != 2) || !request[1]->IsUint8Array()) {
    return CObject::IllegalArgumentError();
  }
  CObjectUint8Array filename(request[1]);
  return CObject::Bool(
      File::Exists(namespc, reinterpret_cast<const char*>(filename.Buffer())));
}

CObject* File::CreateRequest(const CObjectArray& request) {
  if ((request.Length() < 1) || !request[0]->IsIntptr()) {
    return CObject::IllegalArgumentError();
  }
  Namespace* namespc = CObjectToNamespacePointer(request[0]);
  RefCntReleaseScope<Namespace> rs(namespc);
  if ((request.Length() != 3) || !request[1]->IsUint8Array() ||
      !request[2]->IsBool()) {
    return CObject::IllegalArgumentError();
  }
  CObjectUint8Array filename(request[1]);
  CObjectBool exclusive(request[2]);
  return File::Create(namespc, reinterpret_cast<const char*>(filename.Buffer()),
                      exclusive.Value())
             ? CObject::True()
             : CObject::NewOSError();
}

CObject* File::CreatePipeRequest(const CObjectArray& request) {
  if ((request.Length() < 1) || !request[0]->IsIntptr()) {
    return CObject::IllegalArgumentError();
  }
  Namespace* namespc = CObjectToNamespacePointer(request[0]);
  RefCntReleaseScope<Namespace> rs(namespc);

  File* readPipe;
  File* writePipe;
  if (!CreatePipe(namespc, &readPipe, &writePipe)) {
    return CObject::NewOSError();
  }

  CObjectArray* pipes = new CObjectArray(CObject::NewArray(2));
  CObjectNativePointer* readHandle = new CObjectNativePointer(
      CObject::NewNativePointer(reinterpret_cast<intptr_t>(readPipe),
                                sizeof(*readPipe), ReleaseFile));
  CObjectNativePointer* writeHandle = new CObjectNativePointer(
      CObject::NewNativePointer(reinterpret_cast<intptr_t>(writePipe),
                                sizeof(*writePipe), ReleaseFile));
  pipes->SetAt(0, readHandle);
  pipes->SetAt(1, writeHandle);
  return pipes;
}

CObject* File::OpenRequest(const CObjectArray& request) {
  if ((request.Length() < 1) || !request[0]->IsIntptr()) {
    return CObject::IllegalArgumentError();
  }
  Namespace* namespc = CObjectToNamespacePointer(request[0]);
  RefCntReleaseScope<Namespace> rs(namespc);
  if ((request.Length() != 3) || !request[1]->IsUint8Array() ||
      !request[2]->IsInt32()) {
    return CObject::IllegalArgumentError();
  }
  CObjectUint8Array filename(request[1]);
  CObjectInt32 mode(request[2]);
  File::DartFileOpenMode dart_file_mode =
      static_cast<File::DartFileOpenMode>(mode.Value());
  File::FileOpenMode file_mode = File::DartModeToFileMode(dart_file_mode);
  File* file = File::Open(
      namespc, reinterpret_cast<const char*>(filename.Buffer()), file_mode);
  if (file == nullptr) {
    return CObject::NewOSError();
  }
  return new CObjectNativePointer(CObject::NewNativePointer(
      reinterpret_cast<intptr_t>(file), sizeof(*file), ReleaseFile));
}

CObject* File::DeleteRequest(const CObjectArray& request) {
  if ((request.Length() < 1) || !request[0]->IsIntptr()) {
    return CObject::False();
  }
  Namespace* namespc = CObjectToNamespacePointer(request[0]);
  RefCntReleaseScope<Namespace> rs(namespc);
  if ((request.Length() != 2) || !request[1]->IsUint8Array()) {
    return CObject::False();
  }
  CObjectUint8Array filename(request[1]);
  return File::Delete(namespc, reinterpret_cast<const char*>(filename.Buffer()))
             ? CObject::True()
             : CObject::NewOSError();
}

CObject* File::RenameRequest(const CObjectArray& request) {
  if ((request.Length() < 1) || !request[0]->IsIntptr()) {
    return CObject::IllegalArgumentError();
  }
  Namespace* namespc = CObjectToNamespacePointer(request[0]);
  RefCntReleaseScope<Namespace> rs(namespc);
  if ((request.Length() != 3) || !request[1]->IsUint8Array() ||
      !request[2]->IsString()) {
    return CObject::IllegalArgumentError();
  }
  CObjectUint8Array old_path(request[1]);
  CObjectString new_path(request[2]);
  return File::Rename(namespc, reinterpret_cast<const char*>(old_path.Buffer()),
                      new_path.CString())
             ? CObject::True()
             : CObject::NewOSError();
}

CObject* File::CopyRequest(const CObjectArray& request) {
  if ((request.Length() < 1) || !request[0]->IsIntptr()) {
    return CObject::IllegalArgumentError();
  }
  Namespace* namespc = CObjectToNamespacePointer(request[0]);
  RefCntReleaseScope<Namespace> rs(namespc);
  if ((request.Length() != 3) || !request[1]->IsUint8Array() ||
      !request[2]->IsString()) {
    return CObject::IllegalArgumentError();
  }
  CObjectUint8Array old_path(request[1]);
  CObjectString new_path(request[2]);
  return File::Copy(namespc, reinterpret_cast<const char*>(old_path.Buffer()),
                    new_path.CString())
             ? CObject::True()
             : CObject::NewOSError();
}

CObject* File::ResolveSymbolicLinksRequest(const CObjectArray& request) {
  if ((request.Length() < 1) || !request[0]->IsIntptr()) {
    return CObject::IllegalArgumentError();
  }
  Namespace* namespc = CObjectToNamespacePointer(request[0]);
  RefCntReleaseScope<Namespace> rs(namespc);
  if ((request.Length() != 2) || !request[1]->IsUint8Array()) {
    return CObject::IllegalArgumentError();
  }
  CObjectUint8Array filename(request[1]);
  const char* result = File::GetCanonicalPath(
      namespc, reinterpret_cast<const char*>(filename.Buffer()));
  if (result == nullptr) {
    return CObject::NewOSError();
  }
  return new CObjectString(CObject::NewString(result));
}

CObject* File::CloseRequest(const CObjectArray& request) {
  if ((request.Length() != 1) || !request[0]->IsIntptr()) {
    return new CObjectIntptr(CObject::NewIntptr(-1));
  }
  File* file = CObjectToFilePointer(request[0]);
  RefCntReleaseScope<File> rs(file);
  // We have retained a reference to the file here. Therefore the file's
  // destructor can't be running. Since no further requests are dispatched by
  // the Dart code after an async close call, this Close() can't be racing
  // with any other call on the file. We don't do an extra Release(), and we
  // don't delete the weak persistent handle. The file is closed here, but the
  // memory will be cleaned up when the finalizer runs.
  ASSERT(!file->IsClosed());
  file->Close();
  return new CObjectIntptr(CObject::NewIntptr(0));
}

CObject* File::PositionRequest(const CObjectArray& request) {
  if ((request.Length() != 1) || !request[0]->IsIntptr()) {
    return CObject::IllegalArgumentError();
  }
  File* file = CObjectToFilePointer(request[0]);
  RefCntReleaseScope<File> rs(file);
  if (file->IsClosed()) {
    return CObject::FileClosedError();
  }
  const intptr_t return_value = file->Position();
  if (return_value < 0) {
    return CObject::NewOSError();
  }
  return new CObjectIntptr(CObject::NewIntptr(return_value));
}

CObject* File::SetPositionRequest(const CObjectArray& request) {
  if ((request.Length() < 1) || !request[0]->IsIntptr()) {
    return CObject::IllegalArgumentError();
  }
  File* file = CObjectToFilePointer(request[0]);
  RefCntReleaseScope<File> rs(file);
  if ((request.Length() != 2) || !request[1]->IsInt32OrInt64()) {
    return CObject::IllegalArgumentError();
  }
  if (file->IsClosed()) {
    return CObject::FileClosedError();
  }
  const int64_t position = CObjectInt32OrInt64ToInt64(request[1]);
  return file->SetPosition(position) ? CObject::True() : CObject::NewOSError();
}

CObject* File::TruncateRequest(const CObjectArray& request) {
  if ((request.Length() < 1) || !request[0]->IsIntptr()) {
    return CObject::IllegalArgumentError();
  }
  File* file = CObjectToFilePointer(request[0]);
  RefCntReleaseScope<File> rs(file);
  if ((request.Length() != 2) || !request[1]->IsInt32OrInt64()) {
    return CObject::IllegalArgumentError();
  }
  if (file->IsClosed()) {
    return CObject::FileClosedError();
  }
  const int64_t length = CObjectInt32OrInt64ToInt64(request[1]);
  if (file->Truncate(length)) {
    return CObject::True();
  }
  return CObject::NewOSError();
}

CObject* File::LengthRequest(const CObjectArray& request) {
  if ((request.Length() != 1) || !request[0]->IsIntptr()) {
    return CObject::IllegalArgumentError();
  }
  File* file = CObjectToFilePointer(request[0]);
  RefCntReleaseScope<File> rs(file);
  if (file->IsClosed()) {
    return CObject::FileClosedError();
  }
  const int64_t return_value = file->Length();
  if (return_value < 0) {
    return CObject::NewOSError();
  }
  return new CObjectInt64(CObject::NewInt64(return_value));
}

CObject* File::LengthFromPathRequest(const CObjectArray& request) {
  if ((request.Length() < 1) || !request[0]->IsIntptr()) {
    return CObject::IllegalArgumentError();
  }
  Namespace* namespc = CObjectToNamespacePointer(request[0]);
  RefCntReleaseScope<Namespace> rs(namespc);
  if ((request.Length() != 2) || !request[1]->IsUint8Array()) {
    return CObject::IllegalArgumentError();
  }
  CObjectUint8Array filepath(request[1]);
  const int64_t return_value = File::LengthFromPath(
      namespc, reinterpret_cast<const char*>(filepath.Buffer()));
  if (return_value < 0) {
    return CObject::NewOSError();
  }
  return new CObjectInt64(CObject::NewInt64(return_value));
}

CObject* File::LastAccessedRequest(const CObjectArray& request) {
  if ((request.Length() < 1) || !request[0]->IsIntptr()) {
    return CObject::IllegalArgumentError();
  }
  Namespace* namespc = CObjectToNamespacePointer(request[0]);
  RefCntReleaseScope<Namespace> rs(namespc);
  if ((request.Length() != 2) || !request[1]->IsUint8Array()) {
    return CObject::IllegalArgumentError();
  }
  CObjectUint8Array filepath(request[1]);
  const int64_t return_value = File::LastAccessed(
      namespc, reinterpret_cast<const char*>(filepath.Buffer()));
  if (return_value < 0) {
    return CObject::NewOSError();
  }
  return new CObjectIntptr(
      CObject::NewInt64(return_value * kMillisecondsPerSecond));
}

CObject* File::SetLastAccessedRequest(const CObjectArray& request) {
  if ((request.Length() < 1) || !request[0]->IsIntptr()) {
    return CObject::IllegalArgumentError();
  }
  Namespace* namespc = CObjectToNamespacePointer(request[0]);
  RefCntReleaseScope<Namespace> rs(namespc);
  if ((request.Length() != 3) || !request[1]->IsUint8Array() ||
      !request[2]->IsInt32OrInt64()) {
    return CObject::IllegalArgumentError();
  }
  CObjectUint8Array filepath(request[1]);
  const int64_t millis = CObjectInt32OrInt64ToInt64(request[2]);
  return File::SetLastAccessed(
             namespc, reinterpret_cast<const char*>(filepath.Buffer()), millis)
             ? CObject::Null()
             : CObject::NewOSError();
}

CObject* File::LastModifiedRequest(const CObjectArray& request) {
  if ((request.Length() < 1) || !request[0]->IsIntptr()) {
    return CObject::IllegalArgumentError();
  }
  Namespace* namespc = CObjectToNamespacePointer(request[0]);
  RefCntReleaseScope<Namespace> rs(namespc);
  if ((request.Length() != 2) || !request[1]->IsUint8Array()) {
    return CObject::IllegalArgumentError();
  }
  CObjectUint8Array filepath(request[1]);
  const int64_t return_value = File::LastModified(
      namespc, reinterpret_cast<const char*>(filepath.Buffer()));
  if (return_value < 0) {
    return CObject::NewOSError();
  }
  return new CObjectIntptr(
      CObject::NewInt64(return_value * kMillisecondsPerSecond));
}

CObject* File::SetLastModifiedRequest(const CObjectArray& request) {
  if ((request.Length() < 1) || !request[0]->IsIntptr()) {
    return CObject::IllegalArgumentError();
  }
  Namespace* namespc = CObjectToNamespacePointer(request[0]);
  RefCntReleaseScope<Namespace> rs(namespc);
  if ((request.Length() != 3) || !request[1]->IsUint8Array() ||
      !request[2]->IsInt32OrInt64()) {
    return CObject::IllegalArgumentError();
  }
  CObjectUint8Array filepath(request[1]);
  const int64_t millis = CObjectInt32OrInt64ToInt64(request[2]);
  return File::SetLastModified(
             namespc, reinterpret_cast<const char*>(filepath.Buffer()), millis)
             ? CObject::Null()
             : CObject::NewOSError();
}

CObject* File::FlushRequest(const CObjectArray& request) {
  if ((request.Length() < 1) || !request[0]->IsIntptr()) {
    return CObject::IllegalArgumentError();
  }
  File* file = CObjectToFilePointer(request[0]);
  RefCntReleaseScope<File> rs(file);
  if (file->IsClosed()) {
    return CObject::FileClosedError();
  }
  return file->Flush() ? CObject::True() : CObject::NewOSError();
}

CObject* File::ReadByteRequest(const CObjectArray& request) {
  if ((request.Length() < 1) || !request[0]->IsIntptr()) {
    return CObject::IllegalArgumentError();
  }
  File* file = CObjectToFilePointer(request[0]);
  RefCntReleaseScope<File> rs(file);
  if (file->IsClosed()) {
    return CObject::FileClosedError();
  }
  uint8_t buffer;
  const int64_t bytes_read = file->Read(reinterpret_cast<void*>(&buffer), 1);
  if (bytes_read < 0) {
    return CObject::NewOSError();
  }
  if (bytes_read == 0) {
    return new CObjectIntptr(CObject::NewIntptr(-1));
  }
  return new CObjectIntptr(CObject::NewIntptr(buffer));
}

CObject* File::WriteByteRequest(const CObjectArray& request) {
  if ((request.Length() < 1) || !request[0]->IsIntptr()) {
    return CObject::IllegalArgumentError();
  }
  File* file = CObjectToFilePointer(request[0]);
  RefCntReleaseScope<File> rs(file);
  if ((request.Length() != 2) || !request[1]->IsInt32OrInt64()) {
    return CObject::IllegalArgumentError();
  }
  if (file->IsClosed()) {
    return CObject::FileClosedError();
  }
  const int64_t byte = CObjectInt32OrInt64ToInt64(request[1]);
  uint8_t buffer = static_cast<uint8_t>(byte & 0xff);
  return file->WriteFully(reinterpret_cast<void*>(&buffer), 1)
             ? new CObjectInt64(CObject::NewInt64(1))
             : CObject::NewOSError();
}

CObject* File::ReadRequest(const CObjectArray& request) {
  if ((request.Length() < 1) || !request[0]->IsIntptr()) {
    return CObject::IllegalArgumentError();
  }
  File* file = CObjectToFilePointer(request[0]);
  RefCntReleaseScope<File> rs(file);
  if ((request.Length() != 2) || !request[1]->IsInt32OrInt64()) {
    return CObject::IllegalArgumentError();
  }
  if (file->IsClosed()) {
    return CObject::FileClosedError();
  }
  const int64_t length = CObjectInt32OrInt64ToInt64(request[1]);
  Dart_CObject* io_buffer = CObject::NewIOBuffer(length);
  if (io_buffer == nullptr) {
    return CObject::NewOSError();
  }
  uint8_t* data = io_buffer->value.as_external_typed_data.data;
  const int64_t bytes_read = file->Read(data, length);
  if (bytes_read < 0) {
    CObject* error = CObject::NewOSError();
    CObject::FreeIOBufferData(io_buffer);
    return error;
  }

  // Possibly shrink the used malloc() storage if the actual number of bytes is
  // significantly lower.
  CObject::ShrinkIOBuffer(io_buffer, bytes_read);

  auto external_array = new CObjectExternalUint8Array(io_buffer);
  CObjectArray* result = new CObjectArray(CObject::NewArray(2));
  result->SetAt(0, new CObjectIntptr(CObject::NewInt32(0)));
  result->SetAt(1, external_array);
  return result;
}

CObject* File::ReadIntoRequest(const CObjectArray& request) {
  if ((request.Length() < 1) || !request[0]->IsIntptr()) {
    return CObject::IllegalArgumentError();
  }
  File* file = CObjectToFilePointer(request[0]);
  RefCntReleaseScope<File> rs(file);
  if ((request.Length() != 2) || !request[1]->IsInt32OrInt64()) {
    return CObject::IllegalArgumentError();
  }
  if (file->IsClosed()) {
    return CObject::FileClosedError();
  }
  const int64_t length = CObjectInt32OrInt64ToInt64(request[1]);
  Dart_CObject* io_buffer = CObject::NewIOBuffer(length);
  if (io_buffer == nullptr) {
    return CObject::NewOSError();
  }
  uint8_t* data = io_buffer->value.as_external_typed_data.data;
  const int64_t bytes_read = file->Read(data, length);
  if (bytes_read < 0) {
    CObject* error = CObject::NewOSError();
    CObject::FreeIOBufferData(io_buffer);
    return error;
  }

  // Possibly shrink the used malloc() storage if the actual number of bytes is
  // significantly lower.
  CObject::ShrinkIOBuffer(io_buffer, bytes_read);

  auto external_array = new CObjectExternalUint8Array(io_buffer);
  CObjectArray* result = new CObjectArray(CObject::NewArray(3));
  result->SetAt(0, new CObjectIntptr(CObject::NewInt32(0)));
  result->SetAt(1, new CObjectInt64(CObject::NewInt64(bytes_read)));
  result->SetAt(2, external_array);
  return result;
}

static int SizeInBytes(Dart_TypedData_Type type) {
  switch (type) {
    case Dart_TypedData_kInt8:
    case Dart_TypedData_kUint8:
    case Dart_TypedData_kUint8Clamped:
      return 1;
    case Dart_TypedData_kInt16:
    case Dart_TypedData_kUint16:
      return 2;
    case Dart_TypedData_kInt32:
    case Dart_TypedData_kUint32:
    case Dart_TypedData_kFloat32:
      return 4;
    case Dart_TypedData_kInt64:
    case Dart_TypedData_kUint64:
    case Dart_TypedData_kFloat64:
      return 8;
    case Dart_TypedData_kInt32x4:
    case Dart_TypedData_kFloat32x4:
    case Dart_TypedData_kFloat64x2:
      return 16;
    default:
      break;
  }
  UNREACHABLE();
  return -1;
}

CObject* File::WriteFromRequest(const CObjectArray& request) {
  if ((request.Length() < 1) || !request[0]->IsIntptr()) {
    return CObject::IllegalArgumentError();
  }
  File* file = CObjectToFilePointer(request[0]);
  RefCntReleaseScope<File> rs(file);
  if ((request.Length() != 4) ||
      (!request[1]->IsTypedData() && !request[1]->IsArray()) ||
      !request[2]->IsInt32OrInt64() || !request[3]->IsInt32OrInt64()) {
    return CObject::IllegalArgumentError();
  }
  if (file->IsClosed()) {
    return CObject::FileClosedError();
  }
  int64_t start = CObjectInt32OrInt64ToInt64(request[2]);
  int64_t end = CObjectInt32OrInt64ToInt64(request[3]);
  int64_t length = end - start;
  const uint8_t* buffer_start;
  if (request[1]->IsTypedData()) {
    CObjectTypedData typed_data(request[1]);
    start = start * SizeInBytes(typed_data.Type());
    length = length * SizeInBytes(typed_data.Type());
    buffer_start = typed_data.Buffer() + start;
  } else {
    CObjectArray array(request[1]);
    uint8_t* allocated_buffer = Dart_ScopeAllocate(length);
    buffer_start = allocated_buffer;
    for (int i = 0; i < length; i++) {
      if (array[i + start]->IsInt32OrInt64()) {
        int64_t value = CObjectInt32OrInt64ToInt64(array[i + start]);
        allocated_buffer[i] = static_cast<uint8_t>(value & 0xFF);
      } else {
        // Unsupported type.
        return CObject::IllegalArgumentError();
      }
    }
    start = 0;
  }
  return file->WriteFully(reinterpret_cast<const void*>(buffer_start), length)
             ? new CObjectInt64(CObject::NewInt64(length))
             : CObject::NewOSError();
}

CObject* File::CreateLinkRequest(const CObjectArray& request) {
  if ((request.Length() != 3) || !request[0]->IsIntptr()) {
    return CObject::IllegalArgumentError();
  }
  Namespace* namespc = CObjectToNamespacePointer(request[0]);
  RefCntReleaseScope<Namespace> rs(namespc);
  if (!request[1]->IsUint8Array() || !request[2]->IsString()) {
    return CObject::IllegalArgumentError();
  }
  CObjectUint8Array link_name(request[1]);
  CObjectString target_name(request[2]);
  return File::CreateLink(namespc,
                          reinterpret_cast<const char*>(link_name.Buffer()),
                          target_name.CString())
             ? CObject::True()
             : CObject::NewOSError();
}

CObject* File::DeleteLinkRequest(const CObjectArray& request) {
  if ((request.Length() != 2) || !request[0]->IsIntptr()) {
    return CObject::IllegalArgumentError();
  }
  Namespace* namespc = CObjectToNamespacePointer(request[0]);
  RefCntReleaseScope<Namespace> rs(namespc);
  if (!request[1]->IsUint8Array()) {
    return CObject::IllegalArgumentError();
  }
  CObjectUint8Array link_path(request[1]);
  return File::DeleteLink(namespc,
                          reinterpret_cast<const char*>(link_path.Buffer()))
             ? CObject::True()
             : CObject::NewOSError();
}

CObject* File::RenameLinkRequest(const CObjectArray& request) {
  if ((request.Length() != 3) || !request[0]->IsIntptr()) {
    return CObject::IllegalArgumentError();
  }
  Namespace* namespc = CObjectToNamespacePointer(request[0]);
  RefCntReleaseScope<Namespace> rs(namespc);
  if (!request[1]->IsUint8Array() || !request[2]->IsString()) {
    return CObject::IllegalArgumentError();
  }
  CObjectUint8Array old_path(request[1]);
  CObjectString new_path(request[2]);
  return File::RenameLink(namespc,
                          reinterpret_cast<const char*>(old_path.Buffer()),
                          new_path.CString())
             ? CObject::True()
             : CObject::NewOSError();
}

CObject* File::LinkTargetRequest(const CObjectArray& request) {
  if ((request.Length() != 2) || !request[0]->IsIntptr()) {
    return CObject::IllegalArgumentError();
  }
  Namespace* namespc = CObjectToNamespacePointer(request[0]);
  RefCntReleaseScope<Namespace> rs(namespc);
  if (!request[1]->IsUint8Array()) {
    return CObject::IllegalArgumentError();
  }
  CObjectUint8Array link_path(request[1]);
  const char* target = File::LinkTarget(
      namespc, reinterpret_cast<const char*>(link_path.Buffer()));
  if (target == nullptr) {
    return CObject::NewOSError();
  }
  return new CObjectString(CObject::NewString(target));
}

CObject* File::TypeRequest(const CObjectArray& request) {
  if ((request.Length() != 3) || !request[0]->IsIntptr()) {
    return CObject::IllegalArgumentError();
  }
  Namespace* namespc = CObjectToNamespacePointer(request[0]);
  RefCntReleaseScope<Namespace> rs(namespc);
  if (!request[1]->IsUint8Array() || !request[2]->IsBool()) {
    return CObject::IllegalArgumentError();
  }
  CObjectUint8Array path(request[1]);
  CObjectBool follow_links(request[2]);
  File::Type type =
      File::GetType(namespc, reinterpret_cast<const char*>(path.Buffer()),
                    follow_links.Value());
  return new CObjectInt32(CObject::NewInt32(type));
}

CObject* File::IdenticalRequest(const CObjectArray& request) {
  if ((request.Length() != 3) || !request[0]->IsIntptr()) {
    return CObject::IllegalArgumentError();
  }
  Namespace* namespc = CObjectToNamespacePointer(request[0]);
  RefCntReleaseScope<Namespace> rs(namespc);
  if (!request[1]->IsString() || !request[2]->IsString()) {
    return CObject::IllegalArgumentError();
  }
  CObjectString path1(request[1]);
  CObjectString path2(request[2]);
  File::Identical result =
      File::AreIdentical(namespc, path1.CString(), namespc, path2.CString());
  if (result == File::kError) {
    return CObject::NewOSError();
  }
  return (result == File::kIdentical) ? CObject::True() : CObject::False();
}

CObject* File::StatRequest(const CObjectArray& request) {
  if ((request.Length() < 1) || !request[0]->IsIntptr()) {
    return CObject::IllegalArgumentError();
  }
  Namespace* namespc = CObjectToNamespacePointer(request[0]);
  RefCntReleaseScope<Namespace> rs(namespc);
  if ((request.Length() != 2) || !request[1]->IsString()) {
    return CObject::IllegalArgumentError();
  }
  int64_t data[File::kStatSize];
  CObjectString path(request[1]);
  File::Stat(namespc, path.CString(), data);
  if (data[File::kType] == File::kDoesNotExist) {
    return CObject::NewOSError();
  }
  CObjectArray* result = new CObjectArray(CObject::NewArray(File::kStatSize));
  for (int i = 0; i < File::kStatSize; ++i) {
    result->SetAt(i, new CObjectInt64(CObject::NewInt64(data[i])));
  }
  CObjectArray* wrapper = new CObjectArray(CObject::NewArray(2));
  wrapper->SetAt(0, new CObjectInt32(CObject::NewInt32(CObject::kSuccess)));
  wrapper->SetAt(1, result);
  return wrapper;
}

CObject* File::LockRequest(const CObjectArray& request) {
  if ((request.Length() < 1) || !request[0]->IsIntptr()) {
    return CObject::IllegalArgumentError();
  }
  File* file = CObjectToFilePointer(request[0]);
  RefCntReleaseScope<File> rs(file);
  if ((request.Length() != 4) || !request[1]->IsInt32OrInt64() ||
      !request[2]->IsInt32OrInt64() || !request[3]->IsInt32OrInt64()) {
    return CObject::IllegalArgumentError();
  }
  if (file->IsClosed()) {
    return CObject::FileClosedError();
  }
  const int64_t lock = CObjectInt32OrInt64ToInt64(request[1]);
  const int64_t start = CObjectInt32OrInt64ToInt64(request[2]);
  const int64_t end = CObjectInt32OrInt64ToInt64(request[3]);
  return file->Lock(static_cast<File::LockType>(lock), start, end)
             ? CObject::True()
             : CObject::NewOSError();
}

// Inspired by sdk/lib/core/uri.dart
UriDecoder::UriDecoder(const char* uri) : uri_(uri) {
  const char* ch = uri;
  while ((*ch != '\0') && (*ch != '%')) {
    ch++;
  }
  if (*ch == 0) {
    // if there are no '%', nothing to decode, refer to original as decoded.
    decoded_ = const_cast<char*>(uri);
    return;
  }
  const intptr_t len = strlen(uri);
  // Decoded string should be shorter than original because of
  // percent-encoding.
  char* dest = reinterpret_cast<char*>(malloc(len + 1));
  int i = ch - uri;
  // Copy all characters up to first '%' at index i.
  strncpy(dest, uri, i);
  decoded_ = dest;
  dest += i;
  while (*ch != '\0') {
    if (*ch != '%') {
      *(dest++) = *(ch++);
      continue;
    }
    if ((i + 3 > len) || !HexCharPairToByte(ch + 1, dest)) {
      free(decoded_);
      decoded_ = nullptr;
      return;
    }
    ++dest;
    ch += 3;
  }
  *dest = 0;
}

UriDecoder::~UriDecoder() {
  if (uri_ != decoded_ && decoded_ != nullptr) {
    free(decoded_);
  }
}

bool UriDecoder::HexCharPairToByte(const char* pch, char* const dest) {
  int byte = 0;
  for (int i = 0; i < 2; i++) {
    char char_code = *(pch + i);
    if (0x30 <= char_code && char_code <= 0x39) {
      byte = byte * 16 + char_code - 0x30;
    } else {
      // Check ranges A-F (0x41-0x46) and a-f (0x61-0x66).
      char_code |= 0x20;
      if (0x61 <= char_code && char_code <= 0x66) {
        byte = byte * 16 + char_code - 0x57;
      } else {
        return false;
      }
    }
  }
  *dest = byte;
  return true;
}

}  // namespace bin
}  // namespace dart
