Code:
/ 4.0 / 4.0 / untmp / 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.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- HotCommands.cs
- DoubleAnimationUsingKeyFrames.cs
- DataObjectAttribute.cs
- PhonemeEventArgs.cs
- SourceFileBuildProvider.cs
- ModelTreeEnumerator.cs
- FunctionQuery.cs
- EventProviderClassic.cs
- PageParser.cs
- ConnectionStringSettingsCollection.cs
- streamingZipPartStream.cs
- DesignerActionTextItem.cs
- DataRow.cs
- BinaryReader.cs
- HtmlInputText.cs
- BaseDataBoundControl.cs
- CodeNamespace.cs
- Ticks.cs
- DisplayNameAttribute.cs
- DefaultHttpHandler.cs
- ExtensionQuery.cs
- PolicyConversionContext.cs
- DefaultAuthorizationContext.cs
- HtmlForm.cs
- QilLoop.cs
- Pens.cs
- OlePropertyStructs.cs
- WebPartDisplayModeEventArgs.cs
- Codec.cs
- XmlAttributeAttribute.cs
- MD5.cs
- X509ClientCertificateCredentialsElement.cs
- UserControl.cs
- Span.cs
- WorkflowServiceHostFactory.cs
- Unit.cs
- InputReportEventArgs.cs
- ConnectionPointGlyph.cs
- IERequestCache.cs
- Debugger.cs
- AvtEvent.cs
- SqlCommandSet.cs
- _DynamicWinsockMethods.cs
- SchemaNamespaceManager.cs
- SelectingProviderEventArgs.cs
- Parsers.cs
- Section.cs
- SoapProtocolImporter.cs
- altserialization.cs
- XmlEntity.cs
- XmlValidatingReaderImpl.cs
- Tile.cs
- RandomDelayQueuedSendsAsyncResult.cs
- ListViewItemEventArgs.cs
- StateRuntime.cs
- ConfigurationConverterBase.cs
- Span.cs
- DynamicActivityProperty.cs
- contentDescriptor.cs
- ChildTable.cs
- Stacktrace.cs
- PermissionSetTriple.cs
- StylusPointPropertyInfoDefaults.cs
- DataServiceStreamProviderWrapper.cs
- safelink.cs
- JavaScriptObjectDeserializer.cs
- MobileUserControl.cs
- StringCollectionEditor.cs
- WebConfigurationHost.cs
- FormViewDeletedEventArgs.cs
- OperationResponse.cs
- PriorityQueue.cs
- LoginCancelEventArgs.cs
- WindowsRegion.cs
- _KerberosClient.cs
- SafeNativeMethods.cs
- GifBitmapDecoder.cs
- PolyLineSegmentFigureLogic.cs
- CodeGenerator.cs
- Splitter.cs
- ThreadWorkerController.cs
- NotifyParentPropertyAttribute.cs
- Literal.cs
- PerformanceCounterManager.cs
- DesignBindingValueUIHandler.cs
- IOException.cs
- SchemaSetCompiler.cs
- CustomCredentialPolicy.cs
- ViewStateModeByIdAttribute.cs
- QualifiedCellIdBoolean.cs
- ExtractorMetadata.cs
- BrowserCapabilitiesCompiler.cs
- HtmlInputCheckBox.cs
- MenuItemAutomationPeer.cs
- ObjectHandle.cs
- WebPartConnectionsCancelVerb.cs
- BindingContext.cs
- ServiceHttpHandlerFactory.cs
- PersonalizationStateInfoCollection.cs
- PhonemeEventArgs.cs