changeset 4:c5a9d253bfd4

moving to correct folder
author Saaa
date Wed, 07 Oct 2009 14:25:27 +0200
parents 8e3ddf7a3178
children 4cfbf3727998
files ddata/ddata.d
diffstat 1 files changed, 283 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ddata/ddata.d	Wed Oct 07 14:25:27 2009 +0200
@@ -0,0 +1,283 @@
+module ddata.ddata;
+
+//debug
+//import std.stdio;
+import std.string;
+
+import std2.conv : to;
+import std2.traits : isNumeric;
+
+class DDataException : Exception
+{
+    this(char[] msg)
+    {
+    	super(msg);
+    }
+    this( uint loc, char c, char[] msg)
+    {
+    	super( format( `parsing failed at string[`, loc-1, `] = '`,c,`'` ,msg));
+    }
+}
+
+
+private enum TOKEN{ BOF, SQUARE_L, SQUARE_R, COMMA, ECOMMA, VALUE, EOF}
+
+private template Depth(T: T[]) { const Depth = 1 + Depth!(T); }
+private template Depth(T)  { const Depth = 0; }
+
+private template BaseType(T: T[]) { alias BaseType!(T) BaseType; }
+private template BaseType(T) { alias T BaseType; }
+
+private template indexAssign(T: T[])
+{
+	void indexAssign(ref T array,  BaseType!(T) value, int[] indices) 
+	{
+		static if( is( typeof(array[0]) == typeof(value)))
+		{
+			array[indices[0]] = value;
+		}
+		else
+		{
+			indexAssign!(T)( array[indices[0]], value, indices[1..$]);
+		}
+	}
+}
+
+private string ctToString(int i) 
+{
+  if (!i) return "0";
+  string res;
+  while (i) {
+    res = "0123456789"[i%10] ~ res;
+    i /= 10;
+  }
+  return res;
+}
+
+private string indexString(int len) 
+{
+  string res;
+  for (int i = 0; i < len; ++i)
+    res ~= "[index["~ctToString(i)~"]] ";
+  return res;
+}
+
+private string casesString(int depth, TOKEN type)
+{
+  string res;
+  res ~= `switch( depth ){`;
+
+  for (int i = 0; i < depth; ++i)
+  {
+	  switch(type)
+	  {
+		  case TOKEN.COMMA:
+			  res ~=`case `~ctToString(i)~`:`~
+			      	`if(temp`~ indexString(i) ~`.length<=index[`~ctToString(i)~`] )temp`~ indexString(i) ~`.length=temp`~ indexString(i) ~`.length*2;`~
+			      	`break;`;
+		  break;
+		  
+		  case TOKEN.SQUARE_L:
+			  res ~=`case `~ctToString(i)~`:`~
+	    			`temp`~ indexString(i) ~`.length=4;`~
+	    			`break;`;
+		  break;
+		  
+		  case TOKEN.SQUARE_R:
+			  res ~=`case `~ctToString(i)~`:`~
+  					`temp`~ indexString(i) ~`.length=index[`~ctToString(i)~`];`~
+  					`break;`;		  
+		  break;
+		  
+		  default:
+			  assert(false);
+		  break;
+	  }
+  }
+  
+  res ~= `default:assert(false);break;}`;
+  return res;
+}
+
+
+bool toBool(char[] s) 
+{
+	if(s == `true`) 
+	{
+		return true;
+	}
+	else if(s == `false`) 
+	{
+		return false;
+	}
+	else
+	{
+		throw new Exception(`Cannot convert "`~s~`" to bool`);
+	}
+	return false;
+}
+
+public T toArray(T:D[],D)(char[] string)
+{	
+	int[ Depth!(T) ] index = 0;
+	
+	T temp;
+	char c;
+	
+	int depth = -1;
+
+	int sLoc1 = -1, sLoc2 = -1;
+	int loc = -1;
+	
+	TOKEN last = TOKEN.BOF;
+	
+	while(true)
+	{
+		loc++;
+		//debug 
+		//writefln(loc);
+		if( loc >= string.length )
+		{
+			if( last != TOKEN.SQUARE_R) throw new DDataException( `unexpected end`);
+			if( depth != -1 ) throw new DDataException( `array depth not zero after parsing `);
+			//throw new DDataException(`EOF before end of parsing`);
+			return temp;
+		}
+		
+		c = string[loc];
+		//debug 
+		//writefln(c);
+		switch(c)
+		{
+			case ' ', '\t', '\v', '\r', '\n', '\f':
+				if( last == TOKEN.ECOMMA || last == TOKEN.SQUARE_L)
+				{
+					if(sLoc2 < 0)
+					{
+						sLoc1 = loc + 1;
+					}else{
+						sLoc2 = loc;
+						last = TOKEN.VALUE;
+					}
+				}
+			break;
+			
+			case ',':
+				index[depth] ++;
+
+				// resize array if necessary
+				mixin ( casesString(Depth!(T), TOKEN.COMMA ) );
+				
+				if( last == TOKEN.VALUE && depth == Depth!(T)-1 )
+				{
+					index[depth] --;
+					static if( is(BaseType!(T) == bool) )
+					{
+						indexAssign!(T[])( temp, toBool( string[ sLoc1..sLoc2] ), index);
+					}
+					else static if( isNumeric!( BaseType!(T) ) )
+					{
+						indexAssign!(T[])( temp, to!( BaseType!(T) )( string[ sLoc1..sLoc2] ), index);
+					}
+					else
+					{
+						assert(false);
+					}
+					index[depth] ++;
+					sLoc1 = -1;
+					sLoc2 = -1;
+					last = TOKEN.ECOMMA;
+				}else if( last == TOKEN.SQUARE_R ){
+					last = TOKEN.COMMA;
+				}else{
+					throw new DDataException( loc, c, `: Value, ']' or ',' expected.`);
+				}
+			break;
+			
+			case '[':
+				if( last != TOKEN.COMMA && last != TOKEN.BOF && last != TOKEN.SQUARE_L ) throw new DDataException( loc, c, `: Beginning, '[' or ','  expected.`);
+				
+				depth++;
+				if(depth > index.length) throw new DDataException( loc, c, `: Array too deep = `~toString(depth));
+				mixin ( casesString(Depth!(T), TOKEN.SQUARE_L ) );
+				index[depth] = 0;
+				last = TOKEN.SQUARE_L;
+				sLoc1 = -1;
+				sLoc2 = -1;
+			break;
+			
+			case ']':
+				if( last == TOKEN.VALUE && depth == Depth!(T)-1 && sLoc2 != -1)
+				{
+					static if( is(BaseType!(T) == bool) )
+					{
+						indexAssign!(T[])( temp, toBool( string[ sLoc1..sLoc2]), index);
+					}
+					else static if( isNumeric!( BaseType!(T) ) )
+					{
+						indexAssign!(T[])( temp, to!( BaseType!(T) )(string[ sLoc1..sLoc2]), index);
+					}
+					else
+					{
+						assert(false);
+					}
+					sLoc1 = -1;
+					sLoc2 = -1;
+					index[depth] ++;
+				} 
+				else if( last == TOKEN.SQUARE_L ) 
+				{
+					sLoc1 = -1;
+					sLoc2 = -1;
+				} 
+				else if( last == TOKEN.SQUARE_R) 
+				{
+					index[depth] ++;
+				} 
+				else 
+				{
+					throw new DDataException( loc, c, `: Value, '[' or ']' expected.`);
+				}
+				
+				// set array length to index[depth]
+				mixin ( casesString(Depth!(T), TOKEN.SQUARE_R) );
+				
+				index[depth] = 0;
+				depth--;
+				last = TOKEN.SQUARE_R;
+			break;
+				
+			default:
+				if( last == TOKEN.ECOMMA || last == TOKEN.SQUARE_L || last == TOKEN.VALUE)
+				{
+					if( sLoc1 < 0 )
+					{
+						sLoc1 = loc;
+						sLoc2 = loc +1;
+					} else {
+						sLoc2 = loc +1;
+					}
+					last = TOKEN.VALUE;
+					break;
+				}
+				throw new DDataException( loc, c, `: Out of place char found `);
+			break;
+		}
+	}
+}
+
+unittest 
+{
+    writefln("DData UnitTest...");
+    
+	int[][][] ia = [ [[1,2],[3,4],[5]] , [[6],[],[7,8,9]] , [[]] ];
+	
+	char[] s = to!(char[])(ia);
+	int[][][] ia2;
+	
+	ia2 = toArray!(typeof(ia2))(s);
+    assert( ia == ia2);  
+    
+    writefln("Done!");
+}
+