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

Side by Side Diff: runtime/lib/vmservice.cc

Issue 1474603003: Move tar archive parsing to C++ (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Remove <string> and <vector> Created 5 years 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 unified diff | Download patch
OLDNEW
1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 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. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/bootstrap_natives.h" 5 #include "vm/bootstrap_natives.h"
6
7 #include "vm/dart_api_impl.h" 6 #include "vm/dart_api_impl.h"
8 #include "vm/exceptions.h" 7 #include "vm/exceptions.h"
8 #include "vm/growable_array.h"
9 #include "vm/message.h" 9 #include "vm/message.h"
10 #include "vm/native_entry.h" 10 #include "vm/native_entry.h"
11 #include "vm/object.h" 11 #include "vm/object.h"
12 #include "vm/port.h" 12 #include "vm/port.h"
13 #include "vm/service_isolate.h" 13 #include "vm/service_isolate.h"
14 #include "vm/symbols.h" 14 #include "vm/symbols.h"
15 15
16 namespace dart { 16 namespace dart {
17 17
18 DECLARE_FLAG(bool, trace_service); 18 DECLARE_FLAG(bool, trace_service);
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
144 GET_NON_NULL_NATIVE_ARGUMENT(String, stream_id, arguments->NativeArgAt(0)); 144 GET_NON_NULL_NATIVE_ARGUMENT(String, stream_id, arguments->NativeArgAt(0));
145 Service::CancelStream(stream_id.ToCString()); 145 Service::CancelStream(stream_id.ToCString());
146 return Object::null(); 146 return Object::null();
147 } 147 }
148 148
149 149
150 DEFINE_NATIVE_ENTRY(VMService_RequestAssets, 0) { 150 DEFINE_NATIVE_ENTRY(VMService_RequestAssets, 0) {
151 return Service::RequestAssets(); 151 return Service::RequestAssets();
152 } 152 }
153 153
154
155 class ByteStream {
Ivan Posva 2015/11/25 17:09:04 How does this differ from class ReadStream in data
zra 2015/11/25 19:06:15 There isn't a big difference, and I changed to use
156 public:
157 ByteStream(uint8_t* bytes, intptr_t bytes_length) :
158 bytes_(bytes), bytes_length_(bytes_length), cursor_(0) {}
159
160 intptr_t length() const { return bytes_length_; }
161
162 intptr_t remaining() const { return length() - cursor_; }
163
164 intptr_t cursor() const { return cursor_; }
165
166 uint8_t* current() const {
167 return bytes_ + cursor_;
168 }
169
170 uint8_t PeekByte(intptr_t index = 0) const {
171 return bytes_[cursor_ + index];
172 }
173
174 uint8_t ReadByte() {
175 uint8_t r = PeekByte();
176 advance(1);
177 return r;
178 }
179
180 intptr_t ReadBytes(uint8_t* bytes, intptr_t num_bytes) {
181 uint8_t* src = bytes_ + cursor_;
182 num_bytes = num_bytes > remaining() ? remaining() : num_bytes;
183 memmove(bytes, src, num_bytes);
184 advance(num_bytes);
185 return num_bytes;
186 }
187
188 void Skip(intptr_t bytes) {
189 advance(bytes);
190 }
191
192 void SeekToNextBlock(intptr_t blockSize) {
193 intptr_t remainder = blockSize - (cursor_ % blockSize);
194 advance(remainder);
195 }
196
197 void SetCursor(intptr_t cursor) {
198 cursor_ = cursor;
199 if (cursor_ > length()) {
200 cursor_ = length();
201 }
202 }
203
204 private:
205 void advance(intptr_t bytes) {
206 cursor_ += bytes;
207 if (cursor_ > length()) {
208 cursor_ = length();
209 }
210 }
211
212 uint8_t* bytes_;
213 intptr_t bytes_length_;
214 intptr_t cursor_;
215
216 DISALLOW_COPY_AND_ASSIGN(ByteStream);
217 };
218
219
220 class TarArchive {
221 public:
222 static const intptr_t tarHeaderSize = 512;
Ivan Posva 2015/11/25 17:09:04 enum instead of a set of constants? Then you can a
zra 2015/11/25 19:06:15 Changed to private enums.
223 static const intptr_t tarHeaderFilenameSize = 100;
224 static const intptr_t tarHeaderFilenameOffset = 0;
225 static const intptr_t tarHeaderSizeSize = 12;
226 static const intptr_t tarHeaderSizeOffset = 124;
227 static const intptr_t tarHeaderTypeSize = 1;
228 static const intptr_t tarHeaderTypeOffset = 156;
229 static const intptr_t tarHeaderFileType = 0x30;
230
231 TarArchive(uint8_t* bytes, intptr_t bytes_length)
232 : bs_(bytes, bytes_length) {}
233
234 void Read() {
235 while (HasNext()) {
236 char* filename;
237 uint8_t* data;
238 intptr_t data_length;
239 if (Next(&filename, &data, &data_length)) {
240 filenames_.Add(filename);
241 contents_.Add(data);
242 content_lengths_.Add(data_length);
243 }
244 }
245 }
246
247 char* NextFilename() {
248 return filenames_.RemoveLast();
249 }
250
251 uint8_t* NextContent() {
252 return contents_.RemoveLast();
253 }
254
255 intptr_t NextContentLength() {
256 return content_lengths_.RemoveLast();
257 }
258
259 bool HasMore() const {
260 return filenames_.length() > 0;
261 }
262
263 intptr_t Length() const { return filenames_.length(); }
264
265 private:
266 bool HasNext() const {
267 return !EndOfArchive();
268 }
269
270 bool Next(char** filename, uint8_t** data, intptr_t* data_length) {
271 intptr_t startOfBlock = bs_.cursor();
272 *filename = ReadFilename();
273 bs_.SetCursor(startOfBlock + tarHeaderSizeOffset);
274 intptr_t size = ReadSize();
275 bs_.SetCursor(startOfBlock + tarHeaderTypeOffset);
276 uint8_t type = ReadType();
277 bs_.SeekToNextBlock(tarHeaderSize);
278 if (type != tarHeaderFileType) {
279 SkipContents(size);
280 return false;
281 }
282 ReadContents(data, size);
283 *data_length = size;
284 return true;
285 }
286
287 bool EndOfArchive() const {
288 if (bs_.remaining() < (tarHeaderSize * 2)) {
289 return true;
290 }
291 for (intptr_t i = 0; i < (tarHeaderSize * 2); i++) {
292 if (bs_.PeekByte(i) != 0) {
293 return false;
294 }
295 }
296 return true;
297 }
298
299 uint8_t ReadType() {
300 return bs_.ReadByte();
301 }
302
303 void SkipContents(intptr_t size) {
304 bs_.Skip(size);
305 bs_.SeekToNextBlock(tarHeaderSize);
306 }
307
308 intptr_t ReadCString(char** s, intptr_t length) {
309 intptr_t to_read = Utils::Minimum(length, bs_.remaining());
310 char* result = new char[to_read + 1];
311 strncpy(result, reinterpret_cast<char*>(bs_.current()), to_read);
312 result[to_read] = '\0';
313 bs_.SetCursor(bs_.cursor() + to_read);
314 *s = result;
315 return to_read;
316 }
317
318 intptr_t ReadSize() {
319 char* octalSize;
320 unsigned int size;
321
322 ReadCString(&octalSize, tarHeaderSizeSize);
323 int result = sscanf(octalSize, "%o", &size);
324 delete[] octalSize;
325
326 if (result != 1) {
327 return 0;
328 }
329 return size;
330 }
331
332 char* ReadFilename() {
333 char* result;
334 intptr_t result_length = ReadCString(&result, tarHeaderFilenameSize);
335 if (result[0] == '/') {
336 return result;
337 }
338 char* fixed_result = new char[result_length + 2]; // '/' + '\0'.
339 fixed_result[0] = '/';
340 strncpy(&fixed_result[1], result, result_length);
341 fixed_result[result_length + 1] = '\0';
342 delete[] result;
343 return fixed_result;
344 }
345
346 void ReadContents(uint8_t** data, intptr_t size) {
347 uint8_t* result = new uint8_t[size];
348 bs_.ReadBytes(result, size);
349 bs_.SeekToNextBlock(tarHeaderSize);
350 *data = result;
351 }
352
353 ByteStream bs_;
354 GrowableArray<char*> filenames_;
355 GrowableArray<uint8_t*> contents_;
356 GrowableArray<intptr_t> content_lengths_;
357
358 DISALLOW_COPY_AND_ASSIGN(TarArchive);
359 };
360
361 static void ContentsFinalizer(void* isolate_callback_data,
362 Dart_WeakPersistentHandle handle,
363 void* peer) {
364 uint8_t* data = reinterpret_cast<uint8_t*>(peer);
Ivan Posva 2015/11/25 17:36:44 You also should delete the handle here. No?
zra 2015/11/25 19:06:15 Looking at //runtime/bin/io_buffer.h the Finalizer
zra 2015/11/25 20:52:58 We verified offline that WeakPersistentHandles are
365 delete[] data;
366 }
367
368 DEFINE_NATIVE_ENTRY(VMService_DecodeAssets, 1) {
369 GET_NON_NULL_NATIVE_ARGUMENT(TypedData, data, arguments->NativeArgAt(0));
370 Api::Scope scope(thread);
371
372 Dart_Handle data_handle = Api::NewHandle(thread->isolate(), data.raw());
373
374 Dart_TypedData_Type typ;
375 void* bytes;
376 intptr_t length;
377 Dart_Handle err = Dart_TypedDataAcquireData(
378 data_handle, &typ, &bytes, &length);
Ivan Posva 2015/11/25 17:36:44 As discussed we should check if there is a possibi
zra 2015/11/25 19:06:16 Filed issue #25041 and added a TODO.
379 ASSERT(!Dart_IsError(err));
380
381 TarArchive archive(reinterpret_cast<uint8_t*>(bytes), length);
382 archive.Read();
383
384 err = Dart_TypedDataReleaseData(data_handle);
385 ASSERT(!Dart_IsError(err));
386
387 intptr_t archive_size = archive.Length();
388
389 const Array& result_list = Array::Handle(thread->zone(),
390 Array::New(archive_size));
391
392 intptr_t idx = 0;
393 while (archive.HasMore()) {
394 char* filename = archive.NextFilename();
395 uint8_t* contents = archive.NextContent();
396 intptr_t contents_length = archive.NextContentLength();
397
398 const Array& pair = Array::Handle(thread->zone(), Array::New(2));
399
400 const String& dart_filename = String::Handle(thread->zone(),
401 String::New(filename));
402 delete[] filename;
403
404 Dart_Handle dart_contents = Dart_NewExternalTypedData(
405 Dart_TypedData_kUint8, contents, contents_length);
406 ASSERT(!Dart_IsError(dart_contents));
407 Dart_NewWeakPersistentHandle(
408 dart_contents, contents, contents_length, ContentsFinalizer);
409
410 pair.SetAt(0, dart_filename);
411 pair.SetAt(1, Api::UnwrapExternalTypedDataHandle(
412 thread->zone(), dart_contents));
413 result_list.SetAt(idx, pair);
414 idx++;
415 }
416
417 return result_list.raw();
418 }
419
154 } // namespace dart 420 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698