diff mde/file/deserialize.d @ 89:97e6dce08037

Solved some/removed some obsolete jobs/FIXMEs (excluding from gui code). General cleanup.
author Diggory Hardy <diggory.hardy@gmail.com>
date Mon, 29 Sep 2008 18:27:17 +0100
parents 79d816b3e2d2
children 7f7b40fed72b
line wrap: on
line diff
--- a/mde/file/deserialize.d	Mon Sep 29 12:09:44 2008 +0100
+++ b/mde/file/deserialize.d	Mon Sep 29 18:27:17 2008 +0100
@@ -84,7 +84,7 @@
         throw new ParseException ("Invalid associative array: not [ ... ]");  // bad braces.
     
     T[S] ret;
-    foreach (char[] pair; split (src[1..$-1])) {
+    foreach (char[] pair; Split (src[1..$-1])) {
         uint i = 0;
         while (i < pair.length) {   // advance to the ':'
             char c = pair[i];
@@ -97,7 +97,7 @@
                     ++i;
                 }
                 // Could have an unterminated ' or " causing i >= pair.length, but:
-                // 1. Impossible: split would have thrown
+                // 1. Impossible: Split would have thrown
                 // 2. In any case this would be caught below.
             }
             ++i;
@@ -296,7 +296,7 @@
     // cannot access elements of T.tupleof with non-const key, so use a type which can be
     // accessed with a non-const key to store slices:
     char[][T.tupleof.length] temp;
-    foreach (char[] pair; split (src[1..$-1])) {
+    foreach (char[] pair; Split (src[1..$-1])) {
         uint i = 0;
         while (i < pair.length) {   // advance to the ':'
             char c = pair[i];
@@ -322,61 +322,71 @@
 /** Splits a string into substrings separated by '$(B ,)' with support for characters and strings
  * containing escape sequences and for embedded arrays ($(B [...])).
  *
- * Params:
- *     src A string to separate on commas. It shouldn't have enclosing brackets.
+ * ---
+ * foreach (element; Split(src))
+ *     ...
+ * ---
+ * Where src is a string to separate on commas. It shouldn't have enclosing brackets.
  *
- * Returns:
- *     An array of substrings within src, excluding commas. Whitespace is not stripped and
- *     empty strings may get returned.
+ * Output elements are substrings of src separated by commas, excluding the commas.
+ * Not all whitespace is not stripped and empty strings may get returned.
  *
  * Remarks:
- *     This function is primarily intended for as a utility function for use by the templates
+ *     This struct is primarily intended for as a utility for use by the templates
  *     parsing arrays and associative arrays, but it may be useful in other cases too. Hence the
  *     fact no brackets are stripped from src.
  */
-//FIXME foreach struct is more efficient
-char[][] split (char[] src) {
-    src = Util.trim (src);
-    if (src == "")
-        return [];       // empty array: no elements when no data
+struct Split {
+    static Split opCall (char[] source) {
+        Split ret;
+        ret.src = Util.trim (source);
+        return ret;
+    }
+    
+    int opApply(int delegate(ref char[]) dg)
+    {
+        if (src == "")
+            return 0;
+        
+        int result = 0;
+        
+        uint depth = 0;         // surface depth (embedded arrays)
+        size_t i = 0, j = 0;    // current read location, start of current piece
     
-    uint depth = 0;         // surface depth (embedded arrays)
-    char[][] ret;
-    ret.length = src.length / 3;    // unlikely to need a longer array
-    uint k = 0;             // current split piece
-    uint i = 0, j = 0;          // current read location, start of current piece
-    
-    while (i < src.length) {
-        char c = src[i];
-        if (c == '\'' || c == '"') {    // string or character
+        while (i < src.length) {
+            char c = src[i];
+            if (c == '\'' || c == '"') {    // string or character
+                ++i;
+                while (i < src.length && src[i] != c) {
+                    if (src[i] == '\\')
+                        ++i;    // escape seq.
+                        ++i;
+                }   // Doesn't throw if no terminal quote at end of src, but this should be caught later.
+            }
+            else if (c == '[') ++depth;
+            else if (c == ']') {
+                if (depth)
+                    --depth;
+                else throw new ParseException ("Invalid array literal: closes before end of data item.");
+            }
+            else if (c == ',' && depth == 0) {      // only if not an embedded array
+                char[] t = src[j..i];
+                result = dg(t);   // add this piece and increment k
+                if (result)
+                    return result;
+                j = i + 1;
+            }
             ++i;
-            while (i < src.length && src[i] != c) {
-                if (src[i] == '\\')
-                    ++i;    // escape seq.
-                ++i;
-            }   // Doesn't throw if no terminal quote at end of src, but this should be caught later.
         }
-        else if (c == '[') ++depth;
-        else if (c == ']') {
-            if (depth)
-                --depth;
-            else throw new ParseException ("Invalid array literal: closes before end of data item.");
-        }
-        else if (c == ',' && depth == 0) {      // only if not an embedded array
-            if (ret.length <= k)
-                ret.length = ret.length * 2;
-            ret[k++] = src[j..i];   // add this piece and increment k
-            j = i + 1;
-        }
-        ++i;
+        if (i > src.length)
+            throw new ParseException ("Unterminated quote (\' or \")");
+        
+        char[] t = src[j..i];
+        result = dg(t);     // add final piece (i >= j)
+        return result;
     }
-    if (i > src.length)
-        throw new ParseException ("Unterminated quote (\' or \")");
     
-    if (ret.length <= k)
-        ret.length = k + 1;
-    ret[k] = src[j..i];     // add final piece (i >= j)
-    return ret[0..k+1];
+    char[] src;
 }
 
 /* Templated read-int function to read (un)signed 1-4 byte integers.
@@ -486,7 +496,7 @@
 private T[] toArray(T : T[]) (char[] src) {
     T[] ret = new T[16];    // avoid unnecessary allocations
     uint i = 0;
-    foreach (char[] element; split(src[1..$-1])) {
+    foreach (char[] element; Split(src[1..$-1])) {
         if (i == ret.length) ret.length = ret.length * 2;
         ret[i] = deserialize!(T) (element);
         ++i;