Flutter Engine
dart_converter.h
Go to the documentation of this file.
1 // Copyright 2013 The Flutter Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef FLUTTER_FML_DART_DART_CONVERTER_H_
6 #define FLUTTER_FML_DART_DART_CONVERTER_H_
7 
8 #include <memory>
9 #include <vector>
10 
11 #include "flutter/fml/mapping.h"
12 #include "third_party/dart/runtime/include/dart_api.h"
14 
15 namespace tonic {
16 
17 using DartConverterMapping = std::unique_ptr<fml::Mapping>;
18 
19 template <>
21  static Dart_Handle ToDart(const DartConverterMapping& val) {
22  if (!val) {
23  return Dart_Null();
24  }
25 
26  auto dart_list_handle = Dart_NewListOfTypeFilled(
27  ToDartTypeHandle<size_t>(), // type
28  CreateZeroInitializedDartObject<size_t>(), // sentinel
29  val->GetSize() // size
30  );
31 
32  if (Dart_IsError(dart_list_handle)) {
33  FML_LOG(ERROR) << "Error while attempting to allocate a list: "
34  << Dart_GetError(dart_list_handle);
35  return dart_list_handle;
36  }
37 
38  if (val->GetSize() == 0) {
39  // Nothing to copy. Just return the zero sized list.
40  return dart_list_handle;
41  }
42 
43  auto result = Dart_ListSetAsBytes(dart_list_handle, // list
44  0, // offset
45  val->GetMapping(), // native array,
46  val->GetSize() // length
47  );
48 
49  if (Dart_IsError(result)) {
50  FML_LOG(ERROR) << "Error while attempting to create a Dart list: "
51  << Dart_GetError(result);
52  return result;
53  }
54 
55  return dart_list_handle;
56  }
57 
58  static void SetReturnValue(Dart_NativeArguments args,
59  const DartConverterMapping& val) {
60  Dart_SetReturnValue(args, ToDart(val));
61  }
62 
63  static DartConverterMapping FromDart(Dart_Handle dart_list) {
64  if (Dart_IsNull(dart_list)) {
65  return nullptr;
66  }
67 
68  if (Dart_IsError(dart_list)) {
69  FML_LOG(ERROR) << "Cannot convert an error handle to a list: "
70  << Dart_GetError(dart_list);
71  return nullptr;
72  }
73 
74  if (!Dart_IsList(dart_list)) {
75  FML_LOG(ERROR) << "Dart handle was not a list.";
76  return nullptr;
77  }
78 
79  intptr_t length = 0;
80  auto handle = Dart_ListLength(dart_list, &length);
81 
82  if (Dart_IsError(handle)) {
83  FML_LOG(ERROR) << "Could not get the length of the Dart list: "
84  << Dart_GetError(handle);
85  return nullptr;
86  }
87 
88  if (length == 0) {
89  // Return a valid zero sized mapping.
90  return std::make_unique<fml::NonOwnedMapping>(nullptr, 0);
91  }
92 
93  auto mapping_buffer = ::malloc(length);
94 
95  if (!mapping_buffer) {
96  FML_LOG(ERROR)
97  << "Out of memory while attempting to allocate a mapping of size: "
98  << length;
99  return nullptr;
100  }
101 
102  auto mapping = std::make_unique<fml::NonOwnedMapping>(
103  static_cast<const uint8_t*>(mapping_buffer), length,
104  [](const uint8_t* data, size_t size) {
105  ::free(const_cast<uint8_t*>(data));
106  });
107 
108  handle = Dart_ListGetAsBytes(
109  dart_list, // list
110  0, // offset
111  static_cast<uint8_t*>(mapping_buffer), // native array
112  length // length
113  );
114 
115  if (Dart_IsError(handle)) {
116  FML_LOG(ERROR) << "Could not copy Dart list to native buffer: "
117  << Dart_GetError(handle);
118  return nullptr;
119  }
120 
121  return mapping;
122  }
123 };
124 
125 } // namespace tonic
126 
127 #endif // FLUTTER_FML_DART_DART_CONVERTER_H_
G_BEGIN_DECLS FlValue * args
static DartConverterMapping FromDart(Dart_Handle dart_list)
constexpr std::size_t size(T(&array)[N])
Definition: size.h:13
#define FML_LOG(severity)
Definition: logging.h:65
static Dart_Handle ToDart(const DartConverterMapping &val)
size_t length
static void SetReturnValue(Dart_NativeArguments args, const DartConverterMapping &val)
Dart_Handle ToDart(const T &object)
std::unique_ptr< fml::Mapping > DartConverterMapping