Changeset 32

Show
Ignore:
Timestamp:
02/09/08 18:04:11 (1 year ago)
Author:
aarti_pl
Message:

- cleanups
- new module Tokenizer.d

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/doost/core/Any.d

    r31 r32  
    8484        Params: value = value to assign 
    8585     **************************************************************************/ 
    86     //NOTE: Temporar workaround till constructors don't get ability to be templatized 
     86    //NOTE: Temporary workaround till constructors don't get ability to be templatized 
    8787    Any assign(ValueType)(ValueType value) { 
    8888        static if (is(ValueType == Any)) content = value.content !is null ? value.content.clone() : null; 
     
    9393    /*************************************************************************** 
    9494        Gives information if container is empty. 
    95         Returns: true if nothing is assinged to container 
     95        Returns: true if nothing is assigned to container 
    9696     **************************************************************************/ 
    9797    bool empty() { 
     
    213213 
    214214unittest { 
    215     testSuite.begin("Any"); 
     215    testSuite.start("Any"); 
    216216} 
    217217 
  • trunk/doost/core/Traits.d

    r28 r32  
    3636        alias U arrayElementType; 
    3737    else 
    38         static assert(false, "Not an array"); 
     38        static assert(false, "'" ~ T.stringof ~ "' is not an array."); 
     39
     40 
     41/******************************************************************************* 
     42    Evaluates to type of array element 
     43 ******************************************************************************/ 
     44//TODO: checki na spełnianie wymagań co do array 
     45template elementType(T) { 
     46    static if( is( T U : U[] ) ) { 
     47        pragma(msg, "elementType: " ~ T.stringof ~ " -> " ~ U.stringof); 
     48        alias U elementType; 
     49    } else 
     50    static if( is( typeof(T.get(1u)) U == U[]) ) { 
     51        pragma(msg, "elementType: " ~ T.stringof ~ " -> " ~ U.stringof); 
     52        alias U elementType; 
     53    } else 
     54    static assert(false, "'" ~ T.stringof ~ "' can not be threated as array."); 
    3955} 
    4056 
     
    87103 
    88104/******************************************************************************* 
     105    Evaluates to true if value is number 
     106 ******************************************************************************/ 
     107template isNumber( T ) { 
     108        static if( is( T == byte ) 
     109                || is( T == short ) 
     110                || is( T == int ) 
     111                || is( T == long ) 
     112                || is( T == ubyte ) 
     113                || is( T == ushort ) 
     114                || is( T == uint ) 
     115                || is( T == ulong ) 
     116                || is( T == float ) 
     117                || is( T == double ) 
     118                || is( T == real ) 
     119                || is( T == ifloat ) 
     120                || is( T == idouble ) 
     121                || is( T == ireal ) 
     122                || is( T == cfloat ) 
     123                || is( T == cdouble ) 
     124                || is( T == creal ) ) 
     125            const isNumber = true; 
     126        else 
     127            const isNumber = false; 
     128} 
     129 
     130/******************************************************************************* 
     131    Evaluates to true if value is number 
     132 ******************************************************************************/ 
     133template isChar( T ) { 
     134        static if( is( T == char ) 
     135                || is( T == wchar ) 
     136                || is( T == dchar ) 
     137                ) 
     138            const isChar = true; 
     139        else 
     140            const isChar = false; 
     141} 
     142 
     143/******************************************************************************* 
    89144    Evaluates to true for associative arrays 
    90145 ******************************************************************************/ 
     
    93148} 
    94149 
    95  
     150//****************************************************************************** 
     151//****************************************************************************** 
     152//****************************************************************************** 
     153//Reaped from Phobos 2.0 
     154 
     155/** 
     156 * Detect whether type T is a static array. 
     157 */ 
     158template isStaticArray(T : U[N], U, size_t N) 
     159
     160    const bool isStaticArray = true; 
     161
     162 
     163template isStaticArray(T) 
     164
     165    const bool isStaticArray = false; 
     166
     167 
     168static assert (isStaticArray!(int[51])); 
     169static assert (isStaticArray!(int[][2])); 
     170static assert (isStaticArray!(char[][int][11])); 
     171static assert (!isStaticArray!(int[])); 
     172static assert (!isStaticArray!(int[char])); 
     173static assert (!isStaticArray!(int[1][])); 
     174static assert(isStaticArray!(char[13u])); 
     175static assert (isStaticArray!(typeof("string literal"))); 
     176static assert (isStaticArray!(void[0])); 
     177static assert (!isStaticArray!(int[int])); 
     178static assert (!isStaticArray!(int)); 
     179 
     180/** 
     181 * Detect whether type T is a dynamic array. 
     182 */ 
     183template isDynamicArray(T, U = void) 
     184
     185    static const isDynamicArray = false; 
     186
     187 
     188template isDynamicArray(T : U[], U) 
     189
     190  static const isDynamicArray = !isStaticArray!(T); 
     191
     192 
     193static assert(isDynamicArray!(int[])); 
     194static assert(!isDynamicArray!(int[5])); 
     195 
     196/** 
     197 * Detect whether type T is an array. 
     198 */ 
     199template isArray(T) 
     200
     201    static const isArray = isStaticArray!(T) || isDynamicArray!(T); 
     202
     203 
     204static assert(isArray!(int[])); 
     205static assert(isArray!(int[5])); 
     206static assert(!isArray!(uint)); 
     207static assert(!isArray!(uint[uint])); 
     208static assert(isArray!(void[])); 
     209 
     210 
     211template BaseTypeTuple(A) 
     212
     213    static if (is(A P == super)) 
     214    alias P BaseTypeTuple; 
     215    else 
     216    static assert(0, "argument is not a class or interface"); 
     217
     218 
  • trunk/doost/util/DUnit.d

    r31 r32  
    2222import std.path; 
    2323import std.date; 
    24 import std2.traits; 
    2524import std2.conv; 
    2625 
     
    108107//------------------------------------------------------------------------------ 
    109108 
     109class EmptyElem : Element { 
     110public: 
     111    this() { 
     112    } 
     113    override string pattern() { 
     114        return ""; 
     115    } 
     116    override string render(string str) { 
     117        return str; 
     118    } 
     119} 
     120 
     121//------------------------------------------------------------------------------ 
     122 
    110123class HlElem : CellElem { 
    111124public: 
     
    148161//------------------------------------------------------------------------------ 
    149162 
    150 class Table { 
     163Element Empty() { 
     164    return new EmptyElem(); 
     165
     166 
     167//------------------------------------------------------------------------------ 
     168 
     169class Renderer { 
    151170public: 
    152171    this(uint width = 75) { 
     
    211230 
    212231unittest { 
    213     auto p = new Table
     232    auto p = new Renderer
    214233    assert(p.argNumberToMunch("%% %% %% %% %") == 1); 
    215234    assert(p.argNumberToMunch("% %% % %% %") == 3); 
     
    234253 
    235254//------------------------------------------------------------------------------ 
     255 
     256/********************************* 
     257 * Returns !=0 if e is a NaN. 
     258 * Taken from Tango 
     259 */ 
     260//FIXME: remove after conversion to Tango 
     261int isNaN(real x) 
     262{ 
     263    static if (real.mant_dig==double.mant_dig) { 
     264        // 64-bit real 
     265        ulong*  p = cast(ulong *)&x; 
     266        return (*p & 0x7FF0_0000 == 0x7FF0_0000) && *p & 0x000F_FFFF; 
     267    } else { 
     268        // 80-bit real 
     269        ushort* pe = cast(ushort *)&x; 
     270        ulong*  ps = cast(ulong *)&x; 
     271 
     272        return (pe[4] & 0x7FFF) == 0x7FFF && 
     273            *ps & 0x7FFFFFFFFFFFFFFF; 
     274    } 
     275} 
    236276 
    237277class TestCase { 
     
    273313            else tc_no = to!(string)(m_owner.m_tccounter) ~ "."; 
    274314 
    275         if (m_dotiming) m_owner.table.render(m_owner.tc_tim, tc_no, m_testname ~ " test...", result, no, m_elapsedtime); 
    276             else m_owner.table.render(m_owner.tc, tc_no, m_testname ~ " test...", result); 
    277  
    278         if (m_elapsedtime !is real.nan) m_owner.m_elapsedtime+=m_elapsedtime; 
     315        if (m_dotiming) m_owner.renderer.render(m_owner.tc_tim, tc_no, m_testname ~ " test...", result, no, m_elapsedtime); 
     316            else m_owner.renderer.render(m_owner.tc, tc_no, m_testname ~ " test...", result); 
     317 
     318        //BUG: przy sprawdzaniu nan is oraz !is powinno działać 
     319        if (!isNaN(m_elapsedtime)) m_owner.m_elapsedtime+=m_elapsedtime; 
    279320    } 
    280321 
     
    314355        foreach(t; m_traces) { 
    315356            if (t.file != lastfile) { 
    316                 m_owner.table.render(m_owner.simple); 
    317                 if (t.file != "") m_owner.table.render(m_owner.simple, "     " ~ getBaseName(t.file) ~ ":"); 
    318                     else m_owner.table.render(m_owner.simple); 
     357                m_owner.renderer.render(m_owner.simple); 
     358                if (t.file != "") m_owner.renderer.render(m_owner.simple, "     " ~ getBaseName(t.file) ~ ":"); 
     359                    else m_owner.renderer.render(m_owner.simple); 
    319360                lastfile = t.file; 
    320361            } 
    321362 
    322             if (t.line !=0) m_owner.table.render(m_owner.simple, "     " ~ format("%4d:  %s", t.line, t.trace)); 
    323                 else m_owner.table.render(m_owner.simple, "     " ~ t.trace); 
     363            if (t.line !=0) m_owner.renderer.render(m_owner.simple, "     " ~ format("%4d:  %s", t.line, t.trace)); 
     364                else m_owner.renderer.render(m_owner.simple, "     " ~ t.trace); 
    324365        } 
    325366    } 
     
    350391        m_groupname = groupname; 
    351392        if (groupname != "") { 
    352             //m_owner.table.render(m_owner.simple); 
    353             /*if (!first)*/ m_owner.table.render(m_owner.hl); 
    354             m_owner.table.render(m_owner.simple, "Group: " ~ groupname); 
    355             /*if (!last)*/ //m_owner.table.render(m_owner.hl); 
     393            //m_owner.renderer.render(m_owner.simple); 
     394            /*if (!first)*/ m_owner.renderer.render(m_owner.hl); 
     395            m_owner.renderer.render(m_owner.simple, "Group: " ~ groupname); 
     396            /*if (!last)*/ //m_owner.renderer.render(m_owner.hl); 
    356397        } 
    357398    } 
    358399 
    359400    void finish() { 
    360  
     401        //FIXME: currently not possible to finish group, as every call to testGroup 
     402        //creates new group 
     403        //m_owner.m_curgroup = null; 
    361404    } 
    362405 
     
    400443class TestSuite { 
    401444public: 
    402     //TODO: function disable, which sets repeat to 0 
    403445    //TODO: tylko jeden otwarty test suite jednocześnie. 
    404446    //jeÅŒeli ktoś próbuje otworzyć drugi to musi czekać na skończenie pierwszego?? 
     
    410452        m_tccounter = 0; 
    411453        m_tcfcounter = 0; 
    412  
    413         table.render(hl); 
    414         table.render(title, m_suitename ~ " test suite."); 
    415         //table.render(hl); 
     454        m_tcfailed = null; 
     455        m_elapsedtime=0; 
     456 
     457        renderer.render(hl); 
     458        renderer.render(title, m_suitename ~ " test suite."); 
     459        //renderer.render(hl); 
    416460    } 
    417461 
     
    420464 
    421465        if (m_tcfailed.length>0) { 
    422             table.render(hl); 
    423             table.render(simple, "Failed test cases / errors / traces:"); 
    424             table.render(simple); 
     466            renderer.render(hl); 
     467            renderer.render(simple, "Failed test cases / errors / traces:"); 
     468            renderer.render(simple); 
    425469            foreach(tc; m_tcfailed) { 
    426                 table.render(fail, tc.m_number, tc.m_testname); 
    427                 table.render(simple, "     " ~ tc.m_error); 
    428                 table.render(simple); 
     470                renderer.render(fail, tc.m_number, tc.m_testname); 
     471                renderer.render(simple, "     " ~ tc.m_error); 
     472                renderer.render(simple); 
    429473                tc.printTraces; 
    430474            } 
     
    433477 
    434478        if (m_dotraces || m_reqtraces) { 
    435             table.render(hl); 
    436             table.render(simple, "Traces:"); 
    437             table.render(simple); 
     479            renderer.render(hl); 
     480            renderer.render(simple, "Traces:"); 
     481            renderer.render(simple); 
    438482            foreach(tc; m_testcases) { 
    439483                if (tc.m_repeat == 0 || tc.m_dotraces == false) continue; 
    440                 table.render(fail, tc.m_number, tc.m_testname); 
     484                renderer.render(fail, tc.m_number, tc.m_testname); 
    441485                tc.printTraces; 
    442                 table.render(simple); 
     486                renderer.render(simple); 
    443487            } 
    444488        } 
    445489 
    446         table.render(hl); 
    447         table.render(simple); 
    448         table.render(etime,  "Statistics :", "Total time :", m_elapsedtime); 
    449         table.render(stat,  " -    all  :", m_tccounter); 
    450         table.render(stat,  " - passed  :", tcpcounter, cast(double)(tcpcounter*100)/m_tccounter); 
    451         table.render(stat,  " - failed  :", m_tcfcounter, cast(double)(m_tcfcounter*100)/m_tccounter); 
    452         table.render(hl); 
     490        renderer.render(hl); 
     491        renderer.render(simple); 
     492        renderer.render(etime,  "Statistics :", "Total time :", m_elapsedtime); 
     493        renderer.render(stat,  " -    all  :", m_tccounter); 
     494        renderer.render(stat,  " - passed  :", tcpcounter, cast(double)(tcpcounter*100)/m_tccounter); 
     495        renderer.render(stat,  " - failed  :", m_tcfcounter, cast(double)(m_tcfcounter*100)/m_tccounter); 
     496        renderer.render(hl); 
     497        renderer.render(empty); 
     498        renderer.render(empty); 
     499        renderer.render(empty); 
    453500 
    454501    } 
     
    485532 
    486533    TestSuite width(uint w) { 
    487         table.m_width = w; 
     534        renderer.m_width = w; 
    488535        return this; 
    489536    } 
     
    494541     **************************************************************************/ 
    495542    this() { 
    496         table = new Table
     543        renderer = new Renderer
    497544 
    498545        title   = [Sep, Cell(-1, Align.Center), Sep]; 
     
    504551        fail    = [Sep, Cell(5, Align.Right, "%d."), Cell(-1, Align.Left), Sep]; 
    505552        hl      = [Hl]; 
     553        empty   = [Empty]; 
    506554 
    507555    } 
     
    538586        } 
    539587 
    540         if (m_firstingroup) {table.render(hl); m_firstingroup=false;} 
     588        if (m_firstingroup) {renderer.render(hl); m_firstingroup=false;} 
    541589        m_testcases~=tc; 
    542590        m_curcase = tc; 
     
    544592    } 
    545593 
    546     Table table
    547     Row title, tc, tc_tim, simple, etime, stat, fail, hl
     594    Renderer renderer
     595    Row title, tc, tc_tim, simple, etime, stat, fail, hl, empty
    548596 
    549597    void delegate() m_setup; 
     
    600648//------------------------------------------------------------------------------ 
    601649 
    602 bool isNan(real x) { 
    603     if (x is real.nan) return true; 
    604     return false; 
    605 } 
    606  
    607650bool compareFloats(T)(T first, T second) { 
    608651    trace(first, "  ??  ", second); 
    609     if (isNan(first) || isNaN(second)) { 
     652    if (isNaN(first) || isNaN(second)) { 
    610653        return isNaN(first) && isNaN(second); 
    611654    } 
     
    664707} 
    665708 
    666 //TODO: add printouts -- always visible 
    667 //TODO: add versions without file and line 
     709//TODO: add printouts -- always visible (similary as traces) 
    668710//TODO: unit testy tylko w wersji debug 
    669711//TODO: funkcja porównujĠ
  • trunk/doost/util/serializer/Registry.d

    r31 r32  
    155155        /*********************************************************************** 
    156156         **********************************************************************/ 
    157         typeof(this) dup_staticinfo(){ 
     157        typeof(this) dup_info(){ 
    158158            typeof(this) result; 
    159159            static if (is(typeof(this) == class)) 
     
    178178 ******************************************************************************/ 
    179179interface Registration { 
    180     Registration dup_staticinfo(); 
     180    Registration dup_info(); 
    181181} 
    182182 
     
    185185class Registry { 
    186186public: 
    187     Registry dup_staticinfo() { 
     187    Registry dup_info() { 
    188188        auto result = new Registry; 
    189189        foreach(key, value; registry) 
    190             result.registry[key] = value.dup_staticinfo; 
     190            result.registry[key] = value.dup_info; 
    191191        return result; 
    192192    } 
  • trunk/doost/util/serializer/Serializer.d

    r31 r32  
    1616module doost.util.serializer.Serializer; 
    1717 
    18 import std.traits; 
    19  
    2018import doost.api.Common; 
    2119import doost.core.Traits; 
     
    2725 ******************************************************************************/ 
    2826template Serializable() { 
    29     import std.string; 
    3027    void describeUdt(T)(T arch) { 
    3128        foreach(i, v; this.tupleof) 
     
    8784private: 
    8885    const info = "Type '" ~ STORAGE.stringof ~ "' does not meet Storage requirements: "; 
    89     static assert(is(typeof(STORAGE.init) == STORAGE), info ~ "lack of init() method."); 
    90     static assert(is(typeof(STORAGE.dup) == STORAGE), info ~ "lack of dup() method."); 
     86    //static assert(is(typeof(STORAGE.init) == STORAGE), info ~ "lack of init() method."); 
     87    //static assert(is(typeof(STORAGE.dup) == STORAGE), info ~ "lack of dup() method."); 
    9188 
    9289    enum Mode {LOAD, DUMP} 
     90    alias elementType!(STORAGE)[] STORAGETYPE; 
     91 
    9392    mixin CONCRETEARCHIVE!(Archive); 
    9493 
     
    112111     **************************************************************************/ 
    113112    Archive archive() { 
    114         return m_archive.dup_staticinfo; 
     113        return m_archive.dup_info; 
    115114    } 
    116115 
     
    119118     **************************************************************************/ 
    120119    void archive(Archive arch) { 
    121         m_archive = arch.dup_staticinfo; 
     120        m_archive = arch.dup_info; 
    122121    } 
    123122 
     
    140139        normalizedType!(T) value = v; 
    141140 
    142         if (archive is null) archive = m_archive.dup_staticinfo; 
    143             else archive = archive.dup_staticinfo; 
     141        if (archive is null) archive = m_archive.dup_info; 
     142            else archive = archive.dup_info; 
    144143 
    145144        archive.mode = Mode.DUMP; 
     
    170169    VALUE load(VALUE)(STORAGE storage, Archive archive = null) { 
    171170        //TODO: static asserts in serializer --> check if all template functions exists in Archive 
    172         //TODO: czy tu storage nie powinno być duplikowane??? storage.dup 
    173  
    174         if (archive is null) archive = m_archive.dup_staticinfo; 
    175             else archive = archive.dup_staticinfo; 
     171 
     172        if (archive is null) archive = m_archive.dup_info; 
     173            else archive = archive.dup_info; 
    176174 
    177175        archive.mode = Mode.LOAD; 
     
    192190    /*************************************************************************** 
    193191     **************************************************************************/ 
    194     bool traverse(VALUE)(ref VALUE value, ref Archive archive) { 
     192    bool traverse(VALUE)(ref VALUE value, Archive archive) { 
    195193        static if (!is(VALUE TYPE == typedef)) { 
    196194            //level is not increased for typedefs 
     
    199197        } 
    200198 
    201         pragma(msg, "Type: " ~ VALUE.stringof); 
     199        pragma(msg, "Type: " ~ VALUE.stringof ~ " STORAGETYPE: " ~ STORAGETYPE.stringof ~ " STORAGE: " ~ STORAGE.stringof); 
    202200 
    203201        //Eventual additional operations ... at begining of traverse... 
     
    221219        //BUG: Trick with delegate doesn't work here. Why? 
    222220        //compile time extension function for parsing 
     221        //Below line is for debuging; change 0 to 1 
     222        static if (0 && CONCRETEARCHIVE.stringof == "JsonArchiveExt(ARCHIVE)" && VALUE.stringof =="Date") return extend!(VALUE)(value, archive); 
    223223        static if (is(typeof(extend!(VALUE)(value, archive)) == bool)) { 
    224224            return extend!(VALUE)(value, archive); 
     
    269269            return true; 
    270270        } else 
    271         //Bools 
    272         static if(is (VALUE == bool)) { 
     271        static if (is(VALUE == bool)) { 
    273272            if (archive.mode == Mode.LOAD) return loadBool(value, archive); 
    274273                else return dumpBool(value, archive); 
    275274        } else 
    276         //Other built-in types 
    277         //TODO: rozbić isAtomic na Integral i Floating i Char 
    278         static if (isAtomic!(VALUE)) { 
    279             if (archive.mode == Mode.LOAD) return loadAtomic(value, archive); 
    280                 else return dumpAtomic(value, archive); 
    281         } else { 
     275        static if (isNumber!(VALUE)) { 
     276            if (archive.mode == Mode.LOAD) return loadNumber(value, archive); 
     277                else return dumpNumber(value, archive); 
     278        } else 
     279        static if (isChar!(VALUE)) { 
     280            if (archive.mode == Mode.LOAD) return loadChar(value, archive); 
     281                else return dumpChar(value, archive); 
     282        } else 
     283        { 
    282284            static assert(false, "Unsupported type '" ~ VALUE.stringof ~ 
    283285            "'. Types like void*, union, enum are not serializable without additional information"); 
     
    287289    } 
    288290 
    289     //TODO: move checking for version and functions inside user UDT into 
    290     //serializer from Archive. How? 
    291  
    292     /*************************************************************************** 
    293      **************************************************************************/ 
    294     bool attendFields(VALUE)(ref VALUE value, Archive archive) { 
     291    /*************************************************************************** 
     292        Returns: true if ok 
     293     **************************************************************************/ 
     294    bool processMemberStruct(VALUE)(ref VALUE value, Archive archive) { 
     295        uint defined_ver = 0; 
     296        static if (is(typeof((cast(VALUE)value).versionUdt) == uint)) { 
     297            defined_ver = (cast(VALUE)value).versionUdt; 
     298        } 
     299 
     300        auto reg = archive.registry.peek!(TypeDescription, VALUE); 
     301        if (reg !is null && reg.ver > 0) defined_ver = reg.ver; 
     302 
     303        if (archive.mode == Mode.LOAD) { 
     304            uint stored_ver; 
     305            bool loaded=false; 
     306            auto verloaded = loadVersion(stored_ver, archive); 
     307            assert((verloaded == true && stored_ver != 0) || verloaded == false, "For unversioned classes you should not use version specifier!"); 
     308 
     309            if (stored_ver > 0) { 
     310                if (stored_ver != defined_ver && defined_ver>0) { 
     311                    static if ( is(typeof(&value.transform!(Archive)) == void delegate(ref VALUE, Archive, uint))) { 
     312                        value.transform(value, archive, stored_ver); 
     313                        loaded = true; 
     314                    } else { 
     315                        throw new SerializerException("Udt version in storage is different than in program"); 
     316                    } 
     317                } 
     318            } 
     319 
     320            if (!loaded) loadFields(value, archive); 
     321 
     322        } else { 
     323            if (!dumpVersion(defined_ver, archive)) 
     324                throw new SerializerException("Can not dump version."); 
     325 
     326            dumpFields(value, archive); 
     327        } 
     328        return true; 
     329    } 
     330 
     331    /*************************************************************************** 
     332     **************************************************************************/ 
     333    bool processMemberStructFields(VALUE)(ref VALUE value, Archive archive) { 
    295334        //Load function exists 
     335 
    296336        static if ( is(typeof(&value.loadUdt!(Archive)) == void delegate(Archive))) { 
    297337            if (archive.mode == Mode.LOAD) {value.loadUdt(archive); return true;} 
    298         } 
     338        } else alias bool notExistsLoad; 
    299339        //Dump function exists 
    300340        static if ( is(typeof(&value.dumpUdt!(Archive)) == void delegate(Archive))) { 
    301341            if (archive.mode == Mode.DUMP) {value.dumpUdt(archive); return true;} 
    302         } 
    303         //TODO: moÅŒna zmniejszyć wielkość funkcji przez sprawdzenie, czy obie powyÅŒsze 
    304         //funkcje udało się zainstancjować. jeÅŒeli tak to poniÅŒsze nie musi być wstawiane 
    305  
    306         //Exists describe function 
    307         static if ( is(typeof(&value.describeUdt!(Archive)) == void delegate(Archive))) { 
    308             value.describeUdt(archive); 
    309         } else 
    310         //All fields are visible 
    311         static if (areUdtFieldsVisible!(VALUE)) { 
    312             foreach(i, v; value.tupleof) { 
    313                 if (archive.mode == Mode.LOAD) { 
    314                     normalizedType!(typeof(v)) elem; 
    315                     loadOneField(elem, value.tupleof[i].stringof, archive); 
    316                     checkType!(typeof(v))(elem); 
    317  
    318                     static if (isStaticArray!(typeof(v))) { 
    319                         foreach(n, saval; value.tupleof[i]) value.tupleof[i][n] = elem[n]; 
     342        } else alias bool notExistsDump; 
     343 
     344 
     345        //BUG: One more place where it would be much better to have alias defining 
     346        //compile time constants 
     347        //or enum bool notExistsLoad = true; will work? 
     348        static if (is(notExistsLoad == bool) || is(notExistsDump == bool)) { 
     349            //Exists describe function 
     350            static if ( is(typeof(&value.describeUdt!(Archive)) == void delegate(Archive))) { 
     351                value.describeUdt(archive); 
     352            } else 
     353            //All fields are visible 
     354            static if (areUdtFieldsVisible!(VALUE)) { 
     355                foreach(i, v; value.tupleof) { 
     356                    if (archive.mode == Mode.LOAD) { 
     357                        normalizedType!(typeof(v)) elem; 
     358                        loadOneField(elem, value.tupleof[i].stringof, archive); 
     359                        checkType!(typeof(v))(elem); 
     360 
     361                        static if (isStaticArray!(typeof(v))) { 
     362                            foreach(n, saval; value.tupleof[i]) value.tupleof[i][n] = elem[n]; 
     363                        } else { 
     364                            value.tupleof[i]= elem; 
     365                        } 
     366 
    320367                    } else { 
    321                         value.tupleof[i]= elem; 
     368                        normalizedType!(typeof(v)) elem = v; 
     369                        dumpOneField(elem, value.tupleof[i].stringof, archive); 
    322370                    } 
    323  
    324                 } else { 
    325                     normalizedType!(typeof(v)) elem = v; 
    326                     dumpOneField(elem, value.tupleof[i].stringof, archive); 
    327371                } 
     372            } else { 
     373                //FIXME: 
     374                static assert(false, "UDT '" ~ VALUE.stringof ~ "' is not serializable."); 
    328375            } 
    329         } else { 
    330             //FIXME: 
    331             static assert(false, "UDT '" ~ VALUE.stringof ~ "' is not serializable."); 
    332376        } 
    333377 
    334378        return true; 
    335379    } 
    336  
    337  
    338     /*************************************************************************** 
    339         Returns: true if class was imported by this function 
    340      **************************************************************************/ 
    341     bool attendVersion(VALUE)(ref VALUE value, Archive archive, uint stored_ver) { 
    342         if (stored_ver > 0) { 
    343             uint defined_ver = 0; 
    344             //more important is version in registry; it allows to override 
    345             //mistakenly defined versions in classes... 
    346             static if (is(typeof((cast(VALUE)value).versionUdt) == uint)) { 
    347                 defined_ver = (cast(VALUE)value).versionUdt; 
    348             } 
    349             if (auto peek = archive.registry.peek!(TypeDescription, VALUE)) { 
    350                 uint ver = peek.ver; 
    351                 if (ver>0) defined_ver = ver; 
    352             } 
    353             if (stored_ver != defined_ver && defined_ver>0) { 
    354                 static if ( is(typeof(&value.importUdt!(Archive)) == void delegate(ref VALUE, Archive, uint))) { 
    355                     //FIXME: przy imporcie pola nie będÄ 
    356  zparsowane??? (JSON) 
    357                     value.importUdt(value, archive, stored_ver); 
    358                     return true; 
    359                 } else { 
    360                     throw new SerializerException("Udt version in storage is different than in program"); 
    361                 } 
    362             } 
    363         } 
    364         return false; 
    365     } 
    366  
    367380 
    368381//------------------------------------------------------------------------------ 
     
    373386        private: 
    374387        //BUG: private attribute is not applied to template functions 
    375  
    376         //Bug - jak sprawdzić czy poniÅŒsze jest zdefiniowane? 
     388        //BUG: how to check if ArchiveExt is defined? 
    377389        mixin ArchiveExt; 
    378390 
     
    384396        Registry registry; 
    385397 
    386         Archive dup_staticinfo() { 
    387             static if(is(typeof(dup_staticinfoext) == Archive)) { 
    388                 auto result = dup_staticinfoext; 
     398        Archive dup_info() { 
     399            static if(is(typeof(dup_infoext) == Archive)) { 
     400                auto result = dup_infoext; 
    389401            } else auto result = new Archive; 
    390402 
    391403            result.storage = STORAGE.init; 
    392404            result.tracking = tracking; 
    393             result.registry = registry.dup_staticinfo; 
    394  
    395             result.level = 0
    396             result.mode = Mode.DUMP
     405            result.registry = registry.dup_info; 
     406 
     407            result.level = level
     408            result.mode = mode
    397409 
    398410            return result; 
     
    405417        /*********************************************************************** 
    406418         **********************************************************************/ 
    407         void describe(TYPE)(ref TYPE variable, string name="") { 
     419        void describe(TYPE)(ref TYPE variable, string name) { 
    408420            bool result; 
    409421            //writefln("NAME: ", name, " TYPE: ", TYPE.stringof); 
     
    423435        /*********************************************************************** 
    424436         **********************************************************************/ 
    425         void describeStaticArray(T)(T variable, string name="") { 
     437        void describeStaticArray(T)(T variable, string name) { 
    426438            normalizedType!(T) var = variable; 
    427439            describe(var, name); 
     
    437449        /*********************************************************************** 
    438450         **********************************************************************/ 
    439         void importUdt(T)(ref T variable) { 
     451        void transform(T)(ref T variable) { 
    440452            //BUG:This form fails - implicit form doesn't 
    441453            //if (!traverse!(T)(variable, this)) 
  • trunk/doost/util/serializer/archive/JSONArchive.d

    r31 r32  
    1414 ******************************************************************************/ 
    1515 
    16 module doost.util.serializer.JSONArchive; 
     16module doost.util.serializer.JsonArchive; 
    1717 
    1818//------------------------------------------------------------------------------ 
    1919 
    20 template JSONArchive(ARCHIVE) { 
     20/******************************************************************************* 
     21    This is JSON format archive for serializer. 
     22 
     23    Internal policy for returning bool from loaders/dumpers: 
     24    1. true - value was properly loaded/dumped 
     25    2. exception - loading of value was not succesfull (token not found or found 
     26       but is wrongly formatted) 
     27 
     28 ******************************************************************************/ 
     29 
     30template JsonArchive(ARCHIVE) { 
    2131private: 
    2232    //Static functions and definitions 
    2333 
    2434    import std2.conv; 
    25     import std2.string : munch; 
    2635    import std.regexp; 
    2736    import std.typetuple; 
     
    3039    import doost.util.serializer.Registry; 
    3140    import doost.text.Escaper; 
    32  
    33     /******************************************************************************* 
    34      ******************************************************************************/ 
    35     static struct Result(VALUE) { 
    36         bool matched; 
    37         VALUE value; 
    38     } 
     41    import doost.text.Tokenizer; 
    3942 
    4043    /******************************************************************************* 
     
    8992    mixin(generator("Pattern(T)", ["pattern", ""])); 
    9093 
    91     mixin(generator("Skip", [ 
    92                             "skip", " \t\r\n", 
    93                             "space", " ", 
    94                             "newline", "\n", 
    95                             "indent", "    " 
    96                             ])); 
    97     mixin(generator("Array", ["p_begin", r"\[", "p_separator", r",", "p_end", r"\]", "begin", "[", "s_separator", ", ", "s_end", r"]"])); 
    98     mixin(generator("String", ["p_delim", "\"'", "p_content", "\\\"|\\'|\\t|\\r|\\n|\\v|\\f", "p_idcontent", "a-zA-Z0-9_", "s_begin", "\"", "s_end", "\""])); 
     94//    mixin(generator("Skip", [ 
     95//                            "skip", " \t\r\n", 
     96//                            "space", " ", 
     97//                            "newline", "\n", 
     98//                            "indent", "    " 
     99//                            ])); 
     100 
     101    static struct Skip { 
     102 
     103        static public string space = " "; 
     104        static public string newline = "\n"; 
     105        static public string indent = "    "; 
     106 
     107        static public string skip() { 
     108            return m_skip; 
     109        } 
     110 
     111        static public void skip(string s) { 
     112            m_skip = s; 
     113        } 
     114 
     115        static public CharClass!(char) skip_cc() { 
     116            if (m_skip_cc.empty) return m_skip_cc.whitespace; 
     117            return m_skip_cc; 
     118        } 
     119 
     120        static private CharClass!(char) m_skip_cc; 
     121        static public string m_skip = " \t\r\n"; 
     122    } 
     123 
     124 
     125    mixin(generator("Array", ["begin", "[", "separator", ",", "end", "]"])); 
     126    mixin(generator("String", ["delim1", "\"", "delim2", "'"])); 
    99127    mixin(generator("Udt", [ 
    100                             "verbegin", "(", 
    101                             "verend", ")", 
    102  
     128                            "ver", "versionUdt", 
    103129                            "begin", "{", 
    104130                            "kvseparator", ":", 
    105  
    106                             "s_kvseparator", r" : ", 
    107  
    108                             "p_separator", ",", 
    109                             "s_separator", ", ", 
    110  
     131                            "separator", ",", 
    111132                            "end", "}" 
    112133                            ])); 
    113134 
    114     mixin(generator("Reference", ["p_null", "null", "p_ref", r"\$", "p_pointer", r"\*", "s_null", "null", "s_ref", "$", "s_pointer", "*"])); 
     135    mixin(generator("Reference", ["p_null", "null", "p_ref", "$", "p_pointer", r"*", "s_null", "null", "s_ref", "$", "s_pointer", "*"])); 
    115136 
    116137    //-------------------------------------------------------------------------- 
     
    118139    template ArchiveExt() { 
    119140        bool mismatch = false; 
    120         STORAGE rest = STORAGE.init; 
     141        STORAGETYPE rest = STORAGETYPE.init; 
    121142        uint indent = 0; 
    122143 
    123         //wersja[nazwa typu] 
    124         uint[STORAGE] versions; 
    125         //zawartość[nazwa typu] 
    126         STORAGE[STORAGE] includedclasses; // all classes which are part of higher level class 
    127144        //zawartość[nazwa pola] 
    128         STORAGE[STORAGE] fields;          //fields of specific class with values; 
    129  
    130         bool[STORAGE] parsed; 
    131  
    132         Archive dup_staticinfoext() { 
     145        STORAGETYPE[STORAGETYPE] memberStructFields;    &