Code:
/ Dotnetfx_Vista_SP2 / Dotnetfx_Vista_SP2 / 8.0.50727.4016 / DEVDIV / depot / DevDiv / releases / Orcas / QFE / ndp / fx / src / DataWeb / Server / System / Data / Services / Serializers / JsonWriter.cs / 1 / JsonWriter.cs
//---------------------------------------------------------------------- //// Copyright (c) Microsoft Corporation. All rights reserved. // //// Provides a writer implementaion for Json format // // // @owner [....] //--------------------------------------------------------------------- namespace System.Data.Services.Serializers { using System; using System.Collections.Generic; using System.Globalization; using System.IO; using System.Text; using System.Xml; ////// Json text writer /// [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1001:TypesThatOwnDisposableFieldsShouldBeDisposable", Justification = "Original writer is disposed of?")] internal sealed class JsonWriter { ///const tick value for caculating tick values internal static readonly long DatetimeMinTimeTicks = (new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).Ticks; ///Json datetime format private const string JsonDateTimeFormat = @"\/Date({0})\/"; ///Text used to end a data object wrapper in JSON. private const string JsonWrapperEnd = " }"; ///Text used to start a data object wrapper in JSON. private const string JsonWrapperStart = "{ \"d\" : "; ///Writer to write text into private IndentedTextWriter writer; ///scope of the json text - object, array, etc private Stackscopes; /// /// Creates a new instance of Json writer /// /// writer to which text needs to be written public JsonWriter(TextWriter writer) { this.writer = new IndentedTextWriter(writer); this.scopes = new Stack(); } /// /// Various scope types for Json writer /// private enum ScopeType { ///array scope Array = 0, ///object scope Object = 1 } ///Ends wrapped text. public void EndWrapper() { this.writer.Write(JsonWrapperEnd); } ////// End the current scope /// public void EndScope() { if (this.scopes.Count == 0) { throw new InvalidOperationException("No active scope to end."); } this.writer.WriteLine(); this.writer.Indent--; Scope scope = this.scopes.Pop(); if (scope.Type == ScopeType.Array) { this.writer.Write("]"); } else { this.writer.Write("}"); } } ////// Start the array scope /// public void StartArrayScope() { this.StartScope(ScopeType.Array); } ///Starts a data object wrapper. public void StartWrapper() { this.writer.Write(JsonWrapperStart); } ////// Start the object scope /// public void StartObjectScope() { this.StartScope(ScopeType.Object); } ////// Write the name for the object property /// /// name of the object property public void WriteName(string name) { if (String.IsNullOrEmpty(name)) { throw new ArgumentNullException("name"); } if (this.scopes.Count == 0) { throw new InvalidOperationException("No active scope to write into."); } if (this.scopes.Peek().Type != ScopeType.Object) { throw new InvalidOperationException("Names can only be written into Object Scopes."); } Scope currentScope = this.scopes.Peek(); if (currentScope.Type == ScopeType.Object) { if (currentScope.ObjectCount != 0) { this.writer.WriteTrimmed(", "); } currentScope.ObjectCount++; } this.WriteCore(QuoteJScriptString(name), true /*quotes*/); this.writer.WriteTrimmed(": "); } ////// Write the bool value /// /// bool value to be written public void WriteValue(bool value) { this.WriteCore(value ? XmlConstants.XmlTrueLiteral : XmlConstants.XmlFalseLiteral, /* quotes */ false); } ////// Write the int value /// /// int value to be written public void WriteValue(int value) { this.WriteCore(value.ToString(CultureInfo.InvariantCulture), /* quotes */ false); } ////// Write the float value /// /// float value to be written public void WriteValue(float value) { if (double.IsInfinity(value) || double.IsNaN(value)) { this.WriteCore(value.ToString(null, CultureInfo.InvariantCulture), true /*quotes*/); } else { // float.ToString() supports a max scale of six, // whereas float.MinValue and float.MaxValue have 8 digits scale. Hence we need // to use XmlConvert in all other cases, except infinity this.WriteCore(XmlConvert.ToString(value), /* quotes */ false); } } ////// Write the short value /// /// short value to be written public void WriteValue(short value) { this.WriteCore(value.ToString(CultureInfo.InvariantCulture), /* quotes */ false); } ////// Write the long value /// /// long value to be written public void WriteValue(long value) { // Since Json only supports number, we need to convert long into string to prevent data loss this.WriteCore(value.ToString(CultureInfo.InvariantCulture), /* quotes */ true); } ////// Write the double value /// /// double value to be written public void WriteValue(double value) { if (double.IsInfinity(value) || double.IsNaN(value)) { this.WriteCore(value.ToString(null, CultureInfo.InvariantCulture), true /*quotes*/); } else { // double.ToString() supports a max scale of 14, // whereas float.MinValue and float.MaxValue have 16 digits scale. Hence we need // to use XmlConvert in all other cases, except infinity this.WriteCore(XmlConvert.ToString(value), /* quotes */ false); } } ////// Write the Guid value /// /// double value to be written public void WriteValue(Guid value) { this.WriteCore(value.ToString(), /* quotes */ true); } ////// Write the decimal value /// /// decimal value to be written public void WriteValue(decimal value) { // Since Json doesn't have decimal support (it only has one data type - number), // we need to convert decimal to string to prevent data loss this.WriteCore(value.ToString(CultureInfo.InvariantCulture), /* quotes */ true); } ////// Write the DateTime value /// /// dateTime value to be written public void WriteValue(DateTime dateTime) { // taken from the Atlas serializer // DevDiv 41127: Never confuse atlas serialized strings with dates // Serialized date: "\/Date(123)\/" // sb.Append(@"""\/Date("); // sb.Append((datetime.ToUniversalTime().Ticks - DatetimeMinTimeTicks) / 10000); // sb.Append(@")\/"""); switch (dateTime.Kind) { case DateTimeKind.Local: dateTime = dateTime.ToUniversalTime(); break; case DateTimeKind.Unspecified: dateTime = new DateTime(dateTime.Ticks, DateTimeKind.Utc); break; case DateTimeKind.Utc: break; } System.Diagnostics.Debug.Assert(dateTime.Kind == DateTimeKind.Utc, "dateTime.Kind == DateTimeKind.Utc"); this.WriteCore( String.Format( CultureInfo.InvariantCulture, JsonWriter.JsonDateTimeFormat, ((dateTime.Ticks - DatetimeMinTimeTicks) / 10000)), true); } ////// Write the byte value /// /// byte value to be written public void WriteValue(byte value) { this.WriteCore(value.ToString(CultureInfo.InvariantCulture), /* quotes */ false); } ////// Write the sbyte value /// /// sbyte value to be written public void WriteValue(sbyte value) { this.WriteCore(value.ToString(CultureInfo.InvariantCulture), /* quotes */ false); } ////// Write the string value /// /// string value to be written public void WriteValue(string s) { if (s == null) { this.WriteCore("null", /* quotes */ false); } else { this.WriteCore(QuoteJScriptString(s), /* quotes */ true); } } ////// Clears all buffers for the current writer /// public void Flush() { this.writer.Flush(); } ////// Returns the string value with special characters escaped /// /// input string value ///Returns the string value with special characters escaped. private static string QuoteJScriptString(string s) { if (String.IsNullOrEmpty(s)) { return String.Empty; } StringBuilder b = null; int startIndex = 0; int count = 0; for (int i = 0; i < s.Length; i++) { char c = s[i]; // Append the unhandled characters (that do not require special treament) // to the string builder when special characters are detected. if (c == '\r' || c == '\t' || c == '\"' || c == '\'' || c == '\\' || c == '\n' || c < ' ' || c > 0x7F || c == '\b' || c == '\f') { // Flush out the unescaped characters we've built so far. if (b == null) { b = new StringBuilder(s.Length + 6); } if (count > 0) { b.Append(s, startIndex, count); } startIndex = i + 1; count = 0; } switch (c) { case '\r': b.Append("\\r"); break; case '\t': b.Append("\\t"); break; case '\"': b.Append("\\\""); break; case '\'': b.Append("\\\'"); break; case '\\': b.Append("\\\\"); break; case '\n': b.Append("\\n"); break; case '\b': b.Append("\\b"); break; case '\f': b.Append("\\f"); break; default: if ((c < ' ') || (c > 0x7F)) { b.AppendFormat(CultureInfo.InvariantCulture, "\\u{0:x4}", (int)c); } else { count++; } break; } } string processedString = s; if (b != null) { if (count > 0) { b.Append(s, startIndex, count); } processedString = b.ToString(); } return processedString; } ////// Write the string value with/without quotes /// /// string value to be written /// put quotes around the value if this value is true private void WriteCore(string text, bool quotes) { if (this.scopes.Count != 0) { Scope currentScope = this.scopes.Peek(); if (currentScope.Type == ScopeType.Array) { if (currentScope.ObjectCount != 0) { this.writer.WriteTrimmed(", "); } currentScope.ObjectCount++; } } if (quotes) { this.writer.Write('"'); } this.writer.Write(text); if (quotes) { this.writer.Write('"'); } } ////// Start the scope given the scope type /// /// scope type private void StartScope(ScopeType type) { if (this.scopes.Count != 0) { Scope currentScope = this.scopes.Peek(); if ((currentScope.Type == ScopeType.Array) && (currentScope.ObjectCount != 0)) { this.writer.WriteTrimmed(", "); } currentScope.ObjectCount++; } Scope scope = new Scope(type); this.scopes.Push(scope); if (type == ScopeType.Array) { this.writer.Write("["); } else { this.writer.Write("{"); } this.writer.Indent++; this.writer.WriteLine(); } ////// class representing scope information /// private sealed class Scope { ///keeps the count of the nested scopes private int objectCount; ///keeps the type of the scope private ScopeType type; ////// Creates a new instance of scope type /// /// type of the scope public Scope(ScopeType type) { this.type = type; } ////// Get/Set the object count for this scope /// public int ObjectCount { get { return this.objectCount; } set { this.objectCount = value; } } ////// Gets the scope type for this scope /// public ScopeType Type { get { return this.type; } } } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. //---------------------------------------------------------------------- //// Copyright (c) Microsoft Corporation. All rights reserved. // //// Provides a writer implementaion for Json format // // // @owner [....] //--------------------------------------------------------------------- namespace System.Data.Services.Serializers { using System; using System.Collections.Generic; using System.Globalization; using System.IO; using System.Text; using System.Xml; ////// Json text writer /// [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1001:TypesThatOwnDisposableFieldsShouldBeDisposable", Justification = "Original writer is disposed of?")] internal sealed class JsonWriter { ///const tick value for caculating tick values internal static readonly long DatetimeMinTimeTicks = (new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).Ticks; ///Json datetime format private const string JsonDateTimeFormat = @"\/Date({0})\/"; ///Text used to end a data object wrapper in JSON. private const string JsonWrapperEnd = " }"; ///Text used to start a data object wrapper in JSON. private const string JsonWrapperStart = "{ \"d\" : "; ///Writer to write text into private IndentedTextWriter writer; ///scope of the json text - object, array, etc private Stackscopes; /// /// Creates a new instance of Json writer /// /// writer to which text needs to be written public JsonWriter(TextWriter writer) { this.writer = new IndentedTextWriter(writer); this.scopes = new Stack(); } /// /// Various scope types for Json writer /// private enum ScopeType { ///array scope Array = 0, ///object scope Object = 1 } ///Ends wrapped text. public void EndWrapper() { this.writer.Write(JsonWrapperEnd); } ////// End the current scope /// public void EndScope() { if (this.scopes.Count == 0) { throw new InvalidOperationException("No active scope to end."); } this.writer.WriteLine(); this.writer.Indent--; Scope scope = this.scopes.Pop(); if (scope.Type == ScopeType.Array) { this.writer.Write("]"); } else { this.writer.Write("}"); } } ////// Start the array scope /// public void StartArrayScope() { this.StartScope(ScopeType.Array); } ///Starts a data object wrapper. public void StartWrapper() { this.writer.Write(JsonWrapperStart); } ////// Start the object scope /// public void StartObjectScope() { this.StartScope(ScopeType.Object); } ////// Write the name for the object property /// /// name of the object property public void WriteName(string name) { if (String.IsNullOrEmpty(name)) { throw new ArgumentNullException("name"); } if (this.scopes.Count == 0) { throw new InvalidOperationException("No active scope to write into."); } if (this.scopes.Peek().Type != ScopeType.Object) { throw new InvalidOperationException("Names can only be written into Object Scopes."); } Scope currentScope = this.scopes.Peek(); if (currentScope.Type == ScopeType.Object) { if (currentScope.ObjectCount != 0) { this.writer.WriteTrimmed(", "); } currentScope.ObjectCount++; } this.WriteCore(QuoteJScriptString(name), true /*quotes*/); this.writer.WriteTrimmed(": "); } ////// Write the bool value /// /// bool value to be written public void WriteValue(bool value) { this.WriteCore(value ? XmlConstants.XmlTrueLiteral : XmlConstants.XmlFalseLiteral, /* quotes */ false); } ////// Write the int value /// /// int value to be written public void WriteValue(int value) { this.WriteCore(value.ToString(CultureInfo.InvariantCulture), /* quotes */ false); } ////// Write the float value /// /// float value to be written public void WriteValue(float value) { if (double.IsInfinity(value) || double.IsNaN(value)) { this.WriteCore(value.ToString(null, CultureInfo.InvariantCulture), true /*quotes*/); } else { // float.ToString() supports a max scale of six, // whereas float.MinValue and float.MaxValue have 8 digits scale. Hence we need // to use XmlConvert in all other cases, except infinity this.WriteCore(XmlConvert.ToString(value), /* quotes */ false); } } ////// Write the short value /// /// short value to be written public void WriteValue(short value) { this.WriteCore(value.ToString(CultureInfo.InvariantCulture), /* quotes */ false); } ////// Write the long value /// /// long value to be written public void WriteValue(long value) { // Since Json only supports number, we need to convert long into string to prevent data loss this.WriteCore(value.ToString(CultureInfo.InvariantCulture), /* quotes */ true); } ////// Write the double value /// /// double value to be written public void WriteValue(double value) { if (double.IsInfinity(value) || double.IsNaN(value)) { this.WriteCore(value.ToString(null, CultureInfo.InvariantCulture), true /*quotes*/); } else { // double.ToString() supports a max scale of 14, // whereas float.MinValue and float.MaxValue have 16 digits scale. Hence we need // to use XmlConvert in all other cases, except infinity this.WriteCore(XmlConvert.ToString(value), /* quotes */ false); } } ////// Write the Guid value /// /// double value to be written public void WriteValue(Guid value) { this.WriteCore(value.ToString(), /* quotes */ true); } ////// Write the decimal value /// /// decimal value to be written public void WriteValue(decimal value) { // Since Json doesn't have decimal support (it only has one data type - number), // we need to convert decimal to string to prevent data loss this.WriteCore(value.ToString(CultureInfo.InvariantCulture), /* quotes */ true); } ////// Write the DateTime value /// /// dateTime value to be written public void WriteValue(DateTime dateTime) { // taken from the Atlas serializer // DevDiv 41127: Never confuse atlas serialized strings with dates // Serialized date: "\/Date(123)\/" // sb.Append(@"""\/Date("); // sb.Append((datetime.ToUniversalTime().Ticks - DatetimeMinTimeTicks) / 10000); // sb.Append(@")\/"""); switch (dateTime.Kind) { case DateTimeKind.Local: dateTime = dateTime.ToUniversalTime(); break; case DateTimeKind.Unspecified: dateTime = new DateTime(dateTime.Ticks, DateTimeKind.Utc); break; case DateTimeKind.Utc: break; } System.Diagnostics.Debug.Assert(dateTime.Kind == DateTimeKind.Utc, "dateTime.Kind == DateTimeKind.Utc"); this.WriteCore( String.Format( CultureInfo.InvariantCulture, JsonWriter.JsonDateTimeFormat, ((dateTime.Ticks - DatetimeMinTimeTicks) / 10000)), true); } ////// Write the byte value /// /// byte value to be written public void WriteValue(byte value) { this.WriteCore(value.ToString(CultureInfo.InvariantCulture), /* quotes */ false); } ////// Write the sbyte value /// /// sbyte value to be written public void WriteValue(sbyte value) { this.WriteCore(value.ToString(CultureInfo.InvariantCulture), /* quotes */ false); } ////// Write the string value /// /// string value to be written public void WriteValue(string s) { if (s == null) { this.WriteCore("null", /* quotes */ false); } else { this.WriteCore(QuoteJScriptString(s), /* quotes */ true); } } ////// Clears all buffers for the current writer /// public void Flush() { this.writer.Flush(); } ////// Returns the string value with special characters escaped /// /// input string value ///Returns the string value with special characters escaped. private static string QuoteJScriptString(string s) { if (String.IsNullOrEmpty(s)) { return String.Empty; } StringBuilder b = null; int startIndex = 0; int count = 0; for (int i = 0; i < s.Length; i++) { char c = s[i]; // Append the unhandled characters (that do not require special treament) // to the string builder when special characters are detected. if (c == '\r' || c == '\t' || c == '\"' || c == '\'' || c == '\\' || c == '\n' || c < ' ' || c > 0x7F || c == '\b' || c == '\f') { // Flush out the unescaped characters we've built so far. if (b == null) { b = new StringBuilder(s.Length + 6); } if (count > 0) { b.Append(s, startIndex, count); } startIndex = i + 1; count = 0; } switch (c) { case '\r': b.Append("\\r"); break; case '\t': b.Append("\\t"); break; case '\"': b.Append("\\\""); break; case '\'': b.Append("\\\'"); break; case '\\': b.Append("\\\\"); break; case '\n': b.Append("\\n"); break; case '\b': b.Append("\\b"); break; case '\f': b.Append("\\f"); break; default: if ((c < ' ') || (c > 0x7F)) { b.AppendFormat(CultureInfo.InvariantCulture, "\\u{0:x4}", (int)c); } else { count++; } break; } } string processedString = s; if (b != null) { if (count > 0) { b.Append(s, startIndex, count); } processedString = b.ToString(); } return processedString; } ////// Write the string value with/without quotes /// /// string value to be written /// put quotes around the value if this value is true private void WriteCore(string text, bool quotes) { if (this.scopes.Count != 0) { Scope currentScope = this.scopes.Peek(); if (currentScope.Type == ScopeType.Array) { if (currentScope.ObjectCount != 0) { this.writer.WriteTrimmed(", "); } currentScope.ObjectCount++; } } if (quotes) { this.writer.Write('"'); } this.writer.Write(text); if (quotes) { this.writer.Write('"'); } } ////// Start the scope given the scope type /// /// scope type private void StartScope(ScopeType type) { if (this.scopes.Count != 0) { Scope currentScope = this.scopes.Peek(); if ((currentScope.Type == ScopeType.Array) && (currentScope.ObjectCount != 0)) { this.writer.WriteTrimmed(", "); } currentScope.ObjectCount++; } Scope scope = new Scope(type); this.scopes.Push(scope); if (type == ScopeType.Array) { this.writer.Write("["); } else { this.writer.Write("{"); } this.writer.Indent++; this.writer.WriteLine(); } ////// class representing scope information /// private sealed class Scope { ///keeps the count of the nested scopes private int objectCount; ///keeps the type of the scope private ScopeType type; ////// Creates a new instance of scope type /// /// type of the scope public Scope(ScopeType type) { this.type = type; } ////// Get/Set the object count for this scope /// public int ObjectCount { get { return this.objectCount; } set { this.objectCount = value; } } ////// Gets the scope type for this scope /// public ScopeType Type { get { return this.type; } } } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- ThemeDirectoryCompiler.cs
- XXXInfos.cs
- ImageAutomationPeer.cs
- CallbackValidator.cs
- AssemblyBuilderData.cs
- DispatcherProcessingDisabled.cs
- UpdatePanel.cs
- EncodingDataItem.cs
- FrugalMap.cs
- EntityChangedParams.cs
- Binding.cs
- FileDialogPermission.cs
- DesignTimeType.cs
- ScriptResourceDefinition.cs
- EventMappingSettings.cs
- SqlAliasesReferenced.cs
- ChannelServices.cs
- ISFClipboardData.cs
- MenuTracker.cs
- DataGridToolTip.cs
- QuaternionValueSerializer.cs
- GacUtil.cs
- StructuredTypeInfo.cs
- InputReportEventArgs.cs
- CharacterBuffer.cs
- XmlTextReader.cs
- DataRelationCollection.cs
- EntityDataSourceChangingEventArgs.cs
- SingleQueryOperator.cs
- DataGridRowHeaderAutomationPeer.cs
- LogExtent.cs
- ResXResourceSet.cs
- InputEventArgs.cs
- CompModHelpers.cs
- TextTreeTextBlock.cs
- WebPartManagerInternals.cs
- InfoCardClaim.cs
- WindowsListView.cs
- LicenseException.cs
- ButtonPopupAdapter.cs
- HttpVersion.cs
- ReliabilityContractAttribute.cs
- PriorityBinding.cs
- QilGeneratorEnv.cs
- oledbconnectionstring.cs
- Solver.cs
- OdbcErrorCollection.cs
- FontFaceLayoutInfo.cs
- StructuredProperty.cs
- PageAsyncTask.cs
- ParserContext.cs
- XmlComment.cs
- HttpEncoder.cs
- XmlParserContext.cs
- HttpListenerPrefixCollection.cs
- WebPartZoneBase.cs
- RegularExpressionValidator.cs
- WsrmFault.cs
- GeneratedView.cs
- CommandField.cs
- EventLogQuery.cs
- ManagementScope.cs
- DockAndAnchorLayout.cs
- WinEventHandler.cs
- TypeDelegator.cs
- NameValueConfigurationElement.cs
- CfgSemanticTag.cs
- ConnectionProviderAttribute.cs
- CodeTypeOfExpression.cs
- DataBindingHandlerAttribute.cs
- ObjectQueryProvider.cs
- LineVisual.cs
- HostDesigntimeLicenseContext.cs
- WSSecurityPolicy11.cs
- MimeWriter.cs
- Message.cs
- CharEntityEncoderFallback.cs
- UnsafeNativeMethods.cs
- HandleTable.cs
- DiscreteKeyFrames.cs
- HostingEnvironmentException.cs
- Attribute.cs
- ContextProperty.cs
- PageWrapper.cs
- ObjectSecurity.cs
- XmlSchemaComplexContentRestriction.cs
- ThemeInfoAttribute.cs
- AdornerPresentationContext.cs
- AstNode.cs
- ContentControl.cs
- DrawListViewItemEventArgs.cs
- CookielessHelper.cs
- _NegotiateClient.cs
- FileIOPermission.cs
- UIElement.cs
- TextPattern.cs
- DefaultPropertiesToSend.cs
- PerspectiveCamera.cs
- StrokeNodeOperations.cs
- MachineKey.cs