Code:
/ DotNET / DotNET / 8.0 / untmp / whidbey / REDBITS / ndp / clr / src / BCL / System / Text / DecoderFallback.cs / 1 / DecoderFallback.cs
// ==++==
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
//
using System;
using System.Threading;
using System.Globalization;
namespace System.Text
{
[Serializable]
public abstract class DecoderFallback
{
internal bool bIsMicrosoftBestFitFallback = false;
private static DecoderFallback replacementFallback; // Default fallback, uses no best fit & "?"
private static DecoderFallback exceptionFallback;
// Private object for locking instead of locking on a internal 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;
}
}
// Get each of our generic fallbacks.
public static DecoderFallback ReplacementFallback
{
get
{
if (replacementFallback == null)
lock(InternalSyncObject)
if (replacementFallback == null)
replacementFallback = new DecoderReplacementFallback();
return replacementFallback;
}
}
public static DecoderFallback ExceptionFallback
{
get
{
if (exceptionFallback == null)
lock(InternalSyncObject)
if (exceptionFallback == null)
exceptionFallback = new DecoderExceptionFallback();
return exceptionFallback;
}
}
// Fallback
//
// Return the appropriate unicode string alternative to the character that need to fall back.
// Most implimentations will be:
// return new MyCustomDecoderFallbackBuffer(this);
public abstract DecoderFallbackBuffer CreateFallbackBuffer();
// Maximum number of characters that this instance of this fallback could return
public abstract int MaxCharCount { get; }
internal bool IsMicrosoftBestFitFallback
{
get
{
return bIsMicrosoftBestFitFallback;
}
}
}
public abstract class DecoderFallbackBuffer
{
// Most implimentations will probably need an implimenation-specific constructor
// internal methods that cannot be overriden that let us do our fallback thing
// These wrap the internal methods so that we can check for people doing stuff that is incorrect
public abstract bool Fallback(byte[] bytesUnknown, int index);
// Get next character
public abstract char GetNextChar();
// Back up a character
public abstract bool MovePrevious();
// How many chars left in this fallback?
public abstract int Remaining { get; }
// Clear the buffer
public virtual void Reset()
{
while (GetNextChar() != (char)0);
}
// Internal items to help us figure out what we're doing as far as error messages, etc.
// These help us with our performance and messages internally
internal unsafe byte* byteStart = null;
internal unsafe char* charEnd = null;
// Internal Reset
internal unsafe void InternalReset()
{
byteStart = null;
Reset();
}
// Set the above values
// This can't be part of the constructor because DecoderFallbacks would have to know how to impliment these.
internal unsafe void InternalInitialize(byte* byteStart, char* charEnd)
{
this.byteStart = byteStart;
this.charEnd = charEnd;
}
// Fallback the current byte by sticking it into the remaining char buffer.
// This can only be called by our encodings (other have to use the public fallback methods), so
// we can use our DecoderNLS here too (except we don't).
// Returns true if we are successful, false if we can't fallback the character (no buffer space)
// So caller needs to throw buffer space if return false.
// Right now this has both bytes and bytes[], since we might have extra bytes, hence the
// array, and we might need the index, hence the byte*
// Don't touch ref chars unless we succeed
internal unsafe virtual bool InternalFallback(byte[] bytes, byte* pBytes, ref char* chars)
{
// Copy bytes to array (slow, but right now that's what we get to do.
// byte[] bytesUnknown = new byte[count];
// for (int i = 0; i < count; i++)
// bytesUnknown[i] = *(bytes++);
BCLDebug.Assert(byteStart != null, "[DecoderFallback.InternalFallback]Used InternalFallback without calling InternalInitialize");
// See if there's a fallback character and we have an output buffer then copy our string.
if (this.Fallback(bytes, (int)(pBytes - byteStart - bytes.Length)))
{
// Copy the chars to our output
char ch;
char* charTemp = chars;
bool bHighSurrogate = false;
while ((ch = GetNextChar()) != 0)
{
// Make sure no mixed up surrogates
if (Char.IsSurrogate(ch))
{
if (Char.IsHighSurrogate(ch))
{
// High Surrogate
if (bHighSurrogate)
throw new ArgumentException(Environment.GetResourceString("Argument_InvalidCharSequenceNoIndex"));
bHighSurrogate = true;
}
else
{
// Low surrogate
if (bHighSurrogate == false)
throw new ArgumentException(Environment.GetResourceString("Argument_InvalidCharSequenceNoIndex"));
bHighSurrogate = false;
}
}
if (charTemp >= charEnd)
{
// No buffer space
return false;
}
*(charTemp++) = ch;
}
// Need to make sure that bHighSurrogate isn't true
if (bHighSurrogate)
throw new ArgumentException(Environment.GetResourceString("Argument_InvalidCharSequenceNoIndex"));
// Now we aren't going to be false, so its OK to update chars
chars = charTemp;
}
return true;
}
// This version just counts the fallback and doesn't actually copy anything.
internal unsafe virtual int InternalFallback(byte[] bytes, byte* pBytes)
// Right now this has both bytes and bytes[], since we might have extra bytes, hence the
// array, and we might need the index, hence the byte*
{
// Copy bytes to array (slow, but right now that's what we get to do.
// byte[] bytesUnknown = new byte[count];
// for (int i = 0; i < count; i++)
// bytesUnknown[i] = *(bytes++);
BCLDebug.Assert(byteStart != null, "[DecoderFallback.InternalFallback]Used InternalFallback without calling InternalInitialize");
// See if there's a fallback character and we have an output buffer then copy our string.
if (this.Fallback(bytes, (int)(pBytes - byteStart - bytes.Length)))
{
int count = 0;
char ch;
bool bHighSurrogate = false;
while ((ch = GetNextChar()) != 0)
{
// Make sure no mixed up surrogates
if (Char.IsSurrogate(ch))
{
if (Char.IsHighSurrogate(ch))
{
// High Surrogate
if (bHighSurrogate)
throw new ArgumentException(Environment.GetResourceString("Argument_InvalidCharSequenceNoIndex"));
bHighSurrogate = true;
}
else
{
// Low surrogate
if (bHighSurrogate == false)
throw new ArgumentException(Environment.GetResourceString("Argument_InvalidCharSequenceNoIndex"));
bHighSurrogate = false;
}
}
count++;
}
// Need to make sure that bHighSurrogate isn't true
if (bHighSurrogate)
throw new ArgumentException(Environment.GetResourceString("Argument_InvalidCharSequenceNoIndex"));
return count;
}
// If no fallback return 0
return 0;
}
// private helper methods
internal void ThrowLastBytesRecursive(byte[] bytesUnknown)
{
// Create a string representation of our bytes.
StringBuilder strBytes = new StringBuilder(bytesUnknown.Length * 3);
int i;
for (i = 0; i < bytesUnknown.Length && i < 20; i++)
{
if (strBytes.Length > 0)
strBytes.Append(" ");
strBytes.Append(String.Format(CultureInfo.InvariantCulture, "\\x{0:X2}", bytesUnknown[i]));
}
// In case the string's really long
if (i == 20)
strBytes.Append(" ...");
// Throw it, using our complete bytes
throw new ArgumentException(
Environment.GetResourceString("Argument_RecursiveFallbackBytes",
strBytes.ToString()), "bytesUnknown");
}
}
}
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- XMLSyntaxException.cs
- WindowsFont.cs
- EmptyControlCollection.cs
- UiaCoreProviderApi.cs
- Stack.cs
- path.cs
- QueryGeneratorBase.cs
- EasingKeyFrames.cs
- CuspData.cs
- DataGridViewTextBoxColumn.cs
- WindowsImpersonationContext.cs
- CustomAttributeFormatException.cs
- ToolStripOverflow.cs
- FileEnumerator.cs
- __Error.cs
- DefaultProxySection.cs
- Brush.cs
- BeginGetFileNameFromUserRequest.cs
- FamilyMapCollection.cs
- OleAutBinder.cs
- SessionState.cs
- _AutoWebProxyScriptEngine.cs
- OwnerDrawPropertyBag.cs
- InheritanceContextHelper.cs
- SmiXetterAccessMap.cs
- MissingManifestResourceException.cs
- PropertyIdentifier.cs
- CheckableControlBaseAdapter.cs
- RequestSecurityToken.cs
- InternalControlCollection.cs
- DashStyle.cs
- FontConverter.cs
- StorageScalarPropertyMapping.cs
- OleDbEnumerator.cs
- TextTreeFixupNode.cs
- DbResourceAllocator.cs
- elementinformation.cs
- XmlSerializationWriter.cs
- MaskedTextBoxDesigner.cs
- ContentPresenter.cs
- InputLangChangeRequestEvent.cs
- XhtmlBasicCommandAdapter.cs
- XmlSerializerAssemblyAttribute.cs
- _TransmitFileOverlappedAsyncResult.cs
- Constants.cs
- ImmutableCommunicationTimeouts.cs
- RMPermissions.cs
- JsonReader.cs
- DocumentOutline.cs
- ObjectSpanRewriter.cs
- webeventbuffer.cs
- CoTaskMemHandle.cs
- ReadOnlyObservableCollection.cs
- ZipIOExtraFieldPaddingElement.cs
- Registry.cs
- Codec.cs
- DbDataAdapter.cs
- AnimationStorage.cs
- ObjectStateEntryOriginalDbUpdatableDataRecord.cs
- PEFileReader.cs
- exports.cs
- PassportPrincipal.cs
- ManipulationDevice.cs
- CultureSpecificStringDictionary.cs
- ZipPackagePart.cs
- ConfigUtil.cs
- HijriCalendar.cs
- CompiledRegexRunnerFactory.cs
- FontEditor.cs
- SspiSecurityTokenProvider.cs
- InteropAutomationProvider.cs
- SqlFunctionAttribute.cs
- RecordsAffectedEventArgs.cs
- DataGridViewCellStyleBuilderDialog.cs
- WindowsListViewGroupHelper.cs
- ProgressBarRenderer.cs
- BitmapEncoder.cs
- HierarchicalDataTemplate.cs
- TypedRowHandler.cs
- MultipleViewPattern.cs
- BuildProvidersCompiler.cs
- XmlSignatureProperties.cs
- HyperLinkStyle.cs
- COAUTHIDENTITY.cs
- ArraySortHelper.cs
- unsafenativemethodsother.cs
- XmlSignificantWhitespace.cs
- MachineKeySection.cs
- CookielessHelper.cs
- HttpResponseHeader.cs
- CapabilitiesPattern.cs
- AxHostDesigner.cs
- ByteAnimationBase.cs
- EasingFunctionBase.cs
- EncryptedHeader.cs
- ObjectQueryProvider.cs
- RuntimeResourceSet.cs
- ExpressionVisitorHelpers.cs
- AutoFocusStyle.xaml.cs
- GenericUriParser.cs