@@ -27,16 +27,38 @@ public final class files implements Module {
2727 @ Override
2828 public void init () {
2929 files = new HashMap <>();
30+ Variables .set ("FILES_COMPARATOR" , new FunctionValue (new filesComparatorFunction ()));
3031
3132 Functions .set ("fopen" , new fopen ());
32- Functions .set ("listFiles" , new listFiles ());
33+ Functions .set ("flush" , new flush ());
34+ Functions .set ("fclose" , new fclose ());
35+
36+ // Operations
3337 Functions .set ("delete" , new delete ());
38+ Functions .set ("listFiles" , new listFiles ());
39+ Functions .set ("mkdir" , new mkdir ());
40+ Functions .set ("mkdirs" , new mkdirs ());
3441 Functions .set ("rename" , new rename ());
35- Functions .set ("exists" , new exists ());
42+
43+ // Permissions and statuses
44+ Functions .set ("canExecute" , new canExecute ());
45+ Functions .set ("canRead" , new canRead ());
46+ Functions .set ("canWrite" , new canWrite ());
3647 Functions .set ("isDirectory" , new isDirectory ());
3748 Functions .set ("isFile" , new isFile ());
38- Functions .set ("mkdir" , new mkdir ());
49+ Functions .set ("isHidden" , new isHidden ());
50+ Functions .set ("setExecutable" , new setExecutable ());
51+ Functions .set ("setReadable" , new setReadable ());
52+ Functions .set ("setReadOnly" , new setReadOnly ());
53+ Functions .set ("setWritable" , new setWritable ());
54+
55+ Functions .set ("exists" , new exists ());
3956 Functions .set ("fileSize" , new fileSize ());
57+ Functions .set ("getParent" , new getParent ());
58+ Functions .set ("lastModified" , new lastModified ());
59+ Functions .set ("setLastModified" , new setLastModified ());
60+
61+ // IO
4062 Functions .set ("readBoolean" , new readBoolean ());
4163 Functions .set ("readByte" , new readByte ());
4264 Functions .set ("readBytes" , new readBytes ());
@@ -62,8 +84,27 @@ public void init() {
6284 Functions .set ("writeUTF" , new writeUTF ());
6385 Functions .set ("writeLine" , new writeLine ());
6486 Functions .set ("writeText" , new writeText ());
65- Functions .set ("flush" , new flush ());
66- Functions .set ("fclose" , new fclose ());
87+ }
88+
89+ private static class filesComparatorFunction implements Function {
90+
91+ @ Override
92+ public Value execute (Value ... args ) {
93+ Arguments .checkAtLeast (2 , args .length );
94+
95+ final int fd1 = args [0 ].asInt ();
96+ final int fd2 = args [1 ].asInt ();
97+ if (!files .containsKey (fd1 )) {
98+ return NumberValue .of (files .containsKey (fd2 ) ? 1 : 0 );
99+ }
100+ if (!files .containsKey (fd2 )) {
101+ return NumberValue .of (files .containsKey (fd1 ) ? -1 : 0 );
102+ }
103+
104+ final File file1 = files .get (fd1 ).file ;
105+ final File file2 = files .get (fd2 ).file ;
106+ return NumberValue .of (file1 .compareTo (file2 ));
107+ }
67108 }
68109
69110 private static class fopen implements Function {
@@ -129,6 +170,27 @@ protected Value execute(FileInfo fileInfo, Value[] args) throws IOException {
129170 return ArrayValue .of (fileInfo .file .list ());
130171 }
131172 }
173+
174+ private static class canExecute extends FileFunction {
175+ @ Override
176+ protected Value execute (FileInfo fileInfo , Value [] args ) throws IOException {
177+ return NumberValue .fromBoolean (fileInfo .file .canExecute ());
178+ }
179+ }
180+
181+ private static class canRead extends FileFunction {
182+ @ Override
183+ protected Value execute (FileInfo fileInfo , Value [] args ) throws IOException {
184+ return NumberValue .fromBoolean (fileInfo .file .canRead ());
185+ }
186+ }
187+
188+ private static class canWrite extends FileFunction {
189+ @ Override
190+ protected Value execute (FileInfo fileInfo , Value [] args ) throws IOException {
191+ return NumberValue .fromBoolean (fileInfo .file .canWrite ());
192+ }
193+ }
132194
133195 private static class delete extends FileFunction {
134196 @ Override
@@ -143,7 +205,7 @@ protected Value execute(FileInfo fileInfo, Value[] args) throws IOException {
143205 return NumberValue .fromBoolean (fileInfo .file .exists ());
144206 }
145207 }
146-
208+
147209 private static class isDirectory extends FileFunction {
148210 @ Override
149211 protected Value execute (FileInfo fileInfo , Value [] args ) throws IOException {
@@ -157,14 +219,28 @@ protected Value execute(FileInfo fileInfo, Value[] args) throws IOException {
157219 return NumberValue .fromBoolean (fileInfo .file .isFile ());
158220 }
159221 }
160-
222+
223+ private static class isHidden extends FileFunction {
224+ @ Override
225+ protected Value execute (FileInfo fileInfo , Value [] args ) throws IOException {
226+ return NumberValue .fromBoolean (fileInfo .file .isHidden ());
227+ }
228+ }
229+
161230 private static class mkdir extends FileFunction {
162231 @ Override
163232 protected Value execute (FileInfo fileInfo , Value [] args ) throws IOException {
164233 return NumberValue .fromBoolean (fileInfo .file .mkdir ());
165234 }
166235 }
167236
237+ private static class mkdirs extends FileFunction {
238+ @ Override
239+ protected Value execute (FileInfo fileInfo , Value [] args ) throws IOException {
240+ return NumberValue .fromBoolean (fileInfo .file .mkdirs ());
241+ }
242+ }
243+
168244 private static class rename extends FileFunction {
169245 @ Override
170246 protected Value execute (FileInfo fileInfo , Value [] args ) throws IOException {
@@ -179,6 +255,69 @@ protected Value execute(FileInfo fileInfo, Value[] args) throws IOException {
179255 return NumberValue .of (fileInfo .file .length ());
180256 }
181257 }
258+
259+ private static class getParent extends FileFunction {
260+ @ Override
261+ protected Value execute (FileInfo fileInfo , Value [] args ) throws IOException {
262+ final String parent = fileInfo .file .getParent ();
263+ return new StringValue (parent == null ? "" : parent );
264+ }
265+ }
266+
267+ private static class lastModified extends FileFunction {
268+ @ Override
269+ protected Value execute (FileInfo fileInfo , Value [] args ) throws IOException {
270+ return NumberValue .of (fileInfo .file .lastModified ());
271+ }
272+ }
273+
274+ private static class setLastModified extends FileFunction {
275+ @ Override
276+ protected Value execute (FileInfo fileInfo , Value [] args ) throws IOException {
277+ final long time ;
278+ if (args [1 ].type () == Types .NUMBER ) {
279+ time = ((NumberValue )args [1 ]).asLong ();
280+ } else {
281+ time = (long ) args [1 ].asNumber ();
282+ }
283+ fileInfo .file .setLastModified (time );
284+ return NumberValue .ONE ;
285+ }
286+ }
287+
288+ private static class setReadOnly extends FileFunction {
289+ @ Override
290+ protected Value execute (FileInfo fileInfo , Value [] args ) throws IOException {
291+ return NumberValue .fromBoolean (fileInfo .file .setReadOnly ());
292+ }
293+ }
294+
295+ private static class setExecutable extends FileFunction {
296+ @ Override
297+ protected Value execute (FileInfo fileInfo , Value [] args ) throws IOException {
298+ final boolean ownerOnly = (args .length >= 3 ) ? (args [2 ].asInt () != 0 ) : true ;
299+ return NumberValue .fromBoolean (
300+ fileInfo .file .setExecutable (args [1 ].asInt () != 0 , ownerOnly ));
301+ }
302+ }
303+
304+ private static class setReadable extends FileFunction {
305+ @ Override
306+ protected Value execute (FileInfo fileInfo , Value [] args ) throws IOException {
307+ final boolean ownerOnly = (args .length >= 3 ) ? (args [2 ].asInt () != 0 ) : true ;
308+ return NumberValue .fromBoolean (
309+ fileInfo .file .setReadable (args [1 ].asInt () != 0 , ownerOnly ));
310+ }
311+ }
312+
313+ private static class setWritable extends FileFunction {
314+ @ Override
315+ protected Value execute (FileInfo fileInfo , Value [] args ) throws IOException {
316+ final boolean ownerOnly = (args .length >= 3 ) ? (args [2 ].asInt () != 0 ) : true ;
317+ return NumberValue .fromBoolean (
318+ fileInfo .file .setWritable (args [1 ].asInt () != 0 , ownerOnly ));
319+ }
320+ }
182321
183322 private static class readBoolean extends FileFunction {
184323 @ Override
0 commit comments