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

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

Issue 12016011: Remove utils/archive. It is not used at this point. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years, 11 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
« no previous file with comments | « utils/archive/entry.c ('k') | utils/archive/entry_request.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(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 library entry;
6
7 import 'dart:io';
8 import 'archive.dart' as archive;
9 import 'entry_request.dart';
10 import 'read_request.dart' as read;
11 import 'utils.dart';
12
13 /**
14 * A single file in an archive.
15 *
16 * This is accessible via [ArchiveInputStream.onEntry].
17 */
18 class ArchiveEntry {
19 /**
20 * The various properties of this archive entry, as sent over from the C
21 * extension.
22 */
23 final List _properties;
24
25 /**
26 * The id of the archive to which this entry belongs. Used to read the entry
27 * data. This will be set to null once there's no longer data available to be
28 * read for this entry.
29 */
30 int _archiveId;
31
32 /**
33 * The input stream being used to read data from this entry. This is null
34 * until [openInputStream] is called.
35 */
36 InputStream _input;
37
38 // TODO(nweiz): Get rid of this once issue 4202 is fixed.
39 /**
40 * A future that only exists once [openInputStream] is called, and completes
41 * once the input stream is closed.
42 *
43 * For internal use only.
44 */
45 Future inputComplete;
46
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).then((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];
60
61 /** If this entry is a hardlink, this is the destination. Otherwise, null. */
62 String get hardlink => _properties[1];
63 set hardlink(String value) => _set(SET_HARDLINK, 1, value);
64
65 /** The path to this entry in the archive. */
66 String get pathname => _properties[2];
67 set pathname(String value) => _set(SET_PATHNAME, 2, value);
68
69 /** The path to this entry on disk, */
70 String get sourcepath => _properties[3];
71
72 /** If this entry is a symlink, this is the destination. Otherwise, null. */
73 String get symlink => _properties[4];
74 set symlink(String value) => _set(SET_SYMLINK, 4, value);
75
76 /** The group identifier for this entry. */
77 int get gid => _properties[5];
78 set gid(int value) => _set(SET_GID, 5, value);
79
80 /** The user identifier for this entry. */
81 int get uid => _properties[6];
82 set uid(int value) => _set(SET_UID, 6, value);
83
84 /** The permissions bitmask for this entry. */
85 int get perm_mask => _properties[7];
86 set perm_mask(int value) => _set(SET_PERM, 7, value);
87
88 /**
89 * The String representation of the permissions for this entry.
90 *
91 * Note that if you set [perm_mask], this value will not change.
92 */
93 String get strmode => _properties[8];
94
95 /** The name of the group this entry belongs to. */
96 String get gname => _properties[9];
97 set gname(String value) => _set(SET_GNAME, 9, value);
98
99 /** The name of the user this entry belongs to. */
100 String get uname => _properties[10];
101 set uname(String value) => _set(SET_UNAME, 10, value);
102
103 /**
104 * The file flag bits that should be set for this entry.
105 *
106 * Note that if you set [fflags_text], this value will not change, and vice
107 * versa.
108 */
109 int get fflags_set => _properties[11];
110 set fflags_set(int value) => _set(SET_FFLAGS_SET, 11, value);
111
112 /**
113 * The file flag bits that should be cleared for this entry.
114 *
115 * Note that if you set [fflags_text], this value will not change, and vice
116 * versa.
117 */
118 int get fflags_clear => _properties[12];
119 set fflags_clear(int value) => _set(SET_FFLAGS_CLEAR, 12, value);
120
121 /**
122 * The textual representation of the file flags for this entry.
123 *
124 * Note that if you set [fflags_set] or [fflags_clear], this value will not
125 * change, and vice versa.
126 */
127 String get fflags_text => _properties[13];
128
129 /** The filetype bitmask for this entry. */
130 int get filetype_mask => _properties[14];
131 set filetype_mask(int value) => _set(SET_FILETYPE, 14, value);
132
133 /** The filetype and permissions bitmask for this entry. */
134 int get mode_mask => _properties[15];
135 set mode_mask(int value) => _set(SET_MODE, 15, value);
136
137 /** The size of this entry in bytes, or null if it's unset. */
138 int get size => _properties[16];
139 set size(int value) => _set(SET_SIZE, 16, value);
140
141 /** The ID of the device containing this entry, or null if it's unset. */
142 int get dev => _properties[17];
143 set dev(int value) => _set(SET_DEV, 17, value);
144
145 /** The major number of the ID of the device containing this entry. */
146 int get devmajor => _properties[18];
147 set devmajor(int value) => _set(SET_DEVMAJOR, 18, value);
148
149 /** The minor number of the ID of the device containing this entry. */
150 int get devminor => _properties[19];
151 set devminor(int value) => _set(SET_DEVMINOR, 19, value);
152
153 /** The inode number of this entry, or null if it's unset. */
154 int get ino => _properties[20];
155 set ino(int value) => _set(SET_INO, 20, value);
156
157 /** The number of references to this entry. */
158 int get nlink => _properties[21];
159 set nlink(int value) => _set(SET_NLINK, 21, value);
160
161 /** The device ID of this entry. */
162 int get rdev => _properties[22];
163 set rdev(int value) => _set(SET_RDEV, 22, value);
164
165 /** The major number of the device ID of this entry. */
166 int get rdevmajor => _properties[23];
167 set rdevmajor(int value) => _set(SET_RDEVMAJOR, 23, value);
168
169 /** The minor number of the device ID of this entry. */
170 int get rdevminor => _properties[24];
171 set rdevminor(int value) => _set(SET_RDEVMINOR, 24, value);
172
173 /** The last time this entry was accessed, or null if it's unset. */
174 Date get atime => _fromMs(_properties[25]);
175 set atime(Date value) => _set(SET_ATIME, 25, _toMs(value));
176
177 /** The time this entry was created, or null if it's unset. */
178 Date get birthtime => _fromMs(_properties[26]);
179 set birthtime(Date value) => _set(SET_BIRTHTIME, 26, _toMs(value));
180
181 /**
182 * The last time an inode property of this entry was changed, or null if it's
183 * unset.
184 */
185 Date get ctime => _fromMs(_properties[27]);
186 set ctime(Date value) => _set(SET_CTIME, 27, _toMs(value));
187
188 /** The last time this entry was modified, or null if it's unset. */
189 Date get mtime => _fromMs(_properties[28]);
190 set mtime(Date value) => _set(SET_MTIME, 28, _toMs(value));
191
192 /** Whether [openInputStream] has been called. */
193 bool get isInputOpen => _input != null;
194
195 /** Create a deep copy of this [ArchiveEntry]. */
196 Future<ArchiveEntry> clone() {
197 return call(CLONE, _id).
198 transform((array) => new archive.ArchiveEntry.internal(array, null));
199 }
200
201 /**
202 * Consumes the entire contents of this entry at once and returns it wrapped
203 * in a [CompleteArchiveEntry]. All metadata fields in the returned entry are
204 * copies of the fields in this entry.
205 *
206 * This may not be called if [openInputStream] is called, and vice versa.
207 */
208 Future<CompleteArchiveEntry> readAll() {
209 var stream = openInputStream();
210 var buffer = <int>[];
211 var completer = new Completer<List<int>>();
212
213 stream.onData = () => buffer.addAll(stream.read());
214 stream.onError = completer.completeError;
215 stream.onClosed = () => completer.complete(buffer);
216
217 return Future.wait([call(CLONE, _id), completer.future])
218 .then((list) => new CompleteArchiveEntry._(list[0], list[1]));
219 }
220
221 /**
222 * Set a property value with index [value] on the local representation of the
223 * archive entry and on the native representation.
224 */
225 void _set(int requestType, int index, value) {
226 _properties[index] = value;
227 // Since the native code processes messages in order, the SET_* messages
228 // will be received and processed before any further messages.
229 call(requestType, _id, [value]).then((_) {});
230 }
231
232 /**
233 * Converts [ms], the (possibly null) number of milliseconds since the epoch
234 * into a Date object (which may also be null).
235 */
236 Date _fromMs(int ms) {
237 if (ms == null) return null;
238 return new Date.fromMillisecondsSinceEpoch(ms);
239 }
240
241 /**
242 * Converts [date], which may be null, into the number of milliseconds since
243 * the epoch (which may also be null).
244 */
245 int _toMs(Date date) {
246 if (date == null) return null;
247 return date.millisecondsSinceEpoch;
248 }
249
250 /**
251 * Creates a new input stream for reading the contents of this entry.
252 *
253 * The contents of an entry must be consumed before the next entry is read
254 * from the parent [ArchiveInputStream]. This means that [openInputStream]
255 * must be called from the [ArchiveInputStream.onEntry] callback, or before
256 * the future returned by that callback completes. Once the next entry has
257 * been read, calling [openInputStream] will throw an [ArchiveException].
258 *
259 * Only one input stream may be opened per entry.
260 */
261 InputStream openInputStream() {
262 if (_archiveId == null) {
263 throw new UnsupportedError("Cannot open input stream for "
264 "archive entry $pathname.");
265 } else if (_input != null) {
266 throw new UnsupportedError("An input stream has already been"
267 "opened for archive entry $pathname.");
268 }
269
270 var inputCompleter = new Completer();
271 inputComplete = inputCompleter.future;
272
273 _input = new ListInputStream();
274 // TODO(nweiz): Report errors once issue 3657 is fixed
275 var future = _consumeInput().then((_) {
276 if (!_input.closed) _input.markEndOfStream();
277 // Asynchronously complete to give the InputStream callbacks a chance to
278 // fire.
279 return async();
280 }).then((_) => inputCompleter.complete(null));
281
282 future.handleException((e) {
283 print(e);
284 print(future.stackTrace);
285 });
286 return _input;
287 }
288
289 /**
290 * Close this entry so that its input stream no longer produces data.
291 *
292 * In addition to closing the associated input stream, this will prevent new
293 * input streams from being opened.
294 */
295 void close() {
296 _archiveId = null;
297 if (_input != null) _input.close();
298 }
299
300 /**
301 * Read all data from the archive and write it to [_input]. Returns a future
302 * that completes once this is done.
303 *
304 * This assumes that both [_input] and [_archiveId] are non-null and that
305 * [_input] is open, although if that changes before this completes it will
306 * handle it gracefully.
307 */
308 Future _consumeInput() {
309 var data;
310 return call(read.DATA_BLOCK, _archiveId).then((_data) {
311 data = _data;
312 // TODO(nweiz): This async() call is only necessary because of issue 4222.
313 return async();
314 }).then((_) {
315 if (_input.closed || _archiveId == null || data == null) {
316 return new Future.immediate(null);
317 }
318 _input.write(data);
319 return _consumeInput();
320 });
321 }
322 }
323
324 /**
325 * An [ArchiveEntry] that contains the complete decompressed contents of the
326 * file.
327 */
328 class CompleteArchiveEntry extends ArchiveEntry {
329 /** The contents of the entry as bytes. */
330 final List<int> contentBytes;
331
332 /** The contents of the entry as a string. */
333 String get contents => new String.fromCharCodes(contentBytes);
334
335 CompleteArchiveEntry._(List properties, this.contentBytes)
336 : super.internal(properties, null);
337 }
OLDNEW
« no previous file with comments | « utils/archive/entry.c ('k') | utils/archive/entry_request.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698