code dump. unfortunate lack of commits. rick click menu on files/folders. comparative...
[ede] / libede / src / FileSystemIterator.ec
diff --git a/libede/src/FileSystemIterator.ec b/libede/src/FileSystemIterator.ec
new file mode 100644 (file)
index 0000000..6c2cab3
--- /dev/null
@@ -0,0 +1,118 @@
+#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 
+   }
+}