--- /dev/null
+#ifdef BUILDING_ECERE_COM
+namespace sys;
+import "Array"
+#else
+#ifdef ECERE_STATIC
+public import static "ecere"
+#else
+public import "ecere"
+#endif
+#endif
+
+public class FileSystemIterator : InterfaceFileSystemIterator
+{
+public:
+ property char * extensions { set { delete extensions; if(value) extensions = CopyString(value); } get { return extensions; } }
+
+ public bool Iterate(char * startPath, bool followLinks)
+ {
+ bool result = true;
+ bool listDirEntries;
+ Array<FileSystemIteratorStackFrame> stack { };
+ FileSystemIteratorStackFrame frame;
+
+ if(iterateStartPath)
+ {
+ char name[MAX_LOCATION] = "";
+ FileStats stats;
+ if(followLinks)
+ FileGetStats(startPath, stats);
+ else
+ FileGetStatsLink(startPath, stats);
+ GetLastDirectory(startPath, name);
+ listDirEntries = OnObject(owner, name, startPath, stats, true);
+ if(listDirEntries)
+ {
+ OnEnteringDirectory(owner, startPath);
+ // FileListing should have a sorted = true/false property
+ stack.Add((frame = { { startPath, extensions = extensions } }));
+ }
+ }
+
+ if(listDirEntries)
+ {
+ while(frame)
+ {
+ if(frame.listing.Find())
+ {
+ FileStats stats = followLinks ? frame.listing.stats : frame.listing.lstats;
+ listDirEntries = OnObject(owner, frame.listing.name, frame.listing.path, stats, !iterateStartPath && stack.count == 1);
+ if(stats.attribs.isDirectory)
+ {
+ if(listDirEntries)
+ {
+ OnEnteringDirectory(owner, frame.listing.path);
+ stack.Add((frame = { { frame.listing.path, extensions = frame.listing.extensions } }));
+ }
+ else
+ result = false;
+ }
+ }
+ else
+ {
+ if(stack.count > (iterateStartPath ? 0 : 1))
+ OnLeavingDirectory(owner, frame.listing.directory);
+ delete frame;
+ stack.lastIterator.Remove();
+ frame = stack.count == 0 ? null : stack.lastIterator.data;
+ }
+ }
+ if(stack.count != 0)
+ PrintLn("dddddddd");
+ stack.Free();
+ }
+ delete stack;
+ return result;
+ }
+
+private:
+ char * extensions;
+
+ ~FileSystemIterator()
+ {
+ delete extensions;
+ }
+}
+
+public class FileSystemIteratorStackFrame : struct
+{
+public:
+ FileListing listing;
+
+private:
+}
+
+public class InterfaceFileSystemIterator
+{
+public:
+ Window owner; // any_object owner; <-- this makes it so that uses of owner are not compiling...
+ // the idea here is to provide iterators with the ability to use arbitrary data when used by instanciation only not defivation.
+ void * data; // any_object data; <-- this... probably the same
+ bool iterateStartPath;
+
+ virtual bool Iterate(char * startPath, bool followLinks);
+ virtual bool any_object::OnObject(/*any_object data, */char * name, char * path, FileStats stats, bool isRootObject);
+ virtual void any_object::OnEnteringDirectory(/*any_object data, */char * path);
+ virtual void any_object::OnLeavingDirectory(/*any_object data, */char * path);
+
+private:
+}
+
+// TODO: implement threaded iteration somehow....
+static class IteratorThread : Thread
+{
+ void Temp()
+ {
+ //listing = FileListing { dir, extensions = filter.extensions }; // there should be a sorted = true/false
+ }
+}