|
Archives
D Programming
digitalmars.Ddigitalmars.D.bugs digitalmars.D.dtl digitalmars.D.ide digitalmars.D.dwt digitalmars.D.announce digitalmars.D.learn digitalmars.D.debugger D.gnu D C/C++ Programming
c++c++.announce c++.atl c++.beta c++.chat c++.command-line c++.dos c++.dos.16-bits c++.dos.32-bits c++.idde c++.mfc c++.rtl c++.stl c++.stl.hp c++.stl.port c++.stl.sgi c++.stlsoft c++.windows c++.windows.16-bits c++.windows.32-bits c++.wxwindows digitalmars.empire digitalmars.DMDScript electronics |
digitalmars.D.learn - first ddata load attempt
Attached my first attempt to load int and int[] from a D-styled data file. Adding the functions to support the other types is trivial (hope to be using templates :) but supporting an arbitrary deep array isn't that obvious to me yet. Please comment :) ps. it uses std2 because of the possible template use. dmd 1.041 May 30 2009
Templated !!
This is the first time I use templates.
please comment
module ddata.ddata;
import std.stdarg;
import std.stdio;
import std.regexp;
import std2.string;
import std2.traits;
import std2.conv;
private char[][] _file;
private char[] _identifier;
private TypeInfo _type;
private int _row;
private char[] _token;
private int _tokenLen;
public bool Get(T)(in char[][] file, in char[] identifier, ref T var)
{
if (file.length == 0 || file.length > int.max)
{
return false;
}
if (identifier.length == 0 || identifier.length > ubyte.max)
{
return false;
}
RegExp myRegExp = new RegExp("_A-Za-z[_A-Za-z0-9]*");
if ( cast(bool) myRegExp.test(identifier) )
{
return false;
}
_file = file;
_identifier = identifier;
_type = typeid(T);
_row = getRow();
if (_row < 0 || _row >= _file.length)
{
return false;
throw new Exception("Identifier not found");
}
try
{
static if( std2.traits.isNumeric!(T))
{
Parse(var);
return true;
}
static if( typeid(T) is typeid(bool) )
{
parse_bool(var);
return true;
}
static if( std2.traits.isDynamicArray!(T) )
{
Parse_array(var);
return true;
}
return false;
}
catch
{
return false;
}
return true;
}
private int getRow()
{
_token = _type.toString() ~ ' ' ~ _identifier;
writefln(`Search token =`,_token);
_tokenLen = _token.length;
foreach(int row, char[] line; _file)
{
if(line.length > _token.length)
{
if(line[0.._tokenLen] == _token) return row;
}
}
return -1;
}
private void Parse(T)(ref T parsed)
{
uint begin = qcFind( _tokenLen, '=') + 1;
if( begin == -1) throw new Exception(` = not found`);
uint end = qcFind( begin, ';');
if( end == -1) throw new Exception(` ; not found`);
parsed = to!(T)( strip( _file[_row][begin..end]) );
writefln(parsed);
return;
}
private void parse_bool(ref bool parsed)
{
uint begin = qcFind( _tokenLen, '=') + 1;
if( begin == -1) throw new Exception(` = not found`);
uint end = qcFind( begin, ';');
if( end == -1) throw new Exception(` ; not found`);
parsed = (strip( _file[_row][begin..end]) == `true`);
writefln(parsed);
return;
}
private void Parse_array(T:U[],U)(ref T parsed)
{
uint begin = qcFind( _tokenLen, '[') + 1;
if( begin == -1) throw new Exception(` [ not found`);
uint end = qcFind( begin, ']');
if( end == -1) throw new Exception(`] not found`);
auto stringArray = std.string.split(_file[_row][begin..end], `,`);
T array;
array.length = stringArray.length;
foreach(int i, char[] string; stringArray)
{
array[i] = to!(U)(strip(string));
}
parsed = array;
return;
}
private int qcFind(in int start,in char c)
{
int location = std.string.find( _file[_row][start..$], c) + start;
if( location <= start || location >= _file[_row].length )
{
return -1;
}
return location;
}
May 31 2009
Looks interesting, but unfortunately it's still useless to me since it
doesn't seem to support arrays of varying depth, nor boolean arrays I
believe.
ps. Isn't this throw statement unreachable? (throw new Exception("Identifier
not found");)
pps. Since you're going for D-styled, shouldn't booleans be matched not only
for 'true' but for 'false' as well?
"Saaa" <empty needmail.com> wrote in message
news:gvveal$107p$1 digitalmars.com...
Jun 01 2009
Jun 02 2009
|