Code:
/ Net / Net / 3.5.50727.3053 / DEVDIV / depot / DevDiv / releases / Orcas / SP / 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
- ResXResourceWriter.cs
- PrintPreviewControl.cs
- ReflectionUtil.cs
- XmlSchemaInferenceException.cs
- XmlILConstructAnalyzer.cs
- MenuCommands.cs
- RepeatInfo.cs
- GetMemberBinder.cs
- DataSourceHelper.cs
- CommandEventArgs.cs
- HtmlEmptyTagControlBuilder.cs
- DataGridViewColumnDividerDoubleClickEventArgs.cs
- MemberInfoSerializationHolder.cs
- SaveFileDialogDesigner.cs
- TextEditor.cs
- IIS7UserPrincipal.cs
- FastEncoder.cs
- FormViewUpdatedEventArgs.cs
- PrinterUnitConvert.cs
- SharedStatics.cs
- FormsAuthenticationUser.cs
- DateTimeConverter.cs
- ModifierKeysConverter.cs
- ContentDisposition.cs
- Bits.cs
- CallbackHandler.cs
- CategoryAttribute.cs
- PathSegment.cs
- XmlSchemaExternal.cs
- HMACSHA512.cs
- CallbackValidatorAttribute.cs
- Line.cs
- ResourceAssociationType.cs
- ManipulationBoundaryFeedbackEventArgs.cs
- TransactionScope.cs
- Funcletizer.cs
- OpenTypeLayoutCache.cs
- FileDetails.cs
- DoubleAnimation.cs
- RelationshipConverter.cs
- DiscoveryServiceExtension.cs
- OdbcTransaction.cs
- Completion.cs
- MobileCapabilities.cs
- OperatorExpressions.cs
- XDRSchema.cs
- Stylesheet.cs
- DesignerTransaction.cs
- InputReportEventArgs.cs
- WorkflowCreationContext.cs
- URI.cs
- XmlSchemaSequence.cs
- FilterableAttribute.cs
- HandleCollector.cs
- ChannelEndpointElementCollection.cs
- RadioButtonAutomationPeer.cs
- TextTrailingWordEllipsis.cs
- UriExt.cs
- ObjectDataSourceView.cs
- OleDbPermission.cs
- Int16Animation.cs
- StoreAnnotationsMap.cs
- ImageAttributes.cs
- ActivityTypeCodeDomSerializer.cs
- CachedCompositeFamily.cs
- HttpResponseInternalWrapper.cs
- CaseInsensitiveHashCodeProvider.cs
- pingexception.cs
- RepeatButtonAutomationPeer.cs
- OleDbError.cs
- ObjectHandle.cs
- MergeFailedEvent.cs
- Quaternion.cs
- ProcessHost.cs
- DoubleCollection.cs
- CanExecuteRoutedEventArgs.cs
- indexingfiltermarshaler.cs
- BitmapMetadataEnumerator.cs
- ToolStripDesigner.cs
- SqlServer2KCompatibilityAnnotation.cs
- WindowsAltTab.cs
- PolicyLevel.cs
- LifetimeMonitor.cs
- FunctionDescription.cs
- HealthMonitoringSectionHelper.cs
- ObjectQueryExecutionPlan.cs
- DetailsViewModeEventArgs.cs
- XmlSchema.cs
- HtmlInputRadioButton.cs
- RegionInfo.cs
- Encoding.cs
- LogSwitch.cs
- AnimationStorage.cs
- DbDataRecord.cs
- WebException.cs
- XmlEnumAttribute.cs
- WebServiceErrorEvent.cs
- WhitespaceRuleLookup.cs
- Math.cs
- TextDecoration.cs