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

Side by Side Diff: utils/archive/entry.dart

Issue 10832116: Attach the native entry struct to the ArchiveEntry object. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years, 4 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 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 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 #library("entry"); 5 #library("entry");
6 6
7 #import("dart:io"); 7 #import("dart:io");
8 #import("read_request.dart"); 8 #import("archive.dart", prefix: "archive");
9 #import("entry_request.dart");
10 #import("read_request.dart", prefix: 'read');
9 #import("utils.dart"); 11 #import("utils.dart");
10 12
11 /** 13 /**
12 * A single file in an archive. 14 * A single file in an archive.
13 * 15 *
14 * This is accessible via [ArchiveInputStream.onEntry]. 16 * This is accessible via [ArchiveInputStream.onEntry].
15 */ 17 */
16 class ArchiveEntry { 18 class ArchiveEntry {
17 /** 19 /**
18 * The various properties of this archive entry, as sent over from the C 20 * The various properties of this archive entry, as sent over from the C
(...skipping 16 matching lines...) Expand all
35 37
36 // TODO(nweiz): Get rid of this once issue 4202 is fixed. 38 // TODO(nweiz): Get rid of this once issue 4202 is fixed.
37 /** 39 /**
38 * A future that only exists once [openInputStream] is called, and completes 40 * A future that only exists once [openInputStream] is called, and completes
39 * once the input stream is closed. 41 * once the input stream is closed.
40 * 42 *
41 * For internal use only. 43 * For internal use only.
42 */ 44 */
43 Future inputComplete; 45 Future inputComplete;
44 46
45 ArchiveEntry(this._archiveId, this._properties); 47 ArchiveEntry.internal(this._properties, this._archiveId) {
48 attachFinalizer(this, (id) => call(FREE, id), _id);
49 }
50
51 /** Create a new [ArchiveEntry] with default values for all of its fields. */
52 static Future<ArchiveEntry> create() {
53 return call(NEW).transform((properties) {
54 return new archive.ArchiveEntry.internal(properties, null);
55 });
56 }
57
58 /** The id of the underlying archive entry. */
59 int get _id() => _properties[0];
46 60
47 /** If this entry is a hardlink, this is the destination. Otherwise, null. */ 61 /** If this entry is a hardlink, this is the destination. Otherwise, null. */
48 String get hardlink() => _properties[0]; 62 String get hardlink() => _properties[1];
63 set hardlink(String value) => _set(SET_HARDLINK, 1, value);
49 64
50 /** The path to this entry in the archive. */ 65 /** The path to this entry in the archive. */
51 String get pathname() => _properties[1]; 66 String get pathname() => _properties[2];
67 set pathname(String value) => _set(SET_PATHNAME, 2, value);
52 68
53 /** The path to this entry on disk, */ 69 /** The path to this entry on disk, */
54 String get sourcepath() => _properties[2]; 70 String get sourcepath() => _properties[3];
71 set sourcepath(String value) => _set(SET_SOURCEPATH, 3, value);
55 72
56 /** If this entry is a symlink, this is the destination. Otherwise, null. */ 73 /** If this entry is a symlink, this is the destination. Otherwise, null. */
57 String get symlink() => _properties[3]; 74 String get symlink() => _properties[4];
75 set symlink(String value) => _set(SET_SYMLINK, 4, value);
58 76
59 /** The group identifier for this entry. */ 77 /** The group identifier for this entry. */
60 int get gid() => _properties[4]; 78 int get gid() => _properties[5];
79 set gid(int value) => _set(SET_GID, 5, value);
61 80
62 /** The user identifier for this entry. */ 81 /** The user identifier for this entry. */
63 int get uid() => _properties[5]; 82 int get uid() => _properties[6];
83 set uid(int value) => _set(SET_UID, 6, value);
64 84
65 /** The permissions bitmask for this entry. */ 85 /** The permissions bitmask for this entry. */
66 int get perm_mask() => _properties[6]; 86 int get perm_mask() => _properties[7];
87 set perm_mask(int value) => _set(SET_PERM, 7, value);
67 88
68 /** The String representation of the permissions for this entry. */ 89 /**
69 String get strmode() => _properties[7]; 90 * The String representation of the permissions for this entry.
91 *
92 * Note that if you set [perm_mask], this value will not change.
93 */
94 String get strmode() => _properties[8];
70 95
71 /** The name of the group this entry belongs to. */ 96 /** The name of the group this entry belongs to. */
72 String get gname() => _properties[8]; 97 String get gname() => _properties[9];
98 set gname(String value) => _set(SET_GNAME, 9, value);
73 99
74 /** The name of the user this entry belongs to. */ 100 /** The name of the user this entry belongs to. */
75 String get uname() => _properties[9]; 101 String get uname() => _properties[10];
102 set uname(String value) => _set(SET_UNAME, 10, value);
76 103
77 /** The file flag bits that should be set for this entry. */ 104 /**
78 int get fflags_set() => _properties[10]; 105 * The file flag bits that should be set for this entry.
106 *
107 * Note that if you set [fflags_text], this value will not change, and vice
108 * versa.
109 */
110 int get fflags_set() => _properties[11];
111 set fflags_set(int value) => _set(SET_FFLAGS_SET, 11, value);
79 112
80 /** The file flag bits that should be cleared for this entry. */ 113 /**
81 int get fflags_clear() => _properties[11]; 114 * The file flag bits that should be cleared for this entry.
115 *
116 * Note that if you set [fflags_text], this value will not change, and vice
117 * versa.
118 */
119 int get fflags_clear() => _properties[12];
120 set fflags_clear(int value) => _set(SET_FFLAGS_CLEAR, 12, value);
82 121
83 /** The textual representation of the file flags for this entry. */ 122 /**
84 String get fflags_text() => _properties[12]; 123 * The textual representation of the file flags for this entry.
124 *
125 * Note that if you set [fflags_set] or [fflags_clear], this value will not
126 * change, and vice versa.
127 */
128 String get fflags_text() => _properties[13];
129 set fflags_text(String value) => _set(SET_FFLAGS_TEXT, 13, value);
85 130
86 /** The filetype bitmask for this entry. */ 131 /** The filetype bitmask for this entry. */
87 int get filetype_mask() => _properties[13]; 132 int get filetype_mask() => _properties[14];
133 set filetype_mask(int value) => _set(SET_FILETYPE, 14, value);
88 134
89 /** The filetype and permissions bitmask for this entry. */ 135 /** The filetype and permissions bitmask for this entry. */
90 int get mode_mask() => _properties[14]; 136 int get mode_mask() => _properties[15];
137 set mode_mask(int value) => _set(SET_MODE, 15, value);
91 138
92 /** The size of this entry in bytes, or null if it's unset. */ 139 /** The size of this entry in bytes, or null if it's unset. */
93 int get size() => _properties[15]; 140 int get size() => _properties[16];
141 set size(int value) => _set(SET_SIZE, 16, value);
94 142
95 /** The ID of the device containing this entry, or null if it's unset. */ 143 /** The ID of the device containing this entry, or null if it's unset. */
96 int get dev() => _properties[16]; 144 int get dev() => _properties[17];
145 set dev(int value) => _set(SET_DEV, 17, value);
97 146
98 /** The major number of the ID of the device containing this entry. */ 147 /** The major number of the ID of the device containing this entry. */
99 int get devmajor() => _properties[17]; 148 int get devmajor() => _properties[18];
149 set devmajor(int value) => _set(SET_DEVMAJOR, 18, value);
100 150
101 /** The minor number of the ID of the device containing this entry. */ 151 /** The minor number of the ID of the device containing this entry. */
102 int get devminor() => _properties[18]; 152 int get devminor() => _properties[19];
153 set devminor(int value) => _set(SET_DEVMINOR, 19, value);
103 154
104 /** The inode number of this entry, or null if it's unset. */ 155 /** The inode number of this entry, or null if it's unset. */
105 int get ino() => _properties[19]; 156 int get ino() => _properties[20];
157 set ino(int value) => _set(SET_INO, 20, value);
106 158
107 /** The number of references to this entry. */ 159 /** The number of references to this entry. */
108 int get nlink() => _properties[20]; 160 int get nlink() => _properties[21];
161 set nlink(int value) => _set(SET_NLINK, 21, value);
109 162
110 /** The device ID of this entry. */ 163 /** The device ID of this entry. */
111 int get rdev() => _properties[21]; 164 int get rdev() => _properties[22];
165 set rdev(int value) => _set(SET_RDEV, 22, value);
112 166
113 /** The major number of the device ID of this entry. */ 167 /** The major number of the device ID of this entry. */
114 int get rdevmajor() => _properties[22]; 168 int get rdevmajor() => _properties[23];
169 set rdevmajor(int value) => _set(SET_RDEVMAJOR, 23, value);
115 170
116 /** The minor number of the device ID of this entry. */ 171 /** The minor number of the device ID of this entry. */
117 int get rdevminor() => _properties[23]; 172 int get rdevminor() => _properties[24];
173 set rdevminor(int value) => _set(SET_RDEVMINOR, 24, value);
118 174
119 /** The last time this entry was accessed. */ 175 /** The last time this entry was accessed, or null if it's unset. */
120 Date get atime() => new Date.fromMillisecondsSinceEpoch(_properties[24]); 176 Date get atime() => _fromMs(_properties[25]);
177 set atime(Date value) => _set(SET_ATIME, 25, _toMs(value));
121 178
122 /** The nanoseconds at the last time this entry was accessed. */ 179 /** The time this entry was created, or null if it's unset. */
123 int get atime_nsec() => _properties[25]; 180 Date get birthtime() => _fromMs(_properties[26]);
124 181 set birthtime(Date value) => _set(SET_BIRTHTIME, 26, _toMs(value));
125 /** The time this entry was created. */
126 Date get birthtime() => new Date.fromMillisecondsSinceEpoch(_properties[26]);
127
128 /** The nanoseconds at the time this entry was created. */
129 int get birthtime_nsec() => _properties[27];
130
131 /** The last time an inode property of this entry was changed. */
132 Date get ctime() => new Date.fromMillisecondsSinceEpoch(_properties[28]);
133 182
134 /** 183 /**
135 * The nanoseconds at the last time an inode property of this entry was 184 * The last time an inode property of this entry was changed, or null if it's
136 * changed. 185 * unset.
137 */ 186 */
138 int get ctime_nsec() => _properties[29]; 187 Date get ctime() => _fromMs(_properties[27]);
188 set ctime(Date value) => _set(SET_CTIME, 27, _toMs(value));
139 189
140 /** The last time this entry was modified. */ 190 /** The last time this entry was modified, or null if it's unset. */
141 Date get mtime() => new Date.fromMillisecondsSinceEpoch(_properties[30]); 191 Date get mtime() => _fromMs(_properties[28]);
142 192 set mtime(Date value) => _set(SET_MTIME, 28, _toMs(value));
143 /** The nanoseconds at the last time this entry was modified. */
144 int get mtime_nsec() => _properties[31];
145 193
146 /** Whether [openInputStream] has been called. */ 194 /** Whether [openInputStream] has been called. */
147 bool get isInputOpen() => _input != null; 195 bool get isInputOpen() => _input != null;
148 196
197 /** Create a deep copy of this [ArchiveEntry]. */
198 Future<ArchiveEntry> clone() {
199 return call(CLONE, _id).
200 transform((array) => new archive.ArchiveEntry.internal(array, null));
201 }
202
203 /**
204 * Set a property value with index [value] on the local representation of the
205 * archive entry and on the native representation.
206 */
207 void _set(int requestType, int index, value) {
208 _properties[index] = value;
209 // Since the native code processes messages in order, the SET_* messages
210 // will be received and processed before any further messages.
211 call(requestType, _id, [value]).then((_) {});
212 }
213
214 /**
215 * Converts [ms], the (possibly null) number of milliseconds since the epoch
216 * into a Date object (which may also be null).
217 */
218 Date _fromMs(int ms) {
219 if (ms == null) return null;
220 return new Date.fromMillisecondsSinceEpoch(ms);
221 }
222
223 /**
224 * Converts [date], which may be null, into the number of milliseconds since
225 * the epoch (which may also be null).
226 */
227 int _toMs(Date date) {
228 if (date == null) return null;
229 return date.millisecondsSinceEpoch;
230 }
231
149 /** 232 /**
150 * Creates a new input stream for reading the contents of this entry. 233 * Creates a new input stream for reading the contents of this entry.
151 * 234 *
152 * The contents of an entry must be consumed before the next entry is read 235 * The contents of an entry must be consumed before the next entry is read
153 * from the parent [ArchiveInputStream]. This means that [openInputStream] 236 * from the parent [ArchiveInputStream]. This means that [openInputStream]
154 * must be called from the [ArchiveInputStream.onEntry] callback, or before 237 * must be called from the [ArchiveInputStream.onEntry] callback, or before
155 * the future returned by that callback completes. Once the next entry has 238 * the future returned by that callback completes. Once the next entry has
156 * been read, calling [openInputStream] will throw an [ArchiveException]. 239 * been read, calling [openInputStream] will throw an [ArchiveException].
157 * 240 *
158 * Only one input stream may be opened per entry. 241 * Only one input stream may be opened per entry.
159 */ 242 */
160 InputStream openInputStream() { 243 InputStream openInputStream() {
161 if (_archiveId == null) { 244 if (_archiveId == null) {
162 throw new UnsupportedOperationException("Archive entry $pathname is no " 245 throw new UnsupportedOperationException("Cannot open input stream for "
163 "longer being read from the archive."); 246 "archive entry $pathname.");
164 } else if (_input != null) { 247 } else if (_input != null) {
165 throw new UnsupportedOperationException("An input stream has already been" 248 throw new UnsupportedOperationException("An input stream has already been"
166 "opened for archive entry $pathname."); 249 "opened for archive entry $pathname.");
167 } 250 }
168 251
169 var inputCompleter = new Completer(); 252 var inputCompleter = new Completer();
170 inputComplete = inputCompleter.future; 253 inputComplete = inputCompleter.future;
171 254
172 _input = new ListInputStream(); 255 _input = new ListInputStream();
173 // TODO(nweiz): Report errors once issue 3657 is fixed 256 // TODO(nweiz): Report errors once issue 3657 is fixed
(...skipping 25 matching lines...) Expand all
199 /** 282 /**
200 * Read all data from the archive and write it to [_input]. Returns a future 283 * Read all data from the archive and write it to [_input]. Returns a future
201 * that completes once this is done. 284 * that completes once this is done.
202 * 285 *
203 * This assumes that both [_input] and [_archiveId] are non-null and that 286 * This assumes that both [_input] and [_archiveId] are non-null and that
204 * [_input] is open, although if that changes before this completes it will 287 * [_input] is open, although if that changes before this completes it will
205 * handle it gracefully. 288 * handle it gracefully.
206 */ 289 */
207 Future _consumeInput() { 290 Future _consumeInput() {
208 var data; 291 var data;
209 return call(DATA_BLOCK, _archiveId).chain((_data) { 292 return call(read.DATA_BLOCK, _archiveId).chain((_data) {
210 data = _data; 293 data = _data;
211 // TODO(nweiz): This async() call is only necessary because of issue 4222. 294 // TODO(nweiz): This async() call is only necessary because of issue 4222.
212 return async(); 295 return async();
213 }).chain((_) { 296 }).chain((_) {
214 if (_input.closed || _archiveId == null || data == null) { 297 if (_input.closed || _archiveId == null || data == null) {
215 return new Future.immediate(null); 298 return new Future.immediate(null);
216 } 299 }
217 _input.write(data); 300 _input.write(data);
218 return _consumeInput(); 301 return _consumeInput();
219 }); 302 });
220 } 303 }
221 } 304 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698