Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(801)

Unified Diff: mojo/dart/embedder/mojo_io_natives.cc

Issue 1760523007: Add support for compression filters in the mojo dart:io (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « mojo/dart/embedder/io/mojo_patch.dart ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: mojo/dart/embedder/mojo_io_natives.cc
diff --git a/mojo/dart/embedder/mojo_io_natives.cc b/mojo/dart/embedder/mojo_io_natives.cc
index dd18a868e661935a18429c4b1a3c8e9d8d4e16d3..80f283a8875aed4052cdeec5005325151195215c 100644
--- a/mojo/dart/embedder/mojo_io_natives.cc
+++ b/mojo/dart/embedder/mojo_io_natives.cc
@@ -4,10 +4,12 @@
#include <stdio.h>
#include <string.h>
+#include <limits>
#include "dart/runtime/include/dart_api.h"
#include "mojo/dart/embedder/builtin.h"
#include "mojo/dart/embedder/common.h"
+#include "mojo/dart/embedder/io/filter.h"
#include "mojo/dart/embedder/io/internet_address.h"
#include "mojo/dart/embedder/mojo_dart_state.h"
#include "mojo/public/cpp/system/macros.h"
@@ -16,6 +18,11 @@ namespace mojo {
namespace dart {
#define MOJO_IO_NATIVE_LIST(V) \
+ V(Filter_CreateZLibDeflate, 8) \
+ V(Filter_CreateZLibInflate, 4) \
+ V(Filter_End, 1) \
+ V(Filter_Process, 4) \
+ V(Filter_Processed, 3) \
V(InternetAddress_Parse, 1) \
V(InternetAddress_Reverse, 1) \
V(Platform_NumberOfProcessors, 0) \
@@ -68,6 +75,266 @@ const uint8_t* MojoIoNativeSymbol(Dart_NativeFunction nf) {
return nullptr;
}
+class IOBuffer {
+ public:
+ static Dart_Handle Allocate(intptr_t size, uint8_t **buffer) {
+ uint8_t* data = Allocate(size);
+ Dart_Handle result = Dart_NewExternalTypedData(
+ Dart_TypedData_kUint8, data, size);
+ Dart_NewWeakPersistentHandle(result, data, size, IOBuffer::Finalizer);
+
+ if (Dart_IsError(result)) {
+ Free(data);
+ Dart_PropagateError(result);
+ }
+ if (buffer != NULL) {
+ *buffer = data;
+ }
+ return result;
+ }
+
+ // Allocate IO buffer storage.
+ static uint8_t* Allocate(intptr_t size) {
+ return new uint8_t[size];
+ }
+
+ // Function for disposing of IO buffer storage. All backing storage
+ // for IO buffers must be freed using this function.
+ static void Free(void* buffer) {
+ delete[] reinterpret_cast<uint8_t*>(buffer);
+ }
+
+ // Function for finalizing external byte arrays used as IO buffers.
+ static void Finalizer(void* isolate_callback_data,
+ Dart_WeakPersistentHandle handle,
+ void* buffer) {
+ Free(buffer);
+ }
+
+ private:
+ DISALLOW_IMPLICIT_CONSTRUCTORS(IOBuffer);
+};
+
+static Filter* GetFilter(Dart_Handle filter_obj) {
+ Filter* filter;
+ Dart_Handle result = Filter::GetFilterPointerNativeField(filter_obj, &filter);
+ if (Dart_IsError(result)) {
+ Dart_PropagateError(result);
+ }
+ if (filter == NULL) {
+ Dart_ThrowException(DartEmbedder::NewInternalError("Filter destroyed"));
+ }
+ return filter;
+}
+
+static void EndFilter(Dart_Handle filter_obj, Filter* filter) {
+ Filter::SetFilterPointerNativeField(filter_obj, NULL);
+ delete filter;
+}
+
+static uint8_t* copyDictionary(Dart_Handle dictionary_obj) {
+ uint8_t* src = NULL;
+ intptr_t size;
+ Dart_TypedData_Type type;
+
+ if (Dart_IsError(Dart_ListLength(dictionary_obj, &size))) {
+ Dart_ThrowException(DartEmbedder::NewInternalError(
+ "Failed to get the zlib dictionary length"));
+ }
+
+ uint8_t* dictionary = new uint8_t[size];
+
+ if (dictionary == NULL) {
+ Dart_ThrowException(DartEmbedder::NewInternalError(
+ "Failed to allocate buffer for the zlib dictionary"));
+ }
+
+ Dart_Handle result = Dart_TypedDataAcquireData(
+ dictionary_obj, &type, reinterpret_cast<void**>(&src), &size);
+ if (!Dart_IsError(result)) {
+ memmove(dictionary, src, size);
+ Dart_TypedDataReleaseData(dictionary_obj);
+ } else {
+ if (Dart_IsError(Dart_ListGetAsBytes(dictionary_obj, 0, dictionary,
+ size))) {
+ Dart_ThrowException(DartEmbedder::NewInternalError(
+ "Failed to get the zlib dictionary"));
+ }
+ }
+
+ return dictionary;
+}
+
+void Filter_CreateZLibInflate(Dart_NativeArguments args) {
+ Dart_Handle filter_obj = Dart_GetNativeArgument(args, 0);
+ Dart_Handle window_bits_obj = Dart_GetNativeArgument(args, 1);
+ int64_t window_bits = DartEmbedder::GetIntegerValue(window_bits_obj);
+ Dart_Handle dict_obj = Dart_GetNativeArgument(args, 2);
+ uint8_t* dictionary = NULL;
+ intptr_t dictionary_length = 0;
+ if (!Dart_IsNull(dict_obj)) {
+ dictionary = copyDictionary(dict_obj);
+ if (dictionary != NULL) {
+ dictionary_length = 0;
+ Dart_ListLength(dict_obj, &dictionary_length);
+ }
+ }
+ Dart_Handle raw_obj = Dart_GetNativeArgument(args, 3);
+ bool raw;
+ if (Dart_IsError(Dart_BooleanValue(raw_obj, &raw))) {
+ Dart_ThrowException(DartEmbedder::NewInternalError(
+ "Failed to get 'raw' parameter"));
+ }
+ Filter* filter = new ZLibInflateFilter(static_cast<int32_t>(window_bits),
+ dictionary, dictionary_length, raw);
+ if (!filter->Init()) {
+ delete filter;
+ Dart_ThrowException(DartEmbedder::NewInternalError(
+ "Failed to create ZLibInflateFilter"));
+ }
+ Dart_Handle result = Filter::SetFilterPointerNativeField(filter_obj, filter);
+ if (Dart_IsError(result)) {
+ delete filter;
+ Dart_PropagateError(result);
+ }
+}
+
+void Filter_CreateZLibDeflate(Dart_NativeArguments args) {
+ Dart_Handle filter_obj = Dart_GetNativeArgument(args, 0);
+ Dart_Handle gzip_obj = Dart_GetNativeArgument(args, 1);
+ bool gzip = DartEmbedder::GetBooleanValue(gzip_obj);
+ Dart_Handle level_obj = Dart_GetNativeArgument(args, 2);
+ int64_t level = DartEmbedder::GetInt64ValueCheckRange(
+ level_obj,
+ std::numeric_limits<int32_t>::min(),
+ std::numeric_limits<int32_t>::max());
+ Dart_Handle window_bits_obj = Dart_GetNativeArgument(args, 3);
+ int64_t window_bits = DartEmbedder::GetIntegerValue(window_bits_obj);
+ Dart_Handle mLevel_obj = Dart_GetNativeArgument(args, 4);
+ int64_t mem_level = DartEmbedder::GetIntegerValue(mLevel_obj);
+ Dart_Handle strategy_obj = Dart_GetNativeArgument(args, 5);
+ int64_t strategy = DartEmbedder::GetIntegerValue(strategy_obj);
+ Dart_Handle dict_obj = Dart_GetNativeArgument(args, 6);
+ uint8_t* dictionary = NULL;
+ intptr_t dictionary_length = 0;
+ if (!Dart_IsNull(dict_obj)) {
+ dictionary = copyDictionary(dict_obj);
+ if (dictionary != NULL) {
+ dictionary_length = 0;
+ Dart_ListLength(dict_obj, &dictionary_length);
+ }
+ }
+ Dart_Handle raw_obj = Dart_GetNativeArgument(args, 7);
+ bool raw = DartEmbedder::GetBooleanValue(raw_obj);
+ Filter* filter = new ZLibDeflateFilter(gzip, static_cast<int32_t>(level),
+ static_cast<int32_t>(window_bits),
+ static_cast<int32_t>(mem_level),
+ static_cast<int32_t>(strategy),
+ dictionary, dictionary_length, raw);
+ if (!filter->Init()) {
+ delete filter;
+ Dart_ThrowException(DartEmbedder::NewInternalError(
+ "Failed to create ZLibDeflateFilter"));
+ }
+ Dart_Handle result = Filter::SetFilterPointerNativeField(filter_obj, filter);
+ if (Dart_IsError(result)) {
+ delete filter;
+ Dart_PropagateError(result);
+ }
+}
+
+void Filter_Process(Dart_NativeArguments args) {
+ Dart_Handle filter_obj = Dart_GetNativeArgument(args, 0);
+ Filter* filter = GetFilter(filter_obj);
+ Dart_Handle data_obj = Dart_GetNativeArgument(args, 1);
+ intptr_t start =
+ DartEmbedder::GetIntptrValue(Dart_GetNativeArgument(args, 2));
+ intptr_t end = DartEmbedder::GetIntptrValue(Dart_GetNativeArgument(args, 3));
+ intptr_t chunk_length = end - start;
+ intptr_t length;
+ Dart_TypedData_Type type;
+ uint8_t* buffer = NULL;
+ Dart_Handle result = Dart_TypedDataAcquireData(
+ data_obj, &type, reinterpret_cast<void**>(&buffer), &length);
+
+ if (!Dart_IsError(result)) {
+ DCHECK(type == Dart_TypedData_kUint8 || type == Dart_TypedData_kInt8);
+ if (type != Dart_TypedData_kUint8 && type != Dart_TypedData_kInt8) {
+ Dart_TypedDataReleaseData(data_obj);
+ Dart_ThrowException(DartEmbedder::NewInternalError(
+ "Invalid argument passed to Filter_Process"));
+ }
+ uint8_t* zlib_buffer = new uint8_t[chunk_length];
+ if (zlib_buffer == NULL) {
+ Dart_TypedDataReleaseData(data_obj);
+ Dart_ThrowException(DartEmbedder::NewInternalError(
+ "Failed to allocate buffer for zlib"));
+ }
+ memmove(zlib_buffer, buffer + start, chunk_length);
+ Dart_TypedDataReleaseData(data_obj);
+ buffer = zlib_buffer;
+ } else {
+ if (Dart_IsError(Dart_ListLength(data_obj, &length))) {
+ Dart_ThrowException(DartEmbedder::NewInternalError(
+ "Failed to get list length"));
+ }
+ buffer = new uint8_t[chunk_length];
+ if (Dart_IsError(Dart_ListGetAsBytes(
+ data_obj, start, buffer, chunk_length))) {
+ delete[] buffer;
+ Dart_ThrowException(DartEmbedder::NewInternalError(
+ "Failed to get list bytes"));
+ }
+ }
+ // Process will take ownership of buffer, if successful.
+ if (!filter->Process(buffer, chunk_length)) {
+ delete[] buffer;
+ EndFilter(filter_obj, filter);
+ Dart_ThrowException(DartEmbedder::NewInternalError(
+ "Call to Process while still processing data"));
+ }
+}
+
+void Filter_Processed(Dart_NativeArguments args) {
+ Dart_Handle filter_obj = Dart_GetNativeArgument(args, 0);
+ Filter* filter = GetFilter(filter_obj);
+ Dart_Handle flush_obj = Dart_GetNativeArgument(args, 1);
+ bool flush;
+ if (Dart_IsError(Dart_BooleanValue(flush_obj, &flush))) {
+ Dart_ThrowException(DartEmbedder::NewInternalError(
+ "Failed to get 'flush' parameter"));
+ }
+ Dart_Handle end_obj = Dart_GetNativeArgument(args, 2);
+ bool end;
+ if (Dart_IsError(Dart_BooleanValue(end_obj, &end))) {
+ Dart_ThrowException(DartEmbedder::NewInternalError(
+ "Failed to get 'end' parameter"));
+ }
+ intptr_t read = filter->Processed(filter->processed_buffer(),
+ filter->processed_buffer_size(),
+ flush,
+ end);
+ if (read < 0) {
+ // Error, end filter.
+ EndFilter(filter_obj, filter);
+ Dart_ThrowException(DartEmbedder::NewInternalError(
+ "Filter error, bad data"));
+ } else if (read == 0) {
+ Dart_SetReturnValue(args, Dart_Null());
+ } else {
+ uint8_t* io_buffer;
+ Dart_Handle result = IOBuffer::Allocate(read, &io_buffer);
+ memmove(io_buffer, filter->processed_buffer(), read);
+ Dart_SetReturnValue(args, result);
+ }
+}
+
+void Filter_End(Dart_NativeArguments args) {
+ Dart_Handle filter_obj = Dart_GetNativeArgument(args, 0);
+ Filter* filter = GetFilter(filter_obj);
+ EndFilter(filter_obj, filter);
+}
+
void InternetAddress_Parse(Dart_NativeArguments arguments) {
const char* address = DartEmbedder::GetStringArgument(arguments, 0);
CHECK(address != nullptr);
« no previous file with comments | « mojo/dart/embedder/io/mojo_patch.dart ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698