private static XmlSerializer[] GetSerializersFromCache(XmlMapping[] mappings, Type type) { XmlSerializer[] serializers = new XmlSerializer[mappings.Length]; InternalHashtable typedMappingTable = null; lock (s_xmlSerializerTable) { typedMappingTable = s_xmlSerializerTable[type] as InternalHashtable; if (typedMappingTable == null) { typedMappingTable = new InternalHashtable(); s_xmlSerializerTable[type] = typedMappingTable; } } lock (typedMappingTable) { InternalHashtable pendingKeys = new InternalHashtable(); for (int i = 0; i < mappings.Length; i++) { XmlSerializerMappingKey mappingKey = new XmlSerializerMappingKey(mappings[i]); serializers[i] = typedMappingTable[mappingKey] as XmlSerializer; if (serializers[i] == null) { pendingKeys.Add(mappingKey, i); } } if (pendingKeys.Count > 0) { XmlMapping[] pendingMappings = new XmlMapping[pendingKeys.Count]; int index = 0; foreach (XmlSerializerMappingKey mappingKey in pendingKeys.Keys) { pendingMappings[index++] = mappingKey.Mapping; } TempAssembly tempAssembly = new TempAssembly(pendingMappings, new Type[] { type }, null, null, null); XmlSerializerImplementation contract = tempAssembly.Contract; foreach (XmlSerializerMappingKey mappingKey in pendingKeys.Keys) { index = (int)pendingKeys[mappingKey]; serializers[index] = (XmlSerializer)contract.XmlTypedSerializers[mappingKey.Mapping.Key]; serializers[index].SetTempAssembly(tempAssembly, mappingKey.Mapping); typedMappingTable[mappingKey] = serializers[index]; } } } return(serializers); }
private InternalHashtable ListUsedPrefixes(InternalHashtable nsList, string prefix) { InternalHashtable qnIndexes = new InternalHashtable(); int prefixLength = prefix.Length; const string MaxInt32 = "2147483647"; foreach (string alias in _namespaces.Namespaces.Keys) { string name; if (alias.Length > prefixLength) { name = alias; if (name.Length > prefixLength && name.Length <= prefixLength + MaxInt32.Length && name.StartsWith(prefix, StringComparison.Ordinal)) { bool numeric = true; for (int j = prefixLength; j < name.Length; j++) { if (!Char.IsDigit(name, j)) { numeric = false; break; } } if (numeric) { Int64 index = Int64.Parse(name.Substring(prefixLength), NumberStyles.Integer, CultureInfo.InvariantCulture); if (index <= Int32.MaxValue) { Int32 newIndex = (Int32)index; if (!qnIndexes.ContainsKey(newIndex)) { qnIndexes.Add(newIndex, newIndex); } } } } } } if (qnIndexes.Count > 0) { return(qnIndexes); } return(null); }
/// <include file='doc\XmlSerializationWriter.uex' path='docs/doc[@for="XmlSerializationWriter.WriteStartElement5"]/*' /> protected void WriteStartElement(string name, string ns, object o, bool writePrefixed, XmlSerializerNamespaces xmlns) { if (o != null && _objectsInUse != null) { if (_objectsInUse.ContainsKey(o)) { throw new InvalidOperationException(SR.Format(SR.XmlCircularReference, o.GetType().FullName)); } _objectsInUse.Add(o, o); } string prefix = null; bool needEmptyDefaultNamespace = false; if (_namespaces != null) { foreach (string alias in _namespaces.Namespaces.Keys) { string aliasNs = (string)_namespaces.Namespaces[alias]; if (alias.Length > 0 && aliasNs == ns) { prefix = alias; } if (alias.Length == 0) { if (aliasNs == null || aliasNs.Length == 0) { needEmptyDefaultNamespace = true; } if (ns != aliasNs) { writePrefixed = true; } } } _usedPrefixes = ListUsedPrefixes(_namespaces.Namespaces, _aliasBase); } if (writePrefixed && prefix == null && ns != null && ns.Length > 0) { prefix = _w.LookupPrefix(ns); if (prefix == null || prefix.Length == 0) { prefix = NextPrefix(); } } if (prefix == null && xmlns != null) { prefix = xmlns.LookupPrefix(ns); } if (needEmptyDefaultNamespace && prefix == null && ns != null && ns.Length != 0) { prefix = NextPrefix(); } _w.WriteStartElement(prefix, name, ns); if (_namespaces != null) { foreach (string alias in _namespaces.Namespaces.Keys) { string aliasNs = (string)_namespaces.Namespaces[alias]; if (alias.Length == 0 && (aliasNs == null || aliasNs.Length == 0)) { continue; } if (aliasNs == null || aliasNs.Length == 0) { if (alias.Length > 0) { throw new InvalidOperationException(SR.Format(SR.XmlInvalidXmlns, alias)); } WriteAttribute("xmlns", alias, null, aliasNs); } else { if (_w.LookupPrefix(aliasNs) == null) { // write the default namespace declaration only if we have not written it already, over wise we just ignore one provided by the user if (prefix == null && alias.Length == 0) { break; } WriteAttribute("xmlns", alias, null, aliasNs); } } } } WriteNamespaceDeclarations(xmlns); }
private static XmlSerializer[] GetSerializersFromCache(XmlMapping[] mappings, Type type) { XmlSerializer[] serializers = new XmlSerializer[mappings.Length]; InternalHashtable typedMappingTable = null; lock (s_xmlSerializerTable) { typedMappingTable = s_xmlSerializerTable[type] as InternalHashtable; if (typedMappingTable == null) { typedMappingTable = new InternalHashtable(); s_xmlSerializerTable[type] = typedMappingTable; } } lock (typedMappingTable) { InternalHashtable pendingKeys = new InternalHashtable(); for (int i = 0; i < mappings.Length; i++) { XmlSerializerMappingKey mappingKey = new XmlSerializerMappingKey(mappings[i]); serializers[i] = typedMappingTable[mappingKey] as XmlSerializer; if (serializers[i] == null) { pendingKeys.Add(mappingKey, i); } } if (pendingKeys.Count > 0) { XmlMapping[] pendingMappings = new XmlMapping[pendingKeys.Count]; int index = 0; foreach (XmlSerializerMappingKey mappingKey in pendingKeys.Keys) { pendingMappings[index++] = mappingKey.Mapping; } TempAssembly tempAssembly = new TempAssembly(pendingMappings, new Type[] { type }, null, null, null); XmlSerializerImplementation contract = tempAssembly.Contract; foreach (XmlSerializerMappingKey mappingKey in pendingKeys.Keys) { index = (int)pendingKeys[mappingKey]; serializers[index] = (XmlSerializer)contract.TypedSerializers[mappingKey.Mapping.Key]; serializers[index].SetTempAssembly(tempAssembly, mappingKey.Mapping); typedMappingTable[mappingKey] = serializers[index]; } } } return serializers; }
private void WriteEnumMethod(EnumMapping mapping) { string methodName = (string)MethodNames[mapping]; List<Type> argTypes = new List<Type>(); List<string> argNames = new List<string>(); argTypes.Add(mapping.TypeDesc.Type); argNames.Add("v"); ilg = new CodeGenerator(this.typeBuilder); ilg.BeginMethod( typeof(string), GetMethodBuilder(methodName), argTypes.ToArray(), argNames.ToArray(), CodeGenerator.PrivateMethodAttributes); LocalBuilder sLoc = ilg.DeclareLocal(typeof(string), "s"); ilg.Load(null); ilg.Stloc(sLoc); ConstantMapping[] constants = mapping.Constants; if (constants.Length > 0) { InternalHashtable values = new InternalHashtable(); List<Label> caseLabels = new List<Label>(); List<string> retValues = new List<string>(); Label defaultLabel = ilg.DefineLabel(); Label endSwitchLabel = ilg.DefineLabel(); // This local is necessary; otherwise, it becomes if/else LocalBuilder localTmp = ilg.DeclareLocal(mapping.TypeDesc.Type, "localTmp"); ilg.Ldarg("v"); ilg.Stloc(localTmp); for (int i = 0; i < constants.Length; i++) { ConstantMapping c = constants[i]; if (values[c.Value] == null) { Label caseLabel = ilg.DefineLabel(); ilg.Ldloc(localTmp); ilg.Ldc(Enum.ToObject(mapping.TypeDesc.Type, c.Value)); ilg.Beq(caseLabel); caseLabels.Add(caseLabel); retValues.Add(GetCSharpString(c.XmlName)); values.Add(c.Value, c.Value); } } if (mapping.IsFlags) { ilg.Br(defaultLabel); for (int i = 0; i < caseLabels.Count; i++) { ilg.MarkLabel(caseLabels[i]); ilg.Ldc(retValues[i]); ilg.Stloc(sLoc); ilg.Br(endSwitchLabel); } ilg.MarkLabel(defaultLabel); RaCodeGen.ILGenForEnumLongValue(ilg, "v"); LocalBuilder strArray = ilg.DeclareLocal(typeof(String[]), "strArray"); ilg.NewArray(typeof(String), constants.Length); ilg.Stloc(strArray); for (int i = 0; i < constants.Length; i++) { ConstantMapping c = constants[i]; ilg.Ldloc(strArray); ilg.Ldc(i); ilg.Ldstr(GetCSharpString(c.XmlName)); ilg.Stelem(typeof(String)); } ilg.Ldloc(strArray); LocalBuilder longArray = ilg.DeclareLocal(typeof(long[]), "longArray"); ilg.NewArray(typeof(long), constants.Length); ilg.Stloc(longArray); for (int i = 0; i < constants.Length; i++) { ConstantMapping c = constants[i]; ilg.Ldloc(longArray); ilg.Ldc(i); ilg.Ldc(c.Value); ilg.Stelem(typeof(long)); } ilg.Ldloc(longArray); ilg.Ldstr(GetCSharpString(mapping.TypeDesc.FullName)); MethodInfo XmlSerializationWriter_FromEnum = typeof(XmlSerializationWriter).GetMethod( "FromEnum", CodeGenerator.StaticBindingFlags, new Type[] { typeof(Int64), typeof(String[]), typeof(Int64[]), typeof(String) } ); ilg.Call(XmlSerializationWriter_FromEnum); ilg.Stloc(sLoc); ilg.Br(endSwitchLabel); } else { ilg.Br(defaultLabel); // Case bodies for (int i = 0; i < caseLabels.Count; i++) { ilg.MarkLabel(caseLabels[i]); ilg.Ldc(retValues[i]); ilg.Stloc(sLoc); ilg.Br(endSwitchLabel); } MethodInfo CultureInfo_get_InvariantCulture = typeof(CultureInfo).GetMethod( "get_InvariantCulture", CodeGenerator.StaticBindingFlags, Array.Empty<Type>() ); MethodInfo Int64_ToString = typeof(Int64).GetMethod( "ToString", CodeGenerator.InstanceBindingFlags, new Type[] { typeof(IFormatProvider) } ); MethodInfo XmlSerializationWriter_CreateInvalidEnumValueException = typeof(XmlSerializationWriter).GetMethod( "CreateInvalidEnumValueException", CodeGenerator.InstanceBindingFlags, new Type[] { typeof(object), typeof(string) } ); // Default body ilg.MarkLabel(defaultLabel); ilg.Ldarg(0); ilg.Ldarg("v"); ilg.ConvertValue(mapping.TypeDesc.Type, typeof(Int64)); LocalBuilder numLoc = ilg.DeclareLocal(typeof(Int64), "num"); ilg.Stloc(numLoc); // Invoke method on Value type need address ilg.LdlocAddress(numLoc); ilg.Call(CultureInfo_get_InvariantCulture); ilg.Call(Int64_ToString); ilg.Ldstr(GetCSharpString(mapping.TypeDesc.FullName)); ilg.Call(XmlSerializationWriter_CreateInvalidEnumValueException); ilg.Throw(); } ilg.MarkLabel(endSwitchLabel); } ilg.Ldloc(sLoc); ilg.EndMethod(); }
private InternalHashtable ListUsedPrefixes(InternalHashtable nsList, string prefix) { InternalHashtable qnIndexes = new InternalHashtable(); int prefixLength = prefix.Length; const string MaxInt32 = "2147483647"; foreach (string alias in _namespaces.Namespaces.Keys) { string name; if (alias.Length > prefixLength) { name = alias; if (name.Length > prefixLength && name.Length <= prefixLength + MaxInt32.Length && name.StartsWith(prefix, StringComparison.Ordinal)) { bool numeric = true; for (int j = prefixLength; j < name.Length; j++) { if (!Char.IsDigit(name, j)) { numeric = false; break; } } if (numeric) { Int64 index = Int64.Parse(name.Substring(prefixLength), NumberStyles.Integer, CultureInfo.InvariantCulture); if (index <= Int32.MaxValue) { Int32 newIndex = (Int32)index; if (!qnIndexes.ContainsKey(newIndex)) { qnIndexes.Add(newIndex, newIndex); } } } } } } if (qnIndexes.Count > 0) { return qnIndexes; } return null; }