Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*******************************************************************************
- * Authors: $(WEB zoadian.de, Felix 'Zoadian' Hufnagel) /
- * Copyright: $(WEB zoadian.de, Felix 'Zoadian' Hufnagel) /
- ***************************************************************************/
- module zoadge.core.serialize;
- import std.traits;
- import std.typetuple;
- import std.stdio;
- //==========================================================================
- /// noserialize
- enum noserialize;
- //==========================================================================
- /// serialize
- ubyte[] serialize(T)(T t) pure nothrow {
- ubyte[] data;
- static if(isBasicType!T) {
- data ~= *cast(ubyte[T.sizeof]*)&t;
- } else static if(isDynamicArray!T) {
- uint len = t.length; //max length is uint.max
- data ~= *cast(ubyte[len.sizeof]*)&len;
- data ~= cast(ubyte[])t;
- } else static if(isStaticArray!T) {
- auto l = t.length;
- data ~= cast(ubyte[])t;
- } else {
- pragma(msg, "serializing: " ~ T.stringof);
- foreach(M; __traits(allMembers, T)) {
- alias typeof(__traits(getAttributes, __traits(getMember, T, M))) ATR_TYPES;
- //pragma(msg, ATR_TYPES);
- static if(staticIndexOf!(noserialize, ATR_TYPES) == -1) {
- pragma(msg, "\tserializing: " ~ M);
- data ~= serialize(__traits(getMember, t, M));
- }
- }
- }
- return data;
- }
- //==========================================================================
- /// deserialize
- auto deserialize(T)(ubyte[] data, size_t* rSize = null) {
- static if(isBasicType!T) {
- if(rSize !is null) *rSize = T.sizeof;
- return *cast(T*)data.ptr;
- } else static if(isDynamicArray!T) {
- enum TSIZE = ForeachType!(T).sizeof;
- size_t lenInBytes = *cast(uint*)data.ptr * TSIZE;
- enum LSIZE = lenInBytes.sizeof;
- if(rSize !is null) *rSize = LSIZE+lenInBytes;
- return cast(T)data[LSIZE..LSIZE+lenInBytes];
- } else static if(isStaticArray!T) {
- if(rSize !is null) *rSize = T.length * ForeachType!(T).sizeof;
- return (cast(ForeachType!(T)*)data.ptr)[0 .. T.length];
- } else {
- T t;
- size_t tlen = 0;
- pragma(msg, "deserializing: " ~ T.stringof);
- foreach(M; __traits(allMembers, T)) {
- alias typeof(__traits(getAttributes, __traits(getMember, T, M))) ATR_TYPES;
- //pragma(msg, ATR_TYPES);
- static if(staticIndexOf!(noserialize, ATR_TYPES) == -1) {
- pragma(msg, "\tdeserializing: " ~ typeof(__traits(getMember, t, M)).stringof);
- size_t len = 0;
- __traits(getMember, t, M) = deserialize!(typeof(__traits(getMember, t, M)))(data, &len);
- data = data[len..$];
- tlen += len;
- }
- }
- if(rSize !is null) *rSize = tlen;
- return t;
- }
- assert(0);
- }
- unittest
- {
- assert(deserialize!string([5,0,0,0,104,97,108,108,111]) == "hallo");
- assert("hallo".serialize().deserialize!string() == "hallo");
- assert(deserialize!int([42,0,0,0]) == 42);
- assert(deserialize!(short[])([4,0,0,0,42,0,32,0,42,0,32,0]) == [42,32,42,32]);
- assert(deserialize!(short[4])([42,0,32,0,42,0,32,0]) == cast(short[4])[42,32,42,32]);
- assert(serialize(cast(byte)42) == [42]);
- assert(serialize(cast(short)42) == [42,0]);
- assert(serialize(cast(int)42) == [42,0,0,0]);
- assert(serialize(cast(long)42) == [42,0,0,0,0,0,0,0]);
- assert(serialize(cast(float)42.42) == [20,174,41,66]);
- assert(serialize(cast(double)42.42) == [246,40,92,143,194,53,69,64]);
- struct ASFG
- {
- int c = 42;
- }
- struct ASF
- {
- byte a = 42;
- short b = 42;
- ASFG df;
- @noserialize int h = 42;
- long d = 42;
- float e = 42.42;
- double f = 42.42;
- int[2] arr = [32,23];
- //string sadsd = "asdf"; //works but we can not use == to compare the struct later. -> TODO: write opEquals...
- }
- ASF asf;
- asf.serialize().writeln();
- asf.serialize().deserialize!(ASF).writeln();
- asf.writeln();
- assert(asf.serialize().deserialize!(ASF) == asf);
- }
Advertisement
Add Comment
Please, Sign In to add comment