1 /*******************************************************************************
2 
3         Copyright:
4             Copyright (c) 2007 Tango contributors.
5             Some parts copyright (c) 2009-2016 dunnhumby Germany GmbH.
6             All rights reserved.
7 
8         License:
9             Tango Dual License: 3-Clause BSD License / Academic Free License v3.0.
10             See LICENSE_TANGO.txt for details.
11 
12         Version: Jul 2007: Initial version
13 
14         Authors: Lars Ivar, Kris Bell
15 
16 *******************************************************************************/
17 
18 module ocean.io.vfs.model.Vfs;
19 
20 import ocean.meta.types.Qualifiers;
21 
22 import ocean.time.Time : Time;
23 
24 import ocean.io.model.IConduit;
25 
26 import ocean.io.model.IFile : FileInfo;
27 
28 /*******************************************************************************
29 
30         alias FileInfo for filtering.
31 
32 *******************************************************************************/
33 
34 alias FileInfo VfsFilterInfo;
35 alias VfsFilterInfo* VfsInfo;
36 
37 // return false to exclude something
38 alias bool delegate(VfsInfo) VfsFilter;
39 
40 
41 /*******************************************************************************
42 
43 *******************************************************************************/
44 
45 struct VfsStats
46 {
47         ulong bytes;   /// Byte count of files.
48         uint  files;   /// Number of files.
49         uint  folders; /// Number of folders.
50 }
51 
52 /*******************************************************************************
53 
54 ******************************************************************************/
55 
56 interface VfsHost : VfsFolder
57 {
58         /**********************************************************************
59 
60                 Add a child folder. The child cannot 'overlap' with others
61                 in the tree of the same type. Circular references across a
62                 tree of virtual folders are detected and trapped.
63 
64                 The second argument represents an optional name that the
65                 mount should be known as, instead of the name exposed by
66                 the provided folder (it is not an alias.)
67 
68         **********************************************************************/
69 
70         VfsHost mount (VfsFolder folder, istring name=null);
71 
72         /***********************************************************************
73 
74                 Add a set of child folders. The children cannot 'overlap'
75                 with others in the tree of the same type. Circular references
76                 are detected and trapped.
77 
78         ***********************************************************************/
79 
80         VfsHost mount (VfsFolders group);
81 
82         /**********************************************************************
83 
84                 Unhook a child folder.
85 
86         **********************************************************************/
87 
88         VfsHost dismount (VfsFolder folder);
89 
90         /**********************************************************************
91 
92                 Add a symbolic link to another file. These are referenced
93                 by file() alone, and do not show up in tree traversals.
94 
95         **********************************************************************/
96 
97         VfsHost map (VfsFile target, istring name);
98 
99         /***********************************************************************
100 
101                 Add a symbolic link to another folder. These are referenced
102                 by folder() alone, and do not show up in tree traversals.
103 
104         ***********************************************************************/
105 
106         VfsHost map (VfsFolderEntry target, istring name);
107 }
108 
109 
110 /*******************************************************************************
111 
112         Supports a model a bit like CSS selectors, where a selection
113         of operands is made before applying some operation. For example:
114         ---
115         // count of files in this folder
116         auto count = folder.self.files;
117 
118         // accumulated file byte-count
119         auto bytes = folder.self.bytes;
120 
121         // a group of one folder (itself)
122         auto folders = folder.self;
123         ---
124 
125         The same approach is used to select the subtree descending from
126         a folder:
127         ---
128         // count of files in this tree
129         auto count = folder.tree.files;
130 
131         // accumulated file byte-count
132         auto bytes = folder.tree.bytes;
133 
134         // the group of child folders
135         auto folders = folder.tree;
136         ---
137 
138         Filtering can be applied to the tree resulting in a sub-group.
139         Group operations remain applicable. Note that various wildcard
140         characters may be used in the filtering:
141         ---
142         // select a subset of the resultant tree
143         auto folders = folder.tree.subset("install");
144 
145         // get total file bytes for a tree subset, using wildcards
146         auto bytes = folder.tree.subset("foo*").bytes;
147         ---
148 
149         Files are selected from a set of folders in a similar manner:
150         ---
151         // files called "readme.txt" in this folder
152         auto count = folder.self.catalog("readme.txt").files;
153 
154         // files called "read*.*" in this tree
155         auto count = folder.tree.catalog("read*.*").files;
156 
157         // all txt files belonging to folders starting with "ins"
158         auto count = folder.tree.subset("ins*").catalog("*.txt").files;
159 
160         // custom-filtered files within a subtree
161         auto count = folder.tree.catalog(&filter).files;
162         ---
163 
164         Sets of folders and files support iteration via foreach:
165         ---
166         foreach (folder; root.tree)
167                  Stdout.formatln ("folder name:{}", folder.name);
168 
169         foreach (folder; root.tree.subset("ins*"))
170                  Stdout.formatln ("folder name:{}", folder.name);
171 
172         foreach (file; root.tree.catalog("*.d"))
173                  Stdout.formatln ("file name:{}", file.name);
174         ---
175 
176         Creating and opening a sub-folder is supported in a similar
177         manner, where the single instance is 'selected' before the
178         operation is applied. Open differs from create in that the
179         folder must exist for the former:
180         ---
181         root.folder("myNewFolder").create;
182 
183         root.folder("myExistingFolder").open;
184         ---
185 
186         File manipulation is handled in much the same way:
187         ---
188         root.file("myNewFile").create;
189 
190         auto source = root.file("myExistingFile");
191         root.file("myCopiedFile").copy(source);
192         ---
193 
194         The principal benefits of these approaches are twofold: 1. it
195         turns out to be notably more efficient in terms of traversal, and
196         2. there's no casting required, since there is a clean separation
197         between files and folders.
198 
199         See VfsFile for more information on file handling.
200 
201 *******************************************************************************/
202 
203 interface VfsFolder
204 {
205         /***********************************************************************
206 
207                 Return a short name.
208 
209         ***********************************************************************/
210 
211         istring name ();
212 
213         /***********************************************************************
214 
215                 Return a long name.
216 
217         ***********************************************************************/
218 
219         istring toString ();
220 
221         /***********************************************************************
222 
223                 Return a contained file representation.
224 
225         ***********************************************************************/
226 
227         VfsFile file (istring path);
228 
229         /***********************************************************************
230 
231                 Return a contained folder representation.
232 
233         ***********************************************************************/
234 
235         VfsFolderEntry folder (istring path);
236 
237         /***********************************************************************
238 
239                 Returns a folder set containing only this one. Statistics
240                 are inclusive of entries within this folder only.
241 
242         ***********************************************************************/
243 
244         VfsFolders self ();
245 
246         /***********************************************************************
247 
248                 Returns a subtree of folders. Statistics are inclusive of
249                 files within this folder and all others within the tree.
250 
251         ***********************************************************************/
252 
253         VfsFolders tree ();
254 
255         /***********************************************************************
256 
257                 Iterate over the set of immediate child folders. This is
258                 useful for reflecting the hierarchy.
259 
260         ***********************************************************************/
261 
262         int opApply (scope int delegate(ref VfsFolder) dg);
263 
264         /***********************************************************************
265 
266                 Clear all content from this folder and subordinates.
267 
268         ***********************************************************************/
269 
270         VfsFolder clear ();
271 
272         /***********************************************************************
273 
274                 Is folder writable?
275 
276         ***********************************************************************/
277 
278         bool writable ();
279 
280         /***********************************************************************
281 
282                 Close and/or synchronize changes made to this folder. Each
283                 driver should take advantage of this as appropriate, perhaps
284                 combining multiple files together, or possibly copying to a
285                 remote location.
286 
287         ***********************************************************************/
288 
289         VfsFolder close (bool commit = true);
290 
291         /***********************************************************************
292 
293                 A folder is being added or removed from the hierarchy. Use
294                 this to test for validity (or whatever) and throw exceptions
295                 as necessary.
296 
297         ***********************************************************************/
298 
299         void verify (VfsFolder folder, bool mounting);
300 
301         //VfsFolder copy(VfsFolder from, istring to);
302         //VfsFolder move(Entry from, VfsFolder toFolder, istring toName);
303         //istring absolutePath(istring path);
304 }
305 
306 
307 /*******************************************************************************
308 
309         Operations upon a set of folders.
310 
311 *******************************************************************************/
312 
313 interface VfsFolders
314 {
315         /***********************************************************************
316 
317                 Iterate over the set of contained VfsFolder instances.
318 
319         ***********************************************************************/
320 
321         int opApply (scope int delegate(ref VfsFolder) dg);
322 
323         /***********************************************************************
324 
325                 Return the number of files.
326 
327         ***********************************************************************/
328 
329         uint files ();
330 
331         /***********************************************************************
332 
333                 Return the number of folders.
334 
335         ***********************************************************************/
336 
337         uint folders ();
338 
339         /***********************************************************************
340 
341                 Return the total number of entries (files + folders.)
342 
343         ***********************************************************************/
344 
345         uint entries ();
346 
347         /***********************************************************************
348 
349                 Return the total size of contained files.
350 
351         ***********************************************************************/
352 
353         ulong bytes ();
354 
355         /***********************************************************************
356 
357                 Return a subset of folders matching the given pattern.
358 
359         ***********************************************************************/
360 
361         VfsFolders subset (istring pattern);
362 
363        /***********************************************************************
364 
365                 Return a set of files matching the given pattern.
366 
367         ***********************************************************************/
368 
369         VfsFiles catalog (istring pattern);
370 
371         /***********************************************************************
372 
373                 Return a set of files matching the given filter.
374 
375         ***********************************************************************/
376 
377         VfsFiles catalog (scope VfsFilter filter = null);
378 }
379 
380 
381 /*******************************************************************************
382 
383         Operations upon a set of files.
384 
385 *******************************************************************************/
386 
387 interface VfsFiles
388 {
389         /***********************************************************************
390 
391                 Iterate over the set of contained VfsFile instances.
392 
393         ***********************************************************************/
394 
395         int opApply (scope int delegate(ref VfsFile) dg);
396 
397         /***********************************************************************
398 
399                 Return the total number of entries.
400 
401         ***********************************************************************/
402 
403         uint files ();
404 
405         /***********************************************************************
406 
407                 Return the total size of all files.
408 
409         ***********************************************************************/
410 
411         ulong bytes ();
412 }
413 
414 
415 /*******************************************************************************
416 
417         A specific file representation.
418 
419 *******************************************************************************/
420 
421 interface VfsFile
422 {
423         /***********************************************************************
424 
425                 Return a short name.
426 
427         ***********************************************************************/
428 
429         istring name ();
430 
431         /***********************************************************************
432 
433                 Return a long name.
434 
435         ***********************************************************************/
436 
437         istring toString ();
438 
439         /***********************************************************************
440 
441                 Does this file exist?
442 
443         ***********************************************************************/
444 
445         bool exists ();
446 
447         /***********************************************************************
448 
449                 Return the file size.
450 
451         ***********************************************************************/
452 
453         ulong size ();
454 
455         /***********************************************************************
456 
457                 Create and copy the given source.
458 
459         ***********************************************************************/
460 
461         VfsFile copy (VfsFile source);
462 
463         /***********************************************************************
464 
465                 Create and copy the given source, and remove the source.
466 
467         ***********************************************************************/
468 
469         VfsFile move (VfsFile source);
470 
471         /***********************************************************************
472 
473                 Create a new file instance.
474 
475         ***********************************************************************/
476 
477         VfsFile create ();
478 
479         /***********************************************************************
480 
481                 Create a new file instance and populate with stream.
482 
483         ***********************************************************************/
484 
485         VfsFile create (InputStream stream);
486 
487         /***********************************************************************
488 
489                 Remove this file.
490 
491         ***********************************************************************/
492 
493         VfsFile remove ();
494 
495         /***********************************************************************
496 
497                 Return the input stream. Don't forget to close it.
498 
499         ***********************************************************************/
500 
501         InputStream input ();
502 
503         /***********************************************************************
504 
505                 Return the output stream. Don't forget to close it.
506 
507         ***********************************************************************/
508 
509         OutputStream output ();
510 
511         /***********************************************************************
512 
513                 Duplicate this entry.
514 
515         ***********************************************************************/
516 
517         VfsFile dup ();
518 
519         /***********************************************************************
520 
521                 The modified time of the folder.
522 
523         ***********************************************************************/
524 
525         Time modified ();
526 }
527 
528 
529 /*******************************************************************************
530 
531         Handler for folder operations. Needs some work ...
532 
533 *******************************************************************************/
534 
535 interface VfsFolderEntry
536 {
537         /***********************************************************************
538 
539                 Open a folder.
540 
541         ***********************************************************************/
542 
543         VfsFolder open ();
544 
545         /***********************************************************************
546 
547                 Create a new folder.
548 
549         ***********************************************************************/
550 
551         VfsFolder create ();
552 
553         /***********************************************************************
554 
555                 Test to see if a folder exists.
556 
557         ***********************************************************************/
558 
559         bool exists ();
560 }
561 
562 
563 /*******************************************************************************
564 
565     Would be used for things like zip files, where the
566     implementation mantains the contents in memory or on disk, and where
567     the actual zip file isn't/shouldn't be written until one is finished
568     filling it up (for zip due to inefficient file format).
569 
570 *******************************************************************************/
571 
572 interface VfsSync
573 {
574         /***********************************************************************
575 
576         ***********************************************************************/
577 
578         VfsFolder sync ();
579 }
580