diff mde/file/mergetag/Reader.d @ 134:7ababdf97748

Moved mde.setup.paths to mde.file.paths and paths.mdeReader to mde.file.mergetag.Reader.MTMultiReader.
author Diggory Hardy <diggory.hardy@gmail.com>
date Thu, 29 Jan 2009 14:59:45 +0000
parents b16a534f5302
children 4084f07f2c7a
line wrap: on
line diff
--- a/mde/file/mergetag/Reader.d	Fri Jan 23 16:05:05 2009 +0000
+++ b/mde/file/mergetag/Reader.d	Thu Jan 29 14:59:45 2009 +0000
@@ -518,3 +518,67 @@
     void read (ID[] secSet) {}          /// ditto
     void read (IContainer!(ID) secSet) {}/// ditto
 }
+
+
+/** A special adapter for reading from multiple mergetag files.
+ *
+ * The number of files $(B must not) exceed MAX_PATHS. */
+class MTMultiReader : IReader
+{
+    this (FilePath[] files, DataSet ds, bool rdHeader)
+    in {
+        assert (files !is null, "mdeReader.this: files is null");
+    } body {
+        // Don't let sub-readers create their own, separate, datasets:
+        if (ds is null) ds = new DataSet;
+        
+        Exception exc;
+        foreach (file; files) {
+            try {   // try reading header of each file
+                IReader r = makeReader (file, ds, rdHeader);
+                readers[readersLen++] = r;
+            } catch (Exception e) {
+                exc = e;
+            }
+        }
+        if (readersLen == 0)        // no files have valid headers
+            throw exc;              // fail: re-throw last exception
+    }
+    
+    DataSet dataset () {                /// Get the DataSet
+        return readers[0].dataset;      // all readers share the same dataset
+    }
+    void dataset (DataSet ds) {         /// Set the DataSet
+        for (uint i = 0; i < readersLen; ++i) readers[i].dataset (ds);
+    }
+    
+    void dataSecCreator (IDataSection delegate (ID) dsC) {  /// Set the dataSecCreator
+        for (uint i = 0; i < readersLen; ++i) readers[i].dataSecCreator = dsC;
+    }
+    
+    /** Get identifiers for all sections.
+     *
+     * Note: the identifiers from all sections in all files are just strung
+     * together, starting with the highest-priority file. */
+    ID[] getSectionNames () {
+        ID[] names;
+        for (int i = readersLen-1; i >= 0; --i)
+            names ~= readers[i].getSectionNames;
+        return names;
+    }
+    void read () {                      /// Commence reading
+        for (uint i = 0; i < readersLen; ++i) readers[i].read();
+    }
+    void read (ID[] secSet) {           /// ditto
+        for (uint i = 0; i < readersLen; ++i) readers[i].read(secSet);
+    }
+    void read (IContainer   !(ID) secSet) {      /// ditto
+        for (uint i = 0; i < readersLen; ++i) readers[i].read(secSet);
+    }
+    
+    const MAX_READERS = 4;
+private:
+    // Use a simpler static array:
+    IReader[MAX_READERS] readers;
+    ubyte readersLen = 0;
+}