Dargon.PortableObjects is an open-source serialization library for the .net ecosystem released under Version 3 of the GNU Public License and maintained by The Dargon Project developer ItzWarty.
We don't often use Dargon.PortableObjects's serializer directly - check out Dargon.PortableObject.Streams, Dargon.Courier, and Dargon.Services for useful wrappers around Dargon.PortableObjects.
Dargon.PortableObjects is released as a NuGet package via the Dargon Package Source.
- Add
https://nuget.dargon.io/as a NuGet package source. - Run
Install-Package Dargon.PortableObjectsfrom the package management console.
For now, all serializable objects must be common .net types (simple value types, strings, collections, dictionaries, datetimes, timespans, guids) or implementers of IPortableObject.
To exemplify, imagine this hypothetical joystick state data-transfer-object that might be sent across the wire to a remotely controlled device:
public class JoystickStateDto : IPortableObject {
public JoystickStateDto() { }
public JoystickStateDto(int x, int y) { X = x; Y = y; }
public int X { get; set; }
public int Y { get; set; }
public void Serialize(IPofWriter writer) {
writer.WriteS32(0, X);
writer.WriteS32(1, Y);
}
public void Deserialize(IPofReader reader) {
X = reader.readS32(0);
Y = reader.readS32(1);
}
}In the future, we'll support external serializers and this syntax:
[Autoserializable]
public class JoystickStateDto : IPortableObject {
public JoystickStateDto() { }
public JoystickStateDto(int x, int y) { X = x; Y = y; }
public int X { get; set; }
public int Y { get; set; }
}Note the required empty constructor - this is required by us so that we can instantiate instances of the portable type!
You register your portable object types in POF Contexts!
public class CustomPofContext : PofContext {
private int kBasePofId = {number};
public CustomPofContext() {
RegisterPortableObjectType(kBasePofId, typeof(JoystickStateDto));
// alternatively!
RegisterPortableObjectType(kBasePofId, () => new JoystickStateDto([.. dependencies]));
}
}You can combine many POF Contexts into one as follows:
new PofContext().With(x => {
x.MergeContext(new CustomPofContext1());
x.MergeContext(new CustomPofContext2());
});And you can serialize/deserialize objects with the POF Serializer as follows:
pofSerializer = new PofSerializer(pofContext);
using (var ms = new MemoryStream()) {
pofSerializer.Serialize(ms, joystickState);
ms.Position = 0;
var joystickState = pofSerializer.Deserialize<JoystickStateDto>(ms);
// alternatively:
ms.Position = 0;
object something = pofSerializer.Deserialize(ms);
}When serializing a CustomClass<T1, T2>, the POF Serializer writes data 'frames' as follows:
struct pof_frame {
int length; // e.g. 132
pof_type[] type; // e.g. { CustomClass<,>, T1, T2 }
pof_slot[] slots;
}pof_type values are essentially your registered types.
Pof slots look as follows:
struct pof_slot {
int slot_count;
int[] slot_lengths;
byte[][] slot_datas;
}