1// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
2// for details. All rights reserved. Use of this source code is governed by a
3// BSD-style license that can be found in the LICENSE file.
4
5#if !defined(DART_IO_DISABLED)
6
7#include "bin/namespace.h"
8
9#include "bin/builtin.h"
10#include "bin/dartutils.h"
11#include "include/dart_api.h"
12#include "platform/globals.h"
13
14namespace dart {
15namespace bin {
16
17static const int kNamespaceNativeFieldIndex = 0;
18
19static void ReleaseNamespace(void* isolate_callback_data, void* peer) {
20 Namespace* namespc = reinterpret_cast<Namespace*>(peer);
21 ASSERT(namespc != NULL);
22 namespc->Release();
23}
24
25#if defined(DEBUG)
26static bool IsNamespace(Dart_Handle namespc_obj) {
27 Dart_Handle namespc_type =
28 DartUtils::GetDartType("dart:io", "_NamespaceImpl");
29 ASSERT(!Dart_IsError(namespc_type));
30 bool isinstance = false;
31 Dart_Handle result =
32 Dart_ObjectIsType(namespc_obj, namespc_type, &isinstance);
33 ASSERT(!Dart_IsError(result));
34 return isinstance;
35}
36#endif
37
38void FUNCTION_NAME(Namespace_Create)(Dart_NativeArguments args) {
39 Dart_Handle namespc_obj = Dart_GetNativeArgument(args, 0);
40 if (Dart_IsError(namespc_obj)) {
41 Dart_PropagateError(namespc_obj);
42 }
43 DEBUG_ASSERT(IsNamespace(namespc_obj));
44
45 // Allocate a native wrapper for the platform namespc bits.
46 Namespace* namespc = NULL;
47 Dart_Handle result;
48 Dart_Handle native_namespc = Dart_GetNativeArgument(args, 1);
49 if (Dart_IsInteger(native_namespc)) {
50 int64_t namespc_val;
51 result = Dart_IntegerToInt64(native_namespc, &namespc_val);
52 if (Dart_IsError(result)) {
53 Dart_PropagateError(result);
54 }
55 namespc = Namespace::Create(namespc_val);
56 } else if (Dart_IsString(native_namespc)) {
57 const char* namespc_path;
58 result = Dart_StringToCString(native_namespc, &namespc_path);
59 if (Dart_IsError(result)) {
60 Dart_PropagateError(result);
61 }
62 namespc = Namespace::Create(namespc_path);
63 } else {
64 // Propagate a type error.
65 Dart_ThrowException(
66 DartUtils::NewDartArgumentError("Argument must be an int or a String"));
67 }
68
69 // We were unable to create a native Namespace wrapper object due to some
70 // OS-level error.
71 if (namespc == NULL) {
72 Dart_SetReturnValue(args, DartUtils::NewDartOSError());
73 }
74
75 // Set the Dart objects native field to the native wrapper.
76 result = Dart_SetNativeInstanceField(namespc_obj, kNamespaceNativeFieldIndex,
77 reinterpret_cast<intptr_t>(namespc));
78 if (Dart_IsError(result)) {
79 namespc->Release();
80 Dart_PropagateError(result);
81 }
82
83 // Set up a finalizer for the Dart object so that we can do any necessary
84 // platform-specific cleanup for the namespc.
85 Dart_NewFinalizableHandle(namespc_obj, reinterpret_cast<void*>(namespc),
86 sizeof(*namespc), ReleaseNamespace);
87 Dart_SetReturnValue(args, namespc_obj);
88}
89
90void FUNCTION_NAME(Namespace_GetDefault)(Dart_NativeArguments args) {
91 Dart_SetIntegerReturnValue(args, Namespace::Default());
92}
93
94void FUNCTION_NAME(Namespace_GetPointer)(Dart_NativeArguments args) {
95 Namespace* namespc = Namespace::GetNamespace(args, 0);
96 ASSERT(namespc != NULL);
97 namespc->Retain();
98 Dart_SetIntegerReturnValue(args, reinterpret_cast<intptr_t>(namespc));
99}
100
101Namespace* Namespace::GetNamespace(Dart_NativeArguments args, intptr_t index) {
102 Namespace* namespc;
103 Dart_Handle status =
104 Namespace::GetNativeNamespaceArgument(args, index, &namespc);
105 if (Dart_IsError(status)) {
106 Dart_PropagateError(status);
107 }
108 return namespc;
109}
110
111bool Namespace::IsDefault(Namespace* namespc) {
112 return (namespc == NULL) || (namespc->namespc() == NULL);
113}
114
115Dart_Handle Namespace::GetNativeNamespaceArgument(Dart_NativeArguments args,
116 intptr_t index,
117 Namespace** namespc) {
118 Dart_Handle namespc_obj = Dart_GetNativeArgument(args, index);
119 if (Dart_IsError(namespc_obj)) {
120 return namespc_obj;
121 }
122 DEBUG_ASSERT(IsNamespace(namespc_obj));
123
124 Dart_Handle result =
125 Dart_GetNativeInstanceField(namespc_obj, kNamespaceNativeFieldIndex,
126 reinterpret_cast<intptr_t*>(namespc));
127 if (Dart_IsError(result)) {
128 return result;
129 }
130 if (*namespc == NULL) {
131 return Dart_NewUnhandledExceptionError(
132 DartUtils::NewInternalError("No native peer"));
133 }
134 return Dart_Null();
135}
136
137} // namespace bin
138} // namespace dart
139
140#endif // !defined(DART_IO_DISABLED)
141