Index: samples/sample_extension/sample_extension_no_autoscope.cc |
=================================================================== |
--- samples/sample_extension/sample_extension_no_autoscope.cc (revision 0) |
+++ samples/sample_extension/sample_extension_no_autoscope.cc (revision 0) |
@@ -0,0 +1,168 @@ |
+// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
+// for details. All rights reserved. Use of this source code is governed by a |
+// BSD-style license that can be found in the LICENSE file. |
+#include <string.h> |
+#include <stdlib.h> |
+#include <stdio.h> |
+#include "include/dart_api.h" |
+#include "include/dart_native_api.h" |
+ |
+ |
+Dart_NativeFunction ResolveName(Dart_Handle name, |
+ int argc, |
+ bool* auto_setup_scope); |
+ |
+ |
+DART_EXPORT Dart_Handle sample_extension_no_autoscope_Init( |
+ Dart_Handle parent_library) { |
+ if (Dart_IsError(parent_library)) { |
+ return parent_library; |
+ } |
+ |
+ Dart_Handle result_code = Dart_SetNativeResolver(parent_library, ResolveName); |
+ if (Dart_IsError(result_code)) { |
+ return result_code; |
+ } |
+ |
+ return Dart_Null(); |
+} |
+ |
+ |
+Dart_Handle HandleError(Dart_Handle handle) { |
+ if (Dart_IsError(handle)) { |
+ Dart_PropagateError(handle); |
+ } |
+ return handle; |
+} |
+ |
+ |
+void SystemRand(Dart_NativeArguments arguments) { |
+ Dart_EnterScope(); |
+ Dart_Handle result = HandleError(Dart_NewInteger(rand())); |
+ Dart_SetReturnValue(arguments, result); |
+ Dart_ExitScope(); |
+} |
+ |
+ |
+void SystemSrand(Dart_NativeArguments arguments) { |
+ Dart_EnterScope(); |
+ bool success = false; |
+ Dart_Handle seed_object = HandleError(Dart_GetNativeArgument(arguments, 0)); |
+ if (Dart_IsInteger(seed_object)) { |
+ bool fits; |
+ HandleError(Dart_IntegerFitsIntoInt64(seed_object, &fits)); |
+ if (fits) { |
+ int64_t seed; |
+ HandleError(Dart_IntegerToInt64(seed_object, &seed)); |
+ srand(static_cast<unsigned>(seed)); |
+ success = true; |
+ } |
+ } |
+ Dart_SetReturnValue(arguments, HandleError(Dart_NewBoolean(success))); |
+ Dart_ExitScope(); |
+} |
+ |
+ |
+uint8_t* randomArray(int seed, int length) { |
+ if (length <= 0 || length > 10000000) { |
+ return NULL; |
+ } |
+ uint8_t* values = reinterpret_cast<uint8_t*>(malloc(length)); |
+ if (NULL == values) { |
+ return NULL; |
+ } |
+ srand(seed); |
+ for (int i = 0; i < length; ++i) { |
+ values[i] = rand() % 256; |
+ } |
+ return values; |
+} |
+ |
+ |
+void wrappedRandomArray(Dart_Port dest_port_id, |
+ Dart_CObject* message) { |
+ Dart_Port reply_port_id = ILLEGAL_PORT; |
+ if (message->type == Dart_CObject_kArray && |
+ 3 == message->value.as_array.length) { |
+ // Use .as_array and .as_int32 to access the data in the Dart_CObject. |
+ Dart_CObject* param0 = message->value.as_array.values[0]; |
+ Dart_CObject* param1 = message->value.as_array.values[1]; |
+ Dart_CObject* param2 = message->value.as_array.values[2]; |
+ if (param0->type == Dart_CObject_kInt32 && |
+ param1->type == Dart_CObject_kInt32 && |
+ param2->type == Dart_CObject_kSendPort) { |
+ int seed = param0->value.as_int32; |
+ int length = param1->value.as_int32; |
+ reply_port_id = param2->value.as_send_port; |
+ uint8_t* values = randomArray(seed, length); |
+ |
+ if (values != NULL) { |
+ Dart_CObject result; |
+ result.type = Dart_CObject_kTypedData; |
+ result.value.as_typed_data.type = Dart_TypedData_kUint8; |
+ result.value.as_typed_data.values = values; |
+ result.value.as_typed_data.length = length; |
+ Dart_PostCObject(reply_port_id, &result); |
+ free(values); |
+ // It is OK that result is destroyed when function exits. |
+ // Dart_PostCObject has copied its data. |
+ return; |
+ } |
+ } |
+ } |
+ Dart_CObject result; |
+ result.type = Dart_CObject_kNull; |
+ Dart_PostCObject(reply_port_id, &result); |
+} |
+ |
+ |
+void randomArrayServicePort(Dart_NativeArguments arguments) { |
+ Dart_EnterScope(); |
+ Dart_SetReturnValue(arguments, Dart_Null()); |
+ Dart_Port service_port = |
+ Dart_NewNativePort("RandomArrayService", wrappedRandomArray, true); |
+ if (service_port != ILLEGAL_PORT) { |
+ Dart_Handle send_port = HandleError(Dart_NewSendPort(service_port)); |
+ Dart_SetReturnValue(arguments, send_port); |
+ } |
+ Dart_ExitScope(); |
+} |
+ |
+ |
+struct FunctionLookup { |
+ const char* name; |
+ Dart_NativeFunction function; |
+}; |
+ |
+ |
+FunctionLookup function_list[] = { |
+ {"SystemRand", SystemRand}, |
+ {"SystemSrand", SystemSrand}, |
+ {"RandomArray_ServicePort", randomArrayServicePort}, |
+ {NULL, NULL}}; |
+ |
+ |
+Dart_NativeFunction ResolveName(Dart_Handle name, |
+ int argc, |
+ bool* auto_setup_scope) { |
+ if (!Dart_IsString(name)) { |
+ return NULL; |
+ } |
+ Dart_NativeFunction result = NULL; |
+ if (auto_setup_scope == NULL) { |
+ return NULL; |
+ } |
+ *auto_setup_scope = false; |
+ Dart_EnterScope(); |
+ const char* cname; |
+ HandleError(Dart_StringToCString(name, &cname)); |
+ |
+ for (int i=0; function_list[i].name != NULL; ++i) { |
+ if (strcmp(function_list[i].name, cname) == 0) { |
+ result = function_list[i].function; |
+ break; |
+ } |
+ } |
+ Dart_ExitScope(); |
+ return result; |
+} |