Thread overview |
---|
May 30, 2009 first ddata load attempt | ||||
---|---|---|---|---|
| ||||
Attachments: | 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 |
June 01, 2009 Re: first ddata load attempt | ||||
---|---|---|---|---|
| ||||
Posted in reply to Saaa | 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; } |
June 01, 2009 Re: first ddata load attempt | ||||
---|---|---|---|---|
| ||||
Posted in reply to Saaa | 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; > } > |
June 02, 2009 Re: first ddata load attempt | ||||
---|---|---|---|---|
| ||||
Posted in reply to nobody | > 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") erm.. yes.. should have been commented out. > pps. Since you're going for D-styled, shouldn't booleans be matched not only for 'true' but for 'false' as well? But the speed! Maybe I'll add this when I'll add the bool arrays. Why doesn't std2.conv.to parse booleans anyways? |
Copyright © 1999-2021 by the D Language Foundation