31b4e16c7b29312143d5d62b46e7d3c50dd5ae4f
[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 const char * extensions { set { delete extensions; if(value) extensions = CopyString(value); } }
19
20    ~NormalFileSystemIterator()
21    {
22       delete extensions;
23    }
24
25    void Iterate(const 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             bool peek = frame.listing.stats.attribs.isDirectory && OnFolder(frame.listing.path);
58             if(!frame.listing.stats.attribs.isDirectory)
59             {
60                const char * path = frame.listing.path;
61                OnFile(path);
62             }
63             else if(peek)
64             {
65                StackFrame newFrame { };
66                stack.Add(newFrame);
67                newFrame.path = CopyString(frame.listing.path);
68                newFrame.listing = FileListing { newFrame.path, extensions = frame.listing.extensions };
69                frame = newFrame;
70             }
71          }
72          else
73          {
74             StackFrame parentFrame = stack.count > 1 ? stack[stack.count - 2] : null;
75             OutFolder(parentFrame ? parentFrame.listing.path : startPath, !parentFrame);
76             stack.lastIterator.Remove();
77             if(stack.count)
78                frame = stack.lastIterator.data;
79             else
80                frame = null;
81          }
82       }
83    }
84 }
85
86 public class FileSystemIterator
87 {
88 public:
89    bool iterateStartPath;
90
91    virtual bool OnInit(const char * startPath)
92    {
93       return false;
94    }
95
96    virtual bool OnFile(const char * filePath)
97    {
98       return true;
99    }
100
101    virtual bool OnFolder(const char * folderPath)
102    {
103       return true;
104    }
105
106    virtual bool OnVolume(const char * volumePath)
107    {
108       return true;
109    }
110
111    virtual void OutFolder(const char * folderPath, bool isRoot)
112    {
113    }
114 }
115 /*
116 static class IteratorThread : Thread
117 {
118    void Temp()
119    {
120       //listing = FileListing { dir, extensions = filter.extensions };  // there should be a sorted = true/false
121    }
122 }
123 */
124 public class StackFrame
125 {
126    int tag;
127    char * path;
128    FileListing listing;
129
130    ~StackFrame()
131    {
132       delete path;
133       //delete listing;
134    }
135 };