root/trunk/minid/iolib.d

Revision 440, 10.9 kB (checked in by JarrettBillingsley, 1 week ago)

Closes #51, at least I feel like it does.

Line 
1 /******************************************************************************
2 License:
3 Copyright (c) 2008 Jarrett Billingsley
4
5 This software is provided 'as-is', without any express or implied warranty.
6 In no event will the authors be held liable for any damages arising from the
7 use of this software.
8
9 Permission is granted to anyone to use this software for any purpose,
10 including commercial applications, and to alter it and redistribute it freely,
11 subject to the following restrictions:
12
13     1. The origin of this software must not be misrepresented; you must not
14     claim that you wrote the original software. If you use this software in a
15     product, an acknowledgment in the product documentation would be
16     appreciated but is not required.
17
18     2. Altered source versions must be plainly marked as such, and must not
19     be misrepresented as being the original software.
20
21     3. This notice may not be removed or altered from any source distribution.
22 ******************************************************************************/
23
24 module minid.iolib;
25
26 import Path = tango.io.Path;
27 import tango.io.device.FileConduit;
28 import tango.io.File;
29 import tango.io.FileSystem;
30 import tango.io.UnicodeFile;
31 import tango.util.PathUtil;
32
33 import minid.ex;
34 import minid.interpreter;
35 import minid.streamlib;
36 import minid.types;
37
38 struct IOLib
39 {
40 static:
41     private const FileConduit.Style DefaultFileStyle;
42
43     static this()
44     {
45         DefaultFileStyle = FileConduit.Style
46         (
47             FileConduit.Access.Read,
48             FileConduit.ReadExisting.open,
49             FileConduit.Share.ReadWrite,
50             FileConduit.ReadExisting.cache
51         );
52     }
53
54     enum FileMode : mdint
55     {
56         In = 1,
57         Out = 2,
58         New = 4,
59         Append = 8,
60         OutNew = Out | New
61     }
62
63     public void init(MDThread* t)
64     {
65         pushGlobal(t, "modules");
66         field(t, -1, "customLoaders");
67
68         newFunction(t, function uword(MDThread* t, uword numParams)
69         {
70             importModule(t, "stream");
71             pop(t);
72            
73             lookup(t, "stream.stdin");
74             newGlobal(t, "stdin");
75
76             lookup(t, "stream.stdout");
77             newGlobal(t, "stdout");
78
79             lookup(t, "stream.stderr");
80             newGlobal(t, "stderr");
81
82             newTable(t, 5);
83                 pushInt(t, FileMode.In);     fielda(t, -2, "In");
84                 pushInt(t, FileMode.Out);    fielda(t, -2, "Out");
85                 pushInt(t, FileMode.New);    fielda(t, -2, "New");
86                 pushInt(t, FileMode.Append); fielda(t, -2, "Append");
87                 pushInt(t, FileMode.OutNew); fielda(t, -2, "OutNew");
88             newGlobal(t, "FileMode");
89
90             newFunction(t, &File, "File");                 newGlobal(t, "File");
91             newFunction(t, &rename, "rename");             newGlobal(t, "rename");
92             newFunction(t, &remove, "remove");             newGlobal(t, "remove");
93             newFunction(t, &copy, "copy");                 newGlobal(t, "copy");
94             newFunction(t, &size, "size");                 newGlobal(t, "size");
95             newFunction(t, &exists, "exists");             newGlobal(t, "exists");
96             newFunction(t, &isFile, "isFile");             newGlobal(t, "isFile");
97             newFunction(t, &isDir, "isDir");               newGlobal(t, "isDir");
98             newFunction(t, &isReadOnly, "isReadOnly");     newGlobal(t, "isReadOnly");
99             newFunction(t, &currentDir, "currentDir");     newGlobal(t, "currentDir");
100             newFunction(t, &parentDir, "parentDir");       newGlobal(t, "parentDir");
101             newFunction(t, &changeDir, "changeDir");       newGlobal(t, "changeDir");
102             newFunction(t, &makeDir, "makeDir");           newGlobal(t, "makeDir");
103             newFunction(t, &makeDirChain, "makeDirChain"); newGlobal(t, "makeDirChain");
104             newFunction(t, &removeDir, "removeDir");       newGlobal(t, "removeDir");
105             newFunction(t, &listFiles, "listFiles");       newGlobal(t, "listFiles");
106             newFunction(t, &listDirs, "listDirs");         newGlobal(t, "listDirs");
107             newFunction(t, &readFile, "readFile");         newGlobal(t, "readFile");
108             newFunction(t, &writeFile, "writeFile");       newGlobal(t, "writeFile");
109             newFunction(t, &join, "join");                 newGlobal(t, "join");
110             newFunction(t, &dirName, "dirName");           newGlobal(t, "dirName");
111             newFunction(t, &name, "name");                 newGlobal(t, "name");
112             newFunction(t, &extension, "extension");       newGlobal(t, "extension");
113
114                 newFunction(t, &linesIterator, "linesIterator");
115             newFunction(t, &lines, "lines", 1);        newGlobal(t, "lines");
116
117             return 0;
118         }, "io");
119
120         fielda(t, -2, "io");
121         importModule(t, "io");
122         pop(t, 3);
123     }
124
125     uword rename(MDThread* t, uword numParams)
126     {
127         safeCode(t, Path.rename(checkStringParam(t, 1), checkStringParam(t, 2)));
128         return 0;
129     }
130
131     uword remove(MDThread* t, uword numParams)
132     {
133         safeCode(t, Path.remove(checkStringParam(t, 1)));
134         return 0;
135     }
136
137     uword copy(MDThread* t, uword numParams)
138     {
139         safeCode(t, Path.copy(checkStringParam(t, 1), checkStringParam(t, 1)));
140         return 0;
141     }
142
143     uword size(MDThread* t, uword numParams)
144     {
145         pushInt(t, cast(mdint)safeCode(t, Path.fileSize(checkStringParam(t, 1))));
146         return 1;
147     }
148
149     uword exists(MDThread* t, uword numParams)
150     {
151         pushBool(t, Path.exists(checkStringParam(t, 1)));
152         return 1;
153     }
154
155     uword isFile(MDThread* t, uword numParams)
156     {
157         pushBool(t, safeCode(t, !Path.isFolder(checkStringParam(t, 1))));
158         return 1;
159     }
160
161     uword isDir(MDThread* t, uword numParams)
162     {
163         pushBool(t, safeCode(t, Path.isFolder(checkStringParam(t, 1))));
164         return 1;
165     }
166    
167     uword isReadOnly(MDThread* t, uword numParams)
168     {
169         pushBool(t, safeCode(t, !Path.isWritable(checkStringParam(t, 1))));
170         return 1;
171     }
172
173     uword currentDir(MDThread* t, uword numParams)
174     {
175         pushString(t, safeCode(t, FileSystem.getDirectory()));
176         return 1;
177     }
178    
179     uword parentDir(MDThread* t, uword numParams)
180     {
181         auto p = optStringParam(t, 1, ".");
182        
183         if(p == ".")
184             p = FileSystem.getDirectory();
185
186         auto pp = safeCode(t, Path.parse(p));
187
188         if(pp.isAbsolute)
189             pushString(t, safeCode(t, Path.pop(p)));
190         else
191             pushString(t, safeCode(t, Path.join(FileSystem.getDirectory(), p)));
192
193         return 1;
194     }
195
196     uword changeDir(MDThread* t, uword numParams)
197     {
198         safeCode(t, FileSystem.setDirectory(checkStringParam(t, 1)));
199         return 0;
200     }
201
202     uword makeDir(MDThread* t, uword numParams)
203     {
204         auto p = Path.parse(checkStringParam(t, 1));
205
206         if(!p.isAbsolute())
207             safeCode(t, Path.createFolder(Path.join(FileSystem.getDirectory(), p.toString())));
208         else
209             safeCode(t, Path.createFolder(p.toString()));
210
211         return 0;
212     }
213
214     uword makeDirChain(MDThread* t, uword numParams)
215     {
216         auto p = Path.parse(checkStringParam(t, 1));
217        
218         if(!p.isAbsolute())
219             safeCode(t, Path.createPath(Path.join(FileSystem.getDirectory(), p.toString())));
220         else
221             safeCode(t, Path.createPath(p.toString()));
222
223         return 0;
224     }
225
226     uword removeDir(MDThread* t, uword numParams)
227     {
228         safeCode(t, Path.remove(checkStringParam(t, 1)));
229         return 0;
230     }
231    
232     uword listImpl(MDThread* t, uword numParams, bool isFolder)
233     {
234         auto fp = optStringParam(t, 1, ".");
235        
236         if(fp == ".")
237             fp = FileSystem.getDirectory();
238
239         auto listing = newArray(t, 0);
240
241         if(numParams >= 2)
242         {
243             auto filter = checkStringParam(t, 2);
244
245             safeCode(t,
246             {
247                 foreach(ref info; Path.children(fp))
248                 {
249                     if(info.folder is isFolder)
250                     {
251                         pushString(t, info.path);
252                         pushString(t, info.name);
253                         cat(t, 2);
254                         auto fullName = getString(t, -1);
255    
256                         if(patternMatch(fullName, filter))
257                             cateq(t, listing, 1);
258                         else
259                             pop(t);
260                     }
261                 }
262             }());
263         }
264         else
265         {
266             safeCode(t,
267             {
268                 foreach(ref info; Path.children(fp))
269                 {
270                     if(info.folder is isFolder)
271                     {
272                         pushString(t, info.path);
273                         pushString(t, info.name);
274                         cat(t, 2);
275                         cateq(t, listing, 1);
276                     }
277                 }
278             }());
279         }
280
281         return 1;
282     }
283
284     uword listFiles(MDThread* t, uword numParams)
285     {
286         return listImpl(t, numParams, false);
287     }
288
289     uword listDirs(MDThread* t, uword numParams)
290     {
291         return listImpl(t, numParams, true);
292     }
293
294     uword readFile(MDThread* t, uword numParams)
295     {
296         auto name = checkStringParam(t, 1);
297         auto shouldConvert = optBoolParam(t, 2, false);
298
299         if(shouldConvert)
300         {
301             safeCode(t,
302             {
303                 scope file = new .File(name);
304                 auto data = cast(ubyte[])file.read();
305
306                 scope(exit)
307                     delete data;
308
309                 foreach(ref c; data)
310                     if(c > 0x7f)
311                         c = '?';
312
313                 pushString(t, cast(char[])data);
314             }());
315         }
316         else
317         {
318             safeCode(t,
319             {
320                 scope file = new UnicodeFile!(char)(name, Encoding.Unknown);
321                 pushString(t, file.read());
322             }());
323         }
324
325         return 1;
326     }
327
328     uword writeFile(MDThread* t, uword numParams)
329     {
330         auto name = checkStringParam(t, 1);
331         auto data = checkStringParam(t, 2);
332
333         safeCode(t,
334         {
335             scope file = new UnicodeFile!(char)(name, Encoding.UTF_8N);
336             file.write(data);
337         }());
338
339         return 0;
340     }
341    
342     uword linesIterator(MDThread* t, uword numParams)
343     {
344         getExtraVal(t, 0, StreamObj.Fields.input);
345         auto lines = (cast(InputStreamObj.Members*)getExtraBytes(t, -1).ptr).lines;
346
347         auto index = checkIntParam(t, 1) + 1;
348         auto line = safeCode(t, lines.next());
349
350         if(line.ptr is null)
351         {
352             dup(t, 0);
353             pushNull(t);
354             methodCall(t, -2, "close", 0);
355             return 0;
356         }
357
358         pushInt(t, index);
359         pushString(t, line);
360         return 2;
361     }
362
363     uword lines(MDThread* t, uword numParams)
364     {
365         auto name = checkStringParam(t, 1);
366        
367         pushGlobal(t, "File");
368         pushNull(t);
369         pushString(t, name);
370         rawCall(t, -3, 1);
371
372         pushInt(t, 0);
373         getUpval(t, 0);
374        
375         return 3;
376     }
377
378     uword File(MDThread* t, uword numParams)
379     {
380         FileConduit.Style parseFileMode(mdint mode)
381         {
382             auto s = DefaultFileStyle;
383
384             s.access = FileConduit.Access.Read;
385
386             if(mode & FileMode.Out)
387                 s.access |= FileConduit.Access.Write;
388
389             s.open = cast(FileConduit.Open)0;
390
391             if(mode & FileMode.New)
392                 s.open |= FileConduit.Open.Create;
393             else
394             {
395                 if(mode & FileMode.Append)
396                     s.open |= FileConduit.Open.Append;
397
398                 s.open |= FileConduit.Open.Exists;
399             }
400
401             return s;
402         }
403
404         safeCode(t,
405         {
406             auto name = checkStringParam(t, 1);
407
408             auto f = numParams == 1
409                 ? new FileConduit(name, DefaultFileStyle)
410                 : new FileConduit(name, parseFileMode(checkIntParam(t, 2)));
411                
412             lookup(t, "stream.Stream");
413             pushNull(t);
414             pushNativeObj(t, f);
415             rawCall(t, -3, 1);
416         }());
417
418         return 1;
419     }
420    
421     uword join(MDThread* t, uword numParams)
422     {
423         checkAnyParam(t, 1);
424        
425         char[][] tmp;
426        
427         scope(exit)
428             delete tmp;
429
430         for(uword i = 1; i <= numParams; i++)
431             tmp ~= checkStringParam(t, i);
432
433         pushString(t, safeCode(t, Path.join(tmp)));
434         return 1;
435     }
436    
437     uword dirName(MDThread* t, uword numParams)
438     {
439         pushString(t, safeCode(t, Path.parse(checkStringParam(t, 1))).path);
440         return 1;
441     }
442
443     uword name(MDThread* t, uword numParams)
444     {
445         pushString(t, safeCode(t, Path.parse(checkStringParam(t, 1))).name);
446         return 1;
447     }
448
449     uword extension(MDThread* t, uword numParams)
450     {
451         pushString(t, safeCode(t, Path.parse(checkStringParam(t, 1))).ext);
452         return 1;
453     }
454 }
Note: See TracBrowser for help on using the browser.