digitalmars.D.learn - first ddata load attempt
- "Saaa" <empty needmail.com> May 30 2009
- "Saaa" <empty needmail.com> May 31 2009
- "nobody" <somebody somewhere.com> Jun 01 2009
- "Saaa" <empty needmail.com> Jun 02 2009
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...
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;
}
Jun 01 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?
Maybe I'll add this when I'll add the bool arrays. Why doesn't std2.conv.to parse booleans anyways?
Jun 02 2009








"Saaa" <empty needmail.com>