Code:
/ WCF / WCF / 3.5.30729.1 / untmp / Orcas / SP / ndp / cdf / src / NetFx35 / System.ServiceModel.Web / System / Runtime / Serialization / Json / XmlJsonWriter.cs / 1 / XmlJsonWriter.cs
//------------------------------------------------------------ // Copyright (c) Microsoft Corporation. All rights reserved. //----------------------------------------------------------- namespace System.Runtime.Serialization.Json { using System.IO; using System.Text; using System.ServiceModel; using System.Globalization; using System.Runtime.Serialization; using System.Diagnostics.CodeAnalysis; using System.Xml; using System.Security; using System.ServiceModel.Web; class XmlJsonWriter : XmlDictionaryWriter, IXmlJsonWriterInitializer { const char BACK_SLASH = '\\'; const char FORWARD_SLASH = '/'; const char HIGH_SURROGATE_START = (char) 0xd800; const char LOW_SURROGATE_END = (char) 0xdfff; const char MAX_CHAR = (char) 0xfffe; const char WHITESPACE = ' '; const string xmlNamespace = "http://www.w3.org/XML/1998/namespace"; const string xmlnsNamespace = "http://www.w3.org/2000/xmlns/"; //// Critical - Static fields are marked SecurityCritical or readonly to prevent // data from being modified or leaked to other components in appdomain. // [SecurityCritical] static BinHexEncoding binHexEncoding; string attributeText; JsonDataType dataType; int depth; bool endElementBuffer; bool isWritingDataTypeAttribute; bool isWritingServerTypeAttribute; bool isWritingXmlnsAttribute; NameState nameState; JsonNodeType nodeType; JsonNodeWriter nodeWriter; JsonNodeType[] scopes; string serverTypeValue; // Do not use this field's value anywhere other than the WriteState property. // It's OK to set this field's value anywhere and then change the WriteState property appropriately. // If it's necessary to check the WriteState outside WriteState, use the WriteState property. WriteState writeState; bool wroteServerTypeAttribute; public XmlJsonWriter() { InitializeWriter(); } enum JsonDataType { None, Null, Boolean, Number, String, Object, Array }; [Flags] enum NameState { None = 0, IsWritingNameWithMapping = 1, IsWritingNameAttribute = 2, WrittenNameWithMapping = 4, } public override XmlWriterSettings Settings { // The XmlWriterSettings object used to create this writer instance. // If this writer was not created using the Create method, this property // returns a null reference. get { return null; } } public override WriteState WriteState { get { if (writeState == WriteState.Closed) { return WriteState.Closed; } if (HasOpenAttribute) { return WriteState.Attribute; } switch (nodeType) { case JsonNodeType.None: return WriteState.Start; case JsonNodeType.Element: return WriteState.Element; case JsonNodeType.QuotedText: case JsonNodeType.StandaloneText: case JsonNodeType.EndElement: return WriteState.Content; default: return WriteState.Error; } } } public override string XmlLang { get { return null; } } public override XmlSpace XmlSpace { get { return XmlSpace.None; } } static BinHexEncoding BinHexEncoding { //// Critical - fetches the critical binHexEncoding field // Safe - get-only properties only needs to be protected for write; initialized in getter if null. // [SecurityCritical, SecurityTreatAsSafe] get { if (binHexEncoding == null) { binHexEncoding = new BinHexEncoding(); } return binHexEncoding; } } bool HasOpenAttribute { get { return (isWritingDataTypeAttribute || isWritingServerTypeAttribute || IsWritingNameAttribute || isWritingXmlnsAttribute); } } bool IsClosed { get { return (WriteState == WriteState.Closed); } } bool IsWritingCollection { get { return (depth > 0) && (scopes[depth] == JsonNodeType.Collection); } } bool IsWritingNameAttribute { get { return (nameState & NameState.IsWritingNameAttribute) == NameState.IsWritingNameAttribute; } } bool IsWritingNameWithMapping { get { return (nameState & NameState.IsWritingNameWithMapping) == NameState.IsWritingNameWithMapping; } } bool WrittenNameWithMapping { get { return (nameState & NameState.WrittenNameWithMapping) == NameState.WrittenNameWithMapping; } } public override void Close() { if (!IsClosed) { try { WriteEndDocument(); } finally { try { nodeWriter.Flush(); nodeWriter.Close(); } finally { writeState = WriteState.Closed; if (depth != 0) { depth = 0; } } } } } public override void Flush() { if (IsClosed) { ThrowClosed(); } nodeWriter.Flush(); } public override string LookupPrefix(string ns) { if (ns == null) { throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("ns"); } if (ns == Globals.XmlnsNamespace) { return Globals.XmlnsPrefix; } if (ns == xmlNamespace) { return JsonGlobals.xmlPrefix; } if (ns == string.Empty) { return string.Empty; } return null; } public void SetOutput(Stream stream, Encoding encoding, bool ownsStream) { if (stream == null) { throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("stream"); } if (encoding == null) { throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("encoding"); } if (encoding.WebName != Encoding.UTF8.WebName) { stream = new JsonEncodingStreamWrapper(stream, encoding, false); } else { encoding = null; } if (nodeWriter == null) { nodeWriter = new JsonNodeWriter(); } nodeWriter.SetOutput(stream, ownsStream, encoding); InitializeWriter(); } public override void WriteArray(string prefix, string localName, string namespaceUri, bool[] array, int offset, int count) { throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException(SR2.JsonWriteArrayNotSupported)); } public override void WriteArray(string prefix, string localName, string namespaceUri, Int16[] array, int offset, int count) { throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException(SR2.JsonWriteArrayNotSupported)); } public override void WriteArray(string prefix, string localName, string namespaceUri, Int32[] array, int offset, int count) { throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException(SR2.JsonWriteArrayNotSupported)); } public override void WriteArray(string prefix, string localName, string namespaceUri, Int64[] array, int offset, int count) { throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException(SR2.JsonWriteArrayNotSupported)); } public override void WriteArray(string prefix, string localName, string namespaceUri, float[] array, int offset, int count) { throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException(SR2.JsonWriteArrayNotSupported)); } public override void WriteArray(string prefix, string localName, string namespaceUri, double[] array, int offset, int count) { throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException(SR2.JsonWriteArrayNotSupported)); } public override void WriteArray(string prefix, string localName, string namespaceUri, decimal[] array, int offset, int count) { throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException(SR2.JsonWriteArrayNotSupported)); } public override void WriteArray(string prefix, string localName, string namespaceUri, DateTime[] array, int offset, int count) { throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException(SR2.JsonWriteArrayNotSupported)); } public override void WriteArray(string prefix, string localName, string namespaceUri, Guid[] array, int offset, int count) { throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException(SR2.JsonWriteArrayNotSupported)); } public override void WriteArray(string prefix, string localName, string namespaceUri, TimeSpan[] array, int offset, int count) { throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException(SR2.JsonWriteArrayNotSupported)); } public override void WriteArray(string prefix, XmlDictionaryString localName, XmlDictionaryString namespaceUri, bool[] array, int offset, int count) { throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException(SR2.JsonWriteArrayNotSupported)); } public override void WriteArray(string prefix, XmlDictionaryString localName, XmlDictionaryString namespaceUri, decimal[] array, int offset, int count) { throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException(SR2.JsonWriteArrayNotSupported)); } public override void WriteArray(string prefix, XmlDictionaryString localName, XmlDictionaryString namespaceUri, double[] array, int offset, int count) { throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException(SR2.JsonWriteArrayNotSupported)); } public override void WriteArray(string prefix, XmlDictionaryString localName, XmlDictionaryString namespaceUri, float[] array, int offset, int count) { throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException(SR2.JsonWriteArrayNotSupported)); } public override void WriteArray(string prefix, XmlDictionaryString localName, XmlDictionaryString namespaceUri, int[] array, int offset, int count) { throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException(SR2.JsonWriteArrayNotSupported)); } public override void WriteArray(string prefix, XmlDictionaryString localName, XmlDictionaryString namespaceUri, long[] array, int offset, int count) { throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException(SR2.JsonWriteArrayNotSupported)); } public override void WriteArray(string prefix, XmlDictionaryString localName, XmlDictionaryString namespaceUri, short[] array, int offset, int count) { throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException(SR2.JsonWriteArrayNotSupported)); } public override void WriteArray(string prefix, XmlDictionaryString localName, XmlDictionaryString namespaceUri, DateTime[] array, int offset, int count) { throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException(SR2.JsonWriteArrayNotSupported)); } public override void WriteArray(string prefix, XmlDictionaryString localName, XmlDictionaryString namespaceUri, Guid[] array, int offset, int count) { throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException(SR2.JsonWriteArrayNotSupported)); } public override void WriteArray(string prefix, XmlDictionaryString localName, XmlDictionaryString namespaceUri, TimeSpan[] array, int offset, int count) { throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException(SR2.JsonWriteArrayNotSupported)); } public override void WriteBase64(byte[] buffer, int index, int count) { if (buffer == null) { throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("buffer"); } // Not checking upper bound because it will be caught by "count". This is what XmlTextWriter does. if (index < 0) { throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError( new ArgumentOutOfRangeException("index", SR2.GetString(SR2.ValueMustBeNonNegative))); } if (count < 0) { throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError( new ArgumentOutOfRangeException("count", SR2.GetString(SR2.ValueMustBeNonNegative))); } if (count > buffer.Length - index) { throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError( new ArgumentOutOfRangeException("count", SR2.GetString(SR2.JsonSizeExceedsRemainingBufferSpace, buffer.Length - index))); } StartText(); nodeWriter.WriteBase64Text(buffer, 0, buffer, index, count); } public override void WriteBinHex(byte[] buffer, int index, int count) { if (buffer == null) { throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("buffer"); } // Not checking upper bound because it will be caught by "count". This is what XmlTextWriter does. if (index < 0) { throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError( new ArgumentOutOfRangeException("index", SR2.GetString(SR2.ValueMustBeNonNegative))); } if (count < 0) { throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError( new ArgumentOutOfRangeException("count", SR2.GetString(SR2.ValueMustBeNonNegative))); } if (count > buffer.Length - index) { throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError( new ArgumentOutOfRangeException("count", SR2.GetString(SR2.JsonSizeExceedsRemainingBufferSpace, buffer.Length - index))); } StartText(); WriteEscapedJsonString(BinHexEncoding.GetString(buffer, index, count)); } public override void WriteCData(string text) { WriteString(text); } public override void WriteCharEntity(char ch) { WriteString(ch.ToString()); } public override void WriteChars(char[] buffer, int index, int count) { if (buffer == null) { throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("buffer"); } // Not checking upper bound because it will be caught by "count". This is what XmlTextWriter does. if (index < 0) { throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError( new ArgumentOutOfRangeException("index", SR2.GetString(SR2.ValueMustBeNonNegative))); } if (count < 0) { throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError( new ArgumentOutOfRangeException("count", SR2.GetString(SR2.ValueMustBeNonNegative))); } if (count > buffer.Length - index) { throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError( new ArgumentOutOfRangeException("count", SR2.GetString(SR2.JsonSizeExceedsRemainingBufferSpace, buffer.Length - index))); } WriteString(new string(buffer, index, count)); } public override void WriteComment(string text) { throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException(SR2.GetString(SR2.JsonMethodNotSupported, "WriteComment"))); } [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "2#sysid", Justification = "This method is derived from the base")] [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "1#pubid", Justification = "This method is derived from the base")] public override void WriteDocType(string name, string pubid, string sysid, string subset) { throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException(SR2.GetString(SR2.JsonMethodNotSupported, "WriteDocType"))); } public override void WriteEndAttribute() { if (IsClosed) { ThrowClosed(); } if (!HasOpenAttribute) { throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError( new XmlException(SR2.GetString(SR2.JsonNoMatchingStartAttribute))); } Fx.Assert(!(isWritingDataTypeAttribute && isWritingServerTypeAttribute), "Can not write type attribute and __type attribute at the same time."); if (isWritingDataTypeAttribute) { switch (attributeText) { case JsonGlobals.numberString: { ThrowIfServerTypeWritten(JsonGlobals.numberString); dataType = JsonDataType.Number; break; } case JsonGlobals.stringString: { ThrowIfServerTypeWritten(JsonGlobals.stringString); dataType = JsonDataType.String; break; } case JsonGlobals.arrayString: { ThrowIfServerTypeWritten(JsonGlobals.arrayString); dataType = JsonDataType.Array; break; } case JsonGlobals.objectString: { dataType = JsonDataType.Object; break; } case JsonGlobals.nullString: { ThrowIfServerTypeWritten(JsonGlobals.nullString); dataType = JsonDataType.Null; break; } case JsonGlobals.booleanString: { ThrowIfServerTypeWritten(JsonGlobals.booleanString); dataType = JsonDataType.Boolean; break; } default: throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError( new XmlException(SR2.GetString(SR2.JsonUnexpectedAttributeValue, attributeText))); } attributeText = null; isWritingDataTypeAttribute = false; if (!IsWritingNameWithMapping || WrittenNameWithMapping) { WriteDataTypeServerType(); } } else if (isWritingServerTypeAttribute) { serverTypeValue = attributeText; attributeText = null; isWritingServerTypeAttribute = false; // we are writing __type after type="object" (enforced by WSE) if ((!IsWritingNameWithMapping || WrittenNameWithMapping) && dataType == JsonDataType.Object) { WriteServerTypeAttribute(); } } else if (IsWritingNameAttribute) { WriteJsonElementName(attributeText); attributeText = null; nameState = NameState.IsWritingNameWithMapping | NameState.WrittenNameWithMapping; WriteDataTypeServerType(); } else if (isWritingXmlnsAttribute) { attributeText = null; isWritingXmlnsAttribute = false; } } public override void WriteEndDocument() { if (IsClosed) { ThrowClosed(); } if (nodeType != JsonNodeType.None) { while (depth > 0) { WriteEndElement(); } } } public override void WriteEndElement() { if (IsClosed) { ThrowClosed(); } if (depth == 0) { throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError( new XmlException(SR2.GetString(SR2.JsonEndElementNoOpenNodes))); } if (HasOpenAttribute) { throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError( new XmlException(SR2.GetString(SR2.JsonOpenAttributeMustBeClosedFirst, "WriteEndElement"))); } endElementBuffer = false; JsonNodeType token = ExitScope(); if (token == JsonNodeType.Collection) { nodeWriter.WriteText(JsonGlobals.EndCollectionChar); token = ExitScope(); } else if (nodeType == JsonNodeType.QuotedText) { // For writing " WriteJsonQuote(); } else if (nodeType == JsonNodeType.Element) { if ((dataType == JsonDataType.None) && (serverTypeValue != null)) { throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError( new XmlException(SR2.GetString(SR2.JsonMustSpecifyDataType, JsonGlobals.typeString, JsonGlobals.objectString, JsonGlobals.serverTypeString))); } if (IsWritingNameWithMapping && !WrittenNameWithMapping) { // Ending without writing item attribute // Not providing a better error message because localization deadline has passed. throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError( new XmlException(SR2.GetString(SR2.JsonMustSpecifyDataType, JsonGlobals.itemString, string.Empty, JsonGlobals.itemString))); } // the element is empty, it does not have any content, if ((dataType == JsonDataType.None) || (dataType == JsonDataType.String)) { nodeWriter.WriteText(JsonGlobals.QuoteChar); nodeWriter.WriteText(JsonGlobals.QuoteChar); } } else { // Assert on only StandaloneText and EndElement because preceding if // conditions take care of checking for QuotedText and Element. Fx.Assert((nodeType == JsonNodeType.StandaloneText) || (nodeType == JsonNodeType.EndElement), "nodeType has invalid value " + nodeType + ". Expected it to be QuotedText, Element, StandaloneText, or EndElement."); } if (depth != 0) { if (token == JsonNodeType.Element) { endElementBuffer = true; } else if (token == JsonNodeType.Object) { nodeWriter.WriteText(JsonGlobals.EndObjectChar); if ((depth > 0) && scopes[depth] == JsonNodeType.Element) { ExitScope(); endElementBuffer = true; } } } dataType = JsonDataType.None; nodeType = JsonNodeType.EndElement; nameState = NameState.None; wroteServerTypeAttribute = false; } public override void WriteEntityRef(string name) { throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException(SR2.GetString(SR2.JsonMethodNotSupported, "WriteEntityRef"))); } public override void WriteFullEndElement() { WriteEndElement(); } public override void WriteProcessingInstruction(string name, string text) { if (IsClosed) { ThrowClosed(); } if (!name.Equals("xml", StringComparison.OrdinalIgnoreCase)) { throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(SR2.GetString(SR2.JsonXmlProcessingInstructionNotSupported), "name")); } if (WriteState != WriteState.Start) { throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new XmlException(SR2.GetString(SR2.JsonXmlInvalidDeclaration))); } } public override void WriteQualifiedName(string localName, string ns) { if (localName == null) { throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("localName"); } if (localName.Length == 0) { throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperArgument("localName", SR2.GetString(SR2.JsonInvalidLocalNameEmpty)); } if (ns == null) { ns = string.Empty; } base.WriteQualifiedName(localName, ns); } public override void WriteRaw(string data) { WriteString(data); } public override void WriteRaw(char[] buffer, int index, int count) { if (buffer == null) { throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("buffer"); } // Not checking upper bound because it will be caught by "count". This is what XmlTextWriter does. if (index < 0) { throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError( new ArgumentOutOfRangeException("index", SR2.GetString(SR2.ValueMustBeNonNegative))); } if (count < 0) { throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError( new ArgumentOutOfRangeException("count", SR2.GetString(SR2.ValueMustBeNonNegative))); } if (count > buffer.Length - index) { throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError( new ArgumentOutOfRangeException("count", SR2.GetString(SR2.JsonSizeExceedsRemainingBufferSpace, buffer.Length - index))); } WriteString(new string(buffer, index, count)); } [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1308:NormalizeStringsToUppercase")] // [....], ToLowerInvariant is just used in Json error message public override void WriteStartAttribute(string prefix, string localName, string ns) { if (IsClosed) { ThrowClosed(); } if (!string.IsNullOrEmpty(prefix)) { if (IsWritingNameWithMapping && prefix == JsonGlobals.xmlnsPrefix) { if (ns != null && ns != xmlnsNamespace) { throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(System.Runtime.Serialization.SR.GetString(System.Runtime.Serialization.SR.XmlPrefixBoundToNamespace, "xmlns", xmlnsNamespace, ns), "ns")); } } else { throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperArgument("prefix", SR2.GetString(SR2.JsonPrefixMustBeNullOrEmpty, prefix)); } } else { if (IsWritingNameWithMapping && ns == xmlnsNamespace && localName != JsonGlobals.xmlnsPrefix) { prefix = JsonGlobals.xmlnsPrefix; } } if (!string.IsNullOrEmpty(ns)) { if (IsWritingNameWithMapping && ns == xmlnsNamespace) { prefix = JsonGlobals.xmlnsPrefix; } else { throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperArgument("ns", SR2.GetString(SR2.JsonNamespaceMustBeEmpty, ns)); } } if (localName == null) { throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("localName"); } if (localName.Length == 0) { throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperArgument("localName", SR2.GetString(SR2.JsonInvalidLocalNameEmpty)); } if ((nodeType != JsonNodeType.Element) && !wroteServerTypeAttribute) { throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new XmlException(SR2.GetString(SR2.JsonAttributeMustHaveElement))); } if (HasOpenAttribute) { throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError( new XmlException(SR2.GetString(SR2.JsonOpenAttributeMustBeClosedFirst, "WriteStartAttribute"))); } if (prefix == JsonGlobals.xmlnsPrefix) { isWritingXmlnsAttribute = true; } else if (localName == JsonGlobals.typeString) { if (dataType != JsonDataType.None) { throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError( new XmlException(SR2.GetString(SR2.JsonAttributeAlreadyWritten, JsonGlobals.typeString))); } isWritingDataTypeAttribute = true; } else if (localName == JsonGlobals.serverTypeString) { if (serverTypeValue != null) { throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError( new XmlException(SR2.GetString(SR2.JsonAttributeAlreadyWritten, JsonGlobals.serverTypeString))); } if ((dataType != JsonDataType.None) && (dataType != JsonDataType.Object)) { throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError( new XmlException(SR2.GetString(SR2.JsonServerTypeSpecifiedForInvalidDataType, JsonGlobals.serverTypeString, JsonGlobals.typeString, dataType.ToString().ToLowerInvariant(), JsonGlobals.objectString))); } isWritingServerTypeAttribute = true; } else if (localName == JsonGlobals.itemString) { if (WrittenNameWithMapping) { throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError( new XmlException(SR2.GetString(SR2.JsonAttributeAlreadyWritten, JsonGlobals.itemString))); } if (!IsWritingNameWithMapping) { // Don't write attribute with local name "item" if- element is not open. // Not providing a better error message because localization deadline has passed. throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError( new XmlException(SR2.GetString(SR2.JsonEndElementNoOpenNodes))); } nameState |= NameState.IsWritingNameAttribute; } else { throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperArgument("localName", SR2.GetString(SR2.JsonUnexpectedAttributeLocalName, localName)); } } public override void WriteStartDocument(bool standalone) { // In XML, writes the XML declaration with the version "1.0" and the standalone attribute. WriteStartDocument(); } public override void WriteStartDocument() { // In XML, writes the XML declaration with the version "1.0". if (IsClosed) { ThrowClosed(); } if (WriteState != WriteState.Start) { throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError( new XmlException( SR2.GetString(SR2.JsonInvalidWriteState, "WriteStartDocument", WriteState.ToString()))); } } public override void WriteStartElement(string prefix, string localName, string ns) { if (localName == null) { throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("localName"); } if (localName.Length == 0) { throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperArgument("localName", SR2.GetString(SR2.JsonInvalidLocalNameEmpty)); } if (!string.IsNullOrEmpty(prefix)) { if (string.IsNullOrEmpty(ns) || !TrySetWritingNameWithMapping(localName, ns)) { throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperArgument("prefix", SR2.GetString(SR2.JsonPrefixMustBeNullOrEmpty, prefix)); } } if (!string.IsNullOrEmpty(ns)) { if (!TrySetWritingNameWithMapping(localName, ns)) { throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperArgument("ns", SR2.GetString(SR2.JsonNamespaceMustBeEmpty, ns)); } } if (IsClosed) { ThrowClosed(); } if (HasOpenAttribute) { throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError( new XmlException(SR2.GetString(SR2.JsonOpenAttributeMustBeClosedFirst, "WriteStartElement"))); } if ((nodeType != JsonNodeType.None) && depth == 0) { throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError( new XmlException(SR2.GetString(SR2.JsonMultipleRootElementsNotAllowedOnWriter))); } switch (nodeType) { case JsonNodeType.None: { if (!localName.Equals(JsonGlobals.rootString)) { throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError( new XmlException(SR2.GetString(SR2.JsonInvalidRootElementName, localName, JsonGlobals.rootString))); } EnterScope(JsonNodeType.Element); break; } case JsonNodeType.Element: { if ((dataType != JsonDataType.Array) && (dataType != JsonDataType.Object)) { throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError( new XmlException(SR2.GetString(SR2.JsonNodeTypeArrayOrObjectNotSpecified))); } if (!IsWritingCollection) { if (nameState != NameState.IsWritingNameWithMapping) { WriteJsonElementName(localName); } } else if (!localName.Equals(JsonGlobals.itemString)) { throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError( new XmlException(SR2.GetString(SR2.JsonInvalidItemNameForArrayElement, localName, JsonGlobals.itemString))); } EnterScope(JsonNodeType.Element); break; } case JsonNodeType.EndElement: { if (endElementBuffer) { nodeWriter.WriteText(JsonGlobals.MemberSeparatorChar); } if (!IsWritingCollection) { if (nameState != NameState.IsWritingNameWithMapping) { WriteJsonElementName(localName); } } else if (!localName.Equals(JsonGlobals.itemString)) { throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError( new XmlException(SR2.GetString(SR2.JsonInvalidItemNameForArrayElement, localName, JsonGlobals.itemString))); } EnterScope(JsonNodeType.Element); break; } default: throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError( new XmlException(SR2.GetString(SR2.JsonInvalidStartElementCall))); } isWritingDataTypeAttribute = false; isWritingServerTypeAttribute = false; isWritingXmlnsAttribute = false; wroteServerTypeAttribute = false; serverTypeValue = null; dataType = JsonDataType.None; nodeType = JsonNodeType.Element; } public override void WriteString(string text) { if (HasOpenAttribute && (text != null)) { attributeText += text; } else { StartText(); WriteEscapedJsonString(text); } } public override void WriteSurrogateCharEntity(char lowChar, char highChar) { WriteString(string.Concat(highChar, lowChar)); } public override void WriteValue(bool value) { StartText(); nodeWriter.WriteBoolText(value); } public override void WriteValue(decimal value) { StartText(); nodeWriter.WriteDecimalText(value); } public override void WriteValue(double value) { StartText(); nodeWriter.WriteDoubleText(value); } public override void WriteValue(float value) { StartText(); nodeWriter.WriteFloatText(value); } public override void WriteValue(int value) { StartText(); nodeWriter.WriteInt32Text(value); } public override void WriteValue(long value) { StartText(); nodeWriter.WriteInt64Text(value); } public override void WriteValue(Guid value) { StartText(); nodeWriter.WriteGuidText(value); } public override void WriteValue(DateTime value) { StartText(); nodeWriter.WriteDateTimeText(value); } public override void WriteValue(string value) { WriteString(value); } public override void WriteValue(TimeSpan value) { StartText(); nodeWriter.WriteTimeSpanText(value); } public override void WriteValue(UniqueId value) { if (value == null) { throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("value"); } StartText(); nodeWriter.WriteUniqueIdText(value); } public override void WriteValue(object value) { if (IsClosed) { ThrowClosed(); } if (value == null) { throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("value"); } if (value is Array) { WriteValue((Array) value); } else if (value is IStreamProvider) { WriteValue((IStreamProvider) value); } else { WritePrimitiveValue(value); } } [SuppressMessage("Microsoft.Naming", "CA1702:CompoundWordsShouldBeCasedCorrectly", MessageId = "Whitespace", Justification = "This method is derived from the base")] public override void WriteWhitespace(string ws) { if (IsClosed) { ThrowClosed(); } if (ws == null) { throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("ws"); } for (int i = 0; i < ws.Length; ++i) { char c = ws[i]; if (c != ' ' && c != '\t' && c != '\n' && c != '\r') { throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperArgument("ws", SR2.GetString(SR2.JsonOnlyWhitespace, c.ToString(), "WriteWhitespace")); } } WriteString(ws); } public override void WriteXmlAttribute(string localName, string value) { throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException(SR2.GetString(SR2.JsonMethodNotSupported, "WriteXmlAttribute"))); } public override void WriteXmlAttribute(XmlDictionaryString localName, XmlDictionaryString value) { throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException(SR2.GetString(SR2.JsonMethodNotSupported, "WriteXmlAttribute"))); } public override void WriteXmlnsAttribute(string prefix, string namespaceUri) { if (!IsWritingNameWithMapping) { throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException(SR2.GetString(SR2.JsonMethodNotSupported, "WriteXmlnsAttribute"))); } } public override void WriteXmlnsAttribute(string prefix, XmlDictionaryString namespaceUri) { if (!IsWritingNameWithMapping) { throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException(SR2.GetString(SR2.JsonMethodNotSupported, "WriteXmlnsAttribute"))); } } internal static bool CharacterNeedsEscaping(char ch) { return (ch == FORWARD_SLASH || ch == JsonGlobals.QuoteChar || ch < WHITESPACE || ch == BACK_SLASH || (ch >= HIGH_SURROGATE_START && (ch <= LOW_SURROGATE_END || ch >= MAX_CHAR))); } static void ThrowClosed() { throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError( new InvalidOperationException(SR2.GetString(SR2.JsonWriterClosed))); } void CheckText(JsonNodeType nextNodeType) { if (IsClosed) { ThrowClosed(); } if (depth == 0) { throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError( new InvalidOperationException( System.Runtime.Serialization.SR.GetString(System.Runtime.Serialization.SR.XmlIllegalOutsideRoot))); } if ((nextNodeType == JsonNodeType.StandaloneText) && (nodeType == JsonNodeType.QuotedText)) { throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError( new XmlException( SR2.GetString(SR2.JsonCannotWriteStandaloneTextAfterQuotedText))); } } void EnterScope(JsonNodeType currentNodeType) { depth++; if (scopes == null) { scopes = new JsonNodeType[4]; } else if (scopes.Length == depth) { JsonNodeType[] newScopes = new JsonNodeType[depth * 2]; Array.Copy(scopes, newScopes, depth); scopes = newScopes; } scopes[depth] = currentNodeType; } JsonNodeType ExitScope() { JsonNodeType nodeTypeToReturn = scopes[depth]; scopes[depth] = JsonNodeType.None; depth--; return nodeTypeToReturn; } void InitializeWriter() { nodeType = JsonNodeType.None; dataType = JsonDataType.None; isWritingDataTypeAttribute = false; wroteServerTypeAttribute = false; isWritingServerTypeAttribute = false; serverTypeValue = null; attributeText = null; if (depth != 0) { depth = 0; } if ((scopes != null) && (scopes.Length > JsonGlobals.maxScopeSize)) { scopes = null; } // Can't let writeState be at Closed if reinitializing. writeState = WriteState.Start; endElementBuffer = false; } void StartText() { if (HasOpenAttribute) { throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR2.GetString(SR2.JsonMustUseWriteStringForWritingAttributeValues))); } if ((dataType == JsonDataType.None) && (serverTypeValue != null)) { throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError( new XmlException(SR2.GetString(SR2.JsonMustSpecifyDataType, JsonGlobals.typeString, JsonGlobals.objectString, JsonGlobals.serverTypeString))); } if (IsWritingNameWithMapping && !WrittenNameWithMapping) { // Don't write out any text content unless the local name has been written. // Not providing a better error message because localization deadline has passed. throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError( new XmlException(SR2.GetString(SR2.JsonMustSpecifyDataType, JsonGlobals.itemString, string.Empty, JsonGlobals.itemString))); } if ((dataType == JsonDataType.String) || (dataType == JsonDataType.None)) { CheckText(JsonNodeType.QuotedText); if (nodeType != JsonNodeType.QuotedText) { WriteJsonQuote(); } nodeType = JsonNodeType.QuotedText; } else if ((dataType == JsonDataType.Number) || (dataType == JsonDataType.Boolean)) { CheckText(JsonNodeType.StandaloneText); nodeType = JsonNodeType.StandaloneText; } else { ThrowInvalidAttributeContent(); } } void ThrowIfServerTypeWritten(string dataTypeSpecified) { if (serverTypeValue != null) { throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError( new XmlException(SR2.GetString(SR2.JsonInvalidDataTypeSpecifiedForServerType, JsonGlobals.typeString, dataTypeSpecified, JsonGlobals.serverTypeString, JsonGlobals.objectString))); } } [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1308:NormalizeStringsToUppercase")] // [....], ToLowerInvariant is just used in Json error message void ThrowInvalidAttributeContent() { if (HasOpenAttribute) { throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError( new XmlException(SR2.GetString(SR2.JsonInvalidMethodBetweenStartEndAttribute))); } else { throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError( new XmlException(SR2.GetString(SR2.JsonCannotWriteTextAfterNonTextAttribute, dataType.ToString().ToLowerInvariant()))); } } bool TrySetWritingNameWithMapping(string localName, string ns) { if (localName.Equals(JsonGlobals.itemString) && ns.Equals(JsonGlobals.itemString)) { nameState = NameState.IsWritingNameWithMapping; return true; } return false; } void WriteDataTypeServerType() { if (dataType != JsonDataType.None) { switch (dataType) { case JsonDataType.Array: { EnterScope(JsonNodeType.Collection); nodeWriter.WriteText(JsonGlobals.CollectionChar); break; } case JsonDataType.Object: { EnterScope(JsonNodeType.Object); nodeWriter.WriteText(JsonGlobals.ObjectChar); break; } case JsonDataType.Null: { nodeWriter.WriteText(JsonGlobals.nullString); break; } default: break; } if (serverTypeValue != null) { // dataType must be object because we throw in all other case. WriteServerTypeAttribute(); } } } [SecurityCritical, SecurityTreatAsSafe] unsafe void WriteEscapedJsonString(string str) { fixed (char *chars = str) { int i = 0; int j; for (j = 0; j < str.Length; j++) { char ch = chars[j]; if (ch <= FORWARD_SLASH) { if (ch == FORWARD_SLASH || ch == JsonGlobals.QuoteChar) { nodeWriter.WriteChars(chars + i, j - i); nodeWriter.WriteText(BACK_SLASH); nodeWriter.WriteText(ch); i = j + 1; } else if (ch < WHITESPACE) { nodeWriter.WriteChars(chars + i, j - i); nodeWriter.WriteText(BACK_SLASH); nodeWriter.WriteText('u'); nodeWriter.WriteText(string.Format(CultureInfo.InvariantCulture, "{0:x4}", (int) ch)); i = j + 1; } } else if (ch == BACK_SLASH) { nodeWriter.WriteChars(chars + i, j - i); nodeWriter.WriteText(BACK_SLASH); nodeWriter.WriteText(ch); i = j + 1; } else if (ch >= HIGH_SURROGATE_START && (ch <= LOW_SURROGATE_END || ch >= MAX_CHAR)) { nodeWriter.WriteChars(chars + i, j - i); nodeWriter.WriteText(BACK_SLASH); nodeWriter.WriteText('u'); nodeWriter.WriteText(string.Format(CultureInfo.InvariantCulture, "{0:x4}", (int) ch)); i = j + 1; } } if (i < j) { nodeWriter.WriteChars(chars + i, j - i); } } } void WriteJsonElementName(string localName) { WriteJsonQuote(); WriteEscapedJsonString(localName); WriteJsonQuote(); nodeWriter.WriteText(JsonGlobals.NameValueSeparatorChar); } void WriteJsonQuote() { nodeWriter.WriteText(JsonGlobals.QuoteChar); } void WritePrimitiveValue(object value) { if (IsClosed) { ThrowClosed(); } if (value == null) { throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("value")); } if (value is ulong) { WriteValue((ulong) value); } else if (value is string) { WriteValue((string) value); } else if (value is int) { WriteValue((int) value); } else if (value is long) { WriteValue((long) value); } else if (value is bool) { WriteValue((bool) value); } else if (value is double) { WriteValue((double) value); } else if (value is DateTime) { WriteValue((DateTime) value); } else if (value is float) { WriteValue((float) value); } else if (value is decimal) { WriteValue((decimal) value); } else if (value is XmlDictionaryString) { WriteValue((XmlDictionaryString) value); } else if (value is UniqueId) { WriteValue((UniqueId) value); } else if (value is Guid) { WriteValue((Guid) value); } else if (value is TimeSpan) { WriteValue((TimeSpan) value); } else if (value.GetType().IsArray) { throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(SR2.GetString(SR2.JsonNestedArraysNotSupported), "value")); } else { base.WriteValue(value); } } void WriteServerTypeAttribute() { string value = serverTypeValue; JsonDataType oldDataType = dataType; NameState oldNameState = nameState; WriteStartElement(JsonGlobals.serverTypeString); WriteValue(value); WriteEndElement(); dataType = oldDataType; nameState = oldNameState; wroteServerTypeAttribute = true; } void WriteValue(ulong value) { StartText(); nodeWriter.WriteUInt64Text(value); } void WriteValue(Array array) { // This method is called only if WriteValue(object) is called with an array // The contract for XmlWriter.WriteValue(object) requires that this object array be written out as a string. // E.g. WriteValue(new int[] { 1, 2, 3}) should be equivalent to WriteString("1 2 3"). JsonDataType oldDataType = dataType; // Set attribute mode to String because WritePrimitiveValue might write numerical text. // Calls to methods that write numbers can't be mixed with calls that write quoted text unless the attribute mode is explictly string. dataType = JsonDataType.String; StartText(); for (int i = 0; i < array.Length; i++) { if (i != 0) { nodeWriter.WriteText(JsonGlobals.WhitespaceChar); } WritePrimitiveValue(array.GetValue(i)); } dataType = oldDataType; } class JsonNodeWriter : XmlUTF8NodeWriter { [SecurityCritical] internal unsafe void WriteChars(char *chars, int charCount) { base.UnsafeWriteUTF8Chars(chars, charCount); } } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- ExpressionBinding.cs
- NumberFormatter.cs
- RepeatButtonAutomationPeer.cs
- CodeAttachEventStatement.cs
- InkCanvasInnerCanvas.cs
- EvidenceBase.cs
- SqlMethodAttribute.cs
- WebPartDescription.cs
- LoginView.cs
- MsmqReceiveParameters.cs
- QueryExpr.cs
- PageStatePersister.cs
- BuildResult.cs
- StateBag.cs
- Decimal.cs
- SerializationObjectManager.cs
- IisTraceWebEventProvider.cs
- ToolStripProfessionalLowResolutionRenderer.cs
- TextRangeProviderWrapper.cs
- Cast.cs
- HttpApplication.cs
- ArraySegment.cs
- DesignerUtility.cs
- ValueTable.cs
- CodeTypeMember.cs
- ScaleTransform3D.cs
- CompilerGlobalScopeAttribute.cs
- RoutedEventHandlerInfo.cs
- ContextQuery.cs
- Point4D.cs
- TryLoadRunnableWorkflowCommand.cs
- AssemblyAssociatedContentFileAttribute.cs
- OutputScopeManager.cs
- QueryContinueDragEventArgs.cs
- HttpChannelHelpers.cs
- EmbeddedObject.cs
- DiscoveryClientDuplexChannel.cs
- TagNameToTypeMapper.cs
- TextTreePropertyUndoUnit.cs
- PeerMessageDispatcher.cs
- DataView.cs
- UndoManager.cs
- DBCommandBuilder.cs
- MsmqIntegrationInputMessage.cs
- Filter.cs
- FrameworkElementFactory.cs
- PasswordRecoveryDesigner.cs
- URL.cs
- DynamicActionMessageFilter.cs
- SettingsPropertyIsReadOnlyException.cs
- MergeExecutor.cs
- Compiler.cs
- BCLDebug.cs
- TextTreeObjectNode.cs
- CacheEntry.cs
- XXXInfos.cs
- ProcessHostServerConfig.cs
- TableHeaderCell.cs
- PermissionSetTriple.cs
- PrintPreviewGraphics.cs
- TypeLoadException.cs
- ExpressionBindingCollection.cs
- TypeRefElement.cs
- VisualBrush.cs
- XmlSchemaInclude.cs
- StructuredTypeEmitter.cs
- CallContext.cs
- CqlParserHelpers.cs
- ProxyHelper.cs
- QueryStringHandler.cs
- Point4DConverter.cs
- SqlDataSourceView.cs
- VarRemapper.cs
- ExplicitDiscriminatorMap.cs
- DataGridViewSelectedRowCollection.cs
- DragDrop.cs
- PointValueSerializer.cs
- StrongTypingException.cs
- Graph.cs
- CodeTypeParameter.cs
- StorageTypeMapping.cs
- DictationGrammar.cs
- PropertyTabChangedEvent.cs
- DataGridViewCellToolTipTextNeededEventArgs.cs
- VisualBasicSettingsHandler.cs
- CompilerWrapper.cs
- ProfessionalColorTable.cs
- TextContainerChangeEventArgs.cs
- RoutingConfiguration.cs
- WebServiceParameterData.cs
- ViewBase.cs
- AmbiguousMatchException.cs
- ActivityCollectionMarkupSerializer.cs
- _AutoWebProxyScriptWrapper.cs
- SparseMemoryStream.cs
- VisualTarget.cs
- TemplatedWizardStep.cs
- WebServiceFault.cs
- AssemblyContextControlItem.cs
- InstanceNormalEvent.cs