/// <summary> /// Takes an object, serializes it and writes its byte data into the given data object. /// How the byte data looks like depends on the object given: /// if obj is null: /// a single byte equal to ChunkType.NULL /// if the obj was already written to the serialization data before: /// a single byte equal to ChunkType.ID_REF /// 2 bytes containing the objects ID. The ID is read from the objToID map in data /// if the type of the obj is not known: /// a single byte equal to ChunkType.ID_REF /// 3 bytes equal to UNKNOWN_TYPE_ID /// if the type of the obj is a primitive type: /// a single byte equal to ChunkType.PRIMITIVE /// 3 bytes with the type-ID of the primitive /// the serializer for the primitives type will be used to write all following bytes /// if the type of the obj is a known non-primitive type: /// a single byte equal to ChunkType.NEW_REF /// 3 bytes with the type-ID of the object /// the ref-ID of the object will not be written. It is determined /// deterministically from the order of writes / reads. /// the serializer for the objects type will be used to write all following bytes /// /// Attempting to write an object for which no serializer is known will result in an /// error being written to the internal error buffer. /// For more information on the error handling process refer to the documentation of /// GetErrorBuffer(). /// </summary> /// <param name="data">The serialized data used during this serialization process.</param> /// <param name="obj">The object to serialize.</param> public static void Serialize(SerializationData data, object obj) { if (obj == null) { // only write a single byte data.WriteChunkType(ChunkType.NULL); return; } short objID; bool hasID = data.objToID.TryGetValue(obj, out objID); // whether or not the same object was written before to the same data instance if (hasID) { // only write 3 bytes data.WriteChunkType(ChunkType.ID_REF); data.WriteInt2B(objID); return; } Type type = obj.GetType(); Serializer ser; bool isKnownType = typeMap.TryGetValue(type, out ser); // whether or not a known serializer exists for the given object type if (!isKnownType) { // only write 4 bytes data.WriteChunkType(ChunkType.NEW_REF); data.WriteInt3B(UNKNOWN_TYPE_ID); errBuffer.Add(new ErrorSerializeUnknownType(obj)); return; } // whether the data is a primitive (int, float, double, boolean, etc) if (ser.IsPrimitive()) { // primitives write at least 4 bytes, this is the first data.WriteChunkType(ChunkType.PRIMITIVE); } else { // this will register this object as being written to the given data // for the first time. If written to this data again in the future the // object will be serialized with less space requirements. data.RegisterObject(obj); // non-primitives write at least 4 bytes, this is the first data.WriteChunkType(ChunkType.NEW_REF); } // writes the 3 byte type-ID of the object as returned by GetTypeID(object) data.WriteInt3B(ser.id); // delegates further serialization to the serializer registered for the objects type ser.WriteBytes(data, obj); }