public static void WriteTypeCodeIfTrue(this Protocol16Stream output, Protocol16Type type, bool writeTypeCode)
 {
     if (writeTypeCode)
     {
         output.WriteByte((byte)type);
     }
 }
Ejemplo n.º 2
0
 private static void SerializeDictionaryHeader(Protocol16Stream output, Type dictionaryType, out bool writeKeyCode, out bool writeValueCode)
 {
     Type[] genericArguments = dictionaryType.GetGenericArguments();
     writeKeyCode   = (genericArguments[0] == typeof(object));
     writeValueCode = (genericArguments[1] == typeof(object));
     if (writeKeyCode)
     {
         output.WriteTypeCodeIfTrue(Protocol16Type.Unknown, true);
     }
     else
     {
         Protocol16Type typeOfKey = TypeCodeToProtocol16Type(genericArguments[0]);
         if (typeOfKey == Protocol16Type.Unknown || typeOfKey == Protocol16Type.Dictionary)
         {
             throw new Exception("Unexpected - cannot serialize Dictionary with key type: " + genericArguments[0]);
         }
         output.WriteTypeCodeIfTrue(typeOfKey, true);
     }
     if (writeValueCode)
     {
         output.WriteTypeCodeIfTrue(Protocol16Type.Unknown, true);
     }
     else
     {
         Protocol16Type typeOfValue = TypeCodeToProtocol16Type(genericArguments[1]);
         if (typeOfValue == Protocol16Type.Unknown)
         {
             throw new Exception("Unexpected - cannot serialize Dictionary with value type: " + genericArguments[0]);
         }
         output.WriteTypeCodeIfTrue(typeOfValue, true);
         if (typeOfValue == Protocol16Type.Dictionary)
         {
             throw new Exception("TODO: Nested Dictionaries");
         }
     }
 }
Ejemplo n.º 3
0
        private static void SerializeArrayWithSameElements(Protocol16Stream output, Array array, bool writeTypeCode)
        {
            if (array.Length > short.MaxValue)
            {
                throw new NotSupportedException($"Arrays can only have a maximum size of {short.MaxValue} (short.MaxValue). Yours is: {array.Length}");
            }
            output.WriteTypeCodeIfTrue(Protocol16Type.Array, writeTypeCode);
            SerializeShort(output, (short)array.Length, false);

            Type elementType = array.GetType().GetElementType();

            Protocol16Type protocol16Type = TypeCodeToProtocol16Type(elementType);

            if (protocol16Type == Protocol16Type.Unknown)
            {
                throw new Exception("Custom types are currently not supported");
            }
            output.WriteTypeCodeIfTrue(protocol16Type, true);
            if (protocol16Type == Protocol16Type.Dictionary)
            {
                // WTF ExitGames, why are you trying to get GetGenericArguments() of an array..?!
                // I think what you wanted to do is just give the element type to SerializeDictionaryHeader not the array type
                SerializeDictionaryHeader(output, elementType, out var writeKeyCode, out var writeValueCode);
                foreach (var o in array)
                {
                    SerializeDictionaryElements(output, (IDictionary)o, writeKeyCode, writeValueCode);
                }
            }
            else
            {
                foreach (object o in array)
                {
                    Serialize(output, o, false);
                }
            }
        }
Ejemplo n.º 4
0
        private static void SerializeAnyArray(Protocol16Stream output, Array array, bool writeTypeCode, Protocol16Type arrayType)
        {
            if (arrayType == Protocol16Type.ObjectArray)
            {
                SerializeObjectArray(output, (object[])array, writeTypeCode);
                return;
            }

            // Fallback to object array if null is included
            var containsNull = false;

            foreach (var element in array)
            {
                if (element == null)
                {
                    containsNull = true;
                    break;
                }
            }

            if (containsNull)
            {
                SerializeObjectArray(output, (object[])array, writeTypeCode);
                return;
            }

            switch (arrayType)
            {
            case Protocol16Type.StringArray:
                SerializeStringArray(output, (string[])array, writeTypeCode);
                return;

            case Protocol16Type.IntegerArray:
                SerializeIntArray(output, (int[])array, writeTypeCode);
                break;

            case Protocol16Type.ByteArray:
                SerializeByteArray(output, (byte[])array, writeTypeCode);
                break;

            case Protocol16Type.Array:
                SerializeArrayWithSameElements(output, array, writeTypeCode);
                break;

            default:
                throw new Exception("Unknown array type");
            }
        }
Ejemplo n.º 5
0
        public static void Serialize(Protocol16Stream output, object obj, bool writeTypeCode)
        {
            if (obj == null)
            {
                output.WriteTypeCodeIfTrue(Protocol16Type.Null, writeTypeCode);
                return;
            }

            Protocol16Type type = TypeCodeToProtocol16Type(obj.GetType());

            switch (type)
            {
            case Protocol16Type.Boolean:
                SerializeBoolean(output, (bool)obj, writeTypeCode);
                return;

            case Protocol16Type.Byte:
                SerializeByte(output, (byte)obj, writeTypeCode);
                return;

            case Protocol16Type.Short:
                SerializeShort(output, (short)obj, writeTypeCode);
                return;

            case Protocol16Type.Integer:
                SerializeInteger(output, (int)obj, writeTypeCode);
                return;

            case Protocol16Type.Long:
                SerializeLong(output, (long)obj, writeTypeCode);
                return;

            case Protocol16Type.Float:
                SerializeFloat(output, (float)obj, writeTypeCode);
                return;

            case Protocol16Type.Double:
                SerializeDouble(output, (double)obj, writeTypeCode);
                return;

            case Protocol16Type.String:
                SerializeString(output, (string)obj, writeTypeCode);
                return;

            case Protocol16Type.EventData:
                SerializeEventData(output, (EventData)obj, writeTypeCode);
                return;

            case Protocol16Type.Hashtable:
                SerializeHashtable(output, (Hashtable)obj, writeTypeCode);
                return;

            case Protocol16Type.Dictionary:
                SerializeDictionary(output, (IDictionary)obj, writeTypeCode);
                return;

            case Protocol16Type.OperationResponse:
                SerializeOperationResponse(output, (OperationResponse)obj, writeTypeCode);
                return;

            case Protocol16Type.OperationRequest:
                SerializeOperationRequest(output, (OperationRequest)obj, writeTypeCode);
                return;

            case Protocol16Type.IntegerArray:
            case Protocol16Type.StringArray:
            case Protocol16Type.ByteArray:
            case Protocol16Type.ObjectArray:
            case Protocol16Type.Array:
                SerializeAnyArray(output, (Array)obj, writeTypeCode, type);
                return;
            }

            // Special case
            if (obj is ArraySegment <byte> arraySegment)
            {
                SerializeArraySegment(output, arraySegment, writeTypeCode);
                return;
            }

            throw new ArgumentException($"Cannot serialize objects of type {obj.GetType()} / System.TypeCode: {Type.GetTypeCode(obj.GetType())}");
        }