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

Unified Diff: utils/archive/entry.dart

Issue 10842002: Add the beginnings of a Dart wrapper for libarchive. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years, 5 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
Index: utils/archive/entry.dart
diff --git a/utils/archive/entry.dart b/utils/archive/entry.dart
new file mode 100644
index 0000000000000000000000000000000000000000..42fb60112728a0cb123ae180bfd4aae1f2c220e1
--- /dev/null
+++ b/utils/archive/entry.dart
@@ -0,0 +1,221 @@
+// 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.
+
+#library("entry");
+
+#import("dart:io");
+#import("read_request.dart");
+#import("utils.dart");
+
+/**
+ * A single file in an archive.
+ *
+ * This is accessible via [ArchiveInputStream.onEntry].
+ */
+class ArchiveEntry {
+ /**
+ * The various properties of this archive entry, as sent over from the C
+ * extension.
+ */
+ final List _array;
Bob Nystrom 2012/07/31 21:56:48 Can you give this a better name? "_properties"?
nweiz 2012/07/31 23:38:25 Done.
+
+ /**
+ * The id of the archive to which this entry belongs. Used to read the entry
+ * data. This will be set to null once there's no longer data available to be
+ * read for this entry.
+ */
+ int _archiveId;
+
+ /**
+ * The input stream being used to read data from this entry. This is null
+ * until [openInputStream] is called.
+ */
+ InputStream _input;
+
+ // TODO(nweiz): Get rid of this once issue 4202 is fixed.
+ /**
+ * A future that only exists once [openInputStream] is called, and completes
+ * once the input stream is closed.
+ *
+ * For internal use only.
Bob Nystrom 2012/07/31 21:56:48 Make it private then?
nweiz 2012/07/31 23:38:25 It needs to be accessible from input_stream.dart.
+ */
+ Future inputComplete;
+
+ ArchiveEntry(this._archiveId, this._array);
+
+ /** If this entry is a hardlink, this is the destination. Otherwise, null. */
+ String get hardlink() => _array[0];
+
+ /** The path to this entry in the archive. */
+ String get pathname() => _array[1];
+
+ /** The path to this entry on disk, */
+ String get sourcepath() => _array[2];
+
+ /** If this entry is a symlink, this is the destination. Otherwise, null. */
+ String get symlink() => _array[3];
+
+ /** The group identifier for this entry. */
+ int get gid() => _array[4];
+
+ /** The user identifier for this entry. */
+ int get uid() => _array[5];
+
+ /** The permissions bitmask for this entry. */
+ int get perm_mask() => _array[6];
+
+ /** The String representation of the permissions for this entry. */
+ String get strmode() => _array[7];
+
+ /** The name of the group this entry belongs to. */
+ String get gname() => _array[8];
+
+ /** The name of the user this entry belongs to. */
+ String get uname() => _array[9];
+
+ /** The file flag bits that should be set for this entry. */
+ int get fflags_set() => _array[10];
+
+ /** The file flag bits that should be cleared for this entry. */
+ int get fflags_clear() => _array[11];
+
+ /** The textual representation of the file flags for this entry. */
+ String get fflags_text() => _array[12];
+
+ /** The filetype bitmask for this entry. */
+ int get filetype_mask() => _array[13];
+
+ /** The filetype and permissions bitmask for this entry. */
+ int get mode_mask() => _array[14];
+
+ /** The size of this entry in bytes, or null if it's unset. */
+ int get size() => _array[15];
+
+ /** The ID of the device containing this entry, or null if it's unset. */
+ int get dev() => _array[16];
+
+ /** The major number of the ID of the device containing this entry. */
+ int get devmajor() => _array[17];
+
+ /** The minor number of the ID of the device containing this entry. */
+ int get devminor() => _array[18];
+
+ /** The inode number of this entry, or null if it's unset. */
+ int get ino() => _array[19];
+
+ /** The number of references to this entry. */
+ int get nlink() => _array[20];
+
+ /** The device ID of this entry. */
+ int get rdev() => _array[21];
+
+ /** The major number of the device ID of this entry. */
+ int get rdevmajor() => _array[22];
+
+ /** The minor number of the device ID of this entry. */
+ int get rdevminor() => _array[23];
+
+ /** The last time this entry was accessed. */
+ Date get atime() => new Date.fromMillisecondsSinceEpoch(_array[24]);
+
+ /** The nanoseconds at the last time this entry was accessed. */
+ int get atime_nsec() => _array[25];
+
+ /** The time this entry was created. */
+ Date get birthtime() => new Date.fromMillisecondsSinceEpoch(_array[26]);
+
+ /** The nanoseconds at the time this entry was created. */
+ int get birthtime_nsec() => _array[27];
+
+ /** The last time an inode property of this entry was changed. */
+ Date get ctime() => new Date.fromMillisecondsSinceEpoch(_array[28]);
+
+ /**
+ * The nanoseconds at the last time an inode property of this entry was
+ * changed.
+ */
+ int get ctime_nsec() => _array[29];
+
+ /** The last time this entry was modified. */
+ Date get mtime() => new Date.fromMillisecondsSinceEpoch(_array[30]);
+
+ /** The nanoseconds at the last time this entry was modified. */
+ int get mtime_nsec() => _array[31];
+
+ /** Whether [openInputStream] has been called. */
+ bool get inputOpened() => _input != null;
Bob Nystrom 2012/07/31 21:56:48 "isInputOpen" Past tense names are usually for ev
nweiz 2012/07/31 23:38:25 Done.
+
+ /**
+ * Creates a new input stream for reading the contents of this entry.
+ *
+ * The contents of an entry must be consumed before the next entry is read
+ * from the parent [ArchiveInputStream]. This means that [openInputStream]
+ * must be called from the [ArchiveInputStream.onEntry] callback, or before
+ * the future returned by that callback completes. Once the next entry has
+ * been read, calling [openInputStream] will throw an [ArchiveError].
+ *
+ * Only one input stream may be opened per entry.
+ */
+ InputStream openInputStream() {
+ if (_archiveId == null) {
+ throw new ArchiveError("Archive entry $pathname is no longer being read "
+ "from the archive.");
Bob Nystrom 2012/07/31 21:56:48 Ideally these would be StateException, but in the
nweiz 2012/07/31 23:38:25 Done.
+ } else if (_input != null) {
+ throw new ArchiveError("An input stream has already been opened for "
+ "archive entry $pathname.");
+ }
+
+ var inputCompleter = new Completer();
+ inputComplete = inputCompleter.future;
+
+ _input = new ListInputStream();
+ // TODO(nweiz): Report errors once issue 3657 is fixed
+ var fut = _consumeInput().chain((_) {
Bob Nystrom 2012/07/31 21:56:48 "fut" -> "future".
nweiz 2012/07/31 23:38:25 Done.
+ if (!_input.closed) _input.markEndOfStream();
+ // Asynchronously complete to give the InputStream callbacks a chance to
+ // fire.
+ return async();
+ }).transform((_) => inputCompleter.complete(null));
+
+ fut.handleException((e) {
+ print(e);
+ print(fut.stackTrace);
+ });
+ return _input;
+ }
+
+ /**
+ * Close this entry so that its input stream no longer produces data.
+ *
+ * In addition to closing the associated input stream, this will prevent new
+ * input streams from being opened.
+ */
+ void close() {
+ _archiveId = null;
+ if (_input != null) _input.close();
+ }
+
+ /**
+ * Read all data from the archive and write it to [_input]. Returns a future
+ * that completes once this is done.
+ *
+ * This assumes that both [_input] and [_archiveId] are non-null and that
+ * [_input] is open, although if that changes before this completes it will
+ * handle it gracefully.
+ */
+ Future _consumeInput() {
+ var data;
+ return call(DATA_BLOCK, _archiveId).chain((_data) {
+ data = _data;
+ // TODO(nweiz): This async() call is only necessary because of issue 4222.
+ return async();
+ }).chain((_) {
+ if (_input.closed || _archiveId == null || data == null) {
+ return new Future.immediate(null);
+ }
+ _input.write(data);
+ return _consumeInput();
+ });
+ }
+}

Powered by Google App Engine
This is Rietveld 408576698