Code:
/ FX-1434 / FX-1434 / 1.0 / untmp / whidbey / REDBITS / ndp / clr / src / BCL / System / Text / EncoderBestFitFallback.cs / 1 / EncoderBestFitFallback.cs
// ==++==
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
// EncoderBestFitFallback.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.Globalization;
using System.Text;
using System.Threading;
[Serializable()]
internal class InternalEncoderBestFitFallback : EncoderFallback
{
// Our variables
internal Encoding encoding = null;
internal char[] arrayBestFit = null;
internal InternalEncoderBestFitFallback(Encoding encoding)
{
// Need to load our replacement characters table.
this.encoding = encoding;
this.bIsMicrosoftBestFitFallback = true;
}
public override EncoderFallbackBuffer CreateFallbackBuffer()
{
return new InternalEncoderBestFitFallbackBuffer(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)
{
InternalEncoderBestFitFallback that = value as InternalEncoderBestFitFallback;
if (that != null)
{
return (this.encoding.CodePage == that.encoding.CodePage);
}
return (false);
}
public override int GetHashCode()
{
return this.encoding.CodePage;
}
}
internal sealed class InternalEncoderBestFitFallbackBuffer : EncoderFallbackBuffer
{
// Our variables
private char cBestFit = '\0';
private InternalEncoderBestFitFallback oFallback;
private int iCount = -1;
private int iSize;
// 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 InternalEncoderBestFitFallbackBuffer(InternalEncoderBestFitFallback 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.GetBestFitUnicodeToBytesData();
}
}
}
// Fallback methods
public override bool Fallback(char charUnknown, int index)
{
// If we had a buffer already we're being recursive, throw, it's probably at the suspect
// character in our array.
// Shouldn't be able to get here for all of our code pages, table would have to be messed up.
BCLDebug.Assert(iCount < 1, "[InternalEncoderBestFitFallbackBuffer.Fallback(non surrogate)] Fallback char " + ((int)cBestFit).ToString("X4", CultureInfo.InvariantCulture) + " caused recursive fallback");
iCount = iSize = 1;
cBestFit = TryBestFit(charUnknown);
if (cBestFit == '\0')
cBestFit = '?';
return true;
}
public override bool Fallback(char charUnknownHigh, char charUnknownLow, int index)
{
// Double check input surrogate pair
if (!Char.IsHighSurrogate(charUnknownHigh))
throw new ArgumentOutOfRangeException("charUnknownHigh",
Environment.GetResourceString("ArgumentOutOfRange_Range",
0xD800, 0xDBFF));
if (!Char.IsLowSurrogate(charUnknownLow))
throw new ArgumentOutOfRangeException("CharUnknownLow",
Environment.GetResourceString("ArgumentOutOfRange_Range",
0xDC00, 0xDFFF));
// If we had a buffer already we're being recursive, throw, it's probably at the suspect
// character in our array. 0 is processing last character, < 0 is not falling back
// Shouldn't be able to get here, table would have to be messed up.
BCLDebug.Assert(iCount < 1, "[InternalEncoderBestFitFallbackBuffer.Fallback(surrogate)] Fallback char " + ((int)cBestFit).ToString("X4", CultureInfo.InvariantCulture) + " caused recursive fallback");
// Go ahead and get our fallback, surrogates don't have best fit
cBestFit = '?';
iCount = iSize = 2;
return true;
}
// Default version is overridden in EncoderReplacementFallback.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;
charStart = null;
bFallingBack = false;
}
// private helper methods
private char TryBestFit(char cUnknown)
{
// 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;
// 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 we want to be on word boundaries.
// Also note that index can never == highBound (because diff is rounded down)
index = ((iDiff / 2) + lowBound) & 0xFFFE;
char cTest = oFallback.arrayBestFit[index];
if (cTest == cUnknown)
{
// We found it
BCLDebug.Assert(index + 1 < oFallback.arrayBestFit.Length,
"[InternalEncoderBestFitFallbackBuffer.TryBestFit]Expected replacement character at end of array");
return oFallback.arrayBestFit[index + 1];
}
else if (cTest < cUnknown)
{
// 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] == cUnknown)
{
// We found it
BCLDebug.Assert(index + 1 < oFallback.arrayBestFit.Length,
"[InternalEncoderBestFitFallbackBuffer.TryBestFit]Expected replacement character at end of array");
return oFallback.arrayBestFit[index + 1];
}
}
// Char wasn't in our table
return '\0';
}
}
}
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- HashAlgorithm.cs
- CounterSample.cs
- KeyManager.cs
- ImportedPolicyConversionContext.cs
- ToolStripControlHost.cs
- DependencyObjectProvider.cs
- XslCompiledTransform.cs
- UdpChannelListener.cs
- PackWebResponse.cs
- DataSourceControlBuilder.cs
- DocumentViewerAutomationPeer.cs
- LinkLabel.cs
- SmiXetterAccessMap.cs
- TransformerInfoCollection.cs
- HashRepartitionStream.cs
- QuaternionConverter.cs
- Point4DConverter.cs
- RepeatInfo.cs
- Vector3D.cs
- WebServiceParameterData.cs
- EraserBehavior.cs
- StateItem.cs
- OdbcConnectionOpen.cs
- RIPEMD160Managed.cs
- ReadOnlyActivityGlyph.cs
- ITextView.cs
- MarkupWriter.cs
- DetailsViewDeleteEventArgs.cs
- HttpStreamMessageEncoderFactory.cs
- ObjectDataSourceDisposingEventArgs.cs
- DesignTimeResourceProviderFactoryAttribute.cs
- DocumentPage.cs
- RC2.cs
- TextRangeAdaptor.cs
- MutexSecurity.cs
- UserCancellationException.cs
- LinkLabel.cs
- DataGridView.cs
- DesignTimeResourceProviderFactoryAttribute.cs
- TableHeaderCell.cs
- PnrpPermission.cs
- CacheVirtualItemsEvent.cs
- TextureBrush.cs
- EdmComplexTypeAttribute.cs
- CookieHandler.cs
- SoapProtocolReflector.cs
- StorageMappingItemCollection.cs
- LinqDataSourceSelectEventArgs.cs
- UriWriter.cs
- Size3D.cs
- WebPartAuthorizationEventArgs.cs
- FixedSOMFixedBlock.cs
- String.cs
- LockCookie.cs
- Decimal.cs
- LongTypeConverter.cs
- HuffCodec.cs
- CanonicalFontFamilyReference.cs
- ConfigPathUtility.cs
- GenericUriParser.cs
- LinqDataSourceSelectEventArgs.cs
- BaseTemplateParser.cs
- TransactedReceiveScope.cs
- ItemsChangedEventArgs.cs
- DropShadowEffect.cs
- ChannelEndpointElementCollection.cs
- TrackingRecord.cs
- WorkflowCompensationBehavior.cs
- ToolStripRenderEventArgs.cs
- ThreadNeutralSemaphore.cs
- QuaternionIndependentAnimationStorage.cs
- SecurityRuntime.cs
- ToolStripContentPanelRenderEventArgs.cs
- DeviceContext.cs
- CustomValidator.cs
- MdImport.cs
- PathTooLongException.cs
- TileModeValidation.cs
- ContextStack.cs
- SafeFileMappingHandle.cs
- ContextQuery.cs
- AccessViolationException.cs
- RegistrySecurity.cs
- EditCommandColumn.cs
- ConnectionsZone.cs
- ZipIOLocalFileBlock.cs
- ProjectionPlanCompiler.cs
- WsdlParser.cs
- GenerateHelper.cs
- CaseStatementSlot.cs
- MethodBuilderInstantiation.cs
- ToolStripTextBox.cs
- Matrix3DConverter.cs
- CategoryList.cs
- _AutoWebProxyScriptWrapper.cs
- CharacterShapingProperties.cs
- EntityContainerEntitySet.cs
- PickBranch.cs
- EntityDataSourceColumn.cs
- RuntimeConfigLKG.cs