| Index: utils/archive/dart_archive.c
|
| diff --git a/utils/archive/dart_archive.c b/utils/archive/dart_archive.c
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..be53570e70fa6cd19a00aa8298d84849d04621d5
|
| --- /dev/null
|
| +++ b/utils/archive/dart_archive.c
|
| @@ -0,0 +1,248 @@
|
| +// 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 <assert.h>
|
| +#include <errno.h>
|
| +#include <stdlib.h>
|
| +
|
| +#include "dart_archive.h"
|
| +#include "messaging.h"
|
| +
|
| +/** The enumeration of request types for communicating with Dart. */
|
| +enum RequestType {
|
| + kArchiveReadNew = 0,
|
| + kArchiveReadSupportFilterAll,
|
| + kArchiveReadSupportFilterBzip2,
|
| + kArchiveReadSupportFilterCompress,
|
| + kArchiveReadSupportFilterGzip,
|
| + kArchiveReadSupportFilterLzma,
|
| + kArchiveReadSupportFilterXz,
|
| + kArchiveReadSupportFilterProgram,
|
| + kArchiveReadSupportFilterProgramSignature,
|
| + kArchiveReadSupportFormatAll,
|
| + kArchiveReadSupportFormatAr,
|
| + kArchiveReadSupportFormatCpio,
|
| + kArchiveReadSupportFormatEmpty,
|
| + kArchiveReadSupportFormatIso9660,
|
| + kArchiveReadSupportFormatMtree,
|
| + kArchiveReadSupportFormatRaw,
|
| + kArchiveReadSupportFormatTar,
|
| + kArchiveReadSupportFormatZip,
|
| + kArchiveReadSetFilterOptions,
|
| + kArchiveReadSetFormatOptions,
|
| + kArchiveReadSetOptions,
|
| + kArchiveReadOpenFilename,
|
| + kArchiveReadOpenMemory,
|
| + kArchiveReadNextHeader,
|
| + kArchiveReadDataBlock,
|
| + kArchiveReadDataSkip,
|
| + kArchiveReadClose,
|
| + kArchiveReadFree,
|
| + kNumberOfRequestTypes
|
| +};
|
| +
|
| +/**
|
| + * Dispatches a message from Dart to its native function equivalent.
|
| + *
|
| + * In addition to matching up a message with its respective function, this
|
| + * parses out the standard archive struct argument from the message and resolves
|
| + * it to an actual pointer to an archive struct.
|
| + */
|
| +static void archiveDispatch(Dart_Port dest_port_id,
|
| + Dart_Port reply_port_id,
|
| + Dart_CObject* message) {
|
| + if (message->type != kArray) {
|
| + postInvalidArgument(reply_port_id, "Message was not an array.");
|
| + return;
|
| + } else if (message->value.as_array.length < 2) {
|
| + postInvalidArgument(reply_port_id, "Message array had %d elements, " \
|
| + "expected at least 2.", message->value.as_array.length);
|
| + return;
|
| + }
|
| +
|
| + Dart_CObject* wrapped_request_type = message->value.as_array.values[0];
|
| + if (wrapped_request_type->type != kInt32) {
|
| + postInvalidArgument(reply_port_id, "Invalid request type %d.",
|
| + wrapped_request_type->type);
|
| + return;
|
| + }
|
| + enum RequestType request_type = wrapped_request_type->value.as_int32;
|
| +
|
| + Dart_CObject* archive_id = message->value.as_array.values[1];
|
| + struct archive* archive;
|
| + if (archive_id->type == kNull) {
|
| + archive = NULL;
|
| + } else if (archive_id->type == kInt64 || archive_id->type == kInt32) {
|
| + archive = (struct archive*) (intptr_t) getInteger(archive_id);
|
| + } else {
|
| + postInvalidArgument(reply_port_id, "Invalid archive id type %d.",
|
| + archive_id->type);
|
| + return;
|
| + }
|
| +
|
| + switch (request_type) {
|
| + case kArchiveReadNew:
|
| + archiveReadNew(reply_port_id);
|
| + break;
|
| + case kArchiveReadSupportFilterAll:
|
| + archiveReadSupportFilterAll(reply_port_id, archive);
|
| + break;
|
| + case kArchiveReadSupportFilterBzip2:
|
| + archiveReadSupportFilterBzip2(reply_port_id, archive);
|
| + break;
|
| + case kArchiveReadSupportFilterCompress:
|
| + archiveReadSupportFilterCompress(reply_port_id, archive);
|
| + break;
|
| + case kArchiveReadSupportFilterGzip:
|
| + archiveReadSupportFilterGzip(reply_port_id, archive);
|
| + break;
|
| + case kArchiveReadSupportFilterLzma:
|
| + archiveReadSupportFilterLzma(reply_port_id, archive);
|
| + break;
|
| + case kArchiveReadSupportFilterXz:
|
| + archiveReadSupportFilterXz(reply_port_id, archive);
|
| + break;
|
| + case kArchiveReadSupportFilterProgram:
|
| + archiveReadSupportFilterProgram(reply_port_id, archive, message);
|
| + break;
|
| + case kArchiveReadSupportFilterProgramSignature:
|
| + archiveReadSupportFilterProgramSignature(
|
| + reply_port_id, archive, message);
|
| + break;
|
| + case kArchiveReadSupportFormatAll:
|
| + archiveReadSupportFormatAll(reply_port_id, archive);
|
| + break;
|
| + case kArchiveReadSupportFormatAr:
|
| + archiveReadSupportFormatAr(reply_port_id, archive);
|
| + break;
|
| + case kArchiveReadSupportFormatCpio:
|
| + archiveReadSupportFormatCpio(reply_port_id, archive);
|
| + break;
|
| + case kArchiveReadSupportFormatEmpty:
|
| + archiveReadSupportFormatEmpty(reply_port_id, archive);
|
| + break;
|
| + case kArchiveReadSupportFormatIso9660:
|
| + archiveReadSupportFormatIso9660(reply_port_id, archive);
|
| + break;
|
| + case kArchiveReadSupportFormatMtree:
|
| + archiveReadSupportFormatMtree(reply_port_id, archive);
|
| + break;
|
| + case kArchiveReadSupportFormatRaw:
|
| + archiveReadSupportFormatRaw(reply_port_id, archive);
|
| + break;
|
| + case kArchiveReadSupportFormatTar:
|
| + archiveReadSupportFormatTar(reply_port_id, archive);
|
| + break;
|
| + case kArchiveReadSupportFormatZip:
|
| + archiveReadSupportFormatZip(reply_port_id, archive);
|
| + break;
|
| + case kArchiveReadSetFilterOptions:
|
| + archiveReadSetFilterOptions(reply_port_id, archive, message);
|
| + break;
|
| + case kArchiveReadSetFormatOptions:
|
| + archiveReadSetFormatOptions(reply_port_id, archive, message);
|
| + break;
|
| + case kArchiveReadSetOptions:
|
| + archiveReadSetOptions(reply_port_id, archive, message);
|
| + break;
|
| + case kArchiveReadOpenFilename:
|
| + archiveReadOpenFilename(reply_port_id, archive, message);
|
| + break;
|
| + case kArchiveReadOpenMemory:
|
| + archiveReadOpenMemory(reply_port_id, archive, message);
|
| + break;
|
| + case kArchiveReadNextHeader:
|
| + archiveReadNextHeader(reply_port_id, archive);
|
| + break;
|
| + case kArchiveReadDataBlock:
|
| + archiveReadDataBlock(reply_port_id, archive);
|
| + break;
|
| + case kArchiveReadDataSkip:
|
| + archiveReadDataSkip(reply_port_id, archive);
|
| + break;
|
| + case kArchiveReadClose:
|
| + archiveReadClose(reply_port_id, archive);
|
| + break;
|
| + case kArchiveReadFree:
|
| + archiveReadFree(reply_port_id, archive);
|
| + break;
|
| + default:
|
| + postInvalidArgument(reply_port_id, "Invalid request id %d.", request_type);
|
| + break;
|
| + }
|
| +}
|
| +
|
| +/**
|
| + * Checks if [handle] represents an error and, if so, propagates it to Dart.
|
| + * Otherwise, returns [handle].
|
| + */
|
| +static Dart_Handle handleError(Dart_Handle handle) {
|
| + if (Dart_IsError(handle)) Dart_PropagateError(handle);
|
| + return handle;
|
| +}
|
| +
|
| +/**
|
| + * A function exposed to Dart that creates a [ServicePort] for two-way
|
| + * communication between Dart and C.
|
| + *
|
| + * Takes no arguments and returns a [ServicePort].
|
| + */
|
| +static void archiveServicePort(Dart_NativeArguments arguments) {
|
| + Dart_EnterScope();
|
| + Dart_SetReturnValue(arguments, Dart_Null());
|
| + Dart_Port service_port =
|
| + Dart_NewNativePort("ArchiveService", archiveDispatch, false);
|
| + if (service_port != ILLEGAL_PORT) {
|
| + Dart_Handle send_port = handleError(Dart_NewSendPort(service_port));
|
| + Dart_SetReturnValue(arguments, send_port);
|
| + }
|
| + Dart_ExitScope();
|
| +}
|
| +
|
| +/**
|
| + * A struct representing a function exposed to Dart and the name under which it
|
| + * can be looked up.
|
| + */
|
| +struct FunctionLookup {
|
| + const char* name;
|
| + Dart_NativeFunction function;
|
| +};
|
| +
|
| +/** The list of functions exposed to Dart. */
|
| +struct FunctionLookup function_list[] = {
|
| + {"Archive_ServicePort", archiveServicePort},
|
| + {NULL, NULL}
|
| +};
|
| +
|
| +/**
|
| + * Resolves a Dart name as provided in a `native` declaration and returns the
|
| + * C function that should be invoked for that name.
|
| + */
|
| +static Dart_NativeFunction resolveName(Dart_Handle name, int argc) {
|
| + if (!Dart_IsString8(name)) return NULL;
|
| + Dart_EnterScope();
|
| + const char* cname;
|
| + handleError(Dart_StringToCString(name, &cname));
|
| +
|
| + Dart_NativeFunction result = NULL;
|
| + int i;
|
| + for (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;
|
| +}
|
| +
|
| +/** Initializes the C extension. */
|
| +DART_EXPORT Dart_Handle dart_archive_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();
|
| +}
|
|
|