1- const printTree = require ( "print-tree" ) ;
2-
31const path = require ( "./path.js" ) ;
42const { ENOENT , EEXIST , ENOTEMPTY } = require ( "./errors.js" ) ;
53
64const STAT = 0 ;
75
86module . exports = class CacheFS {
97 constructor ( ) {
8+ const root = this . _makeRoot ( ) ;
9+ this . _root = new Map ( [ [ "/" , root ] ] ) ;
10+ }
11+ _makeRoot ( ) {
1012 let root = new Map ( ) ;
1113 let stat = { mode : 0o777 , type : "dir" , size : 0 , mtimeMs : Date . now ( ) } ;
1214 root . set ( STAT , stat ) ;
13- this . _root = new Map ( [ [ "/" , root ] ] ) ;
15+ return root
1416 }
15- _print ( ) {
16- const root = [ ...this . _root . entries ( ) ] [ 0 ] ;
17- return printTree (
18- root ,
19- node => {
20- let stat = node [ 1 ] . get ( STAT ) ;
17+ print ( root ) {
18+ root = root || this . _root . get ( "/" )
19+ let str = "" ;
20+ const printTree = ( root , indent ) => {
21+ for ( let [ file , node ] of root ) {
22+ if ( file === 0 ) continue ;
23+ let stat = node . get ( STAT ) ;
2124 let mode = stat . mode . toString ( 8 ) ;
2225 if ( stat . type === "file" ) {
23- return `${ node [ 0 ] } [mode=${ mode } size=${ stat . size } mtime=${ stat . mtimeMs } ]` ;
26+ str += `\n${ "\t" . repeat ( indent ) } ${ file } \t${ mode } \t${ stat . size } \t${
27+ stat . mtimeMs
28+ } `;
2429 } else {
25- return `${ node [ 0 ] } [mode=${ mode } ]` ;
30+ str += `\n${ "\t" . repeat ( indent ) } ${ file } \t${ mode } ` ;
31+ printTree ( node , indent + 1 ) ;
2632 }
27- } ,
28- node => {
29- if ( node [ 1 ] === null ) {
30- // it's a file
31- return [ ] ;
32- } else {
33- // it's a dir
34- return [ ...node [ 1 ] . entries ( ) ] . filter ( ( [ key ] ) => typeof key === "string" ) ;
33+ }
34+ } ;
35+ printTree ( root , 0 ) ;
36+ return str . trimStart ( ) ;
37+ }
38+ parse ( print ) {
39+ function mk ( stat ) {
40+ if ( stat . length === 1 ) {
41+ let [ mode ] = stat
42+ mode = parseInt ( mode , 8 ) ;
43+ return new Map ( [
44+ [ STAT , { mode, type : "dir" , size : 0 , mtimeMs : Date . now ( ) } ]
45+ ] ) ;
46+ } else {
47+ let [ mode , size , mtimeMs ] = stat ;
48+ mode = parseInt ( mode , 8 ) ;
49+ size = parseInt ( size ) ;
50+ mtimeMs = parseInt ( mtimeMs ) ;
51+ return new Map ( [ [ STAT , { mode, type : "file" , size, mtimeMs } ] ] ) ;
52+ }
53+ }
54+
55+ let lines = print . trim ( ) . split ( "\n" ) ;
56+ let _root = this . _makeRoot ( ) ;
57+ let stack = [
58+ { indent : - 1 , node : _root } ,
59+ { indent : 0 , node : null }
60+ ] ;
61+ for ( let line of lines ) {
62+ // let [, prefix, filename, stat]
63+ let prefix = line . match ( / ^ \t * / ) [ 0 ] ;
64+ let indent = prefix . length ;
65+ line = line . slice ( indent ) ;
66+ let [ filename , ...stat ] = line . split ( "\t" ) ;
67+ let node = mk ( stat ) ;
68+ if ( indent <= stack [ stack . length - 1 ] . indent ) {
69+ while ( indent <= stack [ stack . length - 1 ] . indent ) {
70+ stack . pop ( ) ;
3571 }
3672 }
37- ) ;
73+ stack . push ( { indent, node } ) ;
74+ let cd = stack [ stack . length - 2 ] . node ;
75+ cd . set ( filename , node ) ;
76+ }
77+ return _root ;
3878 }
3979 _lookup ( filepath ) {
4080 let dir = this . _root ;
@@ -44,27 +84,6 @@ module.exports = class CacheFS {
4484 }
4585 return dir ;
4686 }
47- // _mkdirp(filepath) {
48- // let dir = this._root;
49- // let traversing = true;
50- // let tmp;
51- // for (let part of path.split(filepath)) {
52- // if (traversing) {
53- // tmp = dir.get(part);
54- // if (tmp) {
55- // dir = tmp;
56- // } else {
57- // traversing = false;
58- // }
59- // }
60- // if (!traversing) {
61- // tmp = new Map();
62- // dir.set(part, tmp);
63- // dir = tmp;
64- // }
65- // }
66- // return dir;
67- // }
6887 mkdir ( filepath , { mode } ) {
6988 if ( filepath === "/" ) throw new EEXIST ( ) ;
7089 let dir = this . _lookup ( path . dirname ( filepath ) ) ;
0 commit comments