Code:
/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / DataWeb / Server / System / Data / Services / Serializers / JsonWriter.cs / 1602603 / 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 start a data object wrapper in JSON. private const string JsonDataWrapper = "\"d\" : "; ///"results" header for Json data array private const string JsonResultName = "results"; ///Writer to write text into private readonly IndentedTextWriter writer; ///scope of the json text - object, array, etc private readonly 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 } ////// 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); } ////// Write the "d" wrapper text /// public void WriteDataWrapper() { this.writer.Write(JsonDataWrapper); } ////// Write the "results" header for the data array /// public void WriteDataArrayName() { this.WriteName(JsonResultName); } ////// 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 == '\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 '\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 start a data object wrapper in JSON. private const string JsonDataWrapper = "\"d\" : "; ///"results" header for Json data array private const string JsonResultName = "results"; ///Writer to write text into private readonly IndentedTextWriter writer; ///scope of the json text - object, array, etc private readonly 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 } ////// 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); } ////// Write the "d" wrapper text /// public void WriteDataWrapper() { this.writer.Write(JsonDataWrapper); } ////// Write the "results" header for the data array /// public void WriteDataArrayName() { this.WriteName(JsonResultName); } ////// 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 == '\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 '\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
- SkipQueryOptionExpression.cs
- TypeForwardedToAttribute.cs
- UpDownEvent.cs
- Button.cs
- QuaternionAnimation.cs
- FixedSOMTextRun.cs
- XmlSchemaElement.cs
- QilGenerator.cs
- LineMetrics.cs
- HttpGetClientProtocol.cs
- DBCSCodePageEncoding.cs
- AsyncPostBackTrigger.cs
- TypefaceMap.cs
- SuppressMessageAttribute.cs
- TemplateBindingExpression.cs
- PointUtil.cs
- XmlSchemaAll.cs
- ItemDragEvent.cs
- StickyNoteContentControl.cs
- SHA1CryptoServiceProvider.cs
- WindowsAuthenticationModule.cs
- FrameworkElement.cs
- DataGridItemCollection.cs
- FlowDocumentReaderAutomationPeer.cs
- SystemWebExtensionsSectionGroup.cs
- Ray3DHitTestResult.cs
- AnnouncementDispatcherAsyncResult.cs
- precedingsibling.cs
- WebHttpBehavior.cs
- ButtonColumn.cs
- TableChangeProcessor.cs
- IODescriptionAttribute.cs
- AnimatedTypeHelpers.cs
- TouchPoint.cs
- StateBag.cs
- sqlcontext.cs
- securitycriticaldata.cs
- FixedTextContainer.cs
- FileLoadException.cs
- TextServicesDisplayAttribute.cs
- Timer.cs
- ItemsPanelTemplate.cs
- Trace.cs
- ToolstripProfessionalRenderer.cs
- SqlMethodAttribute.cs
- EdmTypeAttribute.cs
- PropertyCollection.cs
- XmlQueryStaticData.cs
- Marshal.cs
- FormViewDeleteEventArgs.cs
- PropertyChangeTracker.cs
- TraceSource.cs
- NamedPermissionSet.cs
- RewritingPass.cs
- CollaborationHelperFunctions.cs
- RequestCacheManager.cs
- OleDbException.cs
- Rect3DValueSerializer.cs
- GridProviderWrapper.cs
- SchemeSettingElementCollection.cs
- oledbmetadatacollectionnames.cs
- AutomationElementCollection.cs
- DodSequenceMerge.cs
- DiscoveryEndpointValidator.cs
- UIElementIsland.cs
- wmiutil.cs
- diagnosticsswitches.cs
- RepeaterCommandEventArgs.cs
- GraphicsState.cs
- PolyQuadraticBezierSegmentFigureLogic.cs
- WebSysDescriptionAttribute.cs
- LineSegment.cs
- Random.cs
- WebBrowserNavigatingEventHandler.cs
- SoapDocumentMethodAttribute.cs
- DesignerResources.cs
- Panel.cs
- JulianCalendar.cs
- SqlDelegatedTransaction.cs
- SymbolDocumentInfo.cs
- TextDecorations.cs
- RenderingEventArgs.cs
- FileLogRecordEnumerator.cs
- InfoCardService.cs
- AsymmetricSignatureDeformatter.cs
- PropertyPath.cs
- unitconverter.cs
- ReadOnlyObservableCollection.cs
- XomlDesignerLoader.cs
- XamlTypeMapperSchemaContext.cs
- CharUnicodeInfo.cs
- WindowsStreamSecurityElement.cs
- SecurityHeaderElementInferenceEngine.cs
- DbProviderServices.cs
- GZipDecoder.cs
- COSERVERINFO.cs
- ManagementOperationWatcher.cs
- InputBinding.cs
- PeerName.cs
- NodeInfo.cs