コード例 #1
0
    /// <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);
    }