| // Copyright 2015 The Chromium 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_DART_CONVERTER_H_ | 
 | #define TONIC_DART_CONVERTER_H_ | 
 |  | 
 | #include <string> | 
 |  | 
 | #include "tonic/dart_state.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 { | 
 | }; | 
 |  | 
 | // 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 | 
 | // template and override the types here. | 
 | // Ex: | 
 | //   typedef int ColorType;  // Want to use a different converter. | 
 | //   class ColorConverterType {};  // Dummy type. | 
 | //   template<> struct DartConvertType<ColorConverterType> { | 
 | //     using ConverterType = ColorConverterType; | 
 | //     using ValueType = ColorType; | 
 | //   }; | 
 | template <typename T> | 
 | struct DartConverterTypes { | 
 |   using ConverterType = T; | 
 |   using ValueType = T; | 
 | }; | 
 |  | 
 | //////////////////////////////////////////////////////////////////////////////// | 
 | // Boolean | 
 |  | 
 | template <> | 
 | struct DartConverter<bool> { | 
 |   static Dart_Handle ToDart(bool val) { return Dart_NewBoolean(val); } | 
 |  | 
 |   static void SetReturnValue(Dart_NativeArguments args, bool val) { | 
 |     Dart_SetBooleanReturnValue(args, val); | 
 |   } | 
 |  | 
 |   static bool FromDart(Dart_Handle handle) { | 
 |     bool result = 0; | 
 |     Dart_BooleanValue(handle, &result); | 
 |     return result; | 
 |   } | 
 |  | 
 |   static bool FromArguments(Dart_NativeArguments args, | 
 |                             int index, | 
 |                             Dart_Handle& exception) { | 
 |     bool result = false; | 
 |     Dart_GetNativeBooleanArgument(args, index, &result); | 
 |     return result; | 
 |   } | 
 | }; | 
 |  | 
 | //////////////////////////////////////////////////////////////////////////////// | 
 | // Numbers | 
 |  | 
 | template <typename T> | 
 | struct DartConverterInteger { | 
 |   static Dart_Handle ToDart(T val) { return Dart_NewInteger(val); } | 
 |  | 
 |   static void SetReturnValue(Dart_NativeArguments args, T val) { | 
 |     Dart_SetIntegerReturnValue(args, val); | 
 |   } | 
 |  | 
 |   static T FromDart(Dart_Handle handle) { | 
 |     int64_t result = 0; | 
 |     Dart_IntegerToInt64(handle, &result); | 
 |     return static_cast<T>(result); | 
 |   } | 
 |  | 
 |   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<unsigned> : public DartConverterInteger<unsigned> {}; | 
 |  | 
 | template <> | 
 | struct DartConverter<long long> : public DartConverterInteger<long long> {}; | 
 |  | 
 | template <> | 
 | struct DartConverter<unsigned long long> { | 
 |   static Dart_Handle ToDart(unsigned long long val) { | 
 |     // FIXME: WebIDL unsigned long long is guaranteed to fit into 64-bit | 
 |     // unsigned, | 
 |     // so we need a dart API for constructing an integer from uint64_t. | 
 |     DCHECK(val <= 0x7fffffffffffffffLL); | 
 |     return Dart_NewInteger(static_cast<int64_t>(val)); | 
 |   } | 
 |  | 
 |   static void SetReturnValue(Dart_NativeArguments args, | 
 |                              unsigned long long val) { | 
 |     DCHECK(val <= 0x7fffffffffffffffLL); | 
 |     Dart_SetIntegerReturnValue(args, val); | 
 |   } | 
 |  | 
 |   static unsigned long long FromDart(Dart_Handle handle) { | 
 |     int64_t result = 0; | 
 |     Dart_IntegerToInt64(handle, &result); | 
 |     return result; | 
 |   } | 
 |  | 
 |   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 { | 
 |   static Dart_Handle ToDart(T val) { return Dart_NewDouble(val); } | 
 |  | 
 |   static void SetReturnValue(Dart_NativeArguments args, T val) { | 
 |     Dart_SetDoubleReturnValue(args, val); | 
 |   } | 
 |  | 
 |   static T FromDart(Dart_Handle handle) { | 
 |     double result = 0; | 
 |     Dart_DoubleValue(handle, &result); | 
 |     return result; | 
 |   } | 
 |  | 
 |   static T FromArguments(Dart_NativeArguments args, | 
 |                          int index, | 
 |                          Dart_Handle& exception) { | 
 |     double result = 0; | 
 |     Dart_GetNativeDoubleArgument(args, index, &result); | 
 |     return result; | 
 |   } | 
 | }; | 
 |  | 
 | template <> | 
 | struct DartConverter<float> : public DartConverterFloatingPoint<float> {}; | 
 |  | 
 | template <> | 
 | struct DartConverter<double> : public DartConverterFloatingPoint<double> {}; | 
 |  | 
 | //////////////////////////////////////////////////////////////////////////////// | 
 | // std::string support (slower, but more convienent for some clients) | 
 |  | 
 | inline Dart_Handle StdStringToDart(const std::string& val) { | 
 |   return Dart_NewStringFromUTF8(reinterpret_cast<const uint8_t*>(val.data()), | 
 |                                 val.length()); | 
 | } | 
 |  | 
 | inline std::string StdStringFromDart(Dart_Handle handle) { | 
 |   uint8_t* data = nullptr; | 
 |   intptr_t length = 0; | 
 |   Dart_Handle r = Dart_StringToUTF8(handle, &data, &length); | 
 |   if (Dart_IsError(r)) { | 
 |     return std::string(); | 
 |   } | 
 |   return std::string(reinterpret_cast<const char*>(data), | 
 |                      static_cast<size_t>(length)); | 
 | } | 
 |  | 
 |  | 
 | // Alias Dart_NewStringFromCString for less typing. | 
 | inline Dart_Handle ToDart(const char* val) { | 
 |   return Dart_NewStringFromCString(val); | 
 | } | 
 |  | 
 | }  // namespace tonic | 
 |  | 
 | #endif  // TONIC_DART_CONVERTER_H_ |