ecere/gui/drivers/X11: (#850,#700,#795) Improved X11/Unity fixes
[sdk] / extras / FileSystemIterator.ec
1 #ifdef BUILDING_ECERE_COM
2 namespace sys;
3 import "Array"
4 #else
5 #ifdef ECERE_STATIC
6 public import static "ecere"
7 #else
8 public import "ecere"
9 #endif
10 #endif
11
12 public class NormalFileSystemIterator : FileSystemIterator
13 {
14 public:
15    Array<StackFrame> stack { };
16
17    char * extensions;
18    property char * extensions { set { delete extensions; if(value) extensions = CopyString(value); } }
19
20    ~NormalFileSystemIterator()
21    {
22       delete extensions;
23    }
24
25    void Iterate(char * startPath)
26    {
27       StackFrame frame;
28
29       if(OnInit(startPath))
30       {
31          frame = stack.firstIterator.data;
32       }
33       else
34       {
35          frame = StackFrame { };
36          stack.Add(frame);
37          frame.path = CopyString(startPath);
38          frame.listing = FileListing { startPath, extensions = extensions };  // there should be a sorted = true/false 
39       }
40
41       if(iterateStartPath)
42       {
43          FileAttribs attribs = FileExists(startPath);
44          // || attribs.isCDROM || attribs.isRemote || attribs.isRemovable || attribs.isServer || attribs.isShare || attribs.isSystem || attribs.isTemporary
45          if(attribs.isDrive)
46             OnVolume(startPath);
47          else if(attribs.isDirectory)
48             OnFolder(startPath);
49          else if(attribs.isFile)
50             OnFile(startPath);
51       }
52
53       while(stack.count)
54       {
55          if(frame.listing.Find())
56          {
57             char * name = frame.listing.name;
58             bool isDirectory = frame.listing.stats.attribs.isDirectory;
59             bool peek = frame.listing.stats.attribs.isDirectory && OnFolder(frame.listing.path);
60             if(!frame.listing.stats.attribs.isDirectory)
61             {
62                char * path = frame.listing.path;
63                OnFile(frame.listing.path);
64             }
65             else if(peek)
66             {
67                StackFrame newFrame { };
68                stack.Add(newFrame);
69                newFrame.path = CopyString(frame.listing.path);
70                newFrame.listing = FileListing { newFrame.path, extensions = frame.listing.extensions };
71                frame = newFrame;
72             }
73          }
74          else
75          {
76             StackFrame parentFrame = stack.count > 1 ? stack[stack.count - 2] : null;
77             OutFolder(parentFrame ? parentFrame.listing.path : startPath, !parentFrame);
78             stack.lastIterator.Remove();
79             if(stack.count)
80                frame = stack.lastIterator.data;
81             else
82                frame = null;
83          }
84       }
85    }
86 }
87
88 public class FileSystemIterator
89 {
90 public:
91    bool iterateStartPath;
92
93    virtual bool OnInit(char * startPath)
94    {
95       return false;
96    }
97    
98    virtual bool OnFile(char * filePath)
99    {
100       return true;
101    }
102
103    virtual bool OnFolder(char * folderPath)
104    {
105       return true;
106    }
107
108    virtual bool OnVolume(char * volumePath)
109    {
110       return true;
111    }
112
113    virtual void OutFolder(char * folderPath, bool isRoot)
114    {
115    }
116 }
117
118 static class IteratorThread : Thread
119 {
120    void Temp()
121    {
122       //listing = FileListing { dir, extensions = filter.extensions };  // there should be a sorted = true/false 
123    }
124 }
125
126 public class StackFrame
127 {
128    int tag;
129    char * path;
130    FileListing listing;
131
132    ~StackFrame()
133    {
134       delete path;
135       //delete listing;
136    }
137 };
138