Mercurial > projects > mde
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;