1008 lines
27 KiB
C#
Raw Normal View History

//
// System.Xml.Serialization.XmlSerializationWriter.cs
//
// Author:
// Tim Coleman (tim@timcoleman.com)
// Lluis Sanchez Gual (lluis@ximian.com)
//
// Copyright (C) Tim Coleman, 2002
//
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
using System;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.Text;
using System.Xml;
using System.Xml.Schema;
using System.Runtime.Serialization;
using System.Reflection;
namespace System.Xml.Serialization
{
public abstract class XmlSerializationWriter
#if NET_2_0
: XmlSerializationGeneratedCode
#endif
{
#region Fields
ObjectIDGenerator idGenerator;
int qnameCount;
bool topLevelElement = false;
ArrayList namespaces;
XmlWriter writer;
Queue referencedElements;
Hashtable callbacks;
Hashtable serializedObjects;
const string xmlNamespace = "http://www.w3.org/2000/xmlns/";
const string unexpectedTypeError = "The type {0} was not expected. Use the" +
" XmlInclude or SoapInclude attribute to specify types that are not known statically.";
#endregion // Fields
#region Constructors
protected XmlSerializationWriter ()
{
qnameCount = 0;
serializedObjects = new Hashtable ();
}
internal void Initialize (XmlWriter writer, XmlSerializerNamespaces nss)
{
this.writer = writer;
if (nss != null)
{
namespaces = new ArrayList ();
foreach (XmlQualifiedName ns in nss.ToArray())
if (ns.Name != "" && ns.Namespace != "")
namespaces.Add (ns);
}
}
#endregion // Constructors
#region Properties
protected ArrayList Namespaces {
get { return namespaces; }
set { namespaces = value; }
}
protected XmlWriter Writer {
get { return writer; }
set { writer = value; }
}
#endregion // Properties
#region Methods
protected void AddWriteCallback (Type type, string typeName, string typeNs, XmlSerializationWriteCallback callback)
{
WriteCallbackInfo info = new WriteCallbackInfo ();
info.Type = type;
info.TypeName = typeName;
info.TypeNs = typeNs;
info.Callback = callback;
if (callbacks == null) callbacks = new Hashtable ();
callbacks.Add (type, info);
}
protected Exception CreateChoiceIdentifierValueException (string value, string identifier, string name, string ns)
{
string message = string.Format ("Value '{0}' of the choice"
+ " identifier '{1}' does not match element '{2}'"
+ " from namespace '{3}'.", value, identifier,
name, ns);
return new InvalidOperationException (message);
}
protected Exception CreateInvalidChoiceIdentifierValueException (string type, string identifier)
{
string message = string.Format ("Invalid or missing choice"
+ " identifier '{0}' of type '{1}'.", identifier,
type);
return new InvalidOperationException (message);
}
protected Exception CreateMismatchChoiceException (string value, string elementName, string enumValue)
{
string message = String.Format ("Value of {0} mismatches the type of {1}, you need to set it to {2}.", elementName, value, enumValue);
return new InvalidOperationException (message);
}
protected Exception CreateUnknownAnyElementException (string name, string ns)
{
string message = String.Format ("The XML element named '{0}' from namespace '{1}' was not expected. The XML element name and namespace must match those provided via XmlAnyElementAttribute(s).", name, ns);
return new InvalidOperationException (message);
}
protected Exception CreateUnknownTypeException (object o)
{
return CreateUnknownTypeException (o.GetType ());
}
protected Exception CreateUnknownTypeException (Type type)
{
string message = String.Format ("The type {0} may not be used in this context.", type);
return new InvalidOperationException (message);
}
protected static byte[] FromByteArrayBase64 (byte[] value)
{
return value;
}
protected static string FromByteArrayHex (byte[] value)
{
return XmlCustomFormatter.FromByteArrayHex (value);
}
protected static string FromChar (char value)
{
return XmlCustomFormatter.FromChar (value);
}
protected static string FromDate (DateTime value)
{
return XmlCustomFormatter.FromDate (value);
}
protected static string FromDateTime (DateTime value)
{
return XmlCustomFormatter.FromDateTime (value);
}
protected static string FromEnum (long value, string[] values, long[] ids)
{
return XmlCustomFormatter.FromEnum (value, values, ids);
}
protected static string FromTime (DateTime value)
{
return XmlCustomFormatter.FromTime (value);
}
protected static string FromXmlName (string name)
{
return XmlCustomFormatter.FromXmlName (name);
}
protected static string FromXmlNCName (string ncName)
{
return XmlCustomFormatter.FromXmlNCName (ncName);
}
protected static string FromXmlNmToken (string nmToken)
{
return XmlCustomFormatter.FromXmlNmToken (nmToken);
}
protected static string FromXmlNmTokens (string nmTokens)
{
return XmlCustomFormatter.FromXmlNmTokens (nmTokens);
}
protected string FromXmlQualifiedName (XmlQualifiedName xmlQualifiedName)
{
if (xmlQualifiedName == null || xmlQualifiedName == XmlQualifiedName.Empty)
return null;
return GetQualifiedName (xmlQualifiedName.Name, xmlQualifiedName.Namespace);
}
private string GetId (object o, bool addToReferencesList)
{
if (idGenerator == null) idGenerator = new ObjectIDGenerator ();
bool firstTime;
long lid = idGenerator.GetId (o, out firstTime);
return String.Format (CultureInfo.InvariantCulture, "id{0}", lid);
}
bool AlreadyQueued (object ob)
{
if (idGenerator == null) return false;
bool firstTime;
idGenerator.HasId (ob, out firstTime);
return !firstTime;
}
private string GetNamespacePrefix (string ns)
{
string prefix = Writer.LookupPrefix (ns);
if (prefix == null)
{
prefix = String.Format (CultureInfo.InvariantCulture, "q{0}", ++qnameCount);
WriteAttribute ("xmlns", prefix, null, ns);
}
return prefix;
}
private string GetQualifiedName (string name, string ns)
{
if (ns == String.Empty) return name;
string prefix = GetNamespacePrefix (ns);
if (prefix == String.Empty)
return name;
else
return String.Format ("{0}:{1}", prefix, name);
}
protected abstract void InitCallbacks ();
protected void TopLevelElement ()
{
topLevelElement = true;
}
protected void WriteAttribute (string localName, byte[] value)
{
WriteAttribute (localName, String.Empty, value);
}
protected void WriteAttribute (string localName, string value)
{
WriteAttribute (String.Empty, localName, String.Empty, value);
}
protected void WriteAttribute (string localName, string ns, byte[] value)
{
if (value == null)
return;
Writer.WriteStartAttribute (localName, ns);
WriteValue (value);
Writer.WriteEndAttribute ();
}
protected void WriteAttribute (string localName, string ns, string value)
{
WriteAttribute (null, localName, ns, value);
}
protected void WriteAttribute (string prefix, string localName, string ns, string value)
{
if (value == null)
return;
Writer.WriteAttributeString (prefix, localName, ns, value);
}
void WriteXmlNode (XmlNode node)
{
if (node is XmlDocument)
node = ((XmlDocument) node).DocumentElement;
node.WriteTo (Writer);
}
protected void WriteElementEncoded (XmlNode node, string name, string ns, bool isNullable, bool any)
{
if (name != string.Empty)
{
if (node == null)
{
if (isNullable)
WriteNullTagEncoded (name, ns);
}
else if (any)
WriteXmlNode (node);
else
{
Writer.WriteStartElement (name, ns);
WriteXmlNode (node);
Writer.WriteEndElement ();
}
}
else
WriteXmlNode(node);
}
protected void WriteElementLiteral (XmlNode node, string name, string ns, bool isNullable, bool any)
{
if (name != string.Empty)
{
if (node == null)
{
if (isNullable)
WriteNullTagLiteral (name, ns);
}
else if (any)
WriteXmlNode (node);
else
{
Writer.WriteStartElement (name, ns);
WriteXmlNode (node);
Writer.WriteEndElement ();
}
}
else
WriteXmlNode (node);
}
protected void WriteElementQualifiedName (string localName, XmlQualifiedName value)
{
WriteElementQualifiedName (localName, String.Empty, value, null);
}
protected void WriteElementQualifiedName (string localName, string ns, XmlQualifiedName value)
{
WriteElementQualifiedName (localName, ns, value, null);
}
protected void WriteElementQualifiedName (string localName, XmlQualifiedName value, XmlQualifiedName xsiType)
{
WriteElementQualifiedName (localName, String.Empty, value, xsiType);
}
protected void WriteElementQualifiedName (string localName, string ns, XmlQualifiedName value, XmlQualifiedName xsiType)
{
localName = XmlCustomFormatter.FromXmlNCName (localName);
WriteStartElement (localName, ns);
if (xsiType != null) WriteXsiType (xsiType.Name, xsiType.Namespace);
Writer.WriteString (FromXmlQualifiedName (value));
WriteEndElement ();
}
protected void WriteElementString (string localName, string value)
{
WriteElementString (localName, String.Empty, value, null);
}
protected void WriteElementString (string localName, string ns, string value)
{
WriteElementString (localName, ns, value, null);
}
protected void WriteElementString (string localName, string value, XmlQualifiedName xsiType)
{
WriteElementString (localName, String.Empty, value, xsiType);
}
protected void WriteElementString (string localName, string ns, string value, XmlQualifiedName xsiType)
{
if (value == null) return;
if (xsiType != null) {
localName = XmlCustomFormatter.FromXmlNCName (localName);
WriteStartElement (localName, ns);
WriteXsiType (xsiType.Name, xsiType.Namespace);
Writer.WriteString (value);
WriteEndElement ();
}
else
Writer.WriteElementString (localName, ns, value);
}
protected void WriteElementStringRaw (string localName, byte[] value)
{
WriteElementStringRaw (localName, String.Empty, value, null);
}
protected void WriteElementStringRaw (string localName, string value)
{
WriteElementStringRaw (localName, String.Empty, value, null);
}
protected void WriteElementStringRaw (string localName, byte[] value, XmlQualifiedName xsiType)
{
WriteElementStringRaw (localName, String.Empty, value, xsiType);
}
protected void WriteElementStringRaw (string localName, string ns, byte[] value)
{
WriteElementStringRaw (localName, ns, value, null);
}
protected void WriteElementStringRaw (string localName, string ns, string value)
{
WriteElementStringRaw (localName, ns, value, null);
}
protected void WriteElementStringRaw (string localName, string value, XmlQualifiedName xsiType)
{
WriteElementStringRaw (localName, String.Empty, value, null);
}
protected void WriteElementStringRaw (string localName, string ns, byte[] value, XmlQualifiedName xsiType)
{
if (value == null)
return;
WriteStartElement (localName, ns);
if (xsiType != null)
WriteXsiType (xsiType.Name, xsiType.Namespace);
if (value.Length > 0)
Writer.WriteBase64(value,0,value.Length);
WriteEndElement ();
}
protected void WriteElementStringRaw (string localName, string ns, string value, XmlQualifiedName xsiType)
{
localName = XmlCustomFormatter.FromXmlNCName (localName);
WriteStartElement (localName, ns);
if (xsiType != null)
WriteXsiType (xsiType.Name, xsiType.Namespace);
Writer.WriteRaw (value);
WriteEndElement ();
}
protected void WriteEmptyTag (string name)
{
WriteEmptyTag (name, String.Empty);
}
protected void WriteEmptyTag (string name, string ns)
{
name = XmlCustomFormatter.FromXmlName (name);
WriteStartElement (name, ns);
WriteEndElement ();
}
protected void WriteEndElement ()
{
WriteEndElement (null);
}
protected void WriteEndElement (object o)
{
if (o != null)
serializedObjects.Remove (o);
Writer.WriteEndElement ();
}
protected void WriteId (object o)
{
WriteAttribute ("id", GetId (o, true));
}
protected void WriteNamespaceDeclarations (XmlSerializerNamespaces xmlns)
{
if (xmlns == null)
return;
ICollection namespaces = xmlns.Namespaces.Values;
foreach (XmlQualifiedName qn in namespaces) {
if (qn.Namespace != String.Empty && Writer.LookupPrefix (qn.Namespace) != qn.Name)
WriteAttribute ("xmlns", qn.Name, xmlNamespace, qn.Namespace);
}
}
protected void WriteNullableQualifiedNameEncoded (string name, string ns, XmlQualifiedName value, XmlQualifiedName xsiType)
{
if (value != null)
WriteElementQualifiedName (name, ns, value, xsiType);
else
WriteNullTagEncoded (name, ns);
}
protected void WriteNullableQualifiedNameLiteral (string name, string ns, XmlQualifiedName value)
{
if (value != null)
WriteElementQualifiedName (name, ns, value);
else
WriteNullTagLiteral (name, ns);
}
protected void WriteNullableStringEncoded (string name, string ns, string value, XmlQualifiedName xsiType)
{
if (value != null)
WriteElementString (name, ns, value, xsiType);
else
WriteNullTagEncoded (name, ns);
}
protected void WriteNullableStringEncodedRaw (string name, string ns, byte[] value, XmlQualifiedName xsiType)
{
if (value == null)
WriteNullTagEncoded (name, ns);
else
WriteElementStringRaw (name, ns, value, xsiType);
}
protected void WriteNullableStringEncodedRaw (string name, string ns, string value, XmlQualifiedName xsiType)
{
if (value == null)
WriteNullTagEncoded (name, ns);
else
WriteElementStringRaw (name, ns, value, xsiType);
}
protected void WriteNullableStringLiteral (string name, string ns, string value)
{
if (value != null)
WriteElementString (name, ns, value, null);
else
WriteNullTagLiteral (name, ns);
}
protected void WriteNullableStringLiteralRaw (string name, string ns, byte[] value)
{
if (value == null)
WriteNullTagLiteral (name, ns);
else
WriteElementStringRaw (name, ns, value);
}
protected void WriteNullableStringLiteralRaw (string name, string ns, string value)
{
if (value == null)
WriteNullTagLiteral (name, ns);
else
WriteElementStringRaw (name, ns, value);
}
protected void WriteNullTagEncoded (string name)
{
WriteNullTagEncoded (name, String.Empty);
}
protected void WriteNullTagEncoded (string name, string ns)
{
Writer.WriteStartElement (name, ns);
Writer.WriteAttributeString ("nil", XmlSchema.InstanceNamespace, "true");
Writer.WriteEndElement ();
}
protected void WriteNullTagLiteral (string name)
{
WriteNullTagLiteral (name, String.Empty);
}
protected void WriteNullTagLiteral (string name, string ns)
{
WriteStartElement (name, ns);
Writer.WriteAttributeString ("nil", XmlSchema.InstanceNamespace, "true");
WriteEndElement ();
}
protected void WritePotentiallyReferencingElement (string n, string ns, object o)
{
WritePotentiallyReferencingElement (n, ns, o, null, false, false);
}
protected void WritePotentiallyReferencingElement (string n, string ns, object o, Type ambientType)
{
WritePotentiallyReferencingElement (n, ns, o, ambientType, false, false);
}
protected void WritePotentiallyReferencingElement (string n, string ns, object o, Type ambientType, bool suppressReference)
{
WritePotentiallyReferencingElement (n, ns, o, ambientType, suppressReference, false);
}
protected void WritePotentiallyReferencingElement (string n, string ns, object o, Type ambientType, bool suppressReference, bool isNullable)
{
if (o == null)
{
if (isNullable) WriteNullTagEncoded (n, ns);
return;
}
var t = o.GetType ();
WriteStartElement (n, ns, true);
CheckReferenceQueue ();
if (callbacks != null && callbacks.ContainsKey (o.GetType ()))
{
WriteCallbackInfo info = (WriteCallbackInfo) callbacks[t];
if (t.IsEnum) {
info.Callback (o);
}
else if (suppressReference) {
Writer.WriteAttributeString ("id", GetId (o, false));
if (ambientType != t) WriteXsiType(info.TypeName, info.TypeNs);
info.Callback (o);
}
else {
if (!AlreadyQueued (o)) referencedElements.Enqueue (o);
Writer.WriteAttributeString ("href", "#" + GetId (o, true));
}
}
else
{
// Must be a primitive type or array of primitives
TypeData td = TypeTranslator.GetTypeData (t, null, true);
if (td.SchemaType == SchemaTypes.Primitive) {
if (t != ambientType)
WriteXsiType (td.XmlType, XmlSchema.Namespace);
Writer.WriteString (XmlCustomFormatter.ToXmlString (td, o));
} else if (IsPrimitiveArray (td)) {
if (!AlreadyQueued (o)) referencedElements.Enqueue (o);
Writer.WriteAttributeString ("href", "#" + GetId (o, true));
} else {
throw new InvalidOperationException ("Invalid type: " + t.FullName);
}
}
WriteEndElement ();
}
protected void WriteReferencedElements ()
{
if (referencedElements == null) return;
if (callbacks == null) return;
while (referencedElements.Count > 0)
{
object o = referencedElements.Dequeue ();
TypeData td = TypeTranslator.GetTypeData (o.GetType ());
WriteCallbackInfo info = (WriteCallbackInfo) callbacks[o.GetType()];
if (info != null) {
WriteStartElement (info.TypeName, info.TypeNs, true);
Writer.WriteAttributeString ("id", GetId (o, false));
if (td.SchemaType != SchemaTypes.Array) // Array use its own "arrayType" attribute
WriteXsiType(info.TypeName, info.TypeNs);
info.Callback (o);
WriteEndElement ();
} else if (IsPrimitiveArray (td)) {
WriteArray (o, td);
}
}
}
bool IsPrimitiveArray (TypeData td)
{
if (td.SchemaType == SchemaTypes.Array) {
if (td.ListItemTypeData.SchemaType == SchemaTypes.Primitive || td.ListItemType == typeof(object))
return true;
return IsPrimitiveArray (td.ListItemTypeData);
} else
return false;
}
void WriteArray (object o, TypeData td)
{
TypeData itemTypeData = td;
string xmlType;
int nDims = -1;
do {
itemTypeData = itemTypeData.ListItemTypeData;
xmlType = itemTypeData.XmlType;
nDims++;
}
while (itemTypeData.SchemaType == SchemaTypes.Array );
while (nDims-- > 0)
xmlType += "[]";
WriteStartElement("Array", XmlSerializer.EncodingNamespace, true);
Writer.WriteAttributeString("id", GetId(o, false));
if (td.SchemaType == SchemaTypes.Array) {
Array a = (Array)o;
int len = a.Length;
Writer.WriteAttributeString("arrayType", XmlSerializer.EncodingNamespace, GetQualifiedName(xmlType, XmlSchema.Namespace) + "[" + len.ToString() + "]");
for (int i = 0; i < len; i++) {
WritePotentiallyReferencingElement("Item", "", a.GetValue(i), td.ListItemType, false, true);
}
}
WriteEndElement();
}
protected void WriteReferencingElement (string n, string ns, object o)
{
WriteReferencingElement (n, ns, o, false);
}
protected void WriteReferencingElement (string n, string ns, object o, bool isNullable)
{
if (o == null)
{
if (isNullable) WriteNullTagEncoded (n, ns);
return;
}
else
{
CheckReferenceQueue ();
if (!AlreadyQueued (o)) referencedElements.Enqueue (o);
Writer.WriteStartElement (n, ns);
Writer.WriteAttributeString ("href", "#" + GetId (o, true));
Writer.WriteEndElement ();
}
}
void CheckReferenceQueue ()
{
if (referencedElements == null)
{
referencedElements = new Queue ();
InitCallbacks ();
}
}
[MonoTODO]
protected void WriteRpcResult (string name, string ns)
{
throw new NotImplementedException ();
}
protected void WriteSerializable (IXmlSerializable serializable, string name, string ns, bool isNullable)
{
WriteSerializable (serializable, name, ns, isNullable, true);
}
#if NET_2_0
protected
#endif
void WriteSerializable (IXmlSerializable serializable, string name, string ns, bool isNullable, bool wrapped)
{
if (serializable == null)
{
if (isNullable && wrapped) WriteNullTagLiteral (name, ns);
return;
}
else
{
if (wrapped)
Writer.WriteStartElement (name, ns);
serializable.WriteXml (Writer);
if (wrapped)
Writer.WriteEndElement ();
}
}
protected void WriteStartDocument ()
{
if (Writer.WriteState == WriteState.Start)
Writer.WriteStartDocument ();
}
protected void WriteStartElement (string name)
{
WriteStartElement (name, String.Empty, null, false);
}
protected void WriteStartElement (string name, string ns)
{
WriteStartElement (name, ns, null, false);
}
protected void WriteStartElement (string name, string ns, bool writePrefixed)
{
WriteStartElement (name, ns, null, writePrefixed);
}
protected void WriteStartElement (string name, string ns, object o)
{
WriteStartElement (name, ns, o, false);
}
protected void WriteStartElement (string name, string ns, object o, bool writePrefixed)
{
WriteStartElement (name, ns, o, writePrefixed, namespaces);
}
#if NET_2_0
protected void WriteStartElement (string name, string ns, Object o, bool writePrefixed, XmlSerializerNamespaces xmlns)
{
WriteStartElement (name, ns, o, writePrefixed, xmlns != null ? xmlns.ToArray () : null);
}
#endif
void WriteStartElement (string name, string ns, object o, bool writePrefixed, ICollection namespaces)
{
if (o != null)
{
if (serializedObjects.Contains (o))
throw new InvalidOperationException ("A circular reference was detected while serializing an object of type " + o.GetType().Name);
else
serializedObjects [o] = o;
}
string prefix = null;
if (topLevelElement && ns != null && ns.Length != 0)
{
if (namespaces != null)
foreach (XmlQualifiedName qn in namespaces)
if (qn.Namespace == ns) {
prefix = qn.Name;
writePrefixed = true;
break;
}
}
if (writePrefixed && ns != string.Empty)
{
name = XmlCustomFormatter.FromXmlName (name);
if (prefix == null)
prefix = Writer.LookupPrefix (ns);
if (prefix == null || prefix.Length == 0)
prefix = "q" + (++qnameCount);
Writer.WriteStartElement (prefix, name, ns);
} else
Writer.WriteStartElement (name, ns);
if (topLevelElement)
{
if (namespaces != null) {
foreach (XmlQualifiedName qn in namespaces)
{
string currentPrefix = Writer.LookupPrefix (qn.Namespace);
if (currentPrefix != null && currentPrefix.Length != 0) continue;
WriteAttribute ("xmlns",qn.Name,xmlNamespace,qn.Namespace);
}
}
topLevelElement = false;
}
}
protected void WriteTypedPrimitive (string name, string ns, object o, bool xsiType)
{
string value;
TypeData td = TypeTranslator.GetTypeData (o.GetType (), null, true);
if (td.SchemaType != SchemaTypes.Primitive)
throw new InvalidOperationException (String.Format ("The type of the argument object '{0}' is not primitive.", td.FullTypeName));
if (name == null) {
ns = td.IsXsdType ? XmlSchema.Namespace : XmlSerializer.WsdlTypesNamespace;
name = td.XmlType;
}
else
name = XmlCustomFormatter.FromXmlName (name);
Writer.WriteStartElement (name, ns);
if (o is XmlQualifiedName)
value = FromXmlQualifiedName ((XmlQualifiedName) o);
else
value = XmlCustomFormatter.ToXmlString (td, o);
if (xsiType)
{
if (td.SchemaType != SchemaTypes.Primitive)
throw new InvalidOperationException (string.Format (unexpectedTypeError, o.GetType().FullName));
WriteXsiType (td.XmlType, td.IsXsdType ? XmlSchema.Namespace : XmlSerializer.WsdlTypesNamespace);
}
WriteValue (value);
Writer.WriteEndElement ();
}
protected void WriteValue (byte[] value)
{
Writer.WriteBase64 (value, 0, value.Length);
}
protected void WriteValue (string value)
{
if (value != null)
Writer.WriteString (value);
}
protected void WriteXmlAttribute (XmlNode node)
{
WriteXmlAttribute (node, null);
}
protected void WriteXmlAttribute (XmlNode node, object container)
{
XmlAttribute attr = node as XmlAttribute;
if (attr == null)
throw new InvalidOperationException ("The node must be either type XmlAttribute or a derived type.");
if (attr.NamespaceURI == XmlSerializer.WsdlNamespace)
{
// The wsdl arrayType attribute needs special handling
if (attr.LocalName == "arrayType") {
string ns, type, dimensions;
TypeTranslator.ParseArrayType (attr.Value, out type, out ns, out dimensions);
string value = GetQualifiedName (type + dimensions, ns);
WriteAttribute (attr.Prefix, attr.LocalName, attr.NamespaceURI, value);
return;
}
}
WriteAttribute (attr.Prefix, attr.LocalName, attr.NamespaceURI, attr.Value);
}
protected void WriteXsiType (string name, string ns)
{
if (ns != null && ns != string.Empty)
WriteAttribute ("type", XmlSchema.InstanceNamespace, GetQualifiedName (name, ns));
else
WriteAttribute ("type", XmlSchema.InstanceNamespace, name);
}
#if NET_2_0
protected Exception CreateInvalidAnyTypeException (object o)
{
if (o == null)
return new InvalidOperationException ("null is invalid as anyType in XmlSerializer");
else
return CreateInvalidAnyTypeException (o.GetType ());
}
protected Exception CreateInvalidAnyTypeException (Type type)
{
return new InvalidOperationException (String.Format ("An object of type '{0}' is invalid as anyType in XmlSerializer", type));
}
protected Exception CreateInvalidEnumValueException (object value, string typeName)
{
return new InvalidOperationException (string.Format(CultureInfo.CurrentCulture,
"'{0}' is not a valid value for {1}.", value, typeName));
}
protected static string FromEnum (long value, string[] values, long[] ids, string typeName)
{
return XmlCustomFormatter.FromEnum (value, values, ids, typeName);
}
[MonoTODO]
protected string FromXmlQualifiedName (XmlQualifiedName xmlQualifiedName, bool ignoreEmpty)
{
throw new NotImplementedException ();
}
[MonoTODO]
protected static Assembly ResolveDynamicAssembly (string assemblyFullName)
{
throw new NotImplementedException ();
}
[MonoTODO]
protected bool EscapeName
{
get { throw new NotImplementedException(); }
set { throw new NotImplementedException(); }
}
#endif
#endregion
class WriteCallbackInfo
{
public Type Type;
public string TypeName;
public string TypeNs;
public XmlSerializationWriteCallback Callback;
}
}
}