//topaz/lib/tonic is moving to //third_party/tonic
Change-Id: Ida0ca4ea14882ff01f54eb10659f62760c0ec687
diff --git a/.clang-format b/.clang-format
deleted file mode 100644
index 6fdf1dc..0000000
--- a/.clang-format
+++ /dev/null
@@ -1,8 +0,0 @@
-# Defines the Chromium style for automatic reformatting.
-# http://clang.llvm.org/docs/ClangFormatStyleOptions.html
-BasedOnStyle: Chromium
-# This defaults to 'Auto'. Explicitly set it for a while, so that
-# 'vector<vector<int> >' in existing files gets formatted to
-# 'vector<vector<int>>'. ('Auto' means that clang-format will only use
-# 'int>>' if the file already contains at least one such instance.)
-Standard: Cpp11
diff --git a/BUILD.gn b/BUILD.gn
index e5edbd6..ebf350c 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -3,9 +3,7 @@
# found in the LICENSE file.
config("config") {
- include_dirs = [
- "//topaz",
- ]
+ include_dirs = [ "//third_party" ]
}
source_set("tonic") {
@@ -36,16 +34,15 @@
]
public_deps = [
+ "common",
+ "converter",
+ "file_loader",
+ "logging",
+ "platform",
+ "scopes",
+ "typed_data",
"//third_party/dart/runtime:dart_api",
- "//garnet/public/lib/fxl",
- "//topaz/lib/tonic/converter",
- "//topaz/lib/tonic/file_loader",
- "//topaz/lib/tonic/logging",
- "//topaz/lib/tonic/scopes",
- "//topaz/lib/tonic/typed_data",
]
- public_configs = [
- ":config",
- ]
+ public_configs = [ ":config" ]
}
diff --git a/common/BUILD.gn b/common/BUILD.gn
new file mode 100644
index 0000000..f7960bb
--- /dev/null
+++ b/common/BUILD.gn
@@ -0,0 +1,13 @@
+# Copyright 2018 The Fuchsia Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+source_set("common") {
+ visibility = [ "../*" ]
+
+ configs += [ "../:config" ]
+
+ sources = [
+ "macros.h",
+ ]
+}
diff --git a/common/build_config.h b/common/build_config.h
new file mode 100644
index 0000000..569347e
--- /dev/null
+++ b/common/build_config.h
@@ -0,0 +1,110 @@
+// Copyright 2016 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// This file adds defines about the platform we're currently building on.
+// Operating System:
+// OS_WIN / OS_MACOSX / OS_LINUX / OS_POSIX (MACOSX or LINUX) /
+// OS_NACL (NACL_SFI or NACL_NONSFI) / OS_NACL_SFI / OS_NACL_NONSFI
+// Compiler:
+// COMPILER_MSVC / COMPILER_GCC
+// Processor:
+// ARCH_CPU_X86 / ARCH_CPU_X86_64 / ARCH_CPU_X86_FAMILY (X86 or X86_64)
+// ARCH_CPU_32_BITS / ARCH_CPU_64_BITS
+
+#ifndef TONIC_COMMON_BUILD_CONFIG_H_
+#define TONIC_COMMON_BUILD_CONFIG_H_
+
+#if defined(__Fuchsia__)
+#define OS_FUCHSIA 1
+#elif defined(ANDROID)
+#define OS_ANDROID 1
+#elif defined(__APPLE__)
+// only include TargetConditions after testing ANDROID as some android builds
+// on mac don't have this header available and it's not needed unless the target
+// is really mac/ios.
+#include <TargetConditionals.h>
+#define OS_MACOSX 1
+#if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE
+#define OS_IOS 1
+#endif // defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE
+#elif defined(__linux__)
+#define OS_LINUX 1
+// include a system header to pull in features.h for glibc/uclibc macros.
+#include <unistd.h>
+#if defined(__GLIBC__) && !defined(__UCLIBC__)
+// we really are using glibc, not uClibc pretending to be glibc
+#define LIBC_GLIBC 1
+#endif
+#elif defined(_WIN32)
+#define OS_WIN 1
+#elif defined(__FreeBSD__)
+#define OS_FREEBSD 1
+#elif defined(__OpenBSD__)
+#define OS_OPENBSD 1
+#elif defined(__sun)
+#define OS_SOLARIS 1
+#elif defined(__QNXNTO__)
+#define OS_QNX 1
+#else
+#error Please add support for your platform in lib/fxl/build_config.h
+#endif
+
+// For access to standard BSD features, use OS_BSD instead of a
+// more specific macro.
+#if defined(OS_FREEBSD) || defined(OS_OPENBSD)
+#define OS_BSD 1
+#endif
+
+// For access to standard POSIXish features, use OS_POSIX instead of a
+// more specific macro.
+#if defined(OS_MACOSX) || defined(OS_LINUX) || defined(OS_FREEBSD) || \
+ defined(OS_OPENBSD) || defined(OS_SOLARIS) || defined(OS_ANDROID) || \
+ defined(OS_NACL) || defined(OS_QNX)
+#define OS_POSIX 1
+#endif
+
+// Processor architecture detection. For more info on what's defined, see:
+// http://msdn.microsoft.com/en-us/library/b0084kay.aspx
+// http://www.agner.org/optimize/calling_conventions.pdf
+// or with gcc, run: "echo | gcc -E -dM -"
+#if defined(_M_X64) || defined(__x86_64__)
+#define ARCH_CPU_X86_FAMILY 1
+#define ARCH_CPU_X86_64 1
+#define ARCH_CPU_64_BITS 1
+#define ARCH_CPU_LITTLE_ENDIAN 1
+#elif defined(_M_IX86) || defined(__i386__)
+#define ARCH_CPU_X86_FAMILY 1
+#define ARCH_CPU_X86 1
+#define ARCH_CPU_32_BITS 1
+#define ARCH_CPU_LITTLE_ENDIAN 1
+#elif defined(__ARMEL__)
+#define ARCH_CPU_ARM_FAMILY 1
+#define ARCH_CPU_ARMEL 1
+#define ARCH_CPU_32_BITS 1
+#define ARCH_CPU_LITTLE_ENDIAN 1
+#elif defined(__aarch64__)
+#define ARCH_CPU_ARM_FAMILY 1
+#define ARCH_CPU_ARM64 1
+#define ARCH_CPU_64_BITS 1
+#define ARCH_CPU_LITTLE_ENDIAN 1
+#elif defined(__pnacl__)
+#define ARCH_CPU_32_BITS 1
+#define ARCH_CPU_LITTLE_ENDIAN 1
+#elif defined(__MIPSEL__)
+#if defined(__LP64__)
+#define ARCH_CPU_MIPS64_FAMILY 1
+#define ARCH_CPU_MIPS64EL 1
+#define ARCH_CPU_64_BITS 1
+#define ARCH_CPU_LITTLE_ENDIAN 1
+#else
+#define ARCH_CPU_MIPS_FAMILY 1
+#define ARCH_CPU_MIPSEL 1
+#define ARCH_CPU_32_BITS 1
+#define ARCH_CPU_LITTLE_ENDIAN 1
+#endif
+#else
+#error Please add support for your architecture in build/build_config.h
+#endif
+
+#endif // TONIC_COMMON_BUILD_CONFIG_H_
diff --git a/common/files.h b/common/files.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/common/files.h
diff --git a/common/macros.h b/common/macros.h
new file mode 100644
index 0000000..9df29fc
--- /dev/null
+++ b/common/macros.h
@@ -0,0 +1,32 @@
+// Copyright 2018 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef TONIC_COMMON_MACROS_H_
+#define TONIC_COMMON_MACROS_H_
+
+#include <cassert>
+#include <cstdio>
+
+#define TONIC_DISALLOW_COPY(TypeName) TypeName(const TypeName &) = delete;
+
+#define TONIC_DISALLOW_ASSIGN(TypeName) \
+ void operator=(const TypeName &) = delete;
+
+#define TONIC_DISALLOW_COPY_AND_ASSIGN(TypeName) \
+ TONIC_DISALLOW_COPY(TypeName) \
+ TONIC_DISALLOW_ASSIGN(TypeName)
+
+#ifndef NDEBUG
+#define TONIC_DCHECK assert
+#else // NDEBUG
+#define TONIC_DCHECK (void)
+#endif // NDEBUG
+
+#define TONIC_CHECK assert
+
+#ifndef TONIC_LOG
+#define TONIC_LOG(message, ...) printf(message "\n", ##__VA_ARGS__);
+#endif // TONIC_LOG
+
+#endif // TONIC_COMMON_MACROS_H_
diff --git a/converter/BUILD.gn b/converter/BUILD.gn
index a1fc125..8c2fe1c 100644
--- a/converter/BUILD.gn
+++ b/converter/BUILD.gn
@@ -3,17 +3,20 @@
# found in the LICENSE file.
source_set("converter") {
+ visibility = [ "../*" ]
+
+ configs += [ "../:config" ]
+
sources = [
"dart_converter.cc",
"dart_converter.h",
]
- public_deps = [
- "//third_party/dart/runtime:dart_api",
- "//garnet/public/lib/fxl",
+ deps = [
+ "../common",
]
- public_configs = [
- "//topaz/lib/tonic:config",
+ public_deps = [
+ "//third_party/dart/runtime:dart_api",
]
}
diff --git a/converter/dart_converter.cc b/converter/dart_converter.cc
index 85251c9..ce58f0f 100644
--- a/converter/dart_converter.cc
+++ b/converter/dart_converter.cc
@@ -2,6 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "lib/tonic/converter/dart_converter.h"
+#include "tonic/converter/dart_converter.h"
// This file exists to ensure dart_converter.h doesn't miss any dependencies.
diff --git a/converter/dart_converter.h b/converter/dart_converter.h
index 0dc782a..a33d01e 100644
--- a/converter/dart_converter.h
+++ b/converter/dart_converter.h
@@ -9,14 +9,13 @@
#include <vector>
#include "third_party/dart/runtime/include/dart_api.h"
-#include "lib/fxl/logging.h"
+#include "tonic/common/macros.h"
namespace tonic {
// DartConvert converts types back and forth from Sky to Dart. The template
// parameter |T| determines what kind of type conversion to perform.
-template <typename T, typename Enable = void>
-struct DartConverter {};
+template <typename T, typename Enable = void> struct DartConverter {};
// This is to work around the fact that typedefs do not create new types. If you
// have a typedef, and want it to use a different converter, specialize this
@@ -28,8 +27,7 @@
// using ConverterType = ColorConverterType;
// using ValueType = ColorType;
// };
-template <typename T>
-struct DartConverterTypes {
+template <typename T> struct DartConverterTypes {
using ConverterType = T;
using ValueType = T;
};
@@ -37,8 +35,7 @@
////////////////////////////////////////////////////////////////////////////////
// Boolean
-template <>
-struct DartConverter<bool> {
+template <> struct DartConverter<bool> {
static Dart_Handle ToDart(bool val) { return Dart_NewBoolean(val); }
static void SetReturnValue(Dart_NativeArguments args, bool val) {
@@ -51,9 +48,8 @@
return result;
}
- static bool FromArguments(Dart_NativeArguments args,
- int index,
- Dart_Handle& exception) {
+ static bool FromArguments(Dart_NativeArguments args, int index,
+ Dart_Handle &exception) {
bool result = false;
Dart_GetNativeBooleanArgument(args, index, &result);
return result;
@@ -63,8 +59,7 @@
////////////////////////////////////////////////////////////////////////////////
// Numbers
-template <typename T>
-struct DartConverterInteger {
+template <typename T> struct DartConverterInteger {
static Dart_Handle ToDart(T val) { return Dart_NewInteger(val); }
static void SetReturnValue(Dart_NativeArguments args, T val) {
@@ -77,17 +72,15 @@
return static_cast<T>(result);
}
- static T FromArguments(Dart_NativeArguments args,
- int index,
- Dart_Handle& exception) {
+ static T FromArguments(Dart_NativeArguments args, int index,
+ Dart_Handle &exception) {
int64_t result = 0;
Dart_GetNativeIntegerArgument(args, index, &result);
return static_cast<T>(result);
}
};
-template <>
-struct DartConverter<int> : public DartConverterInteger<int> {};
+template <> struct DartConverter<int> : public DartConverterInteger<int> {};
template <>
struct DartConverter<long int> : public DartConverterInteger<long int> {};
@@ -102,8 +95,7 @@
struct DartConverter<unsigned long>
: public DartConverterInteger<unsigned long> {};
-template <>
-struct DartConverter<unsigned long long> {
+template <> struct DartConverter<unsigned long long> {
// TODO(abarth): The Dart VM API doesn't yet have an entry-point for
// an unsigned 64-bit type. We will need to add a Dart API for
// constructing an integer from uint64_t.
@@ -112,13 +104,13 @@
// converting values that have the 64th bit set.)
static Dart_Handle ToDart(unsigned long long val) {
- FXL_DCHECK(val <= 0x7fffffffffffffffLL);
+ TONIC_DCHECK(val <= 0x7fffffffffffffffLL);
return Dart_NewInteger(static_cast<int64_t>(val));
}
static void SetReturnValue(Dart_NativeArguments args,
unsigned long long val) {
- FXL_DCHECK(val <= 0x7fffffffffffffffLL);
+ TONIC_DCHECK(val <= 0x7fffffffffffffffLL);
Dart_SetIntegerReturnValue(args, val);
}
@@ -128,17 +120,15 @@
return result;
}
- static unsigned long long FromArguments(Dart_NativeArguments args,
- int index,
- Dart_Handle& exception) {
+ static unsigned long long FromArguments(Dart_NativeArguments args, int index,
+ Dart_Handle &exception) {
int64_t result = 0;
Dart_GetNativeIntegerArgument(args, index, &result);
return result;
}
};
-template <typename T>
-struct DartConverterFloatingPoint {
+template <typename T> struct DartConverterFloatingPoint {
static Dart_Handle ToDart(T val) { return Dart_NewDouble(val); }
static void SetReturnValue(Dart_NativeArguments args, T val) {
@@ -151,9 +141,8 @@
return result;
}
- static T FromArguments(Dart_NativeArguments args,
- int index,
- Dart_Handle& exception) {
+ static T FromArguments(Dart_NativeArguments args, int index,
+ Dart_Handle &exception) {
double result = 0;
Dart_GetNativeDoubleArgument(args, index, &result);
return result;
@@ -187,9 +176,8 @@
return static_cast<T>(result);
}
- static T FromArguments(Dart_NativeArguments args,
- int index,
- Dart_Handle& exception) {
+ static T FromArguments(Dart_NativeArguments args, int index,
+ Dart_Handle &exception) {
int64_t result = 0;
Dart_GetNativeIntegerArgument(args, index, &result);
return static_cast<T>(result);
@@ -199,42 +187,39 @@
////////////////////////////////////////////////////////////////////////////////
// Strings
-template <>
-struct DartConverter<std::string> {
- static Dart_Handle ToDart(const std::string& val) {
- return Dart_NewStringFromUTF8(reinterpret_cast<const uint8_t*>(val.data()),
+template <> struct DartConverter<std::string> {
+ static Dart_Handle ToDart(const std::string &val) {
+ return Dart_NewStringFromUTF8(reinterpret_cast<const uint8_t *>(val.data()),
val.length());
}
static void SetReturnValue(Dart_NativeArguments args,
- const std::string& val) {
+ const std::string &val) {
Dart_SetReturnValue(args, ToDart(val));
}
static std::string FromDart(Dart_Handle handle) {
- uint8_t* data = nullptr;
+ uint8_t *data = nullptr;
intptr_t length = 0;
;
Dart_StringToUTF8(handle, &data, &length);
- return std::string(reinterpret_cast<char*>(data), length);
+ return std::string(reinterpret_cast<char *>(data), length);
}
- static std::string FromArguments(Dart_NativeArguments args,
- int index,
- Dart_Handle& exception) {
+ static std::string FromArguments(Dart_NativeArguments args, int index,
+ Dart_Handle &exception) {
return FromDart(Dart_GetNativeArgument(args, index));
}
};
-template <>
-struct DartConverter<std::u16string> {
- static Dart_Handle ToDart(const std::u16string& val) {
+template <> struct DartConverter<std::u16string> {
+ static Dart_Handle ToDart(const std::u16string &val) {
return Dart_NewStringFromUTF16(
- reinterpret_cast<const uint16_t*>(val.data()), val.length());
+ reinterpret_cast<const uint16_t *>(val.data()), val.length());
}
static void SetReturnValue(Dart_NativeArguments args,
- const std::u16string& val) {
+ const std::u16string &val) {
Dart_SetReturnValue(args, ToDart(val));
}
@@ -243,35 +228,32 @@
Dart_StringLength(handle, &length);
std::vector<uint16_t> data(length);
Dart_StringToUTF16(handle, data.data(), &length);
- return std::u16string(reinterpret_cast<char16_t*>(data.data()), length);
+ return std::u16string(reinterpret_cast<char16_t *>(data.data()), length);
}
- static std::u16string FromArguments(Dart_NativeArguments args,
- int index,
- Dart_Handle& exception) {
+ static std::u16string FromArguments(Dart_NativeArguments args, int index,
+ Dart_Handle &exception) {
return FromDart(Dart_GetNativeArgument(args, index));
}
};
-template <>
-struct DartConverter<const char*> {
- static Dart_Handle ToDart(const char* val) {
+template <> struct DartConverter<const char *> {
+ static Dart_Handle ToDart(const char *val) {
return Dart_NewStringFromCString(val);
}
- static void SetReturnValue(Dart_NativeArguments args, const char* val) {
+ static void SetReturnValue(Dart_NativeArguments args, const char *val) {
Dart_SetReturnValue(args, ToDart(val));
}
- static const char* FromDart(Dart_Handle handle) {
- const char* result = nullptr;
+ static const char *FromDart(Dart_Handle handle) {
+ const char *result = nullptr;
Dart_StringToCString(handle, &result);
return result;
}
- static const char* FromArguments(Dart_NativeArguments args,
- int index,
- Dart_Handle& exception) {
+ static const char *FromArguments(Dart_NativeArguments args, int index,
+ Dart_Handle &exception) {
return FromDart(Dart_GetNativeArgument(args, index));
}
};
@@ -279,13 +261,16 @@
////////////////////////////////////////////////////////////////////////////////
// Collections
-template <typename T>
-struct DartConverter<std::vector<T>> {
+template <typename T, typename Enable = void> struct DartListFactory {
+ static Dart_Handle NewList(intptr_t length) { return Dart_NewList(length); }
+};
+
+template <typename T> struct DartConverter<std::vector<T>> {
using ValueType = typename DartConverterTypes<T>::ValueType;
using ConverterType = typename DartConverterTypes<T>::ConverterType;
- static Dart_Handle ToDart(const std::vector<ValueType>& val) {
- Dart_Handle list = Dart_NewList(val.size());
+ static Dart_Handle ToDart(const std::vector<ValueType> &val) {
+ Dart_Handle list = DartListFactory<ValueType>::NewList(val.size());
if (Dart_IsError(list))
return list;
for (size_t i = 0; i < val.size(); i++) {
@@ -298,7 +283,7 @@
}
static void SetReturnValue(Dart_NativeArguments args,
- const std::vector<ValueType>& val) {
+ const std::vector<ValueType> &val) {
Dart_SetReturnValue(args, ToDart(val));
}
@@ -319,18 +304,17 @@
std::vector<Dart_Handle> items(length);
Dart_Handle items_result =
Dart_ListGetRange(handle, 0, length, items.data());
- FXL_DCHECK(!Dart_IsError(items_result));
+ TONIC_DCHECK(!Dart_IsError(items_result));
for (intptr_t i = 0; i < length; ++i) {
- FXL_DCHECK(items[i]);
+ TONIC_DCHECK(items[i]);
result.push_back(DartConverter<ConverterType>::FromDart(items[i]));
}
return result;
}
- static std::vector<ValueType> FromArguments(Dart_NativeArguments args,
- int index,
- Dart_Handle& exception) {
+ static std::vector<ValueType>
+ FromArguments(Dart_NativeArguments args, int index, Dart_Handle &exception) {
return FromDart(Dart_GetNativeArgument(args, index));
}
};
@@ -338,8 +322,7 @@
////////////////////////////////////////////////////////////////////////////////
// Dart_Handle
-template <>
-struct DartConverter<Dart_Handle> {
+template <> struct DartConverter<Dart_Handle> {
static Dart_Handle ToDart(Dart_Handle val) { return val; }
static void SetReturnValue(Dart_NativeArguments args, Dart_Handle val) {
@@ -348,9 +331,8 @@
static Dart_Handle FromDart(Dart_Handle handle) { return handle; }
- static Dart_Handle FromArguments(Dart_NativeArguments args,
- int index,
- Dart_Handle& exception) {
+ static Dart_Handle FromArguments(Dart_NativeArguments args, int index,
+ Dart_Handle &exception) {
return Dart_GetNativeArgument(args, index);
}
};
@@ -358,15 +340,14 @@
////////////////////////////////////////////////////////////////////////////////
// Convience wrappers using type inference
-template <typename T>
-Dart_Handle ToDart(const T& object) {
+template <typename T> Dart_Handle ToDart(const T &object) {
return DartConverter<T>::ToDart(object);
}
////////////////////////////////////////////////////////////////////////////////
// std::string support
-inline Dart_Handle StdStringToDart(const std::string& val) {
+inline Dart_Handle StdStringToDart(const std::string &val) {
return DartConverter<std::string>::ToDart(val);
}
@@ -375,10 +356,10 @@
}
// Alias Dart_NewStringFromCString for less typing.
-inline Dart_Handle ToDart(const char* val) {
+inline Dart_Handle ToDart(const char *val) {
return Dart_NewStringFromCString(val);
}
-} // namespace tonic
+} // namespace tonic
-#endif // LIB_CONVERTER_TONIC_DART_CONVERTER_H_
+#endif // LIB_CONVERTER_TONIC_DART_CONVERTER_H_
diff --git a/dart_args.h b/dart_args.h
index 31b194f..63972c0 100644
--- a/dart_args.h
+++ b/dart_args.h
@@ -9,18 +9,17 @@
#include <utility>
#include "third_party/dart/runtime/include/dart_api.h"
-#include "lib/tonic/converter/dart_converter.h"
-#include "lib/tonic/dart_wrappable.h"
+#include "tonic/converter/dart_converter.h"
+#include "tonic/dart_wrappable.h"
namespace tonic {
class DartArgIterator {
- public:
+public:
DartArgIterator(Dart_NativeArguments args, int start_index = 1)
: args_(args), index_(start_index), had_exception_(false) {}
- template <typename T>
- T GetNext() {
+ template <typename T> T GetNext() {
if (had_exception_)
return T();
Dart_Handle exception = nullptr;
@@ -36,33 +35,28 @@
Dart_NativeArguments args() const { return args_; }
- private:
+private:
Dart_NativeArguments args_;
int index_;
bool had_exception_;
- FXL_DISALLOW_COPY_AND_ASSIGN(DartArgIterator);
+ TONIC_DISALLOW_COPY_AND_ASSIGN(DartArgIterator);
};
// Classes for generating and storing an argument pack of integer indices
// (based on well-known "indices trick", see: http://goo.gl/bKKojn):
-template <size_t... indices>
-struct IndicesHolder {};
+template <size_t... indices> struct IndicesHolder {};
-template <size_t requested_index, size_t... indices>
-struct IndicesGenerator {
+template <size_t requested_index, size_t... indices> struct IndicesGenerator {
using type = typename IndicesGenerator<requested_index - 1,
- requested_index - 1,
- indices...>::type;
+ requested_index - 1, indices...>::type;
};
-template <size_t... indices>
-struct IndicesGenerator<0, indices...> {
+template <size_t... indices> struct IndicesGenerator<0, indices...> {
using type = IndicesHolder<indices...>;
};
-template <typename T>
-class IndicesForSignature {};
+template <typename T> class IndicesForSignature {};
template <typename ResultType, typename... ArgTypes>
struct IndicesForSignature<ResultType (*)(ArgTypes...)> {
@@ -82,33 +76,30 @@
using type = typename IndicesGenerator<count>::type;
};
-template <size_t index, typename ArgType>
-struct DartArgHolder {
+template <size_t index, typename ArgType> struct DartArgHolder {
using ValueType = typename std::remove_const<
typename std::remove_reference<ArgType>::type>::type;
ValueType value;
- explicit DartArgHolder(DartArgIterator* it)
+ explicit DartArgHolder(DartArgIterator *it)
: value(it->GetNext<ValueType>()) {}
};
-template <typename T>
-void DartReturn(T result, Dart_NativeArguments args) {
+template <typename T> void DartReturn(T result, Dart_NativeArguments args) {
DartConverter<T>::SetReturnValue(args, std::move(result));
}
-template <typename IndicesType, typename T>
-class DartDispatcher {};
+template <typename IndicesType, typename T> class DartDispatcher {};
template <size_t... indices, typename... ArgTypes>
struct DartDispatcher<IndicesHolder<indices...>, void (*)(ArgTypes...)>
: public DartArgHolder<indices, ArgTypes>... {
using FunctionPtr = void (*)(ArgTypes...);
- DartArgIterator* it_;
+ DartArgIterator *it_;
- explicit DartDispatcher(DartArgIterator* it)
+ explicit DartDispatcher(DartArgIterator *it)
: DartArgHolder<indices, ArgTypes>(it)..., it_(it) {}
void Dispatch(FunctionPtr func) {
@@ -121,9 +112,9 @@
: public DartArgHolder<indices, ArgTypes>... {
using FunctionPtr = ResultType (*)(ArgTypes...);
- DartArgIterator* it_;
+ DartArgIterator *it_;
- explicit DartDispatcher(DartArgIterator* it)
+ explicit DartDispatcher(DartArgIterator *it)
: DartArgHolder<indices, ArgTypes>(it)..., it_(it) {}
void Dispatch(FunctionPtr func) {
@@ -141,9 +132,9 @@
: public DartArgHolder<indices, ArgTypes>... {
using FunctionPtr = void (C::*)(ArgTypes...);
- DartArgIterator* it_;
+ DartArgIterator *it_;
- explicit DartDispatcher(DartArgIterator* it)
+ explicit DartDispatcher(DartArgIterator *it)
: DartArgHolder<indices, ArgTypes>(it)..., it_(it) {}
void Dispatch(FunctionPtr func) {
@@ -152,33 +143,16 @@
}
};
-template <size_t... indices, typename C, typename ReturnType, typename... ArgTypes>
-struct DartDispatcher<IndicesHolder<indices...>, ReturnType (C::*)(ArgTypes...) const>
+template <size_t... indices, typename C, typename ReturnType,
+ typename... ArgTypes>
+struct DartDispatcher<IndicesHolder<indices...>,
+ ReturnType (C::*)(ArgTypes...) const>
: public DartArgHolder<indices, ArgTypes>... {
using FunctionPtr = ReturnType (C::*)(ArgTypes...) const;
- DartArgIterator* it_;
+ DartArgIterator *it_;
- explicit DartDispatcher(DartArgIterator* it)
- : DartArgHolder<indices, ArgTypes>(it)..., it_(it) {}
-
- void Dispatch(FunctionPtr func) {
- DartReturn((GetReceiver<C>(it_->args())->*func)(
- DartArgHolder<indices, ArgTypes>::value...), it_->args());
- }
-};
-
-template <size_t... indices,
- typename C,
- typename ResultType,
- typename... ArgTypes>
-struct DartDispatcher<IndicesHolder<indices...>, ResultType (C::*)(ArgTypes...)>
- : public DartArgHolder<indices, ArgTypes>... {
- using FunctionPtr = ResultType (C::*)(ArgTypes...);
-
- DartArgIterator* it_;
-
- explicit DartDispatcher(DartArgIterator* it)
+ explicit DartDispatcher(DartArgIterator *it)
: DartArgHolder<indices, ArgTypes>(it)..., it_(it) {}
void Dispatch(FunctionPtr func) {
@@ -188,8 +162,25 @@
}
};
-template <typename Sig>
-void DartCall(Sig func, Dart_NativeArguments args) {
+template <size_t... indices, typename C, typename ResultType,
+ typename... ArgTypes>
+struct DartDispatcher<IndicesHolder<indices...>, ResultType (C::*)(ArgTypes...)>
+ : public DartArgHolder<indices, ArgTypes>... {
+ using FunctionPtr = ResultType (C::*)(ArgTypes...);
+
+ DartArgIterator *it_;
+
+ explicit DartDispatcher(DartArgIterator *it)
+ : DartArgHolder<indices, ArgTypes>(it)..., it_(it) {}
+
+ void Dispatch(FunctionPtr func) {
+ DartReturn((GetReceiver<C>(it_->args())->*func)(
+ DartArgHolder<indices, ArgTypes>::value...),
+ it_->args());
+ }
+};
+
+template <typename Sig> void DartCall(Sig func, Dart_NativeArguments args) {
DartArgIterator it(args);
using Indices = typename IndicesForSignature<Sig>::type;
DartDispatcher<Indices, Sig> decoder(&it);
@@ -218,6 +209,6 @@
decoder.DispatchCtor(func)->AssociateWithDartWrapper(args);
}
-} // namespace tonic
+} // namespace tonic
-#endif // LIB_TONIC_DART_ARGS_H_
+#endif // LIB_TONIC_DART_ARGS_H_
diff --git a/dart_binding_macros.h b/dart_binding_macros.h
index 2d4488d..e127567 100644
--- a/dart_binding_macros.h
+++ b/dart_binding_macros.h
@@ -5,32 +5,32 @@
#ifndef LIB_TONIC_DART_BINDING_MACROS_H_
#define LIB_TONIC_DART_BINDING_MACROS_H_
-#include "lib/tonic/dart_args.h"
+#include "tonic/dart_args.h"
-#define DART_NATIVE_CALLBACK(CLASS, METHOD) \
- static void CLASS##_##METHOD(Dart_NativeArguments args) { \
- tonic::DartCall(&CLASS::METHOD, args); \
+#define DART_NATIVE_CALLBACK(CLASS, METHOD) \
+ static void CLASS##_##METHOD(Dart_NativeArguments args) { \
+ tonic::DartCall(&CLASS::METHOD, args); \
}
-#define DART_NATIVE_CALLBACK_STATIC(CLASS, METHOD) \
- static void CLASS##_##METHOD(Dart_NativeArguments args) { \
- tonic::DartCallStatic(&CLASS::METHOD, args); \
+#define DART_NATIVE_CALLBACK_STATIC(CLASS, METHOD) \
+ static void CLASS##_##METHOD(Dart_NativeArguments args) { \
+ tonic::DartCallStatic(&CLASS::METHOD, args); \
}
-#define DART_REGISTER_NATIVE(CLASS, METHOD) \
- {#CLASS "_" #METHOD, CLASS##_##METHOD, \
+#define DART_REGISTER_NATIVE(CLASS, METHOD) \
+ {#CLASS "_" #METHOD, CLASS##_##METHOD, \
tonic::IndicesForSignature<decltype(&CLASS::METHOD)>::count + 1, true},
-#define DART_REGISTER_NATIVE_STATIC(CLASS, METHOD) \
- { \
- #CLASS "_" #METHOD, CLASS##_##METHOD, \
- tonic::IndicesForSignature < decltype(&CLASS::METHOD) > ::count, true \
+#define DART_REGISTER_NATIVE_STATIC(CLASS, METHOD) \
+ { \
+#CLASS "_" #METHOD, CLASS##_##METHOD, \
+ tonic::IndicesForSignature < decltype(&CLASS::METHOD) > ::count, true \
}
-#define DART_BIND_ALL(CLASS, FOR_EACH) \
- FOR_EACH(DART_NATIVE_CALLBACK) \
- void CLASS::RegisterNatives(tonic::DartLibraryNatives* natives) { \
- natives->Register({FOR_EACH(DART_REGISTER_NATIVE)}); \
+#define DART_BIND_ALL(CLASS, FOR_EACH) \
+ FOR_EACH(DART_NATIVE_CALLBACK) \
+ void CLASS::RegisterNatives(tonic::DartLibraryNatives *natives) { \
+ natives->Register({FOR_EACH(DART_REGISTER_NATIVE)}); \
}
-#endif // LIB_TONIC_DART_BINDING_MACROS_H_
+#endif // LIB_TONIC_DART_BINDING_MACROS_H_
diff --git a/dart_class_library.cc b/dart_class_library.cc
index cc4eb83..c846ce6 100644
--- a/dart_class_library.cc
+++ b/dart_class_library.cc
@@ -2,10 +2,10 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "lib/tonic/dart_class_library.h"
+#include "tonic/dart_class_library.h"
-#include "lib/fxl/logging.h"
-#include "lib/tonic/dart_wrapper_info.h"
+#include "tonic/common/macros.h"
+#include "tonic/dart_wrapper_info.h"
namespace tonic {
@@ -17,8 +17,8 @@
// isolate dies.
}
-Dart_PersistentHandle DartClassLibrary::GetClass(const DartWrapperInfo& info) {
- const auto& result = info_cache_.insert(std::make_pair(&info, nullptr));
+Dart_PersistentHandle DartClassLibrary::GetClass(const DartWrapperInfo &info) {
+ const auto &result = info_cache_.insert(std::make_pair(&info, nullptr));
if (!result.second) {
// Already present, return value.
return result.first->second;
@@ -27,11 +27,11 @@
&result.first->second);
}
-Dart_PersistentHandle DartClassLibrary::GetClass(
- const std::string& library_name,
- const std::string& interface_name) {
+Dart_PersistentHandle
+DartClassLibrary::GetClass(const std::string &library_name,
+ const std::string &interface_name) {
auto key = std::make_pair(library_name, interface_name);
- const auto& result = name_cache_.insert(std::make_pair(key, nullptr));
+ const auto &result = name_cache_.insert(std::make_pair(key, nullptr));
if (!result.second) {
// Already present, return value.
return result.first->second;
@@ -40,16 +40,16 @@
&result.first->second);
}
-Dart_PersistentHandle DartClassLibrary::GetAndCacheClass(
- const char* library_name,
- const char* interface_name,
- Dart_PersistentHandle* cache_slot) {
+Dart_PersistentHandle
+DartClassLibrary::GetAndCacheClass(const char *library_name,
+ const char *interface_name,
+ Dart_PersistentHandle *cache_slot) {
auto it = providers_.find(library_name);
- FXL_DCHECK(it != providers_.end());
+ TONIC_DCHECK(it != providers_.end());
Dart_Handle class_handle = it->second->GetClassByName(interface_name);
*cache_slot = Dart_NewPersistentHandle(class_handle);
return *cache_slot;
}
-} // namespace tonic
+} // namespace tonic
diff --git a/dart_class_library.h b/dart_class_library.h
index 5d45f23..40a0216 100644
--- a/dart_class_library.h
+++ b/dart_class_library.h
@@ -6,55 +6,55 @@
#define LIB_TONIC_DART_CLASS_LIBRARY_H_
#include <memory>
+#include <string>
#include <unordered_map>
#include "third_party/dart/runtime/include/dart_api.h"
-#include "lib/fxl/macros.h"
-#include "lib/tonic/dart_class_provider.h"
+#include "tonic/dart_class_provider.h"
namespace tonic {
struct DartWrapperInfo;
class DartClassLibrary {
- public:
+public:
explicit DartClassLibrary();
~DartClassLibrary();
- void add_provider(const std::string& library_name,
+ void add_provider(const std::string &library_name,
std::unique_ptr<DartClassProvider> provider) {
providers_.insert(std::make_pair(library_name, std::move(provider)));
}
- Dart_PersistentHandle GetClass(const DartWrapperInfo& info);
- Dart_PersistentHandle GetClass(const std::string& library_name,
- const std::string& interface_name);
+ Dart_PersistentHandle GetClass(const DartWrapperInfo &info);
+ Dart_PersistentHandle GetClass(const std::string &library_name,
+ const std::string &interface_name);
- private:
- Dart_PersistentHandle GetAndCacheClass(const char* library_name,
- const char* interface_name,
- Dart_PersistentHandle* cache_slot);
+private:
+ Dart_PersistentHandle GetAndCacheClass(const char *library_name,
+ const char *interface_name,
+ Dart_PersistentHandle *cache_slot);
// TODO(abarth): Move this class somewhere more general.
// We should also use a more reasonable hash function, such as described in
// http://www.boost.org/doc/libs/1_35_0/doc/html/boost/hash_combine_id241013.html
struct PairHasher {
template <typename T, typename U>
- std::size_t operator()(const std::pair<T, U>& pair) const {
+ std::size_t operator()(const std::pair<T, U> &pair) const {
return std::hash<T>()(pair.first) + 37 * std::hash<U>()(pair.second);
}
};
std::unordered_map<std::string, std::unique_ptr<DartClassProvider>>
providers_;
- std::unordered_map<const DartWrapperInfo*, Dart_PersistentHandle> info_cache_;
- std::unordered_map<std::pair<std::string, std::string>,
- Dart_PersistentHandle,
+ std::unordered_map<const DartWrapperInfo *, Dart_PersistentHandle>
+ info_cache_;
+ std::unordered_map<std::pair<std::string, std::string>, Dart_PersistentHandle,
PairHasher>
name_cache_;
- FXL_DISALLOW_COPY_AND_ASSIGN(DartClassLibrary);
+ TONIC_DISALLOW_COPY_AND_ASSIGN(DartClassLibrary);
};
-} // namespace tonic
+} // namespace tonic
-#endif // LIB_TONIC_DART_CLASS_LIBRARY_H_
+#endif // LIB_TONIC_DART_CLASS_LIBRARY_H_
diff --git a/dart_class_provider.cc b/dart_class_provider.cc
index e4da4e5..361eaef 100644
--- a/dart_class_provider.cc
+++ b/dart_class_provider.cc
@@ -2,28 +2,27 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "lib/tonic/dart_class_provider.h"
+#include "tonic/dart_class_provider.h"
-#include "lib/tonic/converter/dart_converter.h"
-#include "lib/tonic/logging/dart_error.h"
-#include "lib/tonic/dart_state.h"
+#include "tonic/converter/dart_converter.h"
+#include "tonic/dart_state.h"
+#include "tonic/logging/dart_error.h"
namespace tonic {
-DartClassProvider::DartClassProvider(DartState* dart_state,
- const char* class_name) {
+DartClassProvider::DartClassProvider(DartState *dart_state,
+ const char *class_name) {
library_.Set(dart_state, Dart_LookupLibrary(ToDart(class_name)));
}
DartClassProvider::~DartClassProvider() {}
-Dart_Handle DartClassProvider::GetClassByName(const char* class_name) {
+Dart_Handle DartClassProvider::GetClassByName(const char *class_name) {
Dart_Handle name_handle = ToDart(class_name);
Dart_Handle class_handle =
Dart_GetType(library_.value(), name_handle, 0, nullptr);
- FXL_DCHECK(!Dart_IsError(class_handle)) << class_name << ": "
- << Dart_GetError(class_handle);
+ TONIC_DCHECK(!Dart_IsError(class_handle));
return class_handle;
}
-} // namespace tonic
+} // namespace tonic
diff --git a/dart_class_provider.h b/dart_class_provider.h
index d51a40f..3d9bab1 100644
--- a/dart_class_provider.h
+++ b/dart_class_provider.h
@@ -5,26 +5,25 @@
#ifndef LIB_TONIC_DART_CLASS_PROVIDER_H_
#define LIB_TONIC_DART_CLASS_PROVIDER_H_
-#include "lib/fxl/macros.h"
#include "third_party/dart/runtime/include/dart_api.h"
-#include "lib/tonic/dart_persistent_value.h"
+#include "tonic/dart_persistent_value.h"
namespace tonic {
class DartState;
class DartClassProvider {
- public:
- DartClassProvider(DartState* dart_state, const char* library_name);
+public:
+ DartClassProvider(DartState *dart_state, const char *library_name);
~DartClassProvider();
- Dart_Handle GetClassByName(const char* class_name);
+ Dart_Handle GetClassByName(const char *class_name);
- private:
+private:
DartPersistentValue library_;
- FXL_DISALLOW_COPY_AND_ASSIGN(DartClassProvider);
+ TONIC_DISALLOW_COPY_AND_ASSIGN(DartClassProvider);
};
-} // namespace tonic
+} // namespace tonic
-#endif // LIB_TONIC_DART_CLASS_PROVIDER_H_
+#endif // LIB_TONIC_DART_CLASS_PROVIDER_H_
diff --git a/dart_library_natives.cc b/dart_library_natives.cc
index 3627519..379e299 100644
--- a/dart_library_natives.cc
+++ b/dart_library_natives.cc
@@ -2,9 +2,9 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "lib/tonic/dart_library_natives.h"
+#include "tonic/dart_library_natives.h"
-#include "lib/tonic/converter/dart_converter.h"
+#include "tonic/converter/dart_converter.h"
namespace tonic {
@@ -13,33 +13,32 @@
DartLibraryNatives::~DartLibraryNatives() {}
void DartLibraryNatives::Register(std::initializer_list<Entry> entries) {
- for (const Entry& entry : entries) {
+ for (const Entry &entry : entries) {
symbols_.emplace(entry.native_function, entry.symbol);
entries_.emplace(entry.symbol, entry);
}
}
-Dart_NativeFunction DartLibraryNatives::GetNativeFunction(
- Dart_Handle name,
- int argument_count,
- bool* auto_setup_scope) {
+Dart_NativeFunction
+DartLibraryNatives::GetNativeFunction(Dart_Handle name, int argument_count,
+ bool *auto_setup_scope) {
std::string name_string = StdStringFromDart(name);
auto it = entries_.find(name_string);
if (it == entries_.end())
return nullptr;
- const Entry& entry = it->second;
+ const Entry &entry = it->second;
if (entry.argument_count != argument_count)
return nullptr;
*auto_setup_scope = entry.auto_setup_scope;
return entry.native_function;
}
-const uint8_t* DartLibraryNatives::GetSymbol(
- Dart_NativeFunction native_function) {
+const uint8_t *
+DartLibraryNatives::GetSymbol(Dart_NativeFunction native_function) {
auto it = symbols_.find(native_function);
if (it == symbols_.end())
return nullptr;
- return reinterpret_cast<const uint8_t*>(it->second);
+ return reinterpret_cast<const uint8_t *>(it->second);
}
-} // namespace tonic
+} // namespace tonic
diff --git a/dart_library_natives.h b/dart_library_natives.h
index cf15d5a..18bfb34 100644
--- a/dart_library_natives.h
+++ b/dart_library_natives.h
@@ -5,22 +5,22 @@
#ifndef LIB_TONIC_DART_LIBRARY_NATIVES_H_
#define LIB_TONIC_DART_LIBRARY_NATIVES_H_
+#include <initializer_list>
#include <string>
#include <unordered_map>
-#include <initializer_list>
-#include "lib/fxl/logging.h"
#include "third_party/dart/runtime/include/dart_api.h"
+#include "tonic/common/macros.h"
namespace tonic {
class DartLibraryNatives {
- public:
+public:
DartLibraryNatives();
~DartLibraryNatives();
struct Entry {
- const char* symbol;
+ const char *symbol;
Dart_NativeFunction native_function;
int argument_count;
bool auto_setup_scope;
@@ -28,18 +28,17 @@
void Register(std::initializer_list<Entry> entries);
- Dart_NativeFunction GetNativeFunction(Dart_Handle name,
- int argument_count,
- bool* auto_setup_scope);
- const uint8_t* GetSymbol(Dart_NativeFunction native_function);
+ Dart_NativeFunction GetNativeFunction(Dart_Handle name, int argument_count,
+ bool *auto_setup_scope);
+ const uint8_t *GetSymbol(Dart_NativeFunction native_function);
- private:
+private:
std::unordered_map<std::string, Entry> entries_;
- std::unordered_map<Dart_NativeFunction, const char*> symbols_;
+ std::unordered_map<Dart_NativeFunction, const char *> symbols_;
- FXL_DISALLOW_COPY_AND_ASSIGN(DartLibraryNatives);
+ TONIC_DISALLOW_COPY_AND_ASSIGN(DartLibraryNatives);
};
-} // namespace tonic
+} // namespace tonic
-#endif // LIB_TONIC_DART_LIBRARY_NATIVES_H_
+#endif // LIB_TONIC_DART_LIBRARY_NATIVES_H_
diff --git a/dart_list.cc b/dart_list.cc
index acc8972..fa2bd06 100644
--- a/dart_list.cc
+++ b/dart_list.cc
@@ -2,14 +2,14 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "lib/tonic/dart_list.h"
+#include "tonic/dart_list.h"
-#include "lib/tonic/logging/dart_error.h"
+#include "tonic/logging/dart_error.h"
namespace tonic {
DartList::DartList(Dart_Handle dart_handle) : dart_handle_(dart_handle) {
- FXL_DCHECK(Dart_IsList(dart_handle_));
+ TONIC_DCHECK(Dart_IsList(dart_handle_));
intptr_t length;
is_valid_ = !LogIfError(Dart_ListLength(dart_handle_, &length));
@@ -22,9 +22,8 @@
is_valid_ = false;
}
-DartList::DartList(DartList&& other)
- : dart_handle_(other.dart_handle_),
- size_(other.size_),
+DartList::DartList(DartList &&other)
+ : dart_handle_(other.dart_handle_), size_(other.size_),
is_valid_(other.is_valid_) {
other.dart_handle_ = nullptr;
other.size_ = 0;
@@ -37,7 +36,7 @@
DartList DartConverter<DartList>::FromArguments(Dart_NativeArguments args,
int index,
- Dart_Handle& exception) {
+ Dart_Handle &exception) {
Dart_Handle list = Dart_GetNativeArgument(args, index);
if (LogIfError(list) || !Dart_IsList(list)) {
exception = Dart_NewApiError("Invalid Argument");
@@ -47,4 +46,4 @@
return DartList(list);
}
-} // namespace tonic
+} // namespace tonic
diff --git a/dart_list.h b/dart_list.h
index 67a5ec7..392eed3 100644
--- a/dart_list.h
+++ b/dart_list.h
@@ -8,24 +8,22 @@
#include <stddef.h>
#include "third_party/dart/runtime/include/dart_api.h"
-#include "lib/tonic/converter/dart_converter.h"
+#include "tonic/converter/dart_converter.h"
namespace tonic {
class DartList {
- public:
- DartList(DartList&& other);
+public:
+ DartList(DartList &&other);
void Set(size_t index, Dart_Handle value);
Dart_Handle Get(size_t index);
- template <class T>
- void Set(size_t index, T value) {
+ template <class T> void Set(size_t index, T value) {
Set(index, DartConverter<T>::ToDart(value));
}
- template <class T>
- T Get(size_t index) {
+ template <class T> T Get(size_t index) {
return DartConverter<T>::FromDart(Get(index));
}
@@ -35,7 +33,7 @@
explicit operator bool() const { return is_valid_; }
- private:
+private:
explicit DartList(Dart_Handle list);
friend struct DartConverter<DartList>;
@@ -44,16 +42,14 @@
size_t size_;
bool is_valid_;
- DartList(const DartList& other) = delete;
+ DartList(const DartList &other) = delete;
};
-template <>
-struct DartConverter<DartList> {
- static DartList FromArguments(Dart_NativeArguments args,
- int index,
- Dart_Handle& exception);
+template <> struct DartConverter<DartList> {
+ static DartList FromArguments(Dart_NativeArguments args, int index,
+ Dart_Handle &exception);
};
-} // namespace tonic
+} // namespace tonic
-#endif // LIB_TONIC_DART_LIST_H_
+#endif // LIB_TONIC_DART_LIST_H_
diff --git a/dart_message_handler.cc b/dart_message_handler.cc
index 82ca315..04a0640 100644
--- a/dart_message_handler.cc
+++ b/dart_message_handler.cc
@@ -2,51 +2,73 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "lib/tonic/dart_message_handler.h"
+#include "tonic/dart_message_handler.h"
#include "third_party/dart/runtime/include/dart_api.h"
#include "third_party/dart/runtime/include/dart_native_api.h"
#include "third_party/dart/runtime/include/dart_tools_api.h"
-#include "lib/fxl/logging.h"
-#include "lib/tonic/logging/dart_error.h"
-#include "lib/tonic/dart_state.h"
-#include "lib/tonic/dart_sticky_error.h"
+#include "tonic/common/macros.h"
+#include "tonic/dart_state.h"
+#include "tonic/dart_sticky_error.h"
+#include "tonic/logging/dart_error.h"
namespace tonic {
DartMessageHandler::DartMessageHandler()
- : handled_first_message_(false),
- isolate_exited_(false),
+ : handled_first_message_(false), isolate_exited_(false),
isolate_had_uncaught_exception_error_(false),
- isolate_last_error_(kNoError),
- task_runner_(nullptr) {}
+ isolate_had_fatal_error_(false), isolate_last_error_(kNoError),
+ task_dispatcher_(nullptr), message_epilogue_(nullptr) {}
DartMessageHandler::~DartMessageHandler() {
- task_runner_ = nullptr;
+ task_dispatcher_ = nullptr;
+ message_epilogue_ = nullptr;
}
-void DartMessageHandler::Initialize(
- const fxl::RefPtr<fxl::TaskRunner>& runner) {
+void DartMessageHandler::Initialize(TaskDispatcher dispatcher,
+ std::function<void()> message_epilogue) {
// Only can be called once.
- FXL_CHECK(!task_runner_);
- task_runner_ = runner;
- FXL_CHECK(task_runner_);
+ TONIC_CHECK(!task_dispatcher_);
+ task_dispatcher_ = dispatcher;
+ message_epilogue_ = message_epilogue;
+ TONIC_CHECK(task_dispatcher_);
Dart_SetMessageNotifyCallback(MessageNotifyCallback);
}
-void DartMessageHandler::OnMessage(DartState* dart_state) {
- auto task_runner = dart_state->message_handler().task_runner();
+void DartMessageHandler::OnMessage(DartState *dart_state) {
+ auto task_dispatcher_ = dart_state->message_handler().task_dispatcher_;
// Schedule a task to run on the message loop thread.
- fxl::WeakPtr<DartState> dart_state_ptr = dart_state->GetWeakPtr();
- task_runner->PostTask([dart_state_ptr]() {
- if (!dart_state_ptr)
- return;
- dart_state_ptr->message_handler().OnHandleMessage(dart_state_ptr.get());
+ auto weak_dart_state = dart_state->GetWeakPtr();
+ task_dispatcher_([weak_dart_state]() {
+ if (auto dart_state = weak_dart_state.lock()) {
+ dart_state->message_handler().OnHandleMessage(dart_state.get());
+ }
});
}
-void DartMessageHandler::OnHandleMessage(DartState* dart_state) {
+void DartMessageHandler::UnhandledError(Dart_Handle error) {
+ TONIC_DCHECK(Dart_CurrentIsolate());
+ TONIC_DCHECK(Dart_IsError(error));
+
+ isolate_last_error_ = GetErrorHandleType(error);
+ // Remember that we had an uncaught exception error.
+ isolate_had_uncaught_exception_error_ = true;
+ if (Dart_IsFatalError(error)) {
+ isolate_had_fatal_error_ = true;
+ // Stop handling messages.
+ Dart_SetMessageNotifyCallback(nullptr);
+ // Shut down the isolate.
+ Dart_ShutdownIsolate();
+ }
+}
+
+void DartMessageHandler::OnHandleMessage(DartState *dart_state) {
+ if (isolate_had_fatal_error_) {
+ // Don't handle any more messages.
+ return;
+ }
+
DartIsolateScope scope(dart_state->isolate());
DartApiScope dart_api_scope;
Dart_Handle result = Dart_Null();
@@ -70,8 +92,11 @@
return;
}
Dart_SetPausedOnStart(false);
- // We've resumed, handle *all* normal messages that are in the queue.
- result = Dart_HandleMessages();
+ // We've resumed, handle normal messages that are in the queue.
+ result = Dart_HandleMessage();
+ if (message_epilogue_) {
+ message_epilogue_();
+ }
error = LogIfError(result);
}
} else if (Dart_IsPausedOnExit()) {
@@ -86,7 +111,10 @@
}
} else {
// We are processing messages normally.
- result = Dart_HandleMessages();
+ result = Dart_HandleMessage();
+ if (message_epilogue_) {
+ message_epilogue_();
+ }
// If the Dart program has set a return code, then it is intending to shut
// down by way of a fatal error, and so there is no need to emit a log
// message.
@@ -99,17 +127,7 @@
}
if (error) {
- isolate_last_error_ = GetErrorHandleType(result);
- if (Dart_IsError(result)) {
- // Remember that we had an uncaught exception error.
- isolate_had_uncaught_exception_error_ = true;
- if (Dart_IsFatalError(result)) {
- // Stop handling messages.
- Dart_SetMessageNotifyCallback(nullptr);
- // Shut down the isolate.
- Dart_ShutdownIsolate();
- }
- }
+ UnhandledError(result);
} else if (!Dart_HasLivePorts()) {
// The isolate has no live ports and would like to exit.
if (!Dart_IsPausedOnExit() && Dart_ShouldPauseOnExit()) {
@@ -123,8 +141,8 @@
void DartMessageHandler::MessageNotifyCallback(Dart_Isolate dest_isolate) {
auto dart_state = DartState::From(dest_isolate);
- FXL_CHECK(dart_state);
+ TONIC_CHECK(dart_state);
dart_state->message_handler().OnMessage(dart_state);
}
-} // namespace tonic
+} // namespace tonic
diff --git a/dart_message_handler.h b/dart_message_handler.h
index a27c801..f266ed2 100644
--- a/dart_message_handler.h
+++ b/dart_message_handler.h
@@ -5,22 +5,29 @@
#ifndef LIB_TONIC_DART_MESSAGE_HANDLER_H_
#define LIB_TONIC_DART_MESSAGE_HANDLER_H_
+#include <functional>
+
#include "third_party/dart/runtime/include/dart_api.h"
-#include "lib/fxl/memory/ref_ptr.h"
-#include "lib/fxl/memory/weak_ptr.h"
-#include "lib/fxl/tasks/task_runner.h"
-#include "lib/tonic/logging/dart_error.h"
+#include "tonic/logging/dart_error.h"
namespace tonic {
class DartState;
class DartMessageHandler {
- public:
+public:
+ using TaskDispatcher = std::function<void(std::function<void(void)>)>;
+
DartMessageHandler();
+
~DartMessageHandler();
// Messages for the current isolate will be scheduled on |runner|.
- void Initialize(const fxl::RefPtr<fxl::TaskRunner>& runner);
+ void Initialize(TaskDispatcher dispatcher,
+ std::function<void()> message_epilogue = nullptr);
+
+ // Handle an unhandled error. If the error is fatal then shut down the
+ // isolate. The message handler's isolate must be the current isolate.
+ void UnhandledError(Dart_Handle error);
// Did the isolate exit?
bool isolate_exited() const { return isolate_exited_; }
@@ -30,19 +37,13 @@
return isolate_had_uncaught_exception_error_;
}
- DartErrorHandleType isolate_last_error() const {
- return isolate_last_error_;
- }
+ DartErrorHandleType isolate_last_error() const { return isolate_last_error_; }
- protected:
+protected:
// Called from an unknown thread for each message.
- void OnMessage(DartState* dart_state);
+ void OnMessage(DartState *dart_state);
// By default, called on the task runner's thread for each message.
- void OnHandleMessage(DartState* dart_state);
-
- const fxl::RefPtr<fxl::TaskRunner>& task_runner() const {
- return task_runner_;
- }
+ void OnHandleMessage(DartState *dart_state);
bool handled_first_message() const { return handled_first_message_; }
@@ -53,13 +54,15 @@
bool handled_first_message_;
bool isolate_exited_;
bool isolate_had_uncaught_exception_error_;
+ bool isolate_had_fatal_error_;
DartErrorHandleType isolate_last_error_;
- fxl::RefPtr<fxl::TaskRunner> task_runner_;
+ TaskDispatcher task_dispatcher_;
+ std::function<void()> message_epilogue_;
- private:
+private:
static void MessageNotifyCallback(Dart_Isolate dest_isolate);
};
-} // namespace tonic
+} // namespace tonic
-#endif // LIB_TONIC_DART_MESSAGE_HANDLER_H_
+#endif // LIB_TONIC_DART_MESSAGE_HANDLER_H_
diff --git a/dart_microtask_queue.cc b/dart_microtask_queue.cc
index 604de2b..f051042 100644
--- a/dart_microtask_queue.cc
+++ b/dart_microtask_queue.cc
@@ -2,12 +2,12 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "lib/tonic/dart_microtask_queue.h"
+#include "tonic/dart_microtask_queue.h"
-#include "lib/fxl/build_config.h"
-#include "lib/tonic/logging/dart_invoke.h"
-#include "lib/tonic/dart_state.h"
-#include "lib/tonic/dart_sticky_error.h"
+#include "tonic/common/build_config.h"
+#include "tonic/dart_state.h"
+#include "tonic/dart_sticky_error.h"
+#include "tonic/logging/dart_invoke.h"
#ifdef OS_IOS
#include <pthread.h>
@@ -22,31 +22,25 @@
pthread_key_t g_queue_key;
pthread_once_t g_queue_key_once = PTHREAD_ONCE_INIT;
-void MakeKey() {
- pthread_key_create(&g_queue_key, nullptr);
-}
+void MakeKey() { pthread_key_create(&g_queue_key, nullptr); }
-void SetQueue(DartMicrotaskQueue* queue) {
+void SetQueue(DartMicrotaskQueue *queue) {
pthread_once(&g_queue_key_once, MakeKey);
pthread_setspecific(g_queue_key, queue);
}
-DartMicrotaskQueue* GetQueue() {
- return static_cast<tonic::DartMicrotaskQueue*>(
+DartMicrotaskQueue *GetQueue() {
+ return static_cast<tonic::DartMicrotaskQueue *>(
pthread_getspecific(g_queue_key));
}
#else
-thread_local DartMicrotaskQueue* g_queue = nullptr;
+thread_local DartMicrotaskQueue *g_queue = nullptr;
-void SetQueue(DartMicrotaskQueue* queue) {
- g_queue = queue;
-}
+void SetQueue(DartMicrotaskQueue *queue) { g_queue = queue; }
-DartMicrotaskQueue* GetQueue() {
- return g_queue;
-}
+DartMicrotaskQueue *GetQueue() { return g_queue; }
#endif
@@ -60,7 +54,7 @@
SetQueue(new DartMicrotaskQueue());
}
-DartMicrotaskQueue* DartMicrotaskQueue::GetForCurrentThread() {
+DartMicrotaskQueue *DartMicrotaskQueue::GetForCurrentThread() {
return GetQueue();
}
@@ -72,27 +66,25 @@
while (!queue_.empty()) {
MicrotaskQueue local;
std::swap(queue_, local);
- for (const auto& callback : local) {
- fxl::WeakPtr<DartState> dart_state = callback.dart_state();
- if (!dart_state.get())
- continue;
- DartState::Scope dart_scope(dart_state.get());
- Dart_Handle result = DartInvokeVoid(callback.value());
- DartErrorHandleType error = GetErrorHandleType(result);
- if (error != kNoError)
- last_error_ = error;
+ for (const auto &callback : local) {
+ if (auto dart_state = callback.dart_state().lock()) {
+ DartState::Scope dart_scope(dart_state.get());
+ Dart_Handle result = DartInvokeVoid(callback.value());
+ DartErrorHandleType error = GetErrorHandleType(result);
+ if (error != kNoError) {
+ last_error_ = error;
+ }
+ }
}
}
}
void DartMicrotaskQueue::Destroy() {
- FXL_DCHECK(this == GetForCurrentThread());
+ TONIC_DCHECK(this == GetForCurrentThread());
SetQueue(nullptr);
delete this;
}
-DartErrorHandleType DartMicrotaskQueue::GetLastError() {
- return last_error_;
-}
+DartErrorHandleType DartMicrotaskQueue::GetLastError() { return last_error_; }
-}
+} // namespace tonic
diff --git a/dart_microtask_queue.h b/dart_microtask_queue.h
index 1aa5e9f..c2f18f4 100644
--- a/dart_microtask_queue.h
+++ b/dart_microtask_queue.h
@@ -8,36 +8,35 @@
#include <vector>
#include "third_party/dart/runtime/include/dart_api.h"
-#include "lib/tonic/dart_persistent_value.h"
-#include "lib/tonic/logging/dart_error.h"
+#include "tonic/dart_persistent_value.h"
+#include "tonic/logging/dart_error.h"
namespace tonic {
class DartMicrotaskQueue {
- public:
+public:
+ DartMicrotaskQueue();
+ ~DartMicrotaskQueue();
+
static void StartForCurrentThread();
- static DartMicrotaskQueue* GetForCurrentThread();
+
+ static DartMicrotaskQueue *GetForCurrentThread();
void ScheduleMicrotask(Dart_Handle callback);
void RunMicrotasks();
void Destroy();
- bool HasMicrotasks() const {
- return !queue_.empty();
- }
+ bool HasMicrotasks() const { return !queue_.empty(); }
DartErrorHandleType GetLastError();
- private:
- DartMicrotaskQueue();
- ~DartMicrotaskQueue();
-
+private:
typedef std::vector<DartPersistentValue> MicrotaskQueue;
DartErrorHandleType last_error_;
MicrotaskQueue queue_;
};
-} // namespace tonic
+} // namespace tonic
-#endif // LIB_TONIC_DART_MICROTASK_QUEUE_H_
+#endif // LIB_TONIC_DART_MICROTASK_QUEUE_H_
diff --git a/dart_persistent_value.cc b/dart_persistent_value.cc
index 52e7b7e..0c63426 100644
--- a/dart_persistent_value.cc
+++ b/dart_persistent_value.cc
@@ -2,44 +2,48 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "lib/tonic/dart_persistent_value.h"
+#include "tonic/dart_persistent_value.h"
-#include "lib/tonic/scopes/dart_isolate_scope.h"
-#include "lib/tonic/dart_state.h"
+#include "tonic/dart_state.h"
+#include "tonic/scopes/dart_isolate_scope.h"
namespace tonic {
DartPersistentValue::DartPersistentValue() : value_(nullptr) {}
-DartPersistentValue::DartPersistentValue(DartPersistentValue&& other)
+DartPersistentValue::DartPersistentValue(DartPersistentValue &&other)
: dart_state_(other.dart_state_), value_(other.value_) {
- other.dart_state_ = fxl::WeakPtr<DartState>();
+ other.dart_state_.reset();
other.value_ = nullptr;
}
-DartPersistentValue::DartPersistentValue(DartState* dart_state,
+DartPersistentValue::DartPersistentValue(DartState *dart_state,
Dart_Handle value)
: value_(nullptr) {
Set(dart_state, value);
}
-DartPersistentValue::~DartPersistentValue() {
- Clear();
-}
+DartPersistentValue::~DartPersistentValue() { Clear(); }
-void DartPersistentValue::Set(DartState* dart_state, Dart_Handle value) {
- FXL_DCHECK(is_empty());
+void DartPersistentValue::Set(DartState *dart_state, Dart_Handle value) {
+ TONIC_DCHECK(is_empty());
dart_state_ = dart_state->GetWeakPtr();
value_ = Dart_NewPersistentHandle(value);
}
void DartPersistentValue::Clear() {
- if (!value_ || !dart_state_.get())
+ if (!value_) {
return;
+ }
- DartIsolateScope scope(dart_state_->isolate());
+ auto dart_state = dart_state_.lock();
+ if (!dart_state) {
+ return;
+ }
+
+ DartIsolateScope scope(dart_state->isolate());
Dart_DeletePersistentHandle(value_);
- dart_state_ = fxl::WeakPtr<DartState>();
+ dart_state_.reset();
value_ = nullptr;
}
@@ -54,4 +58,4 @@
Clear();
return local;
}
-}
+} // namespace tonic
diff --git a/dart_persistent_value.h b/dart_persistent_value.h
index 1dd466f..14bb002 100644
--- a/dart_persistent_value.h
+++ b/dart_persistent_value.h
@@ -5,9 +5,10 @@
#ifndef LIB_TONIC_DART_PERSISTENT_VALUE_H_
#define LIB_TONIC_DART_PERSISTENT_VALUE_H_
-#include "lib/fxl/macros.h"
-#include "lib/fxl/memory/weak_ptr.h"
+#include <memory>
+
#include "third_party/dart/runtime/include/dart_api.h"
+#include "tonic/common/macros.h"
namespace tonic {
class DartState;
@@ -17,29 +18,29 @@
// this class instead of holding a Dart_PersistentHandle directly so that you
// don't leak the Dart_PersistentHandle.
class DartPersistentValue {
- public:
+public:
DartPersistentValue();
- DartPersistentValue(DartPersistentValue&& other);
- DartPersistentValue(DartState* dart_state, Dart_Handle value);
+ DartPersistentValue(DartPersistentValue &&other);
+ DartPersistentValue(DartState *dart_state, Dart_Handle value);
~DartPersistentValue();
Dart_PersistentHandle value() const { return value_; }
bool is_empty() const { return !value_; }
- void Set(DartState* dart_state, Dart_Handle value);
+ void Set(DartState *dart_state, Dart_Handle value);
void Clear();
Dart_Handle Get();
Dart_Handle Release();
- const fxl::WeakPtr<DartState>& dart_state() const { return dart_state_; }
+ const std::weak_ptr<DartState> &dart_state() const { return dart_state_; }
- private:
- fxl::WeakPtr<DartState> dart_state_;
+private:
+ std::weak_ptr<DartState> dart_state_;
Dart_PersistentHandle value_;
- FXL_DISALLOW_COPY_AND_ASSIGN(DartPersistentValue);
+ TONIC_DISALLOW_COPY_AND_ASSIGN(DartPersistentValue);
};
-} // namespace tonic
+} // namespace tonic
-#endif // LIB_TONIC_DART_PERSISTENT_VALUE_H_
+#endif // LIB_TONIC_DART_PERSISTENT_VALUE_H_
diff --git a/dart_state.cc b/dart_state.cc
index 4fb5b76..2b8a50b 100644
--- a/dart_state.cc
+++ b/dart_state.cc
@@ -2,26 +2,24 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "lib/tonic/dart_state.h"
+#include "tonic/dart_state.h"
-#include "lib/tonic/converter/dart_converter.h"
-#include "lib/tonic/dart_class_library.h"
-#include "lib/tonic/dart_message_handler.h"
-#include "lib/tonic/file_loader/file_loader.h"
+#include "tonic/converter/dart_converter.h"
+#include "tonic/dart_class_library.h"
+#include "tonic/dart_message_handler.h"
+#include "tonic/file_loader/file_loader.h"
namespace tonic {
-DartState::Scope::Scope(DartState* dart_state)
+DartState::Scope::Scope(DartState *dart_state)
: scope_(dart_state->isolate()) {}
DartState::Scope::~Scope() {}
-DartState::DartState()
- : isolate_(nullptr),
- class_library_(new DartClassLibrary),
+DartState::DartState(int dirfd)
+ : isolate_(nullptr), class_library_(new DartClassLibrary),
message_handler_(new DartMessageHandler()),
- file_loader_(new FileLoader()),
- weak_factory_(this) {}
+ file_loader_(new FileLoader(dirfd)) {}
DartState::~DartState() {}
@@ -32,17 +30,15 @@
DidSetIsolate();
}
-DartState* DartState::From(Dart_Isolate isolate) {
- return static_cast<DartState*>(Dart_IsolateData(isolate));
+DartState *DartState::From(Dart_Isolate isolate) {
+ return static_cast<DartState *>(Dart_IsolateData(isolate));
}
-DartState* DartState::Current() {
- return static_cast<DartState*>(Dart_CurrentIsolateData());
+DartState *DartState::Current() {
+ return static_cast<DartState *>(Dart_CurrentIsolateData());
}
-fxl::WeakPtr<DartState> DartState::GetWeakPtr() {
- return weak_factory_.GetWeakPtr();
-}
+std::weak_ptr<DartState> DartState::GetWeakPtr() { return shared_from_this(); }
void DartState::SetReturnCode(uint32_t return_code) {
if (set_return_code_callback_) {
@@ -58,9 +54,8 @@
void DartState::DidSetIsolate() {}
Dart_Handle DartState::HandleLibraryTag(Dart_LibraryTag tag,
- Dart_Handle library,
- Dart_Handle url) {
+ Dart_Handle library, Dart_Handle url) {
return Current()->file_loader().HandleLibraryTag(tag, library, url);
}
-} // namespace tonic
+} // namespace tonic
diff --git a/dart_state.h b/dart_state.h
index d813e86..1174416 100644
--- a/dart_state.h
+++ b/dart_state.h
@@ -5,14 +5,14 @@
#ifndef LIB_TONIC_DART_STATE_H_
#define LIB_TONIC_DART_STATE_H_
+#include <functional>
#include <memory>
#include "third_party/dart/runtime/include/dart_api.h"
-#include "lib/fxl/logging.h"
-#include "lib/fxl/memory/weak_ptr.h"
-#include "lib/tonic/dart_persistent_value.h"
-#include "lib/tonic/scopes/dart_api_scope.h"
-#include "lib/tonic/scopes/dart_isolate_scope.h"
+#include "tonic/common/macros.h"
+#include "tonic/dart_persistent_value.h"
+#include "tonic/scopes/dart_api_scope.h"
+#include "tonic/scopes/dart_isolate_scope.h"
namespace tonic {
class DartClassLibrary;
@@ -21,35 +21,35 @@
// DartState represents the state associated with a given Dart isolate. The
// lifetime of this object is controlled by the DartVM. If you want to hold a
-// reference to a DartState instance, please hold a fxl::WeakPtr<DartState>.
+// reference to a DartState instance, please hold a tonic::WeakPtr<DartState>.
//
// DartState is analogous to gin::PerIsolateData and JSC::ExecState.
-class DartState {
- public:
+class DartState : public std::enable_shared_from_this<DartState> {
+public:
class Scope {
- public:
- Scope(DartState* dart_state);
+ public:
+ Scope(DartState *dart_state);
~Scope();
- private:
+ private:
DartIsolateScope scope_;
DartApiScope api_scope_;
};
- DartState();
+ DartState(int dirfd = -1);
virtual ~DartState();
- static DartState* From(Dart_Isolate isolate);
- static DartState* Current();
+ static DartState *From(Dart_Isolate isolate);
+ static DartState *Current();
- fxl::WeakPtr<DartState> GetWeakPtr();
+ std::weak_ptr<DartState> GetWeakPtr();
Dart_Isolate isolate() { return isolate_; }
void SetIsolate(Dart_Isolate isolate);
- DartClassLibrary& class_library() { return *class_library_; }
- DartMessageHandler& message_handler() { return *message_handler_; }
- FileLoader& file_loader() { return *file_loader_; }
+ DartClassLibrary &class_library() { return *class_library_; }
+ DartMessageHandler &message_handler() { return *message_handler_; }
+ FileLoader &file_loader() { return *file_loader_; }
void SetReturnCode(uint32_t return_code);
void SetReturnCodeCallback(std::function<void(uint32_t)> callback);
@@ -57,11 +57,10 @@
virtual void DidSetIsolate();
- static Dart_Handle HandleLibraryTag(Dart_LibraryTag tag,
- Dart_Handle library,
+ static Dart_Handle HandleLibraryTag(Dart_LibraryTag tag, Dart_Handle library,
Dart_Handle url);
- private:
+private:
Dart_Isolate isolate_;
std::unique_ptr<DartClassLibrary> class_library_;
std::unique_ptr<DartMessageHandler> message_handler_;
@@ -69,12 +68,10 @@
std::function<void(uint32_t)> set_return_code_callback_;
bool has_set_return_code_;
- protected:
- fxl::WeakPtrFactory<DartState> weak_factory_;
-
- FXL_DISALLOW_COPY_AND_ASSIGN(DartState);
+protected:
+ TONIC_DISALLOW_COPY_AND_ASSIGN(DartState);
};
-} // namespace tonic
+} // namespace tonic
-#endif // LIB_TONIC_DART_STATE_H_
+#endif // LIB_TONIC_DART_STATE_H_
diff --git a/dart_sticky_error.cc b/dart_sticky_error.cc
index c232948..ed8d87f 100644
--- a/dart_sticky_error.cc
+++ b/dart_sticky_error.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "lib/tonic/dart_sticky_error.h"
+#include "tonic/dart_sticky_error.h"
namespace tonic {
@@ -22,8 +22,6 @@
return true;
}
-bool DartStickyError::IsSet() {
- return Dart_HasStickyError();
-}
+bool DartStickyError::IsSet() { return Dart_HasStickyError(); }
-} // namespace tonic
+} // namespace tonic
diff --git a/dart_wrappable.cc b/dart_wrappable.cc
index af4793f..3ea3c74 100644
--- a/dart_wrappable.cc
+++ b/dart_wrappable.cc
@@ -2,34 +2,32 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "lib/tonic/dart_wrappable.h"
+#include "tonic/dart_wrappable.h"
-#include "lib/tonic/dart_class_library.h"
-#include "lib/tonic/logging/dart_error.h"
-#include "lib/tonic/dart_state.h"
-#include "lib/tonic/dart_wrapper_info.h"
+#include "tonic/dart_class_library.h"
+#include "tonic/dart_state.h"
+#include "tonic/dart_wrapper_info.h"
+#include "tonic/logging/dart_error.h"
namespace tonic {
-DartWrappable::~DartWrappable() {
- FXL_CHECK(!dart_wrapper_);
-}
+DartWrappable::~DartWrappable() { TONIC_CHECK(!dart_wrapper_); }
-Dart_Handle DartWrappable::CreateDartWrapper(DartState* dart_state) {
- FXL_DCHECK(!dart_wrapper_);
- const DartWrapperInfo& info = GetDartWrapperInfo();
+Dart_Handle DartWrappable::CreateDartWrapper(DartState *dart_state) {
+ TONIC_DCHECK(!dart_wrapper_);
+ const DartWrapperInfo &info = GetDartWrapperInfo();
Dart_PersistentHandle type = dart_state->class_library().GetClass(info);
- FXL_DCHECK(!LogIfError(type));
+ TONIC_DCHECK(!LogIfError(type));
intptr_t native_fields[kNumberOfNativeFields];
native_fields[kPeerIndex] = reinterpret_cast<intptr_t>(this);
native_fields[kWrapperInfoIndex] = reinterpret_cast<intptr_t>(&info);
Dart_Handle wrapper =
Dart_AllocateWithNativeFields(type, kNumberOfNativeFields, native_fields);
- FXL_DCHECK(!LogIfError(wrapper));
+ TONIC_DCHECK(!LogIfError(wrapper));
- info.ref_object(this); // Balanced in FinalizeDartWrapper.
+ this->RetainDartWrappableReference(); // Balanced in FinalizeDartWrapper.
dart_wrapper_ = Dart_NewWeakPersistentHandle(
wrapper, this, GetAllocationSize(), &FinalizeDartWrapper);
@@ -37,64 +35,69 @@
}
void DartWrappable::AssociateWithDartWrapper(Dart_NativeArguments args) {
- FXL_DCHECK(!dart_wrapper_);
+ TONIC_DCHECK(!dart_wrapper_);
Dart_Handle wrapper = Dart_GetNativeArgument(args, 0);
- FXL_CHECK(!LogIfError(wrapper));
+ TONIC_CHECK(!LogIfError(wrapper));
intptr_t native_fields[kNumberOfNativeFields];
- FXL_CHECK(!LogIfError(Dart_GetNativeFieldsOfArgument(
+ TONIC_CHECK(!LogIfError(Dart_GetNativeFieldsOfArgument(
args, 0, kNumberOfNativeFields, native_fields)));
- FXL_CHECK(!native_fields[kPeerIndex]);
- FXL_CHECK(!native_fields[kWrapperInfoIndex]);
+ TONIC_CHECK(!native_fields[kPeerIndex]);
+ TONIC_CHECK(!native_fields[kWrapperInfoIndex]);
- const DartWrapperInfo& info = GetDartWrapperInfo();
- FXL_CHECK(!LogIfError(Dart_SetNativeInstanceField(
+ const DartWrapperInfo &info = GetDartWrapperInfo();
+ TONIC_CHECK(!LogIfError(Dart_SetNativeInstanceField(
wrapper, kPeerIndex, reinterpret_cast<intptr_t>(this))));
- FXL_CHECK(!LogIfError(Dart_SetNativeInstanceField(
+ TONIC_CHECK(!LogIfError(Dart_SetNativeInstanceField(
wrapper, kWrapperInfoIndex, reinterpret_cast<intptr_t>(&info))));
- info.ref_object(this); // Balanced in FinalizeDartWrapper.
+ this->RetainDartWrappableReference(); // Balanced in FinalizeDartWrapper.
dart_wrapper_ = Dart_NewWeakPersistentHandle(
wrapper, this, GetAllocationSize(), &FinalizeDartWrapper);
}
void DartWrappable::ClearDartWrapper() {
- FXL_DCHECK(dart_wrapper_);
+ TONIC_DCHECK(dart_wrapper_);
Dart_Handle wrapper = Dart_HandleFromWeakPersistent(dart_wrapper_);
- FXL_CHECK(!LogIfError(Dart_SetNativeInstanceField(wrapper, kPeerIndex, 0)));
- FXL_CHECK(
+ TONIC_CHECK(!LogIfError(Dart_SetNativeInstanceField(wrapper, kPeerIndex, 0)));
+ TONIC_CHECK(
!LogIfError(Dart_SetNativeInstanceField(wrapper, kWrapperInfoIndex, 0)));
Dart_DeleteWeakPersistentHandle(Dart_CurrentIsolate(), dart_wrapper_);
dart_wrapper_ = nullptr;
- GetDartWrapperInfo().deref_object(this);
+ this->ReleaseDartWrappableReference();
}
-void DartWrappable::FinalizeDartWrapper(void* isolate_callback_data,
+void DartWrappable::FinalizeDartWrapper(void *isolate_callback_data,
Dart_WeakPersistentHandle wrapper,
- void* peer) {
- DartWrappable* wrappable = reinterpret_cast<DartWrappable*>(peer);
+ void *peer) {
+ DartWrappable *wrappable = reinterpret_cast<DartWrappable *>(peer);
wrappable->dart_wrapper_ = nullptr;
- const DartWrapperInfo& info = wrappable->GetDartWrapperInfo();
- info.deref_object(wrappable); // Balanced in CreateDartWrapper.
+ wrappable->ReleaseDartWrappableReference(); // Balanced in CreateDartWrapper.
}
size_t DartWrappable::GetAllocationSize() {
return GetDartWrapperInfo().size_in_bytes;
}
-DartWrappable* DartConverterWrappable::FromDart(Dart_Handle handle) {
+Dart_PersistentHandle
+DartWrappable::GetTypeForWrapper(tonic::DartState *dart_state,
+ const tonic::DartWrapperInfo &wrapper_info) {
+ return dart_state->class_library().GetClass(wrapper_info);
+}
+
+DartWrappable *DartConverterWrappable::FromDart(Dart_Handle handle) {
intptr_t peer = 0;
Dart_Handle result =
Dart_GetNativeInstanceField(handle, DartWrappable::kPeerIndex, &peer);
if (Dart_IsError(result))
return nullptr;
- return reinterpret_cast<DartWrappable*>(peer);
+ return reinterpret_cast<DartWrappable *>(peer);
}
-DartWrappable* DartConverterWrappable::FromArguments(Dart_NativeArguments args,
+DartWrappable *DartConverterWrappable::FromArguments(Dart_NativeArguments args,
int index,
- Dart_Handle& exception) {
+ Dart_Handle &exception) {
intptr_t native_fields[DartWrappable::kNumberOfNativeFields];
Dart_Handle result = Dart_GetNativeFieldsOfArgument(
args, index, DartWrappable::kNumberOfNativeFields, native_fields);
@@ -104,8 +107,8 @@
}
if (!native_fields[DartWrappable::kPeerIndex])
return nullptr;
- return reinterpret_cast<DartWrappable*>(
+ return reinterpret_cast<DartWrappable *>(
native_fields[DartWrappable::kPeerIndex]);
}
-} // namespace tonic
+} // namespace tonic
diff --git a/dart_wrappable.h b/dart_wrappable.h
index 730f21e..a1ea9f5 100644
--- a/dart_wrappable.h
+++ b/dart_wrappable.h
@@ -6,12 +6,11 @@
#define LIB_TONIC_DART_WRAPPABLE_H_
#include "third_party/dart/runtime/include/dart_api.h"
-#include "lib/fxl/logging.h"
-#include "lib/fxl/memory/ref_counted.h"
-#include "lib/tonic/converter/dart_converter.h"
-#include "lib/tonic/logging/dart_error.h"
-#include "lib/tonic/dart_state.h"
-#include "lib/tonic/dart_wrapper_info.h"
+#include "tonic/common/macros.h"
+#include "tonic/converter/dart_converter.h"
+#include "tonic/dart_state.h"
+#include "tonic/dart_wrapper_info.h"
+#include "tonic/logging/dart_error.h"
#include <type_traits>
@@ -20,9 +19,9 @@
// DartWrappable is a base class that you can inherit from in order to be
// exposed to Dart code as an interface.
class DartWrappable {
- public:
+public:
enum DartNativeFields {
- kPeerIndex, // Must be first to work with Dart_GetNativeReceiver.
+ kPeerIndex, // Must be first to work with Dart_GetNativeReceiver.
kWrapperInfoIndex,
kNumberOfNativeFields,
};
@@ -32,75 +31,72 @@
// Subclasses that wish to expose a new interface must override this function
// and provide information about their wrapper. There is no need to call your
// base class's implementation of this function.
- virtual const DartWrapperInfo& GetDartWrapperInfo() const = 0;
+ // Implement using IMPLEMENT_WRAPPERTYPEINFO macro
+ virtual const DartWrapperInfo &GetDartWrapperInfo() const = 0;
// Override this to customize the object size reported to the Dart garbage
// collector.
+ // Implement using IMPLEMENT_WRAPPERTYPEINFO macro
virtual size_t GetAllocationSize();
- Dart_Handle CreateDartWrapper(DartState* dart_state);
+ virtual void RetainDartWrappableReference() const = 0;
+
+ virtual void ReleaseDartWrappableReference() const = 0;
+
+ Dart_Handle CreateDartWrapper(DartState *dart_state);
void AssociateWithDartWrapper(Dart_NativeArguments args);
- void ClearDartWrapper(); // Warning: Might delete this.
+ void ClearDartWrapper(); // Warning: Might delete this.
Dart_WeakPersistentHandle dart_wrapper() const { return dart_wrapper_; }
- protected:
+protected:
virtual ~DartWrappable();
- private:
- static void FinalizeDartWrapper(void* isolate_callback_data,
+ static Dart_PersistentHandle
+ GetTypeForWrapper(tonic::DartState *dart_state,
+ const tonic::DartWrapperInfo &wrapper_info);
+
+private:
+ static void FinalizeDartWrapper(void *isolate_callback_data,
Dart_WeakPersistentHandle wrapper,
- void* peer);
+ void *peer);
Dart_WeakPersistentHandle dart_wrapper_;
- FXL_DISALLOW_COPY_AND_ASSIGN(DartWrappable);
+ TONIC_DISALLOW_COPY_AND_ASSIGN(DartWrappable);
};
-#define DEFINE_WRAPPERTYPEINFO() \
- public: \
- const tonic::DartWrapperInfo& GetDartWrapperInfo() const override { \
- return dart_wrapper_info_; \
- } \
- \
- private: \
- static const tonic::DartWrapperInfo& dart_wrapper_info_
+#define DEFINE_WRAPPERTYPEINFO() \
+public: \
+ const tonic::DartWrapperInfo &GetDartWrapperInfo() const override { \
+ return dart_wrapper_info_; \
+ } \
+ static Dart_PersistentHandle GetDartType(tonic::DartState *dart_state) { \
+ return GetTypeForWrapper(dart_state, dart_wrapper_info_); \
+ } \
+ \
+private: \
+ static const tonic::DartWrapperInfo &dart_wrapper_info_
-#define IMPLEMENT_WRAPPERTYPEINFO(LibraryName, ClassName) \
- static void RefObject_##LibraryName_##ClassName( \
- tonic::DartWrappable* impl) { \
- static_cast<ClassName*>(impl)->AddRef(); \
- } \
- static void DerefObject_##LibraryName_##ClassName( \
- tonic::DartWrappable* impl) { \
- static_cast<ClassName*>(impl)->Release(); \
- } \
- static const tonic::DartWrapperInfo \
- kDartWrapperInfo_##LibraryName_##ClassName = { \
- #LibraryName, \
- #ClassName, \
- sizeof(ClassName), \
- &RefObject_##LibraryName_##ClassName, \
- &DerefObject_##LibraryName_##ClassName, \
- }; \
- const tonic::DartWrapperInfo& ClassName::dart_wrapper_info_ = \
- kDartWrapperInfo_##LibraryName_##ClassName; \
- static_assert(std::is_base_of<fxl::internal::RefCountedThreadSafeBase, \
- ClassName>::value, \
- #ClassName " must be thread-safe reference-countable.");
+#define IMPLEMENT_WRAPPERTYPEINFO(LibraryName, ClassName) \
+ static const tonic::DartWrapperInfo \
+ kDartWrapperInfo_##LibraryName_##ClassName = { \
+ #LibraryName, \
+ #ClassName, \
+ sizeof(ClassName), \
+ }; \
+ const tonic::DartWrapperInfo &ClassName::dart_wrapper_info_ = \
+ kDartWrapperInfo_##LibraryName_##ClassName;
struct DartConverterWrappable {
- static DartWrappable* FromDart(Dart_Handle handle);
- static DartWrappable* FromArguments(Dart_NativeArguments args,
- int index,
- Dart_Handle& exception);
+ static DartWrappable *FromDart(Dart_Handle handle);
+ static DartWrappable *FromArguments(Dart_NativeArguments args, int index,
+ Dart_Handle &exception);
};
template <typename T>
-struct DartConverter<
- T*,
- typename std::enable_if<
- std::is_convertible<T*, const DartWrappable*>::value>::type> {
- static Dart_Handle ToDart(DartWrappable* val) {
+struct DartConverter<T *, typename std::enable_if<std::is_convertible<
+ T *, const DartWrappable *>::value>::type> {
+ static Dart_Handle ToDart(DartWrappable *val) {
if (!val)
return Dart_Null();
if (Dart_WeakPersistentHandle wrapper = val->dart_wrapper())
@@ -108,8 +104,7 @@
return val->CreateDartWrapper(DartState::Current());
}
- static void SetReturnValue(Dart_NativeArguments args,
- DartWrappable* val,
+ static void SetReturnValue(Dart_NativeArguments args, DartWrappable *val,
bool auto_scope = true) {
if (!val)
Dart_SetReturnValue(args, Dart_Null());
@@ -119,56 +114,28 @@
Dart_SetReturnValue(args, val->CreateDartWrapper(DartState::Current()));
}
- static T* FromDart(Dart_Handle handle) {
+ static T *FromDart(Dart_Handle handle) {
// TODO(abarth): We're missing a type check.
- return static_cast<T*>(DartConverterWrappable::FromDart(handle));
+ return static_cast<T *>(DartConverterWrappable::FromDart(handle));
}
- static T* FromArguments(Dart_NativeArguments args,
- int index,
- Dart_Handle& exception,
- bool auto_scope = true) {
+ static T *FromArguments(Dart_NativeArguments args, int index,
+ Dart_Handle &exception, bool auto_scope = true) {
// TODO(abarth): We're missing a type check.
- return static_cast<T*>(
+ return static_cast<T *>(
DartConverterWrappable::FromArguments(args, index, exception));
}
};
-template <typename T>
-struct DartConverter<fxl::RefPtr<T>> {
- static Dart_Handle ToDart(const fxl::RefPtr<T>& val) {
- return DartConverter<T*>::ToDart(val.get());
- }
-
- static fxl::RefPtr<T> FromDart(Dart_Handle handle) {
- return DartConverter<T*>::FromDart(handle);
- }
-
- static fxl::RefPtr<T> FromArguments(Dart_NativeArguments args,
- int index,
- Dart_Handle& exception,
- bool auto_scope = true) {
- return fxl::RefPtr<T>(
- DartConverter<T*>::FromArguments(args, index, exception, auto_scope));
- }
-
- static void SetReturnValue(Dart_NativeArguments args,
- const fxl::RefPtr<T>& val,
- bool auto_scope = true) {
- DartConverter<T*>::SetReturnValue(args, val.get());
- }
-};
-
-template <typename T>
-inline T* GetReceiver(Dart_NativeArguments args) {
+template <typename T> inline T *GetReceiver(Dart_NativeArguments args) {
intptr_t receiver;
Dart_Handle result = Dart_GetNativeReceiver(args, &receiver);
- FXL_DCHECK(!Dart_IsError(result));
+ TONIC_DCHECK(!Dart_IsError(result));
if (!receiver)
Dart_ThrowException(ToDart("Object has been disposed."));
- return static_cast<T*>(reinterpret_cast<DartWrappable*>(receiver));
+ return static_cast<T *>(reinterpret_cast<DartWrappable *>(receiver));
}
-} // namespace tonic
+} // namespace tonic
-#endif // LIB_TONIC_DART_WRAPPABLE_H_
+#endif // LIB_TONIC_DART_WRAPPABLE_H_
diff --git a/dart_wrapper_info.h b/dart_wrapper_info.h
index f91d3d9..5996fca 100644
--- a/dart_wrapper_info.h
+++ b/dart_wrapper_info.h
@@ -5,25 +5,21 @@
#ifndef LIB_TONIC_DART_WRAPPER_INFO_H_
#define LIB_TONIC_DART_WRAPPER_INFO_H_
-#include "lib/fxl/macros.h"
-
namespace tonic {
class DartWrappable;
-typedef void (*DartWrappableAccepter)(DartWrappable*);
+typedef void (*DartWrappableAccepter)(DartWrappable *);
struct DartWrapperInfo {
- const char* library_name;
- const char* interface_name;
+ const char *library_name;
+ const char *interface_name;
const size_t size_in_bytes;
- const DartWrappableAccepter ref_object;
- const DartWrappableAccepter deref_object;
- private:
- DartWrapperInfo(const DartWrapperInfo&) = delete;
- DartWrapperInfo& operator=(const DartWrapperInfo&) = delete;
+private:
+ DartWrapperInfo(const DartWrapperInfo &) = delete;
+ DartWrapperInfo &operator=(const DartWrapperInfo &) = delete;
};
-} // namespace tonic
+} // namespace tonic
-#endif // LIB_TONIC_DART_WRAPPER_INFO_H_
+#endif // LIB_TONIC_DART_WRAPPER_INFO_H_
diff --git a/file_loader/BUILD.gn b/file_loader/BUILD.gn
index b13ea18..0d6425f 100644
--- a/file_loader/BUILD.gn
+++ b/file_loader/BUILD.gn
@@ -3,19 +3,29 @@
# found in the LICENSE file.
source_set("file_loader") {
+ visibility = [ "../*" ]
+
+ configs += [ "../:config" ]
+
sources = [
"file_loader.cc",
"file_loader.h",
]
- deps = [
- "//third_party/dart/runtime:dart_api",
- "//garnet/public/lib/fxl",
- "//topaz/lib/tonic/converter",
- "//topaz/lib/tonic/parsers",
- ]
+ if (is_win) {
+ sources += [ "file_loader_win.cc" ]
+ } else if (is_fuchsia) {
+ sources += [ "file_loader_fuchsia.cc" ]
+ } else {
+ sources += [ "file_loader_posix.cc" ]
+ }
- public_configs = [
- "//topaz/lib/tonic:config",
+ deps = [
+ "../common",
+ "../converter",
+ "../filesystem",
+ "../parsers",
+ "../platform",
+ "//third_party/dart/runtime:dart_api",
]
}
diff --git a/file_loader/file_loader.cc b/file_loader/file_loader.cc
index 13ef2da..fd8d795 100644
--- a/file_loader/file_loader.cc
+++ b/file_loader/file_loader.cc
@@ -2,33 +2,32 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "lib/tonic/file_loader/file_loader.h"
+#include "tonic/file_loader/file_loader.h"
#include <iostream>
#include <memory>
#include <utility>
-#include "lib/fxl/files/directory.h"
-#include "lib/fxl/files/file.h"
-#include "lib/fxl/files/path.h"
-#include "lib/fxl/files/symlink.h"
-#include "lib/fxl/logging.h"
-#include "lib/tonic/converter/dart_converter.h"
-#include "lib/tonic/parsers/packages_map.h"
+#include "filesystem/directory.h"
+#include "filesystem/file.h"
+#include "filesystem/path.h"
+#include "filesystem/portable_unistd.h"
+#include "filesystem/symlink.h"
+#include "tonic/common/macros.h"
+#include "tonic/converter/dart_converter.h"
+#include "tonic/parsers/packages_map.h"
+#include "tonic/platform/platform_utils.h"
namespace tonic {
namespace {
-constexpr char kPackageScheme[] = "package:";
-constexpr size_t kPackageSchemeLength = sizeof(kPackageScheme) - 1;
+constexpr char kDartScheme[] = "dart:";
constexpr char kFileScheme[] = "file:";
constexpr size_t kFileSchemeLength = sizeof(kFileScheme) - 1;
-constexpr char kFileURLPrefix[] = "file://";
-constexpr size_t kFileURLPrefixLength = sizeof(kFileURLPrefix) - 1;
-
-constexpr char kDartScheme[] = "dart:";
+constexpr char kPackageScheme[] = "package:";
+constexpr size_t kPackageSchemeLength = sizeof(kPackageScheme) - 1;
// Extract the scheme prefix ('package:' or 'file:' from )
std::string ExtractSchemePrefix(std::string url) {
@@ -48,17 +47,40 @@
return url;
}
-} // namespace
+} // namespace
-FileLoader::FileLoader() {}
+FileLoader::FileLoader(int dirfd) : dirfd_(dirfd) {}
-FileLoader::~FileLoader() {}
+FileLoader::~FileLoader() {
+ if (dirfd_ >= 0)
+ close(dirfd_);
+}
-bool FileLoader::LoadPackagesMap(const std::string& packages) {
+std::string FileLoader::SanitizeURIEscapedCharacters(const std::string &str) {
+ std::string result;
+ result.reserve(str.size());
+ for (std::string::size_type i = 0; i < str.size(); ++i) {
+ if (str[i] == '%') {
+ if (i > str.size() - 3 || !isxdigit(str[i + 1]) || !isxdigit(str[i + 2]))
+ return "";
+ const std::string hex = str.substr(i + 1, 2);
+ const unsigned char c = strtoul(hex.c_str(), nullptr, 16);
+ if (!c)
+ return "";
+ result += c;
+ i += 2;
+ } else {
+ result += str[i];
+ }
+ }
+ return result;
+}
+
+bool FileLoader::LoadPackagesMap(const std::string &packages) {
packages_ = packages;
dependencies_.insert(packages_);
std::string packages_source;
- if (!files::ReadFileToString(packages_, &packages_source)) {
+ if (!ReadFileToString(packages_, &packages_source)) {
std::cerr << "error: Unable to load .packages file '" << packages_ << "'."
<< std::endl;
return false;
@@ -74,13 +96,33 @@
return true;
}
+std::string FileLoader::GetFilePathForPackageURL(std::string url) {
+ if (!packages_map_)
+ return std::string();
+ TONIC_DCHECK(url.find(kPackageScheme) == 0u);
+ url = url.substr(kPackageSchemeLength);
+
+ size_t slash = url.find(FileLoader::kPathSeparator);
+ if (slash == std::string::npos)
+ return std::string();
+ std::string package = url.substr(0, slash);
+ std::string library_path = url.substr(slash + 1);
+ std::string package_path = packages_map_->Resolve(package);
+ if (package_path.empty())
+ return std::string();
+ if (package_path.find(FileLoader::kFileURLPrefix) == 0u)
+ return SanitizePath(package_path.substr(FileLoader::kFileURLPrefixLength) +
+ library_path);
+ return filesystem::GetDirectoryName(filesystem::AbsolutePath(packages_)) +
+ FileLoader::kPathSeparator + package_path +
+ FileLoader::kPathSeparator + library_path;
+}
+
Dart_Handle FileLoader::HandleLibraryTag(Dart_LibraryTag tag,
- Dart_Handle library,
- Dart_Handle url) {
- FXL_DCHECK(Dart_IsNull(library) ||
- Dart_IsLibrary(library) ||
- Dart_IsString(library));
- FXL_DCHECK(Dart_IsString(url));
+ Dart_Handle library, Dart_Handle url) {
+ TONIC_DCHECK(Dart_IsNull(library) || Dart_IsLibrary(library) ||
+ Dart_IsString(library));
+ TONIC_DCHECK(Dart_IsString(url));
if (tag == Dart_kCanonicalizeUrl)
return CanonicalizeURL(library, url);
if (tag == Dart_kImportTag)
@@ -106,16 +148,17 @@
if (string.find(kDartScheme) == 0u)
return url;
if (string.find(kPackageScheme) == 0u)
- return url;
+ return StdStringToDart(SanitizePath(string));
if (string.find(kFileScheme) == 0u)
- return StdStringToDart(string.substr(kFileSchemeLength));
+ return StdStringToDart(SanitizePath(CanonicalizeFileURL(string)));
std::string library_url = StdStringFromDart(Dart_LibraryUrl(library));
std::string prefix = ExtractSchemePrefix(library_url);
std::string base_path = ExtractPath(library_url);
std::string simplified_path =
- files::SimplifyPath(files::GetDirectoryName(base_path) + "/" + string);
- return StdStringToDart(prefix + simplified_path);
+ filesystem::SimplifyPath(filesystem::GetDirectoryName(base_path) +
+ FileLoader::kPathSeparator + string);
+ return StdStringToDart(SanitizePath(prefix + simplified_path));
}
std::string FileLoader::GetFilePathForURL(std::string url) {
@@ -126,78 +169,61 @@
return url;
}
-std::string FileLoader::GetFilePathForPackageURL(std::string url) {
- if (!packages_map_)
- return std::string();
- FXL_DCHECK(url.find(kPackageScheme) == 0u);
- url = url.substr(kPackageSchemeLength);
- size_t slash = url.find('/');
- if (slash == std::string::npos)
- return std::string();
- std::string package = url.substr(0, slash);
- std::string library_path = url.substr(slash + 1);
- std::string package_path = packages_map_->Resolve(package);
- if (package_path.empty())
- return std::string();
- if (package_path.find(kFileURLPrefix) == 0u)
- return package_path.substr(kFileURLPrefixLength) + library_path;
- return files::GetDirectoryName(files::AbsolutePath(packages_)) + "/" +
- package_path + "/" + library_path;
-}
-
-std::string FileLoader::GetFilePathForFileURL(std::string url) {
- FXL_DCHECK(url.find(kFileURLPrefix) == 0u);
- return url.substr(kFileURLPrefixLength);
-}
-
-std::string FileLoader::GetFileURLForPath(const std::string& path) {
- return std::string(kFileURLPrefix) + path;
-}
-
-std::string FileLoader::Fetch(const std::string& url,
- std::string* resolved_url) {
- std::string path = files::SimplifyPath(GetFilePathForURL(url));
+std::string FileLoader::Fetch(const std::string &url,
+ std::string *resolved_url) {
+ std::string path = filesystem::SimplifyPath(GetFilePathForURL(url));
+ if (path.empty()) {
+ std::cerr << "error: Unable to read Dart source '" << url << "'."
+ << std::endl;
+ PlatformExit(1);
+ }
if (resolved_url)
*resolved_url = GetFileURLForPath(path);
std::string source;
- if (!files::ReadFileToString(files::GetAbsoluteFilePath(path), &source)) {
+ if (!ReadFileToString(filesystem::GetAbsoluteFilePath(path), &source)) {
// TODO(johnmccutchan): The file loader should not explicitly log the error
// or exit the process. Instead these errors should be reported to the
// caller of the FileLoader who can implement the application-specific error
// handling policy.
std::cerr << "error: Unable to read Dart source '" << url << "'."
<< std::endl;
- exit(1);
+ PlatformExit(1);
}
url_dependencies_.insert(url);
dependencies_.insert(path);
return source;
}
-std::pair<uint8_t*, intptr_t> FileLoader::FetchBytes(const std::string& url) {
- std::string path = files::SimplifyPath(GetFilePathForURL(url));
- auto result = files::ReadFileToBytes(files::GetAbsoluteFilePath(path));
+std::pair<uint8_t *, intptr_t> FileLoader::FetchBytes(const std::string &url) {
+ std::string path = filesystem::SimplifyPath(GetFilePathForURL(url));
+ if (path.empty()) {
+ std::cerr << "error: Unable to read Dart source '" << url << "'."
+ << std::endl;
+ PlatformExit(1);
+ }
+ auto result =
+ filesystem::ReadFileToBytes(filesystem::GetAbsoluteFilePath(path));
if (result.first == nullptr) {
- // TODO(aam): Same as above the file loader should not explicitly log the error
- // or exit the process. Instead these errors should be reported to the
+ // TODO(aam): Same as above the file loader should not explicitly log the
+ // error or exit the process. Instead these errors should be reported to the
// caller of the FileLoader who can implement the application-specific error
// handling policy.
std::cerr << "error: Unable to read Dart source '" << url << "'."
<< std::endl;
- exit(1);
+ PlatformExit(1);
}
url_dependencies_.insert(url);
dependencies_.insert(path);
return result;
}
-Dart_Handle FileLoader::LoadLibrary(const std::string& url) {
+Dart_Handle FileLoader::LoadLibrary(const std::string &url) {
std::string resolved_url;
Dart_Handle source = ToDart(Fetch(url, &resolved_url));
return Dart_LoadLibrary(ToDart(url), ToDart(resolved_url), source, 0, 0);
}
-Dart_Handle FileLoader::LoadScript(const std::string& url) {
+Dart_Handle FileLoader::LoadScript(const std::string &url) {
std::string resolved_url;
Dart_Handle source = ToDart(Fetch(url, &resolved_url));
Dart_Handle result =
@@ -215,21 +241,16 @@
}
namespace {
-void ReleaseFetchedBytes(uint8_t* buffer) {
- free(buffer);
-}
-}
+void ReleaseFetchedBytes(uint8_t *buffer) { free(buffer); }
+} // namespace
Dart_Handle FileLoader::Kernel(Dart_Handle url) {
std::string url_string = StdStringFromDart(url);
- std::pair<uint8_t*, intptr_t> fetched_result = FetchBytes(url_string);
+ std::pair<uint8_t *, intptr_t> fetched_result = FetchBytes(url_string);
// TODO(aam): With dartbug.com/28057 addressed, there should be no need
// to pass ownership of fetched program through Dart_ReadKernelBinary.
- void* kernel_program = Dart_ReadKernelBinary(
- fetched_result.first,
- fetched_result.second,
- ReleaseFetchedBytes
- );
+ void *kernel_program = Dart_ReadKernelBinary(
+ fetched_result.first, fetched_result.second, ReleaseFetchedBytes);
if (kernel_program == NULL) {
return Dart_NewApiError("Failed to read kernel binary");
}
@@ -253,8 +274,17 @@
LoadPackagesMap(packages());
return;
}
- const std::string& packages_url = StdStringFromDart(url);
+ const std::string &packages_url = StdStringFromDart(url);
LoadPackagesMap(packages_url);
}
-} // namespace tonic
+std::string FileLoader::GetFilePathForFileURL(std::string url) {
+ TONIC_DCHECK(url.find(FileLoader::kFileURLPrefix) == 0u);
+ return url.substr(FileLoader::kFileURLPrefixLength);
+}
+
+std::string FileLoader::GetFileURLForPath(const std::string &path) {
+ return std::string(FileLoader::kFileURLPrefix) + path;
+}
+
+} // namespace tonic
diff --git a/file_loader/file_loader.h b/file_loader/file_loader.h
index 785904f..56c8fe5 100644
--- a/file_loader/file_loader.h
+++ b/file_loader/file_loader.h
@@ -10,35 +10,32 @@
#include <string>
#include "third_party/dart/runtime/include/dart_api.h"
-#include "lib/fxl/macros.h"
-#include "lib/tonic/parsers/packages_map.h"
+#include "tonic/common/macros.h"
+#include "tonic/parsers/packages_map.h"
namespace tonic {
class FileLoader {
- public:
- FileLoader();
+public:
+ FileLoader(int dirfd = -1);
~FileLoader();
- bool LoadPackagesMap(const std::string& packages);
+ bool LoadPackagesMap(const std::string &packages);
// The path to the `.packages` file the packages map was loaded from.
- const std::string& packages() const {
- return packages_;
- }
+ const std::string &packages() const { return packages_; }
// Fully resolved file paths to dependencies. For example,
// "package:foo/bar.dart" will be resolved to
// "/path/to/package/foo/lib/bar.dart".
- const std::set<std::string>& dependencies() const { return dependencies_; }
+ const std::set<std::string> &dependencies() const { return dependencies_; }
// Canonicalized urls to dependencies. No package resolution is done,
// For example, "package:foo/bar.dart" will be "package:foo/bar.dart".
- const std::set<std::string>& url_dependencies() const {
+ const std::set<std::string> &url_dependencies() const {
return url_dependencies_;
}
- Dart_Handle HandleLibraryTag(Dart_LibraryTag tag,
- Dart_Handle library,
+ Dart_Handle HandleLibraryTag(Dart_LibraryTag tag, Dart_Handle library,
Dart_Handle url);
Dart_Handle CanonicalizeURL(Dart_Handle library, Dart_Handle url);
@@ -48,28 +45,40 @@
Dart_Handle Script(Dart_Handle url);
void SetPackagesUrl(Dart_Handle url);
- Dart_Handle LoadLibrary(const std::string& url);
- Dart_Handle LoadScript(const std::string& url);
+ Dart_Handle LoadLibrary(const std::string &url);
+ Dart_Handle LoadScript(const std::string &url);
- std::string Fetch(const std::string& url,
- std::string* resolved_url = nullptr);
- std::pair<uint8_t*, intptr_t> FetchBytes(const std::string& url);
+ std::string Fetch(const std::string &url,
+ std::string *resolved_url = nullptr);
+ std::pair<uint8_t *, intptr_t> FetchBytes(const std::string &url);
- private:
+ static const char kFileURLPrefix[];
+ static const size_t kFileURLPrefixLength;
+ static const std::string kPathSeparator;
+
+private:
+ static std::string SanitizeURIEscapedCharacters(const std::string &str);
+ static std::string SanitizePath(const std::string &path);
+ static std::string CanonicalizeFileURL(const std::string &url);
+
std::string GetFilePathForURL(std::string url);
std::string GetFilePathForPackageURL(std::string url);
std::string GetFilePathForFileURL(std::string url);
- std::string GetFileURLForPath(const std::string& path);
+ std::string GetFileURLForPath(const std::string &path);
+ bool ReadFileToString(const std::string &path, std::string *result);
+ std::pair<uint8_t *, intptr_t> ReadFileToBytes(const std::string &path);
+
+ int dirfd_;
std::set<std::string> dependencies_;
std::set<std::string> url_dependencies_;
std::string packages_;
std::unique_ptr<PackagesMap> packages_map_;
- FXL_DISALLOW_COPY_AND_ASSIGN(FileLoader);
+ TONIC_DISALLOW_COPY_AND_ASSIGN(FileLoader);
};
-} // namespace tonic
+} // namespace tonic
-#endif // LIB_TONIC_FILE_LOADER_FILE_LOADER_H_
+#endif // LIB_TONIC_FILE_LOADER_FILE_LOADER_H_
diff --git a/file_loader/file_loader_fuchsia.cc b/file_loader/file_loader_fuchsia.cc
new file mode 100644
index 0000000..e67e45f
--- /dev/null
+++ b/file_loader/file_loader_fuchsia.cc
@@ -0,0 +1,66 @@
+// Copyright 2017 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "tonic/file_loader/file_loader.h"
+
+#include <dirent.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/types.h>
+
+#include <iostream>
+#include <memory>
+#include <utility>
+
+#include "filesystem/directory.h"
+#include "filesystem/file.h"
+#include "filesystem/file_descriptor.h"
+#include "filesystem/path.h"
+#include "filesystem/symlink.h"
+#include "tonic/common/macros.h"
+#include "tonic/converter/dart_converter.h"
+#include "tonic/parsers/packages_map.h"
+
+namespace tonic {
+
+const std::string FileLoader::kPathSeparator = "/";
+const char FileLoader::kFileURLPrefix[] = "file://";
+const size_t FileLoader::kFileURLPrefixLength =
+ sizeof(FileLoader::kFileURLPrefix) - 1;
+
+namespace {
+
+const size_t kFileSchemeLength = FileLoader::kFileURLPrefixLength - 2;
+
+} // namespace
+
+std::string FileLoader::SanitizePath(const std::string &url) {
+ return SanitizeURIEscapedCharacters(url);
+}
+
+std::string FileLoader::CanonicalizeFileURL(const std::string &url) {
+ return url.substr(kFileSchemeLength);
+}
+
+bool FileLoader::ReadFileToString(const std::string &path,
+ std::string *result) {
+ if (dirfd_ == -1)
+ return filesystem::ReadFileToString(path, result);
+ const char *cpath = path.c_str();
+ const int offset = (cpath[0] == '/') ? 1 : 0;
+ filesystem::Descriptor fd(openat(dirfd_, &cpath[offset], O_RDONLY));
+ return filesystem::ReadFileDescriptorToString(fd.get(), result);
+}
+
+std::pair<uint8_t *, intptr_t>
+FileLoader::ReadFileToBytes(const std::string &path) {
+ if (dirfd_ == -1)
+ return filesystem::ReadFileToBytes(path);
+ const char *cpath = path.c_str();
+ const int offset = (cpath[0] == '/') ? 1 : 0;
+ filesystem::Descriptor fd(openat(dirfd_, &cpath[offset], O_RDONLY));
+ return filesystem::ReadFileDescriptorToBytes(fd.get());
+}
+
+} // namespace tonic
diff --git a/file_loader/file_loader_posix.cc b/file_loader/file_loader_posix.cc
new file mode 100644
index 0000000..e8920eb
--- /dev/null
+++ b/file_loader/file_loader_posix.cc
@@ -0,0 +1,52 @@
+// Copyright 2017 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "tonic/file_loader/file_loader.h"
+
+#include <iostream>
+#include <memory>
+#include <utility>
+
+#include "filesystem/directory.h"
+#include "filesystem/file.h"
+#include "filesystem/path.h"
+#include "filesystem/symlink.h"
+#include "tonic/common/macros.h"
+#include "tonic/converter/dart_converter.h"
+#include "tonic/parsers/packages_map.h"
+
+namespace tonic {
+
+const std::string FileLoader::kPathSeparator = "/";
+const char FileLoader::kFileURLPrefix[] = "file://";
+const size_t FileLoader::kFileURLPrefixLength =
+ sizeof(FileLoader::kFileURLPrefix) - 1;
+
+namespace {
+
+const size_t kFileSchemeLength = FileLoader::kFileURLPrefixLength - 2;
+
+} // namespace
+
+std::string FileLoader::SanitizePath(const std::string &url) {
+ return SanitizeURIEscapedCharacters(url);
+}
+
+std::string FileLoader::CanonicalizeFileURL(const std::string &url) {
+ return url.substr(kFileSchemeLength);
+}
+
+bool FileLoader::ReadFileToString(const std::string &path,
+ std::string *result) {
+ TONIC_DCHECK(dirfd_ == -1);
+ return filesystem::ReadFileToString(path, result);
+}
+
+std::pair<uint8_t *, intptr_t>
+FileLoader::ReadFileToBytes(const std::string &path) {
+ TONIC_DCHECK(dirfd_ == -1);
+ return filesystem::ReadFileToBytes(path);
+}
+
+} // namespace tonic
diff --git a/file_loader/file_loader_win.cc b/file_loader/file_loader_win.cc
new file mode 100644
index 0000000..2212c59
--- /dev/null
+++ b/file_loader/file_loader_win.cc
@@ -0,0 +1,58 @@
+// Copyright 2017 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "tonic/file_loader/file_loader.h"
+
+#include <iostream>
+#include <memory>
+#include <utility>
+
+#include "filesystem/directory.h"
+#include "filesystem/file.h"
+#include "filesystem/path.h"
+#include "tonic/common/macros.h"
+#include "tonic/parsers/packages_map.h"
+
+namespace tonic {
+namespace {
+
+void FindAndReplaceInPlace(std::string &str, const std::string &findStr,
+ const std::string &replaceStr) {
+ size_t pos = 0;
+ while ((pos = str.find(findStr, pos)) != std::string::npos) {
+ str.replace(pos, findStr.length(), replaceStr);
+ pos += replaceStr.length();
+ }
+}
+
+} // namespace
+
+const char FileLoader::kFileURLPrefix[] = "file:///";
+const size_t FileLoader::kFileURLPrefixLength =
+ sizeof(FileLoader::kFileURLPrefix) - 1;
+const std::string FileLoader::kPathSeparator = "\\";
+
+std::string FileLoader::SanitizePath(const std::string &url) {
+ std::string sanitized = url;
+ FindAndReplaceInPlace(sanitized, "/", FileLoader::kPathSeparator);
+ return SanitizeURIEscapedCharacters(sanitized);
+}
+
+std::string FileLoader::CanonicalizeFileURL(const std::string &url) {
+ return SanitizePath(url.substr(FileLoader::kFileURLPrefixLength));
+}
+
+bool FileLoader::ReadFileToString(const std::string &path,
+ std::string *result) {
+ TONIC_DCHECK(dirfd_ == -1);
+ return files::ReadFileToString(path, result);
+}
+
+std::pair<uint8_t *, intptr_t>
+FileLoader::ReadFileToBytes(const std::string &path) {
+ TONIC_DCHECK(dirfd_ == -1);
+ return files::ReadFileToBytes(path);
+}
+
+} // namespace tonic
diff --git a/filesystem/BUILD.gn b/filesystem/BUILD.gn
new file mode 100644
index 0000000..c61511f
--- /dev/null
+++ b/filesystem/BUILD.gn
@@ -0,0 +1,9 @@
+# Copyright 2018 The Fuchsia Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+group("filesystem") {
+ public_deps = [
+ "filesystem",
+ ]
+}
diff --git a/filesystem/README.md b/filesystem/README.md
new file mode 100644
index 0000000..a97e8f8
--- /dev/null
+++ b/filesystem/README.md
@@ -0,0 +1,4 @@
+Files
+=====
+
+A simple cross-platform library with minimal dependencies to work with files and paths.
\ No newline at end of file
diff --git a/filesystem/filesystem/BUILD.gn b/filesystem/filesystem/BUILD.gn
new file mode 100644
index 0000000..acd48c9
--- /dev/null
+++ b/filesystem/filesystem/BUILD.gn
@@ -0,0 +1,45 @@
+# Copyright 2018 The Fuchsia Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+config("filesystem_config") {
+ visibility = [ ":*" ]
+
+ # We want callers to refer to headers in this folders using the "files"
+ # prefix.
+ include_dirs = [ ".." ]
+}
+
+source_set("filesystem") {
+ visibility = [ "../*" ]
+
+ sources = [
+ "build_config.h",
+ "directory.cc",
+ "directory.h",
+ "eintr_wrapper.h",
+ "file.cc",
+ "file.h",
+ "file_descriptor.cc",
+ "file_descriptor.h",
+ "path.h",
+ "portable_unistd.h",
+ "scoped_temp_dir.cc",
+ "scoped_temp_dir.h",
+ "symlink.h",
+ ]
+
+ if (is_win) {
+ sources += [
+ "path_win.cc",
+ "symlink_win.cc",
+ ]
+ } else {
+ sources += [
+ "path_posix.cc",
+ "symlink_posix.cc",
+ ]
+ }
+
+ public_configs = [ ":filesystem_config" ]
+}
diff --git a/filesystem/filesystem/build_config.h b/filesystem/filesystem/build_config.h
new file mode 100644
index 0000000..7fdfa88
--- /dev/null
+++ b/filesystem/filesystem/build_config.h
@@ -0,0 +1,110 @@
+// Copyright 2016 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// This file adds defines about the platform we're currently building on.
+// Operating System:
+// OS_WIN / OS_MACOSX / OS_LINUX / OS_POSIX (MACOSX or LINUX) /
+// OS_NACL (NACL_SFI or NACL_NONSFI) / OS_NACL_SFI / OS_NACL_NONSFI
+// Compiler:
+// COMPILER_MSVC / COMPILER_GCC
+// Processor:
+// ARCH_CPU_X86 / ARCH_CPU_X86_64 / ARCH_CPU_X86_FAMILY (X86 or X86_64)
+// ARCH_CPU_32_BITS / ARCH_CPU_64_BITS
+
+#ifndef FILESYSTEM_BUILD_CONFIG_H_
+#define FILESYSTEM_BUILD_CONFIG_H_
+
+#if defined(__Fuchsia__)
+#define OS_FUCHSIA 1
+#elif defined(ANDROID)
+#define OS_ANDROID 1
+#elif defined(__APPLE__)
+// only include TargetConditions after testing ANDROID as some android builds
+// on mac don't have this header available and it's not needed unless the target
+// is really mac/ios.
+#include <TargetConditionals.h>
+#define OS_MACOSX 1
+#if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE
+#define OS_IOS 1
+#endif // defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE
+#elif defined(__linux__)
+#define OS_LINUX 1
+// include a system header to pull in features.h for glibc/uclibc macros.
+#include <unistd.h>
+#if defined(__GLIBC__) && !defined(__UCLIBC__)
+// we really are using glibc, not uClibc pretending to be glibc
+#define LIBC_GLIBC 1
+#endif
+#elif defined(_WIN32)
+#define OS_WIN 1
+#elif defined(__FreeBSD__)
+#define OS_FREEBSD 1
+#elif defined(__OpenBSD__)
+#define OS_OPENBSD 1
+#elif defined(__sun)
+#define OS_SOLARIS 1
+#elif defined(__QNXNTO__)
+#define OS_QNX 1
+#else
+#error Please add support for your platform in lib/fxl/build_config.h
+#endif
+
+// For access to standard BSD features, use OS_BSD instead of a
+// more specific macro.
+#if defined(OS_FREEBSD) || defined(OS_OPENBSD)
+#define OS_BSD 1
+#endif
+
+// For access to standard POSIXish features, use OS_POSIX instead of a
+// more specific macro.
+#if defined(OS_MACOSX) || defined(OS_LINUX) || defined(OS_FREEBSD) || \
+ defined(OS_OPENBSD) || defined(OS_SOLARIS) || defined(OS_ANDROID) || \
+ defined(OS_NACL) || defined(OS_QNX)
+#define OS_POSIX 1
+#endif
+
+// Processor architecture detection. For more info on what's defined, see:
+// http://msdn.microsoft.com/en-us/library/b0084kay.aspx
+// http://www.agner.org/optimize/calling_conventions.pdf
+// or with gcc, run: "echo | gcc -E -dM -"
+#if defined(_M_X64) || defined(__x86_64__)
+#define ARCH_CPU_X86_FAMILY 1
+#define ARCH_CPU_X86_64 1
+#define ARCH_CPU_64_BITS 1
+#define ARCH_CPU_LITTLE_ENDIAN 1
+#elif defined(_M_IX86) || defined(__i386__)
+#define ARCH_CPU_X86_FAMILY 1
+#define ARCH_CPU_X86 1
+#define ARCH_CPU_32_BITS 1
+#define ARCH_CPU_LITTLE_ENDIAN 1
+#elif defined(__ARMEL__)
+#define ARCH_CPU_ARM_FAMILY 1
+#define ARCH_CPU_ARMEL 1
+#define ARCH_CPU_32_BITS 1
+#define ARCH_CPU_LITTLE_ENDIAN 1
+#elif defined(__aarch64__)
+#define ARCH_CPU_ARM_FAMILY 1
+#define ARCH_CPU_ARM64 1
+#define ARCH_CPU_64_BITS 1
+#define ARCH_CPU_LITTLE_ENDIAN 1
+#elif defined(__pnacl__)
+#define ARCH_CPU_32_BITS 1
+#define ARCH_CPU_LITTLE_ENDIAN 1
+#elif defined(__MIPSEL__)
+#if defined(__LP64__)
+#define ARCH_CPU_MIPS64_FAMILY 1
+#define ARCH_CPU_MIPS64EL 1
+#define ARCH_CPU_64_BITS 1
+#define ARCH_CPU_LITTLE_ENDIAN 1
+#else
+#define ARCH_CPU_MIPS_FAMILY 1
+#define ARCH_CPU_MIPSEL 1
+#define ARCH_CPU_32_BITS 1
+#define ARCH_CPU_LITTLE_ENDIAN 1
+#endif
+#else
+#error Please add support for your architecture in build/build_config.h
+#endif
+
+#endif // FILESYSTEM_BUILD_CONFIG_H_
diff --git a/filesystem/filesystem/directory.cc b/filesystem/filesystem/directory.cc
new file mode 100644
index 0000000..837d044
--- /dev/null
+++ b/filesystem/filesystem/directory.cc
@@ -0,0 +1,59 @@
+// Copyright 2016 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "filesystem/directory.h"
+
+#include <limits.h>
+#include <sys/stat.h>
+#include <vector>
+
+#include "filesystem/path.h"
+#include "filesystem/portable_unistd.h"
+
+namespace filesystem {
+
+std::string GetCurrentDirectory() {
+ char buffer[PATH_MAX];
+ if (getcwd(buffer, sizeof(buffer)) == NULL) {
+ return {};
+ }
+ return std::string(buffer);
+}
+
+bool IsDirectory(const std::string &path) {
+ struct stat buf;
+ if (stat(path.c_str(), &buf) != 0)
+ return false;
+ return S_ISDIR(buf.st_mode);
+}
+
+bool CreateDirectory(const std::string &full_path) {
+ std::vector<std::string> subpaths;
+
+ // Collect a list of all parent directories.
+ std::string last_path = full_path;
+ subpaths.push_back(full_path);
+ for (std::string path = GetDirectoryName(full_path);
+ !path.empty() && path != last_path; path = GetDirectoryName(path)) {
+ subpaths.push_back(path);
+ last_path = path;
+ }
+
+ // Iterate through the parents and create the missing ones.
+ for (auto it = subpaths.rbegin(); it != subpaths.rend(); ++it) {
+ if (IsDirectory(*it))
+ continue;
+ if (mkdir(it->c_str(), 0700) == 0)
+ continue;
+ // Mkdir failed, but it might be due to the directory appearing out of thin
+ // air. This can occur if two processes are trying to create the same file
+ // system tree at the same time. Check to see if it exists and make sure it
+ // is a directory.
+ if (!IsDirectory(*it))
+ return false;
+ }
+ return true;
+}
+
+} // namespace filesystem
diff --git a/filesystem/filesystem/directory.h b/filesystem/filesystem/directory.h
new file mode 100644
index 0000000..9ac432d
--- /dev/null
+++ b/filesystem/filesystem/directory.h
@@ -0,0 +1,25 @@
+// Copyright 2016 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef FILESYSTEM_DIRECTORY_H_
+#define FILESYSTEM_DIRECTORY_H_
+
+#include <string>
+
+namespace filesystem {
+
+// Returns the current directory. If the current directory cannot be determined,
+// this function will terminate the process.
+std::string GetCurrentDirectory();
+
+// Returns whether the given path is a directory.
+bool IsDirectory(const std::string &path);
+
+// Create a directory at the given path. If necessary, creates any intermediary
+// directory.
+bool CreateDirectory(const std::string &path);
+
+} // namespace filesystem
+
+#endif // FILESYSTEM_DIRECTORY_H_
diff --git a/filesystem/filesystem/eintr_wrapper.h b/filesystem/filesystem/eintr_wrapper.h
new file mode 100644
index 0000000..3f666f9
--- /dev/null
+++ b/filesystem/filesystem/eintr_wrapper.h
@@ -0,0 +1,60 @@
+// Copyright 2016 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef FILESYSTEM_EINTR_WRAPPER_H_
+#define FILESYSTEM_EINTR_WRAPPER_H_
+
+#include <errno.h>
+
+#include "filesystem/build_config.h"
+
+#if defined(OS_WIN)
+
+// Windows has no concept of EINTR.
+#define HANDLE_EINTR(x) (x)
+#define IGNORE_EINTR(x) (x)
+
+#else
+
+#if defined(NDEBUG)
+
+#define HANDLE_EINTR(x) \
+ ({ \
+ decltype(x) eintr_wrapper_result; \
+ do { \
+ eintr_wrapper_result = (x); \
+ } while (eintr_wrapper_result == -1 && errno == EINTR); \
+ eintr_wrapper_result; \
+ })
+
+#else
+
+#define HANDLE_EINTR(x) \
+ ({ \
+ int eintr_wrapper_counter = 0; \
+ decltype(x) eintr_wrapper_result; \
+ do { \
+ eintr_wrapper_result = (x); \
+ } while (eintr_wrapper_result == -1 && errno == EINTR && \
+ eintr_wrapper_counter++ < 100); \
+ eintr_wrapper_result; \
+ })
+
+#endif // NDEBUG
+
+#define IGNORE_EINTR(x) \
+ ({ \
+ decltype(x) eintr_wrapper_result; \
+ do { \
+ eintr_wrapper_result = (x); \
+ if (eintr_wrapper_result == -1 && errno == EINTR) { \
+ eintr_wrapper_result = 0; \
+ } \
+ } while (0); \
+ eintr_wrapper_result; \
+ })
+
+#endif // defined(OS_WIN)
+
+#endif // FILESYSTEM_EINTR_WRAPPER_H_
diff --git a/filesystem/filesystem/file.cc b/filesystem/filesystem/file.cc
new file mode 100644
index 0000000..3f239e1
--- /dev/null
+++ b/filesystem/filesystem/file.cc
@@ -0,0 +1,161 @@
+// Copyright 2016 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "filesystem/file.h"
+
+#include <fcntl.h>
+#include <limits.h>
+#include <sys/stat.h>
+
+#if defined(OS_WIN)
+#define FILE_CREATE_MODE _S_IREAD | _S_IWRITE
+#define BINARY_MODE _O_BINARY
+#else
+#define FILE_CREATE_MODE 0666
+#define BINARY_MODE 0
+#endif
+
+#include "filesystem/eintr_wrapper.h"
+#include "filesystem/file_descriptor.h"
+#include "filesystem/portable_unistd.h"
+#include "filesystem/scoped_temp_dir.h"
+
+namespace filesystem {
+namespace {
+
+template <typename T> bool ReadFileDescriptor(int fd, T *result) {
+
+ if (!result) {
+ return false;
+ }
+
+ result->clear();
+
+ if (fd < 0)
+ return false;
+
+ constexpr size_t kBufferSize = 1 << 16;
+ size_t offset = 0;
+ ssize_t bytes_read = 0;
+ do {
+ offset += bytes_read;
+ result->resize(offset + kBufferSize);
+ bytes_read = HANDLE_EINTR(read(fd, &(*result)[offset], kBufferSize));
+ } while (bytes_read > 0);
+
+ if (bytes_read < 0) {
+ result->clear();
+ return false;
+ }
+
+ result->resize(offset + bytes_read);
+ return true;
+}
+
+} // namespace
+
+bool WriteFile(const std::string &path, const char *data, ssize_t size) {
+ Descriptor fd(HANDLE_EINTR(creat(path.c_str(), FILE_CREATE_MODE)));
+ if (!fd.is_valid())
+ return false;
+ return WriteFileDescriptor(fd.get(), data, size);
+}
+
+bool WriteFileInTwoPhases(const std::string &path, const char *data,
+ size_t data_len, const std::string &temp_root) {
+ ScopedTempDir temp_dir(temp_root);
+
+ std::string temp_file_path;
+ if (!temp_dir.NewTempFile(&temp_file_path)) {
+ return false;
+ }
+
+ if (!WriteFile(temp_file_path, data, data_len)) {
+ return false;
+ }
+
+ if (rename(temp_file_path.c_str(), path.c_str()) != 0) {
+ return false;
+ }
+
+ return true;
+}
+
+bool ReadFileToString(const std::string &path, std::string *result) {
+ Descriptor fd(open(path.c_str(), O_RDONLY));
+ return ReadFileDescriptor(fd.get(), result);
+}
+
+bool ReadFileDescriptorToString(int fd, std::string *result) {
+ return ReadFileDescriptor(fd, result);
+}
+
+#if defined(OS_LINUX) || defined(OS_FUCHSIA)
+bool ReadFileToStringAt(int dirfd, const std::string &path,
+ std::string *result) {
+ Descriptor fd(openat(dirfd, path.c_str(), O_RDONLY));
+ return ReadFileDescriptor(fd.get(), result);
+}
+#endif
+
+bool ReadFileToVector(const std::string &path, std::vector<uint8_t> *result) {
+ Descriptor fd(open(path.c_str(), O_RDONLY | BINARY_MODE));
+ return ReadFileDescriptor(fd.get(), result);
+}
+
+std::pair<uint8_t *, intptr_t> ReadFileToBytes(const std::string &path) {
+ std::pair<uint8_t *, intptr_t> failure_pair{nullptr, -1};
+ Descriptor fd(open(path.c_str(), O_RDONLY | BINARY_MODE));
+ if (!fd.is_valid())
+ return failure_pair;
+ return ReadFileDescriptorToBytes(fd.get());
+}
+
+std::pair<uint8_t *, intptr_t> ReadFileDescriptorToBytes(int fd) {
+ std::pair<uint8_t *, intptr_t> failure_pair{nullptr, -1};
+ struct stat st;
+ if (fstat(fd, &st) != 0) {
+ return failure_pair;
+ }
+ intptr_t file_size = st.st_size;
+ uint8_t *ptr = (uint8_t *)malloc(file_size);
+
+ size_t bytes_left = file_size;
+ size_t offset = 0;
+ while (bytes_left > 0) {
+ ssize_t bytes_read = HANDLE_EINTR(read(fd, &ptr[offset], bytes_left));
+ if (bytes_read < 0) {
+ return failure_pair;
+ }
+ offset += bytes_read;
+ bytes_left -= bytes_read;
+ }
+ return std::pair<uint8_t *, intptr_t>(ptr, file_size);
+}
+
+bool IsFile(const std::string &path) {
+ struct stat buf;
+ if (stat(path.c_str(), &buf) != 0)
+ return false;
+ return S_ISREG(buf.st_mode);
+}
+
+#if defined(OS_LINUX) || defined(OS_FUCHSIA)
+bool IsFileAt(int dirfd, const std::string &path) {
+ struct stat buf;
+ if (fstatat(dirfd, path.c_str(), &buf, 0 /* flags */) != 0)
+ return false;
+ return S_ISREG(buf.st_mode);
+}
+#endif
+
+bool GetFileSize(const std::string &path, uint64_t *size) {
+ struct stat stat_buffer;
+ if (stat(path.c_str(), &stat_buffer) != 0)
+ return false;
+ *size = stat_buffer.st_size;
+ return true;
+}
+
+} // namespace filesystem
diff --git a/filesystem/filesystem/file.h b/filesystem/filesystem/file.h
new file mode 100644
index 0000000..2eb55b8
--- /dev/null
+++ b/filesystem/filesystem/file.h
@@ -0,0 +1,61 @@
+// Copyright 2016 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef FILESYSTEM_FILE_H_
+#define FILESYSTEM_FILE_H_
+
+#include <string>
+#include <vector>
+
+namespace filesystem {
+
+// Writes the given data to the file at the given path. Returns true if the data
+// was successfully written, otherwise returns false.
+bool WriteFile(const std::string &path, const char *data, ssize_t size);
+
+// Writes the given data a temporary file under |temp_root| and then moves the
+// temporary file to |path|, ensuring write atomicity. Returns true if the data
+// was successfully written, otherwise returns false.
+//
+// Note that |path| and |temp_root| must be within the same filesystem for the
+// move to work. For example, it will not work to use |path| under /data and
+// |temp_root| under /tmp.
+bool WriteFileInTwoPhases(const std::string &path, const char *data,
+ size_t data_len, const std::string &temp_root);
+
+// Reads the contents of the file at the given path or file descriptor and
+// stores the data in result. Returns true if the file was read successfully,
+// otherwise returns false. If this function returns false, |result| will be
+// the empty string.
+bool ReadFileToString(const std::string &path, std::string *result);
+bool ReadFileDescriptorToString(int fd, std::string *result);
+
+#if defined(OS_LINUX) || defined(OS_FUCHSIA)
+bool ReadFileToStringAt(int dirfd, const std::string &path,
+ std::string *result);
+#endif
+
+// Reads the contents of the file at the given path and stores the data in
+// result. Returns true if the file was read successfully, otherwise returns
+// false. If this function returns false, |result| will be the empty string.
+bool ReadFileToVector(const std::string &path, std::vector<uint8_t> *result);
+
+// Reads the contents of the file at the given path and if successful, returns
+// pair of read allocated bytes with data and size of the data if succesful.
+// pair of <nullptr, -1> if read failed.
+std::pair<uint8_t *, intptr_t> ReadFileToBytes(const std::string &path);
+std::pair<uint8_t *, intptr_t> ReadFileDescriptorToBytes(int fd);
+
+// Returns whether the given path is a file.
+bool IsFile(const std::string &path);
+#if defined(OS_LINUX) || defined(OS_FUCHSIA)
+bool IsFileAt(int dirfd, const std::string &path);
+#endif
+
+// If the given path is a file, set size to the size of the file.
+bool GetFileSize(const std::string &path, uint64_t *size);
+
+} // namespace filesystem
+
+#endif // FILESYSTEM_FILE_H_
diff --git a/filesystem/filesystem/file_descriptor.cc b/filesystem/filesystem/file_descriptor.cc
new file mode 100644
index 0000000..ada584e
--- /dev/null
+++ b/filesystem/filesystem/file_descriptor.cc
@@ -0,0 +1,31 @@
+// Copyright 2016 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "filesystem/file_descriptor.h"
+
+#include "filesystem/eintr_wrapper.h"
+
+namespace filesystem {
+
+bool WriteFileDescriptor(int fd, const char *data, ssize_t size) {
+ ssize_t total = 0;
+ for (ssize_t partial = 0; total < size; total += partial) {
+ partial = HANDLE_EINTR(write(fd, data + total, size - total));
+ if (partial < 0)
+ return false;
+ }
+ return true;
+}
+
+ssize_t ReadFileDescriptor(int fd, char *data, ssize_t max_size) {
+ ssize_t total = 0;
+ for (ssize_t partial = 0; total < max_size; total += partial) {
+ partial = HANDLE_EINTR(read(fd, data + total, max_size - total));
+ if (partial <= 0)
+ return total ? total : partial;
+ }
+ return total;
+}
+
+} // namespace filesystem
diff --git a/filesystem/filesystem/file_descriptor.h b/filesystem/filesystem/file_descriptor.h
new file mode 100644
index 0000000..f439ea1
--- /dev/null
+++ b/filesystem/filesystem/file_descriptor.h
@@ -0,0 +1,44 @@
+// Copyright 2016 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef FILESYSTEM_FILE_DESCRIPTOR_H_
+#define FILESYSTEM_FILE_DESCRIPTOR_H_
+
+#include <unistd.h>
+
+#include "filesystem/eintr_wrapper.h"
+
+namespace filesystem {
+
+class Descriptor {
+public:
+ using Handle = int;
+
+ Descriptor(Handle handle) : handle_(handle) {}
+
+ ~Descriptor() {
+ if (is_valid()) {
+ IGNORE_EINTR(::close(handle_));
+ }
+ }
+
+ bool is_valid() { return handle_ >= 0; }
+
+ Handle get() { return handle_; }
+
+private:
+ Handle handle_ = -1;
+
+ Descriptor(Descriptor &) = delete;
+
+ void operator=(const Descriptor &) = delete;
+};
+
+bool WriteFileDescriptor(int fd, const char *data, ssize_t size);
+
+ssize_t ReadFileDescriptor(int fd, char *data, ssize_t max_size);
+
+} // namespace filesystem
+
+#endif // FILESYSTEM_FILE_DESCRIPTOR_H_
diff --git a/filesystem/filesystem/path.h b/filesystem/filesystem/path.h
new file mode 100644
index 0000000..a78dbcf
--- /dev/null
+++ b/filesystem/filesystem/path.h
@@ -0,0 +1,33 @@
+// Copyright 2016 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef FILESYSTEM_PATH_H_
+#define FILESYSTEM_PATH_H_
+
+#include <string>
+
+namespace filesystem {
+
+// Resolves ".." and "." components of the path syntactically without consulting
+// the file system.
+std::string SimplifyPath(std::string path);
+
+// Returns the absolute path of a possibly relative path.
+// It doesn't consult the filesystem or simplify the path.
+std::string AbsolutePath(const std::string &path);
+
+// Returns the directory name component of the given path.
+std::string GetDirectoryName(const std::string &path);
+
+// Returns the basename component of the given path by stripping everything up
+// to and including the last slash.
+std::string GetBaseName(const std::string &path);
+
+// Delete the file or directly at the given path. If recursive is true, and path
+// is a directory, also delete the directory's content.
+bool DeletePath(const std::string &path, bool recursive);
+
+} // namespace filesystem
+
+#endif // FILESYSTEM_PATH_H_
diff --git a/filesystem/filesystem/path_posix.cc b/filesystem/filesystem/path_posix.cc
new file mode 100644
index 0000000..aa2262b
--- /dev/null
+++ b/filesystem/filesystem/path_posix.cc
@@ -0,0 +1,226 @@
+// Copyright 2016 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "filesystem/path.h"
+
+#include <dirent.h>
+#include <errno.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <functional>
+#include <list>
+#include <memory>
+
+#include "filesystem/directory.h"
+
+namespace filesystem {
+namespace {
+
+size_t ResolveParentDirectoryTraversal(const std::string &path, size_t put) {
+ if (put >= 2) {
+ size_t previous_separator = path.rfind('/', put - 2);
+ if (previous_separator != std::string::npos)
+ return previous_separator + 1;
+ }
+ if (put == 1 && path[0] == '/') {
+ return put;
+ }
+ return 0;
+}
+
+void SafeCloseDir(DIR *dir) {
+ if (dir)
+ closedir(dir);
+}
+
+bool ForEachEntry(const std::string &path,
+ std::function<bool(const std::string &path)> callback) {
+ std::unique_ptr<DIR, decltype(&SafeCloseDir)> dir(opendir(path.c_str()),
+ SafeCloseDir);
+ if (!dir.get())
+ return false;
+ for (struct dirent *entry = readdir(dir.get()); entry != nullptr;
+ entry = readdir(dir.get())) {
+ char *name = entry->d_name;
+ if (name[0]) {
+ if (name[0] == '.') {
+ if (!name[1] || (name[1] == '.' && !name[2])) {
+ // . or ..
+ continue;
+ }
+ }
+ if (!callback(path + "/" + name))
+ return false;
+ }
+ }
+ return true;
+}
+
+} // namespace
+
+std::string SimplifyPath(std::string path) {
+ if (path.empty())
+ return ".";
+
+ size_t put = 0;
+ size_t get = 0;
+ size_t traversal_root = 0;
+ size_t component_start = 0;
+
+ if (path[0] == '/') {
+ put = 1;
+ get = 1;
+ component_start = 1;
+ }
+
+ while (get < path.size()) {
+ char c = path[get];
+
+ if (c == '.' && (get == component_start || get == component_start + 1)) {
+ // We've seen "." or ".." so far in this component. We need to continue
+ // searching.
+ ++get;
+ continue;
+ }
+
+ if (c == '/') {
+ if (get == component_start || get == component_start + 1) {
+ // We've found a "/" or a "./", which we can elide.
+ ++get;
+ component_start = get;
+ continue;
+ }
+ if (get == component_start + 2) {
+ // We've found a "../", which means we need to remove the previous
+ // component.
+ if (put == traversal_root) {
+ path[put++] = '.';
+ path[put++] = '.';
+ path[put++] = '/';
+ traversal_root = put;
+ } else {
+ put = ResolveParentDirectoryTraversal(path, put);
+ }
+ ++get;
+ component_start = get;
+ continue;
+ }
+ }
+
+ size_t next_separator = path.find('/', get);
+ if (next_separator == std::string::npos) {
+ // We've reached the last component.
+ break;
+ }
+ size_t next_component_start = next_separator + 1;
+ ++next_separator;
+ size_t component_size = next_component_start - component_start;
+ if (put != component_start && component_size > 0) {
+ path.replace(put, component_size,
+ path.substr(component_start, component_size));
+ }
+ put += component_size;
+ get = next_component_start;
+ component_start = next_component_start;
+ }
+
+ size_t last_component_size = path.size() - component_start;
+ if (last_component_size == 1 && path[component_start] == '.') {
+ // The last component is ".", which we can elide.
+ } else if (last_component_size == 2 && path[component_start] == '.' &&
+ path[component_start + 1] == '.') {
+ // The last component is "..", which means we need to remove the previous
+ // component.
+ if (put == traversal_root) {
+ path[put++] = '.';
+ path[put++] = '.';
+ path[put++] = '/';
+ traversal_root = put;
+ } else {
+ put = ResolveParentDirectoryTraversal(path, put);
+ }
+ } else {
+ // Otherwise, we need to copy over the last component.
+ if (put != component_start && last_component_size > 0) {
+ path.replace(put, last_component_size,
+ path.substr(component_start, last_component_size));
+ }
+ put += last_component_size;
+ }
+
+ if (put >= 2 && path[put - 1] == '/')
+ --put; // Trim trailing /
+ else if (put == 0)
+ return "."; // Use . for otherwise empty paths to treat them as relative.
+
+ path.resize(put);
+ return path;
+}
+
+std::string AbsolutePath(const std::string &path) {
+ if (path.size() > 0) {
+ if (path[0] == '/') {
+ // Path is already absolute.
+ return path;
+ }
+ return GetCurrentDirectory() + "/" + path;
+ } else {
+ // Path is empty.
+ return GetCurrentDirectory();
+ }
+}
+
+std::string GetDirectoryName(const std::string &path) {
+ size_t separator = path.rfind('/');
+ if (separator == 0u)
+ return "/";
+ if (separator == std::string::npos)
+ return std::string();
+ return path.substr(0, separator);
+}
+
+std::string GetBaseName(const std::string &path) {
+ size_t separator = path.rfind('/');
+ if (separator == std::string::npos)
+ return path;
+ return path.substr(separator + 1);
+}
+
+bool DeletePath(const std::string &path, bool recursive) {
+ struct stat stat_buffer;
+ if (lstat(path.c_str(), &stat_buffer) != 0)
+ return (errno == ENOENT || errno == ENOTDIR);
+ if (!S_ISDIR(stat_buffer.st_mode))
+ return (unlink(path.c_str()) == 0);
+ if (!recursive)
+ return (rmdir(path.c_str()) == 0);
+
+ // Use std::list, as ForEachEntry callback will modify the container. If the
+ // container is a vector, this will invalidate the reference to the content.
+ std::list<std::string> directories;
+ directories.push_back(path);
+ for (auto it = directories.begin(); it != directories.end(); ++it) {
+ if (!ForEachEntry(*it, [&directories](const std::string &child) {
+ if (IsDirectory(child)) {
+ directories.push_back(child);
+ } else {
+ if (unlink(child.c_str()) != 0)
+ return false;
+ }
+ return true;
+ })) {
+ return false;
+ }
+ }
+ for (auto it = directories.rbegin(); it != directories.rend(); ++it) {
+ if (rmdir(it->c_str()) != 0)
+ return false;
+ }
+ return true;
+}
+
+} // namespace filesystem
diff --git a/filesystem/filesystem/path_win.cc b/filesystem/filesystem/path_win.cc
new file mode 100644
index 0000000..65d84a6
--- /dev/null
+++ b/filesystem/filesystem/path_win.cc
@@ -0,0 +1,228 @@
+// Copyright 2017 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "filesystem/path.h"
+
+#include <windows.h>
+#undef GetCurrentDirectory
+
+#include <direct.h>
+#include <errno.h>
+#include <shellapi.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#include <algorithm>
+#include <functional>
+#include <list>
+#include <memory>
+
+#include "filesystem/directory.h"
+
+namespace filesystem {
+namespace {
+
+size_t RootLength(const std::string &path) {
+ if (path.size() == 0)
+ return 0;
+ if (path[0] == '/')
+ return 1;
+ if (path[0] == '\\') {
+ if (path.size() < 2 || path[1] != '\\')
+ return 1;
+ // The path is a network share. Search for up to two '\'s, as they are
+ // the server and share - and part of the root part.
+ size_t index = path.find('\\', 2);
+ if (index > 0) {
+ index = path.find('\\', index + 1);
+ if (index > 0)
+ return index;
+ }
+ return path.size();
+ }
+ // If the path is of the form 'C:/' or 'C:\', with C being any letter, it's
+ // a root part.
+ if (path.length() >= 2 && path[1] == ':' &&
+ (path[2] == '/' || path[2] == '\\') &&
+ ((path[0] >= 'A' && path[0] <= 'Z') ||
+ (path[0] >= 'a' && path[0] <= 'z'))) {
+ return 3;
+ }
+ return 0;
+}
+
+size_t IsSeparator(const char sep) { return sep == '/' || sep == '\\'; }
+
+size_t LastSeparator(const std::string &path) {
+ return path.find_last_of("/\\");
+}
+
+size_t LastSeparator(const std::string &path, size_t pos) {
+ return path.find_last_of("/\\", pos);
+}
+
+size_t FirstSeparator(const std::string &path, size_t pos) {
+ return path.find_first_of("/\\", pos);
+}
+
+size_t ResolveParentDirectoryTraversal(const std::string &path, size_t put,
+ size_t root_length) {
+ if (put <= root_length) {
+ return root_length;
+ }
+ size_t previous_separator = LastSeparator(path, put - 2);
+ if (previous_separator != std::string::npos)
+ return previous_separator + 1;
+ return 0;
+}
+} // namespace
+
+std::string SimplifyPath(std::string path) {
+ if (path.empty())
+ return ".";
+
+ size_t put = 0;
+ size_t get = 0;
+ size_t traversal_root = 0;
+ size_t component_start = 0;
+
+ size_t rootLength = RootLength(path);
+ if (rootLength > 0) {
+ put = rootLength;
+ get = rootLength;
+ component_start = rootLength;
+ }
+
+ while (get < path.size()) {
+ char c = path[get];
+
+ if (c == '.' && (get == component_start || get == component_start + 1)) {
+ // We've seen "." or ".." so far in this component. We need to continue
+ // searching.
+ ++get;
+ continue;
+ }
+
+ if (IsSeparator(c)) {
+ if (get == component_start || get == component_start + 1) {
+ // We've found a "/" or a "./", which we can elide.
+ ++get;
+ component_start = get;
+ continue;
+ }
+ if (get == component_start + 2) {
+ // We've found a "../", which means we need to remove the previous
+ // component.
+ if (put == traversal_root) {
+ path[put++] = '.';
+ path[put++] = '.';
+ path[put++] = '\\';
+ traversal_root = put;
+ } else {
+ put = ResolveParentDirectoryTraversal(path, put, rootLength);
+ }
+ ++get;
+ component_start = get;
+ continue;
+ }
+ }
+
+ size_t next_separator = FirstSeparator(path, get);
+ if (next_separator == std::string::npos) {
+ // We've reached the last component.
+ break;
+ }
+ size_t next_component_start = next_separator + 1;
+ ++next_separator;
+ size_t component_size = next_component_start - component_start;
+ if (put != component_start && component_size > 0) {
+ path.replace(put, component_size,
+ path.substr(component_start, component_size));
+ }
+ put += component_size;
+ get = next_component_start;
+ component_start = next_component_start;
+ }
+
+ size_t last_component_size = path.size() - component_start;
+ if (last_component_size == 1 && path[component_start] == '.') {
+ // The last component is ".", which we can elide.
+ } else if (last_component_size == 2 && path[component_start] == '.' &&
+ path[component_start + 1] == '.') {
+ // The last component is "..", which means we need to remove the previous
+ // component.
+ if (put == traversal_root) {
+ path[put++] = '.';
+ path[put++] = '.';
+ path[put++] = '\\';
+ traversal_root = put;
+ } else {
+ put = ResolveParentDirectoryTraversal(path, put, rootLength);
+ }
+ } else {
+ // Otherwise, we need to copy over the last component.
+ if (put != component_start && last_component_size > 0) {
+ path.replace(put, last_component_size,
+ path.substr(component_start, last_component_size));
+ }
+ put += last_component_size;
+ }
+
+ if (put >= 2 && IsSeparator(path[put - 1]))
+ --put; // Trim trailing /
+ else if (put == 0)
+ return "."; // Use . for otherwise empty paths to treat them as relative.
+
+ path.resize(put);
+ std::replace(path.begin(), path.end(), '/', '\\');
+ return path;
+}
+
+std::string AbsolutePath(const std::string &path) {
+ char absPath[MAX_PATH];
+ _fullpath(absPath, path.c_str(), MAX_PATH);
+ return std::string(absPath);
+}
+
+std::string GetDirectoryName(const std::string &path) {
+ size_t rootLength = RootLength(path);
+ size_t separator = LastSeparator(path);
+ if (separator < rootLength)
+ separator = rootLength;
+ if (separator == std::string::npos)
+ return std::string();
+ return path.substr(0, separator);
+}
+
+std::string GetBaseName(const std::string &path) {
+ size_t separator = LastSeparator(path);
+ if (separator == std::string::npos)
+ return path;
+ return path.substr(separator + 1);
+}
+
+bool DeletePath(const std::string &path, bool recursive) {
+ // SimplifyPath because SHFileOperation has trouble with double slashes.
+ std::string simple_path = SimplifyPath(path);
+ DWORD ftyp = GetFileAttributesA(simple_path.c_str());
+ if (ftyp == INVALID_FILE_ATTRIBUTES)
+ return false;
+ if (!(ftyp & FILE_ATTRIBUTE_DIRECTORY))
+ return (unlink(simple_path.c_str()) == 0);
+ if (!recursive)
+ return (rmdir(simple_path.c_str()) == 0);
+ SHFILEOPSTRUCTA file_op = {NULL,
+ FO_DELETE,
+ simple_path.c_str(),
+ "",
+ FOF_NOCONFIRMATION | FOF_NOERRORUI | FOF_SILENT,
+ false,
+ 0,
+ ""};
+ int a = SHFileOperationA(&file_op);
+ return (a == 0);
+}
+
+} // namespace filesystem
diff --git a/filesystem/filesystem/portable_unistd.h b/filesystem/filesystem/portable_unistd.h
new file mode 100644
index 0000000..e3f1451
--- /dev/null
+++ b/filesystem/filesystem/portable_unistd.h
@@ -0,0 +1,28 @@
+// Copyright 2017 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef FILESYSTEM_PORTABLE_UNISTD_H_
+#define FILESYSTEM_PORTABLE_UNISTD_H_
+
+#include "filesystem/build_config.h"
+
+#if defined(OS_WIN)
+#include <direct.h>
+#include <io.h>
+#include <stdlib.h>
+
+#define STDERR_FILENO _fileno(stderr)
+#define PATH_MAX _MAX_PATH
+
+#define S_ISDIR(m) (((m)&S_IFMT) == S_IFDIR)
+#define S_ISREG(m) (((m)&S_IFMT) == S_IFREG)
+#define R_OK 4
+
+#define mkdir(path, mode) _mkdir(path)
+
+#else
+#include <unistd.h>
+#endif
+
+#endif // FILESYSTEM_PORTABLE_UNISTD_H_
diff --git a/filesystem/filesystem/scoped_temp_dir.cc b/filesystem/filesystem/scoped_temp_dir.cc
new file mode 100644
index 0000000..9c5e648
--- /dev/null
+++ b/filesystem/filesystem/scoped_temp_dir.cc
@@ -0,0 +1,84 @@
+// Copyright 2016 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "filesystem/scoped_temp_dir.h"
+
+#include "filesystem/build_config.h"
+
+// mkdtemp - required include file
+#if defined(OS_MACOSX)
+#include <unistd.h>
+#elif defined(OS_WIN)
+#include <windows.h>
+#undef CreateDirectory
+#include "filesystem/file.h"
+#else
+#include <stdlib.h>
+#endif
+
+#include "filesystem/directory.h"
+#include "filesystem/file_descriptor.h"
+#include "filesystem/path.h"
+
+namespace filesystem {
+
+ScopedTempDir::ScopedTempDir() = default;
+
+ScopedTempDir::ScopedTempDir(std::string parent_path) {
+#if defined(OS_WIN)
+ if (parent_path.empty()) {
+ char buffer[MAX_PATH];
+ DWORD ret = GetTempPathA(MAX_PATH, buffer);
+ if (ret > MAX_PATH || (ret == 0)) {
+ directory_path_ = "";
+ return;
+ }
+ parent_path = {buffer};
+ }
+ do {
+ directory_path_ = parent_path.ToString() + "\\" + fxl::GenerateUUID();
+ } while (IsFile(directory_path_) || IsDirectory(directory_path_));
+ if (!CreateDirectory(directory_path_)) {
+ directory_path_ = "";
+ }
+#else
+ if (parent_path.empty()) {
+ const char *env_var = getenv("TMPDIR");
+ parent_path = env_var ? std::string{env_var} : "/tmp";
+ }
+ // mkdtemp replaces "XXXXXX" so that the resulting directory path is unique.
+ directory_path_ = parent_path + "/temp_dir_XXXXXX";
+ if (!CreateDirectory(parent_path) || !mkdtemp(&directory_path_[0])) {
+ directory_path_ = "";
+ }
+#endif
+}
+
+ScopedTempDir::~ScopedTempDir() {
+ if (directory_path_.size()) {
+ DeletePath(directory_path_, true);
+ }
+}
+
+const std::string &ScopedTempDir::path() { return directory_path_; }
+
+bool ScopedTempDir::NewTempFile(std::string *output) {
+#if defined(OS_WIN)
+ char buffer[MAX_PATH];
+ UINT ret = GetTempFileNameA(directory_path_.c_str(), "", 0, buffer);
+ output->swap(std::string(buffer));
+ return (ret != 0);
+#else
+ // mkstemp replaces "XXXXXX" so that the resulting file path is unique.
+ std::string file_path = directory_path_ + "/XXXXXX";
+ filesystem::Descriptor fd(mkstemp(&file_path[0]));
+ if (!fd.is_valid()) {
+ return false;
+ }
+ output->swap(file_path);
+ return true;
+#endif
+}
+
+} // namespace filesystem
diff --git a/filesystem/filesystem/scoped_temp_dir.h b/filesystem/filesystem/scoped_temp_dir.h
new file mode 100644
index 0000000..325c816
--- /dev/null
+++ b/filesystem/filesystem/scoped_temp_dir.h
@@ -0,0 +1,30 @@
+// Copyright 2016 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef FILESYSTEM_SCOPED_TEMP_DIR_H_
+#define FILESYSTEM_SCOPED_TEMP_DIR_H_
+
+#include <string>
+
+namespace filesystem {
+
+class ScopedTempDir {
+public:
+ ScopedTempDir();
+
+ explicit ScopedTempDir(std::string parent_path);
+
+ ~ScopedTempDir();
+
+ const std::string &path();
+
+ bool NewTempFile(std::string *output);
+
+private:
+ std::string directory_path_;
+};
+
+} // namespace filesystem
+
+#endif // FILESYSTEM_SCOPED_TEMP_DIR_H_
diff --git a/filesystem/filesystem/symlink.h b/filesystem/filesystem/symlink.h
new file mode 100644
index 0000000..b3e39ae
--- /dev/null
+++ b/filesystem/filesystem/symlink.h
@@ -0,0 +1,23 @@
+// Copyright 2016 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef FILESYSTEM_SYMLINK_H_
+#define FILESYSTEM_SYMLINK_H_
+
+#include <string>
+
+namespace filesystem {
+
+// If |path| is a symbolic link, this function will return true and set
+// |resolved_path| to the path pointed to by the symbolic link. Otherwise,
+// this function will return false and |resolved_path| will be the empty string.
+bool ReadSymbolicLink(const std::string &path, std::string *resolved_path);
+
+// Returns the real path for the given path by unwinding symbolic links and
+// directory traversals.
+std::string GetAbsoluteFilePath(const std::string &path);
+
+} // namespace filesystem
+
+#endif // FILESYSTEM_SYMLINK_H_
diff --git a/filesystem/filesystem/symlink_posix.cc b/filesystem/filesystem/symlink_posix.cc
new file mode 100644
index 0000000..4b942ea
--- /dev/null
+++ b/filesystem/filesystem/symlink_posix.cc
@@ -0,0 +1,44 @@
+// Copyright 2016 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "filesystem/symlink.h"
+
+#include <limits.h>
+#include <unistd.h>
+
+#include "filesystem/build_config.h"
+#include "filesystem/path.h"
+
+namespace filesystem {
+
+bool ReadSymbolicLink(const std::string &path, std::string *resolved_path) {
+ if (path.empty() || resolved_path == nullptr) {
+ return false;
+ }
+
+ char buffer[PATH_MAX];
+ ssize_t length = readlink(path.c_str(), buffer, sizeof(buffer));
+
+ if (length <= 0) {
+ resolved_path->clear();
+ return false;
+ }
+
+ *resolved_path = std::string(buffer, length);
+ return true;
+}
+
+std::string GetAbsoluteFilePath(const std::string &path) {
+#if defined(OS_FUCHSIA)
+ // realpath() isn't supported by Fuchsia. See MG-425.
+ return SimplifyPath(AbsolutePath(path));
+#else
+ char buffer[PATH_MAX];
+ if (realpath(path.c_str(), buffer) == nullptr)
+ return std::string();
+ return buffer;
+#endif // defined(OS_FUCHSIA)
+}
+
+} // namespace filesystem
diff --git a/filesystem/filesystem/symlink_win.cc b/filesystem/filesystem/symlink_win.cc
new file mode 100644
index 0000000..47e6d0f
--- /dev/null
+++ b/filesystem/filesystem/symlink_win.cc
@@ -0,0 +1,44 @@
+// Copyright 2017 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "filesystem/symlink.h"
+
+#include <windows.h>
+#include <winioctl.h>
+
+#include <iostream>
+
+namespace filesystem {
+
+struct UniqueHandleTraits {
+ static HANDLE InvalidValue() { return INVALID_HANDLE_VALUE; }
+ static bool IsValid(HANDLE value) { return value != INVALID_HANDLE_VALUE; }
+ static void Free(HANDLE value) { CloseHandle(value); }
+};
+
+bool ReadSymbolicLink(const std::string &path, std::string *resolved_path) {
+ FXL_CHECK(false) << "Unimplemented";
+ return false;
+}
+
+std::string GetAbsoluteFilePath(const std::string &path) {
+ fxl::UniqueObject<HANDLE, UniqueHandleTraits> file(
+ CreateFileA(path.c_str(), FILE_READ_ATTRIBUTES,
+ FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL,
+ OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL));
+ if (!file.is_valid()) {
+ return std::string();
+ }
+ char buffer[MAX_PATH];
+ DWORD ret = GetFinalPathNameByHandleA(file.get(), buffer, MAX_PATH,
+ FILE_NAME_NORMALIZED);
+ if (ret == 0 || ret > MAX_PATH) {
+ return std::string();
+ }
+ std::string result(buffer);
+ result.erase(0, strlen("\\\\?\\"));
+ return result;
+}
+
+} // namespace filesystem
diff --git a/filesystem/tests/BUILD.gn b/filesystem/tests/BUILD.gn
new file mode 100644
index 0000000..10524e3
--- /dev/null
+++ b/filesystem/tests/BUILD.gn
@@ -0,0 +1,20 @@
+# Copyright 2018 The Fuchsia Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+executable("files_unittests") {
+ testonly = true
+
+ sources = [
+ "directory_unittest.cc",
+ "file_descriptor_unittest.cc",
+ "file_unittest.cc",
+ "files_unittest_main.cc",
+ "path_unittest.cc",
+ "scoped_temp_dir_unittest.cc",
+ ]
+
+ deps = [
+ ":../:filesystem",
+ ]
+}
diff --git a/filesystem/tests/directory_unittest.cc b/filesystem/tests/directory_unittest.cc
new file mode 100644
index 0000000..524e2fc
--- /dev/null
+++ b/filesystem/tests/directory_unittest.cc
@@ -0,0 +1,37 @@
+// Copyright 2017 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "filesystem/directory.h"
+#include "filesystem/path.h"
+#include "filesystem/scoped_temp_dir.h"
+#include "gtest/gtest.h"
+
+namespace filesystem {
+
+TEST(Directory, CreateDirectory) {
+ std::string cwd = GetCurrentDirectory();
+
+ ScopedTempDir dir;
+ EXPECT_TRUE(IsDirectory(dir.path()));
+ EXPECT_EQ(0, chdir(dir.path().c_str()));
+
+ EXPECT_TRUE(CreateDirectory("foo/bar"));
+ EXPECT_TRUE(IsDirectory("foo"));
+ EXPECT_TRUE(IsDirectory("foo/bar"));
+ EXPECT_FALSE(IsDirectory("foo/bar/baz"));
+
+ EXPECT_TRUE(CreateDirectory("foo/bar/baz"));
+ EXPECT_TRUE(IsDirectory("foo/bar/baz"));
+
+ EXPECT_TRUE(CreateDirectory("qux"));
+ EXPECT_TRUE(IsDirectory("qux"));
+
+ EXPECT_EQ(0, chdir(cwd.c_str()));
+
+ std::string abs_path = dir.path() + "/another/one";
+ EXPECT_TRUE(CreateDirectory(abs_path));
+ EXPECT_TRUE(IsDirectory(abs_path));
+}
+
+} // namespace filesystem
diff --git a/filesystem/tests/file_descriptor_unittest.cc b/filesystem/tests/file_descriptor_unittest.cc
new file mode 100644
index 0000000..bebdb97
--- /dev/null
+++ b/filesystem/tests/file_descriptor_unittest.cc
@@ -0,0 +1,39 @@
+// Copyright 2017 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "filesystem/file_descriptor.h"
+#include "lib/fxl/portable_unistd.h"
+
+#include <fcntl.h>
+#include <sys/types.h>
+
+#include <string>
+#include <vector>
+
+#include "filesystem/scoped_temp_dir.h"
+#include "filesystem/unique_fd.h"
+#include "gtest/gtest.h"
+
+namespace filesystem {
+
+TEST(FileDescriptor, WriteAndRead) {
+ files::ScopedTempDir temp_dir;
+ std::string path;
+ ASSERT_TRUE(temp_dir.NewTempFile(&path));
+
+ fxl::UniqueFD fd(open(path.c_str(), O_RDWR));
+ ASSERT_TRUE(fd.is_valid());
+
+ std::string string = "one, two, three";
+ EXPECT_TRUE(WriteFileDescriptor(fd.get(), string.data(), string.size()));
+ EXPECT_EQ(0, lseek(fd.get(), 0, SEEK_SET));
+
+ std::vector<char> buffer;
+ buffer.resize(1024);
+ ssize_t read = ReadFileDescriptor(fd.get(), buffer.data(), 1024);
+ EXPECT_EQ(static_cast<ssize_t>(string.size()), read);
+ EXPECT_EQ(string, buffer.data());
+}
+
+} // namespace filesystem
diff --git a/filesystem/tests/file_unittest.cc b/filesystem/tests/file_unittest.cc
new file mode 100644
index 0000000..33a4e27
--- /dev/null
+++ b/filesystem/tests/file_unittest.cc
@@ -0,0 +1,57 @@
+// Copyright 2016 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "filesystem/file.h"
+
+#include <fcntl.h>
+
+#include "filesystem/path.h"
+#include "filesystem/scoped_temp_dir.h"
+#include "gtest/gtest.h"
+
+namespace filesystem {
+namespace {
+
+TEST(File, GetFileSize) {
+ ScopedTempDir dir;
+ std::string path;
+
+ ASSERT_TRUE(dir.NewTempFile(&path));
+
+ uint64_t size;
+ EXPECT_TRUE(GetFileSize(path, &size));
+ EXPECT_EQ(0u, size);
+
+ std::string content = "Hello World";
+ ASSERT_TRUE(WriteFile(path, content.data(), content.size()));
+ EXPECT_TRUE(GetFileSize(path, &size));
+ EXPECT_EQ(content.size(), size);
+}
+
+TEST(File, WriteFileInTwoPhases) {
+ ScopedTempDir dir;
+ std::string path = dir.path() + "/destination";
+
+ std::string content = "Hello World";
+ ASSERT_TRUE(WriteFileInTwoPhases(path, content, dir.path()));
+ std::string read_content;
+ ASSERT_TRUE(ReadFileToString(path, &read_content));
+ EXPECT_EQ(read_content, content);
+}
+
+#if defined(OS_LINUX) || defined(OS_FUCHSIA)
+TEST(File, IsFileAt) {
+ ScopedTempDir dir;
+ std::string path;
+
+ ASSERT_TRUE(dir.NewTempFile(&path));
+
+ fxl::UniqueFD dirfd(open(dir.path().c_str(), O_RDONLY));
+ ASSERT_TRUE(dirfd.get() != -1);
+ EXPECT_TRUE(IsFileAt(dirfd.get(), GetBaseName(path)));
+}
+#endif
+
+} // namespace
+} // namespace filesystem
diff --git a/filesystem/tests/files_unittest_main.cc b/filesystem/tests/files_unittest_main.cc
new file mode 100644
index 0000000..34362c9
--- /dev/null
+++ b/filesystem/tests/files_unittest_main.cc
@@ -0,0 +1,5 @@
+// Copyright 2018 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "gtest/gtest.h"
diff --git a/filesystem/tests/path_unittest.cc b/filesystem/tests/path_unittest.cc
new file mode 100644
index 0000000..875e8ad
--- /dev/null
+++ b/filesystem/tests/path_unittest.cc
@@ -0,0 +1,234 @@
+// Copyright 2016 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "filesystem/build_config.h"
+#include "filesystem/directory.h"
+#include "filesystem/path.h"
+#include "filesystem/scoped_temp_dir.h"
+#include "gtest/gtest.h"
+
+namespace filesystem {
+
+void ExpectPlatformPath(std::string expected, std::string actual) {
+#if defined(OS_WIN)
+ std::replace(expected.begin(), expected.end(), '/', '\\');
+#endif
+ EXPECT_EQ(expected, actual);
+}
+
+TEST(Path, SimplifyPath) {
+ ExpectPlatformPath(".", SimplifyPath(""));
+ ExpectPlatformPath(".", SimplifyPath("."));
+ ExpectPlatformPath("..", SimplifyPath(".."));
+ ExpectPlatformPath("...", SimplifyPath("..."));
+
+ ExpectPlatformPath("/", SimplifyPath("/"));
+ ExpectPlatformPath("/", SimplifyPath("/."));
+ ExpectPlatformPath("/", SimplifyPath("/.."));
+ ExpectPlatformPath("/...", SimplifyPath("/..."));
+
+ ExpectPlatformPath("foo", SimplifyPath("foo"));
+ ExpectPlatformPath("foo", SimplifyPath("foo/"));
+ ExpectPlatformPath("foo", SimplifyPath("foo/."));
+ ExpectPlatformPath("foo", SimplifyPath("foo/./"));
+ ExpectPlatformPath(".", SimplifyPath("foo/.."));
+ ExpectPlatformPath(".", SimplifyPath("foo/../"));
+ ExpectPlatformPath("foo/...", SimplifyPath("foo/..."));
+ ExpectPlatformPath("foo/...", SimplifyPath("foo/.../"));
+ ExpectPlatformPath("foo/.b", SimplifyPath("foo/.b"));
+ ExpectPlatformPath("foo/.b", SimplifyPath("foo/.b/"));
+
+ ExpectPlatformPath("/foo", SimplifyPath("/foo"));
+ ExpectPlatformPath("/foo", SimplifyPath("/foo/"));
+ ExpectPlatformPath("/foo", SimplifyPath("/foo/."));
+ ExpectPlatformPath("/foo", SimplifyPath("/foo/./"));
+ ExpectPlatformPath("/", SimplifyPath("/foo/.."));
+ ExpectPlatformPath("/", SimplifyPath("/foo/../"));
+ ExpectPlatformPath("/foo/...", SimplifyPath("/foo/..."));
+ ExpectPlatformPath("/foo/...", SimplifyPath("/foo/.../"));
+ ExpectPlatformPath("/foo/.b", SimplifyPath("/foo/.b"));
+ ExpectPlatformPath("/foo/.b", SimplifyPath("/foo/.b/"));
+
+ ExpectPlatformPath("foo/bar", SimplifyPath("foo/bar"));
+ ExpectPlatformPath("foo/bar", SimplifyPath("foo/bar/"));
+ ExpectPlatformPath("foo/bar", SimplifyPath("foo/./bar"));
+ ExpectPlatformPath("foo/bar", SimplifyPath("foo/./bar/"));
+ ExpectPlatformPath("bar", SimplifyPath("foo/../bar"));
+ ExpectPlatformPath("bar", SimplifyPath("foo/baz/../../bar"));
+ ExpectPlatformPath("bar", SimplifyPath("foo/../bar/"));
+ ExpectPlatformPath("foo/.../bar", SimplifyPath("foo/.../bar"));
+ ExpectPlatformPath("foo/.../bar", SimplifyPath("foo/.../bar/"));
+ ExpectPlatformPath("foo/.b/bar", SimplifyPath("foo/.b/bar"));
+ ExpectPlatformPath("foo/.b/bar", SimplifyPath("foo/.b/bar/"));
+
+ ExpectPlatformPath("/foo/bar", SimplifyPath("/foo/bar"));
+ ExpectPlatformPath("/foo/bar", SimplifyPath("/foo/bar/"));
+ ExpectPlatformPath("/foo/bar", SimplifyPath("/foo/./bar"));
+ ExpectPlatformPath("/foo/bar", SimplifyPath("/foo/./bar/"));
+ ExpectPlatformPath("/bar", SimplifyPath("/foo/../bar"));
+ ExpectPlatformPath("/bar", SimplifyPath("/foo/../bar/"));
+ ExpectPlatformPath("/foo/.../bar", SimplifyPath("/foo/.../bar"));
+ ExpectPlatformPath("/foo/.../bar", SimplifyPath("/foo/.../bar/"));
+ ExpectPlatformPath("/foo/.b/bar", SimplifyPath("/foo/.b/bar"));
+ ExpectPlatformPath("/foo/.b/bar", SimplifyPath("/foo/.b/bar/"));
+
+ ExpectPlatformPath("../foo", SimplifyPath("../foo"));
+ ExpectPlatformPath("../../bar", SimplifyPath("../foo/../../bar"));
+ ExpectPlatformPath("/bar", SimplifyPath("/foo/../../bar"));
+
+ // Already clean
+ ExpectPlatformPath(".", SimplifyPath(""));
+ ExpectPlatformPath("abc", SimplifyPath("abc"));
+ ExpectPlatformPath("abc/def", SimplifyPath("abc/def"));
+ ExpectPlatformPath("a/b/c", SimplifyPath("a/b/c"));
+ ExpectPlatformPath(".", SimplifyPath("."));
+ ExpectPlatformPath("..", SimplifyPath(".."));
+ ExpectPlatformPath("../..", SimplifyPath("../.."));
+ ExpectPlatformPath("../../abc", SimplifyPath("../../abc"));
+ ExpectPlatformPath("/abc", SimplifyPath("/abc"));
+ ExpectPlatformPath("/", SimplifyPath("/"));
+
+ // Remove trailing slash
+ ExpectPlatformPath("abc", SimplifyPath("abc/"));
+ ExpectPlatformPath("abc/def", SimplifyPath("abc/def/"));
+ ExpectPlatformPath("a/b/c", SimplifyPath("a/b/c/"));
+ ExpectPlatformPath(".", SimplifyPath("./"));
+ ExpectPlatformPath("..", SimplifyPath("../"));
+ ExpectPlatformPath("../..", SimplifyPath("../../"));
+ ExpectPlatformPath("/abc", SimplifyPath("/abc/"));
+
+ // Remove doubled slash
+ ExpectPlatformPath("abc/def/ghi", SimplifyPath("abc//def//ghi"));
+ ExpectPlatformPath("/abc", SimplifyPath("//abc"));
+ ExpectPlatformPath("/abc", SimplifyPath("///abc"));
+ ExpectPlatformPath("/abc", SimplifyPath("//abc//"));
+ ExpectPlatformPath("abc", SimplifyPath("abc//"));
+
+ // Remove . elements
+ ExpectPlatformPath("abc/def", SimplifyPath("abc/./def"));
+ ExpectPlatformPath("/abc/def", SimplifyPath("/./abc/def"));
+ ExpectPlatformPath("abc", SimplifyPath("abc/."));
+
+ // Remove .. elements
+ ExpectPlatformPath("abc/def/jkl", SimplifyPath("abc/def/ghi/../jkl"));
+ ExpectPlatformPath("abc/jkl", SimplifyPath("abc/def/../ghi/../jkl"));
+ ExpectPlatformPath("abc", SimplifyPath("abc/def/.."));
+ ExpectPlatformPath(".", SimplifyPath("abc/def/../.."));
+ ExpectPlatformPath("/", SimplifyPath("/abc/def/../.."));
+ ExpectPlatformPath("..", SimplifyPath("abc/def/../../.."));
+ ExpectPlatformPath("/", SimplifyPath("/abc/def/../../.."));
+ ExpectPlatformPath("../../mno",
+ SimplifyPath("abc/def/../../../ghi/jkl/../../../mno"));
+ ExpectPlatformPath("/mno", SimplifyPath("/../mno"));
+
+ // Combinations
+ ExpectPlatformPath("def", SimplifyPath("abc/./../def"));
+ ExpectPlatformPath("def", SimplifyPath("abc//./../def"));
+ ExpectPlatformPath("../../def", SimplifyPath("abc/../../././../def"));
+
+#if defined(OS_WIN)
+ ExpectPlatformPath("a\\c", SimplifyPath("a\\b\\..\\c"));
+ ExpectPlatformPath("X:\\a\\c", SimplifyPath("X:/a/b/../c"));
+ ExpectPlatformPath("X:\\a\\b\\c", SimplifyPath("X:/a/b/./c"));
+ ExpectPlatformPath("X:\\c", SimplifyPath("X:/../../c"));
+#endif
+}
+
+TEST(Path, AbsolutePath) {
+#if defined(OS_WIN)
+ // We cut out the drive letter as it can be different on every system.
+ EXPECT_EQ(":\\foo\\bar", AbsolutePath("\\foo\\bar").substr(1));
+ EXPECT_EQ(":\\foo\\bar", AbsolutePath("/foo/bar").substr(1));
+ EXPECT_EQ(":\\foo\\bar\\", AbsolutePath("\\foo\\bar\\").substr(1));
+ EXPECT_EQ(":\\foo\\bar\\", AbsolutePath("/foo/bar/").substr(1));
+ EXPECT_EQ("C:\\foo\\bar\\", AbsolutePath("C:\\foo\\bar\\"));
+ EXPECT_EQ(GetCurrentDirectory() + "\\foo", AbsolutePath("foo"));
+#else
+ EXPECT_EQ("/foo/bar", AbsolutePath("/foo/bar"));
+ EXPECT_EQ("/foo/bar/", AbsolutePath("/foo/bar/"));
+ EXPECT_EQ(GetCurrentDirectory() + "/foo", AbsolutePath("foo"));
+#endif
+ EXPECT_EQ(GetCurrentDirectory(), AbsolutePath(""));
+}
+
+TEST(Path, GetDirectoryName) {
+ EXPECT_EQ("foo", GetDirectoryName("foo/"));
+ EXPECT_EQ("foo/bar", GetDirectoryName("foo/bar/"));
+ EXPECT_EQ("foo", GetDirectoryName("foo/bar"));
+ EXPECT_EQ("foo/bar", GetDirectoryName("foo/bar/.."));
+ EXPECT_EQ("foo/bar/..", GetDirectoryName("foo/bar/../.."));
+ EXPECT_EQ("", GetDirectoryName("foo"));
+ EXPECT_EQ("/", GetDirectoryName("/"));
+ EXPECT_EQ("", GetDirectoryName("a"));
+ EXPECT_EQ("/", GetDirectoryName("/a"));
+ EXPECT_EQ("/a", GetDirectoryName("/a/"));
+ EXPECT_EQ("a", GetDirectoryName("a/"));
+#if defined(OS_WIN)
+ EXPECT_EQ("C:\\", GetDirectoryName("C:\\"));
+ EXPECT_EQ("C:\\foo", GetDirectoryName("C:\\foo\\"));
+ EXPECT_EQ("C:\\foo", GetDirectoryName("C:\\foo\\bar"));
+ EXPECT_EQ("foo\\bar", GetDirectoryName("foo\\bar\\"));
+ EXPECT_EQ("foo", GetDirectoryName("foo\\bar"));
+ EXPECT_EQ("\\", GetDirectoryName("\\"));
+ EXPECT_EQ("\\", GetDirectoryName("\\a"));
+#endif
+}
+
+TEST(Path, GetBaseName) {
+ EXPECT_EQ("", GetBaseName("foo/"));
+ EXPECT_EQ("", GetBaseName("foo/bar/"));
+ EXPECT_EQ("bar", GetBaseName("foo/bar"));
+ EXPECT_EQ("..", GetBaseName("foo/bar/.."));
+ EXPECT_EQ("..", GetBaseName("foo/bar/../.."));
+ EXPECT_EQ("foo", GetBaseName("foo"));
+ EXPECT_EQ("", GetBaseName("/"));
+ EXPECT_EQ("a", GetBaseName("a"));
+ EXPECT_EQ("a", GetBaseName("/a"));
+ EXPECT_EQ("", GetBaseName("/a/"));
+ EXPECT_EQ("", GetBaseName("a/"));
+#if defined(OS_WIN)
+ EXPECT_EQ("", GetBaseName("C:\\"));
+ EXPECT_EQ("", GetBaseName("C:\\foo\\"));
+ EXPECT_EQ("bar", GetBaseName("C:\\foo\\bar"));
+ EXPECT_EQ("", GetBaseName("foo\\bar\\"));
+ EXPECT_EQ("bar", GetBaseName("foo\\bar"));
+ EXPECT_EQ("", GetBaseName("\\"));
+ EXPECT_EQ("a", GetBaseName("\\a"));
+#endif
+}
+
+TEST(Path, DeletePath) {
+ ScopedTempDir dir;
+
+ std::string sub_dir = dir.path() + "/dir";
+ CreateDirectory(sub_dir);
+ EXPECT_TRUE(IsDirectory(sub_dir));
+ EXPECT_TRUE(DeletePath(sub_dir, false));
+ EXPECT_FALSE(IsDirectory(sub_dir));
+}
+
+TEST(Path, DeletePathRecursively) {
+ ScopedTempDir dir;
+
+ std::string sub_dir = dir.path() + "/dir";
+ CreateDirectory(sub_dir);
+ EXPECT_TRUE(IsDirectory(sub_dir));
+
+ std::string sub_sub_dir1 = sub_dir + "/dir1";
+ CreateDirectory(sub_sub_dir1);
+ EXPECT_TRUE(IsDirectory(sub_sub_dir1));
+ std::string sub_sub_dir2 = sub_dir + "/dir2";
+ CreateDirectory(sub_sub_dir2);
+ EXPECT_TRUE(IsDirectory(sub_sub_dir2));
+
+ EXPECT_FALSE(DeletePath(sub_dir, false));
+ EXPECT_TRUE(IsDirectory(sub_dir));
+ EXPECT_TRUE(IsDirectory(sub_sub_dir1));
+
+ EXPECT_TRUE(DeletePath(sub_dir, true));
+ EXPECT_FALSE(IsDirectory(sub_dir));
+ EXPECT_FALSE(IsDirectory(sub_sub_dir1));
+}
+
+} // namespace filesystem
diff --git a/filesystem/tests/scoped_temp_dir_unittest.cc b/filesystem/tests/scoped_temp_dir_unittest.cc
new file mode 100644
index 0000000..1973c4b
--- /dev/null
+++ b/filesystem/tests/scoped_temp_dir_unittest.cc
@@ -0,0 +1,56 @@
+// Copyright 2016 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "filesystem/directory.h"
+#include "filesystem/path.h"
+#include "filesystem/scoped_temp_dir.h"
+#include "gtest/gtest.h"
+
+namespace filesystem {
+
+TEST(ScopedTempDir, Creation) {
+ ScopedTempDir dir;
+
+ EXPECT_TRUE(IsDirectory(dir.path()));
+}
+
+TEST(ScopedTempDir, Deletion) {
+ std::string path;
+ {
+ ScopedTempDir dir;
+ path = dir.path();
+ }
+
+ EXPECT_FALSE(IsDirectory(path));
+}
+
+TEST(ScopedTempDir, NewTempFile) {
+ ScopedTempDir dir;
+ std::string path;
+ EXPECT_TRUE(dir.NewTempFile(&path));
+ EXPECT_FALSE(path.empty());
+}
+
+TEST(ScopedTempDir, CustomParent) {
+ ScopedTempDir root_dir;
+ std::string parent = root_dir.path() + "/a/b/c";
+ std::string path;
+ {
+ ScopedTempDir dir(parent);
+ path = dir.path();
+ EXPECT_TRUE(IsDirectory(path));
+ EXPECT_EQ(path.substr(0, parent.size()), parent);
+ EXPECT_NE("temp_dir_XXXXXX", GetBaseName(path));
+
+ // Regression test - don't create temp_dir_XXXXXX dir next to the temp one.
+ EXPECT_FALSE(
+ files::IsDirectory(GetDirectoryName(path) + "/temp_dir_XXXXXX"));
+ }
+
+ // Verify that the tmp directory itself was deleted, but not the parent.
+ EXPECT_FALSE(IsDirectory(path));
+ EXPECT_TRUE(IsDirectory(parent));
+}
+
+} // namespace filesystem
diff --git a/logging/BUILD.gn b/logging/BUILD.gn
index 1b53b51..504a44d 100644
--- a/logging/BUILD.gn
+++ b/logging/BUILD.gn
@@ -3,6 +3,10 @@
# found in the LICENSE file.
source_set("logging") {
+ visibility = [ "../*" ]
+
+ configs += [ "../:config" ]
+
sources = [
"dart_error.cc",
"dart_error.h",
@@ -10,12 +14,11 @@
"dart_invoke.h",
]
- public_deps = [
- "//third_party/dart/runtime:dart_api",
- "//garnet/public/lib/fxl",
+ deps = [
+ "../common",
]
- public_configs = [
- "//topaz/lib/tonic:config",
+ public_deps = [
+ "//third_party/dart/runtime:dart_api",
]
}
diff --git a/logging/dart_error.cc b/logging/dart_error.cc
index 08de6cc..f1a4646 100644
--- a/logging/dart_error.cc
+++ b/logging/dart_error.cc
@@ -2,18 +2,18 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "lib/tonic/logging/dart_error.h"
+#include "tonic/logging/dart_error.h"
-#include "lib/fxl/logging.h"
+#include "tonic/common/macros.h"
namespace tonic {
namespace DartError {
const char kInvalidArgument[] = "Invalid argument.";
-} // namespace DartError
+} // namespace DartError
bool LogIfError(Dart_Handle handle) {
if (Dart_IsError(handle)) {
- FXL_LOG(ERROR) << Dart_GetError(handle);
+ TONIC_LOG("Dart Error: %s", Dart_GetError(handle));
return true;
}
return false;
@@ -31,4 +31,4 @@
}
}
-} // namespace tonic
+} // namespace tonic
diff --git a/logging/dart_invoke.cc b/logging/dart_invoke.cc
index 4ab05aa..0255114 100644
--- a/logging/dart_invoke.cc
+++ b/logging/dart_invoke.cc
@@ -2,24 +2,23 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "lib/tonic/logging/dart_invoke.h"
+#include "tonic/logging/dart_invoke.h"
-#include "lib/fxl/logging.h"
-#include "lib/tonic/logging/dart_error.h"
+#include "tonic/common/macros.h"
+#include "tonic/logging/dart_error.h"
namespace tonic {
-bool DartInvokeField(Dart_Handle target,
- const char* name,
+bool DartInvokeField(Dart_Handle target, const char *name,
std::initializer_list<Dart_Handle> args) {
Dart_Handle field = Dart_NewStringFromCString(name);
return LogIfError(Dart_Invoke(target, field, args.size(),
- const_cast<Dart_Handle*>(args.begin())));
+ const_cast<Dart_Handle *>(args.begin())));
}
void DartInvoke(Dart_Handle closure, std::initializer_list<Dart_Handle> args) {
int argc = args.size();
- Dart_Handle* argv = const_cast<Dart_Handle*>(args.begin());
+ Dart_Handle *argv = const_cast<Dart_Handle *>(args.begin());
Dart_Handle handle = Dart_InvokeClosure(closure, argc, argv);
LogIfError(handle);
}
@@ -30,4 +29,4 @@
return handle;
}
-} // namespace tonic
+} // namespace tonic
diff --git a/parsers/BUILD.gn b/parsers/BUILD.gn
index 01657c4..94dd584 100644
--- a/parsers/BUILD.gn
+++ b/parsers/BUILD.gn
@@ -3,12 +3,16 @@
# found in the LICENSE file.
source_set("parsers") {
+ visibility = [ "../*" ]
+
+ configs += [ "../:config" ]
+
+ deps = [
+ "../common",
+ ]
+
sources = [
"packages_map.cc",
"packages_map.h",
]
-
- public_configs = [
- "//topaz/lib/tonic:config",
- ]
}
diff --git a/parsers/packages_map.cc b/parsers/packages_map.cc
index ca202c5..cc67091 100644
--- a/parsers/packages_map.cc
+++ b/parsers/packages_map.cc
@@ -4,24 +4,22 @@
// Spec: https://github.com/lrhn/dep-pkgspec/blob/master/DEP-pkgspec.md
-#include "lib/tonic/parsers/packages_map.h"
+#include "tonic/parsers/packages_map.h"
#include <memory>
namespace tonic {
namespace {
-bool isLineBreak(char c) {
- return c == '\r' || c == '\n';
-}
+bool isLineBreak(char c) { return c == '\r' || c == '\n'; }
-} // namespace
+} // namespace
PackagesMap::PackagesMap() {}
PackagesMap::~PackagesMap() {}
-bool PackagesMap::Parse(const std::string& source, std::string* error) {
+bool PackagesMap::Parse(const std::string &source, std::string *error) {
map_.clear();
const auto end = source.end();
for (auto it = source.begin(); it != end; ++it) {
@@ -80,8 +78,8 @@
return true;
}
-std::string PackagesMap::Resolve(const std::string& package_name) {
+std::string PackagesMap::Resolve(const std::string &package_name) {
return map_[package_name];
}
-} // namespace tonic
+} // namespace tonic
diff --git a/platform/BUILD.gn b/platform/BUILD.gn
new file mode 100644
index 0000000..8b6daca
--- /dev/null
+++ b/platform/BUILD.gn
@@ -0,0 +1,25 @@
+# Copyright 2017 The Fuchsia Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+source_set("platform") {
+ visibility = [ "../*" ]
+
+ configs += [ "../:config" ]
+
+ if (is_win) {
+ set_sources_assignment_filter([ "*_posix.cc" ])
+ } else {
+ set_sources_assignment_filter([ "*_win.cc" ])
+ }
+
+ deps = [
+ "../common",
+ ]
+
+ sources = [
+ "platform_utils.h",
+ "platform_utils_posix.cc",
+ "platform_utils_win.cc",
+ ]
+}
diff --git a/platform/platform_utils.h b/platform/platform_utils.h
new file mode 100644
index 0000000..14062d7
--- /dev/null
+++ b/platform/platform_utils.h
@@ -0,0 +1,15 @@
+// Copyright 2017 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef LIB_TONIC_PLATFORM_UTILS_H_
+#define LIB_TONIC_PLATFORM_UTILS_H_
+
+namespace tonic {
+
+// Calls the equivalent of exit(status) for a given platform.
+void PlatformExit(int status);
+
+}
+
+#endif // LIB_TONIC_PLATFORM_UTILS_H_
diff --git a/platform/platform_utils_posix.cc b/platform/platform_utils_posix.cc
new file mode 100644
index 0000000..0cebc15
--- /dev/null
+++ b/platform/platform_utils_posix.cc
@@ -0,0 +1,14 @@
+// Copyright 2017 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "platform_utils.h"
+#include <cstdlib>
+
+namespace tonic {
+
+void PlatformExit(int status) {
+ exit(status);
+}
+
+} // namespace tonic
diff --git a/platform/platform_utils_win.cc b/platform/platform_utils_win.cc
new file mode 100644
index 0000000..8ebbc7e
--- /dev/null
+++ b/platform/platform_utils_win.cc
@@ -0,0 +1,15 @@
+// Copyright 2017 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "platform_utils.h"
+
+#include <windows.h>
+
+namespace tonic {
+
+void PlatformExit(int status) {
+ ::ExitProcess(status);
+}
+
+} // namespace tonic
diff --git a/scopes/BUILD.gn b/scopes/BUILD.gn
index 014813e..ea9af51 100644
--- a/scopes/BUILD.gn
+++ b/scopes/BUILD.gn
@@ -3,18 +3,21 @@
# found in the LICENSE file.
source_set("scopes") {
+ visibility = [ "../*" ]
+
+ configs += [ "../:config" ]
+
sources = [
"dart_api_scope.h",
"dart_isolate_scope.cc",
"dart_isolate_scope.h",
]
- public_deps = [
- "//third_party/dart/runtime:dart_api",
- "//garnet/public/lib/fxl",
+ deps = [
+ "../common",
]
- public_configs = [
- "//topaz/lib/tonic:config",
+ public_deps = [
+ "//third_party/dart/runtime:dart_api",
]
}
diff --git a/scopes/dart_api_scope.h b/scopes/dart_api_scope.h
index d7d94a4..5ac4a98 100644
--- a/scopes/dart_api_scope.h
+++ b/scopes/dart_api_scope.h
@@ -5,23 +5,22 @@
#ifndef LIB_TONIC_SCOPES_DART_API_SCOPE_H_
#define LIB_TONIC_SCOPES_DART_API_SCOPE_H_
-#include "lib/fxl/macros.h"
#include "third_party/dart/runtime/include/dart_api.h"
namespace tonic {
class DartApiScope {
- public:
+public:
DartApiScope() { Dart_EnterScope(); }
~DartApiScope() {
if (Dart_CurrentIsolate())
Dart_ExitScope();
}
- private:
- FXL_DISALLOW_COPY_AND_ASSIGN(DartApiScope);
+private:
+ TONIC_DISALLOW_COPY_AND_ASSIGN(DartApiScope);
};
-} // namespace tonic
+} // namespace tonic
-#endif // LIB_TONIC_SCOPES_DART_API_SCOPE_H_
+#endif // LIB_TONIC_SCOPES_DART_API_SCOPE_H_
diff --git a/scopes/dart_isolate_scope.cc b/scopes/dart_isolate_scope.cc
index 15a06e2..a467cc5 100644
--- a/scopes/dart_isolate_scope.cc
+++ b/scopes/dart_isolate_scope.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "lib/tonic/scopes/dart_isolate_scope.h"
+#include "tonic/scopes/dart_isolate_scope.h"
namespace tonic {
@@ -18,7 +18,7 @@
DartIsolateScope::~DartIsolateScope() {
Dart_Isolate current = Dart_CurrentIsolate();
- FXL_DCHECK(!current || current == isolate_);
+ TONIC_DCHECK(!current || current == isolate_);
if (previous_ == isolate_)
return;
if (current)
@@ -27,4 +27,4 @@
Dart_EnterIsolate(previous_);
}
-} // namespace tonic
+} // namespace tonic
diff --git a/scopes/dart_isolate_scope.h b/scopes/dart_isolate_scope.h
index 97ac65b..bda3ecd 100644
--- a/scopes/dart_isolate_scope.h
+++ b/scopes/dart_isolate_scope.h
@@ -5,24 +5,24 @@
#ifndef LIB_TONIC_SCOPES_DART_ISOLATE_SCOPE_H_
#define LIB_TONIC_SCOPES_DART_ISOLATE_SCOPE_H_
-#include "lib/fxl/logging.h"
#include "third_party/dart/runtime/include/dart_api.h"
+#include "tonic/common/macros.h"
namespace tonic {
// DartIsolateScope is a helper class for entering and exiting a given isolate.
class DartIsolateScope {
- public:
+public:
explicit DartIsolateScope(Dart_Isolate isolate);
~DartIsolateScope();
- private:
+private:
Dart_Isolate isolate_;
Dart_Isolate previous_;
- FXL_DISALLOW_COPY_AND_ASSIGN(DartIsolateScope);
+ TONIC_DISALLOW_COPY_AND_ASSIGN(DartIsolateScope);
};
-} // namespace tonic
+} // namespace tonic
-#endif // LIB_TONIC_SCOPES_DART_ISOLATE_SCOPE_H_
+#endif // LIB_TONIC_SCOPES_DART_ISOLATE_SCOPE_H_
diff --git a/typed_data/BUILD.gn b/typed_data/BUILD.gn
index 87056b8..8cc067e 100644
--- a/typed_data/BUILD.gn
+++ b/typed_data/BUILD.gn
@@ -3,6 +3,10 @@
# found in the LICENSE file.
source_set("typed_data") {
+ visibility = [ "../*" ]
+
+ configs += [ "../:config" ]
+
sources = [
"dart_byte_data.cc",
"dart_byte_data.h",
@@ -16,14 +20,13 @@
"uint8_list.h",
]
- public_deps = [
- "//third_party/dart/runtime:dart_api",
- "//garnet/public/lib/fxl",
- "//topaz/lib/tonic/converter",
- "//topaz/lib/tonic/logging",
+ deps = [
+ "../common",
]
- public_configs = [
- "//topaz/lib/tonic:config",
+ public_deps = [
+ "../converter",
+ "../logging",
+ "//third_party/dart/runtime:dart_api",
]
}
diff --git a/typed_data/dart_byte_data.cc b/typed_data/dart_byte_data.cc
index 9029c4a..6df97e2 100644
--- a/typed_data/dart_byte_data.cc
+++ b/typed_data/dart_byte_data.cc
@@ -2,9 +2,9 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "lib/tonic/typed_data/dart_byte_data.h"
+#include "tonic/typed_data/dart_byte_data.h"
-#include "lib/tonic/logging/dart_error.h"
+#include "tonic/logging/dart_error.h"
namespace tonic {
@@ -18,25 +18,22 @@
Dart_TypedData_Type type;
Dart_TypedDataAcquireData(list, &type, &data_, &length_in_bytes_);
- FXL_DCHECK(!LogIfError(list));
+ TONIC_DCHECK(!LogIfError(list));
if (type != Dart_TypedData_kByteData)
Dart_ThrowException(ToDart("Non-genuine ByteData passed to engine."));
}
-DartByteData::DartByteData(DartByteData&& other)
- : data_(other.data_),
- length_in_bytes_(other.length_in_bytes_),
+DartByteData::DartByteData(DartByteData &&other)
+ : data_(other.data_), length_in_bytes_(other.length_in_bytes_),
dart_handle_(other.dart_handle_) {
other.data_ = nullptr;
other.dart_handle_ = nullptr;
}
-DartByteData::~DartByteData() {
- Release();
-}
+DartByteData::~DartByteData() { Release(); }
std::vector<char> DartByteData::Copy() const {
- const char* ptr = static_cast<const char*>(data_);
+ const char *ptr = static_cast<const char *>(data_);
return std::vector<char>(ptr, ptr + length_in_bytes_);
}
@@ -47,12 +44,11 @@
}
}
-DartByteData DartConverter<DartByteData>::FromArguments(
- Dart_NativeArguments args,
- int index,
- Dart_Handle& exception) {
+DartByteData
+DartConverter<DartByteData>::FromArguments(Dart_NativeArguments args, int index,
+ Dart_Handle &exception) {
Dart_Handle data = Dart_GetNativeArgument(args, index);
- FXL_DCHECK(!LogIfError(data));
+ TONIC_DCHECK(!LogIfError(data));
return DartByteData(data);
}
@@ -61,4 +57,4 @@
Dart_SetReturnValue(args, val.dart_handle());
}
-} // namespace tonic
+} // namespace tonic
diff --git a/typed_data/dart_byte_data.h b/typed_data/dart_byte_data.h
index 17ee6b2..b8eb49c 100644
--- a/typed_data/dart_byte_data.h
+++ b/typed_data/dart_byte_data.h
@@ -8,19 +8,19 @@
#include <vector>
#include "third_party/dart/runtime/include/dart_api.h"
-#include "lib/tonic/converter/dart_converter.h"
+#include "tonic/converter/dart_converter.h"
namespace tonic {
class DartByteData {
- public:
+public:
explicit DartByteData(Dart_Handle list);
- DartByteData(DartByteData&& other);
+ DartByteData(DartByteData &&other);
DartByteData();
~DartByteData();
- const void* data() const { return data_; }
- void* data() { return data_; }
+ const void *data() const { return data_; }
+ void *data() { return data_; }
size_t length_in_bytes() const { return length_in_bytes_; }
Dart_Handle dart_handle() const { return dart_handle_; }
@@ -29,22 +29,20 @@
explicit operator bool() const { return data_ != nullptr; }
- private:
- mutable void* data_;
+private:
+ mutable void *data_;
intptr_t length_in_bytes_;
Dart_Handle dart_handle_;
- DartByteData(const DartByteData& other) = delete;
+ DartByteData(const DartByteData &other) = delete;
};
-template <>
-struct DartConverter<DartByteData> {
+template <> struct DartConverter<DartByteData> {
static void SetReturnValue(Dart_NativeArguments args, DartByteData val);
- static DartByteData FromArguments(Dart_NativeArguments args,
- int index,
- Dart_Handle& exception);
+ static DartByteData FromArguments(Dart_NativeArguments args, int index,
+ Dart_Handle &exception);
};
-} // namespace tonic
+} // namespace tonic
-#endif // LIB_TONIC_TYPED_DATA_DART_BYTE_DATA_H_
+#endif // LIB_TONIC_TYPED_DATA_DART_BYTE_DATA_H_
diff --git a/typed_data/float32_list.cc b/typed_data/float32_list.cc
index 9100883..48d430a 100644
--- a/typed_data/float32_list.cc
+++ b/typed_data/float32_list.cc
@@ -2,9 +2,9 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "lib/tonic/typed_data/float32_list.h"
+#include "tonic/typed_data/float32_list.h"
-#include "lib/tonic/logging/dart_error.h"
+#include "tonic/logging/dart_error.h"
namespace tonic {
@@ -17,24 +17,21 @@
return;
Dart_TypedData_Type type;
- Dart_TypedDataAcquireData(list, &type, reinterpret_cast<void**>(&data_),
+ Dart_TypedDataAcquireData(list, &type, reinterpret_cast<void **>(&data_),
&num_elements_);
- FXL_DCHECK(!LogIfError(list));
+ TONIC_DCHECK(!LogIfError(list));
if (type != Dart_TypedData_kFloat32)
Dart_ThrowException(ToDart("Non-genuine Float32List passed to engine."));
}
-Float32List::Float32List(Float32List&& other)
- : data_(other.data_),
- num_elements_(other.num_elements_),
+Float32List::Float32List(Float32List &&other)
+ : data_(other.data_), num_elements_(other.num_elements_),
dart_handle_(other.dart_handle_) {
other.data_ = nullptr;
other.dart_handle_ = nullptr;
}
-Float32List::~Float32List() {
- Release();
-}
+Float32List::~Float32List() { Release(); }
void Float32List::Release() {
if (data_) {
@@ -47,9 +44,9 @@
Float32List DartConverter<Float32List>::FromArguments(Dart_NativeArguments args,
int index,
- Dart_Handle& exception) {
+ Dart_Handle &exception) {
Dart_Handle list = Dart_GetNativeArgument(args, index);
- FXL_DCHECK(!LogIfError(list));
+ TONIC_DCHECK(!LogIfError(list));
return Float32List(list);
}
@@ -58,4 +55,4 @@
Dart_SetReturnValue(args, val.dart_handle());
}
-} // namespace tonic
+} // namespace tonic
diff --git a/typed_data/float32_list.h b/typed_data/float32_list.h
index edc1041..bf96b27 100644
--- a/typed_data/float32_list.h
+++ b/typed_data/float32_list.h
@@ -6,7 +6,7 @@
#define LIB_TONIC_TYPED_DATA_FLOAT32_LIST_H_
#include "third_party/dart/runtime/include/dart_api.h"
-#include "lib/tonic/converter/dart_converter.h"
+#include "tonic/converter/dart_converter.h"
namespace tonic {
@@ -16,46 +16,44 @@
//
// This is designed to be used with DartConverter only.
class Float32List {
- public:
+public:
explicit Float32List(Dart_Handle list);
- Float32List(Float32List&& other);
+ Float32List(Float32List &&other);
Float32List();
~Float32List();
- float& at(intptr_t i) {
- FXL_CHECK(i < num_elements_);
+ float &at(intptr_t i) {
+ TONIC_CHECK(i < num_elements_);
return data_[i];
}
- const float& at(intptr_t i) const {
- FXL_CHECK(i < num_elements_);
+ const float &at(intptr_t i) const {
+ TONIC_CHECK(i < num_elements_);
return data_[i];
}
- float& operator[](intptr_t i) { return at(i); }
- const float& operator[](intptr_t i) const { return at(i); }
+ float &operator[](intptr_t i) { return at(i); }
+ const float &operator[](intptr_t i) const { return at(i); }
- const float* data() const { return data_; }
+ const float *data() const { return data_; }
intptr_t num_elements() const { return num_elements_; }
Dart_Handle dart_handle() const { return dart_handle_; }
void Release();
- private:
- float* data_;
+private:
+ float *data_;
intptr_t num_elements_;
Dart_Handle dart_handle_;
- Float32List(const Float32List& other) = delete;
+ Float32List(const Float32List &other) = delete;
};
-template <>
-struct DartConverter<Float32List> {
+template <> struct DartConverter<Float32List> {
static void SetReturnValue(Dart_NativeArguments args, Float32List val);
- static Float32List FromArguments(Dart_NativeArguments args,
- int index,
- Dart_Handle& exception);
+ static Float32List FromArguments(Dart_NativeArguments args, int index,
+ Dart_Handle &exception);
};
-} // namespace tonic
+} // namespace tonic
-#endif // LIB_TONIC_TYPED_DATA_FLOAT32_LIST_H_
+#endif // LIB_TONIC_TYPED_DATA_FLOAT32_LIST_H_
diff --git a/typed_data/float64_list.cc b/typed_data/float64_list.cc
index 3eabb93..29494b7 100644
--- a/typed_data/float64_list.cc
+++ b/typed_data/float64_list.cc
@@ -2,9 +2,9 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "lib/tonic/typed_data/float64_list.h"
+#include "tonic/typed_data/float64_list.h"
-#include "lib/tonic/logging/dart_error.h"
+#include "tonic/logging/dart_error.h"
namespace tonic {
@@ -17,24 +17,21 @@
return;
Dart_TypedData_Type type;
- Dart_TypedDataAcquireData(list, &type, reinterpret_cast<void**>(&data_),
+ Dart_TypedDataAcquireData(list, &type, reinterpret_cast<void **>(&data_),
&num_elements_);
- FXL_DCHECK(!LogIfError(list));
+ TONIC_DCHECK(!LogIfError(list));
if (type != Dart_TypedData_kFloat64)
Dart_ThrowException(ToDart("Non-genuine Float64List passed to engine."));
}
-Float64List::Float64List(Float64List&& other)
- : data_(other.data_),
- num_elements_(other.num_elements_),
+Float64List::Float64List(Float64List &&other)
+ : data_(other.data_), num_elements_(other.num_elements_),
dart_handle_(other.dart_handle_) {
other.data_ = nullptr;
other.dart_handle_ = nullptr;
}
-Float64List::~Float64List() {
- Release();
-}
+Float64List::~Float64List() { Release(); }
void Float64List::Release() {
if (data_) {
@@ -47,9 +44,9 @@
Float64List DartConverter<Float64List>::FromArguments(Dart_NativeArguments args,
int index,
- Dart_Handle& exception) {
+ Dart_Handle &exception) {
Dart_Handle list = Dart_GetNativeArgument(args, index);
- FXL_DCHECK(!LogIfError(list));
+ TONIC_DCHECK(!LogIfError(list));
return Float64List(list);
}
@@ -58,4 +55,4 @@
Dart_SetReturnValue(args, val.dart_handle());
}
-} // namespace tonic
+} // namespace tonic
diff --git a/typed_data/float64_list.h b/typed_data/float64_list.h
index 25c7045..1dc6af1 100644
--- a/typed_data/float64_list.h
+++ b/typed_data/float64_list.h
@@ -6,7 +6,7 @@
#define LIB_TONIC_TYPED_DATA_FLOAT64_LIST_H_
#include "third_party/dart/runtime/include/dart_api.h"
-#include "lib/tonic/converter/dart_converter.h"
+#include "tonic/converter/dart_converter.h"
namespace tonic {
@@ -16,46 +16,44 @@
//
// This is designed to be used with DartConverter only.
class Float64List {
- public:
+public:
explicit Float64List(Dart_Handle list);
- Float64List(Float64List&& other);
+ Float64List(Float64List &&other);
Float64List();
~Float64List();
- double& at(intptr_t i) {
- FXL_CHECK(i < num_elements_);
+ double &at(intptr_t i) {
+ TONIC_CHECK(i < num_elements_);
return data_[i];
}
- const double& at(intptr_t i) const {
- FXL_CHECK(i < num_elements_);
+ const double &at(intptr_t i) const {
+ TONIC_CHECK(i < num_elements_);
return data_[i];
}
- double& operator[](intptr_t i) { return at(i); }
- const double& operator[](intptr_t i) const { return at(i); }
+ double &operator[](intptr_t i) { return at(i); }
+ const double &operator[](intptr_t i) const { return at(i); }
- const double* data() const { return data_; }
+ const double *data() const { return data_; }
intptr_t num_elements() const { return num_elements_; }
Dart_Handle dart_handle() const { return dart_handle_; }
void Release();
- private:
- double* data_;
+private:
+ double *data_;
intptr_t num_elements_;
Dart_Handle dart_handle_;
- Float64List(const Float64List& other) = delete;
+ Float64List(const Float64List &other) = delete;
};
-template <>
-struct DartConverter<Float64List> {
+template <> struct DartConverter<Float64List> {
static void SetReturnValue(Dart_NativeArguments args, Float64List val);
- static Float64List FromArguments(Dart_NativeArguments args,
- int index,
- Dart_Handle& exception);
+ static Float64List FromArguments(Dart_NativeArguments args, int index,
+ Dart_Handle &exception);
};
-} // namespace tonic
+} // namespace tonic
-#endif // LIB_TONIC_TYPED_DATA_FLOAT64_LIST_H_
+#endif // LIB_TONIC_TYPED_DATA_FLOAT64_LIST_H_
diff --git a/typed_data/int32_list.cc b/typed_data/int32_list.cc
index 6a6f464..05f8e7f 100644
--- a/typed_data/int32_list.cc
+++ b/typed_data/int32_list.cc
@@ -2,9 +2,9 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "lib/tonic/typed_data/int32_list.h"
+#include "tonic/typed_data/int32_list.h"
-#include "lib/tonic/logging/dart_error.h"
+#include "tonic/logging/dart_error.h"
namespace tonic {
@@ -17,24 +17,21 @@
return;
Dart_TypedData_Type type;
- Dart_TypedDataAcquireData(list, &type, reinterpret_cast<void**>(&data_),
+ Dart_TypedDataAcquireData(list, &type, reinterpret_cast<void **>(&data_),
&num_elements_);
- FXL_DCHECK(!LogIfError(list));
+ TONIC_DCHECK(!LogIfError(list));
if (type != Dart_TypedData_kInt32)
Dart_ThrowException(ToDart("Non-genuine Int32List passed to engine."));
}
-Int32List::Int32List(Int32List&& other)
- : data_(other.data_),
- num_elements_(other.num_elements_),
+Int32List::Int32List(Int32List &&other)
+ : data_(other.data_), num_elements_(other.num_elements_),
dart_handle_(other.dart_handle_) {
other.data_ = nullptr;
other.dart_handle_ = nullptr;
}
-Int32List::~Int32List() {
- Release();
-}
+Int32List::~Int32List() { Release(); }
void Int32List::Release() {
if (data_) {
@@ -47,9 +44,9 @@
Int32List DartConverter<Int32List>::FromArguments(Dart_NativeArguments args,
int index,
- Dart_Handle& exception) {
+ Dart_Handle &exception) {
Dart_Handle list = Dart_GetNativeArgument(args, index);
- FXL_DCHECK(!LogIfError(list));
+ TONIC_DCHECK(!LogIfError(list));
return Int32List(list);
}
@@ -58,4 +55,4 @@
Dart_SetReturnValue(args, val.dart_handle());
}
-} // namespace tonic
+} // namespace tonic
diff --git a/typed_data/int32_list.h b/typed_data/int32_list.h
index dd73933..b0d7096 100644
--- a/typed_data/int32_list.h
+++ b/typed_data/int32_list.h
@@ -6,7 +6,7 @@
#define LIB_TONIC_TYPED_DATA_INT32_LIST_H_
#include "third_party/dart/runtime/include/dart_api.h"
-#include "lib/tonic/converter/dart_converter.h"
+#include "tonic/converter/dart_converter.h"
namespace tonic {
@@ -16,46 +16,44 @@
//
// This is designed to be used with DartConverter only.
class Int32List {
- public:
+public:
explicit Int32List(Dart_Handle list);
- Int32List(Int32List&& other);
+ Int32List(Int32List &&other);
Int32List();
~Int32List();
- int32_t& at(intptr_t i) {
- FXL_CHECK(i < num_elements_);
+ int32_t &at(intptr_t i) {
+ TONIC_CHECK(i < num_elements_);
return data_[i];
}
- const int32_t& at(intptr_t i) const {
- FXL_CHECK(i < num_elements_);
+ const int32_t &at(intptr_t i) const {
+ TONIC_CHECK(i < num_elements_);
return data_[i];
}
- int32_t& operator[](intptr_t i) { return at(i); }
- const int32_t& operator[](intptr_t i) const { return at(i); }
+ int32_t &operator[](intptr_t i) { return at(i); }
+ const int32_t &operator[](intptr_t i) const { return at(i); }
- const int32_t* data() const { return data_; }
+ const int32_t *data() const { return data_; }
intptr_t num_elements() const { return num_elements_; }
Dart_Handle dart_handle() const { return dart_handle_; }
void Release();
- private:
- int32_t* data_;
+private:
+ int32_t *data_;
intptr_t num_elements_;
Dart_Handle dart_handle_;
- Int32List(const Int32List& other) = delete;
+ Int32List(const Int32List &other) = delete;
};
-template <>
-struct DartConverter<Int32List> {
+template <> struct DartConverter<Int32List> {
static void SetReturnValue(Dart_NativeArguments args, Int32List val);
- static Int32List FromArguments(Dart_NativeArguments args,
- int index,
- Dart_Handle& exception);
+ static Int32List FromArguments(Dart_NativeArguments args, int index,
+ Dart_Handle &exception);
};
-} // namespace tonic
+} // namespace tonic
-#endif // LIB_TONIC_TYPED_DATA_INT32_LIST_H_
+#endif // LIB_TONIC_TYPED_DATA_INT32_LIST_H_
diff --git a/typed_data/uint8_list.cc b/typed_data/uint8_list.cc
index 7749f50..6387574 100644
--- a/typed_data/uint8_list.cc
+++ b/typed_data/uint8_list.cc
@@ -2,11 +2,11 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "lib/tonic/typed_data/uint8_list.h"
+#include "tonic/typed_data/uint8_list.h"
#include <string.h>
-#include "lib/tonic/logging/dart_error.h"
+#include "tonic/logging/dart_error.h"
namespace tonic {
@@ -19,24 +19,21 @@
return;
Dart_TypedData_Type type;
- Dart_TypedDataAcquireData(list, &type, reinterpret_cast<void**>(&data_),
+ Dart_TypedDataAcquireData(list, &type, reinterpret_cast<void **>(&data_),
&num_elements_);
- FXL_DCHECK(!LogIfError(list));
+ TONIC_DCHECK(!LogIfError(list));
if (type != Dart_TypedData_kUint8)
Dart_ThrowException(ToDart("Non-genuine Uint8List passed to engine."));
}
-Uint8List::Uint8List(Uint8List&& other)
- : data_(other.data_),
- num_elements_(other.num_elements_),
+Uint8List::Uint8List(Uint8List &&other)
+ : data_(other.data_), num_elements_(other.num_elements_),
dart_handle_(other.dart_handle_) {
other.data_ = nullptr;
other.dart_handle_ = nullptr;
}
-Uint8List::~Uint8List() {
- Release();
-}
+Uint8List::~Uint8List() { Release(); }
void Uint8List::Release() {
if (data_) {
@@ -49,9 +46,9 @@
Uint8List DartConverter<Uint8List>::FromArguments(Dart_NativeArguments args,
int index,
- Dart_Handle& exception) {
+ Dart_Handle &exception) {
Dart_Handle list = Dart_GetNativeArgument(args, index);
- FXL_DCHECK(!LogIfError(list));
+ TONIC_DCHECK(!LogIfError(list));
return Uint8List(list);
}
@@ -60,23 +57,23 @@
Dart_SetReturnValue(args, val.dart_handle());
}
-Dart_Handle DartConverter<Uint8List>::ToDart(const uint8_t* buffer,
+Dart_Handle DartConverter<Uint8List>::ToDart(const uint8_t *buffer,
unsigned int length) {
const intptr_t buffer_length = static_cast<intptr_t>(length);
Dart_Handle array = Dart_NewTypedData(Dart_TypedData_kUint8, buffer_length);
- FXL_DCHECK(!LogIfError(array));
+ TONIC_DCHECK(!LogIfError(array));
{
Dart_TypedData_Type type;
- void* data = nullptr;
+ void *data = nullptr;
intptr_t data_length = 0;
Dart_TypedDataAcquireData(array, &type, &data, &data_length);
- FXL_CHECK(type == Dart_TypedData_kUint8);
- FXL_CHECK(data);
- FXL_CHECK(data_length == buffer_length);
+ TONIC_CHECK(type == Dart_TypedData_kUint8);
+ TONIC_CHECK(data);
+ TONIC_CHECK(data_length == buffer_length);
memmove(data, buffer, data_length);
Dart_TypedDataReleaseData(array);
}
return array;
}
-} // namespace tonic
+} // namespace tonic
diff --git a/typed_data/uint8_list.h b/typed_data/uint8_list.h
index 4ab25f9..984b74d 100644
--- a/typed_data/uint8_list.h
+++ b/typed_data/uint8_list.h
@@ -6,7 +6,7 @@
#define LIB_TONIC_TYPED_DATA_UINT8_LIST_H_
#include "third_party/dart/runtime/include/dart_api.h"
-#include "lib/tonic/converter/dart_converter.h"
+#include "tonic/converter/dart_converter.h"
namespace tonic {
@@ -16,47 +16,45 @@
//
// This is designed to be used with DartConverter only.
class Uint8List {
- public:
+public:
explicit Uint8List(Dart_Handle list);
- Uint8List(Uint8List&& other);
+ Uint8List(Uint8List &&other);
Uint8List();
~Uint8List();
- uint8_t& at(intptr_t i) {
- FXL_CHECK(i < num_elements_);
+ uint8_t &at(intptr_t i) {
+ TONIC_CHECK(i < num_elements_);
return data_[i];
}
- const uint8_t& at(intptr_t i) const {
- FXL_CHECK(i < num_elements_);
+ const uint8_t &at(intptr_t i) const {
+ TONIC_CHECK(i < num_elements_);
return data_[i];
}
- uint8_t& operator[](intptr_t i) { return at(i); }
- const uint8_t& operator[](intptr_t i) const { return at(i); }
+ uint8_t &operator[](intptr_t i) { return at(i); }
+ const uint8_t &operator[](intptr_t i) const { return at(i); }
- const uint8_t* data() const { return data_; }
+ const uint8_t *data() const { return data_; }
intptr_t num_elements() const { return num_elements_; }
Dart_Handle dart_handle() const { return dart_handle_; }
void Release();
- private:
- uint8_t* data_;
+private:
+ uint8_t *data_;
intptr_t num_elements_;
Dart_Handle dart_handle_;
- Uint8List(const Uint8List& other) = delete;
+ Uint8List(const Uint8List &other) = delete;
};
-template <>
-struct DartConverter<Uint8List> {
+template <> struct DartConverter<Uint8List> {
static void SetReturnValue(Dart_NativeArguments args, Uint8List val);
- static Uint8List FromArguments(Dart_NativeArguments args,
- int index,
- Dart_Handle& exception);
- static Dart_Handle ToDart(const uint8_t* buffer, unsigned int length);
+ static Uint8List FromArguments(Dart_NativeArguments args, int index,
+ Dart_Handle &exception);
+ static Dart_Handle ToDart(const uint8_t *buffer, unsigned int length);
};
-} // namespace tonic
+} // namespace tonic
-#endif // LIB_TONIC_TYPED_DATA_UINT8_LIST_H_
+#endif // LIB_TONIC_TYPED_DATA_UINT8_LIST_H_