Initial git commit -- Transition from CodeGuard repository
[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    }
101
102    virtual bool OnFolder(char * folderPath)
103    {
104       return true;
105    }
106
107    virtual bool OnVolume(char * volumePath)
108    {
109       return true;
110    }
111
112    virtual void OutFolder(char * folderPath, bool isRoot)
113    {
114    }
115 }
116
117 static class IteratorThread : Thread
118 {
119    void Temp()
120    {
121       //listing = FileListing { dir, extensions = filter.extensions };  // there should be a sorted = true/false 
122    }
123 }
124
125 public class StackFrame
126 {
127    int tag;
128    char * path;
129    FileListing listing;
130
131    ~StackFrame()
132    {
133       delete path;
134       //delete listing;
135    }
136 };
137