Code:
/ Dotnetfx_Win7_3.5.1 / Dotnetfx_Win7_3.5.1 / 3.5.1 / DEVDIV / depot / DevDiv / releases / whidbey / NetFXspW7 / ndp / clr / src / BCL / System / Text / DecoderBestFitFallback.cs / 1 / DecoderBestFitFallback.cs
// ==++== // // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== // DecoderBestFitFallback.cs // // This is used internally to create best fit behavior as per the original windows best fit behavior. // namespace System.Text { using System; using System.Text; using System.Threading; [Serializable()] internal sealed class InternalDecoderBestFitFallback : DecoderFallback { // Our variables internal Encoding encoding = null; internal char[] arrayBestFit = null; internal char cReplacement = '?'; internal InternalDecoderBestFitFallback(Encoding encoding) { // Need to load our replacement characters table. this.encoding = encoding; this.bIsMicrosoftBestFitFallback = true; } public override DecoderFallbackBuffer CreateFallbackBuffer() { return new InternalDecoderBestFitFallbackBuffer(this); } // Maximum number of characters that this instance of this fallback could return public override int MaxCharCount { get { return 1; } } public override bool Equals(Object value) { InternalDecoderBestFitFallback that = value as InternalDecoderBestFitFallback; if (that != null) { return (this.encoding.CodePage == that.encoding.CodePage); } return (false); } public override int GetHashCode() { return this.encoding.CodePage; } } internal sealed class InternalDecoderBestFitFallbackBuffer : DecoderFallbackBuffer { // Our variables internal char cBestFit = '\0'; internal int iCount = -1; internal int iSize; private InternalDecoderBestFitFallback oFallback; // Private object for locking instead of locking on a public type for SQL reliability work. private static Object s_InternalSyncObject; private static Object InternalSyncObject { get { if (s_InternalSyncObject == null) { Object o = new Object(); Interlocked.CompareExchange(ref s_InternalSyncObject, o, null); } return s_InternalSyncObject; } } // Constructor public InternalDecoderBestFitFallbackBuffer(InternalDecoderBestFitFallback fallback) { this.oFallback = fallback; if (oFallback.arrayBestFit == null) { // Lock so we don't confuse ourselves. lock(InternalSyncObject) { // Double check before we do it again. if (oFallback.arrayBestFit == null) oFallback.arrayBestFit = fallback.encoding.GetBestFitBytesToUnicodeData(); } } } // Fallback methods public override bool Fallback(byte[] bytesUnknown, int index) { // We expect no previous fallback in our buffer BCLDebug.Assert(iCount < 1, "[DecoderReplacementFallbackBuffer.Fallback] Calling fallback without a previously empty buffer"); cBestFit = TryBestFit(bytesUnknown); if (cBestFit == '\0') cBestFit = oFallback.cReplacement; iCount = iSize = 1; return true; } // Default version is overridden in DecoderReplacementFallback.cs public override char GetNextChar() { // Just return cReturn, which is 0 if there's no best fit for it. return (iCount-- > 0) ? cBestFit : '\0'; } public override bool MovePrevious() { // Exception fallback doesn't have anywhere to back up to. if (iCount >= 0) iCount++; // Return true if we could do it. return (iCount >= 0 && iCount <= iSize); } // How many characters left to output? public override int Remaining { get { return (iCount > 0) ? iCount : 0; } } // Clear the buffer public override unsafe void Reset() { iCount = -1; byteStart = null; } // This version just counts the fallback and doesn't actually copy anything. internal unsafe override int InternalFallback(byte[] bytes, byte* pBytes) // Right now this has both bytes and bytes[], which is ----, but we might have extra bytes, hence the // array, and we might need the index, hence the byte* { // return our replacement string Length (always 1 for InternalDecoderBestFitFallback, either // a best fit char or ? return 1; } // private helper methods private char TryBestFit(byte[] bytesCheck) { // Need to figure out our best fit character, low is beginning of array, high is 1 AFTER end of array int lowBound = 0; int highBound = oFallback.arrayBestFit.Length; int index; char cCheck; // Check trivial case first (no best fit) if (highBound == 0) return '\0'; // If our array is too small or too big we can't check if (bytesCheck.Length == 0 || bytesCheck.Length > 2) return '\0'; if (bytesCheck.Length == 1) cCheck = unchecked((char)bytesCheck[0]); else cCheck = unchecked((char)((bytesCheck[0] << 8) + bytesCheck[1])); // Check trivial out of range case if (cCheck < oFallback.arrayBestFit[0] || cCheck > oFallback.arrayBestFit[highBound - 2]) return '\0'; // Binary search the array int iDiff; while ((iDiff = (highBound - lowBound)) > 6) { // Look in the middle, which is complicated by the fact that we have 2 #s for each pair, // so we don't want index to be odd because it must be word aligned. // Also note that index can never == highBound (because diff is rounded down) index = ((iDiff / 2) + lowBound) & 0xFFFE; char cTest = oFallback.arrayBestFit[index]; if (cTest == cCheck) { // We found it BCLDebug.Assert(index + 1 < oFallback.arrayBestFit.Length, "[InternalDecoderBestFitFallbackBuffer.TryBestFit]Expected replacement character at end of array"); return oFallback.arrayBestFit[index + 1]; } else if (cTest < cCheck) { // We weren't high enough lowBound = index; } else { // We weren't low enough highBound = index; } } for (index = lowBound; index < highBound; index += 2) { if (oFallback.arrayBestFit[index] == cCheck) { // We found it BCLDebug.Assert(index + 1 < oFallback.arrayBestFit.Length, "[InternalDecoderBestFitFallbackBuffer.TryBestFit]Expected replacement character at end of array"); return oFallback.arrayBestFit[index + 1]; } } // Char wasn't in our table return '\0'; } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // ==++== // // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== // DecoderBestFitFallback.cs // // This is used internally to create best fit behavior as per the original windows best fit behavior. // namespace System.Text { using System; using System.Text; using System.Threading; [Serializable()] internal sealed class InternalDecoderBestFitFallback : DecoderFallback { // Our variables internal Encoding encoding = null; internal char[] arrayBestFit = null; internal char cReplacement = '?'; internal InternalDecoderBestFitFallback(Encoding encoding) { // Need to load our replacement characters table. this.encoding = encoding; this.bIsMicrosoftBestFitFallback = true; } public override DecoderFallbackBuffer CreateFallbackBuffer() { return new InternalDecoderBestFitFallbackBuffer(this); } // Maximum number of characters that this instance of this fallback could return public override int MaxCharCount { get { return 1; } } public override bool Equals(Object value) { InternalDecoderBestFitFallback that = value as InternalDecoderBestFitFallback; if (that != null) { return (this.encoding.CodePage == that.encoding.CodePage); } return (false); } public override int GetHashCode() { return this.encoding.CodePage; } } internal sealed class InternalDecoderBestFitFallbackBuffer : DecoderFallbackBuffer { // Our variables internal char cBestFit = '\0'; internal int iCount = -1; internal int iSize; private InternalDecoderBestFitFallback oFallback; // Private object for locking instead of locking on a public type for SQL reliability work. private static Object s_InternalSyncObject; private static Object InternalSyncObject { get { if (s_InternalSyncObject == null) { Object o = new Object(); Interlocked.CompareExchange(ref s_InternalSyncObject, o, null); } return s_InternalSyncObject; } } // Constructor public InternalDecoderBestFitFallbackBuffer(InternalDecoderBestFitFallback fallback) { this.oFallback = fallback; if (oFallback.arrayBestFit == null) { // Lock so we don't confuse ourselves. lock(InternalSyncObject) { // Double check before we do it again. if (oFallback.arrayBestFit == null) oFallback.arrayBestFit = fallback.encoding.GetBestFitBytesToUnicodeData(); } } } // Fallback methods public override bool Fallback(byte[] bytesUnknown, int index) { // We expect no previous fallback in our buffer BCLDebug.Assert(iCount < 1, "[DecoderReplacementFallbackBuffer.Fallback] Calling fallback without a previously empty buffer"); cBestFit = TryBestFit(bytesUnknown); if (cBestFit == '\0') cBestFit = oFallback.cReplacement; iCount = iSize = 1; return true; } // Default version is overridden in DecoderReplacementFallback.cs public override char GetNextChar() { // Just return cReturn, which is 0 if there's no best fit for it. return (iCount-- > 0) ? cBestFit : '\0'; } public override bool MovePrevious() { // Exception fallback doesn't have anywhere to back up to. if (iCount >= 0) iCount++; // Return true if we could do it. return (iCount >= 0 && iCount <= iSize); } // How many characters left to output? public override int Remaining { get { return (iCount > 0) ? iCount : 0; } } // Clear the buffer public override unsafe void Reset() { iCount = -1; byteStart = null; } // This version just counts the fallback and doesn't actually copy anything. internal unsafe override int InternalFallback(byte[] bytes, byte* pBytes) // Right now this has both bytes and bytes[], which is ----, but we might have extra bytes, hence the // array, and we might need the index, hence the byte* { // return our replacement string Length (always 1 for InternalDecoderBestFitFallback, either // a best fit char or ? return 1; } // private helper methods private char TryBestFit(byte[] bytesCheck) { // Need to figure out our best fit character, low is beginning of array, high is 1 AFTER end of array int lowBound = 0; int highBound = oFallback.arrayBestFit.Length; int index; char cCheck; // Check trivial case first (no best fit) if (highBound == 0) return '\0'; // If our array is too small or too big we can't check if (bytesCheck.Length == 0 || bytesCheck.Length > 2) return '\0'; if (bytesCheck.Length == 1) cCheck = unchecked((char)bytesCheck[0]); else cCheck = unchecked((char)((bytesCheck[0] << 8) + bytesCheck[1])); // Check trivial out of range case if (cCheck < oFallback.arrayBestFit[0] || cCheck > oFallback.arrayBestFit[highBound - 2]) return '\0'; // Binary search the array int iDiff; while ((iDiff = (highBound - lowBound)) > 6) { // Look in the middle, which is complicated by the fact that we have 2 #s for each pair, // so we don't want index to be odd because it must be word aligned. // Also note that index can never == highBound (because diff is rounded down) index = ((iDiff / 2) + lowBound) & 0xFFFE; char cTest = oFallback.arrayBestFit[index]; if (cTest == cCheck) { // We found it BCLDebug.Assert(index + 1 < oFallback.arrayBestFit.Length, "[InternalDecoderBestFitFallbackBuffer.TryBestFit]Expected replacement character at end of array"); return oFallback.arrayBestFit[index + 1]; } else if (cTest < cCheck) { // We weren't high enough lowBound = index; } else { // We weren't low enough highBound = index; } } for (index = lowBound; index < highBound; index += 2) { if (oFallback.arrayBestFit[index] == cCheck) { // We found it BCLDebug.Assert(index + 1 < oFallback.arrayBestFit.Length, "[InternalDecoderBestFitFallbackBuffer.TryBestFit]Expected replacement character at end of array"); return oFallback.arrayBestFit[index + 1]; } } // Char wasn't in our table return '\0'; } } } // 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
- ContentPresenter.cs
- EdmProviderManifest.cs
- UIPermission.cs
- InputElement.cs
- TableCell.cs
- InputScopeConverter.cs
- MetabaseServerConfig.cs
- SystemUnicastIPAddressInformation.cs
- HttpApplicationFactory.cs
- DataGridViewColumnEventArgs.cs
- DiscreteKeyFrames.cs
- SizeAnimationBase.cs
- KeyGesture.cs
- BlurEffect.cs
- QueryContinueDragEvent.cs
- ByteStack.cs
- SoapServerProtocol.cs
- DetailsViewPageEventArgs.cs
- Int32AnimationUsingKeyFrames.cs
- PropertyInfoSet.cs
- ToolStripDropTargetManager.cs
- LocalIdKeyIdentifierClause.cs
- ProofTokenCryptoHandle.cs
- UnauthorizedWebPart.cs
- DataServiceRequestOfT.cs
- BrowsableAttribute.cs
- ExternalFile.cs
- XmlQueryStaticData.cs
- WebPartConnectionsCancelVerb.cs
- Tracer.cs
- WaitForChangedResult.cs
- MenuBase.cs
- CheckoutException.cs
- WindowsToolbarItemAsMenuItem.cs
- ArcSegment.cs
- CompilerHelpers.cs
- XsltSettings.cs
- ReaderOutput.cs
- InstalledFontCollection.cs
- TileBrush.cs
- XmlNullResolver.cs
- SchemaExporter.cs
- WizardForm.cs
- EventDescriptorCollection.cs
- Selector.cs
- HtmlControl.cs
- HttpCacheVaryByContentEncodings.cs
- MemberJoinTreeNode.cs
- ThousandthOfEmRealPoints.cs
- StringArrayConverter.cs
- SimpleColumnProvider.cs
- DictionaryBase.cs
- SynchronizingStream.cs
- DoubleUtil.cs
- RemoteHelper.cs
- TypeConstant.cs
- SqlAliasesReferenced.cs
- MailMessageEventArgs.cs
- SQLDateTime.cs
- HtmlTextArea.cs
- TimeStampChecker.cs
- InternalDispatchObject.cs
- StrokeCollection2.cs
- ObfuscationAttribute.cs
- BindingBase.cs
- DispatcherSynchronizationContext.cs
- UnsafeNativeMethods.cs
- DataGridTextBox.cs
- MenuItemBinding.cs
- DataControlField.cs
- Deflater.cs
- MissingSatelliteAssemblyException.cs
- XomlCompilerError.cs
- AuthenticateEventArgs.cs
- DataRowChangeEvent.cs
- Condition.cs
- SafeEventHandle.cs
- DPCustomTypeDescriptor.cs
- LoadMessageLogger.cs
- DataGridViewRowDividerDoubleClickEventArgs.cs
- TraceContextRecord.cs
- StructuredProperty.cs
- DataGridViewComboBoxEditingControl.cs
- SqlRemoveConstantOrderBy.cs
- JpegBitmapEncoder.cs
- ObjectStateFormatter.cs
- SimpleTextLine.cs
- SystemWebExtensionsSectionGroup.cs
- UIElement.cs
- PenThreadPool.cs
- Hash.cs
- PartitionResolver.cs
- StrokeFIndices.cs
- HandlerBase.cs
- DiagnosticTraceSchemas.cs
- ScriptingJsonSerializationSection.cs
- CqlQuery.cs
- EntityReference.cs
- WebEventCodes.cs
- StrokeNodeOperations2.cs