Add project files.
This commit is contained in:
26
Compat.Private.Serialization/CodeObject.cs
Normal file
26
Compat.Private.Serialization/CodeObject.cs
Normal file
@@ -0,0 +1,26 @@
|
||||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System.Collections;
|
||||
using System.Collections.Specialized;
|
||||
|
||||
#if !FEATURE_SERIALIZATION
|
||||
namespace System.CodeDom
|
||||
#else
|
||||
namespace Compat.Runtime.Serialization
|
||||
#endif
|
||||
{
|
||||
#if !FEATURE_SERIALIZATION
|
||||
public class CodeObject
|
||||
#else
|
||||
internal class CodeObject
|
||||
#endif
|
||||
{
|
||||
private IDictionary _userData = null;
|
||||
|
||||
public CodeObject() { }
|
||||
|
||||
public IDictionary UserData => _userData ?? (_userData = new ListDictionary());
|
||||
}
|
||||
}
|
||||
409
Compat.Private.Serialization/CodeTypeReference.cs
Normal file
409
Compat.Private.Serialization/CodeTypeReference.cs
Normal file
@@ -0,0 +1,409 @@
|
||||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
|
||||
#if !FEATURE_SERIALIZATION
|
||||
namespace System.CodeDom
|
||||
#else
|
||||
namespace Compat.Runtime.Serialization
|
||||
#endif
|
||||
{
|
||||
[Flags]
|
||||
#if !FEATURE_SERIALIZATION
|
||||
public enum CodeTypeReferenceOptions
|
||||
#else
|
||||
internal enum CodeTypeReferenceOptions
|
||||
#endif
|
||||
{
|
||||
GlobalReference = 0x00000001,
|
||||
GenericTypeParameter = 0x00000002
|
||||
}
|
||||
|
||||
#if !FEATURE_SERIALIZATION
|
||||
public class CodeTypeReference : CodeObject
|
||||
#else
|
||||
internal class CodeTypeReference : CodeObject
|
||||
#endif
|
||||
{
|
||||
private string _baseType;
|
||||
private readonly bool _isInterface;
|
||||
private CodeTypeReferenceCollection _typeArguments;
|
||||
private bool _needsFixup = false;
|
||||
|
||||
public CodeTypeReference()
|
||||
{
|
||||
_baseType = string.Empty;
|
||||
ArrayRank = 0;
|
||||
ArrayElementType = null;
|
||||
}
|
||||
|
||||
public CodeTypeReference(Type type)
|
||||
{
|
||||
if (type == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(type));
|
||||
}
|
||||
|
||||
if (type.IsArray)
|
||||
{
|
||||
ArrayRank = type.GetArrayRank();
|
||||
ArrayElementType = new CodeTypeReference(type.GetElementType());
|
||||
_baseType = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
InitializeFromType(type);
|
||||
ArrayRank = 0;
|
||||
ArrayElementType = null;
|
||||
}
|
||||
|
||||
_isInterface = type.IsInterface;
|
||||
}
|
||||
|
||||
public CodeTypeReference(Type type, CodeTypeReferenceOptions codeTypeReferenceOption) : this(type)
|
||||
{
|
||||
Options = codeTypeReferenceOption;
|
||||
}
|
||||
|
||||
public CodeTypeReference(string typeName, CodeTypeReferenceOptions codeTypeReferenceOption)
|
||||
{
|
||||
Initialize(typeName, codeTypeReferenceOption);
|
||||
}
|
||||
|
||||
public CodeTypeReference(string typeName)
|
||||
{
|
||||
Initialize(typeName);
|
||||
}
|
||||
|
||||
private void InitializeFromType(Type type)
|
||||
{
|
||||
_baseType = type.Name;
|
||||
if (!type.IsGenericParameter)
|
||||
{
|
||||
Type currentType = type;
|
||||
while (currentType.IsNested)
|
||||
{
|
||||
currentType = currentType.DeclaringType;
|
||||
_baseType = currentType.Name + "+" + _baseType;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(type.Namespace))
|
||||
{
|
||||
_baseType = type.Namespace + "." + _baseType;
|
||||
}
|
||||
}
|
||||
|
||||
// pick up the type arguments from an instantiated generic type but not an open one
|
||||
if (type.IsGenericType && !type.ContainsGenericParameters)
|
||||
{
|
||||
Type[] genericArgs = type.GetGenericArguments();
|
||||
for (int i = 0; i < genericArgs.Length; i++)
|
||||
{
|
||||
TypeArguments.Add(new CodeTypeReference(genericArgs[i]));
|
||||
}
|
||||
}
|
||||
else if (!type.IsGenericTypeDefinition)
|
||||
{
|
||||
// if the user handed us a non-generic type, but later
|
||||
// appends generic type arguments, we'll pretend
|
||||
// it's a generic type for their sake - this is good for
|
||||
// them if they pass in System.Nullable class when they
|
||||
// meant the System.Nullable<T> value type.
|
||||
_needsFixup = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void Initialize(string typeName)
|
||||
{
|
||||
Initialize(typeName, Options);
|
||||
}
|
||||
|
||||
private void Initialize(string typeName, CodeTypeReferenceOptions options)
|
||||
{
|
||||
Options = options;
|
||||
if (string.IsNullOrEmpty(typeName))
|
||||
{
|
||||
typeName = typeof(void).FullName;
|
||||
_baseType = typeName;
|
||||
ArrayRank = 0;
|
||||
ArrayElementType = null;
|
||||
return;
|
||||
}
|
||||
|
||||
typeName = RipOffAssemblyInformationFromTypeName(typeName);
|
||||
|
||||
int end = typeName.Length - 1;
|
||||
int current = end;
|
||||
_needsFixup = true; // default to true, and if we find arity or generic type args, we'll clear the flag.
|
||||
|
||||
// Scan the entire string for valid array tails and store ranks for array tails
|
||||
// we found in a queue.
|
||||
var q = new Queue<int>();
|
||||
while (current >= 0)
|
||||
{
|
||||
int rank = 1;
|
||||
if (typeName[current--] == ']')
|
||||
{
|
||||
while (current >= 0 && typeName[current] == ',')
|
||||
{
|
||||
rank++;
|
||||
current--;
|
||||
}
|
||||
|
||||
if (current >= 0 && typeName[current] == '[')
|
||||
{
|
||||
// found a valid array tail
|
||||
q.Enqueue(rank);
|
||||
current--;
|
||||
end = current;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// Try find generic type arguments
|
||||
current = end;
|
||||
var typeArgumentList = new List<CodeTypeReference>();
|
||||
var subTypeNames = new Stack<string>();
|
||||
if (current > 0 && typeName[current--] == ']')
|
||||
{
|
||||
_needsFixup = false;
|
||||
int unmatchedRightBrackets = 1;
|
||||
int subTypeNameEndIndex = end;
|
||||
|
||||
// Try find the matching '[', if we can't find it, we will not try to parse the string
|
||||
while (current >= 0)
|
||||
{
|
||||
if (typeName[current] == '[')
|
||||
{
|
||||
// break if we found matched brackets
|
||||
if (--unmatchedRightBrackets == 0) break;
|
||||
}
|
||||
else if (typeName[current] == ']')
|
||||
{
|
||||
++unmatchedRightBrackets;
|
||||
}
|
||||
else if (typeName[current] == ',' && unmatchedRightBrackets == 1)
|
||||
{
|
||||
//
|
||||
// Type name can contain nested generic types. Following is an example:
|
||||
// System.Collections.Generic.Dictionary`2[[System.string, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],
|
||||
// [System.Collections.Generic.List`1[[System.Int32, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]],
|
||||
// mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]
|
||||
//
|
||||
// Spliltting by ',' won't work. We need to do first-level split by ','.
|
||||
//
|
||||
if (current + 1 < subTypeNameEndIndex)
|
||||
{
|
||||
subTypeNames.Push(typeName.Substring(current + 1, subTypeNameEndIndex - current - 1));
|
||||
}
|
||||
|
||||
subTypeNameEndIndex = current;
|
||||
}
|
||||
--current;
|
||||
}
|
||||
|
||||
if (current > 0 && (end - current - 1) > 0)
|
||||
{
|
||||
// push the last generic type argument name if there is any
|
||||
if (current + 1 < subTypeNameEndIndex)
|
||||
{
|
||||
subTypeNames.Push(typeName.Substring(current + 1, subTypeNameEndIndex - current - 1));
|
||||
}
|
||||
|
||||
// we found matched brackets and the brackets contains some characters.
|
||||
while (subTypeNames.Count > 0)
|
||||
{
|
||||
string name = RipOffAssemblyInformationFromTypeName(subTypeNames.Pop());
|
||||
typeArgumentList.Add(new CodeTypeReference(name));
|
||||
}
|
||||
end = current - 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (end < 0)
|
||||
{
|
||||
// this can happen if we have some string like "[...]"
|
||||
_baseType = typeName;
|
||||
return;
|
||||
}
|
||||
|
||||
if (q.Count > 0)
|
||||
{
|
||||
CodeTypeReference type = new CodeTypeReference(typeName.Substring(0, end + 1), Options);
|
||||
|
||||
for (int i = 0; i < typeArgumentList.Count; i++)
|
||||
{
|
||||
type.TypeArguments.Add(typeArgumentList[i]);
|
||||
}
|
||||
|
||||
while (q.Count > 1)
|
||||
{
|
||||
type = new CodeTypeReference(type, q.Dequeue());
|
||||
}
|
||||
|
||||
// we don't need to create a new CodeTypeReference for the last one.
|
||||
Debug.Assert(q.Count == 1, "We should have one and only one in the rank queue.");
|
||||
_baseType = null;
|
||||
ArrayRank = q.Dequeue();
|
||||
ArrayElementType = type;
|
||||
}
|
||||
else if (typeArgumentList.Count > 0)
|
||||
{
|
||||
for (int i = 0; i < typeArgumentList.Count; i++)
|
||||
{
|
||||
TypeArguments.Add(typeArgumentList[i]);
|
||||
}
|
||||
|
||||
_baseType = typeName.Substring(0, end + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
_baseType = typeName;
|
||||
}
|
||||
|
||||
// Now see if we have some arity. baseType could be null if this is an array type.
|
||||
if (_baseType != null && _baseType.IndexOf('`') != -1) // string.Contains(char) is .NetCore2.1+ specific
|
||||
{
|
||||
_needsFixup = false;
|
||||
}
|
||||
}
|
||||
|
||||
public CodeTypeReference(string typeName, params CodeTypeReference[] typeArguments) : this(typeName)
|
||||
{
|
||||
if (typeArguments != null && typeArguments.Length > 0)
|
||||
{
|
||||
TypeArguments.AddRange(typeArguments);
|
||||
}
|
||||
}
|
||||
|
||||
#if !FEATURE_SERIALIZATION
|
||||
public CodeTypeReference(CodeTypeParameter typeParameter) :
|
||||
this(typeParameter?.Name)
|
||||
{
|
||||
Options = CodeTypeReferenceOptions.GenericTypeParameter;
|
||||
}
|
||||
#endif
|
||||
|
||||
public CodeTypeReference(string baseType, int rank)
|
||||
{
|
||||
_baseType = null;
|
||||
ArrayRank = rank;
|
||||
ArrayElementType = new CodeTypeReference(baseType);
|
||||
}
|
||||
|
||||
public CodeTypeReference(CodeTypeReference arrayType, int rank)
|
||||
{
|
||||
_baseType = null;
|
||||
ArrayRank = rank;
|
||||
ArrayElementType = arrayType;
|
||||
}
|
||||
|
||||
public CodeTypeReference ArrayElementType { get; set; }
|
||||
|
||||
public int ArrayRank { get; set; }
|
||||
|
||||
internal int NestedArrayDepth => ArrayElementType == null ? 0 : 1 + ArrayElementType.NestedArrayDepth;
|
||||
|
||||
public string BaseType
|
||||
{
|
||||
get
|
||||
{
|
||||
if (ArrayRank > 0 && ArrayElementType != null)
|
||||
{
|
||||
return ArrayElementType.BaseType;
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(_baseType))
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
string returnType = _baseType;
|
||||
return _needsFixup && TypeArguments.Count > 0 ?
|
||||
returnType + '`' + TypeArguments.Count.ToString(CultureInfo.InvariantCulture) :
|
||||
returnType;
|
||||
}
|
||||
set
|
||||
{
|
||||
_baseType = value;
|
||||
Initialize(_baseType);
|
||||
}
|
||||
}
|
||||
|
||||
public CodeTypeReferenceOptions Options { get; set; }
|
||||
|
||||
public CodeTypeReferenceCollection TypeArguments
|
||||
{
|
||||
get
|
||||
{
|
||||
if (ArrayRank > 0 && ArrayElementType != null)
|
||||
{
|
||||
return ArrayElementType.TypeArguments;
|
||||
}
|
||||
|
||||
if (_typeArguments == null)
|
||||
{
|
||||
_typeArguments = new CodeTypeReferenceCollection();
|
||||
}
|
||||
|
||||
return _typeArguments;
|
||||
}
|
||||
}
|
||||
|
||||
internal bool IsInterface => _isInterface; // Note that this only works correctly if the Type ctor was used. Otherwise, it's always false.
|
||||
|
||||
//
|
||||
// The string for generic type argument might contain assembly information and square bracket pair.
|
||||
// There might be leading spaces in front the type name.
|
||||
// Following function will rip off assembly information and brackets
|
||||
// Following is an example:
|
||||
// " [System.Collections.Generic.List[[System.string, mscorlib, Version=2.0.0.0, Culture=neutral,
|
||||
// PublicKeyToken=b77a5c561934e089]], mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]"
|
||||
//
|
||||
private string RipOffAssemblyInformationFromTypeName(string typeName)
|
||||
{
|
||||
int start = 0;
|
||||
int end = typeName.Length - 1;
|
||||
string result = typeName;
|
||||
|
||||
// skip whitespace in the beginning
|
||||
while (start < typeName.Length && char.IsWhiteSpace(typeName[start])) start++;
|
||||
while (end >= 0 && char.IsWhiteSpace(typeName[end])) end--;
|
||||
|
||||
if (start < end)
|
||||
{
|
||||
if (typeName[start] == '[' && typeName[end] == ']')
|
||||
{
|
||||
start++;
|
||||
end--;
|
||||
}
|
||||
|
||||
// if we still have a ] at the end, there's no assembly info.
|
||||
if (typeName[end] != ']')
|
||||
{
|
||||
int commaCount = 0;
|
||||
for (int index = end; index >= start; index--)
|
||||
{
|
||||
if (typeName[index] == ',')
|
||||
{
|
||||
commaCount++;
|
||||
if (commaCount == 4)
|
||||
{
|
||||
result = typeName.Substring(start, index - start);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
80
Compat.Private.Serialization/CodeTypeReferenceCollection.cs
Normal file
80
Compat.Private.Serialization/CodeTypeReferenceCollection.cs
Normal file
@@ -0,0 +1,80 @@
|
||||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
using System;
|
||||
using System.Collections;
|
||||
|
||||
#if !FEATURE_SERIALIZATION
|
||||
namespace System.CodeDom
|
||||
#else
|
||||
namespace Compat.Runtime.Serialization
|
||||
#endif
|
||||
{
|
||||
#if !FEATURE_SERIALIZATION
|
||||
public class CodeTypeReferenceCollection : CollectionBase
|
||||
#else
|
||||
internal class CodeTypeReferenceCollection : CollectionBase
|
||||
#endif
|
||||
{
|
||||
public CodeTypeReferenceCollection() { }
|
||||
|
||||
public CodeTypeReferenceCollection(CodeTypeReferenceCollection value)
|
||||
{
|
||||
AddRange(value);
|
||||
}
|
||||
|
||||
public CodeTypeReferenceCollection(CodeTypeReference[] value)
|
||||
{
|
||||
AddRange(value);
|
||||
}
|
||||
|
||||
public CodeTypeReference this[int index]
|
||||
{
|
||||
get { return ((CodeTypeReference)(List[index])); }
|
||||
set { List[index] = value; }
|
||||
}
|
||||
|
||||
public int Add(CodeTypeReference value) => List.Add(value);
|
||||
|
||||
public void Add(string value) => Add(new CodeTypeReference(value));
|
||||
|
||||
public void Add(Type value) => Add(new CodeTypeReference(value));
|
||||
|
||||
public void AddRange(CodeTypeReference[] value)
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(value));
|
||||
}
|
||||
|
||||
for (int i = 0; i < value.Length; i++)
|
||||
{
|
||||
Add(value[i]);
|
||||
}
|
||||
}
|
||||
|
||||
public void AddRange(CodeTypeReferenceCollection value)
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(value));
|
||||
}
|
||||
|
||||
int currentCount = value.Count;
|
||||
for (int i = 0; i < currentCount; i++)
|
||||
{
|
||||
Add(value[i]);
|
||||
}
|
||||
}
|
||||
|
||||
public bool Contains(CodeTypeReference value) => List.Contains(value);
|
||||
|
||||
public void CopyTo(CodeTypeReference[] array, int index) => List.CopyTo(array, index);
|
||||
|
||||
public int IndexOf(CodeTypeReference value) => List.IndexOf(value);
|
||||
|
||||
public void Insert(int index, CodeTypeReference value) => List.Insert(index, value);
|
||||
|
||||
public void Remove(CodeTypeReference value) => List.Remove(value);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netstandard2.0</TargetFramework>
|
||||
<LangVersion>8.0</LangVersion>
|
||||
<RootNamespace />
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<DefineConstants>TRACE;FEATURE_SERIALIZATION</DefineConstants>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="System.Reflection.Emit.Lightweight" Version="4.3.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Update="Resources\SR.resx">
|
||||
<CustomToolNamespace>Compat</CustomToolNamespace>
|
||||
<Generator></Generator>
|
||||
</EmbeddedResource>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
43
Compat.Private.Serialization/Compat/Fx.cs
Normal file
43
Compat.Private.Serialization/Compat/Fx.cs
Normal file
@@ -0,0 +1,43 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace Compat
|
||||
{
|
||||
internal class Fx
|
||||
{
|
||||
public static void Assert(string message)
|
||||
{
|
||||
Debug.Assert(false, message);
|
||||
}
|
||||
|
||||
public static void Assert(bool condition, string message)
|
||||
{
|
||||
Debug.Assert(condition, message);
|
||||
}
|
||||
|
||||
public static bool IsFatal(Exception ex)
|
||||
{
|
||||
ex = Unwrap(ex);
|
||||
|
||||
return ex is NullReferenceException ||
|
||||
ex is StackOverflowException ||
|
||||
ex is OutOfMemoryException ||
|
||||
ex is System.Threading.ThreadAbortException ||
|
||||
ex is System.Runtime.InteropServices.SEHException ||
|
||||
ex is System.Security.SecurityException;
|
||||
}
|
||||
|
||||
internal static Exception Unwrap(Exception ex)
|
||||
{
|
||||
// for certain types of exceptions, we care more about the inner
|
||||
// exception
|
||||
while (ex.InnerException != null &&
|
||||
(ex is System.Reflection.TargetInvocationException))
|
||||
{
|
||||
ex = ex.InnerException;
|
||||
}
|
||||
|
||||
return ex;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
using System;
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
namespace Compat.Runtime
|
||||
{
|
||||
[Serializable]
|
||||
internal class FatalException : SystemException
|
||||
{
|
||||
public FatalException()
|
||||
{
|
||||
}
|
||||
public FatalException(string message) : base(message)
|
||||
{
|
||||
}
|
||||
|
||||
public FatalException(string message, Exception innerException) : base(message, innerException)
|
||||
{
|
||||
// This can't throw something like ArgumentException because that would be worse than
|
||||
// throwing the fatal exception that was requested.
|
||||
Fx.Assert(innerException == null || !Fx.IsFatal(innerException), "FatalException can't be used to wrap fatal exceptions.");
|
||||
}
|
||||
|
||||
protected FatalException(SerializationInfo info, StreamingContext context) : base(info, context)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
115
Compat.Private.Serialization/Compat/Runtime/HashHelper.cs
Normal file
115
Compat.Private.Serialization/Compat/Runtime/HashHelper.cs
Normal file
@@ -0,0 +1,115 @@
|
||||
namespace Compat.Runtime
|
||||
{
|
||||
internal static class HashHelper
|
||||
{
|
||||
// "derived from the RSA Data Security, Inc. MD5 Message-Digest Algorithm"
|
||||
// DO NOT USE FOR SECURITY PURPOSES.
|
||||
public static byte[] ComputeHash(byte[] buffer)
|
||||
{
|
||||
int[] shifts = new int[] { 7, 12, 17, 22, 5, 9, 14, 20, 4, 11, 16, 23, 6, 10, 15, 21 };
|
||||
uint[] sines = new uint[] {
|
||||
0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501,
|
||||
0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821,
|
||||
|
||||
0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8,
|
||||
0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a,
|
||||
|
||||
0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70,
|
||||
0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05, 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665,
|
||||
|
||||
0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1,
|
||||
0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391 };
|
||||
|
||||
int blocks = (buffer.Length + 8) / 64 + 1;
|
||||
|
||||
uint aa = 0x67452301;
|
||||
uint bb = 0xefcdab89;
|
||||
uint cc = 0x98badcfe;
|
||||
uint dd = 0x10325476;
|
||||
|
||||
for (int i = 0; i < blocks; i++)
|
||||
{
|
||||
byte[] block = buffer;
|
||||
int offset = i * 64;
|
||||
|
||||
if (offset + 64 > buffer.Length)
|
||||
{
|
||||
block = new byte[64];
|
||||
|
||||
for (int j = offset; j < buffer.Length; j++)
|
||||
{
|
||||
block[j - offset] = buffer[j];
|
||||
}
|
||||
if (offset <= buffer.Length)
|
||||
{
|
||||
block[buffer.Length - offset] = 0x80;
|
||||
}
|
||||
if (i == blocks - 1)
|
||||
{
|
||||
block[56] = (byte)(buffer.Length << 3);
|
||||
block[57] = (byte)(buffer.Length >> 5);
|
||||
block[58] = (byte)(buffer.Length >> 13);
|
||||
block[59] = (byte)(buffer.Length >> 21);
|
||||
}
|
||||
|
||||
offset = 0;
|
||||
}
|
||||
|
||||
uint a = aa;
|
||||
uint b = bb;
|
||||
uint c = cc;
|
||||
uint d = dd;
|
||||
|
||||
uint f;
|
||||
int g;
|
||||
|
||||
for (int j = 0; j < 64; j++)
|
||||
{
|
||||
if (j < 16)
|
||||
{
|
||||
f = b & c | ~b & d;
|
||||
g = j;
|
||||
}
|
||||
else if (j < 32)
|
||||
{
|
||||
f = b & d | c & ~d;
|
||||
g = 5 * j + 1;
|
||||
}
|
||||
else if (j < 48)
|
||||
{
|
||||
f = b ^ c ^ d;
|
||||
g = 3 * j + 5;
|
||||
}
|
||||
else
|
||||
{
|
||||
f = c ^ (b | ~d);
|
||||
g = 7 * j;
|
||||
}
|
||||
|
||||
g = (g & 0x0f) * 4 + offset;
|
||||
|
||||
uint hold = d;
|
||||
d = c;
|
||||
c = b;
|
||||
|
||||
b = a + f + sines[j] + (uint)(block[g] + (block[g + 1] << 8) + (block[g + 2] << 16) + (block[g + 3] << 24));
|
||||
b = b << shifts[j & 3 | j >> 2 & ~3] | b >> 32 - shifts[j & 3 | j >> 2 & ~3];
|
||||
b += c;
|
||||
|
||||
a = hold;
|
||||
}
|
||||
|
||||
aa += a;
|
||||
bb += b;
|
||||
cc += c;
|
||||
dd += d;
|
||||
}
|
||||
|
||||
return new byte[] {
|
||||
(byte)aa, (byte)(aa >> 8), (byte)(aa >> 16), (byte)(aa >> 24),
|
||||
(byte)bb, (byte)(bb >> 8), (byte)(bb >> 16), (byte)(bb >> 24),
|
||||
(byte)cc, (byte)(cc >> 8), (byte)(cc >> 16), (byte)(cc >> 24),
|
||||
(byte)dd, (byte)(dd >> 8), (byte)(dd >> 16), (byte)(dd >> 24) };
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,161 @@
|
||||
using System.Xml;
|
||||
|
||||
namespace Compat.Runtime.Serialization
|
||||
{
|
||||
internal class Attributes
|
||||
{
|
||||
private static readonly XmlDictionaryString[] serializationLocalNames;
|
||||
|
||||
private static readonly XmlDictionaryString[] schemaInstanceLocalNames;
|
||||
|
||||
static Attributes()
|
||||
{
|
||||
serializationLocalNames = new XmlDictionaryString[]
|
||||
{
|
||||
DictionaryGlobals.IdLocalName,
|
||||
DictionaryGlobals.ArraySizeLocalName,
|
||||
DictionaryGlobals.RefLocalName,
|
||||
DictionaryGlobals.ClrTypeLocalName,
|
||||
DictionaryGlobals.ClrAssemblyLocalName,
|
||||
DictionaryGlobals.ISerializableFactoryTypeLocalName
|
||||
};
|
||||
|
||||
schemaInstanceLocalNames = new XmlDictionaryString[]
|
||||
{
|
||||
DictionaryGlobals.XsiNilLocalName,
|
||||
DictionaryGlobals.XsiTypeLocalName
|
||||
};
|
||||
}
|
||||
|
||||
internal string Id;
|
||||
internal string Ref;
|
||||
internal string XsiTypeName;
|
||||
internal string XsiTypeNamespace;
|
||||
internal string XsiTypePrefix;
|
||||
internal bool XsiNil;
|
||||
internal string ClrAssembly;
|
||||
internal string ClrType;
|
||||
internal int ArraySZSize;
|
||||
internal string FactoryTypeName;
|
||||
internal string FactoryTypeNamespace;
|
||||
internal string FactoryTypePrefix;
|
||||
internal bool UnrecognizedAttributesFound;
|
||||
|
||||
internal void Read(XmlReaderDelegator reader)
|
||||
{
|
||||
Reset();
|
||||
|
||||
while (reader.MoveToNextAttribute())
|
||||
{
|
||||
switch (reader.IndexOfLocalName(serializationLocalNames, DictionaryGlobals.SerializationNamespace))
|
||||
{
|
||||
case 0:
|
||||
ReadId(reader);
|
||||
break;
|
||||
case 1:
|
||||
ReadArraySize(reader);
|
||||
break;
|
||||
case 2:
|
||||
ReadRef(reader);
|
||||
break;
|
||||
case 3:
|
||||
ClrType = reader.Value;
|
||||
break;
|
||||
case 4:
|
||||
ClrAssembly = reader.Value;
|
||||
break;
|
||||
case 5:
|
||||
ReadFactoryType(reader);
|
||||
break;
|
||||
default:
|
||||
switch (reader.IndexOfLocalName(schemaInstanceLocalNames, DictionaryGlobals.SchemaInstanceNamespace))
|
||||
{
|
||||
case 0:
|
||||
ReadXsiNil(reader);
|
||||
break;
|
||||
case 1:
|
||||
ReadXsiType(reader);
|
||||
break;
|
||||
default:
|
||||
if (!reader.IsNamespaceUri(DictionaryGlobals.XmlnsNamespace))
|
||||
{
|
||||
UnrecognizedAttributesFound = true;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
reader.MoveToElement();
|
||||
}
|
||||
|
||||
internal void Reset()
|
||||
{
|
||||
Id = Globals.NewObjectId;
|
||||
Ref = Globals.NewObjectId;
|
||||
XsiTypeName = null;
|
||||
XsiTypeNamespace = null;
|
||||
XsiTypePrefix = null;
|
||||
XsiNil = false;
|
||||
ClrAssembly = null;
|
||||
ClrType = null;
|
||||
ArraySZSize = -1;
|
||||
FactoryTypeName = null;
|
||||
FactoryTypeNamespace = null;
|
||||
FactoryTypePrefix = null;
|
||||
UnrecognizedAttributesFound = false;
|
||||
}
|
||||
|
||||
private void ReadId(XmlReaderDelegator reader)
|
||||
{
|
||||
Id = reader.ReadContentAsString();
|
||||
if (string.IsNullOrEmpty(Id))
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(SR.Format(SR.InvalidXsIdDefinition, Id)));
|
||||
}
|
||||
}
|
||||
|
||||
private void ReadRef(XmlReaderDelegator reader)
|
||||
{
|
||||
Ref = reader.ReadContentAsString();
|
||||
if (string.IsNullOrEmpty(Ref))
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(SR.Format(SR.InvalidXsRefDefinition, Ref)));
|
||||
}
|
||||
}
|
||||
|
||||
private void ReadXsiNil(XmlReaderDelegator reader)
|
||||
{
|
||||
XsiNil = reader.ReadContentAsBoolean();
|
||||
}
|
||||
|
||||
private void ReadArraySize(XmlReaderDelegator reader)
|
||||
{
|
||||
ArraySZSize = reader.ReadContentAsInt();
|
||||
if (ArraySZSize < 0)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(SR.Format(SR.InvalidSizeDefinition, ArraySZSize)));
|
||||
}
|
||||
}
|
||||
|
||||
private void ReadXsiType(XmlReaderDelegator reader)
|
||||
{
|
||||
string xsiTypeString = reader.Value;
|
||||
if (xsiTypeString != null && xsiTypeString.Length > 0)
|
||||
{
|
||||
XmlObjectSerializerReadContext.ParseQualifiedName(xsiTypeString, reader, out XsiTypeName, out XsiTypeNamespace, out XsiTypePrefix);
|
||||
}
|
||||
}
|
||||
|
||||
private void ReadFactoryType(XmlReaderDelegator reader)
|
||||
{
|
||||
string factoryTypeString = reader.Value;
|
||||
if (factoryTypeString != null && factoryTypeString.Length > 0)
|
||||
{
|
||||
XmlObjectSerializerReadContext.ParseQualifiedName(factoryTypeString, reader, out FactoryTypeName, out FactoryTypeNamespace, out FactoryTypePrefix);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,26 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Compat.Runtime.Serialization
|
||||
{
|
||||
internal class ClassDataNode : DataNode<object>
|
||||
{
|
||||
private IList<ExtensionDataMember> _members;
|
||||
|
||||
internal ClassDataNode()
|
||||
{
|
||||
dataType = Globals.TypeOfClassDataNode;
|
||||
}
|
||||
|
||||
internal IList<ExtensionDataMember> Members
|
||||
{
|
||||
get => _members;
|
||||
set => _members = value;
|
||||
}
|
||||
|
||||
public override void Clear()
|
||||
{
|
||||
base.Clear();
|
||||
_members = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,57 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
|
||||
namespace Compat.Runtime.Serialization
|
||||
{
|
||||
internal class CollectionDataNode : DataNode<Array>
|
||||
{
|
||||
private IList<IDataNode> items;
|
||||
private string itemName;
|
||||
private string itemNamespace;
|
||||
private int size = -1;
|
||||
|
||||
internal CollectionDataNode()
|
||||
{
|
||||
dataType = Globals.TypeOfCollectionDataNode;
|
||||
}
|
||||
|
||||
internal IList<IDataNode> Items
|
||||
{
|
||||
get => items;
|
||||
set => items = value;
|
||||
}
|
||||
|
||||
internal string ItemName
|
||||
{
|
||||
get => itemName;
|
||||
set => itemName = value;
|
||||
}
|
||||
|
||||
internal string ItemNamespace
|
||||
{
|
||||
get => itemNamespace;
|
||||
set => itemNamespace = value;
|
||||
}
|
||||
|
||||
internal int Size
|
||||
{
|
||||
get => size;
|
||||
set => size = value;
|
||||
}
|
||||
|
||||
public override void GetData(ElementData element)
|
||||
{
|
||||
base.GetData(element);
|
||||
|
||||
element.AddAttribute(Globals.SerPrefix, Globals.SerializationNamespace, Globals.ArraySizeLocalName, Size.ToString(NumberFormatInfo.InvariantInfo));
|
||||
}
|
||||
|
||||
public override void Clear()
|
||||
{
|
||||
base.Clear();
|
||||
items = null;
|
||||
size = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,30 @@
|
||||
namespace Compat.Runtime.Serialization
|
||||
{
|
||||
internal class DataContractPairKey
|
||||
{
|
||||
private readonly object _object1;
|
||||
private readonly object _object2;
|
||||
|
||||
public DataContractPairKey(object object1, object object2)
|
||||
{
|
||||
_object1 = object1;
|
||||
_object2 = object2;
|
||||
}
|
||||
|
||||
public override bool Equals(object other)
|
||||
{
|
||||
DataContractPairKey otherKey = other as DataContractPairKey;
|
||||
if (otherKey == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return ((otherKey._object1 == _object1 && otherKey._object2 == _object2) || (otherKey._object1 == _object2 && otherKey._object2 == _object1));
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return _object1.GetHashCode() ^ _object2.GetHashCode();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,522 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Xml;
|
||||
using DataContractResolver = System.Runtime.Serialization.DataContractResolver;
|
||||
|
||||
namespace Compat.Runtime.Serialization
|
||||
{
|
||||
using DataContractDictionary = Dictionary<XmlQualifiedName, DataContract>;
|
||||
|
||||
internal sealed class DataContractSerializer : XmlObjectSerializer
|
||||
{
|
||||
private Type _rootType;
|
||||
private DataContract rootContract; // post-surrogate
|
||||
private bool needsContractNsAtRoot;
|
||||
private XmlDictionaryString rootName;
|
||||
private XmlDictionaryString rootNamespace;
|
||||
private int maxItemsInObjectGraph;
|
||||
private bool ignoreExtensionDataObject;
|
||||
private bool preserveObjectReferences;
|
||||
private IDataContractSurrogate dataContractSurrogate;
|
||||
private ReadOnlyCollection<Type> knownTypeCollection;
|
||||
internal IList<Type> knownTypeList;
|
||||
internal DataContractDictionary knownDataContracts;
|
||||
private DataContractResolver dataContractResolver;
|
||||
private bool serializeReadOnlyTypes;
|
||||
|
||||
public DataContractSerializer(Type type)
|
||||
: this(type, (IEnumerable<Type>)null)
|
||||
{
|
||||
}
|
||||
|
||||
public DataContractSerializer(Type type, IEnumerable<Type> knownTypes)
|
||||
: this(type, knownTypes, int.MaxValue, false, false, null)
|
||||
{
|
||||
}
|
||||
|
||||
public DataContractSerializer(Type type,
|
||||
IEnumerable<Type> knownTypes,
|
||||
int maxItemsInObjectGraph,
|
||||
bool ignoreExtensionDataObject,
|
||||
bool preserveObjectReferences,
|
||||
IDataContractSurrogate dataContractSurrogate)
|
||||
: this(type, knownTypes, maxItemsInObjectGraph, ignoreExtensionDataObject, preserveObjectReferences, dataContractSurrogate, null)
|
||||
{
|
||||
}
|
||||
|
||||
public DataContractSerializer(Type type,
|
||||
IEnumerable<Type> knownTypes,
|
||||
int maxItemsInObjectGraph,
|
||||
bool ignoreExtensionDataObject,
|
||||
bool preserveObjectReferences,
|
||||
IDataContractSurrogate dataContractSurrogate,
|
||||
DataContractResolver dataContractResolver)
|
||||
{
|
||||
Initialize(type, knownTypes, maxItemsInObjectGraph, ignoreExtensionDataObject, preserveObjectReferences, dataContractSurrogate, dataContractResolver, false);
|
||||
}
|
||||
|
||||
public DataContractSerializer(Type type, string rootName, string rootNamespace)
|
||||
: this(type, rootName, rootNamespace, null)
|
||||
{
|
||||
}
|
||||
|
||||
public DataContractSerializer(Type type, string rootName, string rootNamespace, IEnumerable<Type> knownTypes)
|
||||
: this(type, rootName, rootNamespace, knownTypes, int.MaxValue, false, false, null)
|
||||
{
|
||||
}
|
||||
|
||||
public DataContractSerializer(Type type, string rootName, string rootNamespace,
|
||||
IEnumerable<Type> knownTypes,
|
||||
int maxItemsInObjectGraph,
|
||||
bool ignoreExtensionDataObject,
|
||||
bool preserveObjectReferences,
|
||||
IDataContractSurrogate dataContractSurrogate)
|
||||
: this(type, rootName, rootNamespace, knownTypes, maxItemsInObjectGraph, ignoreExtensionDataObject, preserveObjectReferences, dataContractSurrogate, null)
|
||||
{
|
||||
}
|
||||
|
||||
public DataContractSerializer(Type type, string rootName, string rootNamespace,
|
||||
IEnumerable<Type> knownTypes,
|
||||
int maxItemsInObjectGraph,
|
||||
bool ignoreExtensionDataObject,
|
||||
bool preserveObjectReferences,
|
||||
IDataContractSurrogate dataContractSurrogate,
|
||||
DataContractResolver dataContractResolver)
|
||||
{
|
||||
XmlDictionary dictionary = new XmlDictionary(2);
|
||||
Initialize(type, dictionary.Add(rootName), dictionary.Add(DataContract.GetNamespace(rootNamespace)), knownTypes, maxItemsInObjectGraph, ignoreExtensionDataObject, preserveObjectReferences, dataContractSurrogate, dataContractResolver, false);
|
||||
}
|
||||
|
||||
public DataContractSerializer(Type type, XmlDictionaryString rootName, XmlDictionaryString rootNamespace)
|
||||
: this(type, rootName, rootNamespace, null)
|
||||
{
|
||||
}
|
||||
|
||||
public DataContractSerializer(Type type, XmlDictionaryString rootName, XmlDictionaryString rootNamespace, IEnumerable<Type> knownTypes)
|
||||
: this(type, rootName, rootNamespace, knownTypes, int.MaxValue, false, false, null, null)
|
||||
{
|
||||
}
|
||||
|
||||
public DataContractSerializer(Type type, XmlDictionaryString rootName, XmlDictionaryString rootNamespace,
|
||||
IEnumerable<Type> knownTypes,
|
||||
int maxItemsInObjectGraph,
|
||||
bool ignoreExtensionDataObject,
|
||||
bool preserveObjectReferences,
|
||||
IDataContractSurrogate dataContractSurrogate)
|
||||
: this(type, rootName, rootNamespace, knownTypes, maxItemsInObjectGraph, ignoreExtensionDataObject, preserveObjectReferences, dataContractSurrogate, null)
|
||||
{
|
||||
}
|
||||
|
||||
public DataContractSerializer(Type type, XmlDictionaryString rootName, XmlDictionaryString rootNamespace,
|
||||
IEnumerable<Type> knownTypes,
|
||||
int maxItemsInObjectGraph,
|
||||
bool ignoreExtensionDataObject,
|
||||
bool preserveObjectReferences,
|
||||
IDataContractSurrogate dataContractSurrogate,
|
||||
DataContractResolver dataContractResolver)
|
||||
{
|
||||
Initialize(type, rootName, rootNamespace, knownTypes, maxItemsInObjectGraph, ignoreExtensionDataObject, preserveObjectReferences, dataContractSurrogate, dataContractResolver, false);
|
||||
}
|
||||
|
||||
public DataContractSerializer(Type type, DataContractSerializerSettings settings)
|
||||
{
|
||||
if (settings == null)
|
||||
{
|
||||
settings = new DataContractSerializerSettings();
|
||||
}
|
||||
Initialize(type, settings.RootName, settings.RootNamespace, settings.KnownTypes, settings.MaxItemsInObjectGraph, settings.IgnoreExtensionDataObject,
|
||||
settings.PreserveObjectReferences, settings.DataContractSurrogate, settings.DataContractResolver, settings.SerializeReadOnlyTypes);
|
||||
}
|
||||
|
||||
private void Initialize(
|
||||
Type type,
|
||||
IEnumerable<Type> knownTypes,
|
||||
int maxItemsInObjectGraph,
|
||||
bool ignoreExtensionDataObject,
|
||||
bool preserveObjectReferences,
|
||||
IDataContractSurrogate dataContractSurrogate,
|
||||
DataContractResolver dataContractResolver,
|
||||
bool serializeReadOnlyTypes)
|
||||
{
|
||||
_rootType = type ?? throw new ArgumentNullException(nameof(type));
|
||||
|
||||
if (knownTypes != null)
|
||||
{
|
||||
knownTypeList = new List<Type>();
|
||||
foreach (Type knownType in knownTypes)
|
||||
{
|
||||
knownTypeList.Add(knownType);
|
||||
}
|
||||
}
|
||||
|
||||
if (maxItemsInObjectGraph < 0)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException(nameof(maxItemsInObjectGraph), SR.ValueMustBeNonNegative));
|
||||
}
|
||||
|
||||
this.maxItemsInObjectGraph = maxItemsInObjectGraph;
|
||||
|
||||
this.ignoreExtensionDataObject = ignoreExtensionDataObject;
|
||||
this.preserveObjectReferences = preserveObjectReferences;
|
||||
this.dataContractSurrogate = dataContractSurrogate;
|
||||
this.dataContractResolver = dataContractResolver;
|
||||
this.serializeReadOnlyTypes = serializeReadOnlyTypes;
|
||||
}
|
||||
|
||||
private void Initialize(Type type, XmlDictionaryString rootName, XmlDictionaryString rootNamespace,
|
||||
IEnumerable<Type> knownTypes,
|
||||
int maxItemsInObjectGraph,
|
||||
bool ignoreExtensionDataObject,
|
||||
bool preserveObjectReferences,
|
||||
IDataContractSurrogate dataContractSurrogate,
|
||||
DataContractResolver dataContractResolver,
|
||||
bool serializeReadOnlyTypes)
|
||||
{
|
||||
Initialize(type, knownTypes, maxItemsInObjectGraph, ignoreExtensionDataObject, preserveObjectReferences, dataContractSurrogate, dataContractResolver, serializeReadOnlyTypes);
|
||||
// validate root name and namespace are both non-null
|
||||
this.rootName = rootName;
|
||||
this.rootNamespace = rootNamespace;
|
||||
}
|
||||
|
||||
public ReadOnlyCollection<Type> KnownTypes
|
||||
{
|
||||
get
|
||||
{
|
||||
if (knownTypeCollection == null)
|
||||
{
|
||||
if (knownTypeList != null)
|
||||
{
|
||||
knownTypeCollection = new ReadOnlyCollection<Type>(knownTypeList);
|
||||
}
|
||||
else
|
||||
{
|
||||
knownTypeCollection = new ReadOnlyCollection<Type>(Globals.EmptyTypeArray);
|
||||
}
|
||||
}
|
||||
return knownTypeCollection;
|
||||
}
|
||||
}
|
||||
|
||||
internal override DataContractDictionary KnownDataContracts
|
||||
{
|
||||
get
|
||||
{
|
||||
if (knownDataContracts == null && knownTypeList != null)
|
||||
{
|
||||
// This assignment may be performed concurrently and thus is a race condition.
|
||||
// It's safe, however, because at worse a new (and identical) dictionary of
|
||||
// data contracts will be created and re-assigned to this field. Introduction
|
||||
// of a lock here could lead to deadlocks.
|
||||
knownDataContracts = XmlObjectSerializerContext.GetDataContractsForKnownTypes(knownTypeList);
|
||||
}
|
||||
return knownDataContracts;
|
||||
}
|
||||
}
|
||||
|
||||
public int MaxItemsInObjectGraph => maxItemsInObjectGraph;
|
||||
|
||||
public IDataContractSurrogate DataContractSurrogate => dataContractSurrogate;
|
||||
|
||||
public bool PreserveObjectReferences => preserveObjectReferences;
|
||||
|
||||
public bool IgnoreExtensionDataObject => ignoreExtensionDataObject;
|
||||
|
||||
public DataContractResolver DataContractResolver => dataContractResolver;
|
||||
|
||||
public bool SerializeReadOnlyTypes => serializeReadOnlyTypes;
|
||||
|
||||
private DataContract RootContract
|
||||
{
|
||||
get
|
||||
{
|
||||
if (rootContract == null)
|
||||
{
|
||||
rootContract = DataContract.GetDataContract(((dataContractSurrogate == null) ? _rootType : GetSurrogatedType(dataContractSurrogate, _rootType)));
|
||||
needsContractNsAtRoot = CheckIfNeedsContractNsAtRoot(rootName, rootNamespace, rootContract);
|
||||
}
|
||||
return rootContract;
|
||||
}
|
||||
}
|
||||
|
||||
internal override void InternalWriteObject(XmlWriterDelegator writer, object graph)
|
||||
{
|
||||
InternalWriteObject(writer, graph, null);
|
||||
}
|
||||
|
||||
internal override void InternalWriteObject(XmlWriterDelegator writer, object graph, DataContractResolver dataContractResolver)
|
||||
{
|
||||
InternalWriteStartObject(writer, graph);
|
||||
InternalWriteObjectContent(writer, graph, dataContractResolver);
|
||||
InternalWriteEndObject(writer);
|
||||
}
|
||||
|
||||
public override void WriteObject(XmlWriter writer, object graph)
|
||||
{
|
||||
WriteObjectHandleExceptions(new XmlWriterDelegator(writer), graph);
|
||||
}
|
||||
|
||||
public override void WriteStartObject(XmlWriter writer, object graph)
|
||||
{
|
||||
WriteStartObjectHandleExceptions(new XmlWriterDelegator(writer), graph);
|
||||
}
|
||||
|
||||
public override void WriteObjectContent(XmlWriter writer, object graph)
|
||||
{
|
||||
WriteObjectContentHandleExceptions(new XmlWriterDelegator(writer), graph);
|
||||
}
|
||||
|
||||
public override void WriteEndObject(XmlWriter writer)
|
||||
{
|
||||
WriteEndObjectHandleExceptions(new XmlWriterDelegator(writer));
|
||||
}
|
||||
|
||||
public override void WriteStartObject(XmlDictionaryWriter writer, object graph)
|
||||
{
|
||||
WriteStartObjectHandleExceptions(new XmlWriterDelegator(writer), graph);
|
||||
}
|
||||
|
||||
public override void WriteObjectContent(XmlDictionaryWriter writer, object graph)
|
||||
{
|
||||
WriteObjectContentHandleExceptions(new XmlWriterDelegator(writer), graph);
|
||||
}
|
||||
|
||||
public override void WriteEndObject(XmlDictionaryWriter writer)
|
||||
{
|
||||
WriteEndObjectHandleExceptions(new XmlWriterDelegator(writer));
|
||||
}
|
||||
|
||||
public void WriteObject(XmlDictionaryWriter writer, object graph, DataContractResolver dataContractResolver)
|
||||
{
|
||||
WriteObjectHandleExceptions(new XmlWriterDelegator(writer), graph, dataContractResolver);
|
||||
}
|
||||
|
||||
public override object ReadObject(XmlReader reader)
|
||||
{
|
||||
return ReadObjectHandleExceptions(new XmlReaderDelegator(reader), true /*verifyObjectName*/);
|
||||
}
|
||||
|
||||
public override object ReadObject(XmlReader reader, bool verifyObjectName)
|
||||
{
|
||||
return ReadObjectHandleExceptions(new XmlReaderDelegator(reader), verifyObjectName);
|
||||
}
|
||||
|
||||
public override bool IsStartObject(XmlReader reader)
|
||||
{
|
||||
return IsStartObjectHandleExceptions(new XmlReaderDelegator(reader));
|
||||
}
|
||||
|
||||
public override object ReadObject(XmlDictionaryReader reader, bool verifyObjectName)
|
||||
{
|
||||
return ReadObjectHandleExceptions(new XmlReaderDelegator(reader), verifyObjectName);
|
||||
}
|
||||
|
||||
public override bool IsStartObject(XmlDictionaryReader reader)
|
||||
{
|
||||
return IsStartObjectHandleExceptions(new XmlReaderDelegator(reader));
|
||||
}
|
||||
|
||||
public object ReadObject(XmlDictionaryReader reader, bool verifyObjectName, DataContractResolver dataContractResolver)
|
||||
{
|
||||
return ReadObjectHandleExceptions(new XmlReaderDelegator(reader), verifyObjectName, dataContractResolver);
|
||||
}
|
||||
|
||||
internal override void InternalWriteStartObject(XmlWriterDelegator writer, object graph)
|
||||
{
|
||||
WriteRootElement(writer, RootContract, rootName, rootNamespace, needsContractNsAtRoot);
|
||||
}
|
||||
|
||||
internal override void InternalWriteObjectContent(XmlWriterDelegator writer, object graph)
|
||||
{
|
||||
InternalWriteObjectContent(writer, graph, null);
|
||||
}
|
||||
|
||||
internal void InternalWriteObjectContent(XmlWriterDelegator writer, object graph, DataContractResolver dataContractResolver)
|
||||
{
|
||||
if (MaxItemsInObjectGraph == 0)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(SR.Format(SR.ExceededMaxItemsQuota, MaxItemsInObjectGraph)));
|
||||
}
|
||||
|
||||
DataContract contract = RootContract;
|
||||
Type declaredType = contract.UnderlyingType;
|
||||
Type graphType = (graph == null) ? declaredType : graph.GetType();
|
||||
|
||||
if (dataContractSurrogate != null)
|
||||
{
|
||||
graph = SurrogateToDataContractType(dataContractSurrogate, graph, declaredType, ref graphType);
|
||||
}
|
||||
|
||||
if (dataContractResolver == null)
|
||||
{
|
||||
dataContractResolver = DataContractResolver;
|
||||
}
|
||||
|
||||
if (graph == null)
|
||||
{
|
||||
if (IsRootXmlAny(rootName, contract))
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(SR.Format(SR.IsAnyCannotBeNull, declaredType)));
|
||||
}
|
||||
|
||||
WriteNull(writer);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (declaredType == graphType)
|
||||
{
|
||||
if (contract.CanContainReferences)
|
||||
{
|
||||
XmlObjectSerializerWriteContext context = XmlObjectSerializerWriteContext.CreateContext(this, contract, dataContractResolver);
|
||||
context.HandleGraphAtTopLevel(writer, graph, contract);
|
||||
context.SerializeWithoutXsiType(contract, writer, graph, declaredType.TypeHandle);
|
||||
}
|
||||
else
|
||||
{
|
||||
contract.WriteXmlValue(writer, graph, null);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
XmlObjectSerializerWriteContext context = null;
|
||||
if (IsRootXmlAny(rootName, contract))
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(SR.Format(SR.IsAnyCannotBeSerializedAsDerivedType, graphType, contract.UnderlyingType)));
|
||||
}
|
||||
|
||||
contract = GetDataContract(contract, declaredType, graphType);
|
||||
context = XmlObjectSerializerWriteContext.CreateContext(this, RootContract, dataContractResolver);
|
||||
if (contract.CanContainReferences)
|
||||
{
|
||||
context.HandleGraphAtTopLevel(writer, graph, contract);
|
||||
}
|
||||
context.OnHandleIsReference(writer, contract, graph);
|
||||
context.SerializeWithXsiTypeAtTopLevel(contract, writer, graph, declaredType.TypeHandle, graphType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal static DataContract GetDataContract(DataContract declaredTypeContract, Type declaredType, Type objectType)
|
||||
{
|
||||
if (declaredType.IsInterface && CollectionDataContract.IsCollectionInterface(declaredType))
|
||||
{
|
||||
return declaredTypeContract;
|
||||
}
|
||||
else if (declaredType.IsArray)//Array covariance is not supported in XSD
|
||||
{
|
||||
return declaredTypeContract;
|
||||
}
|
||||
else
|
||||
{
|
||||
return DataContract.GetDataContract(objectType.TypeHandle, objectType, SerializationMode.SharedContract);
|
||||
}
|
||||
}
|
||||
|
||||
internal void SetDataContractSurrogate(IDataContractSurrogate adapter)
|
||||
{
|
||||
dataContractSurrogate = adapter;
|
||||
}
|
||||
|
||||
internal override void InternalWriteEndObject(XmlWriterDelegator writer)
|
||||
{
|
||||
if (!IsRootXmlAny(rootName, RootContract))
|
||||
{
|
||||
writer.WriteEndElement();
|
||||
}
|
||||
}
|
||||
|
||||
internal override object InternalReadObject(XmlReaderDelegator xmlReader, bool verifyObjectName)
|
||||
{
|
||||
return InternalReadObject(xmlReader, verifyObjectName, null);
|
||||
}
|
||||
|
||||
internal override object InternalReadObject(XmlReaderDelegator xmlReader, bool verifyObjectName, DataContractResolver dataContractResolver)
|
||||
{
|
||||
if (MaxItemsInObjectGraph == 0)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(SR.Format(SR.ExceededMaxItemsQuota, MaxItemsInObjectGraph)));
|
||||
}
|
||||
|
||||
if (dataContractResolver == null)
|
||||
{
|
||||
dataContractResolver = DataContractResolver;
|
||||
}
|
||||
|
||||
if (verifyObjectName)
|
||||
{
|
||||
if (!InternalIsStartObject(xmlReader))
|
||||
{
|
||||
XmlDictionaryString expectedName;
|
||||
XmlDictionaryString expectedNs;
|
||||
if (rootName == null)
|
||||
{
|
||||
expectedName = RootContract.TopLevelElementName;
|
||||
expectedNs = RootContract.TopLevelElementNamespace;
|
||||
}
|
||||
else
|
||||
{
|
||||
expectedName = rootName;
|
||||
expectedNs = rootNamespace;
|
||||
}
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationExceptionWithReaderDetails(SR.Format(SR.ExpectingElement, expectedNs, expectedName), xmlReader));
|
||||
}
|
||||
}
|
||||
else if (!IsStartElement(xmlReader))
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationExceptionWithReaderDetails(SR.Format(SR.ExpectingElementAtDeserialize, XmlNodeType.Element), xmlReader));
|
||||
}
|
||||
|
||||
DataContract contract = RootContract;
|
||||
if (contract.IsPrimitive && object.ReferenceEquals(contract.UnderlyingType, _rootType) /*handle Nullable<T> differently*/)
|
||||
{
|
||||
return contract.ReadXmlValue(xmlReader, null);
|
||||
}
|
||||
|
||||
if (IsRootXmlAny(rootName, contract))
|
||||
{
|
||||
return XmlObjectSerializerReadContext.ReadRootIXmlSerializable(xmlReader, contract as XmlDataContract, false /*isMemberType*/);
|
||||
}
|
||||
|
||||
XmlObjectSerializerReadContext context = XmlObjectSerializerReadContext.CreateContext(this, contract, dataContractResolver);
|
||||
return context.InternalDeserialize(xmlReader, _rootType, contract, null, null);
|
||||
}
|
||||
|
||||
internal override bool InternalIsStartObject(XmlReaderDelegator reader)
|
||||
{
|
||||
return IsRootElement(reader, RootContract, rootName, rootNamespace);
|
||||
}
|
||||
|
||||
internal override Type GetSerializeType(object graph)
|
||||
{
|
||||
return (graph == null) ? _rootType : graph.GetType();
|
||||
}
|
||||
|
||||
internal override Type GetDeserializeType()
|
||||
{
|
||||
return _rootType;
|
||||
}
|
||||
|
||||
internal static object SurrogateToDataContractType(IDataContractSurrogate dataContractSurrogate, object oldObj, Type surrogatedDeclaredType, ref Type objType)
|
||||
{
|
||||
object obj = DataContractSurrogateCaller.GetObjectToSerialize(dataContractSurrogate, oldObj, objType, surrogatedDeclaredType);
|
||||
if (obj != oldObj)
|
||||
{
|
||||
if (obj == null)
|
||||
{
|
||||
objType = Globals.TypeOfObject;
|
||||
}
|
||||
else
|
||||
{
|
||||
objType = obj.GetType();
|
||||
}
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
internal static Type GetSurrogatedType(IDataContractSurrogate dataContractSurrogate, Type type)
|
||||
{
|
||||
return DataContractSurrogateCaller.GetDataContractType(dataContractSurrogate, DataContract.UnwrapNullableType(type));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Xml;
|
||||
using DataContractResolver = System.Runtime.Serialization.DataContractResolver;
|
||||
|
||||
namespace Compat.Runtime.Serialization
|
||||
{
|
||||
public class DataContractSerializerSettings
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets Dummy documentation
|
||||
/// </summary>
|
||||
public XmlDictionaryString RootName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets Dummy documentation
|
||||
/// </summary>
|
||||
public XmlDictionaryString RootNamespace { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets Dummy documentation
|
||||
/// </summary>
|
||||
public IEnumerable<Type> KnownTypes { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets Dummy documentation
|
||||
/// </summary>
|
||||
public int MaxItemsInObjectGraph { get; set; } = int.MaxValue;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether Dummy documentation
|
||||
/// </summary>
|
||||
public bool IgnoreExtensionDataObject { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether Dummy documentation
|
||||
/// </summary>
|
||||
public bool PreserveObjectReferences { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets Dummy documentation
|
||||
/// </summary>
|
||||
internal IDataContractSurrogate DataContractSurrogate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets Dummy documentation
|
||||
/// </summary>
|
||||
public DataContractResolver DataContractResolver { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether Dummy documentation
|
||||
/// </summary>
|
||||
public bool SerializeReadOnlyTypes { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,548 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Xml;
|
||||
using InvalidDataContractException = System.Runtime.Serialization.InvalidDataContractException;
|
||||
|
||||
namespace Compat.Runtime.Serialization
|
||||
{
|
||||
using DataContractDictionary = Dictionary<XmlQualifiedName, DataContract>;
|
||||
|
||||
|
||||
internal class DataContractSet
|
||||
{
|
||||
private Dictionary<XmlQualifiedName, DataContract> contracts;
|
||||
private Dictionary<DataContract, object> processedContracts;
|
||||
private readonly IDataContractSurrogate dataContractSurrogate;
|
||||
private Hashtable surrogateDataTable;
|
||||
private DataContractDictionary knownTypesForObject;
|
||||
private readonly ICollection<Type> referencedTypes;
|
||||
private readonly ICollection<Type> referencedCollectionTypes;
|
||||
private Dictionary<XmlQualifiedName, object> referencedTypesDictionary;
|
||||
private Dictionary<XmlQualifiedName, object> referencedCollectionTypesDictionary;
|
||||
|
||||
|
||||
internal DataContractSet(IDataContractSurrogate dataContractSurrogate) : this(dataContractSurrogate, null, null) { }
|
||||
|
||||
internal DataContractSet(IDataContractSurrogate dataContractSurrogate, ICollection<Type> referencedTypes, ICollection<Type> referencedCollectionTypes)
|
||||
{
|
||||
this.dataContractSurrogate = dataContractSurrogate;
|
||||
this.referencedTypes = referencedTypes;
|
||||
this.referencedCollectionTypes = referencedCollectionTypes;
|
||||
}
|
||||
|
||||
internal DataContractSet(DataContractSet dataContractSet)
|
||||
{
|
||||
if (dataContractSet == null)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("dataContractSet"));
|
||||
}
|
||||
|
||||
dataContractSurrogate = dataContractSet.dataContractSurrogate;
|
||||
referencedTypes = dataContractSet.referencedTypes;
|
||||
referencedCollectionTypes = dataContractSet.referencedCollectionTypes;
|
||||
|
||||
foreach (KeyValuePair<XmlQualifiedName, DataContract> pair in dataContractSet)
|
||||
{
|
||||
Add(pair.Key, pair.Value);
|
||||
}
|
||||
|
||||
if (dataContractSet.processedContracts != null)
|
||||
{
|
||||
foreach (KeyValuePair<DataContract, object> pair in dataContractSet.processedContracts)
|
||||
{
|
||||
ProcessedContracts.Add(pair.Key, pair.Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Dictionary<XmlQualifiedName, DataContract> Contracts
|
||||
{
|
||||
get
|
||||
{
|
||||
if (contracts == null)
|
||||
{
|
||||
contracts = new Dictionary<XmlQualifiedName, DataContract>();
|
||||
}
|
||||
return contracts;
|
||||
}
|
||||
}
|
||||
|
||||
private Dictionary<DataContract, object> ProcessedContracts
|
||||
{
|
||||
get
|
||||
{
|
||||
if (processedContracts == null)
|
||||
{
|
||||
processedContracts = new Dictionary<DataContract, object>();
|
||||
}
|
||||
return processedContracts;
|
||||
}
|
||||
}
|
||||
|
||||
private Hashtable SurrogateDataTable
|
||||
{
|
||||
get
|
||||
{
|
||||
if (surrogateDataTable == null)
|
||||
{
|
||||
surrogateDataTable = new Hashtable();
|
||||
}
|
||||
|
||||
return surrogateDataTable;
|
||||
}
|
||||
}
|
||||
|
||||
internal DataContractDictionary KnownTypesForObject
|
||||
{
|
||||
get => knownTypesForObject;
|
||||
set => knownTypesForObject = value;
|
||||
}
|
||||
|
||||
internal void Add(Type type)
|
||||
{
|
||||
DataContract dataContract = GetDataContract(type);
|
||||
EnsureTypeNotGeneric(dataContract.UnderlyingType);
|
||||
Add(dataContract);
|
||||
}
|
||||
|
||||
internal static void EnsureTypeNotGeneric(Type type)
|
||||
{
|
||||
if (type.ContainsGenericParameters)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.Format(SR.GenericTypeNotExportable, type)));
|
||||
}
|
||||
}
|
||||
|
||||
private void Add(DataContract dataContract)
|
||||
{
|
||||
Add(dataContract.StableName, dataContract);
|
||||
}
|
||||
|
||||
public void Add(XmlQualifiedName name, DataContract dataContract)
|
||||
{
|
||||
if (dataContract.IsBuiltInDataContract)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
InternalAdd(name, dataContract);
|
||||
}
|
||||
|
||||
internal void InternalAdd(XmlQualifiedName name, DataContract dataContract)
|
||||
{
|
||||
if (Contracts.TryGetValue(name, out DataContract dataContractInSet))
|
||||
{
|
||||
if (!dataContractInSet.Equals(dataContract))
|
||||
{
|
||||
if (dataContract.UnderlyingType == null || dataContractInSet.UnderlyingType == null)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.Format(SR.DupContractInDataContractSet, dataContract.StableName.Name, dataContract.StableName.Namespace)));
|
||||
}
|
||||
else
|
||||
{
|
||||
bool typeNamesEqual = (DataContract.GetClrTypeFullName(dataContract.UnderlyingType) == DataContract.GetClrTypeFullName(dataContractInSet.UnderlyingType));
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.Format(SR.DupTypeContractInDataContractSet, (typeNamesEqual ? dataContract.UnderlyingType.AssemblyQualifiedName : DataContract.GetClrTypeFullName(dataContract.UnderlyingType)), (typeNamesEqual ? dataContractInSet.UnderlyingType.AssemblyQualifiedName : DataContract.GetClrTypeFullName(dataContractInSet.UnderlyingType)), dataContract.StableName.Name, dataContract.StableName.Namespace)));
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Contracts.Add(name, dataContract);
|
||||
|
||||
if (dataContract is ClassDataContract)
|
||||
{
|
||||
AddClassDataContract((ClassDataContract)dataContract);
|
||||
}
|
||||
else if (dataContract is CollectionDataContract)
|
||||
{
|
||||
AddCollectionDataContract((CollectionDataContract)dataContract);
|
||||
}
|
||||
else if (dataContract is XmlDataContract)
|
||||
{
|
||||
AddXmlDataContract((XmlDataContract)dataContract);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void AddClassDataContract(ClassDataContract classDataContract)
|
||||
{
|
||||
if (classDataContract.BaseContract != null)
|
||||
{
|
||||
Add(classDataContract.BaseContract.StableName, classDataContract.BaseContract);
|
||||
}
|
||||
if (!classDataContract.IsISerializable)
|
||||
{
|
||||
if (classDataContract.Members != null)
|
||||
{
|
||||
for (int i = 0; i < classDataContract.Members.Count; i++)
|
||||
{
|
||||
DataMember dataMember = classDataContract.Members[i];
|
||||
DataContract memberDataContract = GetMemberTypeDataContract(dataMember);
|
||||
if (dataContractSurrogate != null && dataMember.MemberInfo != null)
|
||||
{
|
||||
object customData = DataContractSurrogateCaller.GetCustomDataToExport(
|
||||
dataContractSurrogate,
|
||||
dataMember.MemberInfo,
|
||||
memberDataContract.UnderlyingType);
|
||||
if (customData != null)
|
||||
{
|
||||
SurrogateDataTable.Add(dataMember, customData);
|
||||
}
|
||||
}
|
||||
Add(memberDataContract.StableName, memberDataContract);
|
||||
}
|
||||
}
|
||||
}
|
||||
AddKnownDataContracts(classDataContract.KnownDataContracts);
|
||||
}
|
||||
|
||||
private void AddCollectionDataContract(CollectionDataContract collectionDataContract)
|
||||
{
|
||||
if (collectionDataContract.IsDictionary)
|
||||
{
|
||||
ClassDataContract keyValueContract = collectionDataContract.ItemContract as ClassDataContract;
|
||||
AddClassDataContract(keyValueContract);
|
||||
}
|
||||
else
|
||||
{
|
||||
DataContract itemContract = GetItemTypeDataContract(collectionDataContract);
|
||||
if (itemContract != null)
|
||||
{
|
||||
Add(itemContract.StableName, itemContract);
|
||||
}
|
||||
}
|
||||
AddKnownDataContracts(collectionDataContract.KnownDataContracts);
|
||||
}
|
||||
|
||||
private void AddXmlDataContract(XmlDataContract xmlDataContract)
|
||||
{
|
||||
AddKnownDataContracts(xmlDataContract.KnownDataContracts);
|
||||
}
|
||||
|
||||
private void AddKnownDataContracts(DataContractDictionary knownDataContracts)
|
||||
{
|
||||
if (knownDataContracts != null)
|
||||
{
|
||||
foreach (DataContract knownDataContract in knownDataContracts.Values)
|
||||
{
|
||||
Add(knownDataContract);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal XmlQualifiedName GetStableName(Type clrType)
|
||||
{
|
||||
if (dataContractSurrogate != null)
|
||||
{
|
||||
Type dcType = DataContractSurrogateCaller.GetDataContractType(dataContractSurrogate, clrType);
|
||||
return DataContract.GetStableName(dcType);
|
||||
}
|
||||
return DataContract.GetStableName(clrType);
|
||||
}
|
||||
|
||||
internal DataContract GetDataContract(Type clrType)
|
||||
{
|
||||
if (dataContractSurrogate == null)
|
||||
{
|
||||
return DataContract.GetDataContract(clrType);
|
||||
}
|
||||
|
||||
DataContract dataContract = DataContract.GetBuiltInDataContract(clrType);
|
||||
if (dataContract != null)
|
||||
{
|
||||
return dataContract;
|
||||
}
|
||||
|
||||
Type dcType = DataContractSurrogateCaller.GetDataContractType(dataContractSurrogate, clrType);
|
||||
dataContract = DataContract.GetDataContract(dcType);
|
||||
if (!SurrogateDataTable.Contains(dataContract))
|
||||
{
|
||||
object customData = DataContractSurrogateCaller.GetCustomDataToExport(
|
||||
dataContractSurrogate, clrType, dcType);
|
||||
if (customData != null)
|
||||
{
|
||||
SurrogateDataTable.Add(dataContract, customData);
|
||||
}
|
||||
}
|
||||
return dataContract;
|
||||
}
|
||||
|
||||
internal DataContract GetMemberTypeDataContract(DataMember dataMember)
|
||||
{
|
||||
if (dataMember.MemberInfo != null)
|
||||
{
|
||||
Type dataMemberType = dataMember.MemberType;
|
||||
if (dataMember.IsGetOnlyCollection)
|
||||
{
|
||||
if (dataContractSurrogate != null)
|
||||
{
|
||||
Type dcType = DataContractSurrogateCaller.GetDataContractType(dataContractSurrogate, dataMemberType);
|
||||
if (dcType != dataMemberType)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.Format(SR.SurrogatesWithGetOnlyCollectionsNotSupported,
|
||||
DataContract.GetClrTypeFullName(dataMemberType), DataContract.GetClrTypeFullName(dataMember.MemberInfo.DeclaringType), dataMember.MemberInfo.Name)));
|
||||
}
|
||||
}
|
||||
return DataContract.GetGetOnlyCollectionDataContract(DataContract.GetId(dataMemberType.TypeHandle), dataMemberType.TypeHandle, dataMemberType, SerializationMode.SharedContract);
|
||||
}
|
||||
else
|
||||
{
|
||||
return GetDataContract(dataMemberType);
|
||||
}
|
||||
}
|
||||
return dataMember.MemberTypeContract;
|
||||
}
|
||||
|
||||
internal DataContract GetItemTypeDataContract(CollectionDataContract collectionContract)
|
||||
{
|
||||
if (collectionContract.ItemType != null)
|
||||
{
|
||||
return GetDataContract(collectionContract.ItemType);
|
||||
}
|
||||
|
||||
return collectionContract.ItemContract;
|
||||
}
|
||||
|
||||
internal object GetSurrogateData(object key)
|
||||
{
|
||||
return SurrogateDataTable[key];
|
||||
}
|
||||
|
||||
internal void SetSurrogateData(object key, object surrogateData)
|
||||
{
|
||||
SurrogateDataTable[key] = surrogateData;
|
||||
}
|
||||
|
||||
public DataContract this[XmlQualifiedName key]
|
||||
{
|
||||
get
|
||||
{
|
||||
DataContract dataContract = DataContract.GetBuiltInDataContract(key.Name, key.Namespace);
|
||||
if (dataContract == null)
|
||||
{
|
||||
Contracts.TryGetValue(key, out dataContract);
|
||||
}
|
||||
return dataContract;
|
||||
}
|
||||
}
|
||||
|
||||
public IDataContractSurrogate DataContractSurrogate => dataContractSurrogate;
|
||||
|
||||
public bool Remove(XmlQualifiedName key)
|
||||
{
|
||||
if (DataContract.GetBuiltInDataContract(key.Name, key.Namespace) != null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return Contracts.Remove(key);
|
||||
}
|
||||
|
||||
public IEnumerator<KeyValuePair<XmlQualifiedName, DataContract>> GetEnumerator()
|
||||
{
|
||||
return Contracts.GetEnumerator();
|
||||
}
|
||||
|
||||
internal bool IsContractProcessed(DataContract dataContract)
|
||||
{
|
||||
return ProcessedContracts.ContainsKey(dataContract);
|
||||
}
|
||||
|
||||
internal void SetContractProcessed(DataContract dataContract)
|
||||
{
|
||||
ProcessedContracts.Add(dataContract, dataContract);
|
||||
}
|
||||
|
||||
private Dictionary<XmlQualifiedName, object> GetReferencedTypes()
|
||||
{
|
||||
if (referencedTypesDictionary == null)
|
||||
{
|
||||
referencedTypesDictionary = new Dictionary<XmlQualifiedName, object>
|
||||
{
|
||||
//Always include Nullable as referenced type
|
||||
//Do not allow surrogating Nullable<T>
|
||||
{ DataContract.GetStableName(Globals.TypeOfNullable), Globals.TypeOfNullable }
|
||||
};
|
||||
if (referencedTypes != null)
|
||||
{
|
||||
foreach (Type type in referencedTypes)
|
||||
{
|
||||
if (type == null)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.ReferencedTypesCannotContainNull));
|
||||
}
|
||||
|
||||
AddReferencedType(referencedTypesDictionary, type);
|
||||
}
|
||||
}
|
||||
}
|
||||
return referencedTypesDictionary;
|
||||
}
|
||||
|
||||
private Dictionary<XmlQualifiedName, object> GetReferencedCollectionTypes()
|
||||
{
|
||||
if (referencedCollectionTypesDictionary == null)
|
||||
{
|
||||
referencedCollectionTypesDictionary = new Dictionary<XmlQualifiedName, object>();
|
||||
if (referencedCollectionTypes != null)
|
||||
{
|
||||
foreach (Type type in referencedCollectionTypes)
|
||||
{
|
||||
if (type == null)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.ReferencedCollectionTypesCannotContainNull));
|
||||
}
|
||||
|
||||
AddReferencedType(referencedCollectionTypesDictionary, type);
|
||||
}
|
||||
}
|
||||
XmlQualifiedName genericDictionaryName = DataContract.GetStableName(Globals.TypeOfDictionaryGeneric);
|
||||
if (!referencedCollectionTypesDictionary.ContainsKey(genericDictionaryName) && GetReferencedTypes().ContainsKey(genericDictionaryName))
|
||||
{
|
||||
AddReferencedType(referencedCollectionTypesDictionary, Globals.TypeOfDictionaryGeneric);
|
||||
}
|
||||
}
|
||||
return referencedCollectionTypesDictionary;
|
||||
}
|
||||
|
||||
private void AddReferencedType(Dictionary<XmlQualifiedName, object> referencedTypes, Type type)
|
||||
{
|
||||
if (IsTypeReferenceable(type))
|
||||
{
|
||||
XmlQualifiedName stableName;
|
||||
try
|
||||
{
|
||||
stableName = GetStableName(type);
|
||||
}
|
||||
catch (InvalidDataContractException)
|
||||
{
|
||||
// Type not referenceable if we can't get a stable name.
|
||||
return;
|
||||
}
|
||||
catch (InvalidOperationException)
|
||||
{
|
||||
// Type not referenceable if we can't get a stable name.
|
||||
return;
|
||||
}
|
||||
|
||||
if (referencedTypes.TryGetValue(stableName, out object value))
|
||||
{
|
||||
Type referencedType = value as Type;
|
||||
if (referencedType != null)
|
||||
{
|
||||
if (referencedType != type)
|
||||
{
|
||||
referencedTypes.Remove(stableName);
|
||||
List<Type> types = new List<Type>
|
||||
{
|
||||
referencedType,
|
||||
type
|
||||
};
|
||||
referencedTypes.Add(stableName, types);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
List<Type> types = (List<Type>)value;
|
||||
if (!types.Contains(type))
|
||||
{
|
||||
types.Add(type);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
referencedTypes.Add(stableName, type);
|
||||
}
|
||||
}
|
||||
}
|
||||
internal bool TryGetReferencedType(XmlQualifiedName stableName, DataContract dataContract, out Type type)
|
||||
{
|
||||
return TryGetReferencedType(stableName, dataContract, false/*useReferencedCollectionTypes*/, out type);
|
||||
}
|
||||
|
||||
internal bool TryGetReferencedCollectionType(XmlQualifiedName stableName, DataContract dataContract, out Type type)
|
||||
{
|
||||
return TryGetReferencedType(stableName, dataContract, true/*useReferencedCollectionTypes*/, out type);
|
||||
}
|
||||
|
||||
private bool TryGetReferencedType(XmlQualifiedName stableName, DataContract dataContract, bool useReferencedCollectionTypes, out Type type)
|
||||
{
|
||||
Dictionary<XmlQualifiedName, object> referencedTypes = useReferencedCollectionTypes ? GetReferencedCollectionTypes() : GetReferencedTypes();
|
||||
if (referencedTypes.TryGetValue(stableName, out object value))
|
||||
{
|
||||
type = value as Type;
|
||||
if (type != null)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Throw ambiguous type match exception
|
||||
List<Type> types = (List<Type>)value;
|
||||
StringBuilder errorMessage = new StringBuilder();
|
||||
bool containsGenericType = false;
|
||||
for (int i = 0; i < types.Count; i++)
|
||||
{
|
||||
Type conflictingType = types[i];
|
||||
if (!containsGenericType)
|
||||
{
|
||||
containsGenericType = conflictingType.IsGenericTypeDefinition;
|
||||
}
|
||||
|
||||
errorMessage.AppendFormat("{0}\"{1}\" ", Environment.NewLine, conflictingType.AssemblyQualifiedName);
|
||||
if (dataContract != null)
|
||||
{
|
||||
DataContract other = GetDataContract(conflictingType);
|
||||
errorMessage.Append(SR.Format(((other != null && other.Equals(dataContract)) ? SR.ReferencedTypeMatchingMessage : SR.ReferencedTypeNotMatchingMessage)));
|
||||
}
|
||||
}
|
||||
if (containsGenericType)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.Format(
|
||||
(useReferencedCollectionTypes ? SR.AmbiguousReferencedCollectionTypes1 : SR.AmbiguousReferencedTypes1),
|
||||
errorMessage.ToString())));
|
||||
}
|
||||
else
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.Format(
|
||||
(useReferencedCollectionTypes ? SR.AmbiguousReferencedCollectionTypes3 : SR.AmbiguousReferencedTypes3),
|
||||
XmlConvert.DecodeName(stableName.Name),
|
||||
stableName.Namespace,
|
||||
errorMessage.ToString())));
|
||||
}
|
||||
}
|
||||
}
|
||||
type = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
private static bool IsTypeReferenceable(Type type)
|
||||
{
|
||||
|
||||
try
|
||||
{
|
||||
return (type.IsSerializable ||
|
||||
type.IsDefined(Globals.TypeOfDataContractAttribute, false) ||
|
||||
(Globals.TypeOfIXmlSerializable.IsAssignableFrom(type) && !type.IsGenericTypeDefinition) ||
|
||||
CollectionDataContract.IsCollection(type, out Type itemType) ||
|
||||
ClassDataContract.IsNonAttributedTypeValidForSerialization(type));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// An exception can be thrown in the designer when a project has a runtime binding redirection for a referenced assembly or a reference dependent assembly.
|
||||
// Type.IsDefined is known to throw System.IO.FileLoadException.
|
||||
// ClassDataContract.IsNonAttributedTypeValidForSerialization is known to throw System.IO.FileNotFoundException.
|
||||
// We guard against all non-critical exceptions.
|
||||
if (Fx.IsFatal(ex))
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
using System;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Reflection;
|
||||
|
||||
namespace Compat.Runtime.Serialization
|
||||
{
|
||||
internal static class DataContractSurrogateCaller
|
||||
{
|
||||
internal static Type GetDataContractType(IDataContractSurrogate surrogate, Type type)
|
||||
{
|
||||
if (DataContract.GetBuiltInDataContract(type) != null)
|
||||
{
|
||||
return type;
|
||||
}
|
||||
|
||||
Type dcType = surrogate.GetDataContractType(type);
|
||||
if (dcType == null)
|
||||
{
|
||||
return type;
|
||||
}
|
||||
|
||||
return dcType;
|
||||
|
||||
}
|
||||
internal static object GetObjectToSerialize(IDataContractSurrogate surrogate, object obj, Type objType, Type membertype)
|
||||
{
|
||||
if (obj == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (DataContract.GetBuiltInDataContract(objType) != null)
|
||||
{
|
||||
return obj;
|
||||
}
|
||||
|
||||
return surrogate.GetObjectToSerialize(obj, membertype);
|
||||
}
|
||||
internal static object GetDeserializedObject(IDataContractSurrogate surrogate, object obj, Type objType, Type memberType)
|
||||
{
|
||||
if (obj == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (DataContract.GetBuiltInDataContract(objType) != null)
|
||||
{
|
||||
return obj;
|
||||
}
|
||||
|
||||
return surrogate.GetDeserializedObject(obj, memberType);
|
||||
}
|
||||
internal static object GetCustomDataToExport(IDataContractSurrogate surrogate, MemberInfo memberInfo, Type dataContractType)
|
||||
{
|
||||
return surrogate.GetCustomDataToExport(memberInfo, dataContractType);
|
||||
}
|
||||
internal static object GetCustomDataToExport(IDataContractSurrogate surrogate, Type clrType, Type dataContractType)
|
||||
{
|
||||
if (DataContract.GetBuiltInDataContract(clrType) != null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return surrogate.GetCustomDataToExport(clrType, dataContractType);
|
||||
}
|
||||
internal static void GetKnownCustomDataTypes(IDataContractSurrogate surrogate, Collection<Type> customDataTypes)
|
||||
{
|
||||
surrogate.GetKnownCustomDataTypes(customDataTypes);
|
||||
}
|
||||
internal static Type GetReferencedTypeOnImport(IDataContractSurrogate surrogate, string typeName, string typeNamespace, object customData)
|
||||
{
|
||||
if (DataContract.GetBuiltInDataContract(typeName, typeNamespace) != null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return surrogate.GetReferencedTypeOnImport(typeName, typeNamespace, customData);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,295 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
|
||||
namespace Compat.Runtime.Serialization
|
||||
{
|
||||
internal class DataMember
|
||||
{
|
||||
private readonly CriticalHelper helper;
|
||||
|
||||
internal DataMember()
|
||||
{
|
||||
helper = new CriticalHelper();
|
||||
}
|
||||
|
||||
internal DataMember(MemberInfo memberInfo)
|
||||
{
|
||||
helper = new CriticalHelper(memberInfo);
|
||||
}
|
||||
|
||||
internal DataMember(string name)
|
||||
{
|
||||
helper = new CriticalHelper(name);
|
||||
}
|
||||
|
||||
internal DataMember(DataContract memberTypeContract, string name, bool isNullable, bool isRequired, bool emitDefaultValue, int order)
|
||||
{
|
||||
helper = new CriticalHelper(memberTypeContract, name, isNullable, isRequired, emitDefaultValue, order);
|
||||
}
|
||||
|
||||
internal MemberInfo MemberInfo => helper.MemberInfo;
|
||||
|
||||
internal string Name
|
||||
{
|
||||
get => helper.Name;
|
||||
set => helper.Name = value;
|
||||
}
|
||||
|
||||
internal int Order
|
||||
{
|
||||
get => helper.Order;
|
||||
set => helper.Order = value;
|
||||
}
|
||||
|
||||
internal bool IsRequired
|
||||
{
|
||||
get => helper.IsRequired;
|
||||
set => helper.IsRequired = value;
|
||||
}
|
||||
|
||||
internal bool EmitDefaultValue
|
||||
{
|
||||
get => helper.EmitDefaultValue;
|
||||
set => helper.EmitDefaultValue = value;
|
||||
}
|
||||
|
||||
internal bool IsNullable
|
||||
{
|
||||
get => helper.IsNullable;
|
||||
set => helper.IsNullable = value;
|
||||
}
|
||||
|
||||
internal bool IsGetOnlyCollection
|
||||
{
|
||||
get => helper.IsGetOnlyCollection;
|
||||
set => helper.IsGetOnlyCollection = value;
|
||||
}
|
||||
|
||||
internal Type MemberType => helper.MemberType;
|
||||
|
||||
internal DataContract MemberTypeContract
|
||||
{
|
||||
get => helper.MemberTypeContract;
|
||||
set => helper.MemberTypeContract = value;
|
||||
}
|
||||
|
||||
internal bool HasConflictingNameAndType
|
||||
{
|
||||
get => helper.HasConflictingNameAndType;
|
||||
set => helper.HasConflictingNameAndType = value;
|
||||
}
|
||||
|
||||
internal DataMember ConflictingMember
|
||||
{
|
||||
get => helper.ConflictingMember;
|
||||
set => helper.ConflictingMember = value;
|
||||
}
|
||||
|
||||
private class CriticalHelper
|
||||
{
|
||||
private DataContract memberTypeContract;
|
||||
private string name;
|
||||
private int order;
|
||||
private bool isRequired;
|
||||
private bool emitDefaultValue;
|
||||
private bool isNullable;
|
||||
private bool isGetOnlyCollection = false;
|
||||
private readonly MemberInfo memberInfo;
|
||||
private bool hasConflictingNameAndType;
|
||||
private DataMember conflictingMember;
|
||||
|
||||
internal CriticalHelper()
|
||||
{
|
||||
emitDefaultValue = Globals.DefaultEmitDefaultValue;
|
||||
}
|
||||
|
||||
internal CriticalHelper(MemberInfo memberInfo)
|
||||
{
|
||||
emitDefaultValue = Globals.DefaultEmitDefaultValue;
|
||||
this.memberInfo = memberInfo;
|
||||
}
|
||||
|
||||
internal CriticalHelper(string name)
|
||||
{
|
||||
Name = name;
|
||||
}
|
||||
|
||||
internal CriticalHelper(DataContract memberTypeContract, string name, bool isNullable, bool isRequired, bool emitDefaultValue, int order)
|
||||
{
|
||||
MemberTypeContract = memberTypeContract;
|
||||
Name = name;
|
||||
IsNullable = isNullable;
|
||||
IsRequired = isRequired;
|
||||
EmitDefaultValue = emitDefaultValue;
|
||||
Order = order;
|
||||
}
|
||||
|
||||
internal MemberInfo MemberInfo => memberInfo;
|
||||
|
||||
internal string Name
|
||||
{
|
||||
get => name;
|
||||
set => name = value;
|
||||
}
|
||||
|
||||
internal int Order
|
||||
{
|
||||
get => order;
|
||||
set => order = value;
|
||||
}
|
||||
|
||||
internal bool IsRequired
|
||||
{
|
||||
get => isRequired;
|
||||
set => isRequired = value;
|
||||
}
|
||||
|
||||
internal bool EmitDefaultValue
|
||||
{
|
||||
get => emitDefaultValue;
|
||||
set => emitDefaultValue = value;
|
||||
}
|
||||
|
||||
internal bool IsNullable
|
||||
{
|
||||
get => isNullable;
|
||||
set => isNullable = value;
|
||||
}
|
||||
|
||||
internal bool IsGetOnlyCollection
|
||||
{
|
||||
get => isGetOnlyCollection;
|
||||
set => isGetOnlyCollection = value;
|
||||
}
|
||||
|
||||
internal Type MemberType
|
||||
{
|
||||
get
|
||||
{
|
||||
FieldInfo field = MemberInfo as FieldInfo;
|
||||
if (field != null)
|
||||
{
|
||||
return field.FieldType;
|
||||
}
|
||||
|
||||
return ((PropertyInfo)MemberInfo).PropertyType;
|
||||
}
|
||||
}
|
||||
|
||||
internal DataContract MemberTypeContract
|
||||
{
|
||||
get
|
||||
{
|
||||
if (memberTypeContract == null)
|
||||
{
|
||||
if (MemberInfo != null)
|
||||
{
|
||||
if (IsGetOnlyCollection)
|
||||
{
|
||||
memberTypeContract = DataContract.GetGetOnlyCollectionDataContract(DataContract.GetId(MemberType.TypeHandle), MemberType.TypeHandle, MemberType, SerializationMode.SharedContract);
|
||||
}
|
||||
else
|
||||
{
|
||||
memberTypeContract = DataContract.GetDataContract(MemberType);
|
||||
}
|
||||
}
|
||||
}
|
||||
return memberTypeContract;
|
||||
}
|
||||
set => memberTypeContract = value;
|
||||
}
|
||||
|
||||
internal bool HasConflictingNameAndType
|
||||
{
|
||||
get => hasConflictingNameAndType;
|
||||
set => hasConflictingNameAndType = value;
|
||||
}
|
||||
|
||||
internal DataMember ConflictingMember
|
||||
{
|
||||
get => conflictingMember;
|
||||
set => conflictingMember = value;
|
||||
}
|
||||
}
|
||||
|
||||
internal bool RequiresMemberAccessForGet()
|
||||
{
|
||||
MemberInfo memberInfo = MemberInfo;
|
||||
FieldInfo field = memberInfo as FieldInfo;
|
||||
if (field != null)
|
||||
{
|
||||
return DataContract.FieldRequiresMemberAccess(field);
|
||||
}
|
||||
else
|
||||
{
|
||||
PropertyInfo property = (PropertyInfo)memberInfo;
|
||||
MethodInfo getMethod = property.GetGetMethod(true /*nonPublic*/);
|
||||
if (getMethod != null)
|
||||
{
|
||||
return DataContract.MethodRequiresMemberAccess(getMethod) || !DataContract.IsTypeVisible(property.PropertyType);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
internal bool RequiresMemberAccessForSet()
|
||||
{
|
||||
MemberInfo memberInfo = MemberInfo;
|
||||
FieldInfo field = memberInfo as FieldInfo;
|
||||
if (field != null)
|
||||
{
|
||||
return DataContract.FieldRequiresMemberAccess(field);
|
||||
}
|
||||
else
|
||||
{
|
||||
PropertyInfo property = (PropertyInfo)memberInfo;
|
||||
MethodInfo setMethod = property.GetSetMethod(true /*nonPublic*/);
|
||||
if (setMethod != null)
|
||||
{
|
||||
return DataContract.MethodRequiresMemberAccess(setMethod) || !DataContract.IsTypeVisible(property.PropertyType);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
internal DataMember BindGenericParameters(DataContract[] paramContracts, Dictionary<DataContract, DataContract> boundContracts)
|
||||
{
|
||||
DataContract memberTypeContract = MemberTypeContract.BindGenericParameters(paramContracts, boundContracts);
|
||||
DataMember boundDataMember = new DataMember(memberTypeContract,
|
||||
Name,
|
||||
!memberTypeContract.IsValueType,
|
||||
IsRequired,
|
||||
EmitDefaultValue,
|
||||
Order);
|
||||
return boundDataMember;
|
||||
}
|
||||
|
||||
internal bool Equals(object other, Dictionary<DataContractPairKey, object> checkedContracts)
|
||||
{
|
||||
if ((object)this == other)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
DataMember dataMember = other as DataMember;
|
||||
if (dataMember != null)
|
||||
{
|
||||
// Note: comparison does not use Order hint since it influences element order but does not specify exact order
|
||||
bool thisIsNullable = (MemberTypeContract == null) ? false : !MemberTypeContract.IsValueType;
|
||||
bool dataMemberIsNullable = (dataMember.MemberTypeContract == null) ? false : !dataMember.MemberTypeContract.IsValueType;
|
||||
return (Name == dataMember.Name
|
||||
&& (IsNullable || thisIsNullable) == (dataMember.IsNullable || dataMemberIsNullable)
|
||||
&& IsRequired == dataMember.IsRequired
|
||||
&& EmitDefaultValue == dataMember.EmitDefaultValue
|
||||
&& MemberTypeContract.Equals(dataMember.MemberTypeContract, checkedContracts));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return base.GetHashCode();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,132 @@
|
||||
using System;
|
||||
using System.Globalization;
|
||||
|
||||
namespace Compat.Runtime.Serialization
|
||||
{
|
||||
internal class DataNode<T> : IDataNode
|
||||
{
|
||||
protected Type dataType;
|
||||
private T _value;
|
||||
private string _dataContractName;
|
||||
private string _dataContractNamespace;
|
||||
private string _clrTypeName;
|
||||
private string _clrAssemblyName;
|
||||
private string _id = Globals.NewObjectId;
|
||||
private bool _isFinalValue;
|
||||
|
||||
internal DataNode()
|
||||
{
|
||||
dataType = typeof(T);
|
||||
_isFinalValue = true;
|
||||
}
|
||||
|
||||
internal DataNode(T value)
|
||||
: this()
|
||||
{
|
||||
_value = value;
|
||||
}
|
||||
|
||||
public Type DataType => dataType;
|
||||
|
||||
public object Value
|
||||
{
|
||||
get => _value;
|
||||
set => _value = (T)value;
|
||||
}
|
||||
|
||||
bool IDataNode.IsFinalValue
|
||||
{
|
||||
get => _isFinalValue;
|
||||
set => _isFinalValue = value;
|
||||
}
|
||||
|
||||
public T GetValue()
|
||||
{
|
||||
return _value;
|
||||
}
|
||||
|
||||
public string DataContractName
|
||||
{
|
||||
get => _dataContractName;
|
||||
set => _dataContractName = value;
|
||||
}
|
||||
|
||||
public string DataContractNamespace
|
||||
{
|
||||
get => _dataContractNamespace;
|
||||
set => _dataContractNamespace = value;
|
||||
}
|
||||
|
||||
public string ClrTypeName
|
||||
{
|
||||
get => _clrTypeName;
|
||||
set => _clrTypeName = value;
|
||||
}
|
||||
|
||||
public string ClrAssemblyName
|
||||
{
|
||||
get => _clrAssemblyName;
|
||||
set => _clrAssemblyName = value;
|
||||
}
|
||||
|
||||
public bool PreservesReferences => (Id != Globals.NewObjectId);
|
||||
|
||||
public string Id
|
||||
{
|
||||
get => _id;
|
||||
set => _id = value;
|
||||
}
|
||||
|
||||
public virtual void GetData(ElementData element)
|
||||
{
|
||||
element.dataNode = this;
|
||||
element.attributeCount = 0;
|
||||
element.childElementIndex = 0;
|
||||
|
||||
if (DataContractName != null)
|
||||
{
|
||||
AddQualifiedNameAttribute(element, Globals.XsiPrefix, Globals.XsiTypeLocalName, Globals.SchemaInstanceNamespace, DataContractName, DataContractNamespace);
|
||||
}
|
||||
|
||||
if (ClrTypeName != null)
|
||||
{
|
||||
element.AddAttribute(Globals.SerPrefix, Globals.SerializationNamespace, Globals.ClrTypeLocalName, ClrTypeName);
|
||||
}
|
||||
|
||||
if (ClrAssemblyName != null)
|
||||
{
|
||||
element.AddAttribute(Globals.SerPrefix, Globals.SerializationNamespace, Globals.ClrAssemblyLocalName, ClrAssemblyName);
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void Clear()
|
||||
{
|
||||
// dataContractName not cleared because it is used when re-serializing from unknown data
|
||||
_clrTypeName = _clrAssemblyName = null;
|
||||
}
|
||||
|
||||
internal void AddQualifiedNameAttribute(ElementData element, string elementPrefix, string elementName, string elementNs, string valueName, string valueNs)
|
||||
{
|
||||
string prefix = ExtensionDataReader.GetPrefix(valueNs);
|
||||
element.AddAttribute(elementPrefix, elementNs, elementName, string.Format(CultureInfo.InvariantCulture, "{0}:{1}", prefix, valueName));
|
||||
|
||||
bool prefixDeclaredOnElement = false;
|
||||
if (element.attributes != null)
|
||||
{
|
||||
for (int i = 0; i < element.attributes.Length; i++)
|
||||
{
|
||||
AttributeData attribute = element.attributes[i];
|
||||
if (attribute != null && attribute.prefix == Globals.XmlnsPrefix && attribute.localName == prefix)
|
||||
{
|
||||
prefixDeclaredOnElement = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!prefixDeclaredOnElement)
|
||||
{
|
||||
element.AddAttribute(Globals.XmlnsPrefix, Globals.XmlnsNamespace, prefix, valueNs);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
using Compat.Xml;
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using DataContractAttribute = System.Runtime.Serialization.DataContractAttribute;
|
||||
using DataMemberAttribute = System.Runtime.Serialization.DataMemberAttribute;
|
||||
|
||||
namespace Compat.Runtime.Serialization
|
||||
{
|
||||
[DataContract(Name = "DateTimeOffset", Namespace = "http://schemas.datacontract.org/2004/07/System")]
|
||||
internal struct DateTimeOffsetAdapter
|
||||
{
|
||||
private DateTime _utcDateTime;
|
||||
private short _offsetMinutes;
|
||||
|
||||
public DateTimeOffsetAdapter(DateTime dateTime, short offsetMinutes)
|
||||
{
|
||||
_utcDateTime = dateTime;
|
||||
_offsetMinutes = offsetMinutes;
|
||||
}
|
||||
|
||||
[DataMember(Name = "DateTime", IsRequired = true)]
|
||||
public DateTime UtcDateTime
|
||||
{
|
||||
get => _utcDateTime;
|
||||
set => _utcDateTime = value;
|
||||
}
|
||||
|
||||
[DataMember(Name = "OffsetMinutes", IsRequired = true)]
|
||||
public short OffsetMinutes
|
||||
{
|
||||
get => _offsetMinutes;
|
||||
set => _offsetMinutes = value;
|
||||
}
|
||||
|
||||
public static DateTimeOffset GetDateTimeOffset(DateTimeOffsetAdapter value)
|
||||
{
|
||||
try
|
||||
{
|
||||
switch (value.UtcDateTime.Kind)
|
||||
{
|
||||
case DateTimeKind.Unspecified:
|
||||
return new DateTimeOffset(value.UtcDateTime, new TimeSpan(0, value.OffsetMinutes, 0));
|
||||
|
||||
//DateTimeKind.Utc and DateTimeKind.Local
|
||||
//Read in deserialized DateTime portion of the DateTimeOffsetAdapter and convert DateTimeKind to Unspecified.
|
||||
//Apply ofset information read from OffsetMinutes portion of the DateTimeOffsetAdapter.
|
||||
//Return converted DateTimeoffset object.
|
||||
default:
|
||||
DateTimeOffset deserialized = new DateTimeOffset(value.UtcDateTime);
|
||||
return deserialized.ToOffset(new TimeSpan(0, value.OffsetMinutes, 0));
|
||||
}
|
||||
}
|
||||
catch (ArgumentException exception)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlExceptionHelper.CreateConversionException(value.ToString(CultureInfo.InvariantCulture), "DateTimeOffset", exception));
|
||||
}
|
||||
}
|
||||
|
||||
public static DateTimeOffsetAdapter GetDateTimeOffsetAdapter(DateTimeOffset value)
|
||||
{
|
||||
return new DateTimeOffsetAdapter(value.UtcDateTime, (short)value.Offset.TotalMinutes);
|
||||
}
|
||||
|
||||
public string ToString(IFormatProvider provider)
|
||||
{
|
||||
return "DateTime: " + UtcDateTime + ", Offset: " + OffsetMinutes;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace Compat.Runtime.Serialization
|
||||
{
|
||||
internal class DiagnosticUtility
|
||||
{
|
||||
public class ExceptionUtility
|
||||
{
|
||||
internal static Exception ThrowHelperFatal(string message, Exception innerException)
|
||||
{
|
||||
return ThrowHelperError(new FatalException(message, innerException));
|
||||
}
|
||||
|
||||
internal static Exception ThrowHelperError(Exception exception)
|
||||
{
|
||||
return ThrowHelper(exception, TraceEventType.Error);
|
||||
}
|
||||
|
||||
internal static Exception ThrowHelper(Exception exception, TraceEventType eventType)
|
||||
{
|
||||
return exception;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,178 @@
|
||||
using System;
|
||||
using System.Xml;
|
||||
|
||||
namespace Compat.Runtime.Serialization
|
||||
{
|
||||
internal static class DictionaryGlobals
|
||||
{
|
||||
public readonly static XmlDictionaryString EmptyString;
|
||||
public readonly static XmlDictionaryString SchemaInstanceNamespace;
|
||||
public readonly static XmlDictionaryString SchemaNamespace;
|
||||
public readonly static XmlDictionaryString SerializationNamespace;
|
||||
public readonly static XmlDictionaryString XmlnsNamespace;
|
||||
public readonly static XmlDictionaryString XsiTypeLocalName;
|
||||
public readonly static XmlDictionaryString XsiNilLocalName;
|
||||
public readonly static XmlDictionaryString ClrTypeLocalName;
|
||||
public readonly static XmlDictionaryString ClrAssemblyLocalName;
|
||||
public readonly static XmlDictionaryString ArraySizeLocalName;
|
||||
public readonly static XmlDictionaryString IdLocalName;
|
||||
public readonly static XmlDictionaryString RefLocalName;
|
||||
public readonly static XmlDictionaryString ISerializableFactoryTypeLocalName;
|
||||
public readonly static XmlDictionaryString CharLocalName;
|
||||
public readonly static XmlDictionaryString BooleanLocalName;
|
||||
public readonly static XmlDictionaryString SignedByteLocalName;
|
||||
public readonly static XmlDictionaryString UnsignedByteLocalName;
|
||||
public readonly static XmlDictionaryString ShortLocalName;
|
||||
public readonly static XmlDictionaryString UnsignedShortLocalName;
|
||||
public readonly static XmlDictionaryString IntLocalName;
|
||||
public readonly static XmlDictionaryString UnsignedIntLocalName;
|
||||
public readonly static XmlDictionaryString LongLocalName;
|
||||
public readonly static XmlDictionaryString UnsignedLongLocalName;
|
||||
public readonly static XmlDictionaryString FloatLocalName;
|
||||
public readonly static XmlDictionaryString DoubleLocalName;
|
||||
public readonly static XmlDictionaryString DecimalLocalName;
|
||||
public readonly static XmlDictionaryString DateTimeLocalName;
|
||||
public readonly static XmlDictionaryString StringLocalName;
|
||||
public readonly static XmlDictionaryString ByteArrayLocalName;
|
||||
public readonly static XmlDictionaryString ObjectLocalName;
|
||||
public readonly static XmlDictionaryString TimeSpanLocalName;
|
||||
public readonly static XmlDictionaryString GuidLocalName;
|
||||
public readonly static XmlDictionaryString UriLocalName;
|
||||
public readonly static XmlDictionaryString QNameLocalName;
|
||||
public readonly static XmlDictionaryString Space;
|
||||
|
||||
public readonly static XmlDictionaryString timeLocalName;
|
||||
public readonly static XmlDictionaryString dateLocalName;
|
||||
public readonly static XmlDictionaryString hexBinaryLocalName;
|
||||
public readonly static XmlDictionaryString gYearMonthLocalName;
|
||||
public readonly static XmlDictionaryString gYearLocalName;
|
||||
public readonly static XmlDictionaryString gMonthDayLocalName;
|
||||
public readonly static XmlDictionaryString gDayLocalName;
|
||||
public readonly static XmlDictionaryString gMonthLocalName;
|
||||
public readonly static XmlDictionaryString integerLocalName;
|
||||
public readonly static XmlDictionaryString positiveIntegerLocalName;
|
||||
public readonly static XmlDictionaryString negativeIntegerLocalName;
|
||||
public readonly static XmlDictionaryString nonPositiveIntegerLocalName;
|
||||
public readonly static XmlDictionaryString nonNegativeIntegerLocalName;
|
||||
public readonly static XmlDictionaryString normalizedStringLocalName;
|
||||
public readonly static XmlDictionaryString tokenLocalName;
|
||||
public readonly static XmlDictionaryString languageLocalName;
|
||||
public readonly static XmlDictionaryString NameLocalName;
|
||||
public readonly static XmlDictionaryString NCNameLocalName;
|
||||
public readonly static XmlDictionaryString XSDIDLocalName;
|
||||
public readonly static XmlDictionaryString IDREFLocalName;
|
||||
public readonly static XmlDictionaryString IDREFSLocalName;
|
||||
public readonly static XmlDictionaryString ENTITYLocalName;
|
||||
public readonly static XmlDictionaryString ENTITIESLocalName;
|
||||
public readonly static XmlDictionaryString NMTOKENLocalName;
|
||||
public readonly static XmlDictionaryString NMTOKENSLocalName;
|
||||
public readonly static XmlDictionaryString AsmxTypesNamespace;
|
||||
|
||||
static DictionaryGlobals()
|
||||
{
|
||||
// Update array size when adding new strings or templates
|
||||
XmlDictionary dictionary = new XmlDictionary(61);
|
||||
|
||||
try
|
||||
{
|
||||
// 0
|
||||
SchemaInstanceNamespace = dictionary.Add(Globals.SchemaInstanceNamespace);
|
||||
SerializationNamespace = dictionary.Add(Globals.SerializationNamespace);
|
||||
SchemaNamespace = dictionary.Add(Globals.SchemaNamespace);
|
||||
XsiTypeLocalName = dictionary.Add(Globals.XsiTypeLocalName);
|
||||
XsiNilLocalName = dictionary.Add(Globals.XsiNilLocalName);
|
||||
|
||||
// 5
|
||||
IdLocalName = dictionary.Add(Globals.IdLocalName);
|
||||
RefLocalName = dictionary.Add(Globals.RefLocalName);
|
||||
ArraySizeLocalName = dictionary.Add(Globals.ArraySizeLocalName);
|
||||
EmptyString = dictionary.Add(String.Empty);
|
||||
ISerializableFactoryTypeLocalName = dictionary.Add(Globals.ISerializableFactoryTypeLocalName);
|
||||
|
||||
// 10
|
||||
XmlnsNamespace = dictionary.Add(Globals.XmlnsNamespace);
|
||||
CharLocalName = dictionary.Add("char");
|
||||
BooleanLocalName = dictionary.Add("boolean");
|
||||
SignedByteLocalName = dictionary.Add("byte");
|
||||
UnsignedByteLocalName = dictionary.Add("unsignedByte");
|
||||
|
||||
// 15
|
||||
ShortLocalName = dictionary.Add("short");
|
||||
UnsignedShortLocalName = dictionary.Add("unsignedShort");
|
||||
IntLocalName = dictionary.Add("int");
|
||||
UnsignedIntLocalName = dictionary.Add("unsignedInt");
|
||||
LongLocalName = dictionary.Add("long");
|
||||
|
||||
// 20
|
||||
UnsignedLongLocalName = dictionary.Add("unsignedLong");
|
||||
FloatLocalName = dictionary.Add("float");
|
||||
DoubleLocalName = dictionary.Add("double");
|
||||
DecimalLocalName = dictionary.Add("decimal");
|
||||
DateTimeLocalName = dictionary.Add("dateTime");
|
||||
|
||||
// 25
|
||||
StringLocalName = dictionary.Add("string");
|
||||
ByteArrayLocalName = dictionary.Add("base64Binary");
|
||||
ObjectLocalName = dictionary.Add("anyType");
|
||||
TimeSpanLocalName = dictionary.Add("duration");
|
||||
GuidLocalName = dictionary.Add("guid");
|
||||
|
||||
// 30
|
||||
UriLocalName = dictionary.Add("anyURI");
|
||||
QNameLocalName = dictionary.Add("QName");
|
||||
ClrTypeLocalName = dictionary.Add(Globals.ClrTypeLocalName);
|
||||
ClrAssemblyLocalName = dictionary.Add(Globals.ClrAssemblyLocalName);
|
||||
Space = dictionary.Add(Globals.Space);
|
||||
|
||||
// 35
|
||||
timeLocalName = dictionary.Add("time");
|
||||
dateLocalName = dictionary.Add("date");
|
||||
hexBinaryLocalName = dictionary.Add("hexBinary");
|
||||
gYearMonthLocalName = dictionary.Add("gYearMonth");
|
||||
gYearLocalName = dictionary.Add("gYear");
|
||||
|
||||
// 40
|
||||
gMonthDayLocalName = dictionary.Add("gMonthDay");
|
||||
gDayLocalName = dictionary.Add("gDay");
|
||||
gMonthLocalName = dictionary.Add("gMonth");
|
||||
integerLocalName = dictionary.Add("integer");
|
||||
positiveIntegerLocalName = dictionary.Add("positiveInteger");
|
||||
|
||||
// 45
|
||||
negativeIntegerLocalName = dictionary.Add("negativeInteger");
|
||||
nonPositiveIntegerLocalName = dictionary.Add("nonPositiveInteger");
|
||||
nonNegativeIntegerLocalName = dictionary.Add("nonNegativeInteger");
|
||||
normalizedStringLocalName = dictionary.Add("normalizedString");
|
||||
tokenLocalName = dictionary.Add("token");
|
||||
|
||||
// 50
|
||||
languageLocalName = dictionary.Add("language");
|
||||
NameLocalName = dictionary.Add("Name");
|
||||
NCNameLocalName = dictionary.Add("NCName");
|
||||
XSDIDLocalName = dictionary.Add("ID");
|
||||
IDREFLocalName = dictionary.Add("IDREF");
|
||||
|
||||
// 55
|
||||
IDREFSLocalName = dictionary.Add("IDREFS");
|
||||
ENTITYLocalName = dictionary.Add("ENTITY");
|
||||
ENTITIESLocalName = dictionary.Add("ENTITIES");
|
||||
NMTOKENLocalName = dictionary.Add("NMTOKEN");
|
||||
NMTOKENSLocalName = dictionary.Add("NMTOKENS");
|
||||
|
||||
// 60
|
||||
AsmxTypesNamespace = dictionary.Add("http://microsoft.com/wsdl/types/");
|
||||
|
||||
// Add new templates here
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (Fx.IsFatal(ex))
|
||||
{
|
||||
throw;
|
||||
}
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperFatal(ex.Message, ex);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
using System;
|
||||
|
||||
namespace Compat.Runtime.Serialization
|
||||
{
|
||||
internal class AttributeData
|
||||
{
|
||||
public string prefix;
|
||||
public string ns;
|
||||
public string localName;
|
||||
public string value;
|
||||
}
|
||||
|
||||
internal class ElementData
|
||||
{
|
||||
public string localName;
|
||||
public string ns;
|
||||
public string prefix;
|
||||
public int attributeCount;
|
||||
public AttributeData[] attributes;
|
||||
public IDataNode dataNode;
|
||||
public int childElementIndex;
|
||||
|
||||
public void AddAttribute(string prefix, string ns, string name, string value)
|
||||
{
|
||||
GrowAttributesIfNeeded();
|
||||
AttributeData attribute = attributes[attributeCount];
|
||||
if (attribute == null)
|
||||
{
|
||||
attributes[attributeCount] = attribute = new AttributeData();
|
||||
}
|
||||
|
||||
attribute.prefix = prefix;
|
||||
attribute.ns = ns;
|
||||
attribute.localName = name;
|
||||
attribute.value = value;
|
||||
attributeCount++;
|
||||
}
|
||||
|
||||
private void GrowAttributesIfNeeded()
|
||||
{
|
||||
if (attributes == null)
|
||||
{
|
||||
attributes = new AttributeData[4];
|
||||
}
|
||||
else if (attributes.Length == attributeCount)
|
||||
{
|
||||
AttributeData[] newAttributes = new AttributeData[attributes.Length * 2];
|
||||
Array.Copy(attributes, 0, newAttributes, 0, attributes.Length);
|
||||
attributes = newAttributes;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,508 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using System.Security;
|
||||
using System.Threading;
|
||||
using System.Xml;
|
||||
using DataContractAttribute = System.Runtime.Serialization.DataContractAttribute;
|
||||
using EnumMemberAttribute = System.Runtime.Serialization.EnumMemberAttribute;
|
||||
|
||||
namespace Compat.Runtime.Serialization
|
||||
{
|
||||
internal sealed class EnumDataContract : DataContract
|
||||
{
|
||||
private readonly EnumDataContractCriticalHelper helper;
|
||||
|
||||
internal EnumDataContract()
|
||||
: base(new EnumDataContractCriticalHelper())
|
||||
{
|
||||
helper = base.Helper as EnumDataContractCriticalHelper;
|
||||
}
|
||||
|
||||
internal EnumDataContract(Type type)
|
||||
: base(new EnumDataContractCriticalHelper(type))
|
||||
{
|
||||
helper = base.Helper as EnumDataContractCriticalHelper;
|
||||
}
|
||||
|
||||
internal static XmlQualifiedName GetBaseContractName(Type type)
|
||||
{
|
||||
return EnumDataContractCriticalHelper.GetBaseContractName(type);
|
||||
}
|
||||
|
||||
internal static Type GetBaseType(XmlQualifiedName baseContractName)
|
||||
{
|
||||
return EnumDataContractCriticalHelper.GetBaseType(baseContractName);
|
||||
}
|
||||
|
||||
internal XmlQualifiedName BaseContractName
|
||||
{
|
||||
get => helper.BaseContractName;
|
||||
set => helper.BaseContractName = value;
|
||||
}
|
||||
|
||||
internal List<DataMember> Members
|
||||
{
|
||||
get => helper.Members;
|
||||
set => helper.Members = value;
|
||||
}
|
||||
|
||||
internal List<long> Values
|
||||
{
|
||||
get => helper.Values;
|
||||
set => helper.Values = value;
|
||||
}
|
||||
|
||||
internal bool IsFlags
|
||||
{
|
||||
get => helper.IsFlags;
|
||||
set => helper.IsFlags = value;
|
||||
}
|
||||
|
||||
internal bool IsULong
|
||||
{
|
||||
get => helper.IsULong;
|
||||
}
|
||||
|
||||
private XmlDictionaryString[] ChildElementNames
|
||||
{
|
||||
get => helper.ChildElementNames;
|
||||
}
|
||||
|
||||
internal override bool CanContainReferences => false;
|
||||
|
||||
private class EnumDataContractCriticalHelper : DataContract.DataContractCriticalHelper
|
||||
{
|
||||
private static readonly Dictionary<Type, XmlQualifiedName> typeToName;
|
||||
private static readonly Dictionary<XmlQualifiedName, Type> nameToType;
|
||||
private XmlQualifiedName baseContractName;
|
||||
private List<DataMember> members;
|
||||
private List<long> values;
|
||||
private bool isULong;
|
||||
private bool isFlags;
|
||||
private readonly bool hasDataContract;
|
||||
private readonly XmlDictionaryString[] childElementNames;
|
||||
|
||||
static EnumDataContractCriticalHelper()
|
||||
{
|
||||
typeToName = new Dictionary<Type, XmlQualifiedName>();
|
||||
nameToType = new Dictionary<XmlQualifiedName, Type>();
|
||||
Add(typeof(sbyte), "byte");
|
||||
Add(typeof(byte), "unsignedByte");
|
||||
Add(typeof(short), "short");
|
||||
Add(typeof(ushort), "unsignedShort");
|
||||
Add(typeof(int), "int");
|
||||
Add(typeof(uint), "unsignedInt");
|
||||
Add(typeof(long), "long");
|
||||
Add(typeof(ulong), "unsignedLong");
|
||||
}
|
||||
|
||||
internal static void Add(Type type, string localName)
|
||||
{
|
||||
XmlQualifiedName stableName = CreateQualifiedName(localName, Globals.SchemaNamespace);
|
||||
typeToName.Add(type, stableName);
|
||||
nameToType.Add(stableName, type);
|
||||
}
|
||||
|
||||
internal static XmlQualifiedName GetBaseContractName(Type type)
|
||||
{
|
||||
typeToName.TryGetValue(type, out XmlQualifiedName retVal);
|
||||
return retVal;
|
||||
}
|
||||
|
||||
internal static Type GetBaseType(XmlQualifiedName baseContractName)
|
||||
{
|
||||
nameToType.TryGetValue(baseContractName, out Type retVal);
|
||||
return retVal;
|
||||
}
|
||||
|
||||
internal EnumDataContractCriticalHelper()
|
||||
{
|
||||
IsValueType = true;
|
||||
}
|
||||
|
||||
internal EnumDataContractCriticalHelper(Type type)
|
||||
: base(type)
|
||||
{
|
||||
StableName = DataContract.GetStableName(type, out hasDataContract);
|
||||
Type baseType = Enum.GetUnderlyingType(type);
|
||||
baseContractName = GetBaseContractName(baseType);
|
||||
ImportBaseType(baseType);
|
||||
IsFlags = type.IsDefined(Globals.TypeOfFlagsAttribute, false);
|
||||
ImportDataMembers();
|
||||
|
||||
XmlDictionary dictionary = new XmlDictionary(2 + Members.Count);
|
||||
Name = dictionary.Add(StableName.Name);
|
||||
Namespace = dictionary.Add(StableName.Namespace);
|
||||
childElementNames = new XmlDictionaryString[Members.Count];
|
||||
for (int i = 0; i < Members.Count; i++)
|
||||
{
|
||||
childElementNames[i] = dictionary.Add(Members[i].Name);
|
||||
}
|
||||
|
||||
if (TryGetDCAttribute(type, out DataContractAttribute dataContractAttribute))
|
||||
{
|
||||
if (dataContractAttribute.IsReference)
|
||||
{
|
||||
DataContract.ThrowInvalidDataContractException(
|
||||
SR.Format(SR.EnumTypeCannotHaveIsReference,
|
||||
DataContract.GetClrTypeFullName(type),
|
||||
dataContractAttribute.IsReference,
|
||||
false),
|
||||
type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal XmlQualifiedName BaseContractName
|
||||
{
|
||||
get => baseContractName;
|
||||
set
|
||||
{
|
||||
baseContractName = value;
|
||||
Type baseType = GetBaseType(baseContractName);
|
||||
if (baseType == null)
|
||||
{
|
||||
ThrowInvalidDataContractException(SR.Format(SR.InvalidEnumBaseType, value.Name, value.Namespace, StableName.Name, StableName.Namespace));
|
||||
}
|
||||
|
||||
ImportBaseType(baseType);
|
||||
}
|
||||
}
|
||||
|
||||
internal List<DataMember> Members
|
||||
{
|
||||
get => members;
|
||||
set => members = value;
|
||||
}
|
||||
|
||||
internal List<long> Values
|
||||
{
|
||||
get => values;
|
||||
set => values = value;
|
||||
}
|
||||
|
||||
internal bool IsFlags
|
||||
{
|
||||
get => isFlags;
|
||||
set => isFlags = value;
|
||||
}
|
||||
|
||||
internal bool IsULong => isULong;
|
||||
|
||||
internal XmlDictionaryString[] ChildElementNames => childElementNames;
|
||||
|
||||
private void ImportBaseType(Type baseType)
|
||||
{
|
||||
isULong = (baseType == Globals.TypeOfULong);
|
||||
}
|
||||
|
||||
private void ImportDataMembers()
|
||||
{
|
||||
Type type = UnderlyingType;
|
||||
FieldInfo[] fields = type.GetFields(BindingFlags.Static | BindingFlags.Public);
|
||||
Dictionary<string, DataMember> memberValuesTable = new Dictionary<string, DataMember>();
|
||||
List<DataMember> tempMembers = new List<DataMember>(fields.Length);
|
||||
List<long> tempValues = new List<long>(fields.Length);
|
||||
|
||||
for (int i = 0; i < fields.Length; i++)
|
||||
{
|
||||
FieldInfo field = fields[i];
|
||||
bool enumMemberValid = false;
|
||||
if (hasDataContract)
|
||||
{
|
||||
object[] memberAttributes = field.GetCustomAttributes(Globals.TypeOfEnumMemberAttribute, false);
|
||||
if (memberAttributes != null && memberAttributes.Length > 0)
|
||||
{
|
||||
if (memberAttributes.Length > 1)
|
||||
{
|
||||
ThrowInvalidDataContractException(SR.Format(SR.TooManyEnumMembers, DataContract.GetClrTypeFullName(field.DeclaringType), field.Name));
|
||||
}
|
||||
|
||||
EnumMemberAttribute memberAttribute = (EnumMemberAttribute)memberAttributes[0];
|
||||
|
||||
DataMember memberContract = new DataMember(field);
|
||||
if (memberAttribute.IsValueSetExplicitly)
|
||||
{
|
||||
if (memberAttribute.Value == null || memberAttribute.Value.Length == 0)
|
||||
{
|
||||
ThrowInvalidDataContractException(SR.Format(SR.InvalidEnumMemberValue, field.Name, DataContract.GetClrTypeFullName(type)));
|
||||
}
|
||||
|
||||
memberContract.Name = memberAttribute.Value;
|
||||
}
|
||||
else
|
||||
{
|
||||
memberContract.Name = field.Name;
|
||||
}
|
||||
|
||||
ClassDataContract.CheckAndAddMember(tempMembers, memberContract, memberValuesTable);
|
||||
enumMemberValid = true;
|
||||
}
|
||||
|
||||
object[] dataMemberAttributes = field.GetCustomAttributes(Globals.TypeOfDataMemberAttribute, false);
|
||||
if (dataMemberAttributes != null && dataMemberAttributes.Length > 0)
|
||||
{
|
||||
ThrowInvalidDataContractException(SR.Format(SR.DataMemberOnEnumField, DataContract.GetClrTypeFullName(field.DeclaringType), field.Name));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!field.IsNotSerialized)
|
||||
{
|
||||
DataMember memberContract = new DataMember(field)
|
||||
{
|
||||
Name = field.Name
|
||||
};
|
||||
ClassDataContract.CheckAndAddMember(tempMembers, memberContract, memberValuesTable);
|
||||
enumMemberValid = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (enumMemberValid)
|
||||
{
|
||||
object enumValue = field.GetValue(null);
|
||||
if (isULong)
|
||||
{
|
||||
tempValues.Add((long)((IConvertible)enumValue).ToUInt64(null));
|
||||
}
|
||||
else
|
||||
{
|
||||
tempValues.Add(((IConvertible)enumValue).ToInt64(null));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Thread.MemoryBarrier();
|
||||
members = tempMembers;
|
||||
values = tempValues;
|
||||
}
|
||||
}
|
||||
|
||||
internal void WriteEnumValue(XmlWriterDelegator writer, object value)
|
||||
{
|
||||
long longValue = IsULong ? (long)((IConvertible)value).ToUInt64(null) : ((IConvertible)value).ToInt64(null);
|
||||
for (int i = 0; i < Values.Count; i++)
|
||||
{
|
||||
if (longValue == Values[i])
|
||||
{
|
||||
writer.WriteString(ChildElementNames[i].Value);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (IsFlags)
|
||||
{
|
||||
int zeroIndex = -1;
|
||||
bool noneWritten = true;
|
||||
for (int i = 0; i < Values.Count; i++)
|
||||
{
|
||||
long current = Values[i];
|
||||
if (current == 0)
|
||||
{
|
||||
zeroIndex = i;
|
||||
continue;
|
||||
}
|
||||
if (longValue == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if ((current & longValue) == current)
|
||||
{
|
||||
if (noneWritten)
|
||||
{
|
||||
noneWritten = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
writer.WriteString(DictionaryGlobals.Space.Value);
|
||||
}
|
||||
|
||||
writer.WriteString(ChildElementNames[i].Value);
|
||||
longValue &= ~current;
|
||||
}
|
||||
}
|
||||
// enforce that enum value was completely parsed
|
||||
if (longValue != 0)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(SR.Format(SR.InvalidEnumValueOnWrite, value, DataContract.GetClrTypeFullName(UnderlyingType))));
|
||||
}
|
||||
|
||||
if (noneWritten && zeroIndex >= 0)
|
||||
{
|
||||
writer.WriteString(ChildElementNames[zeroIndex].Value);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(SR.Format(SR.InvalidEnumValueOnWrite, value, DataContract.GetClrTypeFullName(UnderlyingType))));
|
||||
}
|
||||
}
|
||||
|
||||
internal object ReadEnumValue(XmlReaderDelegator reader)
|
||||
{
|
||||
string stringValue = reader.ReadElementContentAsString();
|
||||
long longValue = 0;
|
||||
int i = 0;
|
||||
if (IsFlags)
|
||||
{
|
||||
// Skip initial spaces
|
||||
for (; i < stringValue.Length; i++)
|
||||
{
|
||||
if (stringValue[i] != ' ')
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Read space-delimited values
|
||||
int startIndex = i;
|
||||
int count = 0;
|
||||
for (; i < stringValue.Length; i++)
|
||||
{
|
||||
if (stringValue[i] == ' ')
|
||||
{
|
||||
count = i - startIndex;
|
||||
if (count > 0)
|
||||
{
|
||||
longValue |= ReadEnumValue(stringValue, startIndex, count);
|
||||
}
|
||||
|
||||
for (++i; i < stringValue.Length; i++)
|
||||
{
|
||||
if (stringValue[i] != ' ')
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
startIndex = i;
|
||||
if (i == stringValue.Length)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
count = i - startIndex;
|
||||
if (count > 0)
|
||||
{
|
||||
longValue |= ReadEnumValue(stringValue, startIndex, count);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (stringValue.Length == 0)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(SR.Format(SR.InvalidEnumValueOnRead, stringValue, DataContract.GetClrTypeFullName(UnderlyingType))));
|
||||
}
|
||||
|
||||
longValue = ReadEnumValue(stringValue, 0, stringValue.Length);
|
||||
}
|
||||
|
||||
if (IsULong)
|
||||
{
|
||||
return Enum.ToObject(UnderlyingType, (ulong)longValue);
|
||||
}
|
||||
|
||||
return Enum.ToObject(UnderlyingType, longValue);
|
||||
}
|
||||
|
||||
private long ReadEnumValue(string value, int index, int count)
|
||||
{
|
||||
for (int i = 0; i < Members.Count; i++)
|
||||
{
|
||||
string memberName = Members[i].Name;
|
||||
if (memberName.Length == count && string.CompareOrdinal(value, index, memberName, 0, count) == 0)
|
||||
{
|
||||
return Values[i];
|
||||
}
|
||||
}
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(SR.Format(SR.InvalidEnumValueOnRead, value.Substring(index, count), DataContract.GetClrTypeFullName(UnderlyingType))));
|
||||
}
|
||||
|
||||
internal string GetStringFromEnumValue(long value)
|
||||
{
|
||||
if (IsULong)
|
||||
{
|
||||
return XmlConvert.ToString((ulong)value);
|
||||
}
|
||||
else
|
||||
{
|
||||
return XmlConvert.ToString(value);
|
||||
}
|
||||
}
|
||||
|
||||
internal long GetEnumValueFromString(string value)
|
||||
{
|
||||
if (IsULong)
|
||||
{
|
||||
return (long)XmlConverter.ToUInt64(value);
|
||||
}
|
||||
else
|
||||
{
|
||||
return XmlConverter.ToInt64(value);
|
||||
}
|
||||
}
|
||||
|
||||
internal override bool Equals(object other, Dictionary<DataContractPairKey, object> checkedContracts)
|
||||
{
|
||||
if (IsEqualOrChecked(other, checkedContracts))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (base.Equals(other, null))
|
||||
{
|
||||
EnumDataContract dataContract = other as EnumDataContract;
|
||||
if (dataContract != null)
|
||||
{
|
||||
if (Members.Count != dataContract.Members.Count || Values.Count != dataContract.Values.Count)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
string[] memberNames1 = new string[Members.Count], memberNames2 = new string[Members.Count];
|
||||
for (int i = 0; i < Members.Count; i++)
|
||||
{
|
||||
memberNames1[i] = Members[i].Name;
|
||||
memberNames2[i] = dataContract.Members[i].Name;
|
||||
}
|
||||
Array.Sort(memberNames1);
|
||||
Array.Sort(memberNames2);
|
||||
for (int i = 0; i < Members.Count; i++)
|
||||
{
|
||||
if (memberNames1[i] != memberNames2[i])
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return (IsFlags == dataContract.IsFlags);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return base.GetHashCode();
|
||||
}
|
||||
|
||||
public override void WriteXmlValue(XmlWriterDelegator xmlWriter, object obj, XmlObjectSerializerWriteContext context)
|
||||
{
|
||||
WriteEnumValue(xmlWriter, obj);
|
||||
}
|
||||
|
||||
public override object ReadXmlValue(XmlReaderDelegator xmlReader, XmlObjectSerializerReadContext context)
|
||||
{
|
||||
object obj = ReadEnumValue(xmlReader);
|
||||
if (context != null)
|
||||
{
|
||||
context.AddNewObject(obj);
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
//------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------
|
||||
using System;
|
||||
using System.Collections.ObjectModel;
|
||||
|
||||
namespace Compat.Runtime.Serialization
|
||||
{
|
||||
public class ExportOptions
|
||||
{
|
||||
private Collection<Type> knownTypes;
|
||||
private IDataContractSurrogate dataContractSurrogate;
|
||||
|
||||
public IDataContractSurrogate DataContractSurrogate
|
||||
{
|
||||
get => dataContractSurrogate;
|
||||
set => dataContractSurrogate = value;
|
||||
}
|
||||
|
||||
internal IDataContractSurrogate GetSurrogate()
|
||||
{
|
||||
return dataContractSurrogate;
|
||||
}
|
||||
|
||||
public Collection<Type> KnownTypes
|
||||
{
|
||||
get
|
||||
{
|
||||
if (knownTypes == null)
|
||||
{
|
||||
knownTypes = new Collection<Type>();
|
||||
}
|
||||
return knownTypes;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
namespace Compat.Runtime.Serialization
|
||||
{
|
||||
internal class ExtensionDataMember
|
||||
{
|
||||
public string Name { get; set; }
|
||||
|
||||
public string Namespace { get; set; }
|
||||
|
||||
public IDataNode Value { get; set; }
|
||||
|
||||
public int MemberIndex { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Compat.Runtime.Serialization
|
||||
{
|
||||
public sealed class ExtensionDataObject
|
||||
{
|
||||
internal ExtensionDataObject()
|
||||
{
|
||||
}
|
||||
|
||||
internal IList<ExtensionDataMember> Members { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,877 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Xml;
|
||||
using SerializationException = System.Runtime.Serialization.SerializationException;
|
||||
|
||||
namespace Compat.Runtime.Serialization
|
||||
{
|
||||
internal class ExtensionDataReader : XmlReader
|
||||
{
|
||||
private enum ExtensionDataNodeType
|
||||
{
|
||||
None,
|
||||
Element,
|
||||
EndElement,
|
||||
Text,
|
||||
Xml,
|
||||
ReferencedElement,
|
||||
NullElement,
|
||||
}
|
||||
|
||||
private readonly Hashtable cache = new Hashtable();
|
||||
private ElementData[] elements;
|
||||
private ElementData element;
|
||||
private ElementData nextElement;
|
||||
private ReadState readState = ReadState.Initial;
|
||||
private ExtensionDataNodeType internalNodeType;
|
||||
private XmlNodeType nodeType;
|
||||
private int depth;
|
||||
private string localName;
|
||||
private string ns;
|
||||
private string prefix;
|
||||
private string value;
|
||||
private int attributeCount;
|
||||
private int attributeIndex;
|
||||
private XmlNodeReader xmlNodeReader;
|
||||
private Queue<IDataNode> deserializedDataNodes;
|
||||
private readonly XmlObjectSerializerReadContext context;
|
||||
|
||||
private static readonly Dictionary<string, string> nsToPrefixTable;
|
||||
|
||||
private static readonly Dictionary<string, string> prefixToNsTable;
|
||||
|
||||
static ExtensionDataReader()
|
||||
{
|
||||
nsToPrefixTable = new Dictionary<string, string>();
|
||||
prefixToNsTable = new Dictionary<string, string>();
|
||||
AddPrefix(Globals.XsiPrefix, Globals.SchemaInstanceNamespace);
|
||||
AddPrefix(Globals.SerPrefix, Globals.SerializationNamespace);
|
||||
AddPrefix(string.Empty, string.Empty);
|
||||
}
|
||||
|
||||
internal ExtensionDataReader(XmlObjectSerializerReadContext context)
|
||||
{
|
||||
attributeIndex = -1;
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
internal void SetDeserializedValue(object obj)
|
||||
{
|
||||
IDataNode deserializedDataNode = (deserializedDataNodes == null || deserializedDataNodes.Count == 0) ? null : deserializedDataNodes.Dequeue();
|
||||
if (deserializedDataNode != null && !(obj is IDataNode))
|
||||
{
|
||||
deserializedDataNode.Value = obj;
|
||||
deserializedDataNode.IsFinalValue = true;
|
||||
}
|
||||
}
|
||||
|
||||
internal IDataNode GetCurrentNode()
|
||||
{
|
||||
IDataNode retVal = element.dataNode;
|
||||
Skip();
|
||||
return retVal;
|
||||
}
|
||||
|
||||
internal void SetDataNode(IDataNode dataNode, string name, string ns)
|
||||
{
|
||||
SetNextElement(dataNode, name, ns, null);
|
||||
element = nextElement;
|
||||
nextElement = null;
|
||||
SetElement();
|
||||
}
|
||||
|
||||
internal void Reset()
|
||||
{
|
||||
localName = null;
|
||||
ns = null;
|
||||
prefix = null;
|
||||
value = null;
|
||||
attributeCount = 0;
|
||||
attributeIndex = -1;
|
||||
depth = 0;
|
||||
element = null;
|
||||
nextElement = null;
|
||||
elements = null;
|
||||
deserializedDataNodes = null;
|
||||
}
|
||||
|
||||
private bool IsXmlDataNode => (internalNodeType == ExtensionDataNodeType.Xml);
|
||||
|
||||
public override XmlNodeType NodeType => IsXmlDataNode ? xmlNodeReader.NodeType : nodeType;
|
||||
public override string LocalName => IsXmlDataNode ? xmlNodeReader.LocalName : localName;
|
||||
public override string NamespaceURI => IsXmlDataNode ? xmlNodeReader.NamespaceURI : ns;
|
||||
public override string Prefix => IsXmlDataNode ? xmlNodeReader.Prefix : prefix;
|
||||
public override string Value => IsXmlDataNode ? xmlNodeReader.Value : value;
|
||||
public override int Depth => IsXmlDataNode ? xmlNodeReader.Depth : depth;
|
||||
public override int AttributeCount => IsXmlDataNode ? xmlNodeReader.AttributeCount : attributeCount;
|
||||
public override bool EOF => IsXmlDataNode ? xmlNodeReader.EOF : (readState == ReadState.EndOfFile);
|
||||
public override ReadState ReadState => IsXmlDataNode ? xmlNodeReader.ReadState : readState;
|
||||
public override bool IsEmptyElement => IsXmlDataNode ? xmlNodeReader.IsEmptyElement : false;
|
||||
public override bool IsDefault => IsXmlDataNode ? xmlNodeReader.IsDefault : base.IsDefault;
|
||||
public override char QuoteChar => IsXmlDataNode ? xmlNodeReader.QuoteChar : base.QuoteChar;
|
||||
public override XmlSpace XmlSpace => IsXmlDataNode ? xmlNodeReader.XmlSpace : base.XmlSpace;
|
||||
public override string XmlLang => IsXmlDataNode ? xmlNodeReader.XmlLang : base.XmlLang;
|
||||
public override string this[int i] => IsXmlDataNode ? xmlNodeReader[i] : GetAttribute(i);
|
||||
public override string this[string name] => IsXmlDataNode ? xmlNodeReader[name] : GetAttribute(name);
|
||||
public override string this[string name, string namespaceURI] => IsXmlDataNode ? xmlNodeReader[name, namespaceURI] : GetAttribute(name, namespaceURI);
|
||||
|
||||
public override bool MoveToFirstAttribute()
|
||||
{
|
||||
if (IsXmlDataNode)
|
||||
{
|
||||
return xmlNodeReader.MoveToFirstAttribute();
|
||||
}
|
||||
|
||||
if (attributeCount == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
MoveToAttribute(0);
|
||||
return true;
|
||||
}
|
||||
|
||||
public override bool MoveToNextAttribute()
|
||||
{
|
||||
if (IsXmlDataNode)
|
||||
{
|
||||
return xmlNodeReader.MoveToNextAttribute();
|
||||
}
|
||||
|
||||
if (attributeIndex + 1 >= attributeCount)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
MoveToAttribute(attributeIndex + 1);
|
||||
return true;
|
||||
}
|
||||
|
||||
public override void MoveToAttribute(int index)
|
||||
{
|
||||
if (IsXmlDataNode)
|
||||
{
|
||||
xmlNodeReader.MoveToAttribute(index);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (index < 0 || index >= attributeCount)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new XmlException(SR.InvalidXmlDeserializingExtensionData));
|
||||
}
|
||||
|
||||
nodeType = XmlNodeType.Attribute;
|
||||
AttributeData attribute = element.attributes[index];
|
||||
localName = attribute.localName;
|
||||
ns = attribute.ns;
|
||||
prefix = attribute.prefix;
|
||||
value = attribute.value;
|
||||
attributeIndex = index;
|
||||
}
|
||||
}
|
||||
|
||||
public override string GetAttribute(string name, string namespaceURI)
|
||||
{
|
||||
if (IsXmlDataNode)
|
||||
{
|
||||
return xmlNodeReader.GetAttribute(name, namespaceURI);
|
||||
}
|
||||
|
||||
for (int i = 0; i < element.attributeCount; i++)
|
||||
{
|
||||
AttributeData attribute = element.attributes[i];
|
||||
if (attribute.localName == name && attribute.ns == namespaceURI)
|
||||
{
|
||||
return attribute.value;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public override bool MoveToAttribute(string name, string namespaceURI)
|
||||
{
|
||||
if (IsXmlDataNode)
|
||||
{
|
||||
return xmlNodeReader.MoveToAttribute(name, ns);
|
||||
}
|
||||
|
||||
for (int i = 0; i < element.attributeCount; i++)
|
||||
{
|
||||
AttributeData attribute = element.attributes[i];
|
||||
if (attribute.localName == name && attribute.ns == namespaceURI)
|
||||
{
|
||||
MoveToAttribute(i);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public override bool MoveToElement()
|
||||
{
|
||||
if (IsXmlDataNode)
|
||||
{
|
||||
return xmlNodeReader.MoveToElement();
|
||||
}
|
||||
|
||||
if (nodeType != XmlNodeType.Attribute)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
SetElement();
|
||||
return true;
|
||||
}
|
||||
|
||||
private void SetElement()
|
||||
{
|
||||
nodeType = XmlNodeType.Element;
|
||||
localName = element.localName;
|
||||
ns = element.ns;
|
||||
prefix = element.prefix;
|
||||
value = string.Empty;
|
||||
attributeCount = element.attributeCount;
|
||||
attributeIndex = -1;
|
||||
}
|
||||
|
||||
public override string LookupNamespace(string prefix)
|
||||
{
|
||||
if (IsXmlDataNode)
|
||||
{
|
||||
return xmlNodeReader.LookupNamespace(prefix);
|
||||
}
|
||||
|
||||
if (!prefixToNsTable.TryGetValue(prefix, out string ns))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return ns;
|
||||
}
|
||||
|
||||
public override void Skip()
|
||||
{
|
||||
if (IsXmlDataNode)
|
||||
{
|
||||
xmlNodeReader.Skip();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ReadState != ReadState.Interactive)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
MoveToElement();
|
||||
if (IsElementNode(internalNodeType))
|
||||
{
|
||||
int depth = 1;
|
||||
while (depth != 0)
|
||||
{
|
||||
if (!Read())
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new XmlException(SR.InvalidXmlDeserializingExtensionData));
|
||||
}
|
||||
|
||||
if (IsElementNode(internalNodeType))
|
||||
{
|
||||
depth++;
|
||||
}
|
||||
else if (internalNodeType == ExtensionDataNodeType.EndElement)
|
||||
{
|
||||
ReadEndElement();
|
||||
depth--;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Read();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private bool IsElementNode(ExtensionDataNodeType nodeType)
|
||||
{
|
||||
return (nodeType == ExtensionDataNodeType.Element ||
|
||||
nodeType == ExtensionDataNodeType.ReferencedElement ||
|
||||
nodeType == ExtensionDataNodeType.NullElement);
|
||||
}
|
||||
|
||||
public override void Close()
|
||||
{
|
||||
if (IsXmlDataNode)
|
||||
{
|
||||
xmlNodeReader.Close();
|
||||
}
|
||||
else
|
||||
{
|
||||
Reset();
|
||||
readState = ReadState.Closed;
|
||||
}
|
||||
}
|
||||
|
||||
public override bool Read()
|
||||
{
|
||||
if (nodeType == XmlNodeType.Attribute && MoveToNextAttribute())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
MoveNext(element.dataNode);
|
||||
|
||||
switch (internalNodeType)
|
||||
{
|
||||
case ExtensionDataNodeType.Element:
|
||||
case ExtensionDataNodeType.ReferencedElement:
|
||||
case ExtensionDataNodeType.NullElement:
|
||||
PushElement();
|
||||
SetElement();
|
||||
break;
|
||||
|
||||
case ExtensionDataNodeType.Text:
|
||||
nodeType = XmlNodeType.Text;
|
||||
prefix = string.Empty;
|
||||
ns = string.Empty;
|
||||
localName = string.Empty;
|
||||
attributeCount = 0;
|
||||
attributeIndex = -1;
|
||||
break;
|
||||
|
||||
case ExtensionDataNodeType.EndElement:
|
||||
nodeType = XmlNodeType.EndElement;
|
||||
prefix = string.Empty;
|
||||
ns = string.Empty;
|
||||
localName = string.Empty;
|
||||
value = string.Empty;
|
||||
attributeCount = 0;
|
||||
attributeIndex = -1;
|
||||
PopElement();
|
||||
break;
|
||||
|
||||
case ExtensionDataNodeType.None:
|
||||
if (depth != 0)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new XmlException(SR.InvalidXmlDeserializingExtensionData));
|
||||
}
|
||||
|
||||
nodeType = XmlNodeType.None;
|
||||
prefix = string.Empty;
|
||||
ns = string.Empty;
|
||||
localName = string.Empty;
|
||||
value = string.Empty;
|
||||
attributeCount = 0;
|
||||
readState = ReadState.EndOfFile;
|
||||
return false;
|
||||
|
||||
case ExtensionDataNodeType.Xml:
|
||||
// do nothing
|
||||
break;
|
||||
|
||||
default:
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SerializationException(SR.InvalidStateInExtensionDataReader));
|
||||
}
|
||||
readState = ReadState.Interactive;
|
||||
return true;
|
||||
}
|
||||
|
||||
public override string Name
|
||||
{
|
||||
get
|
||||
{
|
||||
if (IsXmlDataNode)
|
||||
{
|
||||
return xmlNodeReader.Name;
|
||||
}
|
||||
Fx.Assert("ExtensionDataReader Name property should only be called for IXmlSerializable");
|
||||
return string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
public override bool HasValue
|
||||
{
|
||||
get
|
||||
{
|
||||
if (IsXmlDataNode)
|
||||
{
|
||||
return xmlNodeReader.HasValue;
|
||||
}
|
||||
Fx.Assert("ExtensionDataReader HasValue property should only be called for IXmlSerializable");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public override string BaseURI
|
||||
{
|
||||
get
|
||||
{
|
||||
if (IsXmlDataNode)
|
||||
{
|
||||
return xmlNodeReader.BaseURI;
|
||||
}
|
||||
Fx.Assert("ExtensionDataReader BaseURI property should only be called for IXmlSerializable");
|
||||
return string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
public override XmlNameTable NameTable
|
||||
{
|
||||
get
|
||||
{
|
||||
if (IsXmlDataNode)
|
||||
{
|
||||
return xmlNodeReader.NameTable;
|
||||
}
|
||||
Fx.Assert("ExtensionDataReader NameTable property should only be called for IXmlSerializable");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public override string GetAttribute(string name)
|
||||
{
|
||||
if (IsXmlDataNode)
|
||||
{
|
||||
return xmlNodeReader.GetAttribute(name);
|
||||
}
|
||||
Fx.Assert("ExtensionDataReader GetAttribute method should only be called for IXmlSerializable");
|
||||
return null;
|
||||
}
|
||||
|
||||
public override string GetAttribute(int i)
|
||||
{
|
||||
if (IsXmlDataNode)
|
||||
{
|
||||
return xmlNodeReader.GetAttribute(i);
|
||||
}
|
||||
Fx.Assert("ExtensionDataReader GetAttribute method should only be called for IXmlSerializable");
|
||||
return null;
|
||||
}
|
||||
|
||||
public override bool MoveToAttribute(string name)
|
||||
{
|
||||
if (IsXmlDataNode)
|
||||
{
|
||||
return xmlNodeReader.MoveToAttribute(name);
|
||||
}
|
||||
Fx.Assert("ExtensionDataReader MoveToAttribute method should only be called for IXmlSerializable");
|
||||
return false;
|
||||
}
|
||||
|
||||
public override void ResolveEntity()
|
||||
{
|
||||
if (IsXmlDataNode)
|
||||
{
|
||||
xmlNodeReader.ResolveEntity();
|
||||
}
|
||||
else
|
||||
{
|
||||
Fx.Assert("ExtensionDataReader ResolveEntity method should only be called for IXmlSerializable");
|
||||
}
|
||||
}
|
||||
|
||||
public override bool ReadAttributeValue()
|
||||
{
|
||||
if (IsXmlDataNode)
|
||||
{
|
||||
return xmlNodeReader.ReadAttributeValue();
|
||||
}
|
||||
Fx.Assert("ExtensionDataReader ReadAttributeValue method should only be called for IXmlSerializable");
|
||||
return false;
|
||||
}
|
||||
|
||||
private void MoveNext(IDataNode dataNode)
|
||||
{
|
||||
switch (internalNodeType)
|
||||
{
|
||||
case ExtensionDataNodeType.Text:
|
||||
case ExtensionDataNodeType.ReferencedElement:
|
||||
case ExtensionDataNodeType.NullElement:
|
||||
internalNodeType = ExtensionDataNodeType.EndElement;
|
||||
return;
|
||||
default:
|
||||
Type dataNodeType = dataNode.DataType;
|
||||
if (dataNodeType == Globals.TypeOfClassDataNode)
|
||||
{
|
||||
MoveNextInClass((ClassDataNode)dataNode);
|
||||
}
|
||||
else if (dataNodeType == Globals.TypeOfCollectionDataNode)
|
||||
{
|
||||
MoveNextInCollection((CollectionDataNode)dataNode);
|
||||
}
|
||||
else if (dataNodeType == Globals.TypeOfISerializableDataNode)
|
||||
{
|
||||
MoveNextInISerializable((ISerializableDataNode)dataNode);
|
||||
}
|
||||
else if (dataNodeType == Globals.TypeOfXmlDataNode)
|
||||
{
|
||||
MoveNextInXml((XmlDataNode)dataNode);
|
||||
}
|
||||
else if (dataNode.Value != null)
|
||||
{
|
||||
MoveToDeserializedObject(dataNode);
|
||||
}
|
||||
else
|
||||
{
|
||||
Fx.Assert("Encountered invalid data node when deserializing unknown data");
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SerializationException(SR.InvalidStateInExtensionDataReader));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void SetNextElement(IDataNode node, string name, string ns, string prefix)
|
||||
{
|
||||
internalNodeType = ExtensionDataNodeType.Element;
|
||||
nextElement = GetNextElement();
|
||||
nextElement.localName = name;
|
||||
nextElement.ns = ns;
|
||||
nextElement.prefix = prefix;
|
||||
if (node == null)
|
||||
{
|
||||
nextElement.attributeCount = 0;
|
||||
nextElement.AddAttribute(Globals.XsiPrefix, Globals.SchemaInstanceNamespace, Globals.XsiNilLocalName, Globals.True);
|
||||
internalNodeType = ExtensionDataNodeType.NullElement;
|
||||
}
|
||||
else if (!CheckIfNodeHandled(node))
|
||||
{
|
||||
AddDeserializedDataNode(node);
|
||||
node.GetData(nextElement);
|
||||
if (node is XmlDataNode)
|
||||
{
|
||||
MoveNextInXml((XmlDataNode)node);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void AddDeserializedDataNode(IDataNode node)
|
||||
{
|
||||
if (node.Id != Globals.NewObjectId && (node.Value == null || !node.IsFinalValue))
|
||||
{
|
||||
if (deserializedDataNodes == null)
|
||||
{
|
||||
deserializedDataNodes = new Queue<IDataNode>();
|
||||
}
|
||||
|
||||
deserializedDataNodes.Enqueue(node);
|
||||
}
|
||||
}
|
||||
|
||||
private bool CheckIfNodeHandled(IDataNode node)
|
||||
{
|
||||
bool handled = false;
|
||||
if (node.Id != Globals.NewObjectId)
|
||||
{
|
||||
handled = (cache[node] != null);
|
||||
if (handled)
|
||||
{
|
||||
if (nextElement == null)
|
||||
{
|
||||
nextElement = GetNextElement();
|
||||
}
|
||||
|
||||
nextElement.attributeCount = 0;
|
||||
nextElement.AddAttribute(Globals.SerPrefix, Globals.SerializationNamespace, Globals.RefLocalName, node.Id.ToString(NumberFormatInfo.InvariantInfo));
|
||||
nextElement.AddAttribute(Globals.XsiPrefix, Globals.SchemaInstanceNamespace, Globals.XsiNilLocalName, Globals.True);
|
||||
internalNodeType = ExtensionDataNodeType.ReferencedElement;
|
||||
}
|
||||
else
|
||||
{
|
||||
cache.Add(node, node);
|
||||
}
|
||||
}
|
||||
return handled;
|
||||
}
|
||||
|
||||
private void MoveNextInClass(ClassDataNode dataNode)
|
||||
{
|
||||
if (dataNode.Members != null && element.childElementIndex < dataNode.Members.Count)
|
||||
{
|
||||
if (element.childElementIndex == 0)
|
||||
{
|
||||
context.IncrementItemCount(-dataNode.Members.Count);
|
||||
}
|
||||
|
||||
ExtensionDataMember member = dataNode.Members[element.childElementIndex++];
|
||||
SetNextElement(member.Value, member.Name, member.Namespace, GetPrefix(member.Namespace));
|
||||
}
|
||||
else
|
||||
{
|
||||
internalNodeType = ExtensionDataNodeType.EndElement;
|
||||
element.childElementIndex = 0;
|
||||
}
|
||||
}
|
||||
|
||||
private void MoveNextInCollection(CollectionDataNode dataNode)
|
||||
{
|
||||
if (dataNode.Items != null && element.childElementIndex < dataNode.Items.Count)
|
||||
{
|
||||
if (element.childElementIndex == 0)
|
||||
{
|
||||
context.IncrementItemCount(-dataNode.Items.Count);
|
||||
}
|
||||
|
||||
IDataNode item = dataNode.Items[element.childElementIndex++];
|
||||
SetNextElement(item, dataNode.ItemName, dataNode.ItemNamespace, GetPrefix(dataNode.ItemNamespace));
|
||||
}
|
||||
else
|
||||
{
|
||||
internalNodeType = ExtensionDataNodeType.EndElement;
|
||||
element.childElementIndex = 0;
|
||||
}
|
||||
}
|
||||
|
||||
private void MoveNextInISerializable(ISerializableDataNode dataNode)
|
||||
{
|
||||
if (dataNode.Members != null && element.childElementIndex < dataNode.Members.Count)
|
||||
{
|
||||
if (element.childElementIndex == 0)
|
||||
{
|
||||
context.IncrementItemCount(-dataNode.Members.Count);
|
||||
}
|
||||
|
||||
ISerializableDataMember member = dataNode.Members[element.childElementIndex++];
|
||||
SetNextElement(member.Value, member.Name, string.Empty, string.Empty);
|
||||
}
|
||||
else
|
||||
{
|
||||
internalNodeType = ExtensionDataNodeType.EndElement;
|
||||
element.childElementIndex = 0;
|
||||
}
|
||||
}
|
||||
|
||||
private void MoveNextInXml(XmlDataNode dataNode)
|
||||
{
|
||||
if (IsXmlDataNode)
|
||||
{
|
||||
xmlNodeReader.Read();
|
||||
if (xmlNodeReader.Depth == 0)
|
||||
{
|
||||
internalNodeType = ExtensionDataNodeType.EndElement;
|
||||
xmlNodeReader = null;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
internalNodeType = ExtensionDataNodeType.Xml;
|
||||
if (element == null)
|
||||
{
|
||||
element = nextElement;
|
||||
}
|
||||
else
|
||||
{
|
||||
PushElement();
|
||||
}
|
||||
|
||||
XmlNode wrapperElement = XmlObjectSerializerReadContext.CreateWrapperXmlElement(dataNode.OwnerDocument,
|
||||
dataNode.XmlAttributes, dataNode.XmlChildNodes, element.prefix, element.localName, element.ns);
|
||||
for (int i = 0; i < element.attributeCount; i++)
|
||||
{
|
||||
AttributeData a = element.attributes[i];
|
||||
XmlAttribute xmlAttr = dataNode.OwnerDocument.CreateAttribute(a.prefix, a.localName, a.ns);
|
||||
xmlAttr.Value = a.value;
|
||||
wrapperElement.Attributes.Append(xmlAttr);
|
||||
}
|
||||
xmlNodeReader = new XmlNodeReader(wrapperElement);
|
||||
xmlNodeReader.Read();
|
||||
}
|
||||
}
|
||||
|
||||
private void MoveToDeserializedObject(IDataNode dataNode)
|
||||
{
|
||||
Type type = dataNode.DataType;
|
||||
bool isTypedNode = true;
|
||||
if (type == Globals.TypeOfObject)
|
||||
{
|
||||
type = dataNode.Value.GetType();
|
||||
if (type == Globals.TypeOfObject)
|
||||
{
|
||||
internalNodeType = ExtensionDataNodeType.EndElement;
|
||||
return;
|
||||
}
|
||||
isTypedNode = false;
|
||||
}
|
||||
|
||||
if (!MoveToText(type, dataNode, isTypedNode))
|
||||
{
|
||||
if (dataNode.IsFinalValue)
|
||||
{
|
||||
internalNodeType = ExtensionDataNodeType.EndElement;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new XmlException(SR.Format(SR.InvalidDataNode, DataContract.GetClrTypeFullName(type))));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private bool MoveToText(Type type, IDataNode dataNode, bool isTypedNode)
|
||||
{
|
||||
bool handled = true;
|
||||
switch (Type.GetTypeCode(type))
|
||||
{
|
||||
case TypeCode.Boolean:
|
||||
value = XmlConvert.ToString(isTypedNode ? ((DataNode<bool>)dataNode).GetValue() : (bool)dataNode.Value);
|
||||
break;
|
||||
case TypeCode.Char:
|
||||
value = XmlConvert.ToString((int)(isTypedNode ? ((DataNode<char>)dataNode).GetValue() : (char)dataNode.Value));
|
||||
break;
|
||||
case TypeCode.Byte:
|
||||
value = XmlConvert.ToString(isTypedNode ? ((DataNode<byte>)dataNode).GetValue() : (byte)dataNode.Value);
|
||||
break;
|
||||
case TypeCode.Int16:
|
||||
value = XmlConvert.ToString(isTypedNode ? ((DataNode<short>)dataNode).GetValue() : (short)dataNode.Value);
|
||||
break;
|
||||
case TypeCode.Int32:
|
||||
value = XmlConvert.ToString(isTypedNode ? ((DataNode<int>)dataNode).GetValue() : (int)dataNode.Value);
|
||||
break;
|
||||
case TypeCode.Int64:
|
||||
value = XmlConvert.ToString(isTypedNode ? ((DataNode<long>)dataNode).GetValue() : (long)dataNode.Value);
|
||||
break;
|
||||
case TypeCode.Single:
|
||||
value = XmlConvert.ToString(isTypedNode ? ((DataNode<float>)dataNode).GetValue() : (float)dataNode.Value);
|
||||
break;
|
||||
case TypeCode.Double:
|
||||
value = XmlConvert.ToString(isTypedNode ? ((DataNode<double>)dataNode).GetValue() : (double)dataNode.Value);
|
||||
break;
|
||||
case TypeCode.Decimal:
|
||||
value = XmlConvert.ToString(isTypedNode ? ((DataNode<decimal>)dataNode).GetValue() : (decimal)dataNode.Value);
|
||||
break;
|
||||
case TypeCode.DateTime:
|
||||
DateTime dateTime = isTypedNode ? ((DataNode<DateTime>)dataNode).GetValue() : (DateTime)dataNode.Value;
|
||||
value = dateTime.ToString("yyyy-MM-ddTHH:mm:ss.fffffffK", DateTimeFormatInfo.InvariantInfo);
|
||||
break;
|
||||
case TypeCode.String:
|
||||
value = isTypedNode ? ((DataNode<string>)dataNode).GetValue() : (string)dataNode.Value;
|
||||
break;
|
||||
case TypeCode.SByte:
|
||||
value = XmlConvert.ToString(isTypedNode ? ((DataNode<sbyte>)dataNode).GetValue() : (sbyte)dataNode.Value);
|
||||
break;
|
||||
case TypeCode.UInt16:
|
||||
value = XmlConvert.ToString(isTypedNode ? ((DataNode<ushort>)dataNode).GetValue() : (ushort)dataNode.Value);
|
||||
break;
|
||||
case TypeCode.UInt32:
|
||||
value = XmlConvert.ToString(isTypedNode ? ((DataNode<uint>)dataNode).GetValue() : (uint)dataNode.Value);
|
||||
break;
|
||||
case TypeCode.UInt64:
|
||||
value = XmlConvert.ToString(isTypedNode ? ((DataNode<ulong>)dataNode).GetValue() : (ulong)dataNode.Value);
|
||||
break;
|
||||
case TypeCode.Object:
|
||||
default:
|
||||
if (type == Globals.TypeOfByteArray)
|
||||
{
|
||||
byte[] bytes = isTypedNode ? ((DataNode<byte[]>)dataNode).GetValue() : (byte[])dataNode.Value;
|
||||
value = (bytes == null) ? string.Empty : Convert.ToBase64String(bytes);
|
||||
}
|
||||
else if (type == Globals.TypeOfTimeSpan)
|
||||
{
|
||||
value = XmlConvert.ToString(isTypedNode ? ((DataNode<TimeSpan>)dataNode).GetValue() : (TimeSpan)dataNode.Value);
|
||||
}
|
||||
else if (type == Globals.TypeOfGuid)
|
||||
{
|
||||
Guid guid = isTypedNode ? ((DataNode<Guid>)dataNode).GetValue() : (Guid)dataNode.Value;
|
||||
value = guid.ToString();
|
||||
}
|
||||
else if (type == Globals.TypeOfUri)
|
||||
{
|
||||
Uri uri = isTypedNode ? ((DataNode<Uri>)dataNode).GetValue() : (Uri)dataNode.Value;
|
||||
value = uri.GetComponents(UriComponents.SerializationInfoString, UriFormat.UriEscaped);
|
||||
}
|
||||
else
|
||||
{
|
||||
handled = false;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (handled)
|
||||
{
|
||||
internalNodeType = ExtensionDataNodeType.Text;
|
||||
}
|
||||
|
||||
return handled;
|
||||
}
|
||||
|
||||
private void PushElement()
|
||||
{
|
||||
GrowElementsIfNeeded();
|
||||
elements[depth++] = element;
|
||||
if (nextElement == null)
|
||||
{
|
||||
element = GetNextElement();
|
||||
}
|
||||
else
|
||||
{
|
||||
element = nextElement;
|
||||
nextElement = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void PopElement()
|
||||
{
|
||||
prefix = element.prefix;
|
||||
localName = element.localName;
|
||||
ns = element.ns;
|
||||
|
||||
if (depth == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
depth--;
|
||||
|
||||
if (elements != null)
|
||||
{
|
||||
element = elements[depth];
|
||||
}
|
||||
}
|
||||
|
||||
private void GrowElementsIfNeeded()
|
||||
{
|
||||
if (elements == null)
|
||||
{
|
||||
elements = new ElementData[8];
|
||||
}
|
||||
else if (elements.Length == depth)
|
||||
{
|
||||
ElementData[] newElements = new ElementData[elements.Length * 2];
|
||||
Array.Copy(elements, 0, newElements, 0, elements.Length);
|
||||
elements = newElements;
|
||||
}
|
||||
}
|
||||
|
||||
private ElementData GetNextElement()
|
||||
{
|
||||
int nextDepth = depth + 1;
|
||||
return (elements == null || elements.Length <= nextDepth || elements[nextDepth] == null)
|
||||
? new ElementData() : elements[nextDepth];
|
||||
}
|
||||
|
||||
internal static string GetPrefix(string ns)
|
||||
{
|
||||
ns = ns ?? string.Empty;
|
||||
if (!nsToPrefixTable.TryGetValue(ns, out string prefix))
|
||||
{
|
||||
lock (nsToPrefixTable)
|
||||
{
|
||||
if (!nsToPrefixTable.TryGetValue(ns, out prefix))
|
||||
{
|
||||
prefix = (ns == null || ns.Length == 0) ? string.Empty : "p" + nsToPrefixTable.Count;
|
||||
AddPrefix(prefix, ns);
|
||||
}
|
||||
}
|
||||
}
|
||||
return prefix;
|
||||
}
|
||||
|
||||
private static void AddPrefix(string prefix, string ns)
|
||||
{
|
||||
nsToPrefixTable.Add(ns, prefix);
|
||||
prefixToNsTable.Add(prefix, ns);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Xml;
|
||||
|
||||
namespace Compat.Runtime.Serialization
|
||||
{
|
||||
internal class GenericInfo : IGenericNameProvider
|
||||
{
|
||||
private readonly string genericTypeName;
|
||||
private readonly XmlQualifiedName stableName;
|
||||
private List<GenericInfo> paramGenericInfos;
|
||||
private readonly List<int> nestedParamCounts;
|
||||
|
||||
internal GenericInfo(XmlQualifiedName stableName, string genericTypeName)
|
||||
{
|
||||
this.stableName = stableName;
|
||||
this.genericTypeName = genericTypeName;
|
||||
nestedParamCounts = new List<int>
|
||||
{
|
||||
0
|
||||
};
|
||||
}
|
||||
|
||||
internal void Add(GenericInfo actualParamInfo)
|
||||
{
|
||||
if (paramGenericInfos == null)
|
||||
{
|
||||
paramGenericInfos = new List<GenericInfo>();
|
||||
}
|
||||
|
||||
paramGenericInfos.Add(actualParamInfo);
|
||||
}
|
||||
|
||||
internal void AddToLevel(int level, int count)
|
||||
{
|
||||
if (level >= nestedParamCounts.Count)
|
||||
{
|
||||
do
|
||||
{
|
||||
nestedParamCounts.Add((level == nestedParamCounts.Count) ? count : 0);
|
||||
} while (level >= nestedParamCounts.Count);
|
||||
}
|
||||
else
|
||||
{
|
||||
nestedParamCounts[level] = nestedParamCounts[level] + count;
|
||||
}
|
||||
}
|
||||
|
||||
internal XmlQualifiedName GetExpandedStableName()
|
||||
{
|
||||
if (paramGenericInfos == null)
|
||||
{
|
||||
return stableName;
|
||||
}
|
||||
|
||||
return new XmlQualifiedName(DataContract.EncodeLocalName(DataContract.ExpandGenericParameters(XmlConvert.DecodeName(stableName.Name), this)), stableName.Namespace);
|
||||
}
|
||||
|
||||
internal string GetStableNamespace()
|
||||
{
|
||||
return stableName.Namespace;
|
||||
}
|
||||
|
||||
internal XmlQualifiedName StableName => stableName;
|
||||
|
||||
internal IList<GenericInfo> Parameters => paramGenericInfos;
|
||||
|
||||
public int GetParameterCount()
|
||||
{
|
||||
return paramGenericInfos.Count;
|
||||
}
|
||||
|
||||
public IList<int> GetNestedParameterCounts()
|
||||
{
|
||||
return nestedParamCounts;
|
||||
}
|
||||
|
||||
public string GetParameterName(int paramIndex)
|
||||
{
|
||||
return paramGenericInfos[paramIndex].GetExpandedStableName().Name;
|
||||
}
|
||||
|
||||
public string GetNamespaces()
|
||||
{
|
||||
StringBuilder namespaces = new StringBuilder();
|
||||
for (int j = 0; j < paramGenericInfos.Count; j++)
|
||||
{
|
||||
namespaces.Append(" ").Append(paramGenericInfos[j].GetStableNamespace());
|
||||
}
|
||||
|
||||
return namespaces.ToString();
|
||||
}
|
||||
|
||||
public string GetGenericTypeName()
|
||||
{
|
||||
return genericTypeName;
|
||||
}
|
||||
|
||||
public bool ParametersFromBuiltInNamespaces
|
||||
{
|
||||
get
|
||||
{
|
||||
bool parametersFromBuiltInNamespaces = true;
|
||||
for (int j = 0; j < paramGenericInfos.Count; j++)
|
||||
{
|
||||
if (parametersFromBuiltInNamespaces)
|
||||
{
|
||||
parametersFromBuiltInNamespaces = DataContract.IsBuiltInNamespace(paramGenericInfos[j].GetStableNamespace());
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
return parametersFromBuiltInNamespaces;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Xml;
|
||||
|
||||
namespace Compat.Runtime.Serialization
|
||||
{
|
||||
internal interface IGenericNameProvider
|
||||
{
|
||||
int GetParameterCount();
|
||||
IList<int> GetNestedParameterCounts();
|
||||
string GetParameterName(int paramIndex);
|
||||
string GetNamespaces();
|
||||
string GetGenericTypeName();
|
||||
bool ParametersFromBuiltInNamespaces { get; }
|
||||
}
|
||||
|
||||
internal class GenericNameProvider : IGenericNameProvider
|
||||
{
|
||||
private readonly string _genericTypeName;
|
||||
private readonly object[] _genericParams; //Type or DataContract
|
||||
private readonly IList<int> _nestedParamCounts;
|
||||
|
||||
internal GenericNameProvider(Type type)
|
||||
: this(DataContract.GetClrTypeFullName(type.GetGenericTypeDefinition()), type.GetGenericArguments())
|
||||
{
|
||||
}
|
||||
|
||||
internal GenericNameProvider(string genericTypeName, object[] genericParams)
|
||||
{
|
||||
_genericTypeName = genericTypeName;
|
||||
_genericParams = new object[genericParams.Length];
|
||||
genericParams.CopyTo(_genericParams, 0);
|
||||
|
||||
DataContract.GetClrNameAndNamespace(genericTypeName, out string name, out string ns);
|
||||
_nestedParamCounts = DataContract.GetDataContractNameForGenericName(name, null);
|
||||
}
|
||||
|
||||
public int GetParameterCount()
|
||||
{
|
||||
return _genericParams.Length;
|
||||
}
|
||||
|
||||
public IList<int> GetNestedParameterCounts()
|
||||
{
|
||||
return _nestedParamCounts;
|
||||
}
|
||||
|
||||
public string GetParameterName(int paramIndex)
|
||||
{
|
||||
return GetStableName(paramIndex).Name;
|
||||
}
|
||||
|
||||
public string GetNamespaces()
|
||||
{
|
||||
StringBuilder namespaces = new StringBuilder();
|
||||
for (int j = 0; j < GetParameterCount(); j++)
|
||||
{
|
||||
namespaces.Append(" ").Append(GetStableName(j).Namespace);
|
||||
}
|
||||
|
||||
return namespaces.ToString();
|
||||
}
|
||||
|
||||
public string GetGenericTypeName()
|
||||
{
|
||||
return _genericTypeName;
|
||||
}
|
||||
|
||||
public bool ParametersFromBuiltInNamespaces
|
||||
{
|
||||
get
|
||||
{
|
||||
bool parametersFromBuiltInNamespaces = true;
|
||||
for (int j = 0; j < GetParameterCount(); j++)
|
||||
{
|
||||
if (parametersFromBuiltInNamespaces)
|
||||
{
|
||||
parametersFromBuiltInNamespaces = DataContract.IsBuiltInNamespace(GetStableName(j).Namespace);
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
return parametersFromBuiltInNamespaces;
|
||||
}
|
||||
}
|
||||
|
||||
private XmlQualifiedName GetStableName(int i)
|
||||
{
|
||||
object o = _genericParams[i];
|
||||
XmlQualifiedName qname = o as XmlQualifiedName;
|
||||
if (qname == null)
|
||||
{
|
||||
Type paramType = o as Type;
|
||||
if (paramType != null)
|
||||
{
|
||||
_genericParams[i] = qname = DataContract.GetStableName(paramType);
|
||||
}
|
||||
else
|
||||
{
|
||||
_genericParams[i] = qname = ((DataContract)o).StableName;
|
||||
}
|
||||
}
|
||||
return qname;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Compat.Runtime.Serialization
|
||||
{
|
||||
internal sealed class GenericParameterDataContract : DataContract
|
||||
{
|
||||
private readonly GenericParameterDataContractCriticalHelper _helper;
|
||||
|
||||
internal GenericParameterDataContract(Type type)
|
||||
: base(new GenericParameterDataContractCriticalHelper(type))
|
||||
{
|
||||
_helper = base.Helper as GenericParameterDataContractCriticalHelper;
|
||||
}
|
||||
|
||||
internal int ParameterPosition => _helper.ParameterPosition;
|
||||
|
||||
internal override bool IsBuiltInDataContract => true;
|
||||
|
||||
private class GenericParameterDataContractCriticalHelper : DataContract.DataContractCriticalHelper
|
||||
{
|
||||
private readonly int parameterPosition;
|
||||
|
||||
internal GenericParameterDataContractCriticalHelper(Type type)
|
||||
: base(type)
|
||||
{
|
||||
SetDataContractName(DataContract.GetStableName(type));
|
||||
parameterPosition = type.GenericParameterPosition;
|
||||
}
|
||||
|
||||
internal int ParameterPosition => parameterPosition;
|
||||
}
|
||||
|
||||
internal override DataContract BindGenericParameters(DataContract[] paramContracts, Dictionary<DataContract, DataContract> boundContracts)
|
||||
{
|
||||
return paramContracts[ParameterPosition];
|
||||
}
|
||||
}
|
||||
}
|
||||
1445
Compat.Private.Serialization/Compat/Runtime/Serialization/Globals.cs
Normal file
1445
Compat.Private.Serialization/Compat/Runtime/Serialization/Globals.cs
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,70 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Compat.Runtime.Serialization
|
||||
{
|
||||
internal class HybridObjectCache
|
||||
{
|
||||
private Dictionary<string, object> _objectDictionary;
|
||||
private Dictionary<string, object> _referencedObjectDictionary;
|
||||
|
||||
internal HybridObjectCache()
|
||||
{
|
||||
}
|
||||
|
||||
internal void Add(string id, object obj)
|
||||
{
|
||||
if (_objectDictionary == null)
|
||||
{
|
||||
_objectDictionary = new Dictionary<string, object>();
|
||||
}
|
||||
|
||||
if (_objectDictionary.TryGetValue(id, out object existingObject))
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(SR.Format(SR.MultipleIdDefinition, id)));
|
||||
}
|
||||
|
||||
_objectDictionary.Add(id, obj);
|
||||
}
|
||||
|
||||
internal void Remove(string id)
|
||||
{
|
||||
if (_objectDictionary != null)
|
||||
{
|
||||
_objectDictionary.Remove(id);
|
||||
}
|
||||
}
|
||||
|
||||
internal object GetObject(string id)
|
||||
{
|
||||
if (_referencedObjectDictionary == null)
|
||||
{
|
||||
_referencedObjectDictionary = new Dictionary<string, object>
|
||||
{
|
||||
{ id, null }
|
||||
};
|
||||
}
|
||||
else if (!_referencedObjectDictionary.ContainsKey(id))
|
||||
{
|
||||
_referencedObjectDictionary.Add(id, null);
|
||||
}
|
||||
|
||||
if (_objectDictionary != null)
|
||||
{
|
||||
_objectDictionary.TryGetValue(id, out object obj);
|
||||
return obj;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
internal bool IsObjectReferenced(string id)
|
||||
{
|
||||
if (_referencedObjectDictionary != null)
|
||||
{
|
||||
return _referencedObjectDictionary.ContainsKey(id);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
using System;
|
||||
using System.Reflection;
|
||||
using System.Collections.ObjectModel;
|
||||
|
||||
namespace Compat.Runtime.Serialization
|
||||
{
|
||||
public interface IDataContractSurrogate
|
||||
{
|
||||
Type GetDataContractType(Type type);
|
||||
object GetObjectToSerialize(object obj, Type targetType);
|
||||
object GetDeserializedObject(object obj, Type targetType);
|
||||
object GetCustomDataToExport(MemberInfo memberInfo, Type dataContractType);
|
||||
object GetCustomDataToExport(Type clrType, Type dataContractType);
|
||||
void GetKnownCustomDataTypes(Collection<Type> customDataTypes);
|
||||
Type GetReferencedTypeOnImport(string typeName, string typeNamespace, object customData);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
using System;
|
||||
|
||||
namespace Compat.Runtime.Serialization
|
||||
{
|
||||
internal interface IDataNode
|
||||
{
|
||||
Type DataType { get; }
|
||||
object Value { get; set; } // boxes for primitives
|
||||
string DataContractName { get; set; }
|
||||
string DataContractNamespace { get; set; }
|
||||
string ClrTypeName { get; set; }
|
||||
string ClrAssemblyName { get; set; }
|
||||
string Id { get; set; }
|
||||
bool PreservesReferences { get; }
|
||||
|
||||
// NOTE: consider moving below APIs to DataNode<T> if IDataNode API is made public
|
||||
void GetData(ElementData element);
|
||||
bool IsFinalValue { get; set; }
|
||||
void Clear();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
namespace Compat.Runtime.Serialization
|
||||
{
|
||||
internal class ISerializableDataMember
|
||||
{
|
||||
internal string Name { get; set; }
|
||||
|
||||
internal IDataNode Value { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Compat.Runtime.Serialization
|
||||
{
|
||||
internal class ISerializableDataNode : DataNode<object>
|
||||
{
|
||||
private string _factoryTypeName;
|
||||
private string _factoryTypeNamespace;
|
||||
private IList<ISerializableDataMember> _members;
|
||||
|
||||
internal ISerializableDataNode()
|
||||
{
|
||||
dataType = Globals.TypeOfISerializableDataNode;
|
||||
}
|
||||
|
||||
internal string FactoryTypeName
|
||||
{
|
||||
get => _factoryTypeName;
|
||||
set => _factoryTypeName = value;
|
||||
}
|
||||
|
||||
internal string FactoryTypeNamespace
|
||||
{
|
||||
get => _factoryTypeNamespace;
|
||||
set => _factoryTypeNamespace = value;
|
||||
}
|
||||
|
||||
internal IList<ISerializableDataMember> Members
|
||||
{
|
||||
get => _members;
|
||||
set => _members = value;
|
||||
}
|
||||
|
||||
public override void GetData(ElementData element)
|
||||
{
|
||||
base.GetData(element);
|
||||
|
||||
if (FactoryTypeName != null)
|
||||
{
|
||||
AddQualifiedNameAttribute(element, Globals.SerPrefix, Globals.ISerializableFactoryTypeLocalName, Globals.SerializationNamespace, FactoryTypeName, FactoryTypeNamespace);
|
||||
}
|
||||
}
|
||||
|
||||
public override void Clear()
|
||||
{
|
||||
base.Clear();
|
||||
_members = null;
|
||||
_factoryTypeName = _factoryTypeNamespace = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
namespace Compat.Runtime.Serialization
|
||||
{
|
||||
internal class IntRef
|
||||
{
|
||||
private readonly int _value;
|
||||
|
||||
public IntRef(int value)
|
||||
{
|
||||
_value = value;
|
||||
}
|
||||
|
||||
public int Value => _value;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
using System;
|
||||
using System.Xml;
|
||||
using DataContractResolver = System.Runtime.Serialization.DataContractResolver;
|
||||
|
||||
namespace Compat.Runtime.Serialization
|
||||
{
|
||||
internal sealed class KnownTypeDataContractResolver : DataContractResolver
|
||||
{
|
||||
private readonly XmlObjectSerializerContext _context;
|
||||
|
||||
internal KnownTypeDataContractResolver(XmlObjectSerializerContext context)
|
||||
{
|
||||
Fx.Assert(context != null, "KnownTypeDataContractResolver should not be instantiated with a null context");
|
||||
_context = context;
|
||||
}
|
||||
|
||||
public override bool TryResolveType(Type type, Type declaredType, DataContractResolver knownTypeResolver, out XmlDictionaryString typeName, out XmlDictionaryString typeNamespace)
|
||||
{
|
||||
if (type == null)
|
||||
{
|
||||
typeName = null;
|
||||
typeNamespace = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (declaredType != null && declaredType.IsInterface && CollectionDataContract.IsCollectionInterface(declaredType))
|
||||
{
|
||||
typeName = null;
|
||||
typeNamespace = null;
|
||||
return true;
|
||||
}
|
||||
|
||||
DataContract contract = DataContract.GetDataContract(type);
|
||||
if (_context.IsKnownType(contract, contract.KnownDataContracts, declaredType))
|
||||
{
|
||||
typeName = contract.Name;
|
||||
typeNamespace = contract.Namespace;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
typeName = null;
|
||||
typeNamespace = null;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public override Type ResolveName(string typeName, string typeNamespace, Type declaredType, DataContractResolver knownTypeResolver)
|
||||
{
|
||||
if (typeName == null || typeNamespace == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return _context.ResolveNameFromKnownTypes(new XmlQualifiedName(typeName, typeNamespace));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,599 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.Serialization.Formatters;
|
||||
using System.Xml;
|
||||
using IFormatter = System.Runtime.Serialization.IFormatter;
|
||||
using ISerializationSurrogate = System.Runtime.Serialization.ISerializationSurrogate;
|
||||
using ISurrogateSelector = System.Runtime.Serialization.ISurrogateSelector;
|
||||
using SerializationBinder = System.Runtime.Serialization.SerializationBinder;
|
||||
using SerializationInfo = System.Runtime.Serialization.SerializationInfo;
|
||||
using StreamingContext = System.Runtime.Serialization.StreamingContext;
|
||||
using StreamingContextStates = System.Runtime.Serialization.StreamingContextStates;
|
||||
|
||||
namespace Compat.Runtime.Serialization
|
||||
{
|
||||
public sealed class NetDataContractSerializer : XmlObjectSerializer, IFormatter
|
||||
{
|
||||
private XmlDictionaryString rootName;
|
||||
private XmlDictionaryString rootNamespace;
|
||||
private StreamingContext context;
|
||||
private SerializationBinder binder;
|
||||
private ISurrogateSelector surrogateSelector;
|
||||
private int maxItemsInObjectGraph;
|
||||
private bool ignoreExtensionDataObject;
|
||||
private FormatterAssemblyStyle assemblyFormat;
|
||||
private DataContract cachedDataContract;
|
||||
private static readonly Hashtable typeNameCache = new Hashtable();
|
||||
|
||||
public NetDataContractSerializer()
|
||||
: this(new StreamingContext(StreamingContextStates.All))
|
||||
{
|
||||
}
|
||||
|
||||
public NetDataContractSerializer(StreamingContext context)
|
||||
: this(context, int.MaxValue, false, FormatterAssemblyStyle.Full, null)
|
||||
{
|
||||
}
|
||||
|
||||
public NetDataContractSerializer(StreamingContext context,
|
||||
int maxItemsInObjectGraph,
|
||||
bool ignoreExtensionDataObject,
|
||||
FormatterAssemblyStyle assemblyFormat,
|
||||
ISurrogateSelector surrogateSelector)
|
||||
{
|
||||
Initialize(context, maxItemsInObjectGraph, ignoreExtensionDataObject, assemblyFormat, surrogateSelector);
|
||||
}
|
||||
|
||||
public NetDataContractSerializer(string rootName, string rootNamespace)
|
||||
: this(rootName, rootNamespace, new StreamingContext(StreamingContextStates.All), int.MaxValue, false, FormatterAssemblyStyle.Full, null)
|
||||
{
|
||||
}
|
||||
|
||||
public NetDataContractSerializer(string rootName, string rootNamespace,
|
||||
StreamingContext context,
|
||||
int maxItemsInObjectGraph,
|
||||
bool ignoreExtensionDataObject,
|
||||
FormatterAssemblyStyle assemblyFormat,
|
||||
ISurrogateSelector surrogateSelector)
|
||||
{
|
||||
XmlDictionary dictionary = new XmlDictionary(2);
|
||||
Initialize(dictionary.Add(rootName), dictionary.Add(DataContract.GetNamespace(rootNamespace)), context, maxItemsInObjectGraph, ignoreExtensionDataObject, assemblyFormat, surrogateSelector);
|
||||
}
|
||||
|
||||
public NetDataContractSerializer(XmlDictionaryString rootName, XmlDictionaryString rootNamespace)
|
||||
: this(rootName, rootNamespace, new StreamingContext(StreamingContextStates.All), int.MaxValue, false, FormatterAssemblyStyle.Full, null)
|
||||
{
|
||||
}
|
||||
|
||||
public NetDataContractSerializer(XmlDictionaryString rootName, XmlDictionaryString rootNamespace,
|
||||
StreamingContext context,
|
||||
int maxItemsInObjectGraph,
|
||||
bool ignoreExtensionDataObject,
|
||||
FormatterAssemblyStyle assemblyFormat,
|
||||
ISurrogateSelector surrogateSelector)
|
||||
{
|
||||
Initialize(rootName, rootNamespace, context, maxItemsInObjectGraph, ignoreExtensionDataObject, assemblyFormat, surrogateSelector);
|
||||
}
|
||||
|
||||
private void Initialize(StreamingContext context,
|
||||
int maxItemsInObjectGraph,
|
||||
bool ignoreExtensionDataObject,
|
||||
FormatterAssemblyStyle assemblyFormat,
|
||||
ISurrogateSelector surrogateSelector)
|
||||
{
|
||||
this.context = context;
|
||||
if (maxItemsInObjectGraph < 0)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException(nameof(maxItemsInObjectGraph), SR.ValueMustBeNonNegative));
|
||||
}
|
||||
|
||||
this.maxItemsInObjectGraph = maxItemsInObjectGraph;
|
||||
this.ignoreExtensionDataObject = ignoreExtensionDataObject;
|
||||
this.surrogateSelector = surrogateSelector;
|
||||
AssemblyFormat = assemblyFormat;
|
||||
}
|
||||
|
||||
private void Initialize(XmlDictionaryString rootName, XmlDictionaryString rootNamespace,
|
||||
StreamingContext context,
|
||||
int maxItemsInObjectGraph,
|
||||
bool ignoreExtensionDataObject,
|
||||
FormatterAssemblyStyle assemblyFormat,
|
||||
ISurrogateSelector surrogateSelector)
|
||||
{
|
||||
Initialize(context, maxItemsInObjectGraph, ignoreExtensionDataObject, assemblyFormat, surrogateSelector);
|
||||
this.rootName = rootName;
|
||||
this.rootNamespace = rootNamespace;
|
||||
}
|
||||
|
||||
public StreamingContext Context
|
||||
{
|
||||
get => context;
|
||||
set => context = value;
|
||||
}
|
||||
|
||||
public SerializationBinder Binder
|
||||
{
|
||||
get => binder;
|
||||
set => binder = value;
|
||||
}
|
||||
|
||||
public ISurrogateSelector SurrogateSelector
|
||||
{
|
||||
get => surrogateSelector;
|
||||
set => surrogateSelector = value;
|
||||
}
|
||||
|
||||
public FormatterAssemblyStyle AssemblyFormat
|
||||
{
|
||||
get => assemblyFormat;
|
||||
set
|
||||
{
|
||||
if (value != FormatterAssemblyStyle.Full && value != FormatterAssemblyStyle.Simple)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(SR.Format(SR.InvalidAssemblyFormat, value)));
|
||||
}
|
||||
|
||||
assemblyFormat = value;
|
||||
}
|
||||
}
|
||||
|
||||
public int MaxItemsInObjectGraph => maxItemsInObjectGraph;
|
||||
|
||||
public bool IgnoreExtensionDataObject => ignoreExtensionDataObject;
|
||||
|
||||
public void Serialize(Stream stream, object graph)
|
||||
{
|
||||
base.WriteObject(stream, graph);
|
||||
}
|
||||
|
||||
public object Deserialize(Stream stream)
|
||||
{
|
||||
return base.ReadObject(stream);
|
||||
}
|
||||
|
||||
public object Deserialize(XmlReader reader)
|
||||
{
|
||||
return base.ReadObject(reader);
|
||||
}
|
||||
|
||||
internal override void InternalWriteObject(XmlWriterDelegator writer, object graph)
|
||||
{
|
||||
Hashtable surrogateDataContracts = null;
|
||||
DataContract contract = GetDataContract(graph, ref surrogateDataContracts);
|
||||
|
||||
InternalWriteStartObject(writer, graph, contract);
|
||||
InternalWriteObjectContent(writer, graph, contract, surrogateDataContracts);
|
||||
InternalWriteEndObject(writer);
|
||||
}
|
||||
|
||||
public override void WriteObject(XmlWriter writer, object graph)
|
||||
{
|
||||
WriteObjectHandleExceptions(new XmlWriterDelegator(writer), graph);
|
||||
}
|
||||
|
||||
public override void WriteStartObject(XmlWriter writer, object graph)
|
||||
{
|
||||
WriteStartObjectHandleExceptions(new XmlWriterDelegator(writer), graph);
|
||||
}
|
||||
|
||||
public override void WriteObjectContent(XmlWriter writer, object graph)
|
||||
{
|
||||
WriteObjectContentHandleExceptions(new XmlWriterDelegator(writer), graph);
|
||||
}
|
||||
|
||||
public override void WriteEndObject(XmlWriter writer)
|
||||
{
|
||||
WriteEndObjectHandleExceptions(new XmlWriterDelegator(writer));
|
||||
}
|
||||
|
||||
public override void WriteStartObject(XmlDictionaryWriter writer, object graph)
|
||||
{
|
||||
WriteStartObjectHandleExceptions(new XmlWriterDelegator(writer), graph);
|
||||
}
|
||||
|
||||
internal override void InternalWriteStartObject(XmlWriterDelegator writer, object graph)
|
||||
{
|
||||
Hashtable surrogateDataContracts = null;
|
||||
DataContract contract = GetDataContract(graph, ref surrogateDataContracts);
|
||||
InternalWriteStartObject(writer, graph, contract);
|
||||
}
|
||||
|
||||
private void InternalWriteStartObject(XmlWriterDelegator writer, object graph, DataContract contract)
|
||||
{
|
||||
WriteRootElement(writer, contract, rootName, rootNamespace, CheckIfNeedsContractNsAtRoot(rootName, rootNamespace, contract));
|
||||
}
|
||||
|
||||
public override void WriteObjectContent(XmlDictionaryWriter writer, object graph)
|
||||
{
|
||||
WriteObjectContentHandleExceptions(new XmlWriterDelegator(writer), graph);
|
||||
}
|
||||
|
||||
internal override void InternalWriteObjectContent(XmlWriterDelegator writer, object graph)
|
||||
{
|
||||
Hashtable surrogateDataContracts = null;
|
||||
DataContract contract = GetDataContract(graph, ref surrogateDataContracts);
|
||||
InternalWriteObjectContent(writer, graph, contract, surrogateDataContracts);
|
||||
}
|
||||
|
||||
private void InternalWriteObjectContent(XmlWriterDelegator writer, object graph, DataContract contract, Hashtable surrogateDataContracts)
|
||||
{
|
||||
if (MaxItemsInObjectGraph == 0)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(SR.Format(SR.ExceededMaxItemsQuota, MaxItemsInObjectGraph)));
|
||||
}
|
||||
|
||||
if (IsRootXmlAny(rootName, contract))
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(SR.Format(SR.IsAnyNotSupportedByNetDataContractSerializer, contract.UnderlyingType)));
|
||||
}
|
||||
else if (graph == null)
|
||||
{
|
||||
WriteNull(writer);
|
||||
}
|
||||
else
|
||||
{
|
||||
Type graphType = graph.GetType();
|
||||
if (contract.UnderlyingType != graphType)
|
||||
{
|
||||
contract = GetDataContract(graph, ref surrogateDataContracts);
|
||||
}
|
||||
|
||||
XmlObjectSerializerWriteContext context = null;
|
||||
if (contract.CanContainReferences)
|
||||
{
|
||||
context = XmlObjectSerializerWriteContext.CreateContext(this, surrogateDataContracts);
|
||||
context.HandleGraphAtTopLevel(writer, graph, contract);
|
||||
}
|
||||
|
||||
WriteClrTypeInfo(writer, contract, binder);
|
||||
contract.WriteXmlValue(writer, graph, context);
|
||||
}
|
||||
}
|
||||
|
||||
// Update the overloads whenever you are changing this method
|
||||
internal static void WriteClrTypeInfo(XmlWriterDelegator writer, DataContract dataContract, SerializationBinder binder)
|
||||
{
|
||||
if (!dataContract.IsISerializable && !(dataContract is SurrogateDataContract))
|
||||
{
|
||||
TypeInformation typeInformation = null;
|
||||
Type clrType = dataContract.OriginalUnderlyingType;
|
||||
string clrTypeName = null;
|
||||
string clrAssemblyName = null;
|
||||
|
||||
if (binder != null)
|
||||
{
|
||||
binder.BindToName(clrType, out clrAssemblyName, out clrTypeName);
|
||||
}
|
||||
|
||||
if (clrTypeName == null)
|
||||
{
|
||||
typeInformation = NetDataContractSerializer.GetTypeInformation(clrType);
|
||||
clrTypeName = typeInformation.FullTypeName;
|
||||
}
|
||||
|
||||
if (clrAssemblyName == null)
|
||||
{
|
||||
clrAssemblyName = (typeInformation == null) ?
|
||||
NetDataContractSerializer.GetTypeInformation(clrType).AssemblyString :
|
||||
typeInformation.AssemblyString;
|
||||
|
||||
// Throw in the [TypeForwardedFrom] case to prevent a partially trusted assembly from forwarding itself to an assembly with higher privileges
|
||||
if (!UnsafeTypeForwardingEnabled && !clrType.Assembly.IsFullyTrusted && !IsAssemblyNameForwardingSafe(clrType.Assembly.FullName, clrAssemblyName))
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(SR.Format(SR.TypeCannotBeForwardedFrom, DataContract.GetClrTypeFullName(clrType), clrType.Assembly.FullName, clrAssemblyName)));
|
||||
}
|
||||
}
|
||||
|
||||
WriteClrTypeInfo(writer, clrTypeName, clrAssemblyName);
|
||||
}
|
||||
}
|
||||
|
||||
public static bool UnsafeTypeForwardingEnabled => false;
|
||||
|
||||
// Update the overloads whenever you are changing this method
|
||||
internal static void WriteClrTypeInfo(XmlWriterDelegator writer, Type dataContractType, SerializationBinder binder, string defaultClrTypeName, string defaultClrAssemblyName)
|
||||
{
|
||||
string clrTypeName = null;
|
||||
string clrAssemblyName = null;
|
||||
|
||||
if (binder != null)
|
||||
{
|
||||
binder.BindToName(dataContractType, out clrAssemblyName, out clrTypeName);
|
||||
}
|
||||
|
||||
if (clrTypeName == null)
|
||||
{
|
||||
clrTypeName = defaultClrTypeName;
|
||||
}
|
||||
|
||||
if (clrAssemblyName == null)
|
||||
{
|
||||
clrAssemblyName = defaultClrAssemblyName;
|
||||
}
|
||||
|
||||
WriteClrTypeInfo(writer, clrTypeName, clrAssemblyName);
|
||||
}
|
||||
|
||||
// Update the overloads whenever you are changing this method
|
||||
internal static void WriteClrTypeInfo(
|
||||
XmlWriterDelegator writer,
|
||||
Type dataContractType,
|
||||
SerializationBinder binder,
|
||||
SerializationInfo serInfo)
|
||||
{
|
||||
TypeInformation typeInformation = null;
|
||||
string clrTypeName = null;
|
||||
string clrAssemblyName = null;
|
||||
|
||||
if (binder != null)
|
||||
{
|
||||
binder.BindToName(dataContractType, out clrAssemblyName, out clrTypeName);
|
||||
}
|
||||
|
||||
if (clrTypeName == null)
|
||||
{
|
||||
if (serInfo.IsFullTypeNameSetExplicit)
|
||||
{
|
||||
clrTypeName = serInfo.FullTypeName;
|
||||
}
|
||||
else
|
||||
{
|
||||
typeInformation = NetDataContractSerializer.GetTypeInformation(serInfo.ObjectType);
|
||||
clrTypeName = typeInformation.FullTypeName;
|
||||
}
|
||||
}
|
||||
|
||||
if (clrAssemblyName == null)
|
||||
{
|
||||
if (serInfo.IsAssemblyNameSetExplicit)
|
||||
{
|
||||
clrAssemblyName = serInfo.AssemblyName;
|
||||
}
|
||||
else
|
||||
{
|
||||
clrAssemblyName = (typeInformation == null) ?
|
||||
NetDataContractSerializer.GetTypeInformation(serInfo.ObjectType).AssemblyString :
|
||||
typeInformation.AssemblyString;
|
||||
}
|
||||
}
|
||||
|
||||
WriteClrTypeInfo(writer, clrTypeName, clrAssemblyName);
|
||||
}
|
||||
|
||||
private static void WriteClrTypeInfo(XmlWriterDelegator writer, string clrTypeName, string clrAssemblyName)
|
||||
{
|
||||
if (clrTypeName != null)
|
||||
{
|
||||
writer.WriteAttributeString(Globals.SerPrefix, DictionaryGlobals.ClrTypeLocalName, DictionaryGlobals.SerializationNamespace, DataContract.GetClrTypeString(clrTypeName));
|
||||
}
|
||||
|
||||
if (clrAssemblyName != null)
|
||||
{
|
||||
writer.WriteAttributeString(Globals.SerPrefix, DictionaryGlobals.ClrAssemblyLocalName, DictionaryGlobals.SerializationNamespace, DataContract.GetClrTypeString(clrAssemblyName));
|
||||
}
|
||||
}
|
||||
|
||||
public override void WriteEndObject(XmlDictionaryWriter writer)
|
||||
{
|
||||
WriteEndObjectHandleExceptions(new XmlWriterDelegator(writer));
|
||||
}
|
||||
|
||||
internal override void InternalWriteEndObject(XmlWriterDelegator writer)
|
||||
{
|
||||
writer.WriteEndElement();
|
||||
}
|
||||
|
||||
public override object ReadObject(XmlReader reader)
|
||||
{
|
||||
return ReadObjectHandleExceptions(new XmlReaderDelegator(reader), true /*verifyObjectName*/);
|
||||
}
|
||||
|
||||
public override object ReadObject(XmlReader reader, bool verifyObjectName)
|
||||
{
|
||||
return ReadObjectHandleExceptions(new XmlReaderDelegator(reader), verifyObjectName);
|
||||
}
|
||||
|
||||
public override bool IsStartObject(XmlReader reader)
|
||||
{
|
||||
return IsStartObjectHandleExceptions(new XmlReaderDelegator(reader));
|
||||
}
|
||||
|
||||
public override object ReadObject(XmlDictionaryReader reader, bool verifyObjectName)
|
||||
{
|
||||
return ReadObjectHandleExceptions(new XmlReaderDelegator(reader), verifyObjectName);
|
||||
}
|
||||
|
||||
public override bool IsStartObject(XmlDictionaryReader reader)
|
||||
{
|
||||
return IsStartObjectHandleExceptions(new XmlReaderDelegator(reader));
|
||||
}
|
||||
|
||||
internal override object InternalReadObject(XmlReaderDelegator xmlReader, bool verifyObjectName)
|
||||
{
|
||||
if (MaxItemsInObjectGraph == 0)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(SR.Format(SR.ExceededMaxItemsQuota, MaxItemsInObjectGraph)));
|
||||
}
|
||||
|
||||
// verifyObjectName has no effect in SharedType mode
|
||||
if (!IsStartElement(xmlReader))
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationExceptionWithReaderDetails(SR.Format(SR.ExpectingElementAtDeserialize, XmlNodeType.Element), xmlReader));
|
||||
}
|
||||
|
||||
XmlObjectSerializerReadContext context = XmlObjectSerializerReadContext.CreateContext(this);
|
||||
return context.InternalDeserialize(xmlReader, null, null, null);
|
||||
}
|
||||
|
||||
internal override bool InternalIsStartObject(XmlReaderDelegator reader)
|
||||
{
|
||||
return IsStartElement(reader);
|
||||
}
|
||||
|
||||
internal DataContract GetDataContract(object obj, ref Hashtable surrogateDataContracts)
|
||||
{
|
||||
return GetDataContract(((obj == null) ? Globals.TypeOfObject : obj.GetType()), ref surrogateDataContracts);
|
||||
}
|
||||
|
||||
internal DataContract GetDataContract(Type type, ref Hashtable surrogateDataContracts)
|
||||
{
|
||||
return GetDataContract(type.TypeHandle, type, ref surrogateDataContracts);
|
||||
}
|
||||
|
||||
internal DataContract GetDataContract(RuntimeTypeHandle typeHandle, Type type, ref Hashtable surrogateDataContracts)
|
||||
{
|
||||
DataContract dataContract = GetDataContractFromSurrogateSelector(surrogateSelector, Context, typeHandle, type, ref surrogateDataContracts);
|
||||
if (dataContract != null)
|
||||
{
|
||||
return dataContract;
|
||||
}
|
||||
|
||||
if (cachedDataContract == null)
|
||||
{
|
||||
dataContract = DataContract.GetDataContract(typeHandle, type, SerializationMode.SharedType);
|
||||
cachedDataContract = dataContract;
|
||||
return dataContract;
|
||||
}
|
||||
|
||||
DataContract currentCachedDataContract = cachedDataContract;
|
||||
if (currentCachedDataContract.UnderlyingType.TypeHandle.Equals(typeHandle))
|
||||
{
|
||||
return currentCachedDataContract;
|
||||
}
|
||||
|
||||
return DataContract.GetDataContract(typeHandle, type, SerializationMode.SharedType);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
private static ISerializationSurrogate GetSurrogate(
|
||||
Type type,
|
||||
ISurrogateSelector surrogateSelector,
|
||||
StreamingContext context)
|
||||
{
|
||||
return surrogateSelector.GetSurrogate(type, context, out ISurrogateSelector surrogateSelectorNotUsed);
|
||||
}
|
||||
|
||||
internal static DataContract GetDataContractFromSurrogateSelector(
|
||||
ISurrogateSelector surrogateSelector,
|
||||
StreamingContext context,
|
||||
RuntimeTypeHandle typeHandle,
|
||||
Type type,
|
||||
ref Hashtable surrogateDataContracts)
|
||||
{
|
||||
if (surrogateSelector == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (type == null)
|
||||
{
|
||||
type = Type.GetTypeFromHandle(typeHandle);
|
||||
}
|
||||
|
||||
DataContract builtInDataContract = DataContract.GetBuiltInDataContract(type);
|
||||
if (builtInDataContract != null)
|
||||
{
|
||||
return builtInDataContract;
|
||||
}
|
||||
|
||||
if (surrogateDataContracts != null)
|
||||
{
|
||||
DataContract cachedSurrogateContract = (DataContract)surrogateDataContracts[type];
|
||||
if (cachedSurrogateContract != null)
|
||||
{
|
||||
return cachedSurrogateContract;
|
||||
}
|
||||
}
|
||||
DataContract surrogateContract = null;
|
||||
ISerializationSurrogate surrogate = GetSurrogate(type, surrogateSelector, context);
|
||||
if (surrogate != null)
|
||||
{
|
||||
surrogateContract = new SurrogateDataContract(type, surrogate);
|
||||
}
|
||||
else if (type.IsArray)
|
||||
{
|
||||
Type elementType = type.GetElementType();
|
||||
DataContract itemContract = GetDataContractFromSurrogateSelector(surrogateSelector, context, elementType.TypeHandle, elementType, ref surrogateDataContracts);
|
||||
if (itemContract == null)
|
||||
{
|
||||
itemContract = DataContract.GetDataContract(elementType.TypeHandle, elementType, SerializationMode.SharedType);
|
||||
}
|
||||
|
||||
surrogateContract = new CollectionDataContract(type, itemContract);
|
||||
}
|
||||
if (surrogateContract != null)
|
||||
{
|
||||
if (surrogateDataContracts == null)
|
||||
{
|
||||
surrogateDataContracts = new Hashtable();
|
||||
}
|
||||
|
||||
surrogateDataContracts.Add(type, surrogateContract);
|
||||
return surrogateContract;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
internal static TypeInformation GetTypeInformation(Type type)
|
||||
{
|
||||
TypeInformation typeInformation = null;
|
||||
object typeInformationObject = typeNameCache[type];
|
||||
if (typeInformationObject == null)
|
||||
{
|
||||
string assemblyName = DataContract.GetClrAssemblyName(type, out bool hasTypeForwardedFrom);
|
||||
typeInformation = new TypeInformation(DataContract.GetClrTypeFullNameUsingTypeForwardedFromAttribute(type), assemblyName, hasTypeForwardedFrom);
|
||||
lock (typeNameCache)
|
||||
{
|
||||
typeNameCache[type] = typeInformation;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
typeInformation = (TypeInformation)typeInformationObject;
|
||||
}
|
||||
return typeInformation;
|
||||
}
|
||||
|
||||
private static bool IsAssemblyNameForwardingSafe(string originalAssemblyName, string newAssemblyName)
|
||||
{
|
||||
if (originalAssemblyName == newAssemblyName)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
AssemblyName originalAssembly = new AssemblyName(originalAssemblyName);
|
||||
AssemblyName newAssembly = new AssemblyName(newAssemblyName);
|
||||
|
||||
// mscorlib will get loaded by the runtime regardless of its string casing or its public key token,
|
||||
// so setting the assembly name to mscorlib is always unsafe
|
||||
if (string.Equals(newAssembly.Name, Globals.MscorlibAssemblySimpleName, StringComparison.OrdinalIgnoreCase) ||
|
||||
string.Equals(newAssembly.Name, Globals.MscorlibFileName, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return IsPublicKeyTokenForwardingSafe(originalAssembly.GetPublicKeyToken(), newAssembly.GetPublicKeyToken());
|
||||
}
|
||||
|
||||
private static bool IsPublicKeyTokenForwardingSafe(byte[] sourceToken, byte[] destinationToken)
|
||||
{
|
||||
if (sourceToken == null || destinationToken == null || sourceToken.Length == 0 || destinationToken.Length == 0 || sourceToken.Length != destinationToken.Length)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int i = 0; i < sourceToken.Length; i++)
|
||||
{
|
||||
if (sourceToken[i] != destinationToken[i])
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,114 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Compat.Runtime.Serialization
|
||||
{
|
||||
internal struct ObjectReferenceStack
|
||||
{
|
||||
private const int MaximumArraySize = 16;
|
||||
private const int InitialArraySize = 4;
|
||||
private int count;
|
||||
private object[] objectArray;
|
||||
private bool[] isReferenceArray;
|
||||
private Dictionary<object, object> objectDictionary;
|
||||
|
||||
internal void Push(object obj)
|
||||
{
|
||||
if (objectArray == null)
|
||||
{
|
||||
objectArray = new object[InitialArraySize];
|
||||
objectArray[count++] = obj;
|
||||
}
|
||||
else if (count < MaximumArraySize)
|
||||
{
|
||||
if (count == objectArray.Length)
|
||||
{
|
||||
Array.Resize<object>(ref objectArray, objectArray.Length * 2);
|
||||
}
|
||||
|
||||
objectArray[count++] = obj;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (objectDictionary == null)
|
||||
{
|
||||
objectDictionary = new Dictionary<object, object>();
|
||||
}
|
||||
|
||||
objectDictionary.Add(obj, null);
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
internal void EnsureSetAsIsReference(object obj)
|
||||
{
|
||||
if (count == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (count > MaximumArraySize)
|
||||
{
|
||||
if (objectDictionary == null)
|
||||
{
|
||||
Fx.Assert("Object reference stack in invalid state");
|
||||
}
|
||||
objectDictionary.Remove(obj);
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((objectArray != null) && objectArray[count - 1] == obj)
|
||||
{
|
||||
if (isReferenceArray == null)
|
||||
{
|
||||
isReferenceArray = new bool[objectArray.Length];
|
||||
}
|
||||
else if (count >= isReferenceArray.Length)
|
||||
{
|
||||
|
||||
Array.Resize<bool>(ref isReferenceArray, objectArray.Length);
|
||||
}
|
||||
isReferenceArray[count - 1] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal void Pop(object obj)
|
||||
{
|
||||
if (count > MaximumArraySize)
|
||||
{
|
||||
if (objectDictionary == null)
|
||||
{
|
||||
Fx.Assert("Object reference stack in invalid state");
|
||||
}
|
||||
objectDictionary.Remove(obj);
|
||||
}
|
||||
count--;
|
||||
}
|
||||
|
||||
internal bool Contains(object obj)
|
||||
{
|
||||
int currentCount = count;
|
||||
if (currentCount > MaximumArraySize)
|
||||
{
|
||||
if (objectDictionary != null && objectDictionary.ContainsKey(obj))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
currentCount = MaximumArraySize;
|
||||
}
|
||||
for (int i = (currentCount - 1); i >= 0; i--)
|
||||
{
|
||||
if (Object.ReferenceEquals(obj, objectArray[i]) && isReferenceArray != null && !isReferenceArray[i])
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
internal int Count => count;
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,219 @@
|
||||
using System;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace Compat.Runtime.Serialization
|
||||
{
|
||||
internal class ObjectToIdCache
|
||||
{
|
||||
internal int m_currentCount;
|
||||
internal int[] m_ids;
|
||||
internal object[] m_objs;
|
||||
private bool[] m_isWrapped;
|
||||
|
||||
public ObjectToIdCache()
|
||||
{
|
||||
m_currentCount = 1;
|
||||
m_ids = new int[GetPrime(1)];
|
||||
m_objs = new object[m_ids.Length];
|
||||
m_isWrapped = new bool[m_ids.Length];
|
||||
}
|
||||
|
||||
public int GetId(object obj, ref bool newId)
|
||||
{
|
||||
int position = FindElement(obj, out bool isEmpty, out bool isWrapped);
|
||||
if (!isEmpty)
|
||||
{
|
||||
newId = false;
|
||||
return m_ids[position];
|
||||
}
|
||||
if (!newId)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int id = m_currentCount++;
|
||||
m_objs[position] = obj;
|
||||
m_ids[position] = id;
|
||||
m_isWrapped[position] = isWrapped;
|
||||
if (m_currentCount >= (m_objs.Length - 1))
|
||||
{
|
||||
Rehash();
|
||||
}
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
// (oldObjId, oldObj-id, newObj-newObjId) => (oldObj-oldObjId, newObj-id, newObjId )
|
||||
public int ReassignId(int oldObjId, object oldObj, object newObj)
|
||||
{
|
||||
int position = FindElement(oldObj, out bool isEmpty, out bool isWrapped);
|
||||
if (isEmpty)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int id = m_ids[position];
|
||||
if (oldObjId > 0)
|
||||
{
|
||||
m_ids[position] = oldObjId;
|
||||
}
|
||||
else
|
||||
{
|
||||
RemoveAt(position);
|
||||
}
|
||||
|
||||
position = FindElement(newObj, out isEmpty, out isWrapped);
|
||||
int newObjId = 0;
|
||||
if (!isEmpty)
|
||||
{
|
||||
newObjId = m_ids[position];
|
||||
}
|
||||
|
||||
m_objs[position] = newObj;
|
||||
m_ids[position] = id;
|
||||
m_isWrapped[position] = isWrapped;
|
||||
return newObjId;
|
||||
}
|
||||
|
||||
private int FindElement(object obj, out bool isEmpty, out bool isWrapped)
|
||||
{
|
||||
isWrapped = false;
|
||||
int position = ComputeStartPosition(obj);
|
||||
for (int i = position; i != (position - 1); i++)
|
||||
{
|
||||
if (m_objs[i] == null)
|
||||
{
|
||||
isEmpty = true;
|
||||
return i;
|
||||
}
|
||||
if (m_objs[i] == obj)
|
||||
{
|
||||
isEmpty = false;
|
||||
return i;
|
||||
}
|
||||
if (i == (m_objs.Length - 1))
|
||||
{
|
||||
isWrapped = true;
|
||||
i = -1;
|
||||
}
|
||||
}
|
||||
// m_obj must ALWAYS have atleast one slot empty (null).
|
||||
Fx.Assert("Object table overflow");
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(SR.ObjectTableOverflow));
|
||||
}
|
||||
|
||||
private void RemoveAt(int position)
|
||||
{
|
||||
int cacheSize = m_objs.Length;
|
||||
int lastVacantPosition = position;
|
||||
for (int next = (position == cacheSize - 1) ? 0 : position + 1; next != position; next++)
|
||||
{
|
||||
if (m_objs[next] == null)
|
||||
{
|
||||
m_objs[lastVacantPosition] = null;
|
||||
m_ids[lastVacantPosition] = 0;
|
||||
m_isWrapped[lastVacantPosition] = false;
|
||||
return;
|
||||
}
|
||||
int nextStartPosition = ComputeStartPosition(m_objs[next]);
|
||||
// If we wrapped while placing an object, then it must be that the start position wasn't wrapped to begin with
|
||||
bool isNextStartPositionWrapped = next < position && !m_isWrapped[next];
|
||||
bool isLastVacantPositionWrapped = lastVacantPosition < position;
|
||||
|
||||
// We want to avoid moving objects in the cache if the next bucket position is wrapped, but the last vacant position isn't
|
||||
// and we want to make sure to move objects in the cache when the last vacant position is wrapped but the next bucket position isn't
|
||||
if ((nextStartPosition <= lastVacantPosition && !(isNextStartPositionWrapped && !isLastVacantPositionWrapped)) ||
|
||||
(isLastVacantPositionWrapped && !isNextStartPositionWrapped))
|
||||
{
|
||||
m_objs[lastVacantPosition] = m_objs[next];
|
||||
m_ids[lastVacantPosition] = m_ids[next];
|
||||
// A wrapped object might become unwrapped if it moves from the front of the array to the end of the array
|
||||
m_isWrapped[lastVacantPosition] = m_isWrapped[next] && next > lastVacantPosition;
|
||||
lastVacantPosition = next;
|
||||
}
|
||||
if (next == (cacheSize - 1))
|
||||
{
|
||||
next = -1;
|
||||
}
|
||||
}
|
||||
// m_obj must ALWAYS have atleast one slot empty (null).
|
||||
Fx.Assert("Object table overflow");
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(SR.ObjectTableOverflow));
|
||||
}
|
||||
|
||||
private int ComputeStartPosition(object o)
|
||||
{
|
||||
return (RuntimeHelpers.GetHashCode(o) & 0x7FFFFFFF) % m_objs.Length;
|
||||
}
|
||||
|
||||
private void Rehash()
|
||||
{
|
||||
int size = GetPrime(m_objs.Length * 2);
|
||||
int[] oldIds = m_ids;
|
||||
object[] oldObjs = m_objs;
|
||||
m_ids = new int[size];
|
||||
m_objs = new object[size];
|
||||
m_isWrapped = new bool[size];
|
||||
|
||||
for (int j = 0; j < oldObjs.Length; j++)
|
||||
{
|
||||
object obj = oldObjs[j];
|
||||
if (obj != null)
|
||||
{
|
||||
int position = FindElement(obj, out bool found, out bool isWrapped);
|
||||
m_objs[position] = obj;
|
||||
m_ids[position] = oldIds[j];
|
||||
m_isWrapped[position] = isWrapped;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static int GetPrime(int min)
|
||||
{
|
||||
|
||||
for (int i = 0; i < primes.Length; i++)
|
||||
{
|
||||
int prime = primes[i];
|
||||
if (prime >= min)
|
||||
{
|
||||
return prime;
|
||||
}
|
||||
}
|
||||
|
||||
//outside of our predefined table.
|
||||
//compute the hard way.
|
||||
for (int i = (min | 1); i < int.MaxValue; i += 2)
|
||||
{
|
||||
if (IsPrime(i))
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return min;
|
||||
}
|
||||
|
||||
private static bool IsPrime(int candidate)
|
||||
{
|
||||
if ((candidate & 1) != 0)
|
||||
{
|
||||
int limit = (int)Math.Sqrt(candidate);
|
||||
for (int divisor = 3; divisor <= limit; divisor += 2)
|
||||
{
|
||||
if ((candidate % divisor) == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return (candidate == 2);
|
||||
}
|
||||
|
||||
internal static readonly int[] primes =
|
||||
{
|
||||
3, 7, 17, 37, 89, 197, 431, 919, 1931, 4049, 8419, 17519, 36353,
|
||||
75431, 156437, 324449, 672827, 1395263, 2893249, 5999471,
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,837 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using System.Xml;
|
||||
|
||||
namespace Compat.Runtime.Serialization
|
||||
{
|
||||
internal abstract class PrimitiveDataContract : DataContract
|
||||
{
|
||||
private readonly PrimitiveDataContractCriticalHelper _helper;
|
||||
|
||||
protected PrimitiveDataContract(Type type, XmlDictionaryString name, XmlDictionaryString ns)
|
||||
: base(new PrimitiveDataContractCriticalHelper(type, name, ns))
|
||||
{
|
||||
_helper = base.Helper as PrimitiveDataContractCriticalHelper;
|
||||
}
|
||||
|
||||
internal static PrimitiveDataContract GetPrimitiveDataContract(Type type)
|
||||
{
|
||||
return DataContract.GetBuiltInDataContract(type) as PrimitiveDataContract;
|
||||
}
|
||||
|
||||
internal static PrimitiveDataContract GetPrimitiveDataContract(string name, string ns)
|
||||
{
|
||||
return DataContract.GetBuiltInDataContract(name, ns) as PrimitiveDataContract;
|
||||
}
|
||||
|
||||
internal abstract string WriteMethodName { get; }
|
||||
|
||||
internal abstract string ReadMethodName { get; }
|
||||
|
||||
internal override XmlDictionaryString TopLevelElementNamespace
|
||||
{
|
||||
get => DictionaryGlobals.SerializationNamespace;
|
||||
set { }
|
||||
}
|
||||
|
||||
internal override bool CanContainReferences => false;
|
||||
|
||||
internal override bool IsPrimitive => true;
|
||||
|
||||
internal override bool IsBuiltInDataContract => true;
|
||||
|
||||
internal MethodInfo XmlFormatWriterMethod
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_helper.XmlFormatWriterMethod == null)
|
||||
{
|
||||
if (UnderlyingType.IsValueType)
|
||||
{
|
||||
_helper.XmlFormatWriterMethod = typeof(XmlWriterDelegator).GetMethod(WriteMethodName, Globals.ScanAllMembers, null, new Type[] { UnderlyingType, typeof(XmlDictionaryString), typeof(XmlDictionaryString) }, null);
|
||||
}
|
||||
else
|
||||
{
|
||||
_helper.XmlFormatWriterMethod = typeof(XmlObjectSerializerWriteContext).GetMethod(WriteMethodName, Globals.ScanAllMembers, null, new Type[] { typeof(XmlWriterDelegator), UnderlyingType, typeof(XmlDictionaryString), typeof(XmlDictionaryString) }, null);
|
||||
}
|
||||
}
|
||||
return _helper.XmlFormatWriterMethod;
|
||||
}
|
||||
}
|
||||
|
||||
internal MethodInfo XmlFormatContentWriterMethod
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_helper.XmlFormatContentWriterMethod == null)
|
||||
{
|
||||
if (UnderlyingType.IsValueType)
|
||||
{
|
||||
_helper.XmlFormatContentWriterMethod = typeof(XmlWriterDelegator).GetMethod(WriteMethodName, Globals.ScanAllMembers, null, new Type[] { UnderlyingType }, null);
|
||||
}
|
||||
else
|
||||
{
|
||||
_helper.XmlFormatContentWriterMethod = typeof(XmlObjectSerializerWriteContext).GetMethod(WriteMethodName, Globals.ScanAllMembers, null, new Type[] { typeof(XmlWriterDelegator), UnderlyingType }, null);
|
||||
}
|
||||
}
|
||||
return _helper.XmlFormatContentWriterMethod;
|
||||
}
|
||||
}
|
||||
|
||||
internal MethodInfo XmlFormatReaderMethod
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_helper.XmlFormatReaderMethod == null)
|
||||
{
|
||||
_helper.XmlFormatReaderMethod = typeof(XmlReaderDelegator).GetMethod(ReadMethodName, Globals.ScanAllMembers);
|
||||
}
|
||||
return _helper.XmlFormatReaderMethod;
|
||||
}
|
||||
}
|
||||
|
||||
public override void WriteXmlValue(XmlWriterDelegator xmlWriter, object obj, XmlObjectSerializerWriteContext context)
|
||||
{
|
||||
xmlWriter.WriteAnyType(obj);
|
||||
}
|
||||
|
||||
protected object HandleReadValue(object obj, XmlObjectSerializerReadContext context)
|
||||
{
|
||||
context.AddNewObject(obj);
|
||||
return obj;
|
||||
}
|
||||
|
||||
protected bool TryReadNullAtTopLevel(XmlReaderDelegator reader)
|
||||
{
|
||||
Attributes attributes = new Attributes();
|
||||
attributes.Read(reader);
|
||||
if (attributes.Ref != Globals.NewObjectId)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
|
||||
XmlObjectSerializer.CreateSerializationException(
|
||||
SR.Format(SR.CannotDeserializeRefAtTopLevel, attributes.Ref)));
|
||||
}
|
||||
|
||||
if (attributes.XsiNil)
|
||||
{
|
||||
reader.Skip();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
internal override bool Equals(object other, Dictionary<DataContractPairKey, object> checkedContracts)
|
||||
{
|
||||
PrimitiveDataContract dataContract = other as PrimitiveDataContract;
|
||||
if (dataContract != null)
|
||||
{
|
||||
Type thisType = GetType();
|
||||
Type otherType = other.GetType();
|
||||
return (thisType.Equals(otherType) || thisType.IsSubclassOf(otherType) || otherType.IsSubclassOf(thisType));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private class PrimitiveDataContractCriticalHelper : DataContract.DataContractCriticalHelper
|
||||
{
|
||||
private MethodInfo xmlFormatWriterMethod;
|
||||
private MethodInfo xmlFormatContentWriterMethod;
|
||||
private MethodInfo xmlFormatReaderMethod;
|
||||
|
||||
internal PrimitiveDataContractCriticalHelper(Type type, XmlDictionaryString name, XmlDictionaryString ns)
|
||||
: base(type)
|
||||
{
|
||||
SetDataContractName(name, ns);
|
||||
}
|
||||
|
||||
internal MethodInfo XmlFormatWriterMethod
|
||||
{
|
||||
get => xmlFormatWriterMethod;
|
||||
set => xmlFormatWriterMethod = value;
|
||||
}
|
||||
|
||||
internal MethodInfo XmlFormatContentWriterMethod
|
||||
{
|
||||
get => xmlFormatContentWriterMethod;
|
||||
set => xmlFormatContentWriterMethod = value;
|
||||
}
|
||||
|
||||
internal MethodInfo XmlFormatReaderMethod
|
||||
{
|
||||
get => xmlFormatReaderMethod;
|
||||
set => xmlFormatReaderMethod = value;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
internal class CharDataContract : PrimitiveDataContract
|
||||
{
|
||||
internal CharDataContract()
|
||||
: this(DictionaryGlobals.CharLocalName, DictionaryGlobals.SerializationNamespace)
|
||||
{
|
||||
}
|
||||
|
||||
internal CharDataContract(XmlDictionaryString name, XmlDictionaryString ns)
|
||||
: base(typeof(char), name, ns)
|
||||
{
|
||||
}
|
||||
|
||||
internal override string WriteMethodName => "WriteChar";
|
||||
internal override string ReadMethodName => "ReadElementContentAsChar";
|
||||
|
||||
public override void WriteXmlValue(XmlWriterDelegator writer, object obj, XmlObjectSerializerWriteContext context)
|
||||
{
|
||||
writer.WriteChar((char)obj);
|
||||
}
|
||||
|
||||
public override object ReadXmlValue(XmlReaderDelegator reader, XmlObjectSerializerReadContext context)
|
||||
{
|
||||
return (context == null) ? reader.ReadElementContentAsChar()
|
||||
: HandleReadValue(reader.ReadElementContentAsChar(), context);
|
||||
}
|
||||
}
|
||||
|
||||
internal class AsmxCharDataContract : CharDataContract
|
||||
{
|
||||
internal AsmxCharDataContract() : base(DictionaryGlobals.CharLocalName, DictionaryGlobals.AsmxTypesNamespace) { }
|
||||
}
|
||||
|
||||
internal class BooleanDataContract : PrimitiveDataContract
|
||||
{
|
||||
internal BooleanDataContract()
|
||||
: base(typeof(bool), DictionaryGlobals.BooleanLocalName, DictionaryGlobals.SchemaNamespace)
|
||||
{
|
||||
}
|
||||
|
||||
internal override string WriteMethodName => "WriteBoolean";
|
||||
internal override string ReadMethodName => "ReadElementContentAsBoolean";
|
||||
|
||||
public override void WriteXmlValue(XmlWriterDelegator writer, object obj, XmlObjectSerializerWriteContext context)
|
||||
{
|
||||
writer.WriteBoolean((bool)obj);
|
||||
}
|
||||
|
||||
public override object ReadXmlValue(XmlReaderDelegator reader, XmlObjectSerializerReadContext context)
|
||||
{
|
||||
return (context == null) ? reader.ReadElementContentAsBoolean()
|
||||
: HandleReadValue(reader.ReadElementContentAsBoolean(), context);
|
||||
}
|
||||
}
|
||||
|
||||
internal class SignedByteDataContract : PrimitiveDataContract
|
||||
{
|
||||
internal SignedByteDataContract()
|
||||
: base(typeof(sbyte), DictionaryGlobals.SignedByteLocalName, DictionaryGlobals.SchemaNamespace)
|
||||
{
|
||||
}
|
||||
|
||||
internal override string WriteMethodName => "WriteSignedByte";
|
||||
internal override string ReadMethodName => "ReadElementContentAsSignedByte";
|
||||
|
||||
public override void WriteXmlValue(XmlWriterDelegator writer, object obj, XmlObjectSerializerWriteContext context)
|
||||
{
|
||||
writer.WriteSignedByte((sbyte)obj);
|
||||
}
|
||||
|
||||
public override object ReadXmlValue(XmlReaderDelegator reader, XmlObjectSerializerReadContext context)
|
||||
{
|
||||
return (context == null) ? reader.ReadElementContentAsSignedByte()
|
||||
: HandleReadValue(reader.ReadElementContentAsSignedByte(), context);
|
||||
}
|
||||
}
|
||||
|
||||
internal class UnsignedByteDataContract : PrimitiveDataContract
|
||||
{
|
||||
internal UnsignedByteDataContract()
|
||||
: base(typeof(byte), DictionaryGlobals.UnsignedByteLocalName, DictionaryGlobals.SchemaNamespace)
|
||||
{
|
||||
}
|
||||
|
||||
internal override string WriteMethodName => "WriteUnsignedByte";
|
||||
internal override string ReadMethodName => "ReadElementContentAsUnsignedByte";
|
||||
|
||||
public override void WriteXmlValue(XmlWriterDelegator writer, object obj, XmlObjectSerializerWriteContext context)
|
||||
{
|
||||
writer.WriteUnsignedByte((byte)obj);
|
||||
}
|
||||
|
||||
public override object ReadXmlValue(XmlReaderDelegator reader, XmlObjectSerializerReadContext context)
|
||||
{
|
||||
return (context == null) ? reader.ReadElementContentAsUnsignedByte()
|
||||
: HandleReadValue(reader.ReadElementContentAsUnsignedByte(), context);
|
||||
}
|
||||
}
|
||||
|
||||
internal class ShortDataContract : PrimitiveDataContract
|
||||
{
|
||||
internal ShortDataContract()
|
||||
: base(typeof(short), DictionaryGlobals.ShortLocalName, DictionaryGlobals.SchemaNamespace)
|
||||
{
|
||||
}
|
||||
|
||||
internal override string WriteMethodName => "WriteShort";
|
||||
internal override string ReadMethodName => "ReadElementContentAsShort";
|
||||
|
||||
public override void WriteXmlValue(XmlWriterDelegator writer, object obj, XmlObjectSerializerWriteContext context)
|
||||
{
|
||||
writer.WriteShort((short)obj);
|
||||
}
|
||||
|
||||
public override object ReadXmlValue(XmlReaderDelegator reader, XmlObjectSerializerReadContext context)
|
||||
{
|
||||
return (context == null) ? reader.ReadElementContentAsShort()
|
||||
: HandleReadValue(reader.ReadElementContentAsShort(), context);
|
||||
}
|
||||
}
|
||||
|
||||
internal class UnsignedShortDataContract : PrimitiveDataContract
|
||||
{
|
||||
internal UnsignedShortDataContract()
|
||||
: base(typeof(ushort), DictionaryGlobals.UnsignedShortLocalName, DictionaryGlobals.SchemaNamespace)
|
||||
{
|
||||
}
|
||||
|
||||
internal override string WriteMethodName => "WriteUnsignedShort";
|
||||
internal override string ReadMethodName => "ReadElementContentAsUnsignedShort";
|
||||
|
||||
public override void WriteXmlValue(XmlWriterDelegator writer, object obj, XmlObjectSerializerWriteContext context)
|
||||
{
|
||||
writer.WriteUnsignedShort((ushort)obj);
|
||||
}
|
||||
|
||||
public override object ReadXmlValue(XmlReaderDelegator reader, XmlObjectSerializerReadContext context)
|
||||
{
|
||||
return (context == null) ? reader.ReadElementContentAsUnsignedShort()
|
||||
: HandleReadValue(reader.ReadElementContentAsUnsignedShort(), context);
|
||||
}
|
||||
}
|
||||
|
||||
internal class IntDataContract : PrimitiveDataContract
|
||||
{
|
||||
internal IntDataContract()
|
||||
: base(typeof(int), DictionaryGlobals.IntLocalName, DictionaryGlobals.SchemaNamespace)
|
||||
{
|
||||
}
|
||||
|
||||
internal override string WriteMethodName => "WriteInt";
|
||||
internal override string ReadMethodName => "ReadElementContentAsInt";
|
||||
|
||||
public override void WriteXmlValue(XmlWriterDelegator writer, object obj, XmlObjectSerializerWriteContext context)
|
||||
{
|
||||
writer.WriteInt((int)obj);
|
||||
}
|
||||
|
||||
public override object ReadXmlValue(XmlReaderDelegator reader, XmlObjectSerializerReadContext context)
|
||||
{
|
||||
return (context == null) ? reader.ReadElementContentAsInt()
|
||||
: HandleReadValue(reader.ReadElementContentAsInt(), context);
|
||||
}
|
||||
}
|
||||
|
||||
internal class UnsignedIntDataContract : PrimitiveDataContract
|
||||
{
|
||||
internal UnsignedIntDataContract()
|
||||
: base(typeof(uint), DictionaryGlobals.UnsignedIntLocalName, DictionaryGlobals.SchemaNamespace)
|
||||
{
|
||||
}
|
||||
|
||||
internal override string WriteMethodName => "WriteUnsignedInt";
|
||||
internal override string ReadMethodName => "ReadElementContentAsUnsignedInt";
|
||||
|
||||
public override void WriteXmlValue(XmlWriterDelegator writer, object obj, XmlObjectSerializerWriteContext context)
|
||||
{
|
||||
writer.WriteUnsignedInt((uint)obj);
|
||||
}
|
||||
|
||||
public override object ReadXmlValue(XmlReaderDelegator reader, XmlObjectSerializerReadContext context)
|
||||
{
|
||||
return (context == null) ? reader.ReadElementContentAsUnsignedInt()
|
||||
: HandleReadValue(reader.ReadElementContentAsUnsignedInt(), context);
|
||||
}
|
||||
}
|
||||
|
||||
internal class LongDataContract : PrimitiveDataContract
|
||||
{
|
||||
internal LongDataContract()
|
||||
: this(DictionaryGlobals.LongLocalName, DictionaryGlobals.SchemaNamespace)
|
||||
{
|
||||
}
|
||||
|
||||
internal LongDataContract(XmlDictionaryString name, XmlDictionaryString ns)
|
||||
: base(typeof(long), name, ns)
|
||||
{
|
||||
}
|
||||
|
||||
internal override string WriteMethodName => "WriteLong";
|
||||
internal override string ReadMethodName => "ReadElementContentAsLong";
|
||||
|
||||
public override void WriteXmlValue(XmlWriterDelegator writer, object obj, XmlObjectSerializerWriteContext context)
|
||||
{
|
||||
writer.WriteLong((long)obj);
|
||||
}
|
||||
|
||||
public override object ReadXmlValue(XmlReaderDelegator reader, XmlObjectSerializerReadContext context)
|
||||
{
|
||||
return (context == null) ? reader.ReadElementContentAsLong()
|
||||
: HandleReadValue(reader.ReadElementContentAsLong(), context);
|
||||
}
|
||||
}
|
||||
internal class IntegerDataContract : LongDataContract
|
||||
{
|
||||
internal IntegerDataContract() : base(DictionaryGlobals.integerLocalName, DictionaryGlobals.SchemaNamespace) { }
|
||||
}
|
||||
internal class PositiveIntegerDataContract : LongDataContract
|
||||
{
|
||||
internal PositiveIntegerDataContract() : base(DictionaryGlobals.positiveIntegerLocalName, DictionaryGlobals.SchemaNamespace) { }
|
||||
}
|
||||
internal class NegativeIntegerDataContract : LongDataContract
|
||||
{
|
||||
internal NegativeIntegerDataContract() : base(DictionaryGlobals.negativeIntegerLocalName, DictionaryGlobals.SchemaNamespace) { }
|
||||
}
|
||||
internal class NonPositiveIntegerDataContract : LongDataContract
|
||||
{
|
||||
internal NonPositiveIntegerDataContract() : base(DictionaryGlobals.nonPositiveIntegerLocalName, DictionaryGlobals.SchemaNamespace) { }
|
||||
}
|
||||
internal class NonNegativeIntegerDataContract : LongDataContract
|
||||
{
|
||||
internal NonNegativeIntegerDataContract() : base(DictionaryGlobals.nonNegativeIntegerLocalName, DictionaryGlobals.SchemaNamespace) { }
|
||||
}
|
||||
|
||||
internal class UnsignedLongDataContract : PrimitiveDataContract
|
||||
{
|
||||
internal UnsignedLongDataContract()
|
||||
: base(typeof(ulong), DictionaryGlobals.UnsignedLongLocalName, DictionaryGlobals.SchemaNamespace)
|
||||
{
|
||||
}
|
||||
|
||||
internal override string WriteMethodName => "WriteUnsignedLong";
|
||||
internal override string ReadMethodName => "ReadElementContentAsUnsignedLong";
|
||||
|
||||
public override void WriteXmlValue(XmlWriterDelegator writer, object obj, XmlObjectSerializerWriteContext context)
|
||||
{
|
||||
writer.WriteUnsignedLong((ulong)obj);
|
||||
}
|
||||
|
||||
public override object ReadXmlValue(XmlReaderDelegator reader, XmlObjectSerializerReadContext context)
|
||||
{
|
||||
return (context == null) ? reader.ReadElementContentAsUnsignedLong()
|
||||
: HandleReadValue(reader.ReadElementContentAsUnsignedLong(), context);
|
||||
}
|
||||
}
|
||||
|
||||
internal class FloatDataContract : PrimitiveDataContract
|
||||
{
|
||||
internal FloatDataContract()
|
||||
: base(typeof(float), DictionaryGlobals.FloatLocalName, DictionaryGlobals.SchemaNamespace)
|
||||
{
|
||||
}
|
||||
|
||||
internal override string WriteMethodName => "WriteFloat";
|
||||
internal override string ReadMethodName => "ReadElementContentAsFloat";
|
||||
|
||||
public override void WriteXmlValue(XmlWriterDelegator writer, object obj, XmlObjectSerializerWriteContext context)
|
||||
{
|
||||
writer.WriteFloat((float)obj);
|
||||
}
|
||||
|
||||
public override object ReadXmlValue(XmlReaderDelegator reader, XmlObjectSerializerReadContext context)
|
||||
{
|
||||
return (context == null) ? reader.ReadElementContentAsFloat()
|
||||
: HandleReadValue(reader.ReadElementContentAsFloat(), context);
|
||||
}
|
||||
}
|
||||
|
||||
internal class DoubleDataContract : PrimitiveDataContract
|
||||
{
|
||||
internal DoubleDataContract()
|
||||
: base(typeof(double), DictionaryGlobals.DoubleLocalName, DictionaryGlobals.SchemaNamespace)
|
||||
{
|
||||
}
|
||||
|
||||
internal override string WriteMethodName => "WriteDouble";
|
||||
internal override string ReadMethodName => "ReadElementContentAsDouble";
|
||||
|
||||
public override void WriteXmlValue(XmlWriterDelegator writer, object obj, XmlObjectSerializerWriteContext context)
|
||||
{
|
||||
writer.WriteDouble((double)obj);
|
||||
}
|
||||
|
||||
public override object ReadXmlValue(XmlReaderDelegator reader, XmlObjectSerializerReadContext context)
|
||||
{
|
||||
return (context == null) ? reader.ReadElementContentAsDouble()
|
||||
: HandleReadValue(reader.ReadElementContentAsDouble(), context);
|
||||
}
|
||||
}
|
||||
|
||||
internal class DecimalDataContract : PrimitiveDataContract
|
||||
{
|
||||
internal DecimalDataContract()
|
||||
: base(typeof(decimal), DictionaryGlobals.DecimalLocalName, DictionaryGlobals.SchemaNamespace)
|
||||
{
|
||||
}
|
||||
|
||||
internal override string WriteMethodName => "WriteDecimal";
|
||||
internal override string ReadMethodName => "ReadElementContentAsDecimal";
|
||||
|
||||
public override void WriteXmlValue(XmlWriterDelegator writer, object obj, XmlObjectSerializerWriteContext context)
|
||||
{
|
||||
writer.WriteDecimal((decimal)obj);
|
||||
}
|
||||
|
||||
public override object ReadXmlValue(XmlReaderDelegator reader, XmlObjectSerializerReadContext context)
|
||||
{
|
||||
return (context == null) ? reader.ReadElementContentAsDecimal()
|
||||
: HandleReadValue(reader.ReadElementContentAsDecimal(), context);
|
||||
}
|
||||
}
|
||||
|
||||
internal class DateTimeDataContract : PrimitiveDataContract
|
||||
{
|
||||
internal DateTimeDataContract()
|
||||
: base(typeof(DateTime), DictionaryGlobals.DateTimeLocalName, DictionaryGlobals.SchemaNamespace)
|
||||
{
|
||||
}
|
||||
|
||||
internal override string WriteMethodName => "WriteDateTime";
|
||||
internal override string ReadMethodName => "ReadElementContentAsDateTime";
|
||||
|
||||
public override void WriteXmlValue(XmlWriterDelegator writer, object obj, XmlObjectSerializerWriteContext context)
|
||||
{
|
||||
writer.WriteDateTime((DateTime)obj);
|
||||
}
|
||||
|
||||
public override object ReadXmlValue(XmlReaderDelegator reader, XmlObjectSerializerReadContext context)
|
||||
{
|
||||
return (context == null) ? reader.ReadElementContentAsDateTime()
|
||||
: HandleReadValue(reader.ReadElementContentAsDateTime(), context);
|
||||
}
|
||||
}
|
||||
|
||||
internal class StringDataContract : PrimitiveDataContract
|
||||
{
|
||||
internal StringDataContract()
|
||||
: this(DictionaryGlobals.StringLocalName, DictionaryGlobals.SchemaNamespace)
|
||||
{
|
||||
}
|
||||
|
||||
internal StringDataContract(XmlDictionaryString name, XmlDictionaryString ns)
|
||||
: base(typeof(string), name, ns)
|
||||
{
|
||||
}
|
||||
|
||||
internal override string WriteMethodName => "WriteString";
|
||||
internal override string ReadMethodName => "ReadElementContentAsString";
|
||||
|
||||
public override void WriteXmlValue(XmlWriterDelegator writer, object obj, XmlObjectSerializerWriteContext context)
|
||||
{
|
||||
writer.WriteString((string)obj);
|
||||
}
|
||||
|
||||
public override object ReadXmlValue(XmlReaderDelegator reader, XmlObjectSerializerReadContext context)
|
||||
{
|
||||
if (context == null)
|
||||
{
|
||||
return TryReadNullAtTopLevel(reader) ? null : reader.ReadElementContentAsString();
|
||||
}
|
||||
else
|
||||
{
|
||||
return HandleReadValue(reader.ReadElementContentAsString(), context);
|
||||
}
|
||||
}
|
||||
}
|
||||
internal class TimeDataContract : StringDataContract
|
||||
{
|
||||
internal TimeDataContract() : base(DictionaryGlobals.timeLocalName, DictionaryGlobals.SchemaNamespace) { }
|
||||
}
|
||||
internal class DateDataContract : StringDataContract
|
||||
{
|
||||
internal DateDataContract() : base(DictionaryGlobals.dateLocalName, DictionaryGlobals.SchemaNamespace) { }
|
||||
}
|
||||
internal class HexBinaryDataContract : StringDataContract
|
||||
{
|
||||
internal HexBinaryDataContract() : base(DictionaryGlobals.hexBinaryLocalName, DictionaryGlobals.SchemaNamespace) { }
|
||||
}
|
||||
internal class GYearMonthDataContract : StringDataContract
|
||||
{
|
||||
internal GYearMonthDataContract() : base(DictionaryGlobals.gYearMonthLocalName, DictionaryGlobals.SchemaNamespace) { }
|
||||
}
|
||||
internal class GYearDataContract : StringDataContract
|
||||
{
|
||||
internal GYearDataContract() : base(DictionaryGlobals.gYearLocalName, DictionaryGlobals.SchemaNamespace) { }
|
||||
}
|
||||
internal class GMonthDayDataContract : StringDataContract
|
||||
{
|
||||
internal GMonthDayDataContract() : base(DictionaryGlobals.gMonthDayLocalName, DictionaryGlobals.SchemaNamespace) { }
|
||||
}
|
||||
internal class GDayDataContract : StringDataContract
|
||||
{
|
||||
internal GDayDataContract() : base(DictionaryGlobals.gDayLocalName, DictionaryGlobals.SchemaNamespace) { }
|
||||
}
|
||||
internal class GMonthDataContract : StringDataContract
|
||||
{
|
||||
internal GMonthDataContract() : base(DictionaryGlobals.gMonthLocalName, DictionaryGlobals.SchemaNamespace) { }
|
||||
}
|
||||
internal class NormalizedStringDataContract : StringDataContract
|
||||
{
|
||||
internal NormalizedStringDataContract() : base(DictionaryGlobals.normalizedStringLocalName, DictionaryGlobals.SchemaNamespace) { }
|
||||
}
|
||||
internal class TokenDataContract : StringDataContract
|
||||
{
|
||||
internal TokenDataContract() : base(DictionaryGlobals.tokenLocalName, DictionaryGlobals.SchemaNamespace) { }
|
||||
}
|
||||
internal class LanguageDataContract : StringDataContract
|
||||
{
|
||||
internal LanguageDataContract() : base(DictionaryGlobals.languageLocalName, DictionaryGlobals.SchemaNamespace) { }
|
||||
}
|
||||
internal class NameDataContract : StringDataContract
|
||||
{
|
||||
internal NameDataContract() : base(DictionaryGlobals.NameLocalName, DictionaryGlobals.SchemaNamespace) { }
|
||||
}
|
||||
internal class NCNameDataContract : StringDataContract
|
||||
{
|
||||
internal NCNameDataContract() : base(DictionaryGlobals.NCNameLocalName, DictionaryGlobals.SchemaNamespace) { }
|
||||
}
|
||||
internal class IDDataContract : StringDataContract
|
||||
{
|
||||
internal IDDataContract() : base(DictionaryGlobals.XSDIDLocalName, DictionaryGlobals.SchemaNamespace) { }
|
||||
}
|
||||
internal class IDREFDataContract : StringDataContract
|
||||
{
|
||||
internal IDREFDataContract() : base(DictionaryGlobals.IDREFLocalName, DictionaryGlobals.SchemaNamespace) { }
|
||||
}
|
||||
internal class IDREFSDataContract : StringDataContract
|
||||
{
|
||||
internal IDREFSDataContract() : base(DictionaryGlobals.IDREFSLocalName, DictionaryGlobals.SchemaNamespace) { }
|
||||
}
|
||||
internal class ENTITYDataContract : StringDataContract
|
||||
{
|
||||
internal ENTITYDataContract() : base(DictionaryGlobals.ENTITYLocalName, DictionaryGlobals.SchemaNamespace) { }
|
||||
}
|
||||
internal class ENTITIESDataContract : StringDataContract
|
||||
{
|
||||
internal ENTITIESDataContract() : base(DictionaryGlobals.ENTITIESLocalName, DictionaryGlobals.SchemaNamespace) { }
|
||||
}
|
||||
internal class NMTOKENDataContract : StringDataContract
|
||||
{
|
||||
internal NMTOKENDataContract() : base(DictionaryGlobals.NMTOKENLocalName, DictionaryGlobals.SchemaNamespace) { }
|
||||
}
|
||||
internal class NMTOKENSDataContract : StringDataContract
|
||||
{
|
||||
internal NMTOKENSDataContract() : base(DictionaryGlobals.NMTOKENSLocalName, DictionaryGlobals.SchemaNamespace) { }
|
||||
}
|
||||
|
||||
internal class ByteArrayDataContract : PrimitiveDataContract
|
||||
{
|
||||
internal ByteArrayDataContract()
|
||||
: base(typeof(byte[]), DictionaryGlobals.ByteArrayLocalName, DictionaryGlobals.SchemaNamespace)
|
||||
{
|
||||
}
|
||||
|
||||
internal override string WriteMethodName => "WriteBase64";
|
||||
internal override string ReadMethodName => "ReadElementContentAsBase64";
|
||||
|
||||
public override void WriteXmlValue(XmlWriterDelegator writer, object obj, XmlObjectSerializerWriteContext context)
|
||||
{
|
||||
writer.WriteBase64((byte[])obj);
|
||||
}
|
||||
|
||||
public override object ReadXmlValue(XmlReaderDelegator reader, XmlObjectSerializerReadContext context)
|
||||
{
|
||||
if (context == null)
|
||||
{
|
||||
return TryReadNullAtTopLevel(reader) ? null : reader.ReadElementContentAsBase64();
|
||||
}
|
||||
else
|
||||
{
|
||||
return HandleReadValue(reader.ReadElementContentAsBase64(), context);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal class ObjectDataContract : PrimitiveDataContract
|
||||
{
|
||||
internal ObjectDataContract()
|
||||
: base(typeof(object), DictionaryGlobals.ObjectLocalName, DictionaryGlobals.SchemaNamespace)
|
||||
{
|
||||
}
|
||||
|
||||
internal override string WriteMethodName => "WriteAnyType";
|
||||
internal override string ReadMethodName => "ReadElementContentAsAnyType";
|
||||
|
||||
public override void WriteXmlValue(XmlWriterDelegator writer, object obj, XmlObjectSerializerWriteContext context)
|
||||
{
|
||||
// write nothing
|
||||
}
|
||||
|
||||
public override object ReadXmlValue(XmlReaderDelegator reader, XmlObjectSerializerReadContext context)
|
||||
{
|
||||
object obj;
|
||||
if (reader.IsEmptyElement)
|
||||
{
|
||||
reader.Skip();
|
||||
obj = new object();
|
||||
}
|
||||
else
|
||||
{
|
||||
string localName = reader.LocalName;
|
||||
string ns = reader.NamespaceURI;
|
||||
reader.Read();
|
||||
try
|
||||
{
|
||||
reader.ReadEndElement();
|
||||
obj = new object();
|
||||
}
|
||||
catch (XmlException xes)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(SR.Format(SR.XmlForObjectCannotHaveContent, localName, ns), xes));
|
||||
}
|
||||
}
|
||||
return (context == null) ? obj : HandleReadValue(obj, context);
|
||||
}
|
||||
|
||||
internal override bool CanContainReferences => true;
|
||||
|
||||
internal override bool IsPrimitive => false;
|
||||
|
||||
}
|
||||
|
||||
internal class TimeSpanDataContract : PrimitiveDataContract
|
||||
{
|
||||
internal TimeSpanDataContract()
|
||||
: this(DictionaryGlobals.TimeSpanLocalName, DictionaryGlobals.SerializationNamespace)
|
||||
{
|
||||
}
|
||||
|
||||
internal TimeSpanDataContract(XmlDictionaryString name, XmlDictionaryString ns)
|
||||
: base(typeof(TimeSpan), name, ns)
|
||||
{
|
||||
}
|
||||
|
||||
internal override string WriteMethodName => "WriteTimeSpan";
|
||||
internal override string ReadMethodName => "ReadElementContentAsTimeSpan";
|
||||
|
||||
public override void WriteXmlValue(XmlWriterDelegator writer, object obj, XmlObjectSerializerWriteContext context)
|
||||
{
|
||||
writer.WriteTimeSpan((TimeSpan)obj);
|
||||
}
|
||||
|
||||
public override object ReadXmlValue(XmlReaderDelegator reader, XmlObjectSerializerReadContext context)
|
||||
{
|
||||
return (context == null) ? reader.ReadElementContentAsTimeSpan()
|
||||
: HandleReadValue(reader.ReadElementContentAsTimeSpan(), context);
|
||||
}
|
||||
}
|
||||
|
||||
internal class XsDurationDataContract : TimeSpanDataContract
|
||||
{
|
||||
internal XsDurationDataContract() : base(DictionaryGlobals.TimeSpanLocalName, DictionaryGlobals.SchemaNamespace) { }
|
||||
}
|
||||
|
||||
internal class GuidDataContract : PrimitiveDataContract
|
||||
{
|
||||
internal GuidDataContract()
|
||||
: this(DictionaryGlobals.GuidLocalName, DictionaryGlobals.SerializationNamespace)
|
||||
{
|
||||
}
|
||||
|
||||
internal GuidDataContract(XmlDictionaryString name, XmlDictionaryString ns)
|
||||
: base(typeof(Guid), name, ns)
|
||||
{
|
||||
}
|
||||
|
||||
internal override string WriteMethodName => "WriteGuid";
|
||||
internal override string ReadMethodName => "ReadElementContentAsGuid";
|
||||
|
||||
public override void WriteXmlValue(XmlWriterDelegator writer, object obj, XmlObjectSerializerWriteContext context)
|
||||
{
|
||||
writer.WriteGuid((Guid)obj);
|
||||
}
|
||||
|
||||
public override object ReadXmlValue(XmlReaderDelegator reader, XmlObjectSerializerReadContext context)
|
||||
{
|
||||
return (context == null) ? reader.ReadElementContentAsGuid()
|
||||
: HandleReadValue(reader.ReadElementContentAsGuid(), context);
|
||||
}
|
||||
}
|
||||
|
||||
internal class AsmxGuidDataContract : GuidDataContract
|
||||
{
|
||||
internal AsmxGuidDataContract() : base(DictionaryGlobals.GuidLocalName, DictionaryGlobals.AsmxTypesNamespace) { }
|
||||
}
|
||||
|
||||
internal class UriDataContract : PrimitiveDataContract
|
||||
{
|
||||
internal UriDataContract()
|
||||
: base(typeof(Uri), DictionaryGlobals.UriLocalName, DictionaryGlobals.SchemaNamespace)
|
||||
{
|
||||
}
|
||||
|
||||
internal override string WriteMethodName => "WriteUri";
|
||||
internal override string ReadMethodName => "ReadElementContentAsUri";
|
||||
|
||||
public override void WriteXmlValue(XmlWriterDelegator writer, object obj, XmlObjectSerializerWriteContext context)
|
||||
{
|
||||
writer.WriteUri((Uri)obj);
|
||||
}
|
||||
|
||||
public override object ReadXmlValue(XmlReaderDelegator reader, XmlObjectSerializerReadContext context)
|
||||
{
|
||||
if (context == null)
|
||||
{
|
||||
return TryReadNullAtTopLevel(reader) ? null : reader.ReadElementContentAsUri();
|
||||
}
|
||||
else
|
||||
{
|
||||
return HandleReadValue(reader.ReadElementContentAsUri(), context);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal class QNameDataContract : PrimitiveDataContract
|
||||
{
|
||||
internal QNameDataContract()
|
||||
: base(typeof(XmlQualifiedName), DictionaryGlobals.QNameLocalName, DictionaryGlobals.SchemaNamespace)
|
||||
{
|
||||
}
|
||||
|
||||
internal override string WriteMethodName => "WriteQName";
|
||||
internal override string ReadMethodName => "ReadElementContentAsQName";
|
||||
|
||||
internal override bool IsPrimitive => false;
|
||||
|
||||
public override void WriteXmlValue(XmlWriterDelegator writer, object obj, XmlObjectSerializerWriteContext context)
|
||||
{
|
||||
writer.WriteQName((XmlQualifiedName)obj);
|
||||
}
|
||||
|
||||
public override object ReadXmlValue(XmlReaderDelegator reader, XmlObjectSerializerReadContext context)
|
||||
{
|
||||
if (context == null)
|
||||
{
|
||||
return TryReadNullAtTopLevel(reader) ? null : reader.ReadElementContentAsQName();
|
||||
}
|
||||
else
|
||||
{
|
||||
return HandleReadValue(reader.ReadElementContentAsQName(), context);
|
||||
}
|
||||
}
|
||||
|
||||
internal override void WriteRootElement(XmlWriterDelegator writer, XmlDictionaryString name, XmlDictionaryString ns)
|
||||
{
|
||||
if (object.ReferenceEquals(ns, DictionaryGlobals.SerializationNamespace))
|
||||
{
|
||||
writer.WriteStartElement(Globals.SerPrefix, name, ns);
|
||||
}
|
||||
else if (ns != null && ns.Value != null && ns.Value.Length > 0)
|
||||
{
|
||||
writer.WriteStartElement(Globals.ElementPrefix, name, ns);
|
||||
}
|
||||
else
|
||||
{
|
||||
writer.WriteStartElement(name, ns);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,246 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Xml;
|
||||
using System.Xml.Schema;
|
||||
|
||||
namespace Compat.Runtime.Serialization
|
||||
{
|
||||
using SchemaObjectDictionary = Dictionary<XmlQualifiedName, SchemaObjectInfo>;
|
||||
|
||||
internal class SchemaObjectInfo
|
||||
{
|
||||
internal XmlSchemaType type;
|
||||
internal XmlSchemaElement element;
|
||||
internal XmlSchema schema;
|
||||
internal List<XmlSchemaType> knownTypes;
|
||||
|
||||
internal SchemaObjectInfo(XmlSchemaType type, XmlSchemaElement element, XmlSchema schema, List<XmlSchemaType> knownTypes)
|
||||
{
|
||||
this.type = type;
|
||||
this.element = element;
|
||||
this.schema = schema;
|
||||
this.knownTypes = knownTypes;
|
||||
}
|
||||
}
|
||||
|
||||
internal static class SchemaHelper
|
||||
{
|
||||
|
||||
internal static bool NamespacesEqual(string ns1, string ns2)
|
||||
{
|
||||
if (ns1 == null || ns1.Length == 0)
|
||||
{
|
||||
return (ns2 == null || ns2.Length == 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
return ns1 == ns2;
|
||||
}
|
||||
}
|
||||
|
||||
internal static XmlSchemaType GetSchemaType(XmlSchemaSet schemas, XmlQualifiedName typeQName, out XmlSchema outSchema)
|
||||
{
|
||||
outSchema = null;
|
||||
ICollection currentSchemas = schemas.Schemas();
|
||||
string ns = typeQName.Namespace;
|
||||
foreach (XmlSchema schema in currentSchemas)
|
||||
{
|
||||
if (NamespacesEqual(ns, schema.TargetNamespace))
|
||||
{
|
||||
outSchema = schema;
|
||||
foreach (XmlSchemaObject schemaObj in schema.Items)
|
||||
{
|
||||
XmlSchemaType schemaType = schemaObj as XmlSchemaType;
|
||||
if (schemaType != null && schemaType.Name == typeQName.Name)
|
||||
{
|
||||
return schemaType;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
internal static XmlSchemaType GetSchemaType(SchemaObjectDictionary schemaInfo, XmlQualifiedName typeName)
|
||||
{
|
||||
if (schemaInfo.TryGetValue(typeName, out SchemaObjectInfo schemaObjectInfo))
|
||||
{
|
||||
return schemaObjectInfo.type;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
internal static XmlSchema GetSchemaWithType(SchemaObjectDictionary schemaInfo, XmlSchemaSet schemas, XmlQualifiedName typeName)
|
||||
{
|
||||
if (schemaInfo.TryGetValue(typeName, out SchemaObjectInfo schemaObjectInfo))
|
||||
{
|
||||
if (schemaObjectInfo.schema != null)
|
||||
{
|
||||
return schemaObjectInfo.schema;
|
||||
}
|
||||
}
|
||||
ICollection currentSchemas = schemas.Schemas();
|
||||
string ns = typeName.Namespace;
|
||||
foreach (XmlSchema schema in currentSchemas)
|
||||
{
|
||||
if (NamespacesEqual(ns, schema.TargetNamespace))
|
||||
{
|
||||
return schema;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
internal static XmlSchemaElement GetSchemaElement(XmlSchemaSet schemas, XmlQualifiedName elementQName, out XmlSchema outSchema)
|
||||
{
|
||||
outSchema = null;
|
||||
ICollection currentSchemas = schemas.Schemas();
|
||||
string ns = elementQName.Namespace;
|
||||
foreach (XmlSchema schema in currentSchemas)
|
||||
{
|
||||
if (NamespacesEqual(ns, schema.TargetNamespace))
|
||||
{
|
||||
outSchema = schema;
|
||||
foreach (XmlSchemaObject schemaObj in schema.Items)
|
||||
{
|
||||
XmlSchemaElement schemaElement = schemaObj as XmlSchemaElement;
|
||||
if (schemaElement != null && schemaElement.Name == elementQName.Name)
|
||||
{
|
||||
return schemaElement;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
internal static XmlSchemaElement GetSchemaElement(SchemaObjectDictionary schemaInfo, XmlQualifiedName elementName)
|
||||
{
|
||||
if (schemaInfo.TryGetValue(elementName, out SchemaObjectInfo schemaObjectInfo))
|
||||
{
|
||||
return schemaObjectInfo.element;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
internal static XmlSchema GetSchema(string ns, XmlSchemaSet schemas)
|
||||
{
|
||||
if (ns == null) { ns = string.Empty; }
|
||||
|
||||
ICollection currentSchemas = schemas.Schemas();
|
||||
foreach (XmlSchema schema in currentSchemas)
|
||||
{
|
||||
if ((schema.TargetNamespace == null && ns.Length == 0) || ns.Equals(schema.TargetNamespace))
|
||||
{
|
||||
return schema;
|
||||
}
|
||||
}
|
||||
return CreateSchema(ns, schemas);
|
||||
}
|
||||
|
||||
private static XmlSchema CreateSchema(string ns, XmlSchemaSet schemas)
|
||||
{
|
||||
XmlSchema schema = new XmlSchema
|
||||
{
|
||||
ElementFormDefault = XmlSchemaForm.Qualified
|
||||
};
|
||||
if (ns.Length > 0)
|
||||
{
|
||||
schema.TargetNamespace = ns;
|
||||
schema.Namespaces.Add(Globals.TnsPrefix, ns);
|
||||
}
|
||||
|
||||
|
||||
schemas.Add(schema);
|
||||
return schema;
|
||||
}
|
||||
|
||||
internal static void AddElementForm(XmlSchemaElement element, XmlSchema schema)
|
||||
{
|
||||
if (schema.ElementFormDefault != XmlSchemaForm.Qualified)
|
||||
{
|
||||
element.Form = XmlSchemaForm.Qualified;
|
||||
}
|
||||
}
|
||||
|
||||
internal static void AddSchemaImport(string ns, XmlSchema schema)
|
||||
{
|
||||
if (SchemaHelper.NamespacesEqual(ns, schema.TargetNamespace) || SchemaHelper.NamespacesEqual(ns, Globals.SchemaNamespace) || SchemaHelper.NamespacesEqual(ns, Globals.SchemaInstanceNamespace))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (object item in schema.Includes)
|
||||
{
|
||||
if (item is XmlSchemaImport)
|
||||
{
|
||||
if (SchemaHelper.NamespacesEqual(ns, ((XmlSchemaImport)item).Namespace))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
XmlSchemaImport import = new XmlSchemaImport();
|
||||
if (ns != null && ns.Length > 0)
|
||||
{
|
||||
import.Namespace = ns;
|
||||
}
|
||||
|
||||
schema.Includes.Add(import);
|
||||
}
|
||||
|
||||
internal static XmlSchema GetSchemaWithGlobalElementDeclaration(XmlSchemaElement element, XmlSchemaSet schemas)
|
||||
{
|
||||
ICollection currentSchemas = schemas.Schemas();
|
||||
foreach (XmlSchema schema in currentSchemas)
|
||||
{
|
||||
foreach (XmlSchemaObject schemaObject in schema.Items)
|
||||
{
|
||||
XmlSchemaElement schemaElement = schemaObject as XmlSchemaElement;
|
||||
if (schemaElement == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (schemaElement == element)
|
||||
{
|
||||
return schema;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
internal static XmlQualifiedName GetGlobalElementDeclaration(XmlSchemaSet schemas, XmlQualifiedName typeQName, out bool isNullable)
|
||||
{
|
||||
ICollection currentSchemas = schemas.Schemas();
|
||||
string ns = typeQName.Namespace;
|
||||
if (ns == null)
|
||||
{
|
||||
ns = string.Empty;
|
||||
}
|
||||
|
||||
isNullable = false;
|
||||
foreach (XmlSchema schema in currentSchemas)
|
||||
{
|
||||
foreach (XmlSchemaObject schemaObject in schema.Items)
|
||||
{
|
||||
XmlSchemaElement schemaElement = schemaObject as XmlSchemaElement;
|
||||
if (schemaElement == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (schemaElement.SchemaTypeName.Equals(typeQName))
|
||||
{
|
||||
isNullable = schemaElement.IsNillable;
|
||||
return new XmlQualifiedName(schemaElement.Name, schema.TargetNamespace);
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,46 @@
|
||||
using System;
|
||||
using System.Xml;
|
||||
|
||||
namespace Compat.Runtime.Serialization
|
||||
{
|
||||
using DataContractDictionary = System.Collections.Generic.Dictionary<XmlQualifiedName, DataContract>;
|
||||
|
||||
internal struct ScopedKnownTypes
|
||||
{
|
||||
internal DataContractDictionary[] dataContractDictionaries;
|
||||
private int count;
|
||||
|
||||
internal void Push(DataContractDictionary dataContractDictionary)
|
||||
{
|
||||
if (dataContractDictionaries == null)
|
||||
{
|
||||
dataContractDictionaries = new DataContractDictionary[4];
|
||||
}
|
||||
else if (count == dataContractDictionaries.Length)
|
||||
{
|
||||
Array.Resize<DataContractDictionary>(ref dataContractDictionaries, dataContractDictionaries.Length * 2);
|
||||
}
|
||||
|
||||
dataContractDictionaries[count++] = dataContractDictionary;
|
||||
}
|
||||
|
||||
internal void Pop()
|
||||
{
|
||||
count--;
|
||||
}
|
||||
|
||||
internal DataContract GetDataContract(XmlQualifiedName qname)
|
||||
{
|
||||
for (int i = (count - 1); i >= 0; i--)
|
||||
{
|
||||
DataContractDictionary dataContractDictionary = dataContractDictionaries[i];
|
||||
if (dataContractDictionary.TryGetValue(qname, out DataContract dataContract))
|
||||
{
|
||||
return dataContract;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
namespace Compat.Runtime.Serialization
|
||||
{
|
||||
internal enum SerializationMode
|
||||
{
|
||||
SharedContract,
|
||||
SharedType,
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace Compat.Runtime.Serialization
|
||||
{
|
||||
internal static class SerializationTrace
|
||||
{
|
||||
private static TraceSource _codeGen;
|
||||
|
||||
internal static SourceSwitch CodeGenerationSwitch => CodeGenerationTraceSource.Switch;
|
||||
|
||||
internal static void WriteInstruction(int lineNumber, string instruction)
|
||||
{
|
||||
CodeGenerationTraceSource.TraceInformation("{0:00000}: {1}", lineNumber, instruction);
|
||||
}
|
||||
|
||||
internal static void TraceInstruction(string instruction)
|
||||
{
|
||||
CodeGenerationTraceSource.TraceEvent(TraceEventType.Verbose, 0, instruction);
|
||||
}
|
||||
|
||||
private static TraceSource CodeGenerationTraceSource
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_codeGen == null)
|
||||
{
|
||||
_codeGen = new TraceSource("E5.Runtime.Serialization.CodeGeneration");
|
||||
}
|
||||
return _codeGen;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
using System;
|
||||
using System.Xml;
|
||||
|
||||
namespace Compat.Runtime.Serialization
|
||||
{
|
||||
internal sealed class SpecialTypeDataContract : DataContract
|
||||
{
|
||||
public SpecialTypeDataContract(Type type)
|
||||
: base(new SpecialTypeDataContractCriticalHelper(type))
|
||||
{
|
||||
}
|
||||
|
||||
public SpecialTypeDataContract(Type type, XmlDictionaryString name, XmlDictionaryString ns)
|
||||
: base(new SpecialTypeDataContractCriticalHelper(type, name, ns))
|
||||
{
|
||||
}
|
||||
|
||||
internal override bool IsBuiltInDataContract => true;
|
||||
|
||||
private class SpecialTypeDataContractCriticalHelper : DataContract.DataContractCriticalHelper
|
||||
{
|
||||
internal SpecialTypeDataContractCriticalHelper(Type type)
|
||||
: base(type)
|
||||
{
|
||||
}
|
||||
|
||||
internal SpecialTypeDataContractCriticalHelper(Type type, XmlDictionaryString name, XmlDictionaryString ns)
|
||||
: base(type)
|
||||
{
|
||||
SetDataContractName(name, ns);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
using System;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
namespace Compat.Runtime.Serialization
|
||||
{
|
||||
internal sealed class SurrogateDataContract : DataContract
|
||||
{
|
||||
private readonly SurrogateDataContractCriticalHelper _helper;
|
||||
|
||||
internal SurrogateDataContract(Type type, ISerializationSurrogate serializationSurrogate)
|
||||
: base(new SurrogateDataContractCriticalHelper(type, serializationSurrogate))
|
||||
{
|
||||
_helper = base.Helper as SurrogateDataContractCriticalHelper;
|
||||
}
|
||||
|
||||
internal ISerializationSurrogate SerializationSurrogate => _helper.SerializationSurrogate;
|
||||
|
||||
public override void WriteXmlValue(XmlWriterDelegator xmlWriter, object obj, XmlObjectSerializerWriteContext context)
|
||||
{
|
||||
SerializationInfo serInfo = new SerializationInfo(UnderlyingType, XmlObjectSerializer.FormatterConverter, !context.UnsafeTypeForwardingEnabled);
|
||||
SerializationSurrogateGetObjectData(obj, serInfo, context.GetStreamingContext());
|
||||
context.WriteSerializationInfo(xmlWriter, UnderlyingType, serInfo);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
private object SerializationSurrogateSetObjectData(object obj, SerializationInfo serInfo, StreamingContext context)
|
||||
{
|
||||
return SerializationSurrogate.SetObjectData(obj, serInfo, context, null);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
internal static object GetRealObject(IObjectReference obj, StreamingContext context)
|
||||
{
|
||||
return obj.GetRealObject(context);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
private object GetUninitializedObject(Type objType)
|
||||
{
|
||||
return FormatterServices.GetUninitializedObject(objType);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
private void SerializationSurrogateGetObjectData(object obj, SerializationInfo serInfo, StreamingContext context)
|
||||
{
|
||||
SerializationSurrogate.GetObjectData(obj, serInfo, context);
|
||||
}
|
||||
|
||||
public override object ReadXmlValue(XmlReaderDelegator xmlReader, XmlObjectSerializerReadContext context)
|
||||
{
|
||||
xmlReader.Read();
|
||||
Type objType = UnderlyingType;
|
||||
object obj = objType.IsArray ? Array.CreateInstance(objType.GetElementType(), 0) : GetUninitializedObject(objType);
|
||||
context.AddNewObject(obj);
|
||||
string objectId = context.GetObjectId();
|
||||
SerializationInfo serInfo = context.ReadSerializationInfo(xmlReader, objType);
|
||||
object newObj = SerializationSurrogateSetObjectData(obj, serInfo, context.GetStreamingContext());
|
||||
if (newObj == null)
|
||||
{
|
||||
newObj = obj;
|
||||
}
|
||||
|
||||
if (newObj is IDeserializationCallback)
|
||||
{
|
||||
((IDeserializationCallback)newObj).OnDeserialization(null);
|
||||
}
|
||||
|
||||
if (newObj is IObjectReference)
|
||||
{
|
||||
newObj = GetRealObject((IObjectReference)newObj, context.GetStreamingContext());
|
||||
}
|
||||
|
||||
context.ReplaceDeserializedObject(objectId, obj, newObj);
|
||||
xmlReader.ReadEndElement();
|
||||
return newObj;
|
||||
}
|
||||
|
||||
private class SurrogateDataContractCriticalHelper : DataContract.DataContractCriticalHelper
|
||||
{
|
||||
private readonly ISerializationSurrogate _serializationSurrogate;
|
||||
|
||||
internal SurrogateDataContractCriticalHelper(Type type, ISerializationSurrogate serializationSurrogate)
|
||||
: base(type)
|
||||
{
|
||||
_serializationSurrogate = serializationSurrogate;
|
||||
DataContract.GetDefaultStableName(DataContract.GetClrTypeFullName(type), out string name, out string ns);
|
||||
SetDataContractName(CreateQualifiedName(name, ns));
|
||||
}
|
||||
|
||||
internal ISerializationSurrogate SerializationSurrogate => _serializationSurrogate;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
using System;
|
||||
|
||||
namespace Compat.Runtime.Serialization
|
||||
{
|
||||
internal class TypeHandleRef
|
||||
{
|
||||
private RuntimeTypeHandle _value;
|
||||
|
||||
public TypeHandleRef()
|
||||
{
|
||||
}
|
||||
|
||||
public TypeHandleRef(RuntimeTypeHandle value)
|
||||
{
|
||||
_value = value;
|
||||
}
|
||||
|
||||
public RuntimeTypeHandle Value
|
||||
{
|
||||
get => _value;
|
||||
set => _value = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Compat.Runtime.Serialization
|
||||
{
|
||||
internal class TypeHandleRefEqualityComparer : IEqualityComparer<TypeHandleRef>
|
||||
{
|
||||
public bool Equals(TypeHandleRef x, TypeHandleRef y)
|
||||
{
|
||||
return x.Value.Equals(y.Value);
|
||||
}
|
||||
|
||||
public int GetHashCode(TypeHandleRef obj)
|
||||
{
|
||||
return obj.Value.GetHashCode();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
namespace Compat.Runtime.Serialization
|
||||
{
|
||||
internal sealed class TypeInformation
|
||||
{
|
||||
private readonly string _fullTypeName;
|
||||
private readonly string _assemblyString;
|
||||
private readonly bool _hasTypeForwardedFrom;
|
||||
|
||||
internal TypeInformation(string fullTypeName, string assemblyString, bool hasTypeForwardedFrom)
|
||||
{
|
||||
_fullTypeName = fullTypeName;
|
||||
_assemblyString = assemblyString;
|
||||
_hasTypeForwardedFrom = hasTypeForwardedFrom;
|
||||
}
|
||||
|
||||
internal string FullTypeName => _fullTypeName;
|
||||
|
||||
internal string AssemblyString => _assemblyString;
|
||||
|
||||
internal bool HasTypeForwardedFrom => _hasTypeForwardedFrom;
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,370 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using System.Security;
|
||||
using System.Threading;
|
||||
using System.Xml;
|
||||
using System.Xml.Schema;
|
||||
using System.Xml.Serialization;
|
||||
|
||||
namespace Compat.Runtime.Serialization
|
||||
{
|
||||
using DataContractDictionary = Dictionary<XmlQualifiedName, DataContract>;
|
||||
|
||||
internal delegate IXmlSerializable CreateXmlSerializableDelegate();
|
||||
|
||||
internal sealed class XmlDataContract : DataContract
|
||||
{
|
||||
private readonly XmlDataContractCriticalHelper _helper;
|
||||
|
||||
internal XmlDataContract()
|
||||
: base(new XmlDataContractCriticalHelper())
|
||||
{
|
||||
_helper = base.Helper as XmlDataContractCriticalHelper;
|
||||
}
|
||||
|
||||
internal XmlDataContract(Type type)
|
||||
: base(new XmlDataContractCriticalHelper(type))
|
||||
{
|
||||
_helper = base.Helper as XmlDataContractCriticalHelper;
|
||||
}
|
||||
|
||||
internal override DataContractDictionary KnownDataContracts
|
||||
{
|
||||
get => _helper.KnownDataContracts;
|
||||
set => _helper.KnownDataContracts = value;
|
||||
}
|
||||
|
||||
internal XmlSchemaType XsdType
|
||||
{
|
||||
get => _helper.XsdType;
|
||||
set => _helper.XsdType = value;
|
||||
}
|
||||
|
||||
internal bool IsAnonymous => _helper.IsAnonymous;
|
||||
|
||||
internal override bool HasRoot
|
||||
{
|
||||
get => _helper.HasRoot;
|
||||
set => _helper.HasRoot = value;
|
||||
}
|
||||
|
||||
internal override XmlDictionaryString TopLevelElementName
|
||||
{
|
||||
get => _helper.TopLevelElementName;
|
||||
set => _helper.TopLevelElementName = value;
|
||||
}
|
||||
|
||||
internal override XmlDictionaryString TopLevelElementNamespace
|
||||
{
|
||||
get => _helper.TopLevelElementNamespace;
|
||||
set => _helper.TopLevelElementNamespace = value;
|
||||
}
|
||||
|
||||
internal bool IsTopLevelElementNullable
|
||||
{
|
||||
get => _helper.IsTopLevelElementNullable;
|
||||
set => _helper.IsTopLevelElementNullable = value;
|
||||
}
|
||||
|
||||
internal bool IsTypeDefinedOnImport
|
||||
{
|
||||
get => _helper.IsTypeDefinedOnImport;
|
||||
set => _helper.IsTypeDefinedOnImport = value;
|
||||
}
|
||||
|
||||
internal CreateXmlSerializableDelegate CreateXmlSerializableDelegate
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_helper.CreateXmlSerializableDelegate == null)
|
||||
{
|
||||
lock (this)
|
||||
{
|
||||
if (_helper.CreateXmlSerializableDelegate == null)
|
||||
{
|
||||
CreateXmlSerializableDelegate tempCreateXmlSerializable = GenerateCreateXmlSerializableDelegate();
|
||||
Thread.MemoryBarrier();
|
||||
_helper.CreateXmlSerializableDelegate = tempCreateXmlSerializable;
|
||||
}
|
||||
}
|
||||
}
|
||||
return _helper.CreateXmlSerializableDelegate;
|
||||
}
|
||||
}
|
||||
|
||||
internal override bool CanContainReferences => false;
|
||||
|
||||
internal override bool IsBuiltInDataContract => UnderlyingType == Globals.TypeOfXmlElement || UnderlyingType == Globals.TypeOfXmlNodeArray;
|
||||
|
||||
private class XmlDataContractCriticalHelper : DataContract.DataContractCriticalHelper
|
||||
{
|
||||
private DataContractDictionary knownDataContracts;
|
||||
private bool isKnownTypeAttributeChecked;
|
||||
private XmlDictionaryString topLevelElementName;
|
||||
private XmlDictionaryString topLevelElementNamespace;
|
||||
private bool isTopLevelElementNullable;
|
||||
private bool isTypeDefinedOnImport;
|
||||
private XmlSchemaType xsdType;
|
||||
private bool hasRoot;
|
||||
private CreateXmlSerializableDelegate createXmlSerializable;
|
||||
|
||||
internal XmlDataContractCriticalHelper()
|
||||
{
|
||||
}
|
||||
|
||||
internal XmlDataContractCriticalHelper(Type type)
|
||||
: base(type)
|
||||
{
|
||||
if (type.IsDefined(Globals.TypeOfDataContractAttribute, false))
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new System.Runtime.Serialization.InvalidDataContractException(SR.Format(SR.IXmlSerializableCannotHaveDataContract, DataContract.GetClrTypeFullName(type))));
|
||||
}
|
||||
|
||||
if (type.IsDefined(Globals.TypeOfCollectionDataContractAttribute, false))
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new System.Runtime.Serialization.InvalidDataContractException(SR.Format(SR.IXmlSerializableCannotHaveCollectionDataContract, DataContract.GetClrTypeFullName(type))));
|
||||
}
|
||||
|
||||
SchemaExporter.GetXmlTypeInfo(type, out XmlQualifiedName stableName, out XmlSchemaType xsdType, out bool hasRoot);
|
||||
|
||||
StableName = stableName;
|
||||
XsdType = xsdType;
|
||||
HasRoot = hasRoot;
|
||||
XmlDictionary dictionary = new XmlDictionary();
|
||||
Name = dictionary.Add(StableName.Name);
|
||||
Namespace = dictionary.Add(StableName.Namespace);
|
||||
object[] xmlRootAttributes = (UnderlyingType == null) ? null : UnderlyingType.GetCustomAttributes(Globals.TypeOfXmlRootAttribute, false);
|
||||
if (xmlRootAttributes == null || xmlRootAttributes.Length == 0)
|
||||
{
|
||||
if (hasRoot)
|
||||
{
|
||||
topLevelElementName = Name;
|
||||
topLevelElementNamespace = (StableName.Namespace == Globals.SchemaNamespace) ? DictionaryGlobals.EmptyString : Namespace;
|
||||
isTopLevelElementNullable = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (hasRoot)
|
||||
{
|
||||
XmlRootAttribute xmlRootAttribute = (XmlRootAttribute)xmlRootAttributes[0];
|
||||
isTopLevelElementNullable = xmlRootAttribute.IsNullable;
|
||||
string elementName = xmlRootAttribute.ElementName;
|
||||
topLevelElementName = (elementName == null || elementName.Length == 0) ? Name : dictionary.Add(DataContract.EncodeLocalName(elementName));
|
||||
string elementNs = xmlRootAttribute.Namespace;
|
||||
topLevelElementNamespace = (elementNs == null || elementNs.Length == 0) ? DictionaryGlobals.EmptyString : dictionary.Add(elementNs);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new System.Runtime.Serialization.InvalidDataContractException(SR.Format(SR.IsAnyCannotHaveXmlRoot, DataContract.GetClrTypeFullName(UnderlyingType))));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal override DataContractDictionary KnownDataContracts
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!isKnownTypeAttributeChecked && UnderlyingType != null)
|
||||
{
|
||||
lock (this)
|
||||
{
|
||||
if (!isKnownTypeAttributeChecked)
|
||||
{
|
||||
knownDataContracts = DataContract.ImportKnownTypeAttributes(UnderlyingType);
|
||||
Thread.MemoryBarrier();
|
||||
isKnownTypeAttributeChecked = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return knownDataContracts;
|
||||
}
|
||||
set => knownDataContracts = value;
|
||||
}
|
||||
|
||||
internal XmlSchemaType XsdType
|
||||
{
|
||||
get => xsdType;
|
||||
set => xsdType = value;
|
||||
}
|
||||
|
||||
internal bool IsAnonymous => xsdType != null;
|
||||
|
||||
internal override bool HasRoot
|
||||
{
|
||||
get => hasRoot;
|
||||
set => hasRoot = value;
|
||||
}
|
||||
|
||||
internal override XmlDictionaryString TopLevelElementName
|
||||
{
|
||||
get => topLevelElementName;
|
||||
set => topLevelElementName = value;
|
||||
}
|
||||
|
||||
internal override XmlDictionaryString TopLevelElementNamespace
|
||||
{
|
||||
get => topLevelElementNamespace;
|
||||
set => topLevelElementNamespace = value;
|
||||
}
|
||||
|
||||
internal bool IsTopLevelElementNullable
|
||||
{
|
||||
get => isTopLevelElementNullable;
|
||||
set => isTopLevelElementNullable = value;
|
||||
}
|
||||
|
||||
internal bool IsTypeDefinedOnImport
|
||||
{
|
||||
get => isTypeDefinedOnImport;
|
||||
set => isTypeDefinedOnImport = value;
|
||||
}
|
||||
|
||||
internal CreateXmlSerializableDelegate CreateXmlSerializableDelegate
|
||||
{
|
||||
get => createXmlSerializable;
|
||||
set => createXmlSerializable = value;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private ConstructorInfo GetConstructor()
|
||||
{
|
||||
Type type = UnderlyingType;
|
||||
|
||||
if (type.IsValueType)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
ConstructorInfo ctor = type.GetConstructor(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public, null, Globals.EmptyTypeArray, null);
|
||||
if (ctor == null)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new System.Runtime.Serialization.InvalidDataContractException(SR.Format(SR.IXmlSerializableMustHaveDefaultConstructor, DataContract.GetClrTypeFullName(type))));
|
||||
}
|
||||
|
||||
return ctor;
|
||||
}
|
||||
|
||||
internal void SetTopLevelElementName(XmlQualifiedName elementName)
|
||||
{
|
||||
if (elementName != null)
|
||||
{
|
||||
XmlDictionary dictionary = new XmlDictionary();
|
||||
TopLevelElementName = dictionary.Add(elementName.Name);
|
||||
TopLevelElementNamespace = dictionary.Add(elementName.Namespace);
|
||||
}
|
||||
}
|
||||
|
||||
internal CreateXmlSerializableDelegate GenerateCreateXmlSerializableDelegate()
|
||||
{
|
||||
Type type = UnderlyingType;
|
||||
CodeGenerator ilg = new CodeGenerator();
|
||||
bool memberAccessFlag = RequiresMemberAccessForCreate(null);
|
||||
ilg.BeginMethod("Create" + DataContract.GetClrTypeFullName(type), typeof(CreateXmlSerializableDelegate), memberAccessFlag);
|
||||
if (type.IsValueType)
|
||||
{
|
||||
System.Reflection.Emit.LocalBuilder local = ilg.DeclareLocal(type, type.Name + "Value");
|
||||
ilg.Ldloca(local);
|
||||
ilg.InitObj(type);
|
||||
ilg.Ldloc(local);
|
||||
}
|
||||
else
|
||||
{
|
||||
ilg.New(GetConstructor());
|
||||
}
|
||||
ilg.ConvertValue(UnderlyingType, Globals.TypeOfIXmlSerializable);
|
||||
ilg.Ret();
|
||||
return (CreateXmlSerializableDelegate)ilg.EndMethod();
|
||||
}
|
||||
|
||||
private bool RequiresMemberAccessForCreate(SecurityException securityException)
|
||||
{
|
||||
if (!IsTypeVisible(UnderlyingType))
|
||||
{
|
||||
if (securityException != null)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
|
||||
new SecurityException(SR.Format(SR.PartialTrustIXmlSerializableTypeNotPublic, DataContract.GetClrTypeFullName(UnderlyingType)),
|
||||
securityException));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if (ConstructorRequiresMemberAccess(GetConstructor()))
|
||||
{
|
||||
if (securityException != null)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
|
||||
new SecurityException(SR.Format(SR.PartialTrustIXmlSerialzableNoPublicConstructor, DataContract.GetClrTypeFullName(UnderlyingType)),
|
||||
securityException));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
internal override bool Equals(object other, Dictionary<DataContractPairKey, object> checkedContracts)
|
||||
{
|
||||
if (IsEqualOrChecked(other, checkedContracts))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
XmlDataContract dataContract = other as XmlDataContract;
|
||||
if (dataContract != null)
|
||||
{
|
||||
if (HasRoot != dataContract.HasRoot)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (IsAnonymous)
|
||||
{
|
||||
return dataContract.IsAnonymous;
|
||||
}
|
||||
else
|
||||
{
|
||||
return (StableName.Name == dataContract.StableName.Name && StableName.Namespace == dataContract.StableName.Namespace);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return base.GetHashCode();
|
||||
}
|
||||
|
||||
public override void WriteXmlValue(XmlWriterDelegator xmlWriter, object obj, XmlObjectSerializerWriteContext context)
|
||||
{
|
||||
if (context == null)
|
||||
{
|
||||
XmlObjectSerializerWriteContext.WriteRootIXmlSerializable(xmlWriter, obj);
|
||||
}
|
||||
else
|
||||
{
|
||||
context.WriteIXmlSerializable(xmlWriter, obj);
|
||||
}
|
||||
}
|
||||
|
||||
public override object ReadXmlValue(XmlReaderDelegator xmlReader, XmlObjectSerializerReadContext context)
|
||||
{
|
||||
object o;
|
||||
if (context == null)
|
||||
{
|
||||
o = XmlObjectSerializerReadContext.ReadRootIXmlSerializable(xmlReader, this, true /*isMemberType*/);
|
||||
}
|
||||
else
|
||||
{
|
||||
o = context.ReadIXmlSerializable(xmlReader, this, true /*isMemberType*/);
|
||||
context.AddNewObject(o);
|
||||
}
|
||||
xmlReader.ReadEndElement();
|
||||
return o;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Xml;
|
||||
|
||||
namespace Compat.Runtime.Serialization
|
||||
{
|
||||
internal class XmlDataNode : DataNode<object>
|
||||
{
|
||||
private IList<XmlAttribute> _xmlAttributes;
|
||||
private IList<XmlNode> _xmlChildNodes;
|
||||
private XmlDocument _ownerDocument;
|
||||
|
||||
internal XmlDataNode()
|
||||
{
|
||||
dataType = Globals.TypeOfXmlDataNode;
|
||||
}
|
||||
|
||||
internal IList<XmlAttribute> XmlAttributes
|
||||
{
|
||||
get => _xmlAttributes;
|
||||
set => _xmlAttributes = value;
|
||||
}
|
||||
|
||||
internal IList<XmlNode> XmlChildNodes
|
||||
{
|
||||
get => _xmlChildNodes;
|
||||
set => _xmlChildNodes = value;
|
||||
}
|
||||
|
||||
internal XmlDocument OwnerDocument
|
||||
{
|
||||
get => _ownerDocument;
|
||||
set => _ownerDocument = value;
|
||||
}
|
||||
|
||||
public override void Clear()
|
||||
{
|
||||
base.Clear();
|
||||
_xmlAttributes = null;
|
||||
_xmlChildNodes = null;
|
||||
_ownerDocument = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,902 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using System.Reflection.Emit;
|
||||
using System.Xml;
|
||||
|
||||
namespace Compat.Runtime.Serialization
|
||||
{
|
||||
internal delegate object XmlFormatClassReaderDelegate(XmlReaderDelegator xmlReader, XmlObjectSerializerReadContext context, XmlDictionaryString[] memberNames, XmlDictionaryString[] memberNamespaces);
|
||||
internal delegate object XmlFormatCollectionReaderDelegate(XmlReaderDelegator xmlReader, XmlObjectSerializerReadContext context, XmlDictionaryString itemName, XmlDictionaryString itemNamespace, CollectionDataContract collectionContract);
|
||||
internal delegate void XmlFormatGetOnlyCollectionReaderDelegate(XmlReaderDelegator xmlReader, XmlObjectSerializerReadContext context, XmlDictionaryString itemName, XmlDictionaryString itemNamespace, CollectionDataContract collectionContract);
|
||||
|
||||
internal sealed class XmlFormatReaderGenerator
|
||||
{
|
||||
private readonly CriticalHelper _helper;
|
||||
|
||||
public XmlFormatReaderGenerator()
|
||||
{
|
||||
_helper = new CriticalHelper();
|
||||
}
|
||||
|
||||
public XmlFormatClassReaderDelegate GenerateClassReader(ClassDataContract classContract)
|
||||
{
|
||||
return _helper.GenerateClassReader(classContract);
|
||||
}
|
||||
|
||||
public XmlFormatCollectionReaderDelegate GenerateCollectionReader(CollectionDataContract collectionContract)
|
||||
{
|
||||
return _helper.GenerateCollectionReader(collectionContract);
|
||||
}
|
||||
|
||||
public XmlFormatGetOnlyCollectionReaderDelegate GenerateGetOnlyCollectionReader(CollectionDataContract collectionContract)
|
||||
{
|
||||
return _helper.GenerateGetOnlyCollectionReader(collectionContract);
|
||||
}
|
||||
|
||||
private class CriticalHelper
|
||||
{
|
||||
private CodeGenerator ilg;
|
||||
private LocalBuilder objectLocal;
|
||||
private Type objectType;
|
||||
private ArgBuilder xmlReaderArg;
|
||||
private ArgBuilder contextArg;
|
||||
private ArgBuilder memberNamesArg;
|
||||
private ArgBuilder memberNamespacesArg;
|
||||
private ArgBuilder collectionContractArg;
|
||||
|
||||
public XmlFormatClassReaderDelegate GenerateClassReader(ClassDataContract classContract)
|
||||
{
|
||||
ilg = new CodeGenerator();
|
||||
bool memberAccessFlag = classContract.RequiresMemberAccessForRead(null);
|
||||
ilg.BeginMethod("Read" + classContract.StableName.Name + "FromXml", Globals.TypeOfXmlFormatClassReaderDelegate, memberAccessFlag);
|
||||
InitArgs();
|
||||
CreateObject(classContract);
|
||||
ilg.Call(contextArg, XmlFormatGeneratorStatics.AddNewObjectMethod, objectLocal);
|
||||
InvokeOnDeserializing(classContract);
|
||||
LocalBuilder objectId = null;
|
||||
if (HasFactoryMethod(classContract))
|
||||
{
|
||||
objectId = ilg.DeclareLocal(Globals.TypeOfString, "objectIdRead");
|
||||
ilg.Call(contextArg, XmlFormatGeneratorStatics.GetObjectIdMethod);
|
||||
ilg.Stloc(objectId);
|
||||
}
|
||||
if (classContract.IsISerializable)
|
||||
{
|
||||
ReadISerializable(classContract);
|
||||
}
|
||||
else
|
||||
{
|
||||
ReadClass(classContract);
|
||||
}
|
||||
|
||||
bool isFactoryType = InvokeFactoryMethod(classContract, objectId);
|
||||
if (Globals.TypeOfIDeserializationCallback.IsAssignableFrom(classContract.UnderlyingType))
|
||||
{
|
||||
ilg.Call(objectLocal, XmlFormatGeneratorStatics.OnDeserializationMethod, null);
|
||||
}
|
||||
|
||||
InvokeOnDeserialized(classContract);
|
||||
if (objectId == null || !isFactoryType)
|
||||
{
|
||||
ilg.Load(objectLocal);
|
||||
|
||||
// Do a conversion back from DateTimeOffsetAdapter to DateTimeOffset after deserialization.
|
||||
// DateTimeOffsetAdapter is used here for deserialization purposes to bypass the ISerializable implementation
|
||||
// on DateTimeOffset; which does not work in partial trust.
|
||||
|
||||
if (classContract.UnderlyingType == Globals.TypeOfDateTimeOffsetAdapter)
|
||||
{
|
||||
ilg.ConvertValue(objectLocal.LocalType, Globals.TypeOfDateTimeOffsetAdapter);
|
||||
ilg.Call(XmlFormatGeneratorStatics.GetDateTimeOffsetMethod);
|
||||
ilg.ConvertValue(Globals.TypeOfDateTimeOffset, ilg.CurrentMethod.ReturnType);
|
||||
}
|
||||
else
|
||||
{
|
||||
ilg.ConvertValue(objectLocal.LocalType, ilg.CurrentMethod.ReturnType);
|
||||
}
|
||||
}
|
||||
return (XmlFormatClassReaderDelegate)ilg.EndMethod();
|
||||
}
|
||||
|
||||
public XmlFormatCollectionReaderDelegate GenerateCollectionReader(CollectionDataContract collectionContract)
|
||||
{
|
||||
ilg = GenerateCollectionReaderHelper(collectionContract, false /*isGetOnlyCollection*/);
|
||||
ReadCollection(collectionContract);
|
||||
ilg.Load(objectLocal);
|
||||
ilg.ConvertValue(objectLocal.LocalType, ilg.CurrentMethod.ReturnType);
|
||||
return (XmlFormatCollectionReaderDelegate)ilg.EndMethod();
|
||||
}
|
||||
|
||||
public XmlFormatGetOnlyCollectionReaderDelegate GenerateGetOnlyCollectionReader(CollectionDataContract collectionContract)
|
||||
{
|
||||
ilg = GenerateCollectionReaderHelper(collectionContract, true /*isGetOnlyCollection*/);
|
||||
ReadGetOnlyCollection(collectionContract);
|
||||
return (XmlFormatGetOnlyCollectionReaderDelegate)ilg.EndMethod();
|
||||
}
|
||||
|
||||
private CodeGenerator GenerateCollectionReaderHelper(CollectionDataContract collectionContract, bool isGetOnlyCollection)
|
||||
{
|
||||
ilg = new CodeGenerator();
|
||||
bool memberAccessFlag = collectionContract.RequiresMemberAccessForRead(null);
|
||||
if (isGetOnlyCollection)
|
||||
{
|
||||
ilg.BeginMethod("Read" + collectionContract.StableName.Name + "FromXml" + "IsGetOnly", Globals.TypeOfXmlFormatGetOnlyCollectionReaderDelegate, memberAccessFlag);
|
||||
}
|
||||
else
|
||||
{
|
||||
ilg.BeginMethod("Read" + collectionContract.StableName.Name + "FromXml" + string.Empty, Globals.TypeOfXmlFormatCollectionReaderDelegate, memberAccessFlag);
|
||||
}
|
||||
InitArgs();
|
||||
collectionContractArg = ilg.GetArg(4);
|
||||
return ilg;
|
||||
}
|
||||
|
||||
private void InitArgs()
|
||||
{
|
||||
xmlReaderArg = ilg.GetArg(0);
|
||||
contextArg = ilg.GetArg(1);
|
||||
memberNamesArg = ilg.GetArg(2);
|
||||
memberNamespacesArg = ilg.GetArg(3);
|
||||
}
|
||||
|
||||
private void CreateObject(ClassDataContract classContract)
|
||||
{
|
||||
Type type = objectType = classContract.UnderlyingType;
|
||||
if (type.IsValueType && !classContract.IsNonAttributedType)
|
||||
{
|
||||
type = Globals.TypeOfValueType;
|
||||
}
|
||||
|
||||
objectLocal = ilg.DeclareLocal(type, "objectDeserialized");
|
||||
|
||||
if (classContract.UnderlyingType == Globals.TypeOfDBNull)
|
||||
{
|
||||
ilg.LoadMember(Globals.TypeOfDBNull.GetField("Value"));
|
||||
ilg.Stloc(objectLocal);
|
||||
}
|
||||
else if (classContract.IsNonAttributedType)
|
||||
{
|
||||
if (type.IsValueType)
|
||||
{
|
||||
ilg.Ldloca(objectLocal);
|
||||
ilg.InitObj(type);
|
||||
}
|
||||
else
|
||||
{
|
||||
ilg.New(classContract.GetNonAttributedTypeConstructor());
|
||||
ilg.Stloc(objectLocal);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ilg.Call(null, XmlFormatGeneratorStatics.GetUninitializedObjectMethod, DataContract.GetIdForInitialization(classContract));
|
||||
ilg.ConvertValue(Globals.TypeOfObject, type);
|
||||
ilg.Stloc(objectLocal);
|
||||
}
|
||||
}
|
||||
|
||||
private void InvokeOnDeserializing(ClassDataContract classContract)
|
||||
{
|
||||
if (classContract.BaseContract != null)
|
||||
{
|
||||
InvokeOnDeserializing(classContract.BaseContract);
|
||||
}
|
||||
|
||||
if (classContract.OnDeserializing != null)
|
||||
{
|
||||
ilg.LoadAddress(objectLocal);
|
||||
ilg.ConvertAddress(objectLocal.LocalType, objectType);
|
||||
ilg.Load(contextArg);
|
||||
ilg.LoadMember(XmlFormatGeneratorStatics.GetStreamingContextMethod);
|
||||
ilg.Call(classContract.OnDeserializing);
|
||||
}
|
||||
}
|
||||
|
||||
private void InvokeOnDeserialized(ClassDataContract classContract)
|
||||
{
|
||||
if (classContract.BaseContract != null)
|
||||
{
|
||||
InvokeOnDeserialized(classContract.BaseContract);
|
||||
}
|
||||
|
||||
if (classContract.OnDeserialized != null)
|
||||
{
|
||||
ilg.LoadAddress(objectLocal);
|
||||
ilg.ConvertAddress(objectLocal.LocalType, objectType);
|
||||
ilg.Load(contextArg);
|
||||
ilg.LoadMember(XmlFormatGeneratorStatics.GetStreamingContextMethod);
|
||||
ilg.Call(classContract.OnDeserialized);
|
||||
}
|
||||
}
|
||||
|
||||
private bool HasFactoryMethod(ClassDataContract classContract)
|
||||
{
|
||||
return Globals.TypeOfIObjectReference.IsAssignableFrom(classContract.UnderlyingType);
|
||||
}
|
||||
|
||||
private bool InvokeFactoryMethod(ClassDataContract classContract, LocalBuilder objectId)
|
||||
{
|
||||
if (HasFactoryMethod(classContract))
|
||||
{
|
||||
ilg.Load(contextArg);
|
||||
ilg.LoadAddress(objectLocal);
|
||||
ilg.ConvertAddress(objectLocal.LocalType, Globals.TypeOfIObjectReference);
|
||||
ilg.Load(objectId);
|
||||
ilg.Call(XmlFormatGeneratorStatics.GetRealObjectMethod);
|
||||
ilg.ConvertValue(Globals.TypeOfObject, ilg.CurrentMethod.ReturnType);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void ReadClass(ClassDataContract classContract)
|
||||
{
|
||||
if (classContract.HasExtensionData)
|
||||
{
|
||||
LocalBuilder extensionDataLocal = ilg.DeclareLocal(Globals.TypeOfExtensionDataObject, "extensionData");
|
||||
ilg.New(XmlFormatGeneratorStatics.ExtensionDataObjectCtor);
|
||||
ilg.Store(extensionDataLocal);
|
||||
ReadMembers(classContract, extensionDataLocal);
|
||||
|
||||
ClassDataContract currentContract = classContract;
|
||||
while (currentContract != null)
|
||||
{
|
||||
MethodInfo extensionDataSetMethod = currentContract.ExtensionDataSetMethod;
|
||||
if (extensionDataSetMethod != null)
|
||||
{
|
||||
ilg.Call(objectLocal, extensionDataSetMethod, extensionDataLocal);
|
||||
}
|
||||
|
||||
currentContract = currentContract.BaseContract;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ReadMembers(classContract, null /*extensionDataLocal*/);
|
||||
}
|
||||
}
|
||||
|
||||
private void ReadMembers(ClassDataContract classContract, LocalBuilder extensionDataLocal)
|
||||
{
|
||||
int memberCount = classContract.MemberNames.Length;
|
||||
ilg.Call(contextArg, XmlFormatGeneratorStatics.IncrementItemCountMethod, memberCount);
|
||||
|
||||
LocalBuilder memberIndexLocal = ilg.DeclareLocal(Globals.TypeOfInt, "memberIndex", -1);
|
||||
|
||||
bool[] requiredMembers = GetRequiredMembers(classContract, out int firstRequiredMember);
|
||||
bool hasRequiredMembers = (firstRequiredMember < memberCount);
|
||||
LocalBuilder requiredIndexLocal = hasRequiredMembers ? ilg.DeclareLocal(Globals.TypeOfInt, "requiredIndex", firstRequiredMember) : null;
|
||||
|
||||
object forReadElements = ilg.For(null, null, null);
|
||||
ilg.Call(null, XmlFormatGeneratorStatics.MoveToNextElementMethod, xmlReaderArg);
|
||||
ilg.IfFalseBreak(forReadElements);
|
||||
if (hasRequiredMembers)
|
||||
{
|
||||
ilg.Call(contextArg, XmlFormatGeneratorStatics.GetMemberIndexWithRequiredMembersMethod, xmlReaderArg, memberNamesArg, memberNamespacesArg, memberIndexLocal, requiredIndexLocal, extensionDataLocal);
|
||||
}
|
||||
else
|
||||
{
|
||||
ilg.Call(contextArg, XmlFormatGeneratorStatics.GetMemberIndexMethod, xmlReaderArg, memberNamesArg, memberNamespacesArg, memberIndexLocal, extensionDataLocal);
|
||||
}
|
||||
|
||||
if (memberCount > 0)
|
||||
{
|
||||
Label[] memberLabels = ilg.Switch(memberCount);
|
||||
ReadMembers(classContract, requiredMembers, memberLabels, memberIndexLocal, requiredIndexLocal);
|
||||
ilg.EndSwitch();
|
||||
}
|
||||
else
|
||||
{
|
||||
ilg.Pop();
|
||||
}
|
||||
ilg.EndFor();
|
||||
if (hasRequiredMembers)
|
||||
{
|
||||
ilg.If(requiredIndexLocal, Cmp.LessThan, memberCount);
|
||||
ilg.Call(null, XmlFormatGeneratorStatics.ThrowRequiredMemberMissingExceptionMethod, xmlReaderArg, memberIndexLocal, requiredIndexLocal, memberNamesArg);
|
||||
ilg.EndIf();
|
||||
}
|
||||
}
|
||||
|
||||
private int ReadMembers(ClassDataContract classContract, bool[] requiredMembers, Label[] memberLabels, LocalBuilder memberIndexLocal, LocalBuilder requiredIndexLocal)
|
||||
{
|
||||
int memberCount = (classContract.BaseContract == null) ? 0 : ReadMembers(classContract.BaseContract, requiredMembers,
|
||||
memberLabels, memberIndexLocal, requiredIndexLocal);
|
||||
|
||||
for (int i = 0; i < classContract.Members.Count; i++, memberCount++)
|
||||
{
|
||||
DataMember dataMember = classContract.Members[i];
|
||||
Type memberType = dataMember.MemberType;
|
||||
ilg.Case(memberLabels[memberCount], dataMember.Name);
|
||||
if (dataMember.IsRequired)
|
||||
{
|
||||
int nextRequiredIndex = memberCount + 1;
|
||||
for (; nextRequiredIndex < requiredMembers.Length; nextRequiredIndex++)
|
||||
{
|
||||
if (requiredMembers[nextRequiredIndex])
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ilg.Set(requiredIndexLocal, nextRequiredIndex);
|
||||
}
|
||||
|
||||
LocalBuilder value = null;
|
||||
|
||||
if (dataMember.IsGetOnlyCollection)
|
||||
{
|
||||
ilg.LoadAddress(objectLocal);
|
||||
ilg.LoadMember(dataMember.MemberInfo);
|
||||
value = ilg.DeclareLocal(memberType, dataMember.Name + "Value");
|
||||
ilg.Stloc(value);
|
||||
ilg.Call(contextArg, XmlFormatGeneratorStatics.StoreCollectionMemberInfoMethod, value);
|
||||
ReadValue(memberType, dataMember.Name, classContract.StableName.Namespace);
|
||||
}
|
||||
else
|
||||
{
|
||||
value = ReadValue(memberType, dataMember.Name, classContract.StableName.Namespace);
|
||||
ilg.LoadAddress(objectLocal);
|
||||
ilg.ConvertAddress(objectLocal.LocalType, objectType);
|
||||
ilg.Ldloc(value);
|
||||
ilg.StoreMember(dataMember.MemberInfo);
|
||||
}
|
||||
ilg.Set(memberIndexLocal, memberCount);
|
||||
ilg.EndCase();
|
||||
}
|
||||
return memberCount;
|
||||
}
|
||||
|
||||
private bool[] GetRequiredMembers(ClassDataContract contract, out int firstRequiredMember)
|
||||
{
|
||||
int memberCount = contract.MemberNames.Length;
|
||||
bool[] requiredMembers = new bool[memberCount];
|
||||
GetRequiredMembers(contract, requiredMembers);
|
||||
for (firstRequiredMember = 0; firstRequiredMember < memberCount; firstRequiredMember++)
|
||||
{
|
||||
if (requiredMembers[firstRequiredMember])
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return requiredMembers;
|
||||
}
|
||||
|
||||
private int GetRequiredMembers(ClassDataContract contract, bool[] requiredMembers)
|
||||
{
|
||||
int memberCount = (contract.BaseContract == null) ? 0 : GetRequiredMembers(contract.BaseContract, requiredMembers);
|
||||
List<DataMember> members = contract.Members;
|
||||
for (int i = 0; i < members.Count; i++, memberCount++)
|
||||
{
|
||||
requiredMembers[memberCount] = members[i].IsRequired;
|
||||
}
|
||||
return memberCount;
|
||||
}
|
||||
|
||||
private void ReadISerializable(ClassDataContract classContract)
|
||||
{
|
||||
ConstructorInfo ctor = classContract.GetISerializableConstructor();
|
||||
ilg.LoadAddress(objectLocal);
|
||||
ilg.ConvertAddress(objectLocal.LocalType, objectType);
|
||||
ilg.Call(contextArg, XmlFormatGeneratorStatics.ReadSerializationInfoMethod, xmlReaderArg, classContract.UnderlyingType);
|
||||
ilg.Load(contextArg);
|
||||
ilg.LoadMember(XmlFormatGeneratorStatics.GetStreamingContextMethod);
|
||||
ilg.Call(ctor);
|
||||
}
|
||||
|
||||
private LocalBuilder ReadValue(Type type, string name, string ns)
|
||||
{
|
||||
LocalBuilder value = ilg.DeclareLocal(type, "valueRead");
|
||||
LocalBuilder nullableValue = null;
|
||||
int nullables = 0;
|
||||
while (type.IsGenericType && type.GetGenericTypeDefinition() == Globals.TypeOfNullable)
|
||||
{
|
||||
nullables++;
|
||||
type = type.GetGenericArguments()[0];
|
||||
}
|
||||
|
||||
PrimitiveDataContract primitiveContract = PrimitiveDataContract.GetPrimitiveDataContract(type);
|
||||
if ((primitiveContract != null && primitiveContract.UnderlyingType != Globals.TypeOfObject) || nullables != 0 || type.IsValueType)
|
||||
{
|
||||
LocalBuilder objectId = ilg.DeclareLocal(Globals.TypeOfString, "objectIdRead");
|
||||
ilg.Call(contextArg, XmlFormatGeneratorStatics.ReadAttributesMethod, xmlReaderArg);
|
||||
ilg.Call(contextArg, XmlFormatGeneratorStatics.ReadIfNullOrRefMethod, xmlReaderArg, type, DataContract.IsTypeSerializable(type));
|
||||
ilg.Stloc(objectId);
|
||||
// Deserialize null
|
||||
ilg.If(objectId, Cmp.EqualTo, Globals.NullObjectId);
|
||||
if (nullables != 0)
|
||||
{
|
||||
ilg.LoadAddress(value);
|
||||
ilg.InitObj(value.LocalType);
|
||||
}
|
||||
else if (type.IsValueType)
|
||||
{
|
||||
ThrowValidationException(SR.Format(SR.ValueTypeCannotBeNull, DataContract.GetClrTypeFullName(type)));
|
||||
}
|
||||
else
|
||||
{
|
||||
ilg.Load(null);
|
||||
ilg.Stloc(value);
|
||||
}
|
||||
|
||||
// Deserialize value
|
||||
|
||||
// Compare against Globals.NewObjectId, which is set to string.Empty
|
||||
ilg.ElseIfIsEmptyString(objectId);
|
||||
ilg.Call(contextArg, XmlFormatGeneratorStatics.GetObjectIdMethod);
|
||||
ilg.Stloc(objectId);
|
||||
if (type.IsValueType)
|
||||
{
|
||||
ilg.IfNotIsEmptyString(objectId);
|
||||
ThrowValidationException(SR.Format(SR.ValueTypeCannotHaveId, DataContract.GetClrTypeFullName(type)));
|
||||
ilg.EndIf();
|
||||
}
|
||||
if (nullables != 0)
|
||||
{
|
||||
nullableValue = value;
|
||||
value = ilg.DeclareLocal(type, "innerValueRead");
|
||||
}
|
||||
|
||||
if (primitiveContract != null && primitiveContract.UnderlyingType != Globals.TypeOfObject)
|
||||
{
|
||||
ilg.Call(xmlReaderArg, primitiveContract.XmlFormatReaderMethod);
|
||||
ilg.Stloc(value);
|
||||
if (!type.IsValueType)
|
||||
{
|
||||
ilg.Call(contextArg, XmlFormatGeneratorStatics.AddNewObjectMethod, value);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
InternalDeserialize(value, type, name, ns);
|
||||
}
|
||||
// Deserialize ref
|
||||
ilg.Else();
|
||||
if (type.IsValueType)
|
||||
{
|
||||
ThrowValidationException(SR.Format(SR.ValueTypeCannotHaveRef, DataContract.GetClrTypeFullName(type)));
|
||||
}
|
||||
else
|
||||
{
|
||||
ilg.Call(contextArg, XmlFormatGeneratorStatics.GetExistingObjectMethod, objectId, type, name, ns);
|
||||
ilg.ConvertValue(Globals.TypeOfObject, type);
|
||||
ilg.Stloc(value);
|
||||
}
|
||||
ilg.EndIf();
|
||||
|
||||
if (nullableValue != null)
|
||||
{
|
||||
ilg.If(objectId, Cmp.NotEqualTo, Globals.NullObjectId);
|
||||
WrapNullableObject(value, nullableValue, nullables);
|
||||
ilg.EndIf();
|
||||
value = nullableValue;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
InternalDeserialize(value, type, name, ns);
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
private void InternalDeserialize(LocalBuilder value, Type type, string name, string ns)
|
||||
{
|
||||
ilg.Load(contextArg);
|
||||
ilg.Load(xmlReaderArg);
|
||||
Type declaredType = type.IsPointer ? Globals.TypeOfReflectionPointer : type;
|
||||
ilg.Load(DataContract.GetId(declaredType.TypeHandle));
|
||||
ilg.Ldtoken(declaredType);
|
||||
ilg.Load(name);
|
||||
ilg.Load(ns);
|
||||
ilg.Call(XmlFormatGeneratorStatics.InternalDeserializeMethod);
|
||||
|
||||
if (type.IsPointer)
|
||||
{
|
||||
ilg.Call(XmlFormatGeneratorStatics.UnboxPointer);
|
||||
}
|
||||
else
|
||||
{
|
||||
ilg.ConvertValue(Globals.TypeOfObject, type);
|
||||
}
|
||||
|
||||
ilg.Stloc(value);
|
||||
}
|
||||
|
||||
private void WrapNullableObject(LocalBuilder innerValue, LocalBuilder outerValue, int nullables)
|
||||
{
|
||||
Type innerType = innerValue.LocalType, outerType = outerValue.LocalType;
|
||||
ilg.LoadAddress(outerValue);
|
||||
ilg.Load(innerValue);
|
||||
for (int i = 1; i < nullables; i++)
|
||||
{
|
||||
Type type = Globals.TypeOfNullable.MakeGenericType(innerType);
|
||||
ilg.New(type.GetConstructor(new Type[] { innerType }));
|
||||
innerType = type;
|
||||
}
|
||||
ilg.Call(outerType.GetConstructor(new Type[] { innerType }));
|
||||
}
|
||||
|
||||
private void ReadCollection(CollectionDataContract collectionContract)
|
||||
{
|
||||
Type type = collectionContract.UnderlyingType;
|
||||
Type itemType = collectionContract.ItemType;
|
||||
bool isArray = (collectionContract.Kind == CollectionKind.Array);
|
||||
|
||||
ConstructorInfo constructor = collectionContract.Constructor;
|
||||
|
||||
if (type.IsInterface)
|
||||
{
|
||||
switch (collectionContract.Kind)
|
||||
{
|
||||
case CollectionKind.GenericDictionary:
|
||||
type = Globals.TypeOfDictionaryGeneric.MakeGenericType(itemType.GetGenericArguments());
|
||||
constructor = type.GetConstructor(BindingFlags.Instance | BindingFlags.Public, null, Globals.EmptyTypeArray, null);
|
||||
break;
|
||||
case CollectionKind.Dictionary:
|
||||
type = Globals.TypeOfHashtable;
|
||||
constructor = XmlFormatGeneratorStatics.HashtableCtor;
|
||||
break;
|
||||
case CollectionKind.Collection:
|
||||
case CollectionKind.GenericCollection:
|
||||
case CollectionKind.Enumerable:
|
||||
case CollectionKind.GenericEnumerable:
|
||||
case CollectionKind.List:
|
||||
case CollectionKind.GenericList:
|
||||
type = itemType.MakeArrayType();
|
||||
isArray = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
string itemName = collectionContract.ItemName;
|
||||
string itemNs = collectionContract.StableName.Namespace;
|
||||
|
||||
objectLocal = ilg.DeclareLocal(type, "objectDeserialized");
|
||||
if (!isArray)
|
||||
{
|
||||
if (type.IsValueType)
|
||||
{
|
||||
ilg.Ldloca(objectLocal);
|
||||
ilg.InitObj(type);
|
||||
}
|
||||
else
|
||||
{
|
||||
ilg.New(constructor);
|
||||
ilg.Stloc(objectLocal);
|
||||
ilg.Call(contextArg, XmlFormatGeneratorStatics.AddNewObjectMethod, objectLocal);
|
||||
}
|
||||
}
|
||||
|
||||
LocalBuilder size = ilg.DeclareLocal(Globals.TypeOfInt, "arraySize");
|
||||
ilg.Call(contextArg, XmlFormatGeneratorStatics.GetArraySizeMethod);
|
||||
ilg.Stloc(size);
|
||||
|
||||
LocalBuilder objectId = ilg.DeclareLocal(Globals.TypeOfString, "objectIdRead");
|
||||
ilg.Call(contextArg, XmlFormatGeneratorStatics.GetObjectIdMethod);
|
||||
ilg.Stloc(objectId);
|
||||
|
||||
bool canReadPrimitiveArray = false;
|
||||
if (isArray && TryReadPrimitiveArray(type, itemType, size))
|
||||
{
|
||||
canReadPrimitiveArray = true;
|
||||
ilg.IfNot();
|
||||
}
|
||||
|
||||
ilg.If(size, Cmp.EqualTo, -1);
|
||||
|
||||
LocalBuilder growingCollection = null;
|
||||
if (isArray)
|
||||
{
|
||||
growingCollection = ilg.DeclareLocal(type, "growingCollection");
|
||||
ilg.NewArray(itemType, 32);
|
||||
ilg.Stloc(growingCollection);
|
||||
}
|
||||
LocalBuilder i = ilg.DeclareLocal(Globals.TypeOfInt, "i");
|
||||
object forLoop = ilg.For(i, 0, int.MaxValue);
|
||||
IsStartElement(memberNamesArg, memberNamespacesArg);
|
||||
ilg.If();
|
||||
ilg.Call(contextArg, XmlFormatGeneratorStatics.IncrementItemCountMethod, 1);
|
||||
LocalBuilder value = ReadCollectionItem(collectionContract, itemType, itemName, itemNs);
|
||||
if (isArray)
|
||||
{
|
||||
MethodInfo ensureArraySizeMethod = XmlFormatGeneratorStatics.EnsureArraySizeMethod.MakeGenericMethod(itemType);
|
||||
ilg.Call(null, ensureArraySizeMethod, growingCollection, i);
|
||||
ilg.Stloc(growingCollection);
|
||||
ilg.StoreArrayElement(growingCollection, i, value);
|
||||
}
|
||||
else
|
||||
{
|
||||
StoreCollectionValue(objectLocal, value, collectionContract);
|
||||
}
|
||||
|
||||
ilg.Else();
|
||||
IsEndElement();
|
||||
ilg.If();
|
||||
ilg.Break(forLoop);
|
||||
ilg.Else();
|
||||
HandleUnexpectedItemInCollection(i);
|
||||
ilg.EndIf();
|
||||
ilg.EndIf();
|
||||
|
||||
ilg.EndFor();
|
||||
if (isArray)
|
||||
{
|
||||
MethodInfo trimArraySizeMethod = XmlFormatGeneratorStatics.TrimArraySizeMethod.MakeGenericMethod(itemType);
|
||||
ilg.Call(null, trimArraySizeMethod, growingCollection, i);
|
||||
ilg.Stloc(objectLocal);
|
||||
ilg.Call(contextArg, XmlFormatGeneratorStatics.AddNewObjectWithIdMethod, objectId, objectLocal);
|
||||
}
|
||||
ilg.Else();
|
||||
|
||||
ilg.Call(contextArg, XmlFormatGeneratorStatics.IncrementItemCountMethod, size);
|
||||
if (isArray)
|
||||
{
|
||||
ilg.NewArray(itemType, size);
|
||||
ilg.Stloc(objectLocal);
|
||||
ilg.Call(contextArg, XmlFormatGeneratorStatics.AddNewObjectMethod, objectLocal);
|
||||
}
|
||||
LocalBuilder j = ilg.DeclareLocal(Globals.TypeOfInt, "j");
|
||||
ilg.For(j, 0, size);
|
||||
IsStartElement(memberNamesArg, memberNamespacesArg);
|
||||
ilg.If();
|
||||
LocalBuilder itemValue = ReadCollectionItem(collectionContract, itemType, itemName, itemNs);
|
||||
if (isArray)
|
||||
{
|
||||
ilg.StoreArrayElement(objectLocal, j, itemValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
StoreCollectionValue(objectLocal, itemValue, collectionContract);
|
||||
}
|
||||
|
||||
ilg.Else();
|
||||
HandleUnexpectedItemInCollection(j);
|
||||
ilg.EndIf();
|
||||
ilg.EndFor();
|
||||
ilg.Call(contextArg, XmlFormatGeneratorStatics.CheckEndOfArrayMethod, xmlReaderArg, size, memberNamesArg, memberNamespacesArg);
|
||||
ilg.EndIf();
|
||||
|
||||
if (canReadPrimitiveArray)
|
||||
{
|
||||
ilg.Else();
|
||||
ilg.Call(contextArg, XmlFormatGeneratorStatics.AddNewObjectWithIdMethod, objectId, objectLocal);
|
||||
ilg.EndIf();
|
||||
}
|
||||
}
|
||||
|
||||
private void ReadGetOnlyCollection(CollectionDataContract collectionContract)
|
||||
{
|
||||
Type type = collectionContract.UnderlyingType;
|
||||
Type itemType = collectionContract.ItemType;
|
||||
bool isArray = (collectionContract.Kind == CollectionKind.Array);
|
||||
string itemName = collectionContract.ItemName;
|
||||
string itemNs = collectionContract.StableName.Namespace;
|
||||
|
||||
objectLocal = ilg.DeclareLocal(type, "objectDeserialized");
|
||||
ilg.Load(contextArg);
|
||||
ilg.LoadMember(XmlFormatGeneratorStatics.GetCollectionMemberMethod);
|
||||
ilg.ConvertValue(Globals.TypeOfObject, type);
|
||||
ilg.Stloc(objectLocal);
|
||||
|
||||
//check that items are actually going to be deserialized into the collection
|
||||
IsStartElement(memberNamesArg, memberNamespacesArg);
|
||||
ilg.If();
|
||||
ilg.If(objectLocal, Cmp.EqualTo, null);
|
||||
ilg.Call(null, XmlFormatGeneratorStatics.ThrowNullValueReturnedForGetOnlyCollectionExceptionMethod, type);
|
||||
|
||||
ilg.Else();
|
||||
LocalBuilder size = ilg.DeclareLocal(Globals.TypeOfInt, "arraySize");
|
||||
if (isArray)
|
||||
{
|
||||
ilg.Load(objectLocal);
|
||||
ilg.Call(XmlFormatGeneratorStatics.GetArrayLengthMethod);
|
||||
ilg.Stloc(size);
|
||||
}
|
||||
|
||||
ilg.Call(contextArg, XmlFormatGeneratorStatics.AddNewObjectMethod, objectLocal);
|
||||
|
||||
LocalBuilder i = ilg.DeclareLocal(Globals.TypeOfInt, "i");
|
||||
object forLoop = ilg.For(i, 0, int.MaxValue);
|
||||
IsStartElement(memberNamesArg, memberNamespacesArg);
|
||||
ilg.If();
|
||||
ilg.Call(contextArg, XmlFormatGeneratorStatics.IncrementItemCountMethod, 1);
|
||||
LocalBuilder value = ReadCollectionItem(collectionContract, itemType, itemName, itemNs);
|
||||
if (isArray)
|
||||
{
|
||||
ilg.If(size, Cmp.EqualTo, i);
|
||||
ilg.Call(null, XmlFormatGeneratorStatics.ThrowArrayExceededSizeExceptionMethod, size, type);
|
||||
ilg.Else();
|
||||
ilg.StoreArrayElement(objectLocal, i, value);
|
||||
ilg.EndIf();
|
||||
}
|
||||
else
|
||||
{
|
||||
StoreCollectionValue(objectLocal, value, collectionContract);
|
||||
}
|
||||
|
||||
ilg.Else();
|
||||
IsEndElement();
|
||||
ilg.If();
|
||||
ilg.Break(forLoop);
|
||||
ilg.Else();
|
||||
HandleUnexpectedItemInCollection(i);
|
||||
ilg.EndIf();
|
||||
ilg.EndIf();
|
||||
ilg.EndFor();
|
||||
ilg.Call(contextArg, XmlFormatGeneratorStatics.CheckEndOfArrayMethod, xmlReaderArg, size, memberNamesArg, memberNamespacesArg);
|
||||
|
||||
ilg.EndIf();
|
||||
ilg.EndIf();
|
||||
}
|
||||
|
||||
private bool TryReadPrimitiveArray(Type type, Type itemType, LocalBuilder size)
|
||||
{
|
||||
PrimitiveDataContract primitiveContract = PrimitiveDataContract.GetPrimitiveDataContract(itemType);
|
||||
if (primitiveContract == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
string readArrayMethod = null;
|
||||
switch (Type.GetTypeCode(itemType))
|
||||
{
|
||||
case TypeCode.Boolean:
|
||||
readArrayMethod = "TryReadBooleanArray";
|
||||
break;
|
||||
case TypeCode.DateTime:
|
||||
readArrayMethod = "TryReadDateTimeArray";
|
||||
break;
|
||||
case TypeCode.Decimal:
|
||||
readArrayMethod = "TryReadDecimalArray";
|
||||
break;
|
||||
case TypeCode.Int32:
|
||||
readArrayMethod = "TryReadInt32Array";
|
||||
break;
|
||||
case TypeCode.Int64:
|
||||
readArrayMethod = "TryReadInt64Array";
|
||||
break;
|
||||
case TypeCode.Single:
|
||||
readArrayMethod = "TryReadSingleArray";
|
||||
break;
|
||||
case TypeCode.Double:
|
||||
readArrayMethod = "TryReadDoubleArray";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (readArrayMethod != null)
|
||||
{
|
||||
ilg.Load(xmlReaderArg);
|
||||
ilg.Load(contextArg);
|
||||
ilg.Load(memberNamesArg);
|
||||
ilg.Load(memberNamespacesArg);
|
||||
ilg.Load(size);
|
||||
ilg.Ldloca(objectLocal);
|
||||
ilg.Call(typeof(XmlReaderDelegator).GetMethod(readArrayMethod, Globals.ScanAllMembers));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private LocalBuilder ReadCollectionItem(CollectionDataContract collectionContract, Type itemType, string itemName, string itemNs)
|
||||
{
|
||||
if (collectionContract.Kind == CollectionKind.Dictionary || collectionContract.Kind == CollectionKind.GenericDictionary)
|
||||
{
|
||||
ilg.Call(contextArg, XmlFormatGeneratorStatics.ResetAttributesMethod);
|
||||
LocalBuilder value = ilg.DeclareLocal(itemType, "valueRead");
|
||||
ilg.Load(collectionContractArg);
|
||||
ilg.Call(XmlFormatGeneratorStatics.GetItemContractMethod);
|
||||
ilg.Load(xmlReaderArg);
|
||||
ilg.Load(contextArg);
|
||||
ilg.Call(XmlFormatGeneratorStatics.ReadXmlValueMethod);
|
||||
ilg.ConvertValue(Globals.TypeOfObject, itemType);
|
||||
ilg.Stloc(value);
|
||||
return value;
|
||||
}
|
||||
else
|
||||
{
|
||||
return ReadValue(itemType, itemName, itemNs);
|
||||
}
|
||||
}
|
||||
|
||||
private void StoreCollectionValue(LocalBuilder collection, LocalBuilder value, CollectionDataContract collectionContract)
|
||||
{
|
||||
if (collectionContract.Kind == CollectionKind.GenericDictionary || collectionContract.Kind == CollectionKind.Dictionary)
|
||||
{
|
||||
ClassDataContract keyValuePairContract = DataContract.GetDataContract(value.LocalType) as ClassDataContract;
|
||||
if (keyValuePairContract == null)
|
||||
{
|
||||
Fx.Assert("Failed to create contract for KeyValuePair type");
|
||||
}
|
||||
DataMember keyMember = keyValuePairContract.Members[0];
|
||||
DataMember valueMember = keyValuePairContract.Members[1];
|
||||
LocalBuilder pairKey = ilg.DeclareLocal(keyMember.MemberType, keyMember.Name);
|
||||
LocalBuilder pairValue = ilg.DeclareLocal(valueMember.MemberType, valueMember.Name);
|
||||
ilg.LoadAddress(value);
|
||||
ilg.LoadMember(keyMember.MemberInfo);
|
||||
ilg.Stloc(pairKey);
|
||||
ilg.LoadAddress(value);
|
||||
ilg.LoadMember(valueMember.MemberInfo);
|
||||
ilg.Stloc(pairValue);
|
||||
|
||||
ilg.Call(collection, collectionContract.AddMethod, pairKey, pairValue);
|
||||
if (collectionContract.AddMethod.ReturnType != Globals.TypeOfVoid)
|
||||
{
|
||||
ilg.Pop();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ilg.Call(collection, collectionContract.AddMethod, value);
|
||||
if (collectionContract.AddMethod.ReturnType != Globals.TypeOfVoid)
|
||||
{
|
||||
ilg.Pop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void HandleUnexpectedItemInCollection(LocalBuilder iterator)
|
||||
{
|
||||
IsStartElement();
|
||||
ilg.If();
|
||||
ilg.Call(contextArg, XmlFormatGeneratorStatics.SkipUnknownElementMethod, xmlReaderArg);
|
||||
ilg.Dec(iterator);
|
||||
ilg.Else();
|
||||
ThrowUnexpectedStateException(XmlNodeType.Element);
|
||||
ilg.EndIf();
|
||||
}
|
||||
|
||||
private void IsStartElement(ArgBuilder nameArg, ArgBuilder nsArg)
|
||||
{
|
||||
ilg.Call(xmlReaderArg, XmlFormatGeneratorStatics.IsStartElementMethod2, nameArg, nsArg);
|
||||
}
|
||||
|
||||
private void IsStartElement()
|
||||
{
|
||||
ilg.Call(xmlReaderArg, XmlFormatGeneratorStatics.IsStartElementMethod0);
|
||||
}
|
||||
|
||||
private void IsEndElement()
|
||||
{
|
||||
ilg.Load(xmlReaderArg);
|
||||
ilg.LoadMember(XmlFormatGeneratorStatics.NodeTypeProperty);
|
||||
ilg.Load(XmlNodeType.EndElement);
|
||||
ilg.Ceq();
|
||||
}
|
||||
|
||||
private void ThrowUnexpectedStateException(XmlNodeType expectedState)
|
||||
{
|
||||
ilg.Call(null, XmlFormatGeneratorStatics.CreateUnexpectedStateExceptionMethod, expectedState, xmlReaderArg);
|
||||
ilg.Throw();
|
||||
}
|
||||
|
||||
private void ThrowValidationException(string msg, params object[] values)
|
||||
{
|
||||
if (values != null && values.Length > 0)
|
||||
{
|
||||
ilg.CallStringFormat(msg, values);
|
||||
}
|
||||
else
|
||||
{
|
||||
ilg.Load(msg);
|
||||
}
|
||||
|
||||
ThrowValidationException();
|
||||
}
|
||||
|
||||
private void ThrowValidationException()
|
||||
{
|
||||
ilg.New(XmlFormatGeneratorStatics.SerializationExceptionCtor);
|
||||
ilg.Throw();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
internal static object UnsafeGetUninitializedObject(int id)
|
||||
{
|
||||
return System.Runtime.Serialization.FormatterServices.GetUninitializedObject(DataContract.GetDataContractForInitialization(id).TypeForInitialization);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,743 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using System.Reflection.Emit;
|
||||
using System.Security;
|
||||
using System.Security.Permissions;
|
||||
using System.Xml;
|
||||
|
||||
namespace Compat.Runtime.Serialization
|
||||
{
|
||||
internal delegate void XmlFormatClassWriterDelegate(XmlWriterDelegator xmlWriter, object obj, XmlObjectSerializerWriteContext context, ClassDataContract dataContract);
|
||||
internal delegate void XmlFormatCollectionWriterDelegate(XmlWriterDelegator xmlWriter, object obj, XmlObjectSerializerWriteContext context, CollectionDataContract dataContract);
|
||||
|
||||
internal sealed class XmlFormatWriterGenerator
|
||||
{
|
||||
CriticalHelper _helper;
|
||||
|
||||
public XmlFormatWriterGenerator()
|
||||
{
|
||||
_helper = new CriticalHelper();
|
||||
}
|
||||
|
||||
internal XmlFormatClassWriterDelegate GenerateClassWriter(ClassDataContract classContract)
|
||||
{
|
||||
return _helper.GenerateClassWriter(classContract);
|
||||
}
|
||||
|
||||
internal XmlFormatCollectionWriterDelegate GenerateCollectionWriter(CollectionDataContract collectionContract)
|
||||
{
|
||||
return _helper.GenerateCollectionWriter(collectionContract);
|
||||
}
|
||||
|
||||
class CriticalHelper
|
||||
{
|
||||
CodeGenerator ilg;
|
||||
ArgBuilder xmlWriterArg;
|
||||
ArgBuilder contextArg;
|
||||
ArgBuilder dataContractArg;
|
||||
LocalBuilder objectLocal;
|
||||
|
||||
// Used for classes
|
||||
LocalBuilder contractNamespacesLocal;
|
||||
LocalBuilder memberNamesLocal;
|
||||
LocalBuilder childElementNamespacesLocal;
|
||||
int typeIndex = 1;
|
||||
int childElementIndex = 0;
|
||||
|
||||
internal XmlFormatClassWriterDelegate GenerateClassWriter(ClassDataContract classContract)
|
||||
{
|
||||
ilg = new CodeGenerator();
|
||||
bool memberAccessFlag = classContract.RequiresMemberAccessForWrite(null);
|
||||
ilg.BeginMethod("Write" + classContract.StableName.Name + "ToXml", Globals.TypeOfXmlFormatClassWriterDelegate, memberAccessFlag);
|
||||
InitArgs(classContract.UnderlyingType);
|
||||
if (classContract.IsReadOnlyContract)
|
||||
{
|
||||
ThrowIfCannotSerializeReadOnlyTypes(classContract);
|
||||
}
|
||||
WriteClass(classContract);
|
||||
return (XmlFormatClassWriterDelegate)ilg.EndMethod();
|
||||
}
|
||||
|
||||
internal XmlFormatCollectionWriterDelegate GenerateCollectionWriter(CollectionDataContract collectionContract)
|
||||
{
|
||||
ilg = new CodeGenerator();
|
||||
bool memberAccessFlag = collectionContract.RequiresMemberAccessForWrite(null);
|
||||
ilg.BeginMethod("Write" + collectionContract.StableName.Name + "ToXml", Globals.TypeOfXmlFormatCollectionWriterDelegate, memberAccessFlag);
|
||||
InitArgs(collectionContract.UnderlyingType);
|
||||
if (collectionContract.IsReadOnlyContract)
|
||||
{
|
||||
ThrowIfCannotSerializeReadOnlyTypes(collectionContract);
|
||||
}
|
||||
WriteCollection(collectionContract);
|
||||
return (XmlFormatCollectionWriterDelegate)ilg.EndMethod();
|
||||
}
|
||||
|
||||
void InitArgs(Type objType)
|
||||
{
|
||||
xmlWriterArg = ilg.GetArg(0);
|
||||
contextArg = ilg.GetArg(2);
|
||||
dataContractArg = ilg.GetArg(3);
|
||||
|
||||
objectLocal = ilg.DeclareLocal(objType, "objSerialized");
|
||||
ArgBuilder objectArg = ilg.GetArg(1);
|
||||
ilg.Load(objectArg);
|
||||
|
||||
// Copy the data from the DataTimeOffset object passed in to the DateTimeOffsetAdapter.
|
||||
// DateTimeOffsetAdapter is used here for serialization purposes to bypass the ISerializable implementation
|
||||
// on DateTimeOffset; which does not work in partial trust.
|
||||
|
||||
if (objType == Globals.TypeOfDateTimeOffsetAdapter)
|
||||
{
|
||||
ilg.ConvertValue(objectArg.ArgType, Globals.TypeOfDateTimeOffset);
|
||||
ilg.Call(XmlFormatGeneratorStatics.GetDateTimeOffsetAdapterMethod);
|
||||
}
|
||||
else
|
||||
{
|
||||
ilg.ConvertValue(objectArg.ArgType, objType);
|
||||
}
|
||||
ilg.Stloc(objectLocal);
|
||||
}
|
||||
|
||||
void ThrowIfCannotSerializeReadOnlyTypes(ClassDataContract classContract)
|
||||
{
|
||||
ThrowIfCannotSerializeReadOnlyTypes(XmlFormatGeneratorStatics.ClassSerializationExceptionMessageProperty);
|
||||
}
|
||||
|
||||
void ThrowIfCannotSerializeReadOnlyTypes(CollectionDataContract classContract)
|
||||
{
|
||||
ThrowIfCannotSerializeReadOnlyTypes(XmlFormatGeneratorStatics.CollectionSerializationExceptionMessageProperty);
|
||||
}
|
||||
|
||||
void ThrowIfCannotSerializeReadOnlyTypes(PropertyInfo serializationExceptionMessageProperty)
|
||||
{
|
||||
ilg.Load(contextArg);
|
||||
ilg.LoadMember(XmlFormatGeneratorStatics.SerializeReadOnlyTypesProperty);
|
||||
ilg.IfNot();
|
||||
ilg.Load(dataContractArg);
|
||||
ilg.LoadMember(serializationExceptionMessageProperty);
|
||||
ilg.Load(null);
|
||||
ilg.Call(XmlFormatGeneratorStatics.ThrowInvalidDataContractExceptionMethod);
|
||||
ilg.EndIf();
|
||||
}
|
||||
|
||||
void InvokeOnSerializing(ClassDataContract classContract)
|
||||
{
|
||||
if (classContract.BaseContract != null)
|
||||
InvokeOnSerializing(classContract.BaseContract);
|
||||
if (classContract.OnSerializing != null)
|
||||
{
|
||||
ilg.LoadAddress(objectLocal);
|
||||
ilg.Load(contextArg);
|
||||
ilg.Call(XmlFormatGeneratorStatics.GetStreamingContextMethod);
|
||||
ilg.Call(classContract.OnSerializing);
|
||||
}
|
||||
}
|
||||
|
||||
void InvokeOnSerialized(ClassDataContract classContract)
|
||||
{
|
||||
if (classContract.BaseContract != null)
|
||||
InvokeOnSerialized(classContract.BaseContract);
|
||||
if (classContract.OnSerialized != null)
|
||||
{
|
||||
ilg.LoadAddress(objectLocal);
|
||||
ilg.Load(contextArg);
|
||||
ilg.Call(XmlFormatGeneratorStatics.GetStreamingContextMethod);
|
||||
ilg.Call(classContract.OnSerialized);
|
||||
}
|
||||
}
|
||||
|
||||
void WriteClass(ClassDataContract classContract)
|
||||
{
|
||||
InvokeOnSerializing(classContract);
|
||||
|
||||
if (classContract.IsISerializable)
|
||||
ilg.Call(contextArg, XmlFormatGeneratorStatics.WriteISerializableMethod, xmlWriterArg, objectLocal);
|
||||
else
|
||||
{
|
||||
if (classContract.ContractNamespaces.Length > 1)
|
||||
{
|
||||
contractNamespacesLocal = ilg.DeclareLocal(typeof(XmlDictionaryString[]), "contractNamespaces");
|
||||
ilg.Load(dataContractArg);
|
||||
ilg.LoadMember(XmlFormatGeneratorStatics.ContractNamespacesField);
|
||||
ilg.Store(contractNamespacesLocal);
|
||||
}
|
||||
|
||||
memberNamesLocal = ilg.DeclareLocal(typeof(XmlDictionaryString[]), "memberNames");
|
||||
ilg.Load(dataContractArg);
|
||||
ilg.LoadMember(XmlFormatGeneratorStatics.MemberNamesField);
|
||||
ilg.Store(memberNamesLocal);
|
||||
|
||||
for (int i = 0; i < classContract.ChildElementNamespaces.Length; i++)
|
||||
{
|
||||
if (classContract.ChildElementNamespaces[i] != null)
|
||||
{
|
||||
childElementNamespacesLocal = ilg.DeclareLocal(typeof(XmlDictionaryString[]), "childElementNamespaces");
|
||||
ilg.Load(dataContractArg);
|
||||
ilg.LoadMember(XmlFormatGeneratorStatics.ChildElementNamespacesProperty);
|
||||
ilg.Store(childElementNamespacesLocal);
|
||||
}
|
||||
}
|
||||
|
||||
if (classContract.HasExtensionData)
|
||||
{
|
||||
LocalBuilder extensionDataLocal = ilg.DeclareLocal(Globals.TypeOfExtensionDataObject, "extensionData");
|
||||
ilg.Load(objectLocal);
|
||||
ilg.ConvertValue(objectLocal.LocalType, Globals.TypeOfIExtensibleDataObject);
|
||||
ilg.LoadMember(XmlFormatGeneratorStatics.ExtensionDataProperty);
|
||||
ilg.Store(extensionDataLocal);
|
||||
ilg.Call(contextArg, XmlFormatGeneratorStatics.WriteExtensionDataMethod, xmlWriterArg, extensionDataLocal, -1);
|
||||
WriteMembers(classContract, extensionDataLocal, classContract);
|
||||
}
|
||||
else
|
||||
WriteMembers(classContract, null, classContract);
|
||||
}
|
||||
InvokeOnSerialized(classContract);
|
||||
}
|
||||
|
||||
int WriteMembers(ClassDataContract classContract, LocalBuilder extensionDataLocal, ClassDataContract derivedMostClassContract)
|
||||
{
|
||||
int memberCount = (classContract.BaseContract == null) ? 0 :
|
||||
WriteMembers(classContract.BaseContract, extensionDataLocal, derivedMostClassContract);
|
||||
|
||||
LocalBuilder namespaceLocal = ilg.DeclareLocal(typeof(XmlDictionaryString), "ns");
|
||||
if (contractNamespacesLocal == null)
|
||||
{
|
||||
ilg.Load(dataContractArg);
|
||||
ilg.LoadMember(XmlFormatGeneratorStatics.NamespaceProperty);
|
||||
}
|
||||
else
|
||||
ilg.LoadArrayElement(contractNamespacesLocal, typeIndex - 1);
|
||||
ilg.Store(namespaceLocal);
|
||||
|
||||
ilg.Call(contextArg, XmlFormatGeneratorStatics.IncrementItemCountMethod, classContract.Members.Count);
|
||||
|
||||
for (int i = 0; i < classContract.Members.Count; i++, memberCount++)
|
||||
{
|
||||
DataMember member = classContract.Members[i];
|
||||
Type memberType = member.MemberType;
|
||||
LocalBuilder memberValue = null;
|
||||
if (member.IsGetOnlyCollection)
|
||||
{
|
||||
ilg.Load(contextArg);
|
||||
ilg.Call(XmlFormatGeneratorStatics.StoreIsGetOnlyCollectionMethod);
|
||||
}
|
||||
if (!member.EmitDefaultValue)
|
||||
{
|
||||
memberValue = LoadMemberValue(member);
|
||||
ilg.IfNotDefaultValue(memberValue);
|
||||
}
|
||||
bool writeXsiType = CheckIfMemberHasConflict(member, classContract, derivedMostClassContract);
|
||||
if (writeXsiType || !TryWritePrimitive(memberType, memberValue, member.MemberInfo, null /*arrayItemIndex*/, namespaceLocal, null /*nameLocal*/, i + childElementIndex))
|
||||
{
|
||||
WriteStartElement(memberType, classContract.Namespace, namespaceLocal, null /*nameLocal*/, i + childElementIndex);
|
||||
if (classContract.ChildElementNamespaces[i + childElementIndex] != null)
|
||||
{
|
||||
ilg.Load(xmlWriterArg);
|
||||
ilg.LoadArrayElement(childElementNamespacesLocal, i + childElementIndex);
|
||||
ilg.Call(XmlFormatGeneratorStatics.WriteNamespaceDeclMethod);
|
||||
}
|
||||
if (memberValue == null)
|
||||
memberValue = LoadMemberValue(member);
|
||||
WriteValue(memberValue, writeXsiType);
|
||||
WriteEndElement();
|
||||
}
|
||||
if (classContract.HasExtensionData)
|
||||
ilg.Call(contextArg, XmlFormatGeneratorStatics.WriteExtensionDataMethod, xmlWriterArg, extensionDataLocal, memberCount);
|
||||
if (!member.EmitDefaultValue)
|
||||
{
|
||||
if (member.IsRequired)
|
||||
{
|
||||
ilg.Else();
|
||||
ilg.Call(null, XmlFormatGeneratorStatics.ThrowRequiredMemberMustBeEmittedMethod, member.Name, classContract.UnderlyingType);
|
||||
}
|
||||
ilg.EndIf();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
typeIndex++;
|
||||
childElementIndex += classContract.Members.Count;
|
||||
return memberCount;
|
||||
}
|
||||
|
||||
private LocalBuilder LoadMemberValue(DataMember member)
|
||||
{
|
||||
ilg.LoadAddress(objectLocal);
|
||||
ilg.LoadMember(member.MemberInfo);
|
||||
LocalBuilder memberValue = ilg.DeclareLocal(member.MemberType, member.Name + "Value");
|
||||
ilg.Stloc(memberValue);
|
||||
return memberValue;
|
||||
}
|
||||
|
||||
void WriteCollection(CollectionDataContract collectionContract)
|
||||
{
|
||||
LocalBuilder itemNamespace = ilg.DeclareLocal(typeof(XmlDictionaryString), "itemNamespace");
|
||||
ilg.Load(dataContractArg);
|
||||
ilg.LoadMember(XmlFormatGeneratorStatics.NamespaceProperty);
|
||||
ilg.Store(itemNamespace);
|
||||
|
||||
LocalBuilder itemName = ilg.DeclareLocal(typeof(XmlDictionaryString), "itemName");
|
||||
ilg.Load(dataContractArg);
|
||||
ilg.LoadMember(XmlFormatGeneratorStatics.CollectionItemNameProperty);
|
||||
ilg.Store(itemName);
|
||||
|
||||
if (collectionContract.ChildElementNamespace != null)
|
||||
{
|
||||
ilg.Load(xmlWriterArg);
|
||||
ilg.Load(dataContractArg);
|
||||
ilg.LoadMember(XmlFormatGeneratorStatics.ChildElementNamespaceProperty);
|
||||
ilg.Call(XmlFormatGeneratorStatics.WriteNamespaceDeclMethod);
|
||||
}
|
||||
|
||||
if (collectionContract.Kind == CollectionKind.Array)
|
||||
{
|
||||
Type itemType = collectionContract.ItemType;
|
||||
LocalBuilder i = ilg.DeclareLocal(Globals.TypeOfInt, "i");
|
||||
|
||||
ilg.Call(contextArg, XmlFormatGeneratorStatics.IncrementArrayCountMethod, xmlWriterArg, objectLocal);
|
||||
|
||||
if (!TryWritePrimitiveArray(collectionContract.UnderlyingType, itemType, objectLocal, itemName, itemNamespace))
|
||||
{
|
||||
ilg.For(i, 0, objectLocal);
|
||||
if (!TryWritePrimitive(itemType, null /*value*/, null /*memberInfo*/, i /*arrayItemIndex*/, itemNamespace, itemName, 0 /*nameIndex*/))
|
||||
{
|
||||
WriteStartElement(itemType, collectionContract.Namespace, itemNamespace, itemName, 0 /*nameIndex*/);
|
||||
ilg.LoadArrayElement(objectLocal, i);
|
||||
LocalBuilder memberValue = ilg.DeclareLocal(itemType, "memberValue");
|
||||
ilg.Stloc(memberValue);
|
||||
WriteValue(memberValue, false /*writeXsiType*/);
|
||||
WriteEndElement();
|
||||
}
|
||||
ilg.EndFor();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
MethodInfo incrementCollectionCountMethod = null;
|
||||
switch (collectionContract.Kind)
|
||||
{
|
||||
case CollectionKind.Collection:
|
||||
case CollectionKind.List:
|
||||
case CollectionKind.Dictionary:
|
||||
incrementCollectionCountMethod = XmlFormatGeneratorStatics.IncrementCollectionCountMethod;
|
||||
break;
|
||||
case CollectionKind.GenericCollection:
|
||||
case CollectionKind.GenericList:
|
||||
incrementCollectionCountMethod = XmlFormatGeneratorStatics.IncrementCollectionCountGenericMethod.MakeGenericMethod(collectionContract.ItemType);
|
||||
break;
|
||||
case CollectionKind.GenericDictionary:
|
||||
incrementCollectionCountMethod = XmlFormatGeneratorStatics.IncrementCollectionCountGenericMethod.MakeGenericMethod(Globals.TypeOfKeyValuePair.MakeGenericType(collectionContract.ItemType.GetGenericArguments()));
|
||||
break;
|
||||
}
|
||||
if (incrementCollectionCountMethod != null)
|
||||
{
|
||||
ilg.Call(contextArg, incrementCollectionCountMethod, xmlWriterArg, objectLocal);
|
||||
}
|
||||
|
||||
bool isDictionary = false, isGenericDictionary = false;
|
||||
Type enumeratorType = null;
|
||||
Type[] keyValueTypes = null;
|
||||
if (collectionContract.Kind == CollectionKind.GenericDictionary)
|
||||
{
|
||||
isGenericDictionary = true;
|
||||
keyValueTypes = collectionContract.ItemType.GetGenericArguments();
|
||||
enumeratorType = Globals.TypeOfGenericDictionaryEnumerator.MakeGenericType(keyValueTypes);
|
||||
}
|
||||
else if (collectionContract.Kind == CollectionKind.Dictionary)
|
||||
{
|
||||
isDictionary = true;
|
||||
keyValueTypes = new Type[] { Globals.TypeOfObject, Globals.TypeOfObject };
|
||||
enumeratorType = Globals.TypeOfDictionaryEnumerator;
|
||||
}
|
||||
else
|
||||
{
|
||||
enumeratorType = collectionContract.GetEnumeratorMethod.ReturnType;
|
||||
}
|
||||
MethodInfo moveNextMethod = enumeratorType.GetMethod(Globals.MoveNextMethodName, BindingFlags.Instance | BindingFlags.Public, null, Globals.EmptyTypeArray, null);
|
||||
MethodInfo getCurrentMethod = enumeratorType.GetMethod(Globals.GetCurrentMethodName, BindingFlags.Instance | BindingFlags.Public, null, Globals.EmptyTypeArray, null);
|
||||
if (moveNextMethod == null || getCurrentMethod == null)
|
||||
{
|
||||
if (enumeratorType.IsInterface)
|
||||
{
|
||||
if (moveNextMethod == null)
|
||||
moveNextMethod = XmlFormatGeneratorStatics.MoveNextMethod;
|
||||
if (getCurrentMethod == null)
|
||||
getCurrentMethod = XmlFormatGeneratorStatics.GetCurrentMethod;
|
||||
}
|
||||
else
|
||||
{
|
||||
Type ienumeratorInterface = Globals.TypeOfIEnumerator;
|
||||
CollectionKind kind = collectionContract.Kind;
|
||||
if (kind == CollectionKind.GenericDictionary || kind == CollectionKind.GenericCollection || kind == CollectionKind.GenericEnumerable)
|
||||
{
|
||||
Type[] interfaceTypes = enumeratorType.GetInterfaces();
|
||||
foreach (Type interfaceType in interfaceTypes)
|
||||
{
|
||||
if (interfaceType.IsGenericType
|
||||
&& interfaceType.GetGenericTypeDefinition() == Globals.TypeOfIEnumeratorGeneric
|
||||
&& interfaceType.GetGenericArguments()[0] == collectionContract.ItemType)
|
||||
{
|
||||
ienumeratorInterface = interfaceType;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (moveNextMethod == null)
|
||||
moveNextMethod = CollectionDataContract.GetTargetMethodWithName(Globals.MoveNextMethodName, enumeratorType, ienumeratorInterface);
|
||||
if (getCurrentMethod == null)
|
||||
getCurrentMethod = CollectionDataContract.GetTargetMethodWithName(Globals.GetCurrentMethodName, enumeratorType, ienumeratorInterface);
|
||||
}
|
||||
}
|
||||
Type elementType = getCurrentMethod.ReturnType;
|
||||
LocalBuilder currentValue = ilg.DeclareLocal(elementType, "currentValue");
|
||||
|
||||
LocalBuilder enumerator = ilg.DeclareLocal(enumeratorType, "enumerator");
|
||||
ilg.Call(objectLocal, collectionContract.GetEnumeratorMethod);
|
||||
if (isDictionary)
|
||||
{
|
||||
ilg.ConvertValue(collectionContract.GetEnumeratorMethod.ReturnType, Globals.TypeOfIDictionaryEnumerator);
|
||||
ilg.New(XmlFormatGeneratorStatics.DictionaryEnumeratorCtor);
|
||||
}
|
||||
else if (isGenericDictionary)
|
||||
{
|
||||
Type ctorParam = Globals.TypeOfIEnumeratorGeneric.MakeGenericType(Globals.TypeOfKeyValuePair.MakeGenericType(keyValueTypes));
|
||||
ConstructorInfo dictEnumCtor = enumeratorType.GetConstructor(Globals.ScanAllMembers, null, new Type[] { ctorParam }, null);
|
||||
ilg.ConvertValue(collectionContract.GetEnumeratorMethod.ReturnType, ctorParam);
|
||||
ilg.New(dictEnumCtor);
|
||||
}
|
||||
ilg.Stloc(enumerator);
|
||||
|
||||
ilg.ForEach(currentValue, elementType, enumeratorType, enumerator, getCurrentMethod);
|
||||
if (incrementCollectionCountMethod == null)
|
||||
{
|
||||
ilg.Call(contextArg, XmlFormatGeneratorStatics.IncrementItemCountMethod, 1);
|
||||
}
|
||||
if (!TryWritePrimitive(elementType, currentValue, null /*memberInfo*/, null /*arrayItemIndex*/, itemNamespace, itemName, 0 /*nameIndex*/))
|
||||
{
|
||||
WriteStartElement(elementType, collectionContract.Namespace, itemNamespace, itemName, 0 /*nameIndex*/);
|
||||
|
||||
if (isGenericDictionary || isDictionary)
|
||||
{
|
||||
ilg.Call(dataContractArg, XmlFormatGeneratorStatics.GetItemContractMethod);
|
||||
ilg.Load(xmlWriterArg);
|
||||
ilg.Load(currentValue);
|
||||
ilg.ConvertValue(currentValue.LocalType, Globals.TypeOfObject);
|
||||
ilg.Load(contextArg);
|
||||
ilg.Call(XmlFormatGeneratorStatics.WriteXmlValueMethod);
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteValue(currentValue, false /*writeXsiType*/);
|
||||
}
|
||||
WriteEndElement();
|
||||
}
|
||||
ilg.EndForEach(moveNextMethod);
|
||||
}
|
||||
}
|
||||
|
||||
bool TryWritePrimitive(Type type, LocalBuilder value, MemberInfo memberInfo, LocalBuilder arrayItemIndex, LocalBuilder ns, LocalBuilder name, int nameIndex)
|
||||
{
|
||||
PrimitiveDataContract primitiveContract = PrimitiveDataContract.GetPrimitiveDataContract(type);
|
||||
if (primitiveContract == null || primitiveContract.UnderlyingType == Globals.TypeOfObject)
|
||||
return false;
|
||||
|
||||
// load xmlwriter
|
||||
if (type.IsValueType)
|
||||
{
|
||||
ilg.Load(xmlWriterArg);
|
||||
}
|
||||
else
|
||||
{
|
||||
ilg.Load(contextArg);
|
||||
ilg.Load(xmlWriterArg);
|
||||
}
|
||||
// load primitive value
|
||||
if (value != null)
|
||||
{
|
||||
ilg.Load(value);
|
||||
}
|
||||
else if (memberInfo != null)
|
||||
{
|
||||
ilg.LoadAddress(objectLocal);
|
||||
ilg.LoadMember(memberInfo);
|
||||
}
|
||||
else
|
||||
{
|
||||
ilg.LoadArrayElement(objectLocal, arrayItemIndex);
|
||||
}
|
||||
// load name
|
||||
if (name != null)
|
||||
{
|
||||
ilg.Load(name);
|
||||
}
|
||||
else
|
||||
{
|
||||
ilg.LoadArrayElement(memberNamesLocal, nameIndex);
|
||||
}
|
||||
// load namespace
|
||||
ilg.Load(ns);
|
||||
// call method to write primitive
|
||||
ilg.Call(primitiveContract.XmlFormatWriterMethod);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TryWritePrimitiveArray(Type type, Type itemType, LocalBuilder value, LocalBuilder itemName, LocalBuilder itemNamespace)
|
||||
{
|
||||
PrimitiveDataContract primitiveContract = PrimitiveDataContract.GetPrimitiveDataContract(itemType);
|
||||
if (primitiveContract == null)
|
||||
return false;
|
||||
|
||||
string writeArrayMethod = null;
|
||||
switch (Type.GetTypeCode(itemType))
|
||||
{
|
||||
case TypeCode.Boolean:
|
||||
writeArrayMethod = "WriteBooleanArray";
|
||||
break;
|
||||
case TypeCode.DateTime:
|
||||
writeArrayMethod = "WriteDateTimeArray";
|
||||
break;
|
||||
case TypeCode.Decimal:
|
||||
writeArrayMethod = "WriteDecimalArray";
|
||||
break;
|
||||
case TypeCode.Int32:
|
||||
writeArrayMethod = "WriteInt32Array";
|
||||
break;
|
||||
case TypeCode.Int64:
|
||||
writeArrayMethod = "WriteInt64Array";
|
||||
break;
|
||||
case TypeCode.Single:
|
||||
writeArrayMethod = "WriteSingleArray";
|
||||
break;
|
||||
case TypeCode.Double:
|
||||
writeArrayMethod = "WriteDoubleArray";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (writeArrayMethod != null)
|
||||
{
|
||||
ilg.Load(xmlWriterArg);
|
||||
ilg.Load(value);
|
||||
ilg.Load(itemName);
|
||||
ilg.Load(itemNamespace);
|
||||
ilg.Call(typeof(XmlWriterDelegator).GetMethod(writeArrayMethod, Globals.ScanAllMembers, null, new Type[] { type, typeof(XmlDictionaryString), typeof(XmlDictionaryString) }, null));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void WriteValue(LocalBuilder memberValue, bool writeXsiType)
|
||||
{
|
||||
Type memberType = memberValue.LocalType;
|
||||
if (memberType.IsPointer)
|
||||
{
|
||||
ilg.Load(memberValue);
|
||||
ilg.Load(memberType);
|
||||
ilg.Call(XmlFormatGeneratorStatics.BoxPointer);
|
||||
memberType = Globals.TypeOfReflectionPointer;
|
||||
memberValue = ilg.DeclareLocal(memberType, "memberValueRefPointer");
|
||||
ilg.Store(memberValue);
|
||||
}
|
||||
bool isNullableOfT = (memberType.IsGenericType &&
|
||||
memberType.GetGenericTypeDefinition() == Globals.TypeOfNullable);
|
||||
if (memberType.IsValueType && !isNullableOfT)
|
||||
{
|
||||
PrimitiveDataContract primitiveContract = PrimitiveDataContract.GetPrimitiveDataContract(memberType);
|
||||
if (primitiveContract != null && !writeXsiType)
|
||||
ilg.Call(xmlWriterArg, primitiveContract.XmlFormatContentWriterMethod, memberValue);
|
||||
else
|
||||
InternalSerialize(XmlFormatGeneratorStatics.InternalSerializeMethod, memberValue, memberType, writeXsiType);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (isNullableOfT)
|
||||
{
|
||||
memberValue = UnwrapNullableObject(memberValue); //Leaves !HasValue on stack
|
||||
memberType = memberValue.LocalType;
|
||||
}
|
||||
else
|
||||
{
|
||||
ilg.Load(memberValue);
|
||||
ilg.Load(null);
|
||||
ilg.Ceq();
|
||||
}
|
||||
ilg.If();
|
||||
ilg.Call(contextArg, XmlFormatGeneratorStatics.WriteNullMethod, xmlWriterArg, memberType, DataContract.IsTypeSerializable(memberType));
|
||||
ilg.Else();
|
||||
PrimitiveDataContract primitiveContract = PrimitiveDataContract.GetPrimitiveDataContract(memberType);
|
||||
if (primitiveContract != null && primitiveContract.UnderlyingType != Globals.TypeOfObject && !writeXsiType)
|
||||
{
|
||||
if (isNullableOfT)
|
||||
{
|
||||
ilg.Call(xmlWriterArg, primitiveContract.XmlFormatContentWriterMethod, memberValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
ilg.Call(contextArg, primitiveContract.XmlFormatContentWriterMethod, xmlWriterArg, memberValue);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (memberType == Globals.TypeOfObject || //boxed Nullable<T>
|
||||
memberType == Globals.TypeOfValueType ||
|
||||
((IList)Globals.TypeOfNullable.GetInterfaces()).Contains(memberType))
|
||||
{
|
||||
ilg.Load(memberValue);
|
||||
ilg.ConvertValue(memberValue.LocalType, Globals.TypeOfObject);
|
||||
memberValue = ilg.DeclareLocal(Globals.TypeOfObject, "unwrappedMemberValue");
|
||||
memberType = memberValue.LocalType;
|
||||
ilg.Stloc(memberValue);
|
||||
ilg.If(memberValue, Cmp.EqualTo, null);
|
||||
ilg.Call(contextArg, XmlFormatGeneratorStatics.WriteNullMethod, xmlWriterArg, memberType, DataContract.IsTypeSerializable(memberType));
|
||||
ilg.Else();
|
||||
}
|
||||
InternalSerialize((isNullableOfT ? XmlFormatGeneratorStatics.InternalSerializeMethod : XmlFormatGeneratorStatics.InternalSerializeReferenceMethod),
|
||||
memberValue, memberType, writeXsiType);
|
||||
|
||||
if (memberType == Globals.TypeOfObject) //boxed Nullable<T>
|
||||
ilg.EndIf();
|
||||
}
|
||||
ilg.EndIf();
|
||||
}
|
||||
}
|
||||
|
||||
void InternalSerialize(MethodInfo methodInfo, LocalBuilder memberValue, Type memberType, bool writeXsiType)
|
||||
{
|
||||
ilg.Load(contextArg);
|
||||
ilg.Load(xmlWriterArg);
|
||||
ilg.Load(memberValue);
|
||||
ilg.ConvertValue(memberValue.LocalType, Globals.TypeOfObject);
|
||||
LocalBuilder typeHandleValue = ilg.DeclareLocal(typeof(RuntimeTypeHandle), "typeHandleValue");
|
||||
ilg.Call(null, typeof(Type).GetMethod("GetTypeHandle"), memberValue);
|
||||
ilg.Stloc(typeHandleValue);
|
||||
ilg.LoadAddress(typeHandleValue);
|
||||
ilg.Ldtoken(memberType);
|
||||
ilg.Call(typeof(RuntimeTypeHandle).GetMethod("Equals", new Type[] { typeof(RuntimeTypeHandle) }));
|
||||
ilg.Load(writeXsiType);
|
||||
ilg.Load(DataContract.GetId(memberType.TypeHandle));
|
||||
ilg.Ldtoken(memberType);
|
||||
ilg.Call(methodInfo);
|
||||
}
|
||||
|
||||
|
||||
LocalBuilder UnwrapNullableObject(LocalBuilder memberValue)// Leaves !HasValue on stack
|
||||
{
|
||||
Type memberType = memberValue.LocalType;
|
||||
Label onNull = ilg.DefineLabel();
|
||||
Label end = ilg.DefineLabel();
|
||||
ilg.Load(memberValue);
|
||||
while (memberType.IsGenericType && memberType.GetGenericTypeDefinition() == Globals.TypeOfNullable)
|
||||
{
|
||||
Type innerType = memberType.GetGenericArguments()[0];
|
||||
ilg.Dup();
|
||||
ilg.Call(XmlFormatGeneratorStatics.GetHasValueMethod.MakeGenericMethod(innerType));
|
||||
ilg.Brfalse(onNull);
|
||||
ilg.Call(XmlFormatGeneratorStatics.GetNullableValueMethod.MakeGenericMethod(innerType));
|
||||
memberType = innerType;
|
||||
}
|
||||
memberValue = ilg.DeclareLocal(memberType, "nullableUnwrappedMemberValue");
|
||||
ilg.Stloc(memberValue);
|
||||
ilg.Load(false); //isNull
|
||||
ilg.Br(end);
|
||||
ilg.MarkLabel(onNull);
|
||||
ilg.Pop();
|
||||
ilg.Call(XmlFormatGeneratorStatics.GetDefaultValueMethod.MakeGenericMethod(memberType));
|
||||
ilg.Stloc(memberValue);
|
||||
ilg.Load(true); //isNull
|
||||
ilg.MarkLabel(end);
|
||||
return memberValue;
|
||||
}
|
||||
|
||||
bool NeedsPrefix(Type type, XmlDictionaryString ns)
|
||||
{
|
||||
return type == Globals.TypeOfXmlQualifiedName && (ns != null && ns.Value != null && ns.Value.Length > 0);
|
||||
}
|
||||
|
||||
void WriteStartElement(Type type, XmlDictionaryString ns, LocalBuilder namespaceLocal, LocalBuilder nameLocal, int nameIndex)
|
||||
{
|
||||
bool needsPrefix = NeedsPrefix(type, ns);
|
||||
ilg.Load(xmlWriterArg);
|
||||
// prefix
|
||||
if (needsPrefix)
|
||||
ilg.Load(Globals.ElementPrefix);
|
||||
|
||||
// localName
|
||||
if (nameLocal == null)
|
||||
ilg.LoadArrayElement(memberNamesLocal, nameIndex);
|
||||
else
|
||||
ilg.Load(nameLocal);
|
||||
|
||||
// namespace
|
||||
ilg.Load(namespaceLocal);
|
||||
|
||||
ilg.Call(needsPrefix ? XmlFormatGeneratorStatics.WriteStartElementMethod3 : XmlFormatGeneratorStatics.WriteStartElementMethod2);
|
||||
}
|
||||
|
||||
void WriteEndElement()
|
||||
{
|
||||
ilg.Call(xmlWriterArg, XmlFormatGeneratorStatics.WriteEndElementMethod);
|
||||
}
|
||||
|
||||
bool CheckIfMemberHasConflict(DataMember member, ClassDataContract classContract, ClassDataContract derivedMostClassContract)
|
||||
{
|
||||
// Check for conflict with base type members
|
||||
if (CheckIfConflictingMembersHaveDifferentTypes(member))
|
||||
return true;
|
||||
|
||||
// Check for conflict with derived type members
|
||||
string name = member.Name;
|
||||
string ns = classContract.StableName.Namespace;
|
||||
ClassDataContract currentContract = derivedMostClassContract;
|
||||
while (currentContract != null && currentContract != classContract)
|
||||
{
|
||||
if (ns == currentContract.StableName.Namespace)
|
||||
{
|
||||
List<DataMember> members = currentContract.Members;
|
||||
for (int j = 0; j < members.Count; j++)
|
||||
{
|
||||
if (name == members[j].Name)
|
||||
return CheckIfConflictingMembersHaveDifferentTypes(members[j]);
|
||||
}
|
||||
}
|
||||
currentContract = currentContract.BaseContract;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CheckIfConflictingMembersHaveDifferentTypes(DataMember member)
|
||||
{
|
||||
while (member.ConflictingMember != null)
|
||||
{
|
||||
if (member.MemberType != member.ConflictingMember.MemberType)
|
||||
return true;
|
||||
member = member.ConflictingMember;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
#if NotUsed
|
||||
static Hashtable nsToPrefixTable = new Hashtable(4);
|
||||
internal static string GetPrefix(string ns)
|
||||
{
|
||||
string prefix = (string)nsToPrefixTable[ns];
|
||||
if (prefix == null)
|
||||
{
|
||||
lock (nsToPrefixTable)
|
||||
{
|
||||
if (prefix == null)
|
||||
{
|
||||
prefix = "p" + nsToPrefixTable.Count;
|
||||
nsToPrefixTable.Add(ns, prefix);
|
||||
}
|
||||
}
|
||||
}
|
||||
return prefix;
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,418 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Text;
|
||||
using System.Xml;
|
||||
using DataContractResolver = System.Runtime.Serialization.DataContractResolver;
|
||||
using FormatterConverter = System.Runtime.Serialization.FormatterConverter;
|
||||
using IFormatterConverter = System.Runtime.Serialization.IFormatterConverter;
|
||||
using SerializationException = System.Runtime.Serialization.SerializationException;
|
||||
|
||||
namespace Compat.Runtime.Serialization
|
||||
{
|
||||
using DataContractDictionary = Dictionary<XmlQualifiedName, DataContract>;
|
||||
|
||||
public abstract class XmlObjectSerializer
|
||||
{
|
||||
public abstract void WriteStartObject(XmlDictionaryWriter writer, object graph);
|
||||
public abstract void WriteObjectContent(XmlDictionaryWriter writer, object graph);
|
||||
public abstract void WriteEndObject(XmlDictionaryWriter writer);
|
||||
|
||||
public virtual void WriteObject(Stream stream, object graph)
|
||||
{
|
||||
stream = stream ?? throw new ArgumentNullException(nameof(stream));
|
||||
XmlDictionaryWriter writer = XmlDictionaryWriter.CreateTextWriter(stream: stream, encoding: Encoding.UTF8, ownsStream: false);
|
||||
WriteObject(writer, graph);
|
||||
writer.Flush();
|
||||
}
|
||||
|
||||
public virtual void WriteObject(XmlWriter writer, object graph)
|
||||
{
|
||||
writer = writer ?? throw new ArgumentNullException(nameof(writer));
|
||||
WriteObject(XmlDictionaryWriter.CreateDictionaryWriter(writer), graph);
|
||||
}
|
||||
|
||||
public virtual void WriteStartObject(XmlWriter writer, object graph)
|
||||
{
|
||||
writer = writer ?? throw new ArgumentNullException(nameof(writer));
|
||||
WriteStartObject(XmlDictionaryWriter.CreateDictionaryWriter(writer), graph);
|
||||
}
|
||||
|
||||
public virtual void WriteObjectContent(XmlWriter writer, object graph)
|
||||
{
|
||||
writer = writer ?? throw new ArgumentNullException(nameof(writer));
|
||||
WriteObjectContent(XmlDictionaryWriter.CreateDictionaryWriter(writer), graph);
|
||||
}
|
||||
|
||||
public virtual void WriteEndObject(XmlWriter writer)
|
||||
{
|
||||
writer = writer ?? throw new ArgumentNullException(nameof(writer));
|
||||
WriteEndObject(XmlDictionaryWriter.CreateDictionaryWriter(writer));
|
||||
}
|
||||
|
||||
public virtual void WriteObject(XmlDictionaryWriter writer, object graph)
|
||||
{
|
||||
WriteObjectHandleExceptions(new XmlWriterDelegator(writer), graph);
|
||||
}
|
||||
|
||||
internal void WriteObjectHandleExceptions(XmlWriterDelegator writer, object graph)
|
||||
{
|
||||
WriteObjectHandleExceptions(writer, graph, null);
|
||||
}
|
||||
|
||||
internal void WriteObjectHandleExceptions(XmlWriterDelegator writer, object graph, DataContractResolver dataContractResolver)
|
||||
{
|
||||
try
|
||||
{
|
||||
writer = writer ?? throw new ArgumentNullException(nameof(writer));
|
||||
InternalWriteObject(writer, graph, dataContractResolver);
|
||||
}
|
||||
catch (XmlException ex)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(CreateSerializationException(GetTypeInfoError(SR.ErrorSerializing, GetSerializeType(graph), ex), ex));
|
||||
}
|
||||
catch (FormatException ex)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(CreateSerializationException(GetTypeInfoError(SR.ErrorSerializing, GetSerializeType(graph), ex), ex));
|
||||
}
|
||||
}
|
||||
|
||||
internal virtual DataContractDictionary KnownDataContracts => null;
|
||||
|
||||
internal virtual void InternalWriteObject(XmlWriterDelegator writer, object graph)
|
||||
{
|
||||
WriteStartObject(writer.Writer, graph);
|
||||
WriteObjectContent(writer.Writer, graph);
|
||||
WriteEndObject(writer.Writer);
|
||||
}
|
||||
|
||||
internal virtual void InternalWriteObject(XmlWriterDelegator writer, object graph, DataContractResolver dataContractResolver)
|
||||
{
|
||||
InternalWriteObject(writer, graph);
|
||||
}
|
||||
|
||||
internal virtual void InternalWriteStartObject(XmlWriterDelegator writer, object graph)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException());
|
||||
}
|
||||
internal virtual void InternalWriteObjectContent(XmlWriterDelegator writer, object graph)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException());
|
||||
}
|
||||
internal virtual void InternalWriteEndObject(XmlWriterDelegator writer)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException());
|
||||
}
|
||||
|
||||
internal void WriteStartObjectHandleExceptions(XmlWriterDelegator writer, object graph)
|
||||
{
|
||||
try
|
||||
{
|
||||
writer = writer ?? throw new ArgumentNullException(nameof(writer));
|
||||
InternalWriteStartObject(writer, graph);
|
||||
}
|
||||
catch (XmlException ex)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(GetTypeInfoError(SR.ErrorWriteStartObject, GetSerializeType(graph), ex), ex));
|
||||
}
|
||||
catch (FormatException ex)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(GetTypeInfoError(SR.ErrorWriteStartObject, GetSerializeType(graph), ex), ex));
|
||||
}
|
||||
}
|
||||
|
||||
internal void WriteObjectContentHandleExceptions(XmlWriterDelegator writer, object graph)
|
||||
{
|
||||
try
|
||||
{
|
||||
writer = writer ?? throw new ArgumentNullException(nameof(writer));
|
||||
if (writer.WriteState != WriteState.Element)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(SR.Format(SR.XmlWriterMustBeInElement, writer.WriteState)));
|
||||
}
|
||||
InternalWriteObjectContent(writer, graph);
|
||||
}
|
||||
catch (XmlException ex)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(GetTypeInfoError(SR.ErrorSerializing, GetSerializeType(graph), ex), ex));
|
||||
}
|
||||
catch (FormatException ex)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(GetTypeInfoError(SR.ErrorSerializing, GetSerializeType(graph), ex), ex));
|
||||
}
|
||||
}
|
||||
|
||||
internal void WriteEndObjectHandleExceptions(XmlWriterDelegator writer)
|
||||
{
|
||||
try
|
||||
{
|
||||
writer = writer ?? throw new ArgumentNullException(nameof(writer));
|
||||
InternalWriteEndObject(writer);
|
||||
}
|
||||
catch (XmlException ex)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(GetTypeInfoError(SR.ErrorWriteEndObject, null, ex), ex));
|
||||
}
|
||||
catch (FormatException ex)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(GetTypeInfoError(SR.ErrorWriteEndObject, null, ex), ex));
|
||||
}
|
||||
}
|
||||
|
||||
internal void WriteRootElement(XmlWriterDelegator writer, DataContract contract, XmlDictionaryString name, XmlDictionaryString ns, bool needsContractNsAtRoot)
|
||||
{
|
||||
if (name == null) // root name not set explicitly
|
||||
{
|
||||
if (!contract.HasRoot)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
contract.WriteRootElement(writer, contract.TopLevelElementName, contract.TopLevelElementNamespace);
|
||||
}
|
||||
else
|
||||
{
|
||||
contract.WriteRootElement(writer, name, ns);
|
||||
if (needsContractNsAtRoot)
|
||||
{
|
||||
writer.WriteNamespaceDecl(contract.Namespace);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal bool CheckIfNeedsContractNsAtRoot(XmlDictionaryString name, XmlDictionaryString ns, DataContract contract)
|
||||
{
|
||||
if (name == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (contract.IsBuiltInDataContract || !contract.CanContainReferences || contract.IsISerializable)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
string contractNs = contract.Namespace?.Value;
|
||||
if (string.IsNullOrEmpty(contractNs) || contractNs == ns?.Value)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
internal static void WriteNull(XmlWriterDelegator writer)
|
||||
{
|
||||
writer.WriteAttributeBool(Globals.XsiPrefix, DictionaryGlobals.XsiNilLocalName, DictionaryGlobals.SchemaInstanceNamespace, true);
|
||||
}
|
||||
|
||||
internal static bool IsContractDeclared(DataContract contract, DataContract declaredContract)
|
||||
{
|
||||
return (object.ReferenceEquals(contract.Name, declaredContract.Name) && object.ReferenceEquals(contract.Namespace, declaredContract.Namespace))
|
||||
|| (contract.Name.Value == declaredContract.Name.Value && contract.Namespace.Value == declaredContract.Namespace.Value);
|
||||
}
|
||||
|
||||
public virtual object ReadObject(Stream stream)
|
||||
{
|
||||
stream = stream ?? throw new ArgumentNullException(nameof(stream));
|
||||
return ReadObject(XmlDictionaryReader.CreateTextReader(stream, XmlDictionaryReaderQuotas.Max));
|
||||
}
|
||||
|
||||
public virtual object ReadObject(XmlReader reader)
|
||||
{
|
||||
reader = reader ?? throw new ArgumentNullException(nameof(reader));
|
||||
return ReadObject(XmlDictionaryReader.CreateDictionaryReader(reader));
|
||||
}
|
||||
|
||||
public virtual object ReadObject(XmlDictionaryReader reader)
|
||||
{
|
||||
return ReadObjectHandleExceptions(new XmlReaderDelegator(reader), true /*verifyObjectName*/);
|
||||
}
|
||||
|
||||
public virtual object ReadObject(XmlReader reader, bool verifyObjectName)
|
||||
{
|
||||
reader = reader ?? throw new ArgumentNullException(nameof(reader));
|
||||
return ReadObject(XmlDictionaryReader.CreateDictionaryReader(reader), verifyObjectName);
|
||||
}
|
||||
|
||||
public abstract object ReadObject(XmlDictionaryReader reader, bool verifyObjectName);
|
||||
|
||||
public virtual bool IsStartObject(XmlReader reader)
|
||||
{
|
||||
reader = reader ?? throw new ArgumentNullException(nameof(reader));
|
||||
return IsStartObject(XmlDictionaryReader.CreateDictionaryReader(reader));
|
||||
}
|
||||
|
||||
public abstract bool IsStartObject(XmlDictionaryReader reader);
|
||||
|
||||
internal virtual object InternalReadObject(XmlReaderDelegator reader, bool verifyObjectName)
|
||||
{
|
||||
return ReadObject(reader.UnderlyingReader, verifyObjectName);
|
||||
}
|
||||
|
||||
internal virtual object InternalReadObject(XmlReaderDelegator reader, bool verifyObjectName, DataContractResolver dataContractResolver)
|
||||
{
|
||||
return InternalReadObject(reader, verifyObjectName);
|
||||
}
|
||||
|
||||
internal virtual bool InternalIsStartObject(XmlReaderDelegator reader)
|
||||
{
|
||||
Fx.Assert("XmlObjectSerializer.InternalIsStartObject should never get called");
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException());
|
||||
}
|
||||
|
||||
internal object ReadObjectHandleExceptions(XmlReaderDelegator reader, bool verifyObjectName)
|
||||
{
|
||||
return ReadObjectHandleExceptions(reader, verifyObjectName, null);
|
||||
}
|
||||
|
||||
internal object ReadObjectHandleExceptions(XmlReaderDelegator reader, bool verifyObjectName, DataContractResolver dataContractResolver)
|
||||
{
|
||||
try
|
||||
{
|
||||
reader = reader ?? throw new ArgumentNullException(nameof(reader));
|
||||
return InternalReadObject(reader, verifyObjectName, dataContractResolver);
|
||||
}
|
||||
catch (XmlException ex)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(GetTypeInfoError(SR.ErrorDeserializing, GetDeserializeType(), ex), ex));
|
||||
}
|
||||
catch (FormatException ex)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(GetTypeInfoError(SR.ErrorDeserializing, GetDeserializeType(), ex), ex));
|
||||
}
|
||||
}
|
||||
|
||||
internal bool IsStartObjectHandleExceptions(XmlReaderDelegator reader)
|
||||
{
|
||||
try
|
||||
{
|
||||
reader = reader ?? throw new ArgumentNullException(nameof(reader));
|
||||
return InternalIsStartObject(reader);
|
||||
}
|
||||
catch (XmlException ex)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(GetTypeInfoError(SR.ErrorIsStartObject, GetDeserializeType(), ex), ex));
|
||||
}
|
||||
catch (FormatException ex)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(GetTypeInfoError(SR.ErrorIsStartObject, GetDeserializeType(), ex), ex));
|
||||
}
|
||||
}
|
||||
|
||||
internal bool IsRootXmlAny(XmlDictionaryString rootName, DataContract contract)
|
||||
{
|
||||
return (rootName == null) && !contract.HasRoot;
|
||||
}
|
||||
|
||||
internal bool IsStartElement(XmlReaderDelegator reader)
|
||||
{
|
||||
return (reader.MoveToElement() || reader.IsStartElement());
|
||||
}
|
||||
|
||||
internal bool IsRootElement(XmlReaderDelegator reader, DataContract contract, XmlDictionaryString name, XmlDictionaryString ns)
|
||||
{
|
||||
reader.MoveToElement();
|
||||
if (name != null) // root name set explicitly
|
||||
{
|
||||
return reader.IsStartElement(name, ns);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!contract.HasRoot)
|
||||
{
|
||||
return reader.IsStartElement();
|
||||
}
|
||||
|
||||
if (reader.IsStartElement(contract.TopLevelElementName, contract.TopLevelElementNamespace))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
ClassDataContract classContract = contract as ClassDataContract;
|
||||
if (classContract != null)
|
||||
{
|
||||
classContract = classContract.BaseContract;
|
||||
}
|
||||
|
||||
while (classContract != null)
|
||||
{
|
||||
if (reader.IsStartElement(classContract.TopLevelElementName, classContract.TopLevelElementNamespace))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
classContract = classContract.BaseContract;
|
||||
}
|
||||
if (classContract == null)
|
||||
{
|
||||
DataContract objectContract = PrimitiveDataContract.GetPrimitiveDataContract(Globals.TypeOfObject);
|
||||
if (reader.IsStartElement(objectContract.TopLevelElementName, objectContract.TopLevelElementNamespace))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
internal static string TryAddLineInfo(XmlReaderDelegator reader, string errorMessage)
|
||||
{
|
||||
if (reader.HasLineInfo())
|
||||
{
|
||||
return string.Format(CultureInfo.InvariantCulture, "{0} {1}", SR.Format(SR.ErrorInLine, reader.LineNumber, reader.LinePosition), errorMessage);
|
||||
}
|
||||
|
||||
return errorMessage;
|
||||
}
|
||||
|
||||
internal static Exception CreateSerializationExceptionWithReaderDetails(string errorMessage, XmlReaderDelegator reader)
|
||||
{
|
||||
return XmlObjectSerializer.CreateSerializationException(TryAddLineInfo(reader, SR.Format(SR.EncounteredWithNameNamespace, errorMessage, reader.NodeType, reader.LocalName, reader.NamespaceURI)));
|
||||
}
|
||||
|
||||
internal static SerializationException CreateSerializationException(string errorMessage)
|
||||
{
|
||||
return XmlObjectSerializer.CreateSerializationException(errorMessage, null);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
internal static SerializationException CreateSerializationException(string errorMessage, Exception innerException)
|
||||
{
|
||||
return new SerializationException(errorMessage, innerException);
|
||||
}
|
||||
|
||||
private static string GetTypeInfoError(string errorMessage, Type type, Exception innerException)
|
||||
{
|
||||
string typeInfo = (type == null) ? string.Empty : SR.Format(SR.ErrorTypeInfo, DataContract.GetClrTypeFullName(type));
|
||||
string innerExceptionMessage = innerException?.Message ?? string.Empty;
|
||||
return SR.Format(errorMessage, typeInfo, innerExceptionMessage);
|
||||
}
|
||||
|
||||
internal virtual Type GetSerializeType(object graph)
|
||||
{
|
||||
return graph?.GetType();
|
||||
}
|
||||
|
||||
internal virtual Type GetDeserializeType()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
private static IFormatterConverter formatterConverter;
|
||||
internal static IFormatterConverter FormatterConverter
|
||||
{
|
||||
get
|
||||
{
|
||||
if (formatterConverter == null)
|
||||
{
|
||||
formatterConverter = new FormatterConverter();
|
||||
}
|
||||
|
||||
return formatterConverter;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,342 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using System.Security;
|
||||
using System.Xml;
|
||||
|
||||
namespace Compat.Runtime.Serialization
|
||||
{
|
||||
using DataContractDictionary = Dictionary<XmlQualifiedName, DataContract>;
|
||||
|
||||
internal class XmlObjectSerializerContext
|
||||
{
|
||||
|
||||
protected XmlObjectSerializer serializer;
|
||||
protected DataContract rootTypeDataContract;
|
||||
internal ScopedKnownTypes scopedKnownTypes = new ScopedKnownTypes();
|
||||
protected DataContractDictionary serializerKnownDataContracts;
|
||||
private bool isSerializerKnownDataContractsSetExplicit;
|
||||
protected IList<Type> serializerKnownTypeList;
|
||||
|
||||
private int itemCount;
|
||||
private readonly int maxItemsInObjectGraph;
|
||||
private System.Runtime.Serialization.StreamingContext streamingContext;
|
||||
private readonly bool ignoreExtensionDataObject;
|
||||
private readonly System.Runtime.Serialization.DataContractResolver dataContractResolver;
|
||||
private KnownTypeDataContractResolver knownTypeResolver;
|
||||
|
||||
internal XmlObjectSerializerContext(
|
||||
XmlObjectSerializer serializer,
|
||||
int maxItemsInObjectGraph,
|
||||
System.Runtime.Serialization.StreamingContext streamingContext,
|
||||
bool ignoreExtensionDataObject,
|
||||
System.Runtime.Serialization.DataContractResolver dataContractResolver)
|
||||
{
|
||||
this.serializer = serializer;
|
||||
itemCount = 1;
|
||||
this.maxItemsInObjectGraph = maxItemsInObjectGraph;
|
||||
this.streamingContext = streamingContext;
|
||||
this.ignoreExtensionDataObject = ignoreExtensionDataObject;
|
||||
this.dataContractResolver = dataContractResolver;
|
||||
}
|
||||
|
||||
internal XmlObjectSerializerContext(XmlObjectSerializer serializer,
|
||||
int maxItemsInObjectGraph,
|
||||
System.Runtime.Serialization.StreamingContext streamingContext,
|
||||
bool ignoreExtensionDataObject)
|
||||
: this(serializer, maxItemsInObjectGraph, streamingContext, ignoreExtensionDataObject, null)
|
||||
{
|
||||
}
|
||||
|
||||
internal XmlObjectSerializerContext(
|
||||
DataContractSerializer serializer,
|
||||
DataContract rootTypeDataContract,
|
||||
System.Runtime.Serialization.DataContractResolver dataContractResolver)
|
||||
: this(serializer,
|
||||
serializer.MaxItemsInObjectGraph,
|
||||
new System.Runtime.Serialization.StreamingContext(System.Runtime.Serialization.StreamingContextStates.All),
|
||||
serializer.IgnoreExtensionDataObject,
|
||||
dataContractResolver)
|
||||
{
|
||||
this.rootTypeDataContract = rootTypeDataContract;
|
||||
serializerKnownTypeList = serializer.knownTypeList;
|
||||
}
|
||||
|
||||
internal XmlObjectSerializerContext(NetDataContractSerializer serializer)
|
||||
: this(serializer,
|
||||
serializer.MaxItemsInObjectGraph,
|
||||
serializer.Context,
|
||||
serializer.IgnoreExtensionDataObject)
|
||||
{
|
||||
}
|
||||
|
||||
internal virtual SerializationMode Mode => SerializationMode.SharedContract;
|
||||
|
||||
internal virtual bool IsGetOnlyCollection
|
||||
{
|
||||
get => false;
|
||||
set { }
|
||||
}
|
||||
|
||||
public System.Runtime.Serialization.StreamingContext GetStreamingContext()
|
||||
{
|
||||
return streamingContext;
|
||||
}
|
||||
|
||||
private static MethodInfo incrementItemCountMethod;
|
||||
internal static MethodInfo IncrementItemCountMethod
|
||||
{
|
||||
get
|
||||
{
|
||||
if (incrementItemCountMethod == null)
|
||||
{
|
||||
incrementItemCountMethod = typeof(XmlObjectSerializerContext).GetMethod("IncrementItemCount", Globals.ScanAllMembers);
|
||||
}
|
||||
|
||||
return incrementItemCountMethod;
|
||||
}
|
||||
}
|
||||
public void IncrementItemCount(int count)
|
||||
{
|
||||
if (count > maxItemsInObjectGraph - itemCount)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(SR.Format(SR.ExceededMaxItemsQuota, maxItemsInObjectGraph)));
|
||||
}
|
||||
|
||||
itemCount += count;
|
||||
}
|
||||
|
||||
internal int RemainingItemCount => maxItemsInObjectGraph - itemCount;
|
||||
|
||||
internal bool IgnoreExtensionDataObject => ignoreExtensionDataObject;
|
||||
|
||||
protected System.Runtime.Serialization.DataContractResolver DataContractResolver => dataContractResolver;
|
||||
|
||||
protected KnownTypeDataContractResolver KnownTypeResolver
|
||||
{
|
||||
get
|
||||
{
|
||||
if (knownTypeResolver == null)
|
||||
{
|
||||
knownTypeResolver = new KnownTypeDataContractResolver(this);
|
||||
}
|
||||
return knownTypeResolver;
|
||||
}
|
||||
}
|
||||
|
||||
internal DataContract GetDataContract(Type type)
|
||||
{
|
||||
return GetDataContract(type.TypeHandle, type);
|
||||
}
|
||||
|
||||
internal virtual DataContract GetDataContract(RuntimeTypeHandle typeHandle, Type type)
|
||||
{
|
||||
if (IsGetOnlyCollection)
|
||||
{
|
||||
return DataContract.GetGetOnlyCollectionDataContract(DataContract.GetId(typeHandle), typeHandle, type, Mode);
|
||||
}
|
||||
else
|
||||
{
|
||||
return DataContract.GetDataContract(typeHandle, type, Mode);
|
||||
}
|
||||
}
|
||||
|
||||
internal virtual DataContract GetDataContractSkipValidation(int typeId, RuntimeTypeHandle typeHandle, Type type)
|
||||
{
|
||||
if (IsGetOnlyCollection)
|
||||
{
|
||||
return DataContract.GetGetOnlyCollectionDataContractSkipValidation(typeId, typeHandle, type);
|
||||
}
|
||||
else
|
||||
{
|
||||
return DataContract.GetDataContractSkipValidation(typeId, typeHandle, type);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
internal virtual DataContract GetDataContract(int id, RuntimeTypeHandle typeHandle)
|
||||
{
|
||||
if (IsGetOnlyCollection)
|
||||
{
|
||||
return DataContract.GetGetOnlyCollectionDataContract(id, typeHandle, null /*type*/, Mode);
|
||||
}
|
||||
else
|
||||
{
|
||||
return DataContract.GetDataContract(id, typeHandle, Mode);
|
||||
}
|
||||
}
|
||||
|
||||
internal virtual void CheckIfTypeSerializable(Type memberType, bool isMemberTypeSerializable)
|
||||
{
|
||||
if (!isMemberTypeSerializable)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new System.Runtime.Serialization.InvalidDataContractException(SR.Format(SR.TypeNotSerializable, memberType)));
|
||||
}
|
||||
}
|
||||
|
||||
internal virtual Type GetSurrogatedType(Type type)
|
||||
{
|
||||
return type;
|
||||
}
|
||||
|
||||
private DataContractDictionary SerializerKnownDataContracts
|
||||
{
|
||||
get
|
||||
{
|
||||
// This field must be initialized during construction by serializers using data contracts.
|
||||
if (!isSerializerKnownDataContractsSetExplicit)
|
||||
{
|
||||
serializerKnownDataContracts = serializer.KnownDataContracts;
|
||||
isSerializerKnownDataContractsSetExplicit = true;
|
||||
}
|
||||
return serializerKnownDataContracts;
|
||||
}
|
||||
}
|
||||
|
||||
private DataContract GetDataContractFromSerializerKnownTypes(XmlQualifiedName qname)
|
||||
{
|
||||
DataContractDictionary serializerKnownDataContracts = SerializerKnownDataContracts;
|
||||
if (serializerKnownDataContracts == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return serializerKnownDataContracts.TryGetValue(qname, out DataContract outDataContract) ? outDataContract : null;
|
||||
}
|
||||
|
||||
internal static DataContractDictionary GetDataContractsForKnownTypes(IList<Type> knownTypeList)
|
||||
{
|
||||
if (knownTypeList == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
DataContractDictionary dataContracts = new DataContractDictionary();
|
||||
Dictionary<Type, Type> typesChecked = new Dictionary<Type, Type>();
|
||||
for (int i = 0; i < knownTypeList.Count; i++)
|
||||
{
|
||||
Type knownType = knownTypeList[i];
|
||||
if (knownType == null)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(SR.Format(SR.NullKnownType, "knownTypes")));
|
||||
}
|
||||
|
||||
DataContract.CheckAndAdd(knownType, typesChecked, ref dataContracts);
|
||||
}
|
||||
return dataContracts;
|
||||
}
|
||||
|
||||
internal bool IsKnownType(DataContract dataContract, DataContractDictionary knownDataContracts, Type declaredType)
|
||||
{
|
||||
bool knownTypesAddedInCurrentScope = false;
|
||||
if (knownDataContracts != null)
|
||||
{
|
||||
scopedKnownTypes.Push(knownDataContracts);
|
||||
knownTypesAddedInCurrentScope = true;
|
||||
}
|
||||
|
||||
bool isKnownType = IsKnownType(dataContract, declaredType);
|
||||
|
||||
if (knownTypesAddedInCurrentScope)
|
||||
{
|
||||
scopedKnownTypes.Pop();
|
||||
}
|
||||
return isKnownType;
|
||||
}
|
||||
|
||||
internal bool IsKnownType(DataContract dataContract, Type declaredType)
|
||||
{
|
||||
DataContract knownContract = ResolveDataContractFromKnownTypes(dataContract.StableName.Name, dataContract.StableName.Namespace, null /*memberTypeContract*/, declaredType);
|
||||
return knownContract != null && knownContract.UnderlyingType == dataContract.UnderlyingType;
|
||||
}
|
||||
|
||||
private DataContract ResolveDataContractFromKnownTypes(XmlQualifiedName typeName)
|
||||
{
|
||||
DataContract dataContract = PrimitiveDataContract.GetPrimitiveDataContract(typeName.Name, typeName.Namespace);
|
||||
if (dataContract == null)
|
||||
{
|
||||
dataContract = scopedKnownTypes.GetDataContract(typeName);
|
||||
if (dataContract == null)
|
||||
{
|
||||
dataContract = GetDataContractFromSerializerKnownTypes(typeName);
|
||||
}
|
||||
}
|
||||
return dataContract;
|
||||
}
|
||||
|
||||
private DataContract ResolveDataContractFromDataContractResolver(XmlQualifiedName typeName, Type declaredType)
|
||||
{
|
||||
Type dataContractType = DataContractResolver.ResolveName(typeName.Name, typeName.Namespace, declaredType, KnownTypeResolver);
|
||||
if (dataContractType == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
else
|
||||
{
|
||||
return GetDataContract(dataContractType);
|
||||
}
|
||||
}
|
||||
|
||||
internal Type ResolveNameFromKnownTypes(XmlQualifiedName typeName)
|
||||
{
|
||||
DataContract dataContract = ResolveDataContractFromKnownTypes(typeName);
|
||||
if (dataContract == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
else
|
||||
{
|
||||
return dataContract.OriginalUnderlyingType;
|
||||
}
|
||||
}
|
||||
|
||||
protected DataContract ResolveDataContractFromKnownTypes(string typeName, string typeNs, DataContract memberTypeContract, Type declaredType)
|
||||
{
|
||||
XmlQualifiedName qname = new XmlQualifiedName(typeName, typeNs);
|
||||
DataContract dataContract;
|
||||
if (DataContractResolver == null)
|
||||
{
|
||||
dataContract = ResolveDataContractFromKnownTypes(qname);
|
||||
}
|
||||
else
|
||||
{
|
||||
dataContract = ResolveDataContractFromDataContractResolver(qname, declaredType);
|
||||
}
|
||||
if (dataContract == null)
|
||||
{
|
||||
if (memberTypeContract != null
|
||||
&& !memberTypeContract.UnderlyingType.IsInterface
|
||||
&& memberTypeContract.StableName == qname)
|
||||
{
|
||||
dataContract = memberTypeContract;
|
||||
}
|
||||
if (dataContract == null && rootTypeDataContract != null)
|
||||
{
|
||||
dataContract = ResolveDataContractFromRootDataContract(qname);
|
||||
}
|
||||
}
|
||||
return dataContract;
|
||||
}
|
||||
|
||||
protected virtual DataContract ResolveDataContractFromRootDataContract(XmlQualifiedName typeQName)
|
||||
{
|
||||
if (rootTypeDataContract.StableName == typeQName)
|
||||
{
|
||||
return rootTypeDataContract;
|
||||
}
|
||||
|
||||
CollectionDataContract collectionContract = rootTypeDataContract as CollectionDataContract;
|
||||
while (collectionContract != null)
|
||||
{
|
||||
DataContract itemContract = GetDataContract(GetSurrogatedType(collectionContract.ItemType));
|
||||
if (itemContract.StableName == typeQName)
|
||||
{
|
||||
return itemContract;
|
||||
}
|
||||
collectionContract = itemContract as CollectionDataContract;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,533 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.Serialization.Formatters;
|
||||
|
||||
namespace Compat.Runtime.Serialization
|
||||
{
|
||||
internal class XmlObjectSerializerReadContextComplex : XmlObjectSerializerReadContext
|
||||
{
|
||||
private static readonly Hashtable dataContractTypeCache = new Hashtable();
|
||||
private readonly bool preserveObjectReferences;
|
||||
protected IDataContractSurrogate dataContractSurrogate;
|
||||
private readonly SerializationMode mode;
|
||||
private readonly System.Runtime.Serialization.SerializationBinder binder;
|
||||
private readonly System.Runtime.Serialization.ISurrogateSelector surrogateSelector;
|
||||
private readonly FormatterAssemblyStyle assemblyFormat;
|
||||
private Hashtable surrogateDataContracts;
|
||||
|
||||
internal XmlObjectSerializerReadContextComplex(
|
||||
DataContractSerializer serializer,
|
||||
DataContract rootTypeDataContract,
|
||||
System.Runtime.Serialization.DataContractResolver dataContractResolver)
|
||||
: base(serializer, rootTypeDataContract, dataContractResolver)
|
||||
{
|
||||
mode = SerializationMode.SharedContract;
|
||||
preserveObjectReferences = serializer.PreserveObjectReferences;
|
||||
dataContractSurrogate = serializer.DataContractSurrogate;
|
||||
}
|
||||
|
||||
internal XmlObjectSerializerReadContextComplex(NetDataContractSerializer serializer)
|
||||
: base(serializer)
|
||||
{
|
||||
mode = SerializationMode.SharedType;
|
||||
preserveObjectReferences = true;
|
||||
binder = serializer.Binder;
|
||||
surrogateSelector = serializer.SurrogateSelector;
|
||||
assemblyFormat = serializer.AssemblyFormat;
|
||||
}
|
||||
|
||||
internal XmlObjectSerializerReadContextComplex(XmlObjectSerializer serializer, int maxItemsInObjectGraph, System.Runtime.Serialization.StreamingContext streamingContext, bool ignoreExtensionDataObject)
|
||||
: base(serializer, maxItemsInObjectGraph, streamingContext, ignoreExtensionDataObject)
|
||||
{
|
||||
}
|
||||
|
||||
internal override SerializationMode Mode => mode;
|
||||
|
||||
internal override DataContract GetDataContract(int id, RuntimeTypeHandle typeHandle)
|
||||
{
|
||||
DataContract dataContract = null;
|
||||
if (mode == SerializationMode.SharedType && surrogateSelector != null)
|
||||
{
|
||||
dataContract = NetDataContractSerializer.GetDataContractFromSurrogateSelector(surrogateSelector, GetStreamingContext(), typeHandle, null /*type*/, ref surrogateDataContracts);
|
||||
}
|
||||
|
||||
if (dataContract != null)
|
||||
{
|
||||
if (IsGetOnlyCollection && dataContract is SurrogateDataContract)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new System.Runtime.Serialization.InvalidDataContractException(SR.Format(SR.SurrogatesWithGetOnlyCollectionsNotSupportedSerDeser,
|
||||
DataContract.GetClrTypeFullName(dataContract.UnderlyingType))));
|
||||
}
|
||||
return dataContract;
|
||||
}
|
||||
|
||||
return base.GetDataContract(id, typeHandle);
|
||||
}
|
||||
|
||||
internal override DataContract GetDataContract(RuntimeTypeHandle typeHandle, Type type)
|
||||
{
|
||||
DataContract dataContract = null;
|
||||
if (mode == SerializationMode.SharedType && surrogateSelector != null)
|
||||
{
|
||||
dataContract = NetDataContractSerializer.GetDataContractFromSurrogateSelector(surrogateSelector, GetStreamingContext(), typeHandle, type, ref surrogateDataContracts);
|
||||
}
|
||||
|
||||
if (dataContract != null)
|
||||
{
|
||||
if (IsGetOnlyCollection && dataContract is SurrogateDataContract)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new System.Runtime.Serialization.InvalidDataContractException(SR.Format(SR.SurrogatesWithGetOnlyCollectionsNotSupportedSerDeser,
|
||||
DataContract.GetClrTypeFullName(dataContract.UnderlyingType))));
|
||||
}
|
||||
return dataContract;
|
||||
}
|
||||
|
||||
return base.GetDataContract(typeHandle, type);
|
||||
}
|
||||
|
||||
public override object InternalDeserialize(XmlReaderDelegator xmlReader, int declaredTypeID, RuntimeTypeHandle declaredTypeHandle, string name, string ns)
|
||||
{
|
||||
if (mode == SerializationMode.SharedContract)
|
||||
{
|
||||
if (dataContractSurrogate == null)
|
||||
{
|
||||
return base.InternalDeserialize(xmlReader, declaredTypeID, declaredTypeHandle, name, ns);
|
||||
}
|
||||
else
|
||||
{
|
||||
return InternalDeserializeWithSurrogate(xmlReader, Type.GetTypeFromHandle(declaredTypeHandle), null /*surrogateDataContract*/, name, ns);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return InternalDeserializeInSharedTypeMode(xmlReader, declaredTypeID, Type.GetTypeFromHandle(declaredTypeHandle), name, ns);
|
||||
}
|
||||
}
|
||||
|
||||
internal override object InternalDeserialize(XmlReaderDelegator xmlReader, Type declaredType, string name, string ns)
|
||||
{
|
||||
if (mode == SerializationMode.SharedContract)
|
||||
{
|
||||
if (dataContractSurrogate == null)
|
||||
{
|
||||
return base.InternalDeserialize(xmlReader, declaredType, name, ns);
|
||||
}
|
||||
else
|
||||
{
|
||||
return InternalDeserializeWithSurrogate(xmlReader, declaredType, null /*surrogateDataContract*/, name, ns);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return InternalDeserializeInSharedTypeMode(xmlReader, -1, declaredType, name, ns);
|
||||
}
|
||||
}
|
||||
|
||||
internal override object InternalDeserialize(XmlReaderDelegator xmlReader, Type declaredType, DataContract dataContract, string name, string ns)
|
||||
{
|
||||
if (mode == SerializationMode.SharedContract)
|
||||
{
|
||||
if (dataContractSurrogate == null)
|
||||
{
|
||||
return base.InternalDeserialize(xmlReader, declaredType, dataContract, name, ns);
|
||||
}
|
||||
else
|
||||
{
|
||||
return InternalDeserializeWithSurrogate(xmlReader, declaredType, dataContract, name, ns);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return InternalDeserializeInSharedTypeMode(xmlReader, -1, declaredType, name, ns);
|
||||
}
|
||||
}
|
||||
|
||||
private object InternalDeserializeInSharedTypeMode(XmlReaderDelegator xmlReader, int declaredTypeID, Type declaredType, string name, string ns)
|
||||
{
|
||||
object retObj = null;
|
||||
if (TryHandleNullOrRef(xmlReader, declaredType, name, ns, ref retObj))
|
||||
{
|
||||
return retObj;
|
||||
}
|
||||
|
||||
DataContract dataContract;
|
||||
string assemblyName = attributes.ClrAssembly;
|
||||
string typeName = attributes.ClrType;
|
||||
if (assemblyName != null && typeName != null)
|
||||
{
|
||||
dataContract = ResolveDataContractInSharedTypeMode(assemblyName, typeName, out Assembly assembly, out Type type);
|
||||
if (dataContract == null)
|
||||
{
|
||||
if (assembly == null)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(SR.Format(SR.AssemblyNotFound, assemblyName)));
|
||||
}
|
||||
|
||||
if (type == null)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(SR.Format(SR.ClrTypeNotFound, assembly.FullName, typeName)));
|
||||
}
|
||||
}
|
||||
//Array covariance is not supported in XSD. If declared type is array, data is sent in format of base array
|
||||
if (declaredType != null && declaredType.IsArray)
|
||||
{
|
||||
dataContract = (declaredTypeID < 0) ? GetDataContract(declaredType) : GetDataContract(declaredTypeID, declaredType.TypeHandle);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (assemblyName != null)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(XmlObjectSerializer.TryAddLineInfo(xmlReader, SR.Format(SR.AttributeNotFound, Globals.SerializationNamespace, Globals.ClrTypeLocalName, xmlReader.NodeType, xmlReader.NamespaceURI, xmlReader.LocalName))));
|
||||
}
|
||||
else if (typeName != null)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(XmlObjectSerializer.TryAddLineInfo(xmlReader, SR.Format(SR.AttributeNotFound, Globals.SerializationNamespace, Globals.ClrAssemblyLocalName, xmlReader.NodeType, xmlReader.NamespaceURI, xmlReader.LocalName))));
|
||||
}
|
||||
else if (declaredType == null)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(XmlObjectSerializer.TryAddLineInfo(xmlReader, SR.Format(SR.AttributeNotFound, Globals.SerializationNamespace, Globals.ClrTypeLocalName, xmlReader.NodeType, xmlReader.NamespaceURI, xmlReader.LocalName))));
|
||||
}
|
||||
|
||||
dataContract = (declaredTypeID < 0) ? GetDataContract(declaredType) : GetDataContract(declaredTypeID, declaredType.TypeHandle);
|
||||
}
|
||||
return ReadDataContractValue(dataContract, xmlReader);
|
||||
}
|
||||
|
||||
private object InternalDeserializeWithSurrogate(XmlReaderDelegator xmlReader, Type declaredType, DataContract surrogateDataContract, string name, string ns)
|
||||
{
|
||||
DataContract dataContract = surrogateDataContract ??
|
||||
GetDataContract(DataContractSurrogateCaller.GetDataContractType(dataContractSurrogate, declaredType));
|
||||
if (IsGetOnlyCollection && dataContract.UnderlyingType != declaredType)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new System.Runtime.Serialization.InvalidDataContractException(SR.Format(SR.SurrogatesWithGetOnlyCollectionsNotSupportedSerDeser,
|
||||
DataContract.GetClrTypeFullName(declaredType))));
|
||||
}
|
||||
ReadAttributes(xmlReader);
|
||||
string objectId = GetObjectId();
|
||||
object oldObj = InternalDeserialize(xmlReader, name, ns, declaredType, ref dataContract);
|
||||
object obj = DataContractSurrogateCaller.GetDeserializedObject(dataContractSurrogate, oldObj, dataContract.UnderlyingType, declaredType);
|
||||
ReplaceDeserializedObject(objectId, oldObj, obj);
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
private Type ResolveDataContractTypeInSharedTypeMode(string assemblyName, string typeName, out Assembly assembly)
|
||||
{
|
||||
assembly = null;
|
||||
Type type = null;
|
||||
|
||||
if (binder != null)
|
||||
{
|
||||
type = binder.BindToType(assemblyName, typeName);
|
||||
}
|
||||
|
||||
if (type == null)
|
||||
{
|
||||
XmlObjectDataContractTypeKey key = new XmlObjectDataContractTypeKey(assemblyName, typeName);
|
||||
XmlObjectDataContractTypeInfo dataContractTypeInfo = (XmlObjectDataContractTypeInfo)dataContractTypeCache[key];
|
||||
if (dataContractTypeInfo == null)
|
||||
{
|
||||
if (assemblyFormat == FormatterAssemblyStyle.Full)
|
||||
{
|
||||
if (assemblyName == Globals.MscorlibAssemblyName)
|
||||
{
|
||||
assembly = Globals.TypeOfInt.Assembly;
|
||||
}
|
||||
else
|
||||
{
|
||||
assembly = Assembly.Load(assemblyName);
|
||||
}
|
||||
if (assembly != null)
|
||||
{
|
||||
type = assembly.GetType(typeName);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
assembly = XmlObjectSerializerReadContextComplex.ResolveSimpleAssemblyName(assemblyName);
|
||||
if (assembly != null)
|
||||
{
|
||||
// Catching any exceptions that could be thrown from a failure on assembly load
|
||||
// This is necessary, for example, if there are generic parameters that are qualified with a version of the assembly that predates the one available
|
||||
try
|
||||
{
|
||||
type = assembly.GetType(typeName);
|
||||
}
|
||||
catch (TypeLoadException) { }
|
||||
catch (FileNotFoundException) { }
|
||||
catch (FileLoadException) { }
|
||||
catch (BadImageFormatException) { }
|
||||
|
||||
if (type == null)
|
||||
{
|
||||
type = Type.GetType(typeName, XmlObjectSerializerReadContextComplex.ResolveSimpleAssemblyName, new TopLevelAssemblyTypeResolver(assembly).ResolveType, false /* throwOnError */);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (type != null)
|
||||
{
|
||||
CheckTypeForwardedTo(assembly, type.Assembly, type);
|
||||
|
||||
dataContractTypeInfo = new XmlObjectDataContractTypeInfo(assembly, type);
|
||||
lock (dataContractTypeCache)
|
||||
{
|
||||
if (!dataContractTypeCache.ContainsKey(key))
|
||||
{
|
||||
dataContractTypeCache[key] = dataContractTypeInfo;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
assembly = dataContractTypeInfo.Assembly;
|
||||
type = dataContractTypeInfo.Type;
|
||||
}
|
||||
}
|
||||
|
||||
return type;
|
||||
}
|
||||
|
||||
private DataContract ResolveDataContractInSharedTypeMode(string assemblyName, string typeName, out Assembly assembly, out Type type)
|
||||
{
|
||||
type = ResolveDataContractTypeInSharedTypeMode(assemblyName, typeName, out assembly);
|
||||
if (type != null)
|
||||
{
|
||||
return GetDataContract(type);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
protected override DataContract ResolveDataContractFromTypeName()
|
||||
{
|
||||
if (mode == SerializationMode.SharedContract)
|
||||
{
|
||||
return base.ResolveDataContractFromTypeName();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (attributes.ClrAssembly != null && attributes.ClrType != null)
|
||||
{
|
||||
return ResolveDataContractInSharedTypeMode(attributes.ClrAssembly, attributes.ClrType, out Assembly assembly, out Type type);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
private bool CheckIfTypeSerializableForSharedTypeMode(Type memberType)
|
||||
{
|
||||
Fx.Assert(surrogateSelector != null, "Method should not be called when surrogateSelector is null.");
|
||||
return (surrogateSelector.GetSurrogate(memberType, GetStreamingContext(), out System.Runtime.Serialization.ISurrogateSelector surrogateSelectorNotUsed) != null);
|
||||
}
|
||||
|
||||
internal override void CheckIfTypeSerializable(Type memberType, bool isMemberTypeSerializable)
|
||||
{
|
||||
if (mode == SerializationMode.SharedType && surrogateSelector != null &&
|
||||
CheckIfTypeSerializableForSharedTypeMode(memberType))
|
||||
{
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (dataContractSurrogate != null)
|
||||
{
|
||||
while (memberType.IsArray)
|
||||
{
|
||||
memberType = memberType.GetElementType();
|
||||
}
|
||||
|
||||
memberType = DataContractSurrogateCaller.GetDataContractType(dataContractSurrogate, memberType);
|
||||
if (!DataContract.IsTypeSerializable(memberType))
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new System.Runtime.Serialization.InvalidDataContractException(SR.Format(SR.TypeNotSerializable, memberType)));
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
base.CheckIfTypeSerializable(memberType, isMemberTypeSerializable);
|
||||
}
|
||||
|
||||
internal override Type GetSurrogatedType(Type type)
|
||||
{
|
||||
if (dataContractSurrogate == null)
|
||||
{
|
||||
return base.GetSurrogatedType(type);
|
||||
}
|
||||
else
|
||||
{
|
||||
type = DataContract.UnwrapNullableType(type);
|
||||
Type surrogateType = DataContractSerializer.GetSurrogatedType(dataContractSurrogate, type);
|
||||
if (IsGetOnlyCollection && surrogateType != type)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new System.Runtime.Serialization.InvalidDataContractException(SR.Format(SR.SurrogatesWithGetOnlyCollectionsNotSupportedSerDeser,
|
||||
DataContract.GetClrTypeFullName(type))));
|
||||
}
|
||||
else
|
||||
{
|
||||
return surrogateType;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if USE_REFEMIT
|
||||
public override int GetArraySize()
|
||||
#else
|
||||
internal override int GetArraySize()
|
||||
#endif
|
||||
{
|
||||
return preserveObjectReferences ? attributes.ArraySZSize : -1;
|
||||
}
|
||||
|
||||
private static Assembly ResolveSimpleAssemblyName(AssemblyName assemblyName)
|
||||
{
|
||||
return ResolveSimpleAssemblyName(assemblyName.FullName);
|
||||
}
|
||||
|
||||
private static Assembly ResolveSimpleAssemblyName(string assemblyName)
|
||||
{
|
||||
Assembly assembly;
|
||||
if (assemblyName == Globals.MscorlibAssemblyName)
|
||||
{
|
||||
assembly = Globals.TypeOfInt.Assembly;
|
||||
}
|
||||
else
|
||||
{
|
||||
assembly = Assembly.LoadWithPartialName(assemblyName);
|
||||
if (assembly == null)
|
||||
{
|
||||
AssemblyName an = new AssemblyName(assemblyName)
|
||||
{
|
||||
Version = null
|
||||
};
|
||||
assembly = Assembly.LoadWithPartialName(an.FullName);
|
||||
}
|
||||
}
|
||||
return assembly;
|
||||
}
|
||||
|
||||
private static void CheckTypeForwardedTo(Assembly sourceAssembly, Assembly destinationAssembly, Type resolvedType)
|
||||
{
|
||||
if (sourceAssembly != destinationAssembly && !NetDataContractSerializer.UnsafeTypeForwardingEnabled && !sourceAssembly.IsFullyTrusted)
|
||||
{
|
||||
// We have a TypeForwardedTo attribute
|
||||
//if (!destinationAssembly.PermissionSet.IsSubsetOf(sourceAssembly.PermissionSet))
|
||||
//{
|
||||
// // We look for a matching TypeForwardedFrom attribute
|
||||
// TypeInformation typeInfo = NetDataContractSerializer.GetTypeInformation(resolvedType);
|
||||
// if (typeInfo.HasTypeForwardedFrom)
|
||||
// {
|
||||
// Assembly typeForwardedFromAssembly = null;
|
||||
// try
|
||||
// {
|
||||
// // if this Assembly.Load fails, we still want to throw security exception
|
||||
// typeForwardedFromAssembly = Assembly.Load(typeInfo.AssemblyString);
|
||||
// }
|
||||
// catch { }
|
||||
|
||||
// if (typeForwardedFromAssembly == sourceAssembly)
|
||||
// {
|
||||
// return;
|
||||
// }
|
||||
// }
|
||||
// throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(SR.Format(SR.CannotDeserializeForwardedType, DataContract.GetClrTypeFullName(resolvedType))));
|
||||
//}
|
||||
}
|
||||
}
|
||||
|
||||
private sealed class TopLevelAssemblyTypeResolver
|
||||
{
|
||||
private readonly Assembly topLevelAssembly;
|
||||
|
||||
public TopLevelAssemblyTypeResolver(Assembly topLevelAssembly)
|
||||
{
|
||||
this.topLevelAssembly = topLevelAssembly;
|
||||
}
|
||||
public Type ResolveType(Assembly assembly, string simpleTypeName, bool ignoreCase)
|
||||
{
|
||||
if (assembly == null)
|
||||
{
|
||||
assembly = topLevelAssembly;
|
||||
}
|
||||
|
||||
return assembly.GetType(simpleTypeName, false, ignoreCase);
|
||||
}
|
||||
}
|
||||
|
||||
private class XmlObjectDataContractTypeInfo
|
||||
{
|
||||
private readonly Assembly assembly;
|
||||
private readonly Type type;
|
||||
public XmlObjectDataContractTypeInfo(Assembly assembly, Type type)
|
||||
{
|
||||
this.assembly = assembly;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public Assembly Assembly => assembly;
|
||||
|
||||
public Type Type => type;
|
||||
}
|
||||
|
||||
private class XmlObjectDataContractTypeKey
|
||||
{
|
||||
private readonly string assemblyName;
|
||||
private readonly string typeName;
|
||||
public XmlObjectDataContractTypeKey(string assemblyName, string typeName)
|
||||
{
|
||||
this.assemblyName = assemblyName;
|
||||
this.typeName = typeName;
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (object.ReferenceEquals(this, obj))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
XmlObjectDataContractTypeKey other = obj as XmlObjectDataContractTypeKey;
|
||||
if (other == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (assemblyName != other.assemblyName)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (typeName != other.typeName)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
int hashCode = 0;
|
||||
if (assemblyName != null)
|
||||
{
|
||||
hashCode = assemblyName.GetHashCode();
|
||||
}
|
||||
|
||||
if (typeName != null)
|
||||
{
|
||||
hashCode ^= typeName.GetHashCode();
|
||||
}
|
||||
|
||||
return hashCode;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,863 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Xml;
|
||||
using System.Collections.Generic;
|
||||
using System.Xml.Serialization;
|
||||
using System.Security;
|
||||
using System.Security.Permissions;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace Compat.Runtime.Serialization
|
||||
{
|
||||
internal class XmlObjectSerializerWriteContext : XmlObjectSerializerContext
|
||||
{
|
||||
private ObjectReferenceStack byValObjectsInScope = new ObjectReferenceStack();
|
||||
private XmlSerializableWriter xmlSerializableWriter;
|
||||
private const int depthToCheckCyclicReference = 512;
|
||||
protected bool preserveObjectReferences;
|
||||
private ObjectToIdCache serializedObjects;
|
||||
private bool isGetOnlyCollection;
|
||||
private readonly bool unsafeTypeForwardingEnabled;
|
||||
protected bool serializeReadOnlyTypes;
|
||||
|
||||
internal static XmlObjectSerializerWriteContext CreateContext(DataContractSerializer serializer, DataContract rootTypeDataContract, System.Runtime.Serialization.DataContractResolver dataContractResolver)
|
||||
{
|
||||
return (serializer.PreserveObjectReferences || serializer.DataContractSurrogate != null)
|
||||
? new XmlObjectSerializerWriteContextComplex(serializer, rootTypeDataContract, dataContractResolver)
|
||||
: new XmlObjectSerializerWriteContext(serializer, rootTypeDataContract, dataContractResolver);
|
||||
}
|
||||
|
||||
internal static XmlObjectSerializerWriteContext CreateContext(NetDataContractSerializer serializer, Hashtable surrogateDataContracts)
|
||||
{
|
||||
return new XmlObjectSerializerWriteContextComplex(serializer, surrogateDataContracts);
|
||||
}
|
||||
|
||||
protected XmlObjectSerializerWriteContext(
|
||||
DataContractSerializer serializer,
|
||||
DataContract rootTypeDataContract,
|
||||
System.Runtime.Serialization.DataContractResolver resolver)
|
||||
: base(serializer, rootTypeDataContract, resolver)
|
||||
{
|
||||
serializeReadOnlyTypes = serializer.SerializeReadOnlyTypes;
|
||||
// Known types restricts the set of types that can be deserialized
|
||||
unsafeTypeForwardingEnabled = true;
|
||||
}
|
||||
|
||||
protected XmlObjectSerializerWriteContext(NetDataContractSerializer serializer)
|
||||
: base(serializer)
|
||||
{
|
||||
unsafeTypeForwardingEnabled = NetDataContractSerializer.UnsafeTypeForwardingEnabled;
|
||||
}
|
||||
|
||||
internal XmlObjectSerializerWriteContext(
|
||||
XmlObjectSerializer serializer,
|
||||
int maxItemsInObjectGraph,
|
||||
System.Runtime.Serialization.StreamingContext streamingContext,
|
||||
bool ignoreExtensionDataObject)
|
||||
: base(serializer, maxItemsInObjectGraph, streamingContext, ignoreExtensionDataObject)
|
||||
{
|
||||
// Known types restricts the set of types that can be deserialized
|
||||
unsafeTypeForwardingEnabled = true;
|
||||
}
|
||||
|
||||
protected ObjectToIdCache SerializedObjects
|
||||
{
|
||||
get
|
||||
{
|
||||
if (serializedObjects == null)
|
||||
{
|
||||
serializedObjects = new ObjectToIdCache();
|
||||
}
|
||||
|
||||
return serializedObjects;
|
||||
}
|
||||
}
|
||||
|
||||
internal override bool IsGetOnlyCollection
|
||||
{
|
||||
get => isGetOnlyCollection;
|
||||
set => isGetOnlyCollection = value;
|
||||
}
|
||||
|
||||
internal bool SerializeReadOnlyTypes => serializeReadOnlyTypes;
|
||||
|
||||
internal bool UnsafeTypeForwardingEnabled => unsafeTypeForwardingEnabled;
|
||||
|
||||
#if USE_REFEMIT
|
||||
public void StoreIsGetOnlyCollection()
|
||||
#else
|
||||
internal void StoreIsGetOnlyCollection()
|
||||
#endif
|
||||
{
|
||||
isGetOnlyCollection = true;
|
||||
}
|
||||
|
||||
public void InternalSerializeReference(XmlWriterDelegator xmlWriter, object obj, bool isDeclaredType, bool writeXsiType, int declaredTypeID, RuntimeTypeHandle declaredTypeHandle)
|
||||
{
|
||||
if (!OnHandleReference(xmlWriter, obj, true /*canContainCyclicReference*/))
|
||||
{
|
||||
InternalSerialize(xmlWriter, obj, isDeclaredType, writeXsiType, declaredTypeID, declaredTypeHandle);
|
||||
}
|
||||
|
||||
OnEndHandleReference(xmlWriter, obj, true /*canContainCyclicReference*/);
|
||||
}
|
||||
|
||||
public virtual void InternalSerialize(XmlWriterDelegator xmlWriter, object obj, bool isDeclaredType, bool writeXsiType, int declaredTypeID, RuntimeTypeHandle declaredTypeHandle)
|
||||
{
|
||||
if (writeXsiType)
|
||||
{
|
||||
Type declaredType = Globals.TypeOfObject;
|
||||
SerializeWithXsiType(xmlWriter, obj, Type.GetTypeHandle(obj), null/*type*/, -1, declaredType.TypeHandle, declaredType);
|
||||
}
|
||||
else if (isDeclaredType)
|
||||
{
|
||||
DataContract contract = GetDataContract(declaredTypeID, declaredTypeHandle);
|
||||
SerializeWithoutXsiType(contract, xmlWriter, obj, declaredTypeHandle);
|
||||
}
|
||||
else
|
||||
{
|
||||
RuntimeTypeHandle objTypeHandle = Type.GetTypeHandle(obj);
|
||||
if (declaredTypeHandle.Equals(objTypeHandle))
|
||||
{
|
||||
DataContract dataContract = (declaredTypeID >= 0)
|
||||
? GetDataContract(declaredTypeID, declaredTypeHandle)
|
||||
: GetDataContract(declaredTypeHandle, null /*type*/);
|
||||
SerializeWithoutXsiType(dataContract, xmlWriter, obj, declaredTypeHandle);
|
||||
}
|
||||
else
|
||||
{
|
||||
SerializeWithXsiType(xmlWriter, obj, objTypeHandle, null /*type*/, declaredTypeID, declaredTypeHandle, Type.GetTypeFromHandle(declaredTypeHandle));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal void SerializeWithoutXsiType(DataContract dataContract, XmlWriterDelegator xmlWriter, object obj, RuntimeTypeHandle declaredTypeHandle)
|
||||
{
|
||||
if (OnHandleIsReference(xmlWriter, dataContract, obj))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (dataContract.KnownDataContracts != null)
|
||||
{
|
||||
scopedKnownTypes.Push(dataContract.KnownDataContracts);
|
||||
WriteDataContractValue(dataContract, xmlWriter, obj, declaredTypeHandle);
|
||||
scopedKnownTypes.Pop();
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteDataContractValue(dataContract, xmlWriter, obj, declaredTypeHandle);
|
||||
}
|
||||
}
|
||||
|
||||
internal virtual void SerializeWithXsiTypeAtTopLevel(DataContract dataContract, XmlWriterDelegator xmlWriter, object obj, RuntimeTypeHandle originalDeclaredTypeHandle, Type graphType)
|
||||
{
|
||||
bool verifyKnownType = false;
|
||||
Type declaredType = rootTypeDataContract.OriginalUnderlyingType;
|
||||
|
||||
if (declaredType.IsInterface && CollectionDataContract.IsCollectionInterface(declaredType))
|
||||
{
|
||||
if (DataContractResolver != null)
|
||||
{
|
||||
WriteResolvedTypeInfo(xmlWriter, graphType, declaredType);
|
||||
}
|
||||
}
|
||||
else if (!declaredType.IsArray) //Array covariance is not supported in XSD. If declared type is array do not write xsi:type. Instead write xsi:type for each item
|
||||
{
|
||||
verifyKnownType = WriteTypeInfo(xmlWriter, dataContract, rootTypeDataContract);
|
||||
}
|
||||
SerializeAndVerifyType(dataContract, xmlWriter, obj, verifyKnownType, originalDeclaredTypeHandle, declaredType);
|
||||
}
|
||||
|
||||
protected virtual void SerializeWithXsiType(XmlWriterDelegator xmlWriter, object obj, RuntimeTypeHandle objectTypeHandle, Type objectType, int declaredTypeID, RuntimeTypeHandle declaredTypeHandle, Type declaredType)
|
||||
{
|
||||
DataContract dataContract;
|
||||
bool verifyKnownType = false;
|
||||
if (declaredType.IsInterface && CollectionDataContract.IsCollectionInterface(declaredType))
|
||||
{
|
||||
dataContract = GetDataContractSkipValidation(DataContract.GetId(objectTypeHandle), objectTypeHandle, objectType);
|
||||
if (OnHandleIsReference(xmlWriter, dataContract, obj))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (Mode == SerializationMode.SharedType && dataContract.IsValidContract(Mode))
|
||||
{
|
||||
dataContract = dataContract.GetValidContract(Mode);
|
||||
}
|
||||
else
|
||||
{
|
||||
dataContract = GetDataContract(declaredTypeHandle, declaredType);
|
||||
}
|
||||
|
||||
if (!WriteClrTypeInfo(xmlWriter, dataContract) && DataContractResolver != null)
|
||||
{
|
||||
if (objectType == null)
|
||||
{
|
||||
objectType = Type.GetTypeFromHandle(objectTypeHandle);
|
||||
}
|
||||
WriteResolvedTypeInfo(xmlWriter, objectType, declaredType);
|
||||
}
|
||||
}
|
||||
else if (declaredType.IsArray)//Array covariance is not supported in XSD. If declared type is array do not write xsi:type. Instead write xsi:type for each item
|
||||
{
|
||||
// A call to OnHandleIsReference is not necessary here -- arrays cannot be IsReference
|
||||
dataContract = GetDataContract(objectTypeHandle, objectType);
|
||||
WriteClrTypeInfo(xmlWriter, dataContract);
|
||||
dataContract = GetDataContract(declaredTypeHandle, declaredType);
|
||||
}
|
||||
else
|
||||
{
|
||||
dataContract = GetDataContract(objectTypeHandle, objectType);
|
||||
if (OnHandleIsReference(xmlWriter, dataContract, obj))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!WriteClrTypeInfo(xmlWriter, dataContract))
|
||||
{
|
||||
DataContract declaredTypeContract = (declaredTypeID >= 0)
|
||||
? GetDataContract(declaredTypeID, declaredTypeHandle)
|
||||
: GetDataContract(declaredTypeHandle, declaredType);
|
||||
verifyKnownType = WriteTypeInfo(xmlWriter, dataContract, declaredTypeContract);
|
||||
}
|
||||
}
|
||||
|
||||
SerializeAndVerifyType(dataContract, xmlWriter, obj, verifyKnownType, declaredTypeHandle, declaredType);
|
||||
}
|
||||
|
||||
internal bool OnHandleIsReference(XmlWriterDelegator xmlWriter, DataContract contract, object obj)
|
||||
{
|
||||
if (preserveObjectReferences || !contract.IsReference || isGetOnlyCollection)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool isNew = true;
|
||||
int objectId = SerializedObjects.GetId(obj, ref isNew);
|
||||
byValObjectsInScope.EnsureSetAsIsReference(obj);
|
||||
if (isNew)
|
||||
{
|
||||
xmlWriter.WriteAttributeString(Globals.SerPrefix, DictionaryGlobals.IdLocalName,
|
||||
DictionaryGlobals.SerializationNamespace, string.Format(CultureInfo.InvariantCulture, "{0}{1}", "i", objectId));
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
xmlWriter.WriteAttributeString(Globals.SerPrefix, DictionaryGlobals.RefLocalName, DictionaryGlobals.SerializationNamespace, string.Format(CultureInfo.InvariantCulture, "{0}{1}", "i", objectId));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
protected void SerializeAndVerifyType(DataContract dataContract, XmlWriterDelegator xmlWriter, object obj, bool verifyKnownType, RuntimeTypeHandle declaredTypeHandle, Type declaredType)
|
||||
{
|
||||
bool knownTypesAddedInCurrentScope = false;
|
||||
if (dataContract.KnownDataContracts != null)
|
||||
{
|
||||
scopedKnownTypes.Push(dataContract.KnownDataContracts);
|
||||
knownTypesAddedInCurrentScope = true;
|
||||
}
|
||||
|
||||
if (verifyKnownType)
|
||||
{
|
||||
if (!IsKnownType(dataContract, declaredType))
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(SR.Format(SR.DcTypeNotFoundOnSerialize, DataContract.GetClrTypeFullName(dataContract.UnderlyingType), dataContract.StableName.Name, dataContract.StableName.Namespace)));
|
||||
}
|
||||
}
|
||||
WriteDataContractValue(dataContract, xmlWriter, obj, declaredTypeHandle);
|
||||
|
||||
if (knownTypesAddedInCurrentScope)
|
||||
{
|
||||
scopedKnownTypes.Pop();
|
||||
}
|
||||
}
|
||||
|
||||
internal virtual bool WriteClrTypeInfo(XmlWriterDelegator xmlWriter, DataContract dataContract)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
internal virtual bool WriteClrTypeInfo(XmlWriterDelegator xmlWriter, Type dataContractType, string clrTypeName, string clrAssemblyName)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
internal virtual bool WriteClrTypeInfo(XmlWriterDelegator xmlWriter, Type dataContractType, System.Runtime.Serialization.SerializationInfo serInfo)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public virtual void WriteAnyType(XmlWriterDelegator xmlWriter, object value)
|
||||
{
|
||||
xmlWriter.WriteAnyType(value);
|
||||
}
|
||||
|
||||
public virtual void WriteString(XmlWriterDelegator xmlWriter, string value)
|
||||
{
|
||||
xmlWriter.WriteString(value);
|
||||
}
|
||||
public virtual void WriteString(XmlWriterDelegator xmlWriter, string value, XmlDictionaryString name, XmlDictionaryString ns)
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
WriteNull(xmlWriter, typeof(string), true/*isMemberTypeSerializable*/, name, ns);
|
||||
}
|
||||
else
|
||||
{
|
||||
xmlWriter.WriteStartElementPrimitive(name, ns);
|
||||
xmlWriter.WriteString(value);
|
||||
xmlWriter.WriteEndElementPrimitive();
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void WriteBase64(XmlWriterDelegator xmlWriter, byte[] value)
|
||||
{
|
||||
xmlWriter.WriteBase64(value);
|
||||
}
|
||||
public virtual void WriteBase64(XmlWriterDelegator xmlWriter, byte[] value, XmlDictionaryString name, XmlDictionaryString ns)
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
WriteNull(xmlWriter, typeof(byte[]), true/*isMemberTypeSerializable*/, name, ns);
|
||||
}
|
||||
else
|
||||
{
|
||||
xmlWriter.WriteStartElementPrimitive(name, ns);
|
||||
xmlWriter.WriteBase64(value);
|
||||
xmlWriter.WriteEndElementPrimitive();
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void WriteUri(XmlWriterDelegator xmlWriter, Uri value)
|
||||
{
|
||||
xmlWriter.WriteUri(value);
|
||||
}
|
||||
public virtual void WriteUri(XmlWriterDelegator xmlWriter, Uri value, XmlDictionaryString name, XmlDictionaryString ns)
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
WriteNull(xmlWriter, typeof(Uri), true/*isMemberTypeSerializable*/, name, ns);
|
||||
}
|
||||
else
|
||||
{
|
||||
xmlWriter.WriteStartElementPrimitive(name, ns);
|
||||
xmlWriter.WriteUri(value);
|
||||
xmlWriter.WriteEndElementPrimitive();
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void WriteQName(XmlWriterDelegator xmlWriter, XmlQualifiedName value)
|
||||
{
|
||||
xmlWriter.WriteQName(value);
|
||||
}
|
||||
public virtual void WriteQName(XmlWriterDelegator xmlWriter, XmlQualifiedName value, XmlDictionaryString name, XmlDictionaryString ns)
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
WriteNull(xmlWriter, typeof(XmlQualifiedName), true/*isMemberTypeSerializable*/, name, ns);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ns != null && ns.Value != null && ns.Value.Length > 0)
|
||||
{
|
||||
xmlWriter.WriteStartElement(Globals.ElementPrefix, name, ns);
|
||||
}
|
||||
else
|
||||
{
|
||||
xmlWriter.WriteStartElement(name, ns);
|
||||
}
|
||||
|
||||
xmlWriter.WriteQName(value);
|
||||
xmlWriter.WriteEndElement();
|
||||
}
|
||||
}
|
||||
|
||||
internal void HandleGraphAtTopLevel(XmlWriterDelegator writer, object obj, DataContract contract)
|
||||
{
|
||||
writer.WriteXmlnsAttribute(Globals.XsiPrefix, DictionaryGlobals.SchemaInstanceNamespace);
|
||||
if (contract.IsISerializable)
|
||||
{
|
||||
writer.WriteXmlnsAttribute(Globals.XsdPrefix, DictionaryGlobals.SchemaNamespace);
|
||||
}
|
||||
|
||||
OnHandleReference(writer, obj, true /*canContainReferences*/);
|
||||
}
|
||||
|
||||
internal virtual bool OnHandleReference(XmlWriterDelegator xmlWriter, object obj, bool canContainCyclicReference)
|
||||
{
|
||||
if (xmlWriter._depth < depthToCheckCyclicReference)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (canContainCyclicReference)
|
||||
{
|
||||
if (byValObjectsInScope.Contains(obj))
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(SR.Format(SR.CannotSerializeObjectWithCycles, DataContract.GetClrTypeFullName(obj.GetType()))));
|
||||
}
|
||||
|
||||
byValObjectsInScope.Push(obj);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
internal virtual void OnEndHandleReference(XmlWriterDelegator xmlWriter, object obj, bool canContainCyclicReference)
|
||||
{
|
||||
if (xmlWriter._depth < depthToCheckCyclicReference)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (canContainCyclicReference)
|
||||
{
|
||||
byValObjectsInScope.Pop(obj);
|
||||
}
|
||||
}
|
||||
|
||||
public void WriteNull(XmlWriterDelegator xmlWriter, Type memberType, bool isMemberTypeSerializable)
|
||||
{
|
||||
CheckIfTypeSerializable(memberType, isMemberTypeSerializable);
|
||||
WriteNull(xmlWriter);
|
||||
}
|
||||
|
||||
internal void WriteNull(XmlWriterDelegator xmlWriter, Type memberType, bool isMemberTypeSerializable, XmlDictionaryString name, XmlDictionaryString ns)
|
||||
{
|
||||
xmlWriter.WriteStartElement(name, ns);
|
||||
WriteNull(xmlWriter, memberType, isMemberTypeSerializable);
|
||||
xmlWriter.WriteEndElement();
|
||||
}
|
||||
|
||||
public void IncrementArrayCount(XmlWriterDelegator xmlWriter, Array array)
|
||||
{
|
||||
IncrementCollectionCount(xmlWriter, array.GetLength(0));
|
||||
}
|
||||
|
||||
public void IncrementCollectionCount(XmlWriterDelegator xmlWriter, ICollection collection)
|
||||
{
|
||||
IncrementCollectionCount(xmlWriter, collection.Count);
|
||||
}
|
||||
|
||||
public void IncrementCollectionCountGeneric<T>(XmlWriterDelegator xmlWriter, ICollection<T> collection)
|
||||
{
|
||||
IncrementCollectionCount(xmlWriter, collection.Count);
|
||||
}
|
||||
|
||||
private void IncrementCollectionCount(XmlWriterDelegator xmlWriter, int size)
|
||||
{
|
||||
IncrementItemCount(size);
|
||||
WriteArraySize(xmlWriter, size);
|
||||
}
|
||||
|
||||
internal virtual void WriteArraySize(XmlWriterDelegator xmlWriter, int size)
|
||||
{
|
||||
}
|
||||
|
||||
public static T GetDefaultValue<T>()
|
||||
{
|
||||
return default(T);
|
||||
}
|
||||
|
||||
public static T GetNullableValue<T>(Nullable<T> value) where T : struct
|
||||
{
|
||||
// value.Value will throw if hasValue is false
|
||||
return value.Value;
|
||||
}
|
||||
|
||||
public static void ThrowRequiredMemberMustBeEmitted(string memberName, Type type)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new System.Runtime.Serialization.SerializationException(SR.Format(SR.RequiredMemberMustBeEmitted, memberName, type.FullName)));
|
||||
}
|
||||
|
||||
public static bool GetHasValue<T>(Nullable<T> value) where T : struct
|
||||
{
|
||||
return value.HasValue;
|
||||
}
|
||||
|
||||
internal void WriteIXmlSerializable(XmlWriterDelegator xmlWriter, object obj)
|
||||
{
|
||||
if (xmlSerializableWriter == null)
|
||||
{
|
||||
xmlSerializableWriter = new XmlSerializableWriter();
|
||||
}
|
||||
|
||||
WriteIXmlSerializable(xmlWriter, obj, xmlSerializableWriter);
|
||||
}
|
||||
|
||||
internal static void WriteRootIXmlSerializable(XmlWriterDelegator xmlWriter, object obj)
|
||||
{
|
||||
WriteIXmlSerializable(xmlWriter, obj, new XmlSerializableWriter());
|
||||
}
|
||||
|
||||
private static void WriteIXmlSerializable(XmlWriterDelegator xmlWriter, object obj, XmlSerializableWriter xmlSerializableWriter)
|
||||
{
|
||||
xmlSerializableWriter.BeginWrite(xmlWriter.Writer, obj);
|
||||
IXmlSerializable xmlSerializable = obj as IXmlSerializable;
|
||||
if (xmlSerializable != null)
|
||||
{
|
||||
xmlSerializable.WriteXml(xmlSerializableWriter);
|
||||
}
|
||||
else
|
||||
{
|
||||
XmlElement xmlElement = obj as XmlElement;
|
||||
if (xmlElement != null)
|
||||
{
|
||||
xmlElement.WriteTo(xmlSerializableWriter);
|
||||
}
|
||||
else
|
||||
{
|
||||
XmlNode[] xmlNodes = obj as XmlNode[];
|
||||
if (xmlNodes != null)
|
||||
{
|
||||
foreach (XmlNode xmlNode in xmlNodes)
|
||||
{
|
||||
xmlNode.WriteTo(xmlSerializableWriter);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(SR.Format(SR.UnknownXmlType, DataContract.GetClrTypeFullName(obj.GetType()))));
|
||||
}
|
||||
}
|
||||
}
|
||||
xmlSerializableWriter.EndWrite();
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
internal void GetObjectData(
|
||||
System.Runtime.Serialization.ISerializable obj,
|
||||
System.Runtime.Serialization.SerializationInfo serInfo,
|
||||
System.Runtime.Serialization.StreamingContext context)
|
||||
{
|
||||
// Demand the serialization formatter permission every time
|
||||
//Globals.SerializationFormatterPermission.Demand();
|
||||
obj.GetObjectData(serInfo, context);
|
||||
}
|
||||
|
||||
public void WriteISerializable(XmlWriterDelegator xmlWriter, System.Runtime.Serialization.ISerializable obj)
|
||||
{
|
||||
Type objType = obj.GetType();
|
||||
System.Runtime.Serialization.SerializationInfo serInfo = new System.Runtime.Serialization.SerializationInfo(objType, XmlObjectSerializer.FormatterConverter, !UnsafeTypeForwardingEnabled);
|
||||
GetObjectData(obj, serInfo, GetStreamingContext());
|
||||
|
||||
if (!UnsafeTypeForwardingEnabled && serInfo.AssemblyName == Globals.MscorlibAssemblyName)
|
||||
{
|
||||
// Throw if a malicious type tries to set its assembly name to "0" to get deserialized in mscorlib
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(SR.Format(SR.ISerializableAssemblyNameSetToZero, DataContract.GetClrTypeFullName(obj.GetType()))));
|
||||
}
|
||||
|
||||
WriteSerializationInfo(xmlWriter, objType, serInfo);
|
||||
}
|
||||
|
||||
internal void WriteSerializationInfo(XmlWriterDelegator xmlWriter, Type objType, System.Runtime.Serialization.SerializationInfo serInfo)
|
||||
{
|
||||
if (DataContract.GetClrTypeFullName(objType) != serInfo.FullTypeName)
|
||||
{
|
||||
if (DataContractResolver != null)
|
||||
{
|
||||
if (ResolveType(serInfo.ObjectType, objType, out XmlDictionaryString typeName, out XmlDictionaryString typeNs))
|
||||
{
|
||||
xmlWriter.WriteAttributeQualifiedName(Globals.SerPrefix, DictionaryGlobals.ISerializableFactoryTypeLocalName, DictionaryGlobals.SerializationNamespace, typeName, typeNs);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DataContract.GetDefaultStableName(serInfo.FullTypeName, out string typeName, out string typeNs);
|
||||
xmlWriter.WriteAttributeQualifiedName(Globals.SerPrefix, DictionaryGlobals.ISerializableFactoryTypeLocalName, DictionaryGlobals.SerializationNamespace, DataContract.GetClrTypeString(typeName), DataContract.GetClrTypeString(typeNs));
|
||||
}
|
||||
}
|
||||
|
||||
WriteClrTypeInfo(xmlWriter, objType, serInfo);
|
||||
IncrementItemCount(serInfo.MemberCount);
|
||||
foreach (System.Runtime.Serialization.SerializationEntry serEntry in serInfo)
|
||||
{
|
||||
XmlDictionaryString name = DataContract.GetClrTypeString(DataContract.EncodeLocalName(serEntry.Name));
|
||||
xmlWriter.WriteStartElement(name, DictionaryGlobals.EmptyString);
|
||||
object obj = serEntry.Value;
|
||||
if (obj == null)
|
||||
{
|
||||
WriteNull(xmlWriter);
|
||||
}
|
||||
else
|
||||
{
|
||||
InternalSerializeReference(xmlWriter, obj, false /*isDeclaredType*/, false /*writeXsiType*/, -1, Globals.TypeOfObject.TypeHandle);
|
||||
}
|
||||
|
||||
xmlWriter.WriteEndElement();
|
||||
}
|
||||
}
|
||||
|
||||
public void WriteExtensionData(XmlWriterDelegator xmlWriter, ExtensionDataObject extensionData, int memberIndex)
|
||||
{
|
||||
if (IgnoreExtensionDataObject || extensionData == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
IList<ExtensionDataMember> members = extensionData.Members;
|
||||
if (members != null)
|
||||
{
|
||||
for (int i = 0; i < extensionData.Members.Count; i++)
|
||||
{
|
||||
ExtensionDataMember member = extensionData.Members[i];
|
||||
if (member.MemberIndex == memberIndex)
|
||||
{
|
||||
WriteExtensionDataMember(xmlWriter, member);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void WriteExtensionDataMember(XmlWriterDelegator xmlWriter, ExtensionDataMember member)
|
||||
{
|
||||
xmlWriter.WriteStartElement(member.Name, member.Namespace);
|
||||
IDataNode dataNode = member.Value;
|
||||
WriteExtensionDataValue(xmlWriter, dataNode);
|
||||
xmlWriter.WriteEndElement();
|
||||
}
|
||||
|
||||
internal virtual void WriteExtensionDataTypeInfo(XmlWriterDelegator xmlWriter, IDataNode dataNode)
|
||||
{
|
||||
if (dataNode.DataContractName != null)
|
||||
{
|
||||
WriteTypeInfo(xmlWriter, dataNode.DataContractName, dataNode.DataContractNamespace);
|
||||
}
|
||||
|
||||
WriteClrTypeInfo(xmlWriter, dataNode.DataType, dataNode.ClrTypeName, dataNode.ClrAssemblyName);
|
||||
}
|
||||
|
||||
internal void WriteExtensionDataValue(XmlWriterDelegator xmlWriter, IDataNode dataNode)
|
||||
{
|
||||
IncrementItemCount(1);
|
||||
if (dataNode == null)
|
||||
{
|
||||
WriteNull(xmlWriter);
|
||||
return;
|
||||
}
|
||||
|
||||
if (dataNode.PreservesReferences
|
||||
&& OnHandleReference(xmlWriter, (dataNode.Value == null ? dataNode : dataNode.Value), true /*canContainCyclicReference*/))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Type dataType = dataNode.DataType;
|
||||
if (dataType == Globals.TypeOfClassDataNode)
|
||||
{
|
||||
WriteExtensionClassData(xmlWriter, (ClassDataNode)dataNode);
|
||||
}
|
||||
else if (dataType == Globals.TypeOfCollectionDataNode)
|
||||
{
|
||||
WriteExtensionCollectionData(xmlWriter, (CollectionDataNode)dataNode);
|
||||
}
|
||||
else if (dataType == Globals.TypeOfXmlDataNode)
|
||||
{
|
||||
WriteExtensionXmlData(xmlWriter, (XmlDataNode)dataNode);
|
||||
}
|
||||
else if (dataType == Globals.TypeOfISerializableDataNode)
|
||||
{
|
||||
WriteExtensionISerializableData(xmlWriter, (ISerializableDataNode)dataNode);
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteExtensionDataTypeInfo(xmlWriter, dataNode);
|
||||
|
||||
if (dataType == Globals.TypeOfObject)
|
||||
{
|
||||
// NOTE: serialize value in DataNode<object> since it may contain non-primitive
|
||||
// deserialized object (ex. empty class)
|
||||
object o = dataNode.Value;
|
||||
if (o != null)
|
||||
{
|
||||
InternalSerialize(xmlWriter, o, false /*isDeclaredType*/, false /*writeXsiType*/, -1, o.GetType().TypeHandle);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
xmlWriter.WriteExtensionData(dataNode);
|
||||
}
|
||||
}
|
||||
if (dataNode.PreservesReferences)
|
||||
{
|
||||
OnEndHandleReference(xmlWriter, (dataNode.Value == null ? dataNode : dataNode.Value), true /*canContainCyclicReference*/);
|
||||
}
|
||||
}
|
||||
|
||||
internal bool TryWriteDeserializedExtensionData(XmlWriterDelegator xmlWriter, IDataNode dataNode)
|
||||
{
|
||||
object o = dataNode.Value;
|
||||
if (o == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Type declaredType = (dataNode.DataContractName == null) ? o.GetType() : Globals.TypeOfObject;
|
||||
InternalSerialize(xmlWriter, o, false /*isDeclaredType*/, false /*writeXsiType*/, -1, declaredType.TypeHandle);
|
||||
return true;
|
||||
}
|
||||
|
||||
private void WriteExtensionClassData(XmlWriterDelegator xmlWriter, ClassDataNode dataNode)
|
||||
{
|
||||
if (!TryWriteDeserializedExtensionData(xmlWriter, dataNode))
|
||||
{
|
||||
WriteExtensionDataTypeInfo(xmlWriter, dataNode);
|
||||
|
||||
IList<ExtensionDataMember> members = dataNode.Members;
|
||||
if (members != null)
|
||||
{
|
||||
for (int i = 0; i < members.Count; i++)
|
||||
{
|
||||
WriteExtensionDataMember(xmlWriter, members[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void WriteExtensionCollectionData(XmlWriterDelegator xmlWriter, CollectionDataNode dataNode)
|
||||
{
|
||||
if (!TryWriteDeserializedExtensionData(xmlWriter, dataNode))
|
||||
{
|
||||
WriteExtensionDataTypeInfo(xmlWriter, dataNode);
|
||||
|
||||
WriteArraySize(xmlWriter, dataNode.Size);
|
||||
|
||||
IList<IDataNode> items = dataNode.Items;
|
||||
if (items != null)
|
||||
{
|
||||
for (int i = 0; i < items.Count; i++)
|
||||
{
|
||||
xmlWriter.WriteStartElement(dataNode.ItemName, dataNode.ItemNamespace);
|
||||
WriteExtensionDataValue(xmlWriter, items[i]);
|
||||
xmlWriter.WriteEndElement();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void WriteExtensionISerializableData(XmlWriterDelegator xmlWriter, ISerializableDataNode dataNode)
|
||||
{
|
||||
if (!TryWriteDeserializedExtensionData(xmlWriter, dataNode))
|
||||
{
|
||||
WriteExtensionDataTypeInfo(xmlWriter, dataNode);
|
||||
|
||||
if (dataNode.FactoryTypeName != null)
|
||||
{
|
||||
xmlWriter.WriteAttributeQualifiedName(Globals.SerPrefix, DictionaryGlobals.ISerializableFactoryTypeLocalName, DictionaryGlobals.SerializationNamespace, dataNode.FactoryTypeName, dataNode.FactoryTypeNamespace);
|
||||
}
|
||||
|
||||
IList<ISerializableDataMember> members = dataNode.Members;
|
||||
if (members != null)
|
||||
{
|
||||
for (int i = 0; i < members.Count; i++)
|
||||
{
|
||||
ISerializableDataMember member = members[i];
|
||||
xmlWriter.WriteStartElement(member.Name, string.Empty);
|
||||
WriteExtensionDataValue(xmlWriter, member.Value);
|
||||
xmlWriter.WriteEndElement();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void WriteExtensionXmlData(XmlWriterDelegator xmlWriter, XmlDataNode dataNode)
|
||||
{
|
||||
if (!TryWriteDeserializedExtensionData(xmlWriter, dataNode))
|
||||
{
|
||||
IList<XmlAttribute> xmlAttributes = dataNode.XmlAttributes;
|
||||
if (xmlAttributes != null)
|
||||
{
|
||||
foreach (XmlAttribute attribute in xmlAttributes)
|
||||
{
|
||||
attribute.WriteTo(xmlWriter.Writer);
|
||||
}
|
||||
}
|
||||
WriteExtensionDataTypeInfo(xmlWriter, dataNode);
|
||||
|
||||
IList<XmlNode> xmlChildNodes = dataNode.XmlChildNodes;
|
||||
if (xmlChildNodes != null)
|
||||
{
|
||||
foreach (XmlNode node in xmlChildNodes)
|
||||
{
|
||||
node.WriteTo(xmlWriter.Writer);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void WriteDataContractValue(DataContract dataContract, XmlWriterDelegator xmlWriter, object obj, RuntimeTypeHandle declaredTypeHandle)
|
||||
{
|
||||
dataContract.WriteXmlValue(xmlWriter, obj, this);
|
||||
}
|
||||
|
||||
protected virtual void WriteNull(XmlWriterDelegator xmlWriter)
|
||||
{
|
||||
XmlObjectSerializer.WriteNull(xmlWriter);
|
||||
}
|
||||
|
||||
private void WriteResolvedTypeInfo(XmlWriterDelegator writer, Type objectType, Type declaredType)
|
||||
{
|
||||
if (ResolveType(objectType, declaredType, out XmlDictionaryString typeName, out XmlDictionaryString typeNamespace))
|
||||
{
|
||||
WriteTypeInfo(writer, typeName, typeNamespace);
|
||||
}
|
||||
}
|
||||
|
||||
private bool ResolveType(Type objectType, Type declaredType, out XmlDictionaryString typeName, out XmlDictionaryString typeNamespace)
|
||||
{
|
||||
if (!DataContractResolver.TryResolveType(objectType, declaredType, KnownTypeResolver, out typeName, out typeNamespace))
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(SR.Format(SR.ResolveTypeReturnedFalse, DataContract.GetClrTypeFullName(DataContractResolver.GetType()), DataContract.GetClrTypeFullName(objectType))));
|
||||
}
|
||||
if (typeName == null)
|
||||
{
|
||||
if (typeNamespace == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(SR.Format(SR.ResolveTypeReturnedNull, DataContract.GetClrTypeFullName(DataContractResolver.GetType()), DataContract.GetClrTypeFullName(objectType))));
|
||||
}
|
||||
}
|
||||
if (typeNamespace == null)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(SR.Format(SR.ResolveTypeReturnedNull, DataContract.GetClrTypeFullName(DataContractResolver.GetType()), DataContract.GetClrTypeFullName(objectType))));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
protected virtual bool WriteTypeInfo(XmlWriterDelegator writer, DataContract contract, DataContract declaredContract)
|
||||
{
|
||||
if (!XmlObjectSerializer.IsContractDeclared(contract, declaredContract))
|
||||
{
|
||||
if (DataContractResolver == null)
|
||||
{
|
||||
WriteTypeInfo(writer, contract.Name, contract.Namespace);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteResolvedTypeInfo(writer, contract.OriginalUnderlyingType, declaredContract.OriginalUnderlyingType);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
protected virtual void WriteTypeInfo(XmlWriterDelegator writer, string dataContractName, string dataContractNamespace)
|
||||
{
|
||||
writer.WriteAttributeQualifiedName(Globals.XsiPrefix, DictionaryGlobals.XsiTypeLocalName, DictionaryGlobals.SchemaInstanceNamespace, dataContractName, dataContractNamespace);
|
||||
}
|
||||
|
||||
protected virtual void WriteTypeInfo(XmlWriterDelegator writer, XmlDictionaryString dataContractName, XmlDictionaryString dataContractNamespace)
|
||||
{
|
||||
writer.WriteAttributeQualifiedName(Globals.XsiPrefix, DictionaryGlobals.XsiTypeLocalName, DictionaryGlobals.SchemaInstanceNamespace, dataContractName, dataContractNamespace);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,406 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Xml;
|
||||
using DataContractResolver = System.Runtime.Serialization.DataContractResolver;
|
||||
using InvalidDataContractException = System.Runtime.Serialization.InvalidDataContractException;
|
||||
using ISurrogateSelector = System.Runtime.Serialization.ISurrogateSelector;
|
||||
using SerializationBinder = System.Runtime.Serialization.SerializationBinder;
|
||||
using SerializationInfo = System.Runtime.Serialization.SerializationInfo;
|
||||
using StreamingContext = System.Runtime.Serialization.StreamingContext;
|
||||
|
||||
namespace Compat.Runtime.Serialization
|
||||
{
|
||||
internal class XmlObjectSerializerWriteContextComplex : XmlObjectSerializerWriteContext
|
||||
{
|
||||
protected IDataContractSurrogate dataContractSurrogate;
|
||||
private readonly SerializationMode mode;
|
||||
private readonly SerializationBinder binder;
|
||||
private readonly ISurrogateSelector surrogateSelector;
|
||||
private StreamingContext streamingContext;
|
||||
private Hashtable surrogateDataContracts;
|
||||
|
||||
internal XmlObjectSerializerWriteContextComplex(
|
||||
DataContractSerializer serializer,
|
||||
DataContract rootTypeDataContract,
|
||||
DataContractResolver dataContractResolver)
|
||||
: base(serializer, rootTypeDataContract, dataContractResolver)
|
||||
{
|
||||
mode = SerializationMode.SharedContract;
|
||||
preserveObjectReferences = serializer.PreserveObjectReferences;
|
||||
dataContractSurrogate = serializer.DataContractSurrogate;
|
||||
}
|
||||
|
||||
internal XmlObjectSerializerWriteContextComplex(NetDataContractSerializer serializer, Hashtable surrogateDataContracts)
|
||||
: base(serializer)
|
||||
{
|
||||
mode = SerializationMode.SharedType;
|
||||
preserveObjectReferences = true;
|
||||
streamingContext = serializer.Context;
|
||||
binder = serializer.Binder;
|
||||
surrogateSelector = serializer.SurrogateSelector;
|
||||
this.surrogateDataContracts = surrogateDataContracts;
|
||||
}
|
||||
|
||||
internal XmlObjectSerializerWriteContextComplex(XmlObjectSerializer serializer, int maxItemsInObjectGraph, StreamingContext streamingContext, bool ignoreExtensionDataObject)
|
||||
: base(serializer, maxItemsInObjectGraph, streamingContext, ignoreExtensionDataObject)
|
||||
{
|
||||
}
|
||||
|
||||
internal override SerializationMode Mode => mode;
|
||||
|
||||
internal override DataContract GetDataContract(RuntimeTypeHandle typeHandle, Type type)
|
||||
{
|
||||
DataContract dataContract = null;
|
||||
if (mode == SerializationMode.SharedType && surrogateSelector != null)
|
||||
{
|
||||
dataContract = NetDataContractSerializer.GetDataContractFromSurrogateSelector(surrogateSelector, streamingContext, typeHandle, type, ref surrogateDataContracts);
|
||||
}
|
||||
|
||||
if (dataContract != null)
|
||||
{
|
||||
if (IsGetOnlyCollection && dataContract is SurrogateDataContract)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.Format(SR.SurrogatesWithGetOnlyCollectionsNotSupportedSerDeser,
|
||||
DataContract.GetClrTypeFullName(dataContract.UnderlyingType))));
|
||||
}
|
||||
return dataContract;
|
||||
}
|
||||
|
||||
return base.GetDataContract(typeHandle, type);
|
||||
}
|
||||
|
||||
internal override DataContract GetDataContract(int id, RuntimeTypeHandle typeHandle)
|
||||
{
|
||||
DataContract dataContract = null;
|
||||
if (mode == SerializationMode.SharedType && surrogateSelector != null)
|
||||
{
|
||||
dataContract = NetDataContractSerializer.GetDataContractFromSurrogateSelector(surrogateSelector, streamingContext, typeHandle, null /*type*/, ref surrogateDataContracts);
|
||||
}
|
||||
|
||||
if (dataContract != null)
|
||||
{
|
||||
if (IsGetOnlyCollection && dataContract is SurrogateDataContract)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.Format(SR.SurrogatesWithGetOnlyCollectionsNotSupportedSerDeser,
|
||||
DataContract.GetClrTypeFullName(dataContract.UnderlyingType))));
|
||||
}
|
||||
return dataContract;
|
||||
}
|
||||
|
||||
return base.GetDataContract(id, typeHandle);
|
||||
}
|
||||
|
||||
internal override DataContract GetDataContractSkipValidation(int typeId, RuntimeTypeHandle typeHandle, Type type)
|
||||
{
|
||||
DataContract dataContract = null;
|
||||
if (mode == SerializationMode.SharedType && surrogateSelector != null)
|
||||
{
|
||||
dataContract = NetDataContractSerializer.GetDataContractFromSurrogateSelector(surrogateSelector, streamingContext, typeHandle, null /*type*/, ref surrogateDataContracts);
|
||||
}
|
||||
|
||||
if (dataContract != null)
|
||||
{
|
||||
if (IsGetOnlyCollection && dataContract is SurrogateDataContract)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.Format(SR.SurrogatesWithGetOnlyCollectionsNotSupportedSerDeser,
|
||||
DataContract.GetClrTypeFullName(dataContract.UnderlyingType))));
|
||||
}
|
||||
return dataContract;
|
||||
}
|
||||
|
||||
return base.GetDataContractSkipValidation(typeId, typeHandle, type);
|
||||
}
|
||||
|
||||
internal override bool WriteClrTypeInfo(XmlWriterDelegator xmlWriter, DataContract dataContract)
|
||||
{
|
||||
if (mode == SerializationMode.SharedType)
|
||||
{
|
||||
NetDataContractSerializer.WriteClrTypeInfo(xmlWriter, dataContract, binder);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
internal override bool WriteClrTypeInfo(XmlWriterDelegator xmlWriter, Type dataContractType, string clrTypeName, string clrAssemblyName)
|
||||
{
|
||||
if (mode == SerializationMode.SharedType)
|
||||
{
|
||||
NetDataContractSerializer.WriteClrTypeInfo(xmlWriter, dataContractType, binder, clrTypeName, clrAssemblyName);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
internal override bool WriteClrTypeInfo(XmlWriterDelegator xmlWriter, Type dataContractType, SerializationInfo serInfo)
|
||||
{
|
||||
if (mode == SerializationMode.SharedType)
|
||||
{
|
||||
NetDataContractSerializer.WriteClrTypeInfo(xmlWriter, dataContractType, binder, serInfo);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public override void WriteAnyType(XmlWriterDelegator xmlWriter, object value)
|
||||
{
|
||||
if (!OnHandleReference(xmlWriter, value, false /*canContainCyclicReference*/))
|
||||
{
|
||||
xmlWriter.WriteAnyType(value);
|
||||
}
|
||||
}
|
||||
|
||||
public override void WriteString(XmlWriterDelegator xmlWriter, string value)
|
||||
{
|
||||
if (!OnHandleReference(xmlWriter, value, false /*canContainCyclicReference*/))
|
||||
{
|
||||
xmlWriter.WriteString(value);
|
||||
}
|
||||
}
|
||||
public override void WriteString(XmlWriterDelegator xmlWriter, string value, XmlDictionaryString name, XmlDictionaryString ns)
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
WriteNull(xmlWriter, typeof(string), true/*isMemberTypeSerializable*/, name, ns);
|
||||
}
|
||||
else
|
||||
{
|
||||
xmlWriter.WriteStartElementPrimitive(name, ns);
|
||||
if (!OnHandleReference(xmlWriter, value, false /*canContainCyclicReference*/))
|
||||
{
|
||||
xmlWriter.WriteString(value);
|
||||
}
|
||||
|
||||
xmlWriter.WriteEndElementPrimitive();
|
||||
}
|
||||
}
|
||||
|
||||
public override void WriteBase64(XmlWriterDelegator xmlWriter, byte[] value)
|
||||
{
|
||||
if (!OnHandleReference(xmlWriter, value, false /*canContainCyclicReference*/))
|
||||
{
|
||||
xmlWriter.WriteBase64(value);
|
||||
}
|
||||
}
|
||||
public override void WriteBase64(XmlWriterDelegator xmlWriter, byte[] value, XmlDictionaryString name, XmlDictionaryString ns)
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
WriteNull(xmlWriter, typeof(byte[]), true/*isMemberTypeSerializable*/, name, ns);
|
||||
}
|
||||
else
|
||||
{
|
||||
xmlWriter.WriteStartElementPrimitive(name, ns);
|
||||
if (!OnHandleReference(xmlWriter, value, false /*canContainCyclicReference*/))
|
||||
{
|
||||
xmlWriter.WriteBase64(value);
|
||||
}
|
||||
|
||||
xmlWriter.WriteEndElementPrimitive();
|
||||
}
|
||||
}
|
||||
|
||||
public override void WriteUri(XmlWriterDelegator xmlWriter, Uri value)
|
||||
{
|
||||
if (!OnHandleReference(xmlWriter, value, false /*canContainCyclicReference*/))
|
||||
{
|
||||
xmlWriter.WriteUri(value);
|
||||
}
|
||||
}
|
||||
public override void WriteUri(XmlWriterDelegator xmlWriter, Uri value, XmlDictionaryString name, XmlDictionaryString ns)
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
WriteNull(xmlWriter, typeof(Uri), true/*isMemberTypeSerializable*/, name, ns);
|
||||
}
|
||||
else
|
||||
{
|
||||
xmlWriter.WriteStartElementPrimitive(name, ns);
|
||||
if (!OnHandleReference(xmlWriter, value, false /*canContainCyclicReference*/))
|
||||
{
|
||||
xmlWriter.WriteUri(value);
|
||||
}
|
||||
|
||||
xmlWriter.WriteEndElementPrimitive();
|
||||
}
|
||||
}
|
||||
|
||||
public override void WriteQName(XmlWriterDelegator xmlWriter, XmlQualifiedName value)
|
||||
{
|
||||
if (!OnHandleReference(xmlWriter, value, false /*canContainCyclicReference*/))
|
||||
{
|
||||
xmlWriter.WriteQName(value);
|
||||
}
|
||||
}
|
||||
public override void WriteQName(XmlWriterDelegator xmlWriter, XmlQualifiedName value, XmlDictionaryString name, XmlDictionaryString ns)
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
WriteNull(xmlWriter, typeof(XmlQualifiedName), true/*isMemberTypeSerializable*/, name, ns);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ns != null && ns.Value != null && ns.Value.Length > 0)
|
||||
{
|
||||
xmlWriter.WriteStartElement(Globals.ElementPrefix, name, ns);
|
||||
}
|
||||
else
|
||||
{
|
||||
xmlWriter.WriteStartElement(name, ns);
|
||||
}
|
||||
|
||||
if (!OnHandleReference(xmlWriter, value, false /*canContainCyclicReference*/))
|
||||
{
|
||||
xmlWriter.WriteQName(value);
|
||||
}
|
||||
|
||||
xmlWriter.WriteEndElement();
|
||||
}
|
||||
}
|
||||
|
||||
public override void InternalSerialize(XmlWriterDelegator xmlWriter, object obj, bool isDeclaredType, bool writeXsiType, int declaredTypeID, RuntimeTypeHandle declaredTypeHandle)
|
||||
{
|
||||
if (dataContractSurrogate == null)
|
||||
{
|
||||
base.InternalSerialize(xmlWriter, obj, isDeclaredType, writeXsiType, declaredTypeID, declaredTypeHandle);
|
||||
}
|
||||
else
|
||||
{
|
||||
InternalSerializeWithSurrogate(xmlWriter, obj, isDeclaredType, writeXsiType, declaredTypeID, declaredTypeHandle);
|
||||
}
|
||||
}
|
||||
|
||||
internal override bool OnHandleReference(XmlWriterDelegator xmlWriter, object obj, bool canContainCyclicReference)
|
||||
{
|
||||
if (preserveObjectReferences && !IsGetOnlyCollection)
|
||||
{
|
||||
bool isNew = true;
|
||||
int objectId = SerializedObjects.GetId(obj, ref isNew);
|
||||
if (isNew)
|
||||
{
|
||||
xmlWriter.WriteAttributeInt(Globals.SerPrefix, DictionaryGlobals.IdLocalName, DictionaryGlobals.SerializationNamespace, objectId);
|
||||
}
|
||||
else
|
||||
{
|
||||
xmlWriter.WriteAttributeInt(Globals.SerPrefix, DictionaryGlobals.RefLocalName, DictionaryGlobals.SerializationNamespace, objectId);
|
||||
xmlWriter.WriteAttributeBool(Globals.XsiPrefix, DictionaryGlobals.XsiNilLocalName, DictionaryGlobals.SchemaInstanceNamespace, true);
|
||||
}
|
||||
return !isNew;
|
||||
}
|
||||
return base.OnHandleReference(xmlWriter, obj, canContainCyclicReference);
|
||||
}
|
||||
|
||||
internal override void OnEndHandleReference(XmlWriterDelegator xmlWriter, object obj, bool canContainCyclicReference)
|
||||
{
|
||||
if (preserveObjectReferences && !IsGetOnlyCollection)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
base.OnEndHandleReference(xmlWriter, obj, canContainCyclicReference);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
private bool CheckIfTypeSerializableForSharedTypeMode(Type memberType)
|
||||
{
|
||||
Fx.Assert(surrogateSelector != null, "Method should not be called when surrogateSelector is null.");
|
||||
return (surrogateSelector.GetSurrogate(memberType, streamingContext, out ISurrogateSelector surrogateSelectorNotUsed) != null);
|
||||
}
|
||||
|
||||
internal override void CheckIfTypeSerializable(Type memberType, bool isMemberTypeSerializable)
|
||||
{
|
||||
if (mode == SerializationMode.SharedType && surrogateSelector != null &&
|
||||
CheckIfTypeSerializableForSharedTypeMode(memberType))
|
||||
{
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (dataContractSurrogate != null)
|
||||
{
|
||||
while (memberType.IsArray)
|
||||
{
|
||||
memberType = memberType.GetElementType();
|
||||
}
|
||||
|
||||
memberType = DataContractSurrogateCaller.GetDataContractType(dataContractSurrogate, memberType);
|
||||
if (!DataContract.IsTypeSerializable(memberType))
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.Format(SR.TypeNotSerializable, memberType)));
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
base.CheckIfTypeSerializable(memberType, isMemberTypeSerializable);
|
||||
}
|
||||
|
||||
internal override Type GetSurrogatedType(Type type)
|
||||
{
|
||||
if (dataContractSurrogate == null)
|
||||
{
|
||||
return base.GetSurrogatedType(type);
|
||||
}
|
||||
else
|
||||
{
|
||||
type = DataContract.UnwrapNullableType(type);
|
||||
Type surrogateType = DataContractSerializer.GetSurrogatedType(dataContractSurrogate, type);
|
||||
if (IsGetOnlyCollection && surrogateType != type)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.Format(SR.SurrogatesWithGetOnlyCollectionsNotSupportedSerDeser,
|
||||
DataContract.GetClrTypeFullName(type))));
|
||||
}
|
||||
else
|
||||
{
|
||||
return surrogateType;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void InternalSerializeWithSurrogate(XmlWriterDelegator xmlWriter, object obj, bool isDeclaredType, bool writeXsiType, int declaredTypeID, RuntimeTypeHandle declaredTypeHandle)
|
||||
{
|
||||
RuntimeTypeHandle objTypeHandle = isDeclaredType ? declaredTypeHandle : Type.GetTypeHandle(obj);
|
||||
object oldObj = obj;
|
||||
int objOldId = 0;
|
||||
Type objType = Type.GetTypeFromHandle(objTypeHandle);
|
||||
Type declaredType = GetSurrogatedType(Type.GetTypeFromHandle(declaredTypeHandle));
|
||||
|
||||
declaredTypeHandle = declaredType.TypeHandle;
|
||||
obj = DataContractSerializer.SurrogateToDataContractType(dataContractSurrogate, obj, declaredType, ref objType);
|
||||
objTypeHandle = objType.TypeHandle;
|
||||
if (oldObj != obj)
|
||||
{
|
||||
objOldId = SerializedObjects.ReassignId(0, oldObj, obj);
|
||||
}
|
||||
|
||||
if (writeXsiType)
|
||||
{
|
||||
declaredType = Globals.TypeOfObject;
|
||||
SerializeWithXsiType(xmlWriter, obj, objTypeHandle, objType, -1, declaredType.TypeHandle, declaredType);
|
||||
}
|
||||
else if (declaredTypeHandle.Equals(objTypeHandle))
|
||||
{
|
||||
DataContract contract = GetDataContract(objTypeHandle, objType);
|
||||
SerializeWithoutXsiType(contract, xmlWriter, obj, declaredTypeHandle);
|
||||
}
|
||||
else
|
||||
{
|
||||
SerializeWithXsiType(xmlWriter, obj, objTypeHandle, objType, -1, declaredTypeHandle, declaredType);
|
||||
}
|
||||
if (oldObj != obj)
|
||||
{
|
||||
SerializedObjects.ReassignId(objOldId, obj, oldObj);
|
||||
}
|
||||
}
|
||||
|
||||
internal override void WriteArraySize(XmlWriterDelegator xmlWriter, int size)
|
||||
{
|
||||
if (preserveObjectReferences && size > -1)
|
||||
{
|
||||
xmlWriter.WriteAttributeInt(Globals.SerPrefix, DictionaryGlobals.ArraySizeLocalName, DictionaryGlobals.SerializationNamespace, size);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,199 @@
|
||||
using System;
|
||||
using System.Xml;
|
||||
using System.Xml.Schema;
|
||||
using System.Xml.Serialization;
|
||||
|
||||
namespace Compat.Runtime.Serialization
|
||||
{
|
||||
internal class XmlSerializableReader : XmlReader, IXmlLineInfo, IXmlTextParser
|
||||
{
|
||||
private XmlReaderDelegator xmlReader;
|
||||
private int startDepth;
|
||||
private bool isRootEmptyElement;
|
||||
private XmlReader innerReader;
|
||||
|
||||
private XmlReader InnerReader => innerReader;
|
||||
|
||||
internal void BeginRead(XmlReaderDelegator xmlReader)
|
||||
{
|
||||
if (xmlReader.NodeType != XmlNodeType.Element)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializerReadContext.CreateUnexpectedStateException(XmlNodeType.Element, xmlReader));
|
||||
}
|
||||
|
||||
this.xmlReader = xmlReader;
|
||||
startDepth = xmlReader.Depth;
|
||||
innerReader = xmlReader.UnderlyingReader;
|
||||
isRootEmptyElement = InnerReader.IsEmptyElement;
|
||||
}
|
||||
|
||||
internal void EndRead()
|
||||
{
|
||||
if (isRootEmptyElement)
|
||||
{
|
||||
xmlReader.Read();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (xmlReader.IsStartElement() && xmlReader.Depth == startDepth)
|
||||
{
|
||||
xmlReader.Read();
|
||||
}
|
||||
|
||||
while (xmlReader.Depth > startDepth)
|
||||
{
|
||||
if (!xmlReader.Read())
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializerReadContext.CreateUnexpectedStateException(XmlNodeType.EndElement, xmlReader));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override bool Read()
|
||||
{
|
||||
XmlReader reader = InnerReader;
|
||||
if (reader.Depth == startDepth)
|
||||
{
|
||||
if (reader.NodeType == XmlNodeType.EndElement ||
|
||||
(reader.NodeType == XmlNodeType.Element && reader.IsEmptyElement))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return reader.Read();
|
||||
}
|
||||
|
||||
public override void Close()
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(SR.IXmlSerializableIllegalOperation));
|
||||
}
|
||||
|
||||
public override XmlReaderSettings Settings => InnerReader.Settings;
|
||||
public override XmlNodeType NodeType => InnerReader.NodeType;
|
||||
public override string Name => InnerReader.Name;
|
||||
public override string LocalName => InnerReader.LocalName;
|
||||
public override string NamespaceURI => InnerReader.NamespaceURI;
|
||||
public override string Prefix => InnerReader.Prefix;
|
||||
public override bool HasValue => InnerReader.HasValue;
|
||||
public override string Value => InnerReader.Value;
|
||||
public override int Depth => InnerReader.Depth;
|
||||
public override string BaseURI => InnerReader.BaseURI;
|
||||
public override bool IsEmptyElement => InnerReader.IsEmptyElement;
|
||||
public override bool IsDefault => InnerReader.IsDefault;
|
||||
public override char QuoteChar => InnerReader.QuoteChar;
|
||||
public override XmlSpace XmlSpace => InnerReader.XmlSpace;
|
||||
public override string XmlLang => InnerReader.XmlLang;
|
||||
public override IXmlSchemaInfo SchemaInfo => InnerReader.SchemaInfo;
|
||||
public override Type ValueType => InnerReader.ValueType;
|
||||
public override int AttributeCount => InnerReader.AttributeCount;
|
||||
public override string this[int i] => InnerReader[i];
|
||||
public override string this[string name] => InnerReader[name];
|
||||
public override string this[string name, string namespaceURI] => InnerReader[name, namespaceURI];
|
||||
public override bool EOF => InnerReader.EOF;
|
||||
public override ReadState ReadState => InnerReader.ReadState;
|
||||
public override XmlNameTable NameTable => InnerReader.NameTable;
|
||||
public override bool CanResolveEntity => InnerReader.CanResolveEntity;
|
||||
public override bool CanReadBinaryContent => InnerReader.CanReadBinaryContent;
|
||||
public override bool CanReadValueChunk => InnerReader.CanReadValueChunk;
|
||||
public override bool HasAttributes => InnerReader.HasAttributes;
|
||||
|
||||
public override string GetAttribute(string name) { return InnerReader.GetAttribute(name); }
|
||||
public override string GetAttribute(string name, string namespaceURI) { return InnerReader.GetAttribute(name, namespaceURI); }
|
||||
public override string GetAttribute(int i) { return InnerReader.GetAttribute(i); }
|
||||
public override bool MoveToAttribute(string name) { return InnerReader.MoveToAttribute(name); }
|
||||
public override bool MoveToAttribute(string name, string ns) { return InnerReader.MoveToAttribute(name, ns); }
|
||||
public override void MoveToAttribute(int i) { InnerReader.MoveToAttribute(i); }
|
||||
public override bool MoveToFirstAttribute() { return InnerReader.MoveToFirstAttribute(); }
|
||||
public override bool MoveToNextAttribute() { return InnerReader.MoveToNextAttribute(); }
|
||||
public override bool MoveToElement() { return InnerReader.MoveToElement(); }
|
||||
public override string LookupNamespace(string prefix) { return InnerReader.LookupNamespace(prefix); }
|
||||
public override bool ReadAttributeValue() { return InnerReader.ReadAttributeValue(); }
|
||||
public override void ResolveEntity() { InnerReader.ResolveEntity(); }
|
||||
public override bool IsStartElement() { return InnerReader.IsStartElement(); }
|
||||
public override bool IsStartElement(string name) { return InnerReader.IsStartElement(name); }
|
||||
public override bool IsStartElement(string localname, string ns) { return InnerReader.IsStartElement(localname, ns); }
|
||||
public override XmlNodeType MoveToContent() { return InnerReader.MoveToContent(); }
|
||||
|
||||
public override object ReadContentAsObject() { return InnerReader.ReadContentAsObject(); }
|
||||
public override bool ReadContentAsBoolean() { return InnerReader.ReadContentAsBoolean(); }
|
||||
public override DateTime ReadContentAsDateTime() { return InnerReader.ReadContentAsDateTime(); }
|
||||
public override double ReadContentAsDouble() { return InnerReader.ReadContentAsDouble(); }
|
||||
public override int ReadContentAsInt() { return InnerReader.ReadContentAsInt(); }
|
||||
public override long ReadContentAsLong() { return InnerReader.ReadContentAsLong(); }
|
||||
public override string ReadContentAsString() { return InnerReader.ReadContentAsString(); }
|
||||
public override object ReadContentAs(Type returnType, IXmlNamespaceResolver namespaceResolver) { return InnerReader.ReadContentAs(returnType, namespaceResolver); }
|
||||
public override int ReadContentAsBase64(byte[] buffer, int index, int count) { return InnerReader.ReadContentAsBase64(buffer, index, count); }
|
||||
public override int ReadContentAsBinHex(byte[] buffer, int index, int count) { return InnerReader.ReadContentAsBinHex(buffer, index, count); }
|
||||
public override int ReadValueChunk(char[] buffer, int index, int count) { return InnerReader.ReadValueChunk(buffer, index, count); }
|
||||
public override string ReadString() { return InnerReader.ReadString(); }
|
||||
|
||||
// IXmlTextParser members
|
||||
bool IXmlTextParser.Normalized
|
||||
{
|
||||
get
|
||||
{
|
||||
IXmlTextParser xmlTextParser = InnerReader as IXmlTextParser;
|
||||
return (xmlTextParser == null) ? xmlReader.Normalized : xmlTextParser.Normalized;
|
||||
}
|
||||
set
|
||||
{
|
||||
IXmlTextParser xmlTextParser = InnerReader as IXmlTextParser;
|
||||
if (xmlTextParser == null)
|
||||
{
|
||||
xmlReader.Normalized = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
xmlTextParser.Normalized = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
WhitespaceHandling IXmlTextParser.WhitespaceHandling
|
||||
{
|
||||
get
|
||||
{
|
||||
IXmlTextParser xmlTextParser = InnerReader as IXmlTextParser;
|
||||
return (xmlTextParser == null) ? xmlReader.WhitespaceHandling : xmlTextParser.WhitespaceHandling;
|
||||
}
|
||||
set
|
||||
{
|
||||
IXmlTextParser xmlTextParser = InnerReader as IXmlTextParser;
|
||||
if (xmlTextParser == null)
|
||||
{
|
||||
xmlReader.WhitespaceHandling = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
xmlTextParser.WhitespaceHandling = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// IXmlLineInfo members
|
||||
bool IXmlLineInfo.HasLineInfo()
|
||||
{
|
||||
IXmlLineInfo xmlLineInfo = InnerReader as IXmlLineInfo;
|
||||
return (xmlLineInfo == null) ? xmlReader.HasLineInfo() : xmlLineInfo.HasLineInfo();
|
||||
}
|
||||
|
||||
int IXmlLineInfo.LineNumber
|
||||
{
|
||||
get
|
||||
{
|
||||
IXmlLineInfo xmlLineInfo = InnerReader as IXmlLineInfo;
|
||||
return (xmlLineInfo == null) ? xmlReader.LineNumber : xmlLineInfo.LineNumber;
|
||||
}
|
||||
}
|
||||
|
||||
int IXmlLineInfo.LinePosition
|
||||
{
|
||||
get
|
||||
{
|
||||
IXmlLineInfo xmlLineInfo = InnerReader as IXmlLineInfo;
|
||||
return (xmlLineInfo == null) ? xmlReader.LinePosition : xmlLineInfo.LinePosition;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
using System.Xml;
|
||||
|
||||
namespace Compat.Runtime.Serialization
|
||||
{
|
||||
internal class XmlSerializableWriter : XmlWriter
|
||||
{
|
||||
private XmlWriter _xmlWriter;
|
||||
private int _depth = 0;
|
||||
private object _obj;
|
||||
|
||||
internal void BeginWrite(XmlWriter xmlWriter, object obj)
|
||||
{
|
||||
_depth = 0;
|
||||
_xmlWriter = xmlWriter;
|
||||
_obj = obj;
|
||||
}
|
||||
|
||||
internal void EndWrite()
|
||||
{
|
||||
if (_depth != 0)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(SR.Format(SR.IXmlSerializableMissingEndElements, (_obj == null ? string.Empty : DataContract.GetClrTypeFullName(_obj.GetType())))));
|
||||
}
|
||||
|
||||
_obj = null;
|
||||
}
|
||||
|
||||
public override void WriteStartDocument()
|
||||
{
|
||||
if (WriteState == WriteState.Start)
|
||||
{
|
||||
_xmlWriter.WriteStartDocument();
|
||||
}
|
||||
}
|
||||
public override void WriteEndDocument() { _xmlWriter.WriteEndDocument(); }
|
||||
public override void WriteStartDocument(bool standalone)
|
||||
{
|
||||
if (WriteState == WriteState.Start)
|
||||
{
|
||||
_xmlWriter.WriteStartDocument(standalone);
|
||||
}
|
||||
}
|
||||
public override void WriteDocType(string name, string pubid, string sysid, string subset)
|
||||
{
|
||||
// XmlSerializer does not write doc type
|
||||
}
|
||||
|
||||
public override void WriteStartElement(string prefix, string localName, string ns)
|
||||
{
|
||||
_xmlWriter.WriteStartElement(prefix, localName, ns);
|
||||
_depth++;
|
||||
}
|
||||
|
||||
public override void WriteEndElement()
|
||||
{
|
||||
if (_depth == 0)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(SR.Format(SR.IXmlSerializableWritePastSubTree, (_obj == null ? string.Empty : DataContract.GetClrTypeFullName(_obj.GetType())))));
|
||||
}
|
||||
|
||||
_xmlWriter.WriteEndElement();
|
||||
_depth--;
|
||||
}
|
||||
|
||||
public override void WriteFullEndElement()
|
||||
{
|
||||
if (_depth == 0)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(SR.Format(SR.IXmlSerializableWritePastSubTree, (_obj == null ? string.Empty : DataContract.GetClrTypeFullName(_obj.GetType())))));
|
||||
}
|
||||
|
||||
_xmlWriter.WriteFullEndElement();
|
||||
_depth--;
|
||||
}
|
||||
|
||||
public override void Close()
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(SR.IXmlSerializableIllegalOperation));
|
||||
}
|
||||
|
||||
public override void WriteStartAttribute(string prefix, string localName, string ns)
|
||||
{
|
||||
_xmlWriter.WriteStartAttribute(prefix, localName, ns);
|
||||
}
|
||||
|
||||
public override void WriteEndAttribute() { _xmlWriter.WriteEndAttribute(); }
|
||||
public override void WriteCData(string text) { _xmlWriter.WriteCData(text); }
|
||||
public override void WriteComment(string text) { _xmlWriter.WriteComment(text); }
|
||||
public override void WriteProcessingInstruction(string name, string text) { _xmlWriter.WriteProcessingInstruction(name, text); }
|
||||
public override void WriteEntityRef(string name) { _xmlWriter.WriteEntityRef(name); }
|
||||
public override void WriteCharEntity(char ch) { _xmlWriter.WriteCharEntity(ch); }
|
||||
public override void WriteWhitespace(string ws) { _xmlWriter.WriteWhitespace(ws); }
|
||||
public override void WriteString(string text) { _xmlWriter.WriteString(text); }
|
||||
public override void WriteSurrogateCharEntity(char lowChar, char highChar) { _xmlWriter.WriteSurrogateCharEntity(lowChar, highChar); }
|
||||
public override void WriteChars(char[] buffer, int index, int count) { _xmlWriter.WriteChars(buffer, index, count); }
|
||||
public override void WriteRaw(char[] buffer, int index, int count) { _xmlWriter.WriteRaw(buffer, index, count); }
|
||||
public override void WriteRaw(string data) { _xmlWriter.WriteRaw(data); }
|
||||
public override void WriteBase64(byte[] buffer, int index, int count) { _xmlWriter.WriteBase64(buffer, index, count); }
|
||||
public override void WriteBinHex(byte[] buffer, int index, int count) { _xmlWriter.WriteBinHex(buffer, index, count); }
|
||||
public override WriteState WriteState => _xmlWriter.WriteState;
|
||||
public override void Flush() { _xmlWriter.Flush(); }
|
||||
public override void WriteName(string name) { _xmlWriter.WriteName(name); }
|
||||
public override void WriteQualifiedName(string localName, string ns) { _xmlWriter.WriteQualifiedName(localName, ns); }
|
||||
public override string LookupPrefix(string ns) { return _xmlWriter.LookupPrefix(ns); }
|
||||
public override XmlSpace XmlSpace => _xmlWriter.XmlSpace;
|
||||
public override string XmlLang => _xmlWriter.XmlLang;
|
||||
public override void WriteNmToken(string name) { _xmlWriter.WriteNmToken(name); }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,812 @@
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Xml;
|
||||
|
||||
namespace Compat.Runtime.Serialization
|
||||
{
|
||||
internal class XmlWriterDelegator
|
||||
{
|
||||
protected XmlWriter _writer;
|
||||
protected XmlDictionaryWriter _dictionaryWriter;
|
||||
internal int _depth;
|
||||
private int _prefixes;
|
||||
|
||||
public XmlWriterDelegator(XmlWriter writer)
|
||||
{
|
||||
_writer = writer ?? throw new ArgumentNullException(nameof(writer));
|
||||
_dictionaryWriter = writer as XmlDictionaryWriter;
|
||||
}
|
||||
|
||||
internal XmlWriter Writer => _writer;
|
||||
|
||||
internal void Flush()
|
||||
{
|
||||
_writer.Flush();
|
||||
}
|
||||
|
||||
internal string LookupPrefix(string ns)
|
||||
{
|
||||
return _writer.LookupPrefix(ns);
|
||||
}
|
||||
|
||||
private void WriteEndAttribute()
|
||||
{
|
||||
_writer.WriteEndAttribute();
|
||||
}
|
||||
|
||||
public void WriteEndElement()
|
||||
{
|
||||
_writer.WriteEndElement();
|
||||
_depth--;
|
||||
}
|
||||
|
||||
internal void WriteRaw(char[] buffer, int index, int count)
|
||||
{
|
||||
_writer.WriteRaw(buffer, index, count);
|
||||
}
|
||||
|
||||
internal void WriteRaw(string data)
|
||||
{
|
||||
_writer.WriteRaw(data);
|
||||
}
|
||||
|
||||
|
||||
internal void WriteXmlnsAttribute(XmlDictionaryString ns)
|
||||
{
|
||||
if (_dictionaryWriter != null)
|
||||
{
|
||||
if (ns != null)
|
||||
{
|
||||
_dictionaryWriter.WriteXmlnsAttribute(null, ns);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteXmlnsAttribute(ns.Value);
|
||||
}
|
||||
}
|
||||
|
||||
internal void WriteXmlnsAttribute(string ns)
|
||||
{
|
||||
if (ns != null)
|
||||
{
|
||||
if (ns.Length == 0)
|
||||
{
|
||||
_writer.WriteAttributeString("xmlns", string.Empty, null, ns);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_dictionaryWriter != null)
|
||||
{
|
||||
_dictionaryWriter.WriteXmlnsAttribute(null, ns);
|
||||
}
|
||||
else
|
||||
{
|
||||
string prefix = _writer.LookupPrefix(ns);
|
||||
if (prefix == null)
|
||||
{
|
||||
prefix = string.Format(CultureInfo.InvariantCulture, "d{0}p{1}", _depth, _prefixes);
|
||||
_prefixes++;
|
||||
_writer.WriteAttributeString("xmlns", prefix, null, ns);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal void WriteXmlnsAttribute(string prefix, XmlDictionaryString ns)
|
||||
{
|
||||
if (_dictionaryWriter != null)
|
||||
{
|
||||
_dictionaryWriter.WriteXmlnsAttribute(prefix, ns);
|
||||
}
|
||||
else
|
||||
{
|
||||
_writer.WriteAttributeString("xmlns", prefix, null, ns.Value);
|
||||
}
|
||||
}
|
||||
|
||||
private void WriteStartAttribute(string prefix, string localName, string ns)
|
||||
{
|
||||
_writer.WriteStartAttribute(prefix, localName, ns);
|
||||
}
|
||||
|
||||
private void WriteStartAttribute(string prefix, XmlDictionaryString localName, XmlDictionaryString namespaceUri)
|
||||
{
|
||||
if (_dictionaryWriter != null)
|
||||
{
|
||||
_dictionaryWriter.WriteStartAttribute(prefix, localName, namespaceUri);
|
||||
}
|
||||
else
|
||||
{
|
||||
_writer.WriteStartAttribute(prefix,
|
||||
(localName == null ? null : localName.Value),
|
||||
(namespaceUri == null ? null : namespaceUri.Value));
|
||||
}
|
||||
}
|
||||
|
||||
internal void WriteAttributeString(string prefix, string localName, string ns, string value)
|
||||
{
|
||||
WriteStartAttribute(prefix, localName, ns);
|
||||
WriteAttributeStringValue(value);
|
||||
WriteEndAttribute();
|
||||
}
|
||||
|
||||
internal void WriteAttributeString(string prefix, XmlDictionaryString attrName, XmlDictionaryString attrNs, string value)
|
||||
{
|
||||
WriteStartAttribute(prefix, attrName, attrNs);
|
||||
WriteAttributeStringValue(value);
|
||||
WriteEndAttribute();
|
||||
}
|
||||
|
||||
private void WriteAttributeStringValue(string value)
|
||||
{
|
||||
_writer.WriteValue(value);
|
||||
}
|
||||
|
||||
internal void WriteAttributeString(string prefix, XmlDictionaryString attrName, XmlDictionaryString attrNs, XmlDictionaryString value)
|
||||
{
|
||||
WriteStartAttribute(prefix, attrName, attrNs);
|
||||
WriteAttributeStringValue(value);
|
||||
WriteEndAttribute();
|
||||
}
|
||||
|
||||
private void WriteAttributeStringValue(XmlDictionaryString value)
|
||||
{
|
||||
if (_dictionaryWriter == null)
|
||||
{
|
||||
_writer.WriteString(value.Value);
|
||||
}
|
||||
else
|
||||
{
|
||||
_dictionaryWriter.WriteString(value);
|
||||
}
|
||||
}
|
||||
|
||||
internal void WriteAttributeInt(string prefix, XmlDictionaryString attrName, XmlDictionaryString attrNs, int value)
|
||||
{
|
||||
WriteStartAttribute(prefix, attrName, attrNs);
|
||||
WriteAttributeIntValue(value);
|
||||
WriteEndAttribute();
|
||||
}
|
||||
|
||||
private void WriteAttributeIntValue(int value)
|
||||
{
|
||||
_writer.WriteValue(value);
|
||||
}
|
||||
|
||||
internal void WriteAttributeBool(string prefix, XmlDictionaryString attrName, XmlDictionaryString attrNs, bool value)
|
||||
{
|
||||
WriteStartAttribute(prefix, attrName, attrNs);
|
||||
WriteAttributeBoolValue(value);
|
||||
WriteEndAttribute();
|
||||
}
|
||||
|
||||
private void WriteAttributeBoolValue(bool value)
|
||||
{
|
||||
_writer.WriteValue(value);
|
||||
}
|
||||
|
||||
internal void WriteAttributeQualifiedName(string attrPrefix, XmlDictionaryString attrName, XmlDictionaryString attrNs, string name, string ns)
|
||||
{
|
||||
WriteXmlnsAttribute(ns);
|
||||
WriteStartAttribute(attrPrefix, attrName, attrNs);
|
||||
WriteAttributeQualifiedNameValue(name, ns);
|
||||
WriteEndAttribute();
|
||||
}
|
||||
|
||||
private void WriteAttributeQualifiedNameValue(string name, string ns)
|
||||
{
|
||||
_writer.WriteQualifiedName(name, ns);
|
||||
}
|
||||
|
||||
internal void WriteAttributeQualifiedName(string attrPrefix, XmlDictionaryString attrName, XmlDictionaryString attrNs, XmlDictionaryString name, XmlDictionaryString ns)
|
||||
{
|
||||
WriteXmlnsAttribute(ns);
|
||||
WriteStartAttribute(attrPrefix, attrName, attrNs);
|
||||
WriteAttributeQualifiedNameValue(name, ns);
|
||||
WriteEndAttribute();
|
||||
}
|
||||
|
||||
private void WriteAttributeQualifiedNameValue(XmlDictionaryString name, XmlDictionaryString ns)
|
||||
{
|
||||
if (_dictionaryWriter == null)
|
||||
{
|
||||
_writer.WriteQualifiedName(name.Value, ns.Value);
|
||||
}
|
||||
else
|
||||
{
|
||||
_dictionaryWriter.WriteQualifiedName(name, ns);
|
||||
}
|
||||
}
|
||||
|
||||
internal void WriteStartElement(string localName, string ns)
|
||||
{
|
||||
WriteStartElement(null, localName, ns);
|
||||
}
|
||||
|
||||
internal virtual void WriteStartElement(string prefix, string localName, string ns)
|
||||
{
|
||||
_writer.WriteStartElement(prefix, localName, ns);
|
||||
_depth++;
|
||||
_prefixes = 1;
|
||||
}
|
||||
|
||||
public void WriteStartElement(XmlDictionaryString localName, XmlDictionaryString namespaceUri)
|
||||
{
|
||||
WriteStartElement(null, localName, namespaceUri);
|
||||
}
|
||||
|
||||
internal void WriteStartElement(string prefix, XmlDictionaryString localName, XmlDictionaryString namespaceUri)
|
||||
{
|
||||
if (_dictionaryWriter != null)
|
||||
{
|
||||
_dictionaryWriter.WriteStartElement(prefix, localName, namespaceUri);
|
||||
}
|
||||
else
|
||||
{
|
||||
_writer.WriteStartElement(prefix, (localName == null ? null : localName.Value), (namespaceUri == null ? null : namespaceUri.Value));
|
||||
}
|
||||
|
||||
_depth++;
|
||||
_prefixes = 1;
|
||||
}
|
||||
|
||||
internal void WriteStartElementPrimitive(XmlDictionaryString localName, XmlDictionaryString namespaceUri)
|
||||
{
|
||||
if (_dictionaryWriter != null)
|
||||
{
|
||||
_dictionaryWriter.WriteStartElement(null, localName, namespaceUri);
|
||||
}
|
||||
else
|
||||
{
|
||||
_writer.WriteStartElement(null, (localName == null ? null : localName.Value), (namespaceUri == null ? null : namespaceUri.Value));
|
||||
}
|
||||
}
|
||||
|
||||
internal void WriteEndElementPrimitive()
|
||||
{
|
||||
_writer.WriteEndElement();
|
||||
}
|
||||
|
||||
internal WriteState WriteState => _writer.WriteState;
|
||||
|
||||
internal string XmlLang => _writer.XmlLang;
|
||||
|
||||
internal XmlSpace XmlSpace => _writer.XmlSpace;
|
||||
|
||||
public void WriteNamespaceDecl(XmlDictionaryString ns)
|
||||
{
|
||||
WriteXmlnsAttribute(ns);
|
||||
}
|
||||
|
||||
private Exception CreateInvalidPrimitiveTypeException(Type type)
|
||||
{
|
||||
return new System.Runtime.Serialization.InvalidDataContractException(SR.Format(SR.InvalidPrimitiveType, DataContract.GetClrTypeFullName(type)));
|
||||
}
|
||||
|
||||
internal void WriteAnyType(object value)
|
||||
{
|
||||
WriteAnyType(value, value.GetType());
|
||||
}
|
||||
|
||||
internal void WriteAnyType(object value, Type valueType)
|
||||
{
|
||||
bool handled = true;
|
||||
switch (Type.GetTypeCode(valueType))
|
||||
{
|
||||
case TypeCode.Boolean:
|
||||
WriteBoolean((bool)value);
|
||||
break;
|
||||
case TypeCode.Char:
|
||||
WriteChar((char)value);
|
||||
break;
|
||||
case TypeCode.Byte:
|
||||
WriteUnsignedByte((byte)value);
|
||||
break;
|
||||
case TypeCode.Int16:
|
||||
WriteShort((short)value);
|
||||
break;
|
||||
case TypeCode.Int32:
|
||||
WriteInt((int)value);
|
||||
break;
|
||||
case TypeCode.Int64:
|
||||
WriteLong((long)value);
|
||||
break;
|
||||
case TypeCode.Single:
|
||||
WriteFloat((float)value);
|
||||
break;
|
||||
case TypeCode.Double:
|
||||
WriteDouble((double)value);
|
||||
break;
|
||||
case TypeCode.Decimal:
|
||||
WriteDecimal((decimal)value);
|
||||
break;
|
||||
case TypeCode.DateTime:
|
||||
WriteDateTime((DateTime)value);
|
||||
break;
|
||||
case TypeCode.String:
|
||||
WriteString((string)value);
|
||||
break;
|
||||
case TypeCode.SByte:
|
||||
WriteSignedByte((sbyte)value);
|
||||
break;
|
||||
case TypeCode.UInt16:
|
||||
WriteUnsignedShort((ushort)value);
|
||||
break;
|
||||
case TypeCode.UInt32:
|
||||
WriteUnsignedInt((uint)value);
|
||||
break;
|
||||
case TypeCode.UInt64:
|
||||
WriteUnsignedLong((ulong)value);
|
||||
break;
|
||||
case TypeCode.Empty:
|
||||
case TypeCode.DBNull:
|
||||
case TypeCode.Object:
|
||||
default:
|
||||
if (valueType == Globals.TypeOfByteArray)
|
||||
{
|
||||
WriteBase64((byte[])value);
|
||||
}
|
||||
else if (valueType == Globals.TypeOfObject)
|
||||
{
|
||||
//Write Nothing
|
||||
}
|
||||
else if (valueType == Globals.TypeOfTimeSpan)
|
||||
{
|
||||
WriteTimeSpan((TimeSpan)value);
|
||||
}
|
||||
else if (valueType == Globals.TypeOfGuid)
|
||||
{
|
||||
WriteGuid((Guid)value);
|
||||
}
|
||||
else if (valueType == Globals.TypeOfUri)
|
||||
{
|
||||
WriteUri((Uri)value);
|
||||
}
|
||||
else if (valueType == Globals.TypeOfXmlQualifiedName)
|
||||
{
|
||||
WriteQName((XmlQualifiedName)value);
|
||||
}
|
||||
else
|
||||
{
|
||||
handled = false;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
if (!handled)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(CreateInvalidPrimitiveTypeException(valueType));
|
||||
}
|
||||
}
|
||||
|
||||
internal void WriteExtensionData(IDataNode dataNode)
|
||||
{
|
||||
bool handled = true;
|
||||
Type valueType = dataNode.DataType;
|
||||
switch (Type.GetTypeCode(valueType))
|
||||
{
|
||||
case TypeCode.Boolean:
|
||||
WriteBoolean(((DataNode<bool>)dataNode).GetValue());
|
||||
break;
|
||||
case TypeCode.Char:
|
||||
WriteChar(((DataNode<char>)dataNode).GetValue());
|
||||
break;
|
||||
case TypeCode.Byte:
|
||||
WriteUnsignedByte(((DataNode<byte>)dataNode).GetValue());
|
||||
break;
|
||||
case TypeCode.Int16:
|
||||
WriteShort(((DataNode<short>)dataNode).GetValue());
|
||||
break;
|
||||
case TypeCode.Int32:
|
||||
WriteInt(((DataNode<int>)dataNode).GetValue());
|
||||
break;
|
||||
case TypeCode.Int64:
|
||||
WriteLong(((DataNode<long>)dataNode).GetValue());
|
||||
break;
|
||||
case TypeCode.Single:
|
||||
WriteFloat(((DataNode<float>)dataNode).GetValue());
|
||||
break;
|
||||
case TypeCode.Double:
|
||||
WriteDouble(((DataNode<double>)dataNode).GetValue());
|
||||
break;
|
||||
case TypeCode.Decimal:
|
||||
WriteDecimal(((DataNode<decimal>)dataNode).GetValue());
|
||||
break;
|
||||
case TypeCode.DateTime:
|
||||
WriteDateTime(((DataNode<DateTime>)dataNode).GetValue());
|
||||
break;
|
||||
case TypeCode.String:
|
||||
WriteString(((DataNode<string>)dataNode).GetValue());
|
||||
break;
|
||||
case TypeCode.SByte:
|
||||
WriteSignedByte(((DataNode<sbyte>)dataNode).GetValue());
|
||||
break;
|
||||
case TypeCode.UInt16:
|
||||
WriteUnsignedShort(((DataNode<ushort>)dataNode).GetValue());
|
||||
break;
|
||||
case TypeCode.UInt32:
|
||||
WriteUnsignedInt(((DataNode<uint>)dataNode).GetValue());
|
||||
break;
|
||||
case TypeCode.UInt64:
|
||||
WriteUnsignedLong(((DataNode<ulong>)dataNode).GetValue());
|
||||
break;
|
||||
case TypeCode.Empty:
|
||||
case TypeCode.DBNull:
|
||||
case TypeCode.Object:
|
||||
default:
|
||||
if (valueType == Globals.TypeOfByteArray)
|
||||
{
|
||||
WriteBase64(((DataNode<byte[]>)dataNode).GetValue());
|
||||
}
|
||||
else if (valueType == Globals.TypeOfObject)
|
||||
{
|
||||
object obj = dataNode.Value;
|
||||
if (obj != null)
|
||||
{
|
||||
WriteAnyType(obj);
|
||||
}
|
||||
}
|
||||
else if (valueType == Globals.TypeOfTimeSpan)
|
||||
{
|
||||
WriteTimeSpan(((DataNode<TimeSpan>)dataNode).GetValue());
|
||||
}
|
||||
else if (valueType == Globals.TypeOfGuid)
|
||||
{
|
||||
WriteGuid(((DataNode<Guid>)dataNode).GetValue());
|
||||
}
|
||||
else if (valueType == Globals.TypeOfUri)
|
||||
{
|
||||
WriteUri(((DataNode<Uri>)dataNode).GetValue());
|
||||
}
|
||||
else if (valueType == Globals.TypeOfXmlQualifiedName)
|
||||
{
|
||||
WriteQName(((DataNode<XmlQualifiedName>)dataNode).GetValue());
|
||||
}
|
||||
else
|
||||
{
|
||||
handled = false;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
if (!handled)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(CreateInvalidPrimitiveTypeException(valueType));
|
||||
}
|
||||
}
|
||||
|
||||
internal void WriteString(string value)
|
||||
{
|
||||
_writer.WriteValue(value);
|
||||
}
|
||||
|
||||
internal virtual void WriteBoolean(bool value)
|
||||
{
|
||||
_writer.WriteValue(value);
|
||||
}
|
||||
public void WriteBoolean(bool value, XmlDictionaryString name, XmlDictionaryString ns)
|
||||
{
|
||||
WriteStartElementPrimitive(name, ns);
|
||||
WriteBoolean(value);
|
||||
WriteEndElementPrimitive();
|
||||
}
|
||||
|
||||
internal virtual void WriteDateTime(DateTime value)
|
||||
{
|
||||
_writer.WriteValue(value);
|
||||
}
|
||||
|
||||
public void WriteDateTime(DateTime value, XmlDictionaryString name, XmlDictionaryString ns)
|
||||
{
|
||||
WriteStartElementPrimitive(name, ns);
|
||||
WriteDateTime(value);
|
||||
WriteEndElementPrimitive();
|
||||
}
|
||||
|
||||
internal virtual void WriteDecimal(decimal value)
|
||||
{
|
||||
_writer.WriteValue(value);
|
||||
}
|
||||
public void WriteDecimal(decimal value, XmlDictionaryString name, XmlDictionaryString ns)
|
||||
{
|
||||
WriteStartElementPrimitive(name, ns);
|
||||
WriteDecimal(value);
|
||||
WriteEndElementPrimitive();
|
||||
}
|
||||
|
||||
internal virtual void WriteDouble(double value)
|
||||
{
|
||||
_writer.WriteValue(value);
|
||||
}
|
||||
public void WriteDouble(double value, XmlDictionaryString name, XmlDictionaryString ns)
|
||||
{
|
||||
WriteStartElementPrimitive(name, ns);
|
||||
WriteDouble(value);
|
||||
WriteEndElementPrimitive();
|
||||
}
|
||||
|
||||
internal virtual void WriteInt(int value)
|
||||
{
|
||||
_writer.WriteValue(value);
|
||||
}
|
||||
public void WriteInt(int value, XmlDictionaryString name, XmlDictionaryString ns)
|
||||
{
|
||||
WriteStartElementPrimitive(name, ns);
|
||||
WriteInt(value);
|
||||
WriteEndElementPrimitive();
|
||||
}
|
||||
|
||||
internal virtual void WriteLong(long value)
|
||||
{
|
||||
_writer.WriteValue(value);
|
||||
}
|
||||
public void WriteLong(long value, XmlDictionaryString name, XmlDictionaryString ns)
|
||||
{
|
||||
WriteStartElementPrimitive(name, ns);
|
||||
WriteLong(value);
|
||||
WriteEndElementPrimitive();
|
||||
}
|
||||
|
||||
internal virtual void WriteFloat(float value)
|
||||
{
|
||||
_writer.WriteValue(value);
|
||||
}
|
||||
public void WriteFloat(float value, XmlDictionaryString name, XmlDictionaryString ns)
|
||||
{
|
||||
WriteStartElementPrimitive(name, ns);
|
||||
WriteFloat(value);
|
||||
WriteEndElementPrimitive();
|
||||
}
|
||||
|
||||
private const int CharChunkSize = 76;
|
||||
private const int ByteChunkSize = CharChunkSize / 4 * 3;
|
||||
|
||||
internal virtual void WriteBase64(byte[] bytes)
|
||||
{
|
||||
if (bytes == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_writer.WriteBase64(bytes, 0, bytes.Length);
|
||||
}
|
||||
|
||||
internal virtual void WriteShort(short value)
|
||||
{
|
||||
_writer.WriteValue(value);
|
||||
}
|
||||
public void WriteShort(short value, XmlDictionaryString name, XmlDictionaryString ns)
|
||||
{
|
||||
WriteStartElementPrimitive(name, ns);
|
||||
WriteShort(value);
|
||||
WriteEndElementPrimitive();
|
||||
}
|
||||
|
||||
internal virtual void WriteUnsignedByte(byte value)
|
||||
{
|
||||
_writer.WriteValue(value);
|
||||
}
|
||||
public void WriteUnsignedByte(byte value, XmlDictionaryString name, XmlDictionaryString ns)
|
||||
{
|
||||
WriteStartElementPrimitive(name, ns);
|
||||
WriteUnsignedByte(value);
|
||||
WriteEndElementPrimitive();
|
||||
}
|
||||
|
||||
internal virtual void WriteSignedByte(sbyte value)
|
||||
{
|
||||
_writer.WriteValue(value);
|
||||
}
|
||||
public void WriteSignedByte(sbyte value, XmlDictionaryString name, XmlDictionaryString ns)
|
||||
{
|
||||
WriteStartElementPrimitive(name, ns);
|
||||
WriteSignedByte(value);
|
||||
WriteEndElementPrimitive();
|
||||
}
|
||||
|
||||
internal virtual void WriteUnsignedInt(uint value)
|
||||
{
|
||||
_writer.WriteValue(value);
|
||||
}
|
||||
public void WriteUnsignedInt(uint value, XmlDictionaryString name, XmlDictionaryString ns)
|
||||
{
|
||||
WriteStartElementPrimitive(name, ns);
|
||||
WriteUnsignedInt(value);
|
||||
WriteEndElementPrimitive();
|
||||
}
|
||||
|
||||
internal virtual void WriteUnsignedLong(ulong value)
|
||||
{
|
||||
_writer.WriteRaw(XmlConvert.ToString(value));
|
||||
}
|
||||
public void WriteUnsignedLong(ulong value, XmlDictionaryString name, XmlDictionaryString ns)
|
||||
{
|
||||
WriteStartElementPrimitive(name, ns);
|
||||
WriteUnsignedLong(value);
|
||||
WriteEndElementPrimitive();
|
||||
}
|
||||
|
||||
internal virtual void WriteUnsignedShort(ushort value)
|
||||
{
|
||||
_writer.WriteValue(value);
|
||||
}
|
||||
public void WriteUnsignedShort(ushort value, XmlDictionaryString name, XmlDictionaryString ns)
|
||||
{
|
||||
WriteStartElementPrimitive(name, ns);
|
||||
WriteUnsignedShort(value);
|
||||
WriteEndElementPrimitive();
|
||||
}
|
||||
|
||||
internal virtual void WriteChar(char value)
|
||||
{
|
||||
_writer.WriteValue(value);
|
||||
}
|
||||
public void WriteChar(char value, XmlDictionaryString name, XmlDictionaryString ns)
|
||||
{
|
||||
WriteStartElementPrimitive(name, ns);
|
||||
WriteChar(value);
|
||||
WriteEndElementPrimitive();
|
||||
}
|
||||
|
||||
internal void WriteTimeSpan(TimeSpan value)
|
||||
{
|
||||
_writer.WriteRaw(XmlConvert.ToString(value));
|
||||
}
|
||||
public void WriteTimeSpan(TimeSpan value, XmlDictionaryString name, XmlDictionaryString ns)
|
||||
{
|
||||
WriteStartElementPrimitive(name, ns);
|
||||
WriteTimeSpan(value);
|
||||
WriteEndElementPrimitive();
|
||||
}
|
||||
|
||||
internal void WriteGuid(Guid value)
|
||||
{
|
||||
_writer.WriteRaw(value.ToString());
|
||||
}
|
||||
public void WriteGuid(Guid value, XmlDictionaryString name, XmlDictionaryString ns)
|
||||
{
|
||||
WriteStartElementPrimitive(name, ns);
|
||||
WriteGuid(value);
|
||||
WriteEndElementPrimitive();
|
||||
}
|
||||
|
||||
internal void WriteUri(Uri value)
|
||||
{
|
||||
_writer.WriteString(value.GetComponents(UriComponents.SerializationInfoString, UriFormat.UriEscaped));
|
||||
}
|
||||
|
||||
internal virtual void WriteQName(XmlQualifiedName value)
|
||||
{
|
||||
if (value != XmlQualifiedName.Empty)
|
||||
{
|
||||
WriteXmlnsAttribute(value.Namespace);
|
||||
WriteQualifiedName(value.Name, value.Namespace);
|
||||
}
|
||||
}
|
||||
|
||||
internal void WriteQualifiedName(string localName, string ns)
|
||||
{
|
||||
_writer.WriteQualifiedName(localName, ns);
|
||||
}
|
||||
|
||||
internal void WriteQualifiedName(XmlDictionaryString localName, XmlDictionaryString ns)
|
||||
{
|
||||
if (_dictionaryWriter == null)
|
||||
{
|
||||
_writer.WriteQualifiedName(localName.Value, ns.Value);
|
||||
}
|
||||
else
|
||||
{
|
||||
_dictionaryWriter.WriteQualifiedName(localName, ns);
|
||||
}
|
||||
}
|
||||
|
||||
public void WriteBooleanArray(bool[] value, XmlDictionaryString itemName, XmlDictionaryString itemNamespace)
|
||||
{
|
||||
if (_dictionaryWriter == null)
|
||||
{
|
||||
for (int i = 0; i < value.Length; i++)
|
||||
{
|
||||
WriteBoolean(value[i], itemName, itemNamespace);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_dictionaryWriter.WriteArray(null, itemName, itemNamespace, value, 0, value.Length);
|
||||
}
|
||||
}
|
||||
|
||||
public void WriteDateTimeArray(DateTime[] value, XmlDictionaryString itemName, XmlDictionaryString itemNamespace)
|
||||
{
|
||||
if (_dictionaryWriter == null)
|
||||
{
|
||||
for (int i = 0; i < value.Length; i++)
|
||||
{
|
||||
WriteDateTime(value[i], itemName, itemNamespace);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_dictionaryWriter.WriteArray(null, itemName, itemNamespace, value, 0, value.Length);
|
||||
}
|
||||
}
|
||||
|
||||
public void WriteDecimalArray(decimal[] value, XmlDictionaryString itemName, XmlDictionaryString itemNamespace)
|
||||
{
|
||||
if (_dictionaryWriter == null)
|
||||
{
|
||||
for (int i = 0; i < value.Length; i++)
|
||||
{
|
||||
WriteDecimal(value[i], itemName, itemNamespace);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_dictionaryWriter.WriteArray(null, itemName, itemNamespace, value, 0, value.Length);
|
||||
}
|
||||
}
|
||||
|
||||
public void WriteInt32Array(int[] value, XmlDictionaryString itemName, XmlDictionaryString itemNamespace)
|
||||
{
|
||||
if (_dictionaryWriter == null)
|
||||
{
|
||||
for (int i = 0; i < value.Length; i++)
|
||||
{
|
||||
WriteInt(value[i], itemName, itemNamespace);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_dictionaryWriter.WriteArray(null, itemName, itemNamespace, value, 0, value.Length);
|
||||
}
|
||||
}
|
||||
|
||||
public void WriteInt64Array(long[] value, XmlDictionaryString itemName, XmlDictionaryString itemNamespace)
|
||||
{
|
||||
if (_dictionaryWriter == null)
|
||||
{
|
||||
for (int i = 0; i < value.Length; i++)
|
||||
{
|
||||
WriteLong(value[i], itemName, itemNamespace);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_dictionaryWriter.WriteArray(null, itemName, itemNamespace, value, 0, value.Length);
|
||||
}
|
||||
}
|
||||
|
||||
public void WriteSingleArray(float[] value, XmlDictionaryString itemName, XmlDictionaryString itemNamespace)
|
||||
{
|
||||
if (_dictionaryWriter == null)
|
||||
{
|
||||
for (int i = 0; i < value.Length; i++)
|
||||
{
|
||||
WriteFloat(value[i], itemName, itemNamespace);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_dictionaryWriter.WriteArray(null, itemName, itemNamespace, value, 0, value.Length);
|
||||
}
|
||||
}
|
||||
|
||||
public void WriteDoubleArray(double[] value, XmlDictionaryString itemName, XmlDictionaryString itemNamespace)
|
||||
{
|
||||
if (_dictionaryWriter == null)
|
||||
{
|
||||
for (int i = 0; i < value.Length; i++)
|
||||
{
|
||||
WriteDouble(value[i], itemName, itemNamespace);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_dictionaryWriter.WriteArray(null, itemName, itemNamespace, value, 0, value.Length);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,387 @@
|
||||
//------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//------------------------------------------------------------
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Reflection;
|
||||
using System.Xml;
|
||||
using System.Xml.Schema;
|
||||
using InvalidDataContractException = System.Runtime.Serialization.InvalidDataContractException;
|
||||
|
||||
namespace Compat.Runtime.Serialization
|
||||
{
|
||||
|
||||
public class XsdDataContractExporter
|
||||
{
|
||||
private ExportOptions options;
|
||||
private XmlSchemaSet schemas;
|
||||
private DataContractSet dataContractSet;
|
||||
|
||||
public XsdDataContractExporter()
|
||||
{
|
||||
}
|
||||
|
||||
public XsdDataContractExporter(XmlSchemaSet schemas)
|
||||
{
|
||||
this.schemas = schemas;
|
||||
}
|
||||
|
||||
public ExportOptions Options
|
||||
{
|
||||
get => options;
|
||||
set => options = value;
|
||||
}
|
||||
|
||||
public XmlSchemaSet Schemas
|
||||
{
|
||||
get
|
||||
{
|
||||
XmlSchemaSet schemaSet = GetSchemaSet();
|
||||
SchemaImporter.CompileSchemaSet(schemaSet);
|
||||
return schemaSet;
|
||||
}
|
||||
}
|
||||
|
||||
private XmlSchemaSet GetSchemaSet()
|
||||
{
|
||||
if (schemas == null)
|
||||
{
|
||||
schemas = new XmlSchemaSet
|
||||
{
|
||||
XmlResolver = null
|
||||
};
|
||||
}
|
||||
return schemas;
|
||||
}
|
||||
|
||||
private DataContractSet DataContractSet
|
||||
{
|
||||
get
|
||||
{
|
||||
if (dataContractSet == null)
|
||||
{
|
||||
dataContractSet = new DataContractSet((Options == null) ? null : Options.GetSurrogate());
|
||||
}
|
||||
return dataContractSet;
|
||||
}
|
||||
}
|
||||
|
||||
public void Export(ICollection<Assembly> assemblies)
|
||||
{
|
||||
if (assemblies == null)
|
||||
{
|
||||
throw Compat.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("assemblies"));
|
||||
}
|
||||
|
||||
DataContractSet oldValue = (dataContractSet == null) ? null : new DataContractSet(dataContractSet);
|
||||
try
|
||||
{
|
||||
foreach (Assembly assembly in assemblies)
|
||||
{
|
||||
if (assembly == null)
|
||||
{
|
||||
throw Compat.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(SR.Format(SR.CannotExportNullAssembly, "assemblies")));
|
||||
}
|
||||
|
||||
Type[] types = assembly.GetTypes();
|
||||
for (int j = 0; j < types.Length; j++)
|
||||
{
|
||||
CheckAndAddType(types[j]);
|
||||
}
|
||||
}
|
||||
|
||||
Export();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (Fx.IsFatal(ex))
|
||||
{
|
||||
throw;
|
||||
}
|
||||
dataContractSet = oldValue;
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
public void Export(ICollection<Type> types)
|
||||
{
|
||||
if (types == null)
|
||||
{
|
||||
throw Compat.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException(nameof(types)));
|
||||
}
|
||||
|
||||
DataContractSet oldValue = (dataContractSet == null) ? null : new DataContractSet(dataContractSet);
|
||||
try
|
||||
{
|
||||
foreach (Type type in types)
|
||||
{
|
||||
if (type == null)
|
||||
{
|
||||
throw Compat.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(SR.Format(SR.CannotExportNullType, nameof(types))));
|
||||
}
|
||||
|
||||
AddType(type);
|
||||
}
|
||||
|
||||
Export();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (Fx.IsFatal(ex))
|
||||
{
|
||||
throw;
|
||||
}
|
||||
dataContractSet = oldValue;
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
public void Export(Type type)
|
||||
{
|
||||
if (type == null)
|
||||
{
|
||||
throw Compat.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException(nameof(type)));
|
||||
}
|
||||
|
||||
DataContractSet oldValue = (dataContractSet == null) ? null : new DataContractSet(dataContractSet);
|
||||
try
|
||||
{
|
||||
AddType(type);
|
||||
Export();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (Fx.IsFatal(ex))
|
||||
{
|
||||
throw;
|
||||
}
|
||||
dataContractSet = oldValue;
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
public XmlQualifiedName GetSchemaTypeName(Type type)
|
||||
{
|
||||
if (type == null)
|
||||
{
|
||||
throw Compat.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException(nameof(type)));
|
||||
}
|
||||
|
||||
type = GetSurrogatedType(type);
|
||||
DataContract dataContract = DataContract.GetDataContract(type);
|
||||
DataContractSet.EnsureTypeNotGeneric(dataContract.UnderlyingType);
|
||||
XmlDataContract xmlDataContract = dataContract as XmlDataContract;
|
||||
if (xmlDataContract != null && xmlDataContract.IsAnonymous)
|
||||
{
|
||||
return XmlQualifiedName.Empty;
|
||||
}
|
||||
|
||||
return dataContract.StableName;
|
||||
}
|
||||
|
||||
public XmlSchemaType GetSchemaType(Type type)
|
||||
{
|
||||
if (type == null)
|
||||
{
|
||||
throw Compat.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("type"));
|
||||
}
|
||||
|
||||
type = GetSurrogatedType(type);
|
||||
DataContract dataContract = DataContract.GetDataContract(type);
|
||||
DataContractSet.EnsureTypeNotGeneric(dataContract.UnderlyingType);
|
||||
XmlDataContract xmlDataContract = dataContract as XmlDataContract;
|
||||
if (xmlDataContract != null && xmlDataContract.IsAnonymous)
|
||||
{
|
||||
return xmlDataContract.XsdType;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public XmlQualifiedName GetRootElementName(Type type)
|
||||
{
|
||||
if (type == null)
|
||||
{
|
||||
throw Compat.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("type"));
|
||||
}
|
||||
|
||||
type = GetSurrogatedType(type);
|
||||
DataContract dataContract = DataContract.GetDataContract(type);
|
||||
DataContractSet.EnsureTypeNotGeneric(dataContract.UnderlyingType);
|
||||
if (dataContract.HasRoot)
|
||||
{
|
||||
return new XmlQualifiedName(dataContract.TopLevelElementName.Value, dataContract.TopLevelElementNamespace.Value);
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private Type GetSurrogatedType(Type type)
|
||||
{
|
||||
IDataContractSurrogate dataContractSurrogate;
|
||||
if (options != null && (dataContractSurrogate = Options.GetSurrogate()) != null)
|
||||
{
|
||||
type = DataContractSurrogateCaller.GetDataContractType(dataContractSurrogate, type);
|
||||
}
|
||||
|
||||
return type;
|
||||
}
|
||||
|
||||
private void CheckAndAddType(Type type)
|
||||
{
|
||||
type = GetSurrogatedType(type);
|
||||
if (!type.ContainsGenericParameters && DataContract.IsTypeSerializable(type))
|
||||
{
|
||||
AddType(type);
|
||||
}
|
||||
}
|
||||
|
||||
private void AddType(Type type)
|
||||
{
|
||||
DataContractSet.Add(type);
|
||||
}
|
||||
|
||||
private void Export()
|
||||
{
|
||||
AddKnownTypes();
|
||||
SchemaExporter schemaExporter = new SchemaExporter(GetSchemaSet(), DataContractSet);
|
||||
schemaExporter.Export();
|
||||
}
|
||||
|
||||
private void AddKnownTypes()
|
||||
{
|
||||
if (Options != null)
|
||||
{
|
||||
Collection<Type> knownTypes = Options.KnownTypes;
|
||||
|
||||
if (knownTypes != null)
|
||||
{
|
||||
for (int i = 0; i < knownTypes.Count; i++)
|
||||
{
|
||||
Type type = knownTypes[i];
|
||||
if (type == null)
|
||||
{
|
||||
throw Compat.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(SR.CannotExportNullKnownType));
|
||||
}
|
||||
|
||||
AddType(type);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool CanExport(ICollection<Assembly> assemblies)
|
||||
{
|
||||
if (assemblies == null)
|
||||
{
|
||||
throw Compat.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("assemblies"));
|
||||
}
|
||||
|
||||
DataContractSet oldValue = (dataContractSet == null) ? null : new DataContractSet(dataContractSet);
|
||||
try
|
||||
{
|
||||
foreach (Assembly assembly in assemblies)
|
||||
{
|
||||
if (assembly == null)
|
||||
{
|
||||
throw Compat.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(SR.Format(SR.CannotExportNullAssembly, nameof(assemblies))));
|
||||
}
|
||||
|
||||
Type[] types = assembly.GetTypes();
|
||||
for (int j = 0; j < types.Length; j++)
|
||||
{
|
||||
CheckAndAddType(types[j]);
|
||||
}
|
||||
}
|
||||
AddKnownTypes();
|
||||
return true;
|
||||
}
|
||||
catch (InvalidDataContractException)
|
||||
{
|
||||
dataContractSet = oldValue;
|
||||
return false;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (Fx.IsFatal(ex))
|
||||
{
|
||||
throw;
|
||||
}
|
||||
dataContractSet = oldValue;
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
public bool CanExport(ICollection<Type> types)
|
||||
{
|
||||
if (types == null)
|
||||
{
|
||||
throw Compat.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException(nameof(types)));
|
||||
}
|
||||
|
||||
DataContractSet oldValue = (dataContractSet == null) ? null : new DataContractSet(dataContractSet);
|
||||
try
|
||||
{
|
||||
foreach (Type type in types)
|
||||
{
|
||||
if (type == null)
|
||||
{
|
||||
throw Compat.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(SR.Format(SR.CannotExportNullType, nameof(types))));
|
||||
}
|
||||
|
||||
AddType(type);
|
||||
}
|
||||
AddKnownTypes();
|
||||
return true;
|
||||
}
|
||||
catch (InvalidDataContractException)
|
||||
{
|
||||
dataContractSet = oldValue;
|
||||
return false;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (Fx.IsFatal(ex))
|
||||
{
|
||||
throw;
|
||||
}
|
||||
dataContractSet = oldValue;
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
public bool CanExport(Type type)
|
||||
{
|
||||
if (type == null)
|
||||
{
|
||||
throw Compat.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException(nameof(type)));
|
||||
}
|
||||
|
||||
DataContractSet oldValue = (dataContractSet == null) ? null : new DataContractSet(dataContractSet);
|
||||
try
|
||||
{
|
||||
AddType(type);
|
||||
AddKnownTypes();
|
||||
return true;
|
||||
}
|
||||
catch (InvalidDataContractException)
|
||||
{
|
||||
dataContractSet = oldValue;
|
||||
return false;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (Fx.IsFatal(ex))
|
||||
{
|
||||
throw;
|
||||
}
|
||||
dataContractSet = oldValue;
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
601
Compat.Private.Serialization/Compat/Text/Base64Encoding.cs
Normal file
601
Compat.Private.Serialization/Compat/Text/Base64Encoding.cs
Normal file
@@ -0,0 +1,601 @@
|
||||
using Compat.Runtime.Serialization;
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Security;
|
||||
using System.Text;
|
||||
|
||||
namespace Compat.Text
|
||||
{
|
||||
internal class Base64Encoding : Encoding
|
||||
{
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.StyleCop.CSharp.SpacingRules", "SA1025:CodeMustNotContainMultipleWhitespaceInARow", Justification = "This alignment is optimal.")]
|
||||
private static readonly byte[] char2val = new byte[128]
|
||||
{
|
||||
/* 0-15 */ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
/* 16-31 */ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
/* 32-47 */ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 62, 0xFF, 0xFF, 0xFF, 63,
|
||||
/* 48-63 */ 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 0xFF, 0xFF, 0xFF, 64, 0xFF, 0xFF,
|
||||
/* 64-79 */ 0xFF, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
|
||||
/* 80-95 */ 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
/* 96-111 */ 0xFF, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
|
||||
/* 112-127 */ 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
};
|
||||
private static readonly string val2char = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||
private static readonly byte[] val2byte = new byte[]
|
||||
{
|
||||
(byte)'A', (byte)'B', (byte)'C', (byte)'D', (byte)'E', (byte)'F', (byte)'G', (byte)'H', (byte)'I', (byte)'J', (byte)'K', (byte)'L', (byte)'M', (byte)'N', (byte)'O', (byte)'P',
|
||||
(byte)'Q', (byte)'R', (byte)'S', (byte)'T', (byte)'U', (byte)'V', (byte)'W', (byte)'X', (byte)'Y', (byte)'Z', (byte)'a', (byte)'b', (byte)'c', (byte)'d', (byte)'e', (byte)'f',
|
||||
(byte)'g', (byte)'h', (byte)'i', (byte)'j', (byte)'k', (byte)'l', (byte)'m', (byte)'n', (byte)'o', (byte)'p', (byte)'q', (byte)'r', (byte)'s', (byte)'t', (byte)'u', (byte)'v',
|
||||
(byte)'w', (byte)'x', (byte)'y', (byte)'z', (byte)'0', (byte)'1', (byte)'2', (byte)'3', (byte)'4', (byte)'5', (byte)'6', (byte)'7', (byte)'8', (byte)'9', (byte)'+', (byte)'/'
|
||||
};
|
||||
|
||||
public override int GetMaxByteCount(int charCount)
|
||||
{
|
||||
if (charCount < 0)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException(nameof(charCount), SR.ValueMustBeNonNegative));
|
||||
}
|
||||
|
||||
if ((charCount % 4) != 0)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new FormatException(SR.Format(SR.XmlInvalidBase64Length, charCount.ToString(NumberFormatInfo.CurrentInfo))));
|
||||
}
|
||||
|
||||
return charCount / 4 * 3;
|
||||
}
|
||||
|
||||
private bool IsValidLeadBytes(int v1, int v2, int v3, int v4)
|
||||
{
|
||||
// First two chars of a four char base64 sequence can't be ==, and must be valid
|
||||
return ((v1 | v2) < 64) && ((v3 | v4) != 0xFF);
|
||||
}
|
||||
|
||||
private bool IsValidTailBytes(int v3, int v4)
|
||||
{
|
||||
// If the third char is = then the fourth char must be =
|
||||
return !(v3 == 64 && v4 != 64);
|
||||
}
|
||||
|
||||
public override unsafe int GetByteCount(char[] chars, int index, int count)
|
||||
{
|
||||
if (chars == null)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException(nameof(chars)));
|
||||
}
|
||||
|
||||
if (index < 0)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException(nameof(index), SR.ValueMustBeNonNegative));
|
||||
}
|
||||
|
||||
if (index > chars.Length)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException(nameof(index), SR.Format(SR.OffsetExceedsBufferSize, chars.Length)));
|
||||
}
|
||||
|
||||
if (count < 0)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException(nameof(count), SR.ValueMustBeNonNegative));
|
||||
}
|
||||
|
||||
if (count > chars.Length - index)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException(nameof(count), SR.Format(SR.SizeExceedsRemainingBufferSpace, chars.Length - index)));
|
||||
}
|
||||
|
||||
if (count == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((count % 4) != 0)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new FormatException(SR.Format(SR.XmlInvalidBase64Length, count.ToString(NumberFormatInfo.CurrentInfo))));
|
||||
}
|
||||
|
||||
fixed (byte* _char2val = char2val)
|
||||
{
|
||||
fixed (char* _chars = &chars[index])
|
||||
{
|
||||
int totalCount = 0;
|
||||
char* pch = _chars;
|
||||
char* pchMax = _chars + count;
|
||||
while (pch < pchMax)
|
||||
{
|
||||
Fx.Assert(pch + 4 <= pchMax, "");
|
||||
char pch0 = pch[0];
|
||||
char pch1 = pch[1];
|
||||
char pch2 = pch[2];
|
||||
char pch3 = pch[3];
|
||||
|
||||
if ((pch0 | pch1 | pch2 | pch3) >= 128)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new FormatException(SR.Format(SR.XmlInvalidBase64Sequence, new string(pch, 0, 4), index + (int)(pch - _chars))));
|
||||
}
|
||||
|
||||
// xx765432 xx107654 xx321076 xx543210
|
||||
// 76543210 76543210 76543210
|
||||
int v1 = _char2val[pch0];
|
||||
int v2 = _char2val[pch1];
|
||||
int v3 = _char2val[pch2];
|
||||
int v4 = _char2val[pch3];
|
||||
|
||||
if (!IsValidLeadBytes(v1, v2, v3, v4) || !IsValidTailBytes(v3, v4))
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new FormatException(SR.Format(SR.XmlInvalidBase64Sequence, new string(pch, 0, 4), index + (int)(pch - _chars))));
|
||||
}
|
||||
|
||||
int byteCount = (v4 != 64 ? 3 : (v3 != 64 ? 2 : 1));
|
||||
totalCount += byteCount;
|
||||
pch += 4;
|
||||
}
|
||||
return totalCount;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override unsafe int GetBytes(char[] chars, int charIndex, int charCount, byte[] bytes, int byteIndex)
|
||||
{
|
||||
if (chars == null)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException(nameof(chars)));
|
||||
}
|
||||
|
||||
if (charIndex < 0)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException(nameof(charIndex), SR.ValueMustBeNonNegative));
|
||||
}
|
||||
|
||||
if (charIndex > chars.Length)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException(nameof(charIndex), SR.Format(SR.OffsetExceedsBufferSize, chars.Length)));
|
||||
}
|
||||
|
||||
if (charCount < 0)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException(nameof(charCount), SR.ValueMustBeNonNegative));
|
||||
}
|
||||
|
||||
if (charCount > chars.Length - charIndex)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException(nameof(charCount), SR.Format(SR.SizeExceedsRemainingBufferSpace, chars.Length - charIndex)));
|
||||
}
|
||||
|
||||
if (bytes == null)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException(nameof(bytes)));
|
||||
}
|
||||
|
||||
if (byteIndex < 0)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException(nameof(byteIndex), SR.ValueMustBeNonNegative));
|
||||
}
|
||||
|
||||
if (byteIndex > bytes.Length)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException(nameof(byteIndex), SR.Format(SR.OffsetExceedsBufferSize, bytes.Length)));
|
||||
}
|
||||
|
||||
if (charCount == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((charCount % 4) != 0)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new FormatException(SR.Format(SR.XmlInvalidBase64Length, charCount.ToString(NumberFormatInfo.CurrentInfo))));
|
||||
}
|
||||
|
||||
fixed (byte* _char2val = char2val)
|
||||
{
|
||||
fixed (char* _chars = &chars[charIndex])
|
||||
{
|
||||
fixed (byte* _bytes = &bytes[byteIndex])
|
||||
{
|
||||
char* pch = _chars;
|
||||
char* pchMax = _chars + charCount;
|
||||
byte* pb = _bytes;
|
||||
byte* pbMax = _bytes + bytes.Length - byteIndex;
|
||||
while (pch < pchMax)
|
||||
{
|
||||
Fx.Assert(pch + 4 <= pchMax, "");
|
||||
char pch0 = pch[0];
|
||||
char pch1 = pch[1];
|
||||
char pch2 = pch[2];
|
||||
char pch3 = pch[3];
|
||||
|
||||
if ((pch0 | pch1 | pch2 | pch3) >= 128)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new FormatException(SR.Format(SR.XmlInvalidBase64Sequence, new string(pch, 0, 4), charIndex + (int)(pch - _chars))));
|
||||
}
|
||||
// xx765432 xx107654 xx321076 xx543210
|
||||
// 76543210 76543210 76543210
|
||||
|
||||
int v1 = _char2val[pch0];
|
||||
int v2 = _char2val[pch1];
|
||||
int v3 = _char2val[pch2];
|
||||
int v4 = _char2val[pch3];
|
||||
|
||||
if (!IsValidLeadBytes(v1, v2, v3, v4) || !IsValidTailBytes(v3, v4))
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new FormatException(SR.Format(SR.XmlInvalidBase64Sequence, new string(pch, 0, 4), charIndex + (int)(pch - _chars))));
|
||||
}
|
||||
|
||||
int byteCount = (v4 != 64 ? 3 : (v3 != 64 ? 2 : 1));
|
||||
if (pb + byteCount > pbMax)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(SR.XmlArrayTooSmall, nameof(bytes)));
|
||||
}
|
||||
|
||||
pb[0] = (byte)((v1 << 2) | ((v2 >> 4) & 0x03));
|
||||
if (byteCount > 1)
|
||||
{
|
||||
pb[1] = (byte)((v2 << 4) | ((v3 >> 2) & 0x0F));
|
||||
if (byteCount > 2)
|
||||
{
|
||||
pb[2] = (byte)((v3 << 6) | ((v4 >> 0) & 0x3F));
|
||||
}
|
||||
}
|
||||
pb += byteCount;
|
||||
pch += 4;
|
||||
}
|
||||
return (int)(pb - _bytes);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public virtual unsafe int GetBytes(byte[] chars, int charIndex, int charCount, byte[] bytes, int byteIndex)
|
||||
{
|
||||
if (chars == null)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException(nameof(chars)));
|
||||
}
|
||||
|
||||
if (charIndex < 0)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException(nameof(charIndex), SR.ValueMustBeNonNegative));
|
||||
}
|
||||
|
||||
if (charIndex > chars.Length)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException(nameof(charIndex), SR.Format(SR.OffsetExceedsBufferSize, chars.Length)));
|
||||
}
|
||||
|
||||
if (charCount < 0)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException(nameof(charCount), SR.ValueMustBeNonNegative));
|
||||
}
|
||||
|
||||
if (charCount > chars.Length - charIndex)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException(nameof(charCount), SR.Format(SR.SizeExceedsRemainingBufferSpace, chars.Length - charIndex)));
|
||||
}
|
||||
|
||||
if (bytes == null)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException(nameof(bytes)));
|
||||
}
|
||||
|
||||
if (byteIndex < 0)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException(nameof(byteIndex), SR.ValueMustBeNonNegative));
|
||||
}
|
||||
|
||||
if (byteIndex > bytes.Length)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException(nameof(byteIndex), SR.Format(SR.OffsetExceedsBufferSize, bytes.Length)));
|
||||
}
|
||||
|
||||
if (charCount == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((charCount % 4) != 0)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new FormatException(SR.Format(SR.XmlInvalidBase64Length, charCount.ToString(NumberFormatInfo.CurrentInfo))));
|
||||
}
|
||||
|
||||
fixed (byte* _char2val = char2val)
|
||||
{
|
||||
fixed (byte* _chars = &chars[charIndex])
|
||||
{
|
||||
fixed (byte* _bytes = &bytes[byteIndex])
|
||||
{
|
||||
byte* pch = _chars;
|
||||
byte* pchMax = _chars + charCount;
|
||||
byte* pb = _bytes;
|
||||
byte* pbMax = _bytes + bytes.Length - byteIndex;
|
||||
while (pch < pchMax)
|
||||
{
|
||||
Fx.Assert(pch + 4 <= pchMax, "");
|
||||
byte pch0 = pch[0];
|
||||
byte pch1 = pch[1];
|
||||
byte pch2 = pch[2];
|
||||
byte pch3 = pch[3];
|
||||
if ((pch0 | pch1 | pch2 | pch3) >= 128)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new FormatException(SR.Format(SR.XmlInvalidBase64Sequence, new string((sbyte*)pch, 0, 4), charIndex + (int)(pch - _chars))));
|
||||
}
|
||||
// xx765432 xx107654 xx321076 xx543210
|
||||
// 76543210 76543210 76543210
|
||||
|
||||
int v1 = _char2val[pch0];
|
||||
int v2 = _char2val[pch1];
|
||||
int v3 = _char2val[pch2];
|
||||
int v4 = _char2val[pch3];
|
||||
|
||||
if (!IsValidLeadBytes(v1, v2, v3, v4) || !IsValidTailBytes(v3, v4))
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new FormatException(SR.Format(SR.XmlInvalidBase64Sequence, new string((sbyte*)pch, 0, 4), charIndex + (int)(pch - _chars))));
|
||||
}
|
||||
|
||||
int byteCount = (v4 != 64 ? 3 : (v3 != 64 ? 2 : 1));
|
||||
if (pb + byteCount > pbMax)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(SR.XmlArrayTooSmall, nameof(bytes)));
|
||||
}
|
||||
|
||||
pb[0] = (byte)((v1 << 2) | ((v2 >> 4) & 0x03));
|
||||
if (byteCount > 1)
|
||||
{
|
||||
pb[1] = (byte)((v2 << 4) | ((v3 >> 2) & 0x0F));
|
||||
if (byteCount > 2)
|
||||
{
|
||||
pb[2] = (byte)((v3 << 6) | ((v4 >> 0) & 0x3F));
|
||||
}
|
||||
}
|
||||
pb += byteCount;
|
||||
pch += 4;
|
||||
}
|
||||
return (int)(pb - _bytes);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override int GetMaxCharCount(int byteCount)
|
||||
{
|
||||
if (byteCount < 0 || byteCount > int.MaxValue / 4 * 3 - 2)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException(nameof(byteCount), SR.Format(SR.ValueMustBeInRange, 0, int.MaxValue / 4 * 3 - 2)));
|
||||
}
|
||||
|
||||
return ((byteCount + 2) / 3) * 4;
|
||||
}
|
||||
|
||||
public override int GetCharCount(byte[] bytes, int index, int count)
|
||||
{
|
||||
return GetMaxCharCount(count);
|
||||
}
|
||||
|
||||
public override unsafe int GetChars(byte[] bytes, int byteIndex, int byteCount, char[] chars, int charIndex)
|
||||
{
|
||||
if (bytes == null)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException(nameof(bytes)));
|
||||
}
|
||||
|
||||
if (byteIndex < 0)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException(nameof(byteIndex), SR.ValueMustBeNonNegative));
|
||||
}
|
||||
|
||||
if (byteIndex > bytes.Length)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException(nameof(byteIndex), SR.Format(SR.OffsetExceedsBufferSize, bytes.Length)));
|
||||
}
|
||||
|
||||
if (byteCount < 0)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException(nameof(byteCount), SR.ValueMustBeNonNegative));
|
||||
}
|
||||
|
||||
if (byteCount > bytes.Length - byteIndex)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException(nameof(byteCount), SR.Format(SR.SizeExceedsRemainingBufferSpace, bytes.Length - byteIndex)));
|
||||
}
|
||||
|
||||
int charCount = GetCharCount(bytes, byteIndex, byteCount);
|
||||
if (chars == null)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException(nameof(chars)));
|
||||
}
|
||||
|
||||
if (charIndex < 0)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException(nameof(charIndex), SR.ValueMustBeNonNegative));
|
||||
}
|
||||
|
||||
if (charIndex > chars.Length)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException(nameof(charIndex), SR.Format(SR.OffsetExceedsBufferSize, chars.Length)));
|
||||
}
|
||||
|
||||
if (charCount < 0 || charCount > chars.Length - charIndex)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(SR.XmlArrayTooSmall, nameof(chars)));
|
||||
}
|
||||
|
||||
// We've computed exactly how many chars there are and verified that
|
||||
// there's enough space in the char buffer, so we can proceed without
|
||||
// checking the charCount.
|
||||
|
||||
if (byteCount > 0)
|
||||
{
|
||||
fixed (char* _val2char = val2char)
|
||||
{
|
||||
fixed (byte* _bytes = &bytes[byteIndex])
|
||||
{
|
||||
fixed (char* _chars = &chars[charIndex])
|
||||
{
|
||||
byte* pb = _bytes;
|
||||
byte* pbMax = pb + byteCount - 3;
|
||||
char* pch = _chars;
|
||||
|
||||
// Convert chunks of 3 bytes to 4 chars
|
||||
while (pb <= pbMax)
|
||||
{
|
||||
// 76543210 76543210 76543210
|
||||
// xx765432 xx107654 xx321076 xx543210
|
||||
|
||||
// Inspect the code carefully before you change this
|
||||
pch[0] = _val2char[(pb[0] >> 2)];
|
||||
pch[1] = _val2char[((pb[0] & 0x03) << 4) | (pb[1] >> 4)];
|
||||
pch[2] = _val2char[((pb[1] & 0x0F) << 2) | (pb[2] >> 6)];
|
||||
pch[3] = _val2char[pb[2] & 0x3F];
|
||||
|
||||
pb += 3;
|
||||
pch += 4;
|
||||
}
|
||||
|
||||
// Handle 1 or 2 trailing bytes
|
||||
if (pb - pbMax == 2)
|
||||
{
|
||||
// 1 trailing byte
|
||||
// 76543210 xxxxxxxx xxxxxxxx
|
||||
// xx765432 xx10xxxx xxxxxxxx xxxxxxxx
|
||||
pch[0] = _val2char[(pb[0] >> 2)];
|
||||
pch[1] = _val2char[((pb[0] & 0x03) << 4)];
|
||||
pch[2] = '=';
|
||||
pch[3] = '=';
|
||||
}
|
||||
else if (pb - pbMax == 1)
|
||||
{
|
||||
// 2 trailing bytes
|
||||
// 76543210 76543210 xxxxxxxx
|
||||
// xx765432 xx107654 xx3210xx xxxxxxxx
|
||||
pch[0] = _val2char[(pb[0] >> 2)];
|
||||
pch[1] = _val2char[((pb[0] & 0x03) << 4) | (pb[1] >> 4)];
|
||||
pch[2] = _val2char[((pb[1] & 0x0F) << 2)];
|
||||
pch[3] = '=';
|
||||
}
|
||||
else
|
||||
{
|
||||
// 0 trailing bytes
|
||||
Fx.Assert(pb - pbMax == 3, "");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return charCount;
|
||||
}
|
||||
|
||||
public unsafe int GetChars(byte[] bytes, int byteIndex, int byteCount, byte[] chars, int charIndex)
|
||||
{
|
||||
if (bytes == null)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException(nameof(bytes)));
|
||||
}
|
||||
|
||||
if (byteIndex < 0)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException(nameof(byteIndex), SR.ValueMustBeNonNegative));
|
||||
}
|
||||
|
||||
if (byteIndex > bytes.Length)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException(nameof(byteIndex), SR.Format(SR.OffsetExceedsBufferSize, bytes.Length)));
|
||||
}
|
||||
|
||||
if (byteCount < 0)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException(nameof(byteCount), SR.ValueMustBeNonNegative));
|
||||
}
|
||||
|
||||
if (byteCount > bytes.Length - byteIndex)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException(nameof(byteCount), SR.Format(SR.SizeExceedsRemainingBufferSpace, bytes.Length - byteIndex)));
|
||||
}
|
||||
|
||||
int charCount = GetCharCount(bytes, byteIndex, byteCount);
|
||||
if (chars == null)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException(nameof(chars)));
|
||||
}
|
||||
|
||||
if (charIndex < 0)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException(nameof(charIndex), SR.ValueMustBeNonNegative));
|
||||
}
|
||||
|
||||
if (charIndex > chars.Length)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException(nameof(charIndex), SR.Format(SR.OffsetExceedsBufferSize, chars.Length)));
|
||||
}
|
||||
|
||||
if (charCount < 0 || charCount > chars.Length - charIndex)
|
||||
{
|
||||
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(SR.XmlArrayTooSmall, nameof(chars)));
|
||||
}
|
||||
|
||||
// We've computed exactly how many chars there are and verified that
|
||||
// there's enough space in the char buffer, so we can proceed without
|
||||
// checking the charCount.
|
||||
|
||||
if (byteCount > 0)
|
||||
{
|
||||
fixed (byte* _val2byte = val2byte)
|
||||
{
|
||||
fixed (byte* _bytes = &bytes[byteIndex])
|
||||
{
|
||||
fixed (byte* _chars = &chars[charIndex])
|
||||
{
|
||||
byte* pb = _bytes;
|
||||
byte* pbMax = pb + byteCount - 3;
|
||||
byte* pch = _chars;
|
||||
|
||||
// Convert chunks of 3 bytes to 4 chars
|
||||
while (pb <= pbMax)
|
||||
{
|
||||
// 76543210 76543210 76543210
|
||||
// xx765432 xx107654 xx321076 xx543210
|
||||
|
||||
// Inspect the code carefully before you change this
|
||||
pch[0] = _val2byte[(pb[0] >> 2)];
|
||||
pch[1] = _val2byte[((pb[0] & 0x03) << 4) | (pb[1] >> 4)];
|
||||
pch[2] = _val2byte[((pb[1] & 0x0F) << 2) | (pb[2] >> 6)];
|
||||
pch[3] = _val2byte[pb[2] & 0x3F];
|
||||
|
||||
pb += 3;
|
||||
pch += 4;
|
||||
}
|
||||
|
||||
// Handle 1 or 2 trailing bytes
|
||||
if (pb - pbMax == 2)
|
||||
{
|
||||
// 1 trailing byte
|
||||
// 76543210 xxxxxxxx xxxxxxxx
|
||||
// xx765432 xx10xxxx xxxxxxxx xxxxxxxx
|
||||
pch[0] = _val2byte[(pb[0] >> 2)];
|
||||
pch[1] = _val2byte[((pb[0] & 0x03) << 4)];
|
||||
pch[2] = (byte)'=';
|
||||
pch[3] = (byte)'=';
|
||||
}
|
||||
else if (pb - pbMax == 1)
|
||||
{
|
||||
// 2 trailing bytes
|
||||
// 76543210 76543210 xxxxxxxx
|
||||
// xx765432 xx107654 xx3210xx xxxxxxxx
|
||||
pch[0] = _val2byte[(pb[0] >> 2)];
|
||||
pch[1] = _val2byte[((pb[0] & 0x03) << 4) | (pb[1] >> 4)];
|
||||
pch[2] = _val2byte[((pb[1] & 0x0F) << 2)];
|
||||
pch[3] = (byte)'=';
|
||||
}
|
||||
else
|
||||
{
|
||||
// 0 trailing bytes
|
||||
Fx.Assert(pb - pbMax == 3, "");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return charCount;
|
||||
}
|
||||
}
|
||||
}
|
||||
422
Compat.Private.Serialization/Compat/Xml/ArrayHelper.cs
Normal file
422
Compat.Private.Serialization/Compat/Xml/ArrayHelper.cs
Normal file
@@ -0,0 +1,422 @@
|
||||
using System;
|
||||
using System.Xml;
|
||||
|
||||
namespace Compat.Xml
|
||||
{
|
||||
internal abstract class ArrayHelper<TArgument, TArray>
|
||||
{
|
||||
private const int MaxInitialArrayLength = 65535;
|
||||
|
||||
public TArray[] ReadArray(XmlDictionaryReader reader, TArgument localName, TArgument namespaceUri, int maxArrayLength)
|
||||
{
|
||||
TArray[][] arrays = null;
|
||||
TArray[] array = null;
|
||||
int arrayCount = 0;
|
||||
int totalRead = 0;
|
||||
if (reader.TryGetArrayLength(out int count))
|
||||
{
|
||||
if (count > maxArrayLength)
|
||||
{
|
||||
XmlExceptionHelper.ThrowMaxArrayLengthOrMaxItemsQuotaExceeded(reader, maxArrayLength);
|
||||
}
|
||||
|
||||
if (count > MaxInitialArrayLength)
|
||||
{
|
||||
count = MaxInitialArrayLength;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
count = 32;
|
||||
}
|
||||
while (true)
|
||||
{
|
||||
array = new TArray[count];
|
||||
int read = 0;
|
||||
while (read < array.Length)
|
||||
{
|
||||
int actual = ReadArray(reader, localName, namespaceUri, array, read, array.Length - read);
|
||||
if (actual == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
read += actual;
|
||||
}
|
||||
if (totalRead > maxArrayLength - read)
|
||||
{
|
||||
XmlExceptionHelper.ThrowMaxArrayLengthOrMaxItemsQuotaExceeded(reader, maxArrayLength);
|
||||
}
|
||||
|
||||
totalRead += read;
|
||||
if (read < array.Length || reader.NodeType == XmlNodeType.EndElement)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (arrays == null)
|
||||
{
|
||||
arrays = new TArray[32][];
|
||||
}
|
||||
|
||||
arrays[arrayCount++] = array;
|
||||
count = count * 2;
|
||||
}
|
||||
if (totalRead != array.Length || arrayCount > 0)
|
||||
{
|
||||
TArray[] newArray = new TArray[totalRead];
|
||||
int offset = 0;
|
||||
for (int i = 0; i < arrayCount; i++)
|
||||
{
|
||||
Array.Copy(arrays[i], 0, newArray, offset, arrays[i].Length);
|
||||
offset += arrays[i].Length;
|
||||
}
|
||||
Array.Copy(array, 0, newArray, offset, totalRead - offset);
|
||||
array = newArray;
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
public void WriteArray(XmlDictionaryWriter writer, string prefix, TArgument localName, TArgument namespaceUri, XmlDictionaryReader reader)
|
||||
{
|
||||
if (reader.TryGetArrayLength(out int count))
|
||||
{
|
||||
count = Math.Min(count, 256);
|
||||
}
|
||||
else
|
||||
{
|
||||
count = 256;
|
||||
}
|
||||
|
||||
TArray[] array = new TArray[count];
|
||||
while (true)
|
||||
{
|
||||
int actual = ReadArray(reader, localName, namespaceUri, array, 0, array.Length);
|
||||
if (actual == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
WriteArray(writer, prefix, localName, namespaceUri, array, 0, actual);
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract int ReadArray(XmlDictionaryReader reader, TArgument localName, TArgument namespaceUri, TArray[] array, int offset, int count);
|
||||
protected abstract void WriteArray(XmlDictionaryWriter writer, string prefix, TArgument localName, TArgument namespaceUri, TArray[] array, int offset, int count);
|
||||
}
|
||||
|
||||
// Supported array types
|
||||
// bool
|
||||
// Int16
|
||||
// Int32
|
||||
// Int64
|
||||
// Float
|
||||
// Double
|
||||
// Decimal
|
||||
// DateTime
|
||||
// Guid
|
||||
// TimeSpan
|
||||
|
||||
// Int8 is not supported since sbyte[] is non-cls compliant, and uncommon
|
||||
// UniqueId is not supported since elements may be variable size strings
|
||||
|
||||
internal class BooleanArrayHelperWithString : ArrayHelper<string, bool>
|
||||
{
|
||||
public static readonly BooleanArrayHelperWithString Instance = new BooleanArrayHelperWithString();
|
||||
|
||||
protected override int ReadArray(XmlDictionaryReader reader, string localName, string namespaceUri, bool[] array, int offset, int count)
|
||||
{
|
||||
return reader.ReadArray(localName, namespaceUri, array, offset, count);
|
||||
}
|
||||
|
||||
protected override void WriteArray(XmlDictionaryWriter writer, string prefix, string localName, string namespaceUri, bool[] array, int offset, int count)
|
||||
{
|
||||
writer.WriteArray(prefix, localName, namespaceUri, array, offset, count);
|
||||
}
|
||||
}
|
||||
|
||||
internal class BooleanArrayHelperWithDictionaryString : ArrayHelper<XmlDictionaryString, bool>
|
||||
{
|
||||
public static readonly BooleanArrayHelperWithDictionaryString Instance = new BooleanArrayHelperWithDictionaryString();
|
||||
|
||||
protected override int ReadArray(XmlDictionaryReader reader, XmlDictionaryString localName, XmlDictionaryString namespaceUri, bool[] array, int offset, int count)
|
||||
{
|
||||
return reader.ReadArray(localName, namespaceUri, array, offset, count);
|
||||
}
|
||||
|
||||
protected override void WriteArray(XmlDictionaryWriter writer, string prefix, XmlDictionaryString localName, XmlDictionaryString namespaceUri, bool[] array, int offset, int count)
|
||||
{
|
||||
writer.WriteArray(prefix, localName, namespaceUri, array, offset, count);
|
||||
}
|
||||
}
|
||||
|
||||
internal class Int16ArrayHelperWithString : ArrayHelper<string, short>
|
||||
{
|
||||
public static readonly Int16ArrayHelperWithString Instance = new Int16ArrayHelperWithString();
|
||||
|
||||
protected override int ReadArray(XmlDictionaryReader reader, string localName, string namespaceUri, short[] array, int offset, int count)
|
||||
{
|
||||
return reader.ReadArray(localName, namespaceUri, array, offset, count);
|
||||
}
|
||||
|
||||
protected override void WriteArray(XmlDictionaryWriter writer, string prefix, string localName, string namespaceUri, short[] array, int offset, int count)
|
||||
{
|
||||
writer.WriteArray(prefix, localName, namespaceUri, array, offset, count);
|
||||
}
|
||||
}
|
||||
|
||||
internal class Int16ArrayHelperWithDictionaryString : ArrayHelper<XmlDictionaryString, short>
|
||||
{
|
||||
public static readonly Int16ArrayHelperWithDictionaryString Instance = new Int16ArrayHelperWithDictionaryString();
|
||||
|
||||
protected override int ReadArray(XmlDictionaryReader reader, XmlDictionaryString localName, XmlDictionaryString namespaceUri, short[] array, int offset, int count)
|
||||
{
|
||||
return reader.ReadArray(localName, namespaceUri, array, offset, count);
|
||||
}
|
||||
|
||||
protected override void WriteArray(XmlDictionaryWriter writer, string prefix, XmlDictionaryString localName, XmlDictionaryString namespaceUri, short[] array, int offset, int count)
|
||||
{
|
||||
writer.WriteArray(prefix, localName, namespaceUri, array, offset, count);
|
||||
}
|
||||
}
|
||||
|
||||
internal class Int32ArrayHelperWithString : ArrayHelper<string, int>
|
||||
{
|
||||
public static readonly Int32ArrayHelperWithString Instance = new Int32ArrayHelperWithString();
|
||||
|
||||
protected override int ReadArray(XmlDictionaryReader reader, string localName, string namespaceUri, int[] array, int offset, int count)
|
||||
{
|
||||
return reader.ReadArray(localName, namespaceUri, array, offset, count);
|
||||
}
|
||||
|
||||
protected override void WriteArray(XmlDictionaryWriter writer, string prefix, string localName, string namespaceUri, int[] array, int offset, int count)
|
||||
{
|
||||
writer.WriteArray(prefix, localName, namespaceUri, array, offset, count);
|
||||
}
|
||||
}
|
||||
|
||||
internal class Int32ArrayHelperWithDictionaryString : ArrayHelper<XmlDictionaryString, int>
|
||||
{
|
||||
public static readonly Int32ArrayHelperWithDictionaryString Instance = new Int32ArrayHelperWithDictionaryString();
|
||||
|
||||
protected override int ReadArray(XmlDictionaryReader reader, XmlDictionaryString localName, XmlDictionaryString namespaceUri, int[] array, int offset, int count)
|
||||
{
|
||||
return reader.ReadArray(localName, namespaceUri, array, offset, count);
|
||||
}
|
||||
|
||||
protected override void WriteArray(XmlDictionaryWriter writer, string prefix, XmlDictionaryString localName, XmlDictionaryString namespaceUri, int[] array, int offset, int count)
|
||||
{
|
||||
writer.WriteArray(prefix, localName, namespaceUri, array, offset, count);
|
||||
}
|
||||
}
|
||||
|
||||
internal class Int64ArrayHelperWithString : ArrayHelper<string, long>
|
||||
{
|
||||
public static readonly Int64ArrayHelperWithString Instance = new Int64ArrayHelperWithString();
|
||||
|
||||
protected override int ReadArray(XmlDictionaryReader reader, string localName, string namespaceUri, long[] array, int offset, int count)
|
||||
{
|
||||
return reader.ReadArray(localName, namespaceUri, array, offset, count);
|
||||
}
|
||||
|
||||
protected override void WriteArray(XmlDictionaryWriter writer, string prefix, string localName, string namespaceUri, long[] array, int offset, int count)
|
||||
{
|
||||
writer.WriteArray(prefix, localName, namespaceUri, array, offset, count);
|
||||
}
|
||||
}
|
||||
|
||||
internal class Int64ArrayHelperWithDictionaryString : ArrayHelper<XmlDictionaryString, long>
|
||||
{
|
||||
public static readonly Int64ArrayHelperWithDictionaryString Instance = new Int64ArrayHelperWithDictionaryString();
|
||||
|
||||
protected override int ReadArray(XmlDictionaryReader reader, XmlDictionaryString localName, XmlDictionaryString namespaceUri, long[] array, int offset, int count)
|
||||
{
|
||||
return reader.ReadArray(localName, namespaceUri, array, offset, count);
|
||||
}
|
||||
|
||||
protected override void WriteArray(XmlDictionaryWriter writer, string prefix, XmlDictionaryString localName, XmlDictionaryString namespaceUri, long[] array, int offset, int count)
|
||||
{
|
||||
writer.WriteArray(prefix, localName, namespaceUri, array, offset, count);
|
||||
}
|
||||
}
|
||||
|
||||
internal class SingleArrayHelperWithString : ArrayHelper<string, float>
|
||||
{
|
||||
public static readonly SingleArrayHelperWithString Instance = new SingleArrayHelperWithString();
|
||||
|
||||
protected override int ReadArray(XmlDictionaryReader reader, string localName, string namespaceUri, float[] array, int offset, int count)
|
||||
{
|
||||
return reader.ReadArray(localName, namespaceUri, array, offset, count);
|
||||
}
|
||||
|
||||
protected override void WriteArray(XmlDictionaryWriter writer, string prefix, string localName, string namespaceUri, float[] array, int offset, int count)
|
||||
{
|
||||
writer.WriteArray(prefix, localName, namespaceUri, array, offset, count);
|
||||
}
|
||||
}
|
||||
|
||||
internal class SingleArrayHelperWithDictionaryString : ArrayHelper<XmlDictionaryString, float>
|
||||
{
|
||||
public static readonly SingleArrayHelperWithDictionaryString Instance = new SingleArrayHelperWithDictionaryString();
|
||||
|
||||
protected override int ReadArray(XmlDictionaryReader reader, XmlDictionaryString localName, XmlDictionaryString namespaceUri, float[] array, int offset, int count)
|
||||
{
|
||||
return reader.ReadArray(localName, namespaceUri, array, offset, count);
|
||||
}
|
||||
|
||||
protected override void WriteArray(XmlDictionaryWriter writer, string prefix, XmlDictionaryString localName, XmlDictionaryString namespaceUri, float[] array, int offset, int count)
|
||||
{
|
||||
writer.WriteArray(prefix, localName, namespaceUri, array, offset, count);
|
||||
}
|
||||
}
|
||||
|
||||
internal class DoubleArrayHelperWithString : ArrayHelper<string, double>
|
||||
{
|
||||
public static readonly DoubleArrayHelperWithString Instance = new DoubleArrayHelperWithString();
|
||||
|
||||
protected override int ReadArray(XmlDictionaryReader reader, string localName, string namespaceUri, double[] array, int offset, int count)
|
||||
{
|
||||
return reader.ReadArray(localName, namespaceUri, array, offset, count);
|
||||
}
|
||||
|
||||
protected override void WriteArray(XmlDictionaryWriter writer, string prefix, string localName, string namespaceUri, double[] array, int offset, int count)
|
||||
{
|
||||
writer.WriteArray(prefix, localName, namespaceUri, array, offset, count);
|
||||
}
|
||||
}
|
||||
|
||||
internal class DoubleArrayHelperWithDictionaryString : ArrayHelper<XmlDictionaryString, double>
|
||||
{
|
||||
public static readonly DoubleArrayHelperWithDictionaryString Instance = new DoubleArrayHelperWithDictionaryString();
|
||||
|
||||
protected override int ReadArray(XmlDictionaryReader reader, XmlDictionaryString localName, XmlDictionaryString namespaceUri, double[] array, int offset, int count)
|
||||
{
|
||||
return reader.ReadArray(localName, namespaceUri, array, offset, count);
|
||||
}
|
||||
|
||||
protected override void WriteArray(XmlDictionaryWriter writer, string prefix, XmlDictionaryString localName, XmlDictionaryString namespaceUri, double[] array, int offset, int count)
|
||||
{
|
||||
writer.WriteArray(prefix, localName, namespaceUri, array, offset, count);
|
||||
}
|
||||
}
|
||||
|
||||
internal class DecimalArrayHelperWithString : ArrayHelper<string, decimal>
|
||||
{
|
||||
public static readonly DecimalArrayHelperWithString Instance = new DecimalArrayHelperWithString();
|
||||
|
||||
protected override int ReadArray(XmlDictionaryReader reader, string localName, string namespaceUri, decimal[] array, int offset, int count)
|
||||
{
|
||||
return reader.ReadArray(localName, namespaceUri, array, offset, count);
|
||||
}
|
||||
|
||||
protected override void WriteArray(XmlDictionaryWriter writer, string prefix, string localName, string namespaceUri, decimal[] array, int offset, int count)
|
||||
{
|
||||
writer.WriteArray(prefix, localName, namespaceUri, array, offset, count);
|
||||
}
|
||||
}
|
||||
|
||||
internal class DecimalArrayHelperWithDictionaryString : ArrayHelper<XmlDictionaryString, decimal>
|
||||
{
|
||||
public static readonly DecimalArrayHelperWithDictionaryString Instance = new DecimalArrayHelperWithDictionaryString();
|
||||
|
||||
protected override int ReadArray(XmlDictionaryReader reader, XmlDictionaryString localName, XmlDictionaryString namespaceUri, decimal[] array, int offset, int count)
|
||||
{
|
||||
return reader.ReadArray(localName, namespaceUri, array, offset, count);
|
||||
}
|
||||
|
||||
protected override void WriteArray(XmlDictionaryWriter writer, string prefix, XmlDictionaryString localName, XmlDictionaryString namespaceUri, decimal[] array, int offset, int count)
|
||||
{
|
||||
writer.WriteArray(prefix, localName, namespaceUri, array, offset, count);
|
||||
}
|
||||
}
|
||||
|
||||
internal class DateTimeArrayHelperWithString : ArrayHelper<string, DateTime>
|
||||
{
|
||||
public static readonly DateTimeArrayHelperWithString Instance = new DateTimeArrayHelperWithString();
|
||||
|
||||
protected override int ReadArray(XmlDictionaryReader reader, string localName, string namespaceUri, DateTime[] array, int offset, int count)
|
||||
{
|
||||
return reader.ReadArray(localName, namespaceUri, array, offset, count);
|
||||
}
|
||||
|
||||
protected override void WriteArray(XmlDictionaryWriter writer, string prefix, string localName, string namespaceUri, DateTime[] array, int offset, int count)
|
||||
{
|
||||
writer.WriteArray(prefix, localName, namespaceUri, array, offset, count);
|
||||
}
|
||||
}
|
||||
|
||||
internal class DateTimeArrayHelperWithDictionaryString : ArrayHelper<XmlDictionaryString, DateTime>
|
||||
{
|
||||
public static readonly DateTimeArrayHelperWithDictionaryString Instance = new DateTimeArrayHelperWithDictionaryString();
|
||||
|
||||
protected override int ReadArray(XmlDictionaryReader reader, XmlDictionaryString localName, XmlDictionaryString namespaceUri, DateTime[] array, int offset, int count)
|
||||
{
|
||||
return reader.ReadArray(localName, namespaceUri, array, offset, count);
|
||||
}
|
||||
|
||||
protected override void WriteArray(XmlDictionaryWriter writer, string prefix, XmlDictionaryString localName, XmlDictionaryString namespaceUri, DateTime[] array, int offset, int count)
|
||||
{
|
||||
writer.WriteArray(prefix, localName, namespaceUri, array, offset, count);
|
||||
}
|
||||
}
|
||||
|
||||
internal class GuidArrayHelperWithString : ArrayHelper<string, Guid>
|
||||
{
|
||||
public static readonly GuidArrayHelperWithString Instance = new GuidArrayHelperWithString();
|
||||
|
||||
protected override int ReadArray(XmlDictionaryReader reader, string localName, string namespaceUri, Guid[] array, int offset, int count)
|
||||
{
|
||||
return reader.ReadArray(localName, namespaceUri, array, offset, count);
|
||||
}
|
||||
|
||||
protected override void WriteArray(XmlDictionaryWriter writer, string prefix, string localName, string namespaceUri, Guid[] array, int offset, int count)
|
||||
{
|
||||
writer.WriteArray(prefix, localName, namespaceUri, array, offset, count);
|
||||
}
|
||||
}
|
||||
|
||||
internal class GuidArrayHelperWithDictionaryString : ArrayHelper<XmlDictionaryString, Guid>
|
||||
{
|
||||
public static readonly GuidArrayHelperWithDictionaryString Instance = new GuidArrayHelperWithDictionaryString();
|
||||
|
||||
protected override int ReadArray(XmlDictionaryReader reader, XmlDictionaryString localName, XmlDictionaryString namespaceUri, Guid[] array, int offset, int count)
|
||||
{
|
||||
return reader.ReadArray(localName, namespaceUri, array, offset, count);
|
||||
}
|
||||
|
||||
protected override void WriteArray(XmlDictionaryWriter writer, string prefix, XmlDictionaryString localName, XmlDictionaryString namespaceUri, Guid[] array, int offset, int count)
|
||||
{
|
||||
writer.WriteArray(prefix, localName, namespaceUri, array, offset, count);
|
||||
}
|
||||
}
|
||||
|
||||
internal class TimeSpanArrayHelperWithString : ArrayHelper<string, TimeSpan>
|
||||
{
|
||||
public static readonly TimeSpanArrayHelperWithString Instance = new TimeSpanArrayHelperWithString();
|
||||
|
||||
protected override int ReadArray(XmlDictionaryReader reader, string localName, string namespaceUri, TimeSpan[] array, int offset, int count)
|
||||
{
|
||||
return reader.ReadArray(localName, namespaceUri, array, offset, count);
|
||||
}
|
||||
|
||||
protected override void WriteArray(XmlDictionaryWriter writer, string prefix, string localName, string namespaceUri, TimeSpan[] array, int offset, int count)
|
||||
{
|
||||
writer.WriteArray(prefix, localName, namespaceUri, array, offset, count);
|
||||
}
|
||||
}
|
||||
|
||||
internal class TimeSpanArrayHelperWithDictionaryString : ArrayHelper<XmlDictionaryString, TimeSpan>
|
||||
{
|
||||
public static readonly TimeSpanArrayHelperWithDictionaryString Instance = new TimeSpanArrayHelperWithDictionaryString();
|
||||
|
||||
protected override int ReadArray(XmlDictionaryReader reader, XmlDictionaryString localName, XmlDictionaryString namespaceUri, TimeSpan[] array, int offset, int count)
|
||||
{
|
||||
return reader.ReadArray(localName, namespaceUri, array, offset, count);
|
||||
}
|
||||
|
||||
protected override void WriteArray(XmlDictionaryWriter writer, string prefix, XmlDictionaryString localName, XmlDictionaryString namespaceUri, TimeSpan[] array, int offset, int count)
|
||||
{
|
||||
writer.WriteArray(prefix, localName, namespaceUri, array, offset, count);
|
||||
}
|
||||
}
|
||||
}
|
||||
288
Compat.Private.Serialization/Compat/Xml/XmlExceptionHelper.cs
Normal file
288
Compat.Private.Serialization/Compat/Xml/XmlExceptionHelper.cs
Normal file
@@ -0,0 +1,288 @@
|
||||
////using System.ServiceModel.Channels;
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Xml;
|
||||
|
||||
namespace Compat.Xml
|
||||
{
|
||||
internal static class XmlExceptionHelper
|
||||
{
|
||||
private static void ThrowXmlException(XmlDictionaryReader reader, string res)
|
||||
{
|
||||
ThrowXmlException(reader, res, null);
|
||||
}
|
||||
|
||||
private static void ThrowXmlException(XmlDictionaryReader reader, string res, string arg1)
|
||||
{
|
||||
ThrowXmlException(reader, res, arg1, null);
|
||||
}
|
||||
|
||||
private static void ThrowXmlException(XmlDictionaryReader reader, string res, string arg1, string arg2)
|
||||
{
|
||||
ThrowXmlException(reader, res, arg1, arg2, null);
|
||||
}
|
||||
|
||||
private static void ThrowXmlException(XmlDictionaryReader reader, string res, string arg1, string arg2, string arg3)
|
||||
{
|
||||
string s = SR.Format(res, arg1, arg2, arg3);
|
||||
if (reader is IXmlLineInfo lineInfo && lineInfo.HasLineInfo())
|
||||
{
|
||||
s += " " + SR.Format(SR.XmlLineInfo, lineInfo.LineNumber, lineInfo.LinePosition);
|
||||
}
|
||||
|
||||
throw Compat.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new System.Xml.XmlException(s));
|
||||
}
|
||||
|
||||
public static void ThrowXmlException(XmlDictionaryReader reader, XmlException exception)
|
||||
{
|
||||
string s = exception.Message;
|
||||
if (reader is IXmlLineInfo lineInfo && lineInfo.HasLineInfo())
|
||||
{
|
||||
s += " " + SR.Format(SR.XmlLineInfo, lineInfo.LineNumber, lineInfo.LinePosition);
|
||||
}
|
||||
throw Compat.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new XmlException(s));
|
||||
}
|
||||
|
||||
private static string GetName(string prefix, string localName)
|
||||
{
|
||||
if (prefix.Length == 0)
|
||||
{
|
||||
return localName;
|
||||
}
|
||||
else
|
||||
{
|
||||
return string.Concat(prefix, ":", localName);
|
||||
}
|
||||
}
|
||||
|
||||
private static string GetWhatWasFound(XmlDictionaryReader reader)
|
||||
{
|
||||
if (reader.EOF)
|
||||
{
|
||||
return SR.XmlFoundEndOfFile;
|
||||
}
|
||||
|
||||
switch (reader.NodeType)
|
||||
{
|
||||
case XmlNodeType.Element:
|
||||
return SR.Format(SR.XmlFoundElement, GetName(reader.Prefix, reader.LocalName), reader.NamespaceURI);
|
||||
case XmlNodeType.EndElement:
|
||||
return SR.Format(SR.XmlFoundEndElement, GetName(reader.Prefix, reader.LocalName), reader.NamespaceURI);
|
||||
case XmlNodeType.Text:
|
||||
case XmlNodeType.Whitespace:
|
||||
case XmlNodeType.SignificantWhitespace:
|
||||
return SR.Format(SR.XmlFoundText, reader.Value);
|
||||
case XmlNodeType.Comment:
|
||||
return SR.Format(SR.XmlFoundComment, reader.Value);
|
||||
case XmlNodeType.CDATA:
|
||||
return SR.Format(SR.XmlFoundCData, reader.Value);
|
||||
}
|
||||
return SR.Format(SR.XmlFoundNodeType, reader.NodeType);
|
||||
}
|
||||
|
||||
//public static void ThrowStartElementExpected(XmlDictionaryReader reader)
|
||||
//{
|
||||
// ThrowXmlException(reader, SR.XmlStartElementExpected, GetWhatWasFound(reader));
|
||||
//}
|
||||
|
||||
//public static void ThrowStartElementExpected(XmlDictionaryReader reader, string name)
|
||||
//{
|
||||
// ThrowXmlException(reader, SR.XmlStartElementNameExpected, name, GetWhatWasFound(reader));
|
||||
//}
|
||||
|
||||
//public static void ThrowStartElementExpected(XmlDictionaryReader reader, string localName, string ns)
|
||||
//{
|
||||
// ThrowXmlException(reader, SR.XmlStartElementLocalNameNsExpected, localName, ns, GetWhatWasFound(reader));
|
||||
//}
|
||||
|
||||
//public static void ThrowStartElementExpected(XmlDictionaryReader reader, XmlDictionaryString localName, XmlDictionaryString ns)
|
||||
//{
|
||||
// ThrowStartElementExpected(reader, localName?.Value, ns?.Value);
|
||||
//}
|
||||
|
||||
//public static void ThrowFullStartElementExpected(XmlDictionaryReader reader)
|
||||
//{
|
||||
// ThrowXmlException(reader, SR.XmlFullStartElementExpected, GetWhatWasFound(reader));
|
||||
//}
|
||||
|
||||
//public static void ThrowFullStartElementExpected(XmlDictionaryReader reader, string name)
|
||||
//{
|
||||
// ThrowXmlException(reader, SR.XmlFullStartElementNameExpected, name, GetWhatWasFound(reader));
|
||||
//}
|
||||
|
||||
//public static void ThrowFullStartElementExpected(XmlDictionaryReader reader, string localName, string ns)
|
||||
//{
|
||||
// ThrowXmlException(reader, SR.XmlFullStartElementLocalNameNsExpected, localName, ns, GetWhatWasFound(reader));
|
||||
//}
|
||||
|
||||
//public static void ThrowFullStartElementExpected(XmlDictionaryReader reader, XmlDictionaryString localName, XmlDictionaryString ns)
|
||||
//{
|
||||
// ThrowFullStartElementExpected(reader, localName?.Value, ns?.Value);
|
||||
//}
|
||||
|
||||
//public static void ThrowEndElementExpected(XmlDictionaryReader reader, string localName, string ns)
|
||||
//{
|
||||
// ThrowXmlException(reader, SR.XmlEndElementExpected, localName, ns, GetWhatWasFound(reader));
|
||||
//}
|
||||
|
||||
//public static void ThrowMaxStringContentLengthExceeded(XmlDictionaryReader reader, int maxStringContentLength)
|
||||
//{
|
||||
// ThrowXmlException(reader, SR.XmlMaxStringContentLengthExceeded, maxStringContentLength.ToString(NumberFormatInfo.CurrentInfo));
|
||||
//}
|
||||
|
||||
//public static void ThrowMaxArrayLengthExceeded(XmlDictionaryReader reader, int maxArrayLength)
|
||||
//{
|
||||
// ThrowXmlException(reader, SR.XmlMaxArrayLengthExceeded, maxArrayLength.ToString(NumberFormatInfo.CurrentInfo));
|
||||
//}
|
||||
|
||||
public static void ThrowMaxArrayLengthOrMaxItemsQuotaExceeded(XmlDictionaryReader reader, int maxQuota)
|
||||
{
|
||||
ThrowXmlException(reader, SR.XmlMaxArrayLengthOrMaxItemsQuotaExceeded, maxQuota.ToString(NumberFormatInfo.CurrentInfo));
|
||||
}
|
||||
|
||||
//public static void ThrowMaxDepthExceeded(XmlDictionaryReader reader, int maxDepth)
|
||||
//{
|
||||
// ThrowXmlException(reader, SR.XmlMaxDepthExceeded, maxDepth.ToString(NumberFormatInfo.CurrentInfo));
|
||||
//}
|
||||
|
||||
//public static void ThrowMaxBytesPerReadExceeded(XmlDictionaryReader reader, int maxBytesPerRead)
|
||||
//{
|
||||
// ThrowXmlException(reader, SR.XmlMaxBytesPerReadExceeded, maxBytesPerRead.ToString(NumberFormatInfo.CurrentInfo));
|
||||
//}
|
||||
|
||||
//public static void ThrowMaxNameTableCharCountExceeded(XmlDictionaryReader reader, int maxNameTableCharCount)
|
||||
//{
|
||||
// ThrowXmlException(reader, SR.XmlMaxNameTableCharCountExceeded, maxNameTableCharCount.ToString(NumberFormatInfo.CurrentInfo));
|
||||
//}
|
||||
|
||||
//public static void ThrowBase64DataExpected(XmlDictionaryReader reader)
|
||||
//{
|
||||
// ThrowXmlException(reader, SR.XmlBase64DataExpected, GetWhatWasFound(reader));
|
||||
//}
|
||||
|
||||
//public static void ThrowUndefinedPrefix(XmlDictionaryReader reader, string prefix)
|
||||
//{
|
||||
// ThrowXmlException(reader, SR.XmlUndefinedPrefix, prefix);
|
||||
//}
|
||||
|
||||
//public static void ThrowProcessingInstructionNotSupported(XmlDictionaryReader reader)
|
||||
//{
|
||||
// ThrowXmlException(reader, SR.XmlProcessingInstructionNotSupported);
|
||||
//}
|
||||
|
||||
//public static void ThrowInvalidXml(XmlDictionaryReader reader, byte b)
|
||||
//{
|
||||
// ThrowXmlException(reader, SR.XmlInvalidXmlByte, b.ToString("X2", CultureInfo.InvariantCulture));
|
||||
//}
|
||||
|
||||
//public static void ThrowUnexpectedEndOfFile(XmlDictionaryReader reader)
|
||||
//{
|
||||
// ThrowXmlException(reader, SR.XmlUnexpectedEndOfFile, ((XmlBaseReader)reader).GetOpenElements());
|
||||
//}
|
||||
|
||||
//public static void ThrowUnexpectedEndElement(XmlDictionaryReader reader)
|
||||
//{
|
||||
// ThrowXmlException(reader, SR.XmlUnexpectedEndElement);
|
||||
//}
|
||||
|
||||
//public static void ThrowTokenExpected(XmlDictionaryReader reader, string expected, char found)
|
||||
//{
|
||||
// ThrowXmlException(reader, SR.XmlTokenExpected, expected, found.ToString());
|
||||
//}
|
||||
|
||||
//public static void ThrowTokenExpected(XmlDictionaryReader reader, string expected, string found)
|
||||
//{
|
||||
// ThrowXmlException(reader, SR.XmlTokenExpected, expected, found);
|
||||
//}
|
||||
|
||||
//public static void ThrowInvalidCharRef(XmlDictionaryReader reader)
|
||||
//{
|
||||
// ThrowXmlException(reader, SR.XmlInvalidCharRef);
|
||||
//}
|
||||
|
||||
//public static void ThrowTagMismatch(XmlDictionaryReader reader, string expectedPrefix, string expectedLocalName, string foundPrefix, string foundLocalName)
|
||||
//{
|
||||
// ThrowXmlException(reader, SR.XmlTagMismatch, GetName(expectedPrefix, expectedLocalName), GetName(foundPrefix, foundLocalName));
|
||||
//}
|
||||
|
||||
//public static void ThrowDuplicateXmlnsAttribute(XmlDictionaryReader reader, string localName, string ns)
|
||||
//{
|
||||
// string name;
|
||||
// if (localName.Length == 0)
|
||||
// {
|
||||
// name = "xmlns";
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// name = "xmlns:" + localName;
|
||||
// }
|
||||
|
||||
// ThrowXmlException(reader, SR.XmlDuplicateAttribute, name, name, ns);
|
||||
//}
|
||||
|
||||
//public static void ThrowDuplicateAttribute(XmlDictionaryReader reader, string prefix1, string prefix2, string localName, string ns)
|
||||
//{
|
||||
// ThrowXmlException(reader, SR.XmlDuplicateAttribute, GetName(prefix1, localName), GetName(prefix2, localName), ns);
|
||||
//}
|
||||
|
||||
//public static void ThrowInvalidBinaryFormat(XmlDictionaryReader reader)
|
||||
//{
|
||||
// ThrowXmlException(reader, SR.XmlInvalidFormat);
|
||||
//}
|
||||
|
||||
//public static void ThrowInvalidRootData(XmlDictionaryReader reader)
|
||||
//{
|
||||
// ThrowXmlException(reader, SR.XmlInvalidRootData);
|
||||
//}
|
||||
|
||||
//public static void ThrowMultipleRootElements(XmlDictionaryReader reader)
|
||||
//{
|
||||
// ThrowXmlException(reader, SR.XmlMultipleRootElements);
|
||||
//}
|
||||
|
||||
//public static void ThrowDeclarationNotFirst(XmlDictionaryReader reader)
|
||||
//{
|
||||
// ThrowXmlException(reader, SR.XmlDeclNotFirst);
|
||||
//}
|
||||
|
||||
//public static void ThrowConversionOverflow(XmlDictionaryReader reader, string value, string type)
|
||||
//{
|
||||
// ThrowXmlException(reader, SR.XmlConversionOverflow, value, type);
|
||||
//}
|
||||
|
||||
//public static void ThrowXmlDictionaryStringIDOutOfRange(XmlDictionaryReader reader)
|
||||
//{
|
||||
// ThrowXmlException(reader, SR.XmlDictionaryStringIDRange, XmlDictionaryString.MinKey.ToString(NumberFormatInfo.CurrentInfo), XmlDictionaryString.MaxKey.ToString(NumberFormatInfo.CurrentInfo));
|
||||
//}
|
||||
|
||||
//public static void ThrowXmlDictionaryStringIDUndefinedStatic(XmlDictionaryReader reader, int key)
|
||||
//{
|
||||
// ThrowXmlException(reader, SR.XmlDictionaryStringIDUndefinedStatic, key.ToString(NumberFormatInfo.CurrentInfo));
|
||||
//}
|
||||
|
||||
//public static void ThrowXmlDictionaryStringIDUndefinedSession(XmlDictionaryReader reader, int key)
|
||||
//{
|
||||
// ThrowXmlException(reader, SR.XmlDictionaryStringIDUndefinedSession, key.ToString(NumberFormatInfo.CurrentInfo));
|
||||
//}
|
||||
|
||||
//public static void ThrowEmptyNamespace(XmlDictionaryReader reader)
|
||||
//{
|
||||
// ThrowXmlException(reader, SR.XmlEmptyNamespaceRequiresNullPrefix);
|
||||
//}
|
||||
|
||||
public static XmlException CreateConversionException(string value, string type, Exception exception)
|
||||
{
|
||||
return new XmlException(SR.Format(SR.XmlInvalidConversion, value, type), exception);
|
||||
}
|
||||
|
||||
public static XmlException CreateEncodingException(byte[] buffer, int offset, int count, Exception exception)
|
||||
{
|
||||
return CreateEncodingException(new System.Text.UTF8Encoding(false, false).GetString(buffer, offset, count), exception);
|
||||
}
|
||||
|
||||
public static XmlException CreateEncodingException(string value, Exception exception)
|
||||
{
|
||||
return new XmlException(SR.Format(SR.XmlInvalidUTF8Bytes, value), exception);
|
||||
}
|
||||
}
|
||||
}
|
||||
3996
Compat.Private.Serialization/Resources/Common/SR.Designer.cs
generated
Normal file
3996
Compat.Private.Serialization/Resources/Common/SR.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load Diff
136
Compat.Private.Serialization/Resources/Common/SR.cs
Normal file
136
Compat.Private.Serialization/Resources/Common/SR.cs
Normal file
@@ -0,0 +1,136 @@
|
||||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
#nullable enable
|
||||
|
||||
using System;
|
||||
using System.Resources;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace Compat
|
||||
{
|
||||
internal partial class SR
|
||||
{
|
||||
// This method is used to decide if we need to append the exception message parameters to the message when calling SR.Format.
|
||||
// by default it returns false.
|
||||
// Native code generators can replace the value this returns based on user input at the time of native code generation.
|
||||
// Marked as NoInlining because if this is used in an AoT compiled app that is not compiled into a single file, the user
|
||||
// could compile each module with a different setting for this. We want to make sure there's a consistent behavior
|
||||
// that doesn't depend on which native module this method got inlined into.
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
private static bool UsingResourceKeys() => false;
|
||||
|
||||
internal static string GetResourceString(string resourceKey, string? defaultString = null)
|
||||
{
|
||||
if (UsingResourceKeys())
|
||||
{
|
||||
return defaultString ?? resourceKey;
|
||||
}
|
||||
|
||||
string? resourceString = null;
|
||||
try
|
||||
{
|
||||
resourceString = ResourceManager.GetString(resourceKey);
|
||||
}
|
||||
catch (MissingManifestResourceException) { }
|
||||
|
||||
if (defaultString != null && resourceKey.Equals(resourceString))
|
||||
{
|
||||
return defaultString;
|
||||
}
|
||||
|
||||
return resourceString!; // only null if missing resources
|
||||
}
|
||||
|
||||
internal static string Format(string resourceFormat, object? p1)
|
||||
{
|
||||
if (UsingResourceKeys())
|
||||
{
|
||||
return string.Join(", ", resourceFormat, p1);
|
||||
}
|
||||
|
||||
return string.Format(resourceFormat, p1);
|
||||
}
|
||||
|
||||
internal static string Format(string resourceFormat, object? p1, object? p2)
|
||||
{
|
||||
if (UsingResourceKeys())
|
||||
{
|
||||
return string.Join(", ", resourceFormat, p1, p2);
|
||||
}
|
||||
|
||||
return string.Format(resourceFormat, p1, p2);
|
||||
}
|
||||
|
||||
internal static string Format(string resourceFormat, object? p1, object? p2, object? p3)
|
||||
{
|
||||
if (UsingResourceKeys())
|
||||
{
|
||||
return string.Join(", ", resourceFormat, p1, p2, p3);
|
||||
}
|
||||
|
||||
return string.Format(resourceFormat, p1, p2, p3);
|
||||
}
|
||||
|
||||
internal static string Format(string resourceFormat, params object?[]? args)
|
||||
{
|
||||
if (args != null)
|
||||
{
|
||||
if (UsingResourceKeys())
|
||||
{
|
||||
return resourceFormat + ", " + string.Join(", ", args);
|
||||
}
|
||||
|
||||
return string.Format(resourceFormat, args);
|
||||
}
|
||||
|
||||
return resourceFormat;
|
||||
}
|
||||
|
||||
internal static string Format(IFormatProvider? provider, string resourceFormat, object? p1)
|
||||
{
|
||||
if (UsingResourceKeys())
|
||||
{
|
||||
return string.Join(", ", resourceFormat, p1);
|
||||
}
|
||||
|
||||
return string.Format(provider, resourceFormat, p1);
|
||||
}
|
||||
|
||||
internal static string Format(IFormatProvider? provider, string resourceFormat, object? p1, object? p2)
|
||||
{
|
||||
if (UsingResourceKeys())
|
||||
{
|
||||
return string.Join(", ", resourceFormat, p1, p2);
|
||||
}
|
||||
|
||||
return string.Format(provider, resourceFormat, p1, p2);
|
||||
}
|
||||
|
||||
internal static string Format(IFormatProvider? provider, string resourceFormat, object? p1, object? p2, object? p3)
|
||||
{
|
||||
if (UsingResourceKeys())
|
||||
{
|
||||
return string.Join(", ", resourceFormat, p1, p2, p3);
|
||||
}
|
||||
|
||||
return string.Format(provider, resourceFormat, p1, p2, p3);
|
||||
}
|
||||
|
||||
internal static string Format(IFormatProvider? provider, string resourceFormat, params object?[]? args)
|
||||
{
|
||||
if (args != null)
|
||||
{
|
||||
if (UsingResourceKeys())
|
||||
{
|
||||
return resourceFormat + ", " + string.Join(", ", args);
|
||||
}
|
||||
|
||||
return string.Format(provider, resourceFormat, args);
|
||||
}
|
||||
|
||||
return resourceFormat;
|
||||
}
|
||||
}
|
||||
}
|
||||
1431
Compat.Private.Serialization/Resources/SR.resx
Normal file
1431
Compat.Private.Serialization/Resources/SR.resx
Normal file
File diff suppressed because it is too large
Load Diff
123
NetDataContractSerializer.sln
Normal file
123
NetDataContractSerializer.sln
Normal file
@@ -0,0 +1,123 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 16
|
||||
VisualStudioVersion = 16.0.29209.152
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Compat.Private.Serialization", "Compat.Private.Serialization\Compat.Private.Serialization.csproj", "{1F4EB25F-3A60-45DC-A547-47847B194B32}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Debug|x86 = Debug|x86
|
||||
Release|Any CPU = Release|Any CPU
|
||||
Release|x86 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{AB2CF6F8-831A-440A-B90A-4C1EB3437A15}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{AB2CF6F8-831A-440A-B90A-4C1EB3437A15}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{AB2CF6F8-831A-440A-B90A-4C1EB3437A15}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{AB2CF6F8-831A-440A-B90A-4C1EB3437A15}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{AB2CF6F8-831A-440A-B90A-4C1EB3437A15}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{AB2CF6F8-831A-440A-B90A-4C1EB3437A15}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{AB2CF6F8-831A-440A-B90A-4C1EB3437A15}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{AB2CF6F8-831A-440A-B90A-4C1EB3437A15}.Release|x86.Build.0 = Release|Any CPU
|
||||
{998759D0-5251-44FB-B5ED-331D28751F1C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{998759D0-5251-44FB-B5ED-331D28751F1C}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{998759D0-5251-44FB-B5ED-331D28751F1C}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{998759D0-5251-44FB-B5ED-331D28751F1C}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{998759D0-5251-44FB-B5ED-331D28751F1C}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{998759D0-5251-44FB-B5ED-331D28751F1C}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{998759D0-5251-44FB-B5ED-331D28751F1C}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{998759D0-5251-44FB-B5ED-331D28751F1C}.Release|x86.Build.0 = Release|Any CPU
|
||||
{A2AEAA66-FA33-437C-BC21-E644A4865543}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{A2AEAA66-FA33-437C-BC21-E644A4865543}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{A2AEAA66-FA33-437C-BC21-E644A4865543}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{A2AEAA66-FA33-437C-BC21-E644A4865543}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{A2AEAA66-FA33-437C-BC21-E644A4865543}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{A2AEAA66-FA33-437C-BC21-E644A4865543}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{A2AEAA66-FA33-437C-BC21-E644A4865543}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{A2AEAA66-FA33-437C-BC21-E644A4865543}.Release|x86.Build.0 = Release|Any CPU
|
||||
{624AA825-698D-490D-8C71-1126035E96F2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{624AA825-698D-490D-8C71-1126035E96F2}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{624AA825-698D-490D-8C71-1126035E96F2}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{624AA825-698D-490D-8C71-1126035E96F2}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{624AA825-698D-490D-8C71-1126035E96F2}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{624AA825-698D-490D-8C71-1126035E96F2}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{624AA825-698D-490D-8C71-1126035E96F2}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{624AA825-698D-490D-8C71-1126035E96F2}.Release|x86.Build.0 = Release|Any CPU
|
||||
{29E0781B-FEED-47A4-B5D0-F3F47C642DE3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{29E0781B-FEED-47A4-B5D0-F3F47C642DE3}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{29E0781B-FEED-47A4-B5D0-F3F47C642DE3}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{29E0781B-FEED-47A4-B5D0-F3F47C642DE3}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{29E0781B-FEED-47A4-B5D0-F3F47C642DE3}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{29E0781B-FEED-47A4-B5D0-F3F47C642DE3}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{29E0781B-FEED-47A4-B5D0-F3F47C642DE3}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{29E0781B-FEED-47A4-B5D0-F3F47C642DE3}.Release|x86.Build.0 = Release|Any CPU
|
||||
{4D9C3EA3-30AD-43C2-835E-166A42872C03}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{4D9C3EA3-30AD-43C2-835E-166A42872C03}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{4D9C3EA3-30AD-43C2-835E-166A42872C03}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{4D9C3EA3-30AD-43C2-835E-166A42872C03}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{4D9C3EA3-30AD-43C2-835E-166A42872C03}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{4D9C3EA3-30AD-43C2-835E-166A42872C03}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{4D9C3EA3-30AD-43C2-835E-166A42872C03}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{4D9C3EA3-30AD-43C2-835E-166A42872C03}.Release|x86.Build.0 = Release|Any CPU
|
||||
{35BD700E-2888-4B11-ABFA-D49371E9ECDE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{35BD700E-2888-4B11-ABFA-D49371E9ECDE}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{35BD700E-2888-4B11-ABFA-D49371E9ECDE}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{35BD700E-2888-4B11-ABFA-D49371E9ECDE}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{35BD700E-2888-4B11-ABFA-D49371E9ECDE}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{35BD700E-2888-4B11-ABFA-D49371E9ECDE}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{35BD700E-2888-4B11-ABFA-D49371E9ECDE}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{35BD700E-2888-4B11-ABFA-D49371E9ECDE}.Release|x86.Build.0 = Release|Any CPU
|
||||
{C1853B29-C445-4098-81A5-3ADB633DF213}.Debug|Any CPU.ActiveCfg = Debug|x86
|
||||
{C1853B29-C445-4098-81A5-3ADB633DF213}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{C1853B29-C445-4098-81A5-3ADB633DF213}.Debug|x86.Build.0 = Debug|x86
|
||||
{C1853B29-C445-4098-81A5-3ADB633DF213}.Release|Any CPU.ActiveCfg = Release|x86
|
||||
{C1853B29-C445-4098-81A5-3ADB633DF213}.Release|x86.ActiveCfg = Release|x86
|
||||
{C1853B29-C445-4098-81A5-3ADB633DF213}.Release|x86.Build.0 = Release|x86
|
||||
{302B8E43-8366-4E01-B35F-CB0C97902806}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{302B8E43-8366-4E01-B35F-CB0C97902806}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{302B8E43-8366-4E01-B35F-CB0C97902806}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{302B8E43-8366-4E01-B35F-CB0C97902806}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{302B8E43-8366-4E01-B35F-CB0C97902806}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{302B8E43-8366-4E01-B35F-CB0C97902806}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{302B8E43-8366-4E01-B35F-CB0C97902806}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{302B8E43-8366-4E01-B35F-CB0C97902806}.Release|x86.Build.0 = Release|Any CPU
|
||||
{DAFF1345-4EB5-449E-94CE-1064C9E98FA9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{DAFF1345-4EB5-449E-94CE-1064C9E98FA9}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{DAFF1345-4EB5-449E-94CE-1064C9E98FA9}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{DAFF1345-4EB5-449E-94CE-1064C9E98FA9}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{DAFF1345-4EB5-449E-94CE-1064C9E98FA9}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{DAFF1345-4EB5-449E-94CE-1064C9E98FA9}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{DAFF1345-4EB5-449E-94CE-1064C9E98FA9}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{DAFF1345-4EB5-449E-94CE-1064C9E98FA9}.Release|x86.Build.0 = Release|Any CPU
|
||||
{1F4EB25F-3A60-45DC-A547-47847B194B32}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{1F4EB25F-3A60-45DC-A547-47847B194B32}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{1F4EB25F-3A60-45DC-A547-47847B194B32}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{1F4EB25F-3A60-45DC-A547-47847B194B32}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{1F4EB25F-3A60-45DC-A547-47847B194B32}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{1F4EB25F-3A60-45DC-A547-47847B194B32}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{1F4EB25F-3A60-45DC-A547-47847B194B32}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{1F4EB25F-3A60-45DC-A547-47847B194B32}.Release|x86.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(NestedProjects) = preSolution
|
||||
{624AA825-698D-490D-8C71-1126035E96F2} = {A3A5753A-2E8F-4970-B7BB-AA59E3C49247}
|
||||
{29E0781B-FEED-47A4-B5D0-F3F47C642DE3} = {76D59EF6-6073-4E0A-B2CC-A69FCF66557A}
|
||||
{4D9C3EA3-30AD-43C2-835E-166A42872C03} = {6EC5CC4A-E47A-4945-B986-645EEE26E6DD}
|
||||
{35BD700E-2888-4B11-ABFA-D49371E9ECDE} = {6EC5CC4A-E47A-4945-B986-645EEE26E6DD}
|
||||
{C1853B29-C445-4098-81A5-3ADB633DF213} = {76D59EF6-6073-4E0A-B2CC-A69FCF66557A}
|
||||
{302B8E43-8366-4E01-B35F-CB0C97902806} = {76D59EF6-6073-4E0A-B2CC-A69FCF66557A}
|
||||
{0E9962A0-1883-4D05-A162-02BE32F9B6C4} = {76D59EF6-6073-4E0A-B2CC-A69FCF66557A}
|
||||
{DAE39861-D2F3-419B-9E8A-E783F0C5E89E} = {0E9962A0-1883-4D05-A162-02BE32F9B6C4}
|
||||
{6EC5CC4A-E47A-4945-B986-645EEE26E6DD} = {DAE39861-D2F3-419B-9E8A-E783F0C5E89E}
|
||||
{AB081229-928D-4718-A905-E35062D720CB} = {0E9962A0-1883-4D05-A162-02BE32F9B6C4}
|
||||
{5A0F307E-BCA1-4BD7-9A5B-CF77607CA079} = {AB081229-928D-4718-A905-E35062D720CB}
|
||||
{DAFF1345-4EB5-449E-94CE-1064C9E98FA9} = {5A0F307E-BCA1-4BD7-9A5B-CF77607CA079}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {FB69BC62-AC69-4BB8-AB33-DF7E370C9F5B}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
Reference in New Issue
Block a user