Changeset 591

Show
Ignore:
Timestamp:
06/11/09 03:30:07 (3 years ago)
Author:
BCS
Message:

Added support for 3rd party types and arrays

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/Serial/Common.d

    r587 r591  
    33public import Interface; 
    44public import Demarshal; 
    5 public import Common
     5import State
    66 
    77alias Object function(Source!(char) source, ref OutMap) Factory; 
    88Factory[char[]] Factories; 
     9 
     10template NativeBaseType(T) 
     11{ 
     12    const bool NativeBaseType = is(T == int) || is(T == uint) || is(T == long) 
     13    || is(T == ulong) || is(T == short) ||is(T == ushort) 
     14    || is(T == byte) || is(T == ubyte) || is(T == float) 
     15    || is(T == double) || is(T == real); 
     16} 
    917 
    1018 
     
    1321    static if(is(typeof(this) == class)) 
    1422    { 
    15         static const char[] StaticTypeTag = typeof(this).stringof; 
     23        static const char[] StaticTypeTag = typeof(this).mangleof; 
    1624         
    1725        bool TypeTag(Sink!(char) sink, ref InMap map) 
  • trunk/Serial/Demarshal.d

    r587 r591  
    22 
    33import std.conv; 
     4import std.stdio; 
    45 
    56import Serialize; 
    67import utill; 
     8import Third; 
    79import XML; 
    8  
    9  
    10 import std.stdio; 
    11 T DemarshalNative(T)(Source!(char) source
     10import State; 
     11 
     12 
     13T DemarshalNative(T)(Source!(char) source, ref OutMap map
    1214{ 
    13     char[] str = ReadContentXML(source); 
    14     if(str == "") throw new Exception("Unexpected end of Source"); 
    15  
    16     char c; 
    17     // eat whitespace. 
    18     outter: for(;;) switch(c = source.Peek()) 
    19         { 
    20         case ' ', '\n', '\r', '\v', '\t': source.Pick(c); break; 
    21         default: break outter; 
    22         } 
    23  
    24     static if(is(T == int))         return toInt(str); 
    25     else static if(is(T == uint))   return toUint(str); 
    26     else static if(is(T == long))   return toLong(str); 
    27     else static if(is(T == ulong))  return toUlong(str); 
    28     else static if(is(T == short))  return toShort(str); 
    29     else static if(is(T == ushort)) return toUshort(str); 
    30     else static if(is(T == byte))   return toByte(str); 
    31     else static if(is(T == ubyte))  return toUbyte(str); 
    32     else static if(is(T == float))  return toFloat(str); 
    33     else static if(is(T == double)) return toDouble(str); 
    34     else static if(is(T == real))   return toReal(str); 
    35     else static assert(false, "Don't known how to Demarshal "~T.stringof); 
    36 
    37  
    38 struct OutMap 
    39 
    40     void*[uint] map; 
    41     bool Hold(uint sn, void* ptr) 
    42     { 
    43         if(sn in map) return false; 
    44         map[sn] = ptr; 
    45         return true; 
    46          
    47     } 
    48     bool Get(uint sn, ref void* ptr) 
    49     { 
    50         if(auto pptr = sn in map) 
    51         { 
    52             ptr = *pptr; 
    53             return true; 
    54         } 
    55         return false; 
     15 
     16    static if(is(T == char[])) 
     17    { 
     18        char[] str = ReadContentXML(source); 
     19        return str; 
     20    } 
     21    else static if(is(T B == B[])) 
     22    { 
     23        T t; 
     24        //writef("reading list of "~B.stringof~"\n"); 
     25        if(source.Pick("null",false)) 
     26        { 
     27            //writef("Found empty\n"); 
     28            t.length = 0; 
     29        } 
     30        else 
     31        { 
     32            //writef("Found non empty\n"); 
     33            t.length = 16; 
     34            int at = 0; 
     35            static if(NativeBaseType!(B)) 
     36            { 
     37                do 
     38                { 
     39                    if(at >= t.length) t.length = 2*at; 
     40                    //writef("."); 
     41                    t[at++] = DemarshalNative!(B)(source,map); 
     42                    //writef(".\n"); 
     43                }while(source.Pick(",",false)); 
     44            } 
     45            else 
     46            { 
     47                const static char[] tag = NameFromType!(B); 
     48                while(source.Peek("<"~tag~">")) 
     49                { 
     50                    if(at >= t.length) t.length = 2*at; 
     51                    D!(tag,B)(source,t[at],map); 
     52                    at++; 
     53                } 
     54            } 
     55            t.length = at; 
     56        } 
     57        return t; 
     58    } 
     59    else  
     60    { 
     61        char[] str = ReadContentXML!("<,")(source); 
     62        if(str == "") throw new Exception("Unexpected end of Source while looking for '"~T.stringof~"'"); 
     63     
     64        static if(is(T == int))         return toInt(str); 
     65        else static if(is(T == uint))   return toUint(str); 
     66        else static if(is(T == long))   return toLong(str); 
     67        else static if(is(T == ulong))  return toUlong(str); 
     68        else static if(is(T == short))  return toShort(str); 
     69        else static if(is(T == ushort)) return toUshort(str); 
     70        else static if(is(T == byte))   return toByte(str); 
     71        else static if(is(T == ubyte))  return toUbyte(str); 
     72        else static if(is(T == float))  return toFloat(str); 
     73        else static if(is(T == double)) return toDouble(str); 
     74        else static if(is(T == real))   return toReal(str); 
     75        else static assert(false, "Don't known how to Demarshal "~T.stringof); 
    5676    } 
    5777} 
     
    112132void D(char[] name, V)(Source!(char) source, ref V v, ref OutMap map) 
    113133{ 
    114     static if(is(V == char[])) 
     134    static if(is(typeof(&v.MarshalMe))) 
     135    { 
     136        static if(is(V == class)) 
     137        { 
     138            if(source.Pick("<"~name~">NULL</"~name~">",false)) 
     139            { 
     140                v = null; 
     141            } 
     142            else 
     143            { 
     144                source.Pick("<"~name); 
     145     
     146                static if(is(typeof(typeof(v).CyclicType)) && typeof(v).CyclicType) 
     147                { 
     148                    source.Pick(" ID=\""); 
     149                    char[] ids = XML.ReadContentXML!("\"")(source); 
     150                    source.Pick("\""); 
     151     
     152                    uint id = toUint(ids); 
     153                    void* vp; 
     154                    if(source.Pick("/>",false)) 
     155                    { 
     156                        if(!map.Get(id, vp)) throw new Error("Back ref not found: "~ids); 
     157                        v = cast(typeof(v))vp; 
     158                        return; 
     159                    } 
     160                } 
     161                 
     162     
     163                source.Pick(" type=\""); 
     164                char[] type = XML.ReadContentXML!("\"")(source); 
     165                source.Pick("\">"); 
     166                if(auto fact = type in .Serialize.Factories) 
     167                { 
     168                    v = cast(V)(*fact)(source,map); 
     169                    assert(v !is null, "Invalid type returned by "~type~", expected " ~V.stringof); 
     170                } 
     171                else 
     172                    throw new Error("Unknown derived type "~type); 
     173     
     174                source.Pick("</"~name~">"); 
     175     
     176                static if(is(typeof(typeof(v).CyclicType)) && typeof(v).CyclicType) 
     177                    map.Hold(id,cast(void*)v); 
     178            } 
     179        } 
     180        else static if(is(V == struct)) 
     181        { 
     182            source.Pick("<"~name~">"); 
     183            v = V.DemarshalMe(source, map); 
     184            source.Pick("</"~name~">"); 
     185        } 
     186        else static assert(false, "Internal Error"); 
     187    } 
     188    else static if(is(V == struct) || is(V == class)) 
    115189    { 
    116190        source.Pick("<"~name~">"); 
    117         v = XML.ReadContentXML(source); 
     191        v = ThirdPartyAccess!(V).demarshial(SourceHandle(&map, source)); 
    118192        source.Pick("</"~name~">"); 
    119193    } 
    120     else static if(is(V == class)) 
    121     { 
    122         if(source.Pick("<"~name~">NULL</"~name~">",false)) 
    123         { 
    124             v = null; 
    125         } 
    126         else 
    127         { 
    128             source.Pick("<"~name); 
    129  
    130             static if(is(typeof(typeof(v).CyclicType)) && typeof(v).CyclicType) 
    131             { 
    132                 source.Pick(" ID=\""); 
    133                 char[] ids = XML.ReadContentXML!('\"')(source); 
    134                 source.Pick("\""); 
    135  
    136                 uint id = toUint(ids); 
    137                 void* vp; 
    138                 if(source.Pick("/>",false)) 
    139                 { 
    140                     if(!map.Get(id, vp)) throw new Error("Back ref not found: "~ids); 
    141                     v = cast(typeof(v))vp; 
    142                     return; 
    143                 } 
    144             } 
    145              
    146  
    147             source.Pick(" type=\""); 
    148             char[] type = XML.ReadContentXML!('\"')(source); 
    149             source.Pick("\">"); 
    150             if(auto fact = type in .Serialize.Factories) 
    151             { 
    152                 v = cast(V)(*fact)(source,map); 
    153                 assert(v !is null, "Invalid type returned by "~type~", expected " ~V.stringof); 
    154             } 
    155             else 
    156                 throw new Error("Unknown derived type "~type); 
    157  
    158             source.Pick("</"~name~">"); 
    159  
    160             static if(is(typeof(typeof(v).CyclicType)) && typeof(v).CyclicType) 
    161                 map.Hold(id,cast(void*)v); 
    162         } 
    163     } 
    164     else static if(is(V == struct) || (is(V S == S*) && is(S==struct))) 
     194    else 
    165195    { 
    166196        source.Pick("<"~name~">"); 
    167         v = V.DemarshalMe(source, map); 
     197        v = DemarshalNative!(V)(source,map); 
    168198        source.Pick("</"~name~">"); 
    169199    } 
    170     else 
    171     { 
    172         source.Pick("<"~name~">"); 
    173         v = DemarshalNative!(V)(source); 
    174         source.Pick("</"~name~">"); 
    175     } 
    176200 
    177201} 
  • trunk/Serial/Interface.d

    r587 r591  
    1212    static assert(is(T == char) || is(T == byte)); 
    1313    bool Peek(T t); 
     14    bool Peek(T[] ts); 
    1415    T Peek(); 
    1516    bool Pick(ref T t, bool must = false); 
  • trunk/Serial/Marshal.d

    r587 r591  
    55import Serialize; 
    66import utill; 
     7import Third; 
     8import XML; 
     9public import State; 
    710 
    811char[] TrimType(char[] name) 
     
    1215} 
    1316 
    14 void MarshalNative(T)(Sink!(char) sink, T t
     17void MarshalNative(T)(Sink!(char) sink, T t, ref InMap map
    1518{ 
    16     static if(is(T == int) || is(T == uint) || is(T == long) 
    17             || is(T == ulong) || is(T == short) ||is(T == ushort) 
    18             || is(T == byte) || is(T == ubyte) || is(T == float) 
    19             || is(T == double) || is(T == real)) 
    20         sink.Dump(std.string.format("%s", t)); 
    21     else static assert(false, "Don't known how to Marshal "~T.stringof); 
    22 
    23  
    24 struct InMap 
    25 
    26     uint at = 0; 
    27     uint[void*] map; 
    28      
    29     bool Hold(void* ptr, ref uint sn) 
     19    static if(is(T == char[])) 
    3020    { 
    31         if(auto snp = ptr in map) 
     21        XML.WriteContentXML(sink,t); 
     22    } 
     23    else static if(is(T B == B[])) 
     24    { 
     25        if(t.length == 0) 
    3226        { 
    33             sn = *snp; 
    34             return true; 
     27            sink.Dump("null"); 
    3528        } 
    3629        else 
    3730        { 
    38             sn = at; 
    39             at++; 
    40             map[ptr] = sn; 
    41             return false; 
     31            static if(NativeBaseType!(B)) 
     32            { 
     33                MarshalNative!(B)(sink,t[0],map); 
     34                foreach(b;t[1..$]) 
     35                { 
     36                    sink.Dump(","); 
     37                    MarshalNative!(B)(sink,b,map); 
     38                } 
     39            } 
     40            else 
     41            { 
     42                const static char[] tag = NameFromType!(B); 
     43                foreach(b;t) 
     44                { 
     45                    M!(tag,B)(sink,b,map); 
     46                } 
     47            } 
    4248        } 
    4349    } 
     50    else static if(NativeBaseType!(T)) 
     51        sink.Dump(std.string.format("%s", t)); 
     52    else static assert(false, "Don't known how to Marshal "~T.stringof); 
    4453} 
    4554 
     
    7483void M(char[] name, V)(Sink!(char)sink, V v, ref InMap map) 
    7584{ 
    76     static if(is(V == char[])) 
     85    static if(is(typeof(&v.MarshalMe))) 
    7786    { 
    78         sink.Dump("<"~name~">"); 
    79         XML.WriteContentXML(sink,v); 
    80         sink.Dump("</"~name~">"); 
    81     } 
    82     else static if(is(typeof(v) == class)) 
    83     { 
    84         if(v is null) 
     87        static if(is(V == class)) 
    8588        { 
    86             sink.Dump("<"~name~">NULL</"~name~">"); 
     89            if(v is null) 
     90            { 
     91                sink.Dump("<"~name~">NULL</"~name~">"); 
     92            } 
     93            else 
     94            { 
     95                sink.Dump("<"~name); 
     96                if(v.TypeTag(sink, map)) return; 
     97                sink.Dump("\">"); 
     98                v.MarshalMe(sink,map); 
     99                sink.Dump("</"~name~">"); 
     100            } 
    87101        } 
    88         else 
     102        else static if(is(utill.Usefull!(V).BaseType == struct)) 
    89103        { 
    90             sink.Dump("<"~name); 
    91             if(v.TypeTag(sink, map)) return; 
    92             sink.Dump("\">"); 
     104            sink.Dump("<"~name~">"); 
    93105            v.MarshalMe(sink,map); 
    94106            sink.Dump("</"~name~">"); 
    95107        } 
     108        else static assert(false, "Internal Error"); 
    96109    } 
    97     else static if(is(utill.Usefull!(V).BaseType == struct)) 
     110    else static if(is(V == struct) || is(V == class)) 
    98111    { 
    99112        sink.Dump("<"~name~">"); 
    100         v.MarshalMe(sink,map); 
     113        ThirdPartyAccess!(V).marshial(v,SinkHandle(&map, sink)); 
    101114        sink.Dump("</"~name~">"); 
    102115    } 
     
    104117    { 
    105118        sink.Dump("<"~name~">"); 
    106         MarshalNative!(typeof(v))(sink,v); 
     119        MarshalNative!(typeof(v))(sink,v,map); 
    107120        sink.Dump("</"~name~">"); 
    108121    } 
  • trunk/Serial/XML.d

    r585 r591  
    1212 *     the read data with escaping removed. 
    1313 */ 
    14 char[] ReadContentXML(char term = '<')(Source!(char) source) 
     14char[] ReadContentXML(char[] term = "<")(Source!(char) source) 
    1515{ 
    1616    char[] ret = new char[16]; 
    1717    int i = 0; 
    1818    char t; 
    19     while(!source.Peek(term)) 
     19    while(-1 == std.string.find(term, source.Peek())) 
    2020    { 
    2121        source.Pick(t); 
  • trunk/Serial/test1.d

    r587 r591  
    66import Serialize; 
    77import StringSourceSink; 
     8import Third; 
    89 
    910class CS 
    1011{ 
    1112    mixin SerializableRecuring!(); 
    12  
    1313    int i = 5;  float j = 3.1415926; 
    14  
    15     this(){} 
    16     this(int) { i++; j++; } 
    17  
     14    this(){}    this(int) { i++; j++; } 
    1815    char[] toString() { return format("<%s,%s>", this.tupleof); } 
    1916} 
     
    2219{ 
    2320    mixin SerializableRecuring!(); 
     21    real f = 2.717; 
     22    this(){}    this(int) { f++; super(0); } 
     23    char[] toString() { return format("<%s,%s>", super.toString()[1..$-1], this.tupleof); } 
     24} 
    2425 
    25     real f = 2.717; 
     26/// show arrays 
    2627 
    27     this(){} 
    28     this(int) { f++; super(0); } 
    29  
    30     char[] toString() { return format("<%s,%s>", super.toString()[1..$-1], this.tupleof); } 
     28struct TS 
     29
     30    mixin Serializable!(); 
     31    int ti; 
     32    char[] toString() { return format("<%s>", this.tupleof); } 
    3133} 
    3234 
     
    3436{ 
    3537    mixin Serializable!(); 
     38    int foo; float bar; CS cs; char[] someString; int[][] data; TS[] tdata; 
     39    char[] toString() { return format("<%s,%s,%s,%s,%s,%s>", this.tupleof); } 
     40} 
    3641 
    37     int foo; 
    38     float bar; 
    39     CS cs; 
    40     char[] someString; 
    41  
    42     char[] toString() { return format("<%s,%s,%s,%s>", this.tupleof); } 
    43 
     42/// show aliased references 
    4443 
    4544struct SC 
    4645{ 
    4746    mixin Serializable!(); 
    48     CS a; 
    49     CS b; 
     47    CS a; CS b; 
     48    char[] toString() { return format("<%s,%s>", this.tupleof); } 
     49
     50 
     51/// Show 3rd party types 
     52 
     53struct TPS 
     54
     55    int i = 2; int j = 3; char[] str = "five"; 
     56    char[] toString() { return format("<%s,%s,%s>", this.tupleof);} 
     57
     58 
     59void TPSm(TPS v, SinkHandle h) 
     60
     61    Push!("i", int)(v.i, h);    Push!("j", int)(v.j, h);    Push!("str", char[])(v.str, h); 
     62
     63TPS TPSd(SourceHandle h) 
     64
     65    TPS ret; 
     66    ret.i = Pull!("i", int)(h); ret.j = Pull!("j", int)(h); ret.str = Pull!("str", char[])(h); 
     67    return ret; 
     68
     69mixin WorkWith!(TPS, TPSm, TPSd); 
     70 
     71struct ST 
     72
     73    mixin Serializable!(); 
     74    char[] name = "some text to test";  TPS a = TPS(3, 5, "eight"); 
    5075    char[] toString() { return format("<%s,%s>", this.tupleof); } 
    5176} 
     
    5378void main() 
    5479{ 
    55     SS ss = SS(42, 2.717, null, "<weee!'\"&>"); 
     80    SS ss = SS(42, 2.717, null, "<weee!'\"&>", [[cast(int)6,9,42][],[cast(int)6,9,54]], [TS(3),TS(1)]); 
    5681    SC sc; 
    5782    Si c; 
     83    ST st; 
    5884 
    5985    ss.cs = null;       c = new Si(); 
     
    6894    c = new Si();    
    6995    (new DS(1)).Serialize(c);   writef("%s\n\t%s\n", c.get, CS.Deserialize(new So(c.get))); 
    70                  
    71      
     96 
     97    st.name = "somthing to expect"; c = new Si(); 
     98    st.Serialize(c); writef("%s\n\t%s\n", c.get, ST.Deserialize(new So(c.get))); 
     99 
    72100    sc.a = new CS(1);   sc.b = new CS(1);   c = new Si();   sc.Serialize(c); 
    73101    auto same = SC.Deserialize(new So(c.get)); 
  • trunk/Serial/utill.d

    r586 r591  
    11module utill; 
    22 
     3template ArrayDepth(T) 
     4{ 
     5    static if(is(T B == B[])) 
     6        const int ArrayDepth = 1 + ArrayDepth!(B); 
     7    else 
     8        const int ArrayDepth = 0; 
     9} 
     10 
     11static assert(0 == ArrayDepth!(int)); 
     12static assert(1 == ArrayDepth!(int[])); 
     13static assert(2 == ArrayDepth!(int[][])); 
     14 
     15 
     16 
     17template NameFromType(T, char[] suffix) 
     18{ 
     19    static if(is(T B == B[])) const char[] NameFromType = NameFromType!(B, "A" ~ suffix); 
     20    else static if(is(T B == B*)) const char[] NameFromType = NameFromType!(B, "P" ~ suffix); 
     21    else const char[] NameFromType = suffix == "" ? T.stringof : T.stringof ~ "-" ~ suffix; 
     22} 
     23 
     24template NameFromType(T) 
     25{ 
     26    const char[] NameFromType = NameFromType!(T,""); 
     27} 
     28 
     29pragma(msg, NameFromType!(int)); 
     30pragma(msg, NameFromType!(int[])); 
     31pragma(msg, NameFromType!(int[][])); 
     32pragma(msg, NameFromType!(int*[])); 
    333 
    434template Usefull(T) 
    535{ 
    6     static if(is(T U == U*))  
     36    static if(is(T== struct)) 
     37        alias T BaseType; 
     38    else static if(is(T U == U*))  
    739    { 
    840        static if(is(U == struct))