OLD | NEW |
---|---|
(Empty) | |
1 // Copyright (c) 2012, 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 #include <assert.h> | |
6 #include <errno.h> | |
7 #include <stdlib.h> | |
8 | |
9 #include "dart_archive.h" | |
10 #include "messaging.h" | |
11 | |
12 /** The enumeration of request types for communicating with Dart. */ | |
13 enum RequestType { | |
14 kArchiveReadNew = 0, | |
15 kArchiveReadSupportFilterAll, | |
16 kArchiveReadSupportFilterBzip2, | |
17 kArchiveReadSupportFilterCompress, | |
18 kArchiveReadSupportFilterGzip, | |
19 kArchiveReadSupportFilterLzma, | |
20 kArchiveReadSupportFilterXz, | |
21 kArchiveReadSupportFilterProgram, | |
22 kArchiveReadSupportFilterProgramSignature, | |
23 kArchiveReadSupportFormatAll, | |
24 kArchiveReadSupportFormatAr, | |
25 kArchiveReadSupportFormatCpio, | |
26 kArchiveReadSupportFormatEmpty, | |
27 kArchiveReadSupportFormatIso9660, | |
28 kArchiveReadSupportFormatMtree, | |
29 kArchiveReadSupportFormatRaw, | |
30 kArchiveReadSupportFormatTar, | |
31 kArchiveReadSupportFormatZip, | |
32 kArchiveReadSetFilterOptions, | |
33 kArchiveReadSetFormatOptions, | |
34 kArchiveReadSetOptions, | |
35 kArchiveReadOpenFilename, | |
36 kArchiveReadOpenMemory, | |
37 kArchiveReadNextHeader, | |
38 kArchiveReadDataBlock, | |
39 kArchiveReadDataSkip, | |
40 kArchiveReadClose, | |
41 kArchiveReadFree, | |
42 kNumberOfRequestTypes | |
43 }; | |
44 | |
45 /** | |
46 * Dispatches a message from Dart to its native function equivalent. | |
47 * | |
48 * In addition to matching up a message with its respective function, this | |
49 * parses out the standard archive struct argument from the message and resolves | |
50 * it to an actual pointer to an archive struct. | |
51 */ | |
52 static void archiveDispatch(Dart_Port dest_port_id, | |
53 Dart_Port reply_port_id, | |
54 Dart_CObject* message) { | |
55 if (message->type != kArray) { | |
56 postInvalidArgument(reply_port_id, "Message was not an array."); | |
57 return; | |
58 } else if (message->value.as_array.length < 2) { | |
59 char buffer[100]; | |
60 snprintf(buffer, 100, "Message array had %d elements, expected at least 2.", | |
61 message->value.as_array.length); | |
62 postInvalidArgument(reply_port_id, buffer); | |
63 return; | |
64 } | |
65 | |
66 Dart_CObject* wrapped_request_type = message->value.as_array.values[0]; | |
67 if (wrapped_request_type->type != kInt32) { | |
68 char buffer[100]; | |
69 snprintf(buffer, 100, "Invalid request type %d.", | |
70 wrapped_request_type->type); | |
71 postInvalidArgument(reply_port_id, buffer); | |
Bob Nystrom
2012/07/31 21:56:48
The above three lines are repeated frequently. I k
nweiz
2012/07/31 23:38:25
Done.
| |
72 return; | |
73 } | |
74 enum RequestType request_type = wrapped_request_type->value.as_int32; | |
75 if (request_type < kArchiveReadNew || request_type >= kNumberOfRequestTypes) { | |
76 char buffer[100]; | |
Bob Nystrom
2012/07/31 21:56:48
Instead of checking this here, how about making it
nweiz
2012/07/31 23:38:25
Done.
| |
77 snprintf(buffer, 100, "Invalid request id %d.", request_type); | |
78 postInvalidArgument(reply_port_id, buffer); | |
79 return; | |
80 } | |
81 | |
82 Dart_CObject* archive_id = message->value.as_array.values[1]; | |
83 struct archive* archive; | |
84 if (archive_id->type == kNull) { | |
85 archive = NULL; | |
86 } else if (archive_id->type == kInt64 || archive_id->type == kInt32) { | |
87 archive = (struct archive*) (intptr_t) getInteger(archive_id); | |
88 } else { | |
89 char buffer[100]; | |
90 snprintf(buffer, 100, "Invalid archive id type %d.", archive_id->type); | |
91 postInvalidArgument(reply_port_id, buffer); | |
92 return; | |
93 } | |
94 | |
95 switch (request_type) { | |
96 case kArchiveReadNew: | |
97 archiveReadNew(reply_port_id); | |
98 break; | |
99 case kArchiveReadSupportFilterAll: | |
100 archiveReadSupportFilterAll(reply_port_id, archive); | |
101 break; | |
102 case kArchiveReadSupportFilterBzip2: | |
103 archiveReadSupportFilterBzip2(reply_port_id, archive); | |
104 break; | |
105 case kArchiveReadSupportFilterCompress: | |
106 archiveReadSupportFilterCompress(reply_port_id, archive); | |
107 break; | |
108 case kArchiveReadSupportFilterGzip: | |
109 archiveReadSupportFilterGzip(reply_port_id, archive); | |
110 break; | |
111 case kArchiveReadSupportFilterLzma: | |
112 archiveReadSupportFilterLzma(reply_port_id, archive); | |
113 break; | |
114 case kArchiveReadSupportFilterXz: | |
115 archiveReadSupportFilterXz(reply_port_id, archive); | |
116 break; | |
117 case kArchiveReadSupportFilterProgram: | |
118 archiveReadSupportFilterProgram(reply_port_id, archive, message); | |
119 break; | |
120 case kArchiveReadSupportFilterProgramSignature: | |
121 archiveReadSupportFilterProgramSignature( | |
122 reply_port_id, archive, message); | |
123 break; | |
124 case kArchiveReadSupportFormatAll: | |
125 archiveReadSupportFormatAll(reply_port_id, archive); | |
126 break; | |
127 case kArchiveReadSupportFormatAr: | |
128 archiveReadSupportFormatAr(reply_port_id, archive); | |
129 break; | |
130 case kArchiveReadSupportFormatCpio: | |
131 archiveReadSupportFormatCpio(reply_port_id, archive); | |
132 break; | |
133 case kArchiveReadSupportFormatEmpty: | |
134 archiveReadSupportFormatEmpty(reply_port_id, archive); | |
135 break; | |
136 case kArchiveReadSupportFormatIso9660: | |
137 archiveReadSupportFormatIso9660(reply_port_id, archive); | |
138 break; | |
139 case kArchiveReadSupportFormatMtree: | |
140 archiveReadSupportFormatMtree(reply_port_id, archive); | |
141 break; | |
142 case kArchiveReadSupportFormatRaw: | |
143 archiveReadSupportFormatRaw(reply_port_id, archive); | |
144 break; | |
145 case kArchiveReadSupportFormatTar: | |
146 archiveReadSupportFormatTar(reply_port_id, archive); | |
147 break; | |
148 case kArchiveReadSupportFormatZip: | |
149 archiveReadSupportFormatZip(reply_port_id, archive); | |
150 break; | |
151 case kArchiveReadSetFilterOptions: | |
152 archiveReadSetFilterOptions(reply_port_id, archive, message); | |
153 break; | |
154 case kArchiveReadSetFormatOptions: | |
155 archiveReadSetFormatOptions(reply_port_id, archive, message); | |
156 break; | |
157 case kArchiveReadSetOptions: | |
158 archiveReadSetOptions(reply_port_id, archive, message); | |
159 break; | |
160 case kArchiveReadOpenFilename: | |
161 archiveReadOpenFilename(reply_port_id, archive, message); | |
162 break; | |
163 case kArchiveReadOpenMemory: | |
164 archiveReadOpenMemory(reply_port_id, archive, message); | |
165 break; | |
166 case kArchiveReadNextHeader: | |
167 archiveReadNextHeader(reply_port_id, archive); | |
168 break; | |
169 case kArchiveReadDataBlock: | |
170 archiveReadDataBlock(reply_port_id, archive); | |
171 break; | |
172 case kArchiveReadDataSkip: | |
173 archiveReadDataSkip(reply_port_id, archive); | |
174 break; | |
175 case kArchiveReadClose: | |
176 archiveReadClose(reply_port_id, archive); | |
177 break; | |
178 case kArchiveReadFree: | |
179 archiveReadFree(reply_port_id, archive); | |
180 break; | |
181 } | |
182 } | |
183 | |
184 /** | |
185 * Checks if [handle] represents an error and, if so, propagates it to Dart. | |
186 * Otherwise, returns [handle]. | |
187 */ | |
188 static Dart_Handle HandleError(Dart_Handle handle) { | |
189 if (Dart_IsError(handle)) Dart_PropagateError(handle); | |
190 return handle; | |
191 } | |
192 | |
193 /** | |
194 * A function exposed to Dart that creates a [ServicePort] for two-way | |
195 * communication between Dart and C. | |
196 * | |
197 * Takes no arguments and returns a [ServicePort]. | |
198 */ | |
199 static void archiveServicePort(Dart_NativeArguments arguments) { | |
200 Dart_EnterScope(); | |
201 Dart_SetReturnValue(arguments, Dart_Null()); | |
202 Dart_Port service_port = | |
203 Dart_NewNativePort("ArchiveService", archiveDispatch, false); | |
204 if (service_port != ILLEGAL_PORT) { | |
205 Dart_Handle send_port = HandleError(Dart_NewSendPort(service_port)); | |
206 Dart_SetReturnValue(arguments, send_port); | |
207 } | |
208 Dart_ExitScope(); | |
209 } | |
210 | |
211 // Standard name resolution code | |
Bob Nystrom
2012/07/31 21:56:48
Can probably remove this.
nweiz
2012/07/31 23:38:25
Done.
| |
212 | |
213 /** | |
214 * A struct representing a function exposed to Dart and the name under which it | |
215 * can be looked up. | |
216 */ | |
217 struct FunctionLookup { | |
218 const char* name; | |
219 Dart_NativeFunction function; | |
220 }; | |
221 | |
222 /** The list of functions exposed to Dart. */ | |
223 struct FunctionLookup function_list[] = { | |
224 {"Archive_ServicePort", archiveServicePort}, | |
225 {NULL, NULL}}; | |
Bob Nystrom
2012/07/31 21:56:48
I would put the last } on the next line:
struct F
nweiz
2012/07/31 23:38:25
This style was copied from the sample_extension ex
nweiz
2012/07/31 23:38:25
Done.
| |
226 | |
227 /** | |
228 * Resolves a Dart name as provided in a `native` declaration and returns the | |
229 * C function that should be invoked for that name. | |
230 */ | |
231 static Dart_NativeFunction ResolveName(Dart_Handle name, int argc) { | |
232 if (!Dart_IsString8(name)) return NULL; | |
233 Dart_NativeFunction result = NULL; | |
234 Dart_EnterScope(); | |
235 const char* cname; | |
236 HandleError(Dart_StringToCString(name, &cname)); | |
237 | |
238 int i; | |
Bob Nystrom
2012/07/31 21:56:48
I would move the declaration of result to just abo
nweiz
2012/07/31 23:38:25
Done. This is all copied from sample_extension, bu
| |
239 for (i=0; function_list[i].name != NULL; ++i) { | |
Bob Nystrom
2012/07/31 21:56:48
Spaces around =
nweiz
2012/07/31 23:38:25
Done.
| |
240 if (strcmp(function_list[i].name, cname) == 0) { | |
241 result = function_list[i].function; | |
242 break; | |
243 } | |
244 } | |
245 Dart_ExitScope(); | |
246 return result; | |
247 } | |
248 | |
249 /** Initializes the C extension. */ | |
250 DART_EXPORT Dart_Handle dart_archive_Init(Dart_Handle parent_library) { | |
251 if (Dart_IsError(parent_library)) return parent_library; | |
252 | |
253 Dart_Handle result_code = Dart_SetNativeResolver(parent_library, ResolveName); | |
254 if (Dart_IsError(result_code)) return result_code; | |
255 | |
256 return Dart_Null(); | |
257 } | |
OLD | NEW |