(De)Serializing interfaces

Rikki Cattermole via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Sun Aug 23 03:37:10 PDT 2015


On 8/23/2015 10:17 PM, nims wrote:
> On Sunday, 23 August 2015 at 08:38:14 UTC, Rikki Cattermole wrote:
>> What I was thinking was having a serialize method take an output range
>> which you will just pass in a value.
> I'm not really sure what you mean. Replacing the operator by a range
> function or serializing everything automatically?

Oh not quite. Humm, how to explain this.

import std.traits : isBasicType, isArray;

interface Serializable {
	void serialize(OutputRange!ubyte);
	void deserialize(InputRange!ubyte);

	final void putValue(T)(OutputRange!ubyte output, ref T value) {
		static if (isArray!T) {
			putValue(output, value.length);
			foreach(v; value)
				putValue(v);
		} else static if (isBasicType!T) {
			// convert to ubytes ext. ext. and call put on output.
		} else if (Serializable sv = cast(Serializable)value) {
			sv.serialize(output);
		} else {
			static assert(0, "I don't know how to handle this");
		}
	}

	final T getValue(T)(InputRange!ubyte input) {
		ubyte[T.sizeof] ret;
		foreach(i; 0 .. T.sizeof)
			ret[i] = input.moveFront;
		return to!T(ret);
	}
}

class ... : Serializable {
	int x, y;
	float z;

	void serialize(OutputRange!ubyte output) {
		output.putValue(x);
		output.putValue(y);
		output.putValue(z);
     	}

	void deserialize(InputRange!ubyte input) {
		x = input.getValue!int;
		y = input.getValue!int;
		z = input.getValue!float;
	}
}

>> A hash? Yeah, TypeInfo_Class should. It will take a pointer.
>> https://github.com/D-Programming-Language/druntime/blob/master/src/object.d#L261
>>
>>
>> size_t hash = typeid(avalue).getHash(&avalue);
>>
>> But keep in mind avalue must be an rvalue.
> Sounds good! How do I then create an instance having the same type?

The hash value won't help you much really. It's meant for comparing 
instances.

>> My suggestion would be evaluate the type "down" aka get
>> immutable(char) from immutable(char)[] aka string. So don't try to
>> serialize the string straight. Grab the length put that to the output
>> range, then try to serialize each of the values of the array
>> individually as another function call to itself.
>>
>> Same sort of deal with other classes, check that they have the
>> interface and if so, call it's serialize method with yourself.
>>
>> A little confusing I must admit.
> I'm sorry I didn't get that. Would you have a piece of code for
> illustration?

Take a look at the top code snippet.
You will probably want a couple of free functions be the function you 
call to serialize and deserialize. That way it can control embedding 
e.g. the class name as the first set of values. Which is trivial to use 
with the help of e.g. Object.factory or with the help of TypeInfo.init.

On that note I'll see about getting you a snippet of code that may 
interest you here.
If you can please come on[0] to make it slightly easier for me.

[0] https://gitter.im/rikkimax/chatWithMe



More information about the Digitalmars-d-learn mailing list