Code:
/ WCF / WCF / 3.5.30729.1 / untmp / Orcas / SP / ndp / cdf / src / WCF / Serialization / System / Xml / XmlStreamNodeWriter.cs / 1 / XmlStreamNodeWriter.cs
//------------------------------------------------------------ // Copyright (c) Microsoft Corporation. All rights reserved. //----------------------------------------------------------- namespace System.Xml { using System.IO; using System.Collections.Generic; using System.Text; using System.Diagnostics; using System.Globalization; using System.Runtime.Serialization; using System.Security; abstract class XmlStreamNodeWriter : XmlNodeWriter { Stream stream; byte[] buffer; int offset; bool ownsStream; const int bufferLength = 512; const int maxEntityLength = 32; const int maxBytesPerChar = 3; static UTF8Encoding UTF8Encoding = new UTF8Encoding(false, true); protected XmlStreamNodeWriter() { this.buffer = new byte[bufferLength]; } protected void SetOutput(Stream stream, bool ownsStream) { this.stream = stream; this.ownsStream = ownsStream; this.offset = 0; } // Getting/Setting the Stream exists for fragmenting public Stream Stream { get { return stream; } set { stream = value; } } // StreamBuffer/BufferOffset exists only for the BinaryWriter to fix up nodes public byte[] StreamBuffer { get { return buffer; } } public int BufferOffset { get { return offset; } } public int Position { get { return (int)stream.Position + offset; } } protected byte[] GetBuffer(int count, out int offset) { DiagnosticUtility.DebugAssert(count >= 0 && count <= bufferLength, ""); int bufferOffset = this.offset; if (bufferOffset + count <= bufferLength) { offset = bufferOffset; } else { FlushBuffer(); offset = 0; } #if DEBUG DiagnosticUtility.DebugAssert(offset + count <= bufferLength, ""); for (int i = 0; i < count; i++) { buffer[offset + i] = (byte)'<'; } #endif return buffer; } protected void Advance(int count) { DiagnosticUtility.DebugAssert(offset + count <= bufferLength, ""); offset += count; } void EnsureByte() { if (offset >= bufferLength) { FlushBuffer(); } } protected void WriteByte(byte b) { EnsureByte(); buffer[offset++] = b; } protected void WriteByte(char ch) { DiagnosticUtility.DebugAssert(ch < 0x80, ""); WriteByte((byte)ch); } protected void WriteBytes(byte b1, byte b2) { byte[] buffer = this.buffer; int offset = this.offset; if (offset + 1 >= bufferLength) { FlushBuffer(); offset = 0; } buffer[offset + 0] = b1; buffer[offset + 1] = b2; this.offset += 2; } protected void WriteBytes(char ch1, char ch2) { DiagnosticUtility.DebugAssert(ch1 < 0x80 && ch2 < 0x80, ""); WriteBytes((byte)ch1, (byte)ch2); } public void WriteBytes(byte[] byteBuffer, int byteOffset, int byteCount) { if (byteCount < bufferLength) { int offset; byte[] buffer = GetBuffer(byteCount, out offset); Buffer.BlockCopy(byteBuffer, byteOffset, buffer, offset, byteCount); Advance(byteCount); } else { FlushBuffer(); stream.Write(byteBuffer, byteOffset, byteCount); } } ////// Critical - contains unsafe code /// caller needs to validate arguments /// [SecurityCritical] unsafe protected void UnsafeWriteBytes(byte* bytes, int byteCount) { FlushBuffer(); byte[] buffer = this.buffer; while (byteCount >= bufferLength) { for (int i = 0; i < bufferLength; i++) buffer[i] = bytes[i]; stream.Write(buffer, 0, bufferLength); bytes += bufferLength; byteCount -= bufferLength; } { for (int i = 0; i < byteCount; i++) buffer[i] = bytes[i]; stream.Write(buffer, 0, byteCount); } } ////// Critical - contains unsafe code /// Safe - unsafe code is effectively encapsulated, all inputs are validated /// [SecurityCritical, SecurityTreatAsSafe] unsafe protected void WriteUTF8Char(int ch) { if (ch < 0x80) { WriteByte((byte)ch); } else if (ch <= char.MaxValue) { char* chars = stackalloc char[1]; chars[0] = (char)ch; UnsafeWriteUTF8Chars(chars, 1); } else { SurrogateChar surrogateChar = new SurrogateChar(ch); char* chars = stackalloc char[2]; chars[0] = surrogateChar.HighChar; chars[1] = surrogateChar.LowChar; UnsafeWriteUTF8Chars(chars, 2); } } protected void WriteUTF8Chars(byte[] chars, int charOffset, int charCount) { if (charCount < bufferLength) { int offset; byte[] buffer = GetBuffer(charCount, out offset); Buffer.BlockCopy(chars, charOffset, buffer, offset, charCount); Advance(charCount); } else { FlushBuffer(); stream.Write(chars, charOffset, charCount); } } ////// Critical - contains unsafe code /// Safe - unsafe code is effectively encapsulated, all inputs are validated /// [SecurityCritical, SecurityTreatAsSafe] unsafe protected void WriteUTF8Chars(string value) { int count = value.Length; if (count > 0) { fixed (char* chars = value) { UnsafeWriteUTF8Chars(chars, count); } } } ////// Critical - contains unsafe code /// caller needs to validate arguments /// [SecurityCritical] unsafe protected void UnsafeWriteUTF8Chars(char* chars, int charCount) { const int charChunkSize = bufferLength / maxBytesPerChar; while (charCount > charChunkSize) { int offset; int chunkSize = charChunkSize; if ((int)(chars[chunkSize - 1] & 0xFC00) == 0xD800) // This is a high surrogate chunkSize--; byte[] buffer = GetBuffer(chunkSize * maxBytesPerChar, out offset); Advance(UnsafeGetUTF8Chars(chars, chunkSize, buffer, offset)); charCount -= chunkSize; chars += chunkSize; } if (charCount > 0) { int offset; byte[] buffer = GetBuffer(charCount * maxBytesPerChar, out offset); Advance(UnsafeGetUTF8Chars(chars, charCount, buffer, offset)); } } ////// Critical - contains unsafe code /// caller needs to validate arguments /// [SecurityCritical] unsafe protected void UnsafeWriteUnicodeChars(char* chars, int charCount) { const int charChunkSize = bufferLength / 2; while (charCount > charChunkSize) { int offset; int chunkSize = charChunkSize; if ((int)(chars[chunkSize - 1] & 0xFC00) == 0xD800) // This is a high surrogate chunkSize--; byte[] buffer = GetBuffer(chunkSize * 2, out offset); Advance(UnsafeGetUnicodeChars(chars, chunkSize, buffer, offset)); charCount -= chunkSize; chars += chunkSize; } if (charCount > 0) { int offset; byte[] buffer = GetBuffer(charCount * 2, out offset); Advance(UnsafeGetUnicodeChars(chars, charCount, buffer, offset)); } } ////// Critical - contains unsafe code /// caller needs to validate arguments /// [SecurityCritical] unsafe protected int UnsafeGetUnicodeChars(char* chars, int charCount, byte[] buffer, int offset) { char* charsMax = chars + charCount; while (chars < charsMax) { char value = *chars++; buffer[offset++] = (byte)value; value >>= 8; buffer[offset++] = (byte)value; } return charCount * 2; } ////// Critical - contains unsafe code /// caller needs to validate arguments /// [SecurityCritical] unsafe protected int UnsafeGetUTF8Length(char* chars, int charCount) { char* charsMax = chars + charCount; while (chars < charsMax) { if (*chars >= 0x80) break; chars++; } if (chars == charsMax) return charCount; return (int)(chars - (charsMax - charCount)) + UTF8Encoding.GetByteCount(chars, (int)(charsMax - chars)); } ////// Critical - contains unsafe code /// caller needs to validate arguments /// [SecurityCritical] unsafe protected int UnsafeGetUTF8Chars(char* chars, int charCount, byte[] buffer, int offset) { if (charCount > 0) { fixed (byte* _bytes = &buffer[offset]) { byte* bytes = _bytes; byte* bytesMax = &bytes[buffer.Length - offset]; char* charsMax = &chars[charCount]; while (true) { while (chars < charsMax && *chars < 0x80) { *bytes = (byte)*chars; bytes++; chars++; } if (chars >= charsMax) break; char* charsStart = chars; while (chars < charsMax && *chars >= 0x80) { chars++; } bytes += UTF8Encoding.GetBytes(charsStart, (int)(chars - charsStart), bytes, (int)(bytesMax - bytes)); if (chars >= charsMax) break; } return (int)(bytes - _bytes); } } return 0; } protected virtual void FlushBuffer() { if (offset != 0) { stream.Write(buffer, 0, offset); offset = 0; } } public override void Flush() { FlushBuffer(); stream.Flush(); } public override void Close() { if (stream != null) { if (ownsStream) { stream.Close(); } stream = null; } } } } // 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
- TextServicesLoader.cs
- DataGridItem.cs
- ToolboxService.cs
- DbProviderFactories.cs
- AppSettings.cs
- SafeFileMappingHandle.cs
- HTMLTextWriter.cs
- OrderedDictionaryStateHelper.cs
- DictionaryKeyPropertyAttribute.cs
- ChineseLunisolarCalendar.cs
- PeerContact.cs
- XPathPatternParser.cs
- SimpleBitVector32.cs
- ColumnMapTranslator.cs
- XmlWriterTraceListener.cs
- EventDescriptor.cs
- BinaryCommonClasses.cs
- CLSCompliantAttribute.cs
- SqlMethodAttribute.cs
- StatusBarPanelClickEvent.cs
- XamlTypeMapperSchemaContext.cs
- RsaSecurityToken.cs
- WorkflowRuntimeServiceElementCollection.cs
- FixedSOMTableCell.cs
- CapabilitiesUse.cs
- XmlQueryStaticData.cs
- EventsTab.cs
- DTCTransactionManager.cs
- RecognizerInfo.cs
- SynchronizedCollection.cs
- SharedStream.cs
- InvokeCompletedEventArgs.cs
- ClosableStream.cs
- StringUtil.cs
- StatusBar.cs
- BindingEditor.xaml.cs
- SubclassTypeValidatorAttribute.cs
- TagMapInfo.cs
- EntityChangedParams.cs
- RadialGradientBrush.cs
- TextDecorationCollection.cs
- WinInetCache.cs
- ReturnType.cs
- BitmapEffectRenderDataResource.cs
- FontSourceCollection.cs
- DataServiceBuildProvider.cs
- WhereaboutsReader.cs
- Int64AnimationBase.cs
- ParseNumbers.cs
- XPathNavigatorReader.cs
- FixedTextBuilder.cs
- IgnoreSection.cs
- SQLConvert.cs
- CodePropertyReferenceExpression.cs
- TextBoxAutoCompleteSourceConverter.cs
- DBAsyncResult.cs
- FormViewAutoFormat.cs
- AuthenticationManager.cs
- DataGridViewBand.cs
- AsyncMethodInvoker.cs
- smtpconnection.cs
- SqlRetyper.cs
- XmlILConstructAnalyzer.cs
- BamlRecordReader.cs
- OptimalTextSource.cs
- SpecialFolderEnumConverter.cs
- DynamicDocumentPaginator.cs
- XPathNodeHelper.cs
- dbdatarecord.cs
- SelectionProcessor.cs
- UnsafeNativeMethodsPenimc.cs
- ModuleBuilderData.cs
- StylusPointCollection.cs
- VisualStyleInformation.cs
- RequestCacheManager.cs
- DataException.cs
- WebExceptionStatus.cs
- FullTrustAssemblyCollection.cs
- ToolBar.cs
- SettingsBindableAttribute.cs
- AdRotator.cs
- HMACSHA384.cs
- WebPartHeaderCloseVerb.cs
- ByteStream.cs
- Point3DCollection.cs
- ConfigurationSettings.cs
- ReadWriteObjectLock.cs
- EntityCommandExecutionException.cs
- NumericUpDown.cs
- GeneralTransform3DCollection.cs
- DrawListViewColumnHeaderEventArgs.cs
- SoapHeaderAttribute.cs
- PreviousTrackingServiceAttribute.cs
- GetMemberBinder.cs
- XMLSyntaxException.cs
- SeekableMessageNavigator.cs
- SqlMultiplexer.cs
- QilStrConcatenator.cs
- Transform3DGroup.cs
- RouteParameter.cs