Code:
/ WCF / WCF / 3.5.30729.1 / untmp / Orcas / SP / ndp / cdf / src / NetFx35 / System.ServiceModel.Web / System / Runtime / Serialization / Json / JsonEncodingStreamWrapper.cs / 1 / JsonEncodingStreamWrapper.cs
//------------------------------------------------------------ // Copyright (c) Microsoft Corporation. All rights reserved. //----------------------------------------------------------- #pragma warning disable 1634 // Stops compiler from warning about unknown warnings (for Presharp) namespace System.Runtime.Serialization.Json { using System.IO; using System.ServiceModel; using System.Text; using System.Xml; using System.Security; // This wrapper does not support seek. // Supports: UTF-8, Unicode, BigEndianUnicode // ASSUMPTION ([....]): This class will only be used for EITHER reading OR writing. It can be done, it would just mean more buffers. class JsonEncodingStreamWrapper : Stream { //// Review - Static fields are marked SecurityCritical or readonly to prevent // data from being modified or leaked to other components in appdomain. // [SecurityRequiresReview] static readonly UnicodeEncoding SafeBEUTF16 = new UnicodeEncoding(true, false, false); //// Review - Static fields are marked SecurityCritical or readonly to prevent // data from being modified or leaked to other components in appdomain. // [SecurityRequiresReview] static readonly UnicodeEncoding SafeUTF16 = new UnicodeEncoding(false, false, false); //// Review - Static fields are marked SecurityCritical or readonly to prevent // data from being modified or leaked to other components in appdomain. // [SecurityRequiresReview] static readonly UTF8Encoding SafeUTF8 = new UTF8Encoding(false, false); //// Review - Static fields are marked SecurityCritical or readonly to prevent // data from being modified or leaked to other components in appdomain. // [SecurityRequiresReview] static readonly UnicodeEncoding ValidatingBEUTF16 = new UnicodeEncoding(true, false, true); //// Review - Static fields are marked SecurityCritical or readonly to prevent // data from being modified or leaked to other components in appdomain. // [SecurityRequiresReview] static readonly UnicodeEncoding ValidatingUTF16 = new UnicodeEncoding(false, false, true); //// Review - Static fields are marked SecurityCritical or readonly to prevent // data from being modified or leaked to other components in appdomain. // [SecurityRequiresReview] static readonly UTF8Encoding ValidatingUTF8 = new UTF8Encoding(false, true); const int BufferLength = 128; byte[] byteBuffer = new byte[1]; int byteCount; int byteOffset; byte[] bytes; char[] chars; Decoder dec; Encoder enc; Encoding encoding; SupportedEncoding encodingCode; bool isReading; Stream stream; public JsonEncodingStreamWrapper(Stream stream, Encoding encoding, bool isReader) { this.isReading = isReader; if (isReader) { InitForReading(stream, encoding); } else { if (encoding == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("encoding"); } InitForWriting(stream, encoding); } } enum SupportedEncoding { UTF8, UTF16LE, UTF16BE, None } // This stream wrapper does not support duplex public override bool CanRead { get { if (!isReading) { return false; } return this.stream.CanRead; } } // The encoding conversion and buffering breaks seeking. public override bool CanSeek { get {return false; } } // Delegate properties public override bool CanTimeout { get {return this.stream.CanTimeout; } } // This stream wrapper does not support duplex public override bool CanWrite { get { if (isReading) { return false; } return this.stream.CanWrite; } } public override long Length { get {return this.stream.Length; } } // The encoding conversion and buffering breaks seeking. public override long Position { get { #pragma warning suppress 56503 // The contract for non seekable stream is to throw exception throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException()); } set {throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException()); } } public override int ReadTimeout { get {return this.stream.ReadTimeout; } set {this.stream.ReadTimeout = value; } } public override int WriteTimeout { get {return this.stream.WriteTimeout; } set {this.stream.WriteTimeout = value; } } public static ArraySegmentProcessBuffer(byte[] buffer, int offset, int count, Encoding encoding) { try { SupportedEncoding expectedEnc = GetSupportedEncoding(encoding); SupportedEncoding dataEnc; if (count < 2) { dataEnc = SupportedEncoding.UTF8; } else { dataEnc = ReadEncoding(buffer[offset], buffer[offset + 1]); } if ((expectedEnc != SupportedEncoding.None) && (expectedEnc != dataEnc)) { ThrowExpectedEncodingMismatch(expectedEnc, dataEnc); } // Fastpath: UTF-8 if (dataEnc == SupportedEncoding.UTF8) { return new ArraySegment (buffer, offset, count); } // Convert to UTF-8 return new ArraySegment (ValidatingUTF8.GetBytes(GetEncoding(dataEnc).GetChars(buffer, offset, count))); } catch (DecoderFallbackException e) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( new XmlException(SR2.GetString(SR2.JsonInvalidBytes), e)); } } public override void Close() { Flush(); base.Close(); this.stream.Close(); } public override void Flush() { this.stream.Flush(); } public override int Read(byte[] buffer, int offset, int count) { try { if (byteCount == 0) { if (encodingCode == SupportedEncoding.UTF8) { return this.stream.Read(buffer, offset, count); } // No more bytes than can be turned into characters byteOffset = 0; byteCount = this.stream.Read(bytes, byteCount, (chars.Length - 1) * 2); // Check for end of stream if (byteCount == 0) { return 0; } // Fix up incomplete chars CleanupCharBreak(); // Change encoding int charCount = this.encoding.GetChars(bytes, 0, byteCount, chars, 0); byteCount = Encoding.UTF8.GetBytes(chars, 0, charCount, bytes, 0); } // Give them bytes if (byteCount < count) { count = byteCount; } Buffer.BlockCopy(bytes, byteOffset, buffer, offset, count); byteOffset += count; byteCount -= count; return count; } catch (DecoderFallbackException ex) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( new XmlException(SR2.GetString(SR2.JsonInvalidBytes), ex)); } } public override int ReadByte() { if (byteCount == 0 && encodingCode == SupportedEncoding.UTF8) { return this.stream.ReadByte(); } if (Read(byteBuffer, 0, 1) == 0) { return -1; } return byteBuffer[0]; } public override long Seek(long offset, SeekOrigin origin) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException()); } // Delegate methods public override void SetLength(long value) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException()); } public override void Write(byte[] buffer, int offset, int count) { // Optimize UTF-8 case if (encodingCode == SupportedEncoding.UTF8) { this.stream.Write(buffer, offset, count); return; } while (count > 0) { int size = chars.Length < count ? chars.Length : count; int charCount = dec.GetChars(buffer, offset, size, chars, 0, false); byteCount = enc.GetBytes(chars, 0, charCount, bytes, 0, false); this.stream.Write(bytes, 0, byteCount); offset += size; count -= size; } } public override void WriteByte(byte b) { if (encodingCode == SupportedEncoding.UTF8) { this.stream.WriteByte(b); return; } byteBuffer[0] = b; Write(byteBuffer, 0, 1); } static Encoding GetEncoding(SupportedEncoding e) { switch (e) { case SupportedEncoding.UTF8: return ValidatingUTF8; case SupportedEncoding.UTF16LE: return ValidatingUTF16; case SupportedEncoding.UTF16BE: return ValidatingBEUTF16; default: throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( new XmlException(SR2.GetString(SR2.JsonEncodingNotSupported))); } } static string GetEncodingName(SupportedEncoding enc) { switch (enc) { case SupportedEncoding.UTF8: return "utf-8"; case SupportedEncoding.UTF16LE: return "utf-16LE"; case SupportedEncoding.UTF16BE: return "utf-16BE"; default: throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( new XmlException(SR2.GetString(SR2.JsonEncodingNotSupported))); } } static SupportedEncoding GetSupportedEncoding(Encoding encoding) { if (encoding == null) { return SupportedEncoding.None; } if (encoding.WebName == ValidatingUTF8.WebName) { return SupportedEncoding.UTF8; } else if (encoding.WebName == ValidatingUTF16.WebName) { return SupportedEncoding.UTF16LE; } else if (encoding.WebName == ValidatingBEUTF16.WebName) { return SupportedEncoding.UTF16BE; } else { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( new XmlException(SR2.GetString(SR2.JsonEncodingNotSupported))); } } static SupportedEncoding ReadEncoding(byte b1, byte b2) { if (b1 == 0x00 && b2 != 0x00) { return SupportedEncoding.UTF16BE; } else if (b1 != 0x00 && b2 == 0x00) { // 857 It's possible to misdetect UTF-32LE as UTF-16LE, but that's OK. return SupportedEncoding.UTF16LE; } else if (b1 == 0x00 && b2 == 0x00) { // UTF-32BE not supported throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new XmlException(SR2.GetString(SR2.JsonInvalidBytes))); } else { return SupportedEncoding.UTF8; } } static void ThrowExpectedEncodingMismatch(SupportedEncoding expEnc, SupportedEncoding actualEnc) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new XmlException(SR2.GetString(SR2.JsonExpectedEncoding, GetEncodingName(expEnc), GetEncodingName(actualEnc)))); } void CleanupCharBreak() { int max = byteOffset + byteCount; // Read on 2 byte boundaries if ((byteCount % 2) != 0) { int b = this.stream.ReadByte(); if (b < 0) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( new XmlException(SR2.GetString(SR2.JsonUnexpectedEndOfFile))); } bytes[max++] = (byte) b; byteCount++; } // Don't cut off a surrogate character int w; if (encodingCode == SupportedEncoding.UTF16LE) { w = bytes[max - 2] + (bytes[max - 1] << 8); } else { w = bytes[max - 1] + (bytes[max - 2] << 8); } if ((w & 0xDC00) != 0xDC00 && w >= 0xD800 && w <= 0xDBFF) // First 16-bit number of surrogate pair { int b1 = this.stream.ReadByte(); int b2 = this.stream.ReadByte(); if (b2 < 0) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( new XmlException(SR2.GetString(SR2.JsonUnexpectedEndOfFile))); } bytes[max++] = (byte) b1; bytes[max++] = (byte) b2; byteCount += 2; } } void EnsureBuffers() { EnsureByteBuffer(); if (chars == null) { chars = new char[BufferLength]; } } void EnsureByteBuffer() { if (bytes != null) { return; } bytes = new byte[BufferLength * 4]; byteOffset = 0; byteCount = 0; } void FillBuffer(int count) { count -= byteCount; while (count > 0) { int read = stream.Read(bytes, byteOffset + byteCount, count); if (read == 0) { break; } byteCount += read; count -= read; } } void InitForReading(Stream inputStream, Encoding expectedEncoding) { try { this.stream = new BufferedStream(inputStream); SupportedEncoding expectedEnc = GetSupportedEncoding(expectedEncoding); SupportedEncoding dataEnc = ReadEncoding(); if ((expectedEnc != SupportedEncoding.None) && (expectedEnc != dataEnc)) { ThrowExpectedEncodingMismatch(expectedEnc, dataEnc); } // Fastpath: UTF-8 (do nothing) if (dataEnc != SupportedEncoding.UTF8) { // Convert to UTF-8 EnsureBuffers(); FillBuffer((BufferLength - 1) * 2); this.encodingCode = dataEnc; this.encoding = GetEncoding(dataEnc); CleanupCharBreak(); int count = this.encoding.GetChars(bytes, byteOffset, byteCount, chars, 0); byteOffset = 0; byteCount = ValidatingUTF8.GetBytes(chars, 0, count, bytes, 0); } } catch (DecoderFallbackException ex) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( new XmlException(SR2.GetString(SR2.JsonInvalidBytes), ex)); } } void InitForWriting(Stream outputStream, Encoding writeEncoding) { this.encoding = writeEncoding; this.stream = new BufferedStream(outputStream); // Set the encoding code this.encodingCode = GetSupportedEncoding(writeEncoding); if (this.encodingCode != SupportedEncoding.UTF8) { EnsureBuffers(); dec = ValidatingUTF8.GetDecoder(); enc = this.encoding.GetEncoder(); } } SupportedEncoding ReadEncoding() { int b1 = this.stream.ReadByte(); int b2 = this.stream.ReadByte(); EnsureByteBuffer(); SupportedEncoding e; if (b1 == -1) { e = SupportedEncoding.UTF8; byteCount = 0; } else if (b2 == -1) { e = SupportedEncoding.UTF8; bytes[0] = (byte) b1; byteCount = 1; } else { e = ReadEncoding((byte) b1, (byte) b2); bytes[0] = (byte) b1; bytes[1] = (byte) b2; byteCount = 2; } return e; } } } // 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
- CustomAttribute.cs
- ScriptControl.cs
- DirectoryInfo.cs
- ConsoleTraceListener.cs
- RemotingService.cs
- Misc.cs
- HitTestResult.cs
- ListViewItemMouseHoverEvent.cs
- ExceptQueryOperator.cs
- ErrorHandler.cs
- SimpleType.cs
- ServiceReference.cs
- EdmToObjectNamespaceMap.cs
- ReflectEventDescriptor.cs
- WorkflowPageSetupDialog.cs
- PropertyValidationContext.cs
- CaseInsensitiveOrdinalStringComparer.cs
- DebuggerAttributes.cs
- QuaternionAnimationBase.cs
- SelectorAutomationPeer.cs
- Variable.cs
- SpeechEvent.cs
- FormViewInsertEventArgs.cs
- Int64Storage.cs
- DetailsViewInsertEventArgs.cs
- SystemPens.cs
- FileDialogCustomPlaces.cs
- Vector.cs
- __TransparentProxy.cs
- DataControlCommands.cs
- SiteMapNode.cs
- RunWorkerCompletedEventArgs.cs
- XamlInt32CollectionSerializer.cs
- SimpleRecyclingCache.cs
- KeyedCollection.cs
- SqlDataSource.cs
- DataGridViewColumnEventArgs.cs
- GroupBox.cs
- WebCodeGenerator.cs
- ColumnWidthChangingEvent.cs
- SecurityTokenAuthenticator.cs
- HtmlSelectionListAdapter.cs
- Group.cs
- CodeNamespace.cs
- ContainerSelectorActiveEvent.cs
- IResourceProvider.cs
- IWorkflowDebuggerService.cs
- HttpResponseHeader.cs
- IDictionary.cs
- DiscoveryProxy.cs
- Trigger.cs
- SimpleTypesSurrogate.cs
- ColumnTypeConverter.cs
- EDesignUtil.cs
- TextTabProperties.cs
- DataGridViewBand.cs
- XmlHierarchyData.cs
- LazyTextWriterCreator.cs
- ResolveResponseInfo.cs
- MultipartContentParser.cs
- SqlDependency.cs
- UInt32.cs
- XAMLParseException.cs
- XPathDescendantIterator.cs
- DeploymentExceptionMapper.cs
- MembershipPasswordException.cs
- KeyInstance.cs
- ErasingStroke.cs
- ExpressionLexer.cs
- XmlDigitalSignatureProcessor.cs
- IndexedString.cs
- WebHostScriptMappingsInstallComponent.cs
- BufferModesCollection.cs
- ErrorTableItemStyle.cs
- Propagator.JoinPropagator.cs
- TextFragmentEngine.cs
- UseManagedPresentationElement.cs
- PolicyStatement.cs
- InvalidWMPVersionException.cs
- NetDataContractSerializer.cs
- bindurihelper.cs
- TimelineGroup.cs
- WebPartZoneCollection.cs
- PropertyValueChangedEvent.cs
- LocalizationParserHooks.cs
- EntityClassGenerator.cs
- SchemaCreator.cs
- RelOps.cs
- GenericTransactionFlowAttribute.cs
- SourceElementsCollection.cs
- ImageClickEventArgs.cs
- ServiceConfigurationTraceRecord.cs
- ProgressiveCrcCalculatingStream.cs
- Enlistment.cs
- Point.cs
- BooleanProjectedSlot.cs
- ErrorRuntimeConfig.cs
- InputScopeAttribute.cs
- CodeChecksumPragma.cs
- StaticResourceExtension.cs