CreateFallbackBuffer() публичный абстрактный Метод

public abstract CreateFallbackBuffer ( ) : EncoderFallbackBuffer
Результат EncoderFallbackBuffer
Пример #1
0
 private EncoderFallbackBuffer FallbackBufferInitializeInner()
 {
     if (m_fallback != null)
     {
         m_fallbackBuffer = m_fallback.CreateFallbackBuffer();
     }
     else
     {
         m_fallbackBuffer = EncoderFallback.ReplacementFallback.CreateFallbackBuffer();
     }
     return(m_fallbackBuffer);
 }
Пример #2
0
        unsafe static char [] GetFallbackChars(char *chars, char *start, EncoderFallback fallback, ref EncoderFallbackBuffer buffer)
        {
            if (buffer == null)
            {
                buffer = fallback.CreateFallbackBuffer();
            }

            buffer.Fallback(*chars, (int)(chars - start));

            char [] fallback_chars = new char [buffer.Remaining];
            for (int i = 0; i < fallback_chars.Length; i++)
            {
                fallback_chars [i] = buffer.GetNextChar();
            }

            buffer.Reset();

            return(fallback_chars);
        }
Пример #3
0
        public override unsafe int GetBytes(char *chars, int charCount,
                                            byte *bytes, int byteCount, EncoderNLS encoder)
        {
            // Just need to ASSERT, this is called by something else internal that checked parameters already
            Debug.Assert(bytes != null, "[SBCSCodePageEncoding.GetBytes]bytes is null");
            Debug.Assert(byteCount >= 0, "[SBCSCodePageEncoding.GetBytes]byteCount is negative");
            Debug.Assert(chars != null, "[SBCSCodePageEncoding.GetBytes]chars is null");
            Debug.Assert(charCount >= 0, "[SBCSCodePageEncoding.GetBytes]charCount is negative");

            // Assert because we shouldn't be able to have a null encoder.
            Debug.Assert(EncoderFallback != null, "[SBCSCodePageEncoding.GetBytes]Attempting to use null encoder fallback");

            CheckMemorySection();

            // Need to test fallback
            EncoderReplacementFallback fallback = null;

            // Get any left over characters
            char charLeftOver = (char)0;

            if (encoder != null)
            {
                charLeftOver = encoder.charLeftOver;
                Debug.Assert(charLeftOver == 0 || char.IsHighSurrogate(charLeftOver),
                             "[SBCSCodePageEncoding.GetBytes]leftover character should be high surrogate");
                fallback = encoder.Fallback as EncoderReplacementFallback;

                // Verify that we have no fallbackbuffer, for SBCS its always empty, so just assert
                Debug.Assert(!encoder.m_throwOnOverflow || !encoder.InternalHasFallbackBuffer ||
                             encoder.FallbackBuffer.Remaining == 0,
                             "[SBCSCodePageEncoding.GetBytes]Expected empty fallback buffer at start");
                //                if (encoder.m_throwOnOverflow && encoder.InternalHasFallbackBuffer &&
                //                    encoder.FallbackBuffer.Remaining > 0)
                //                    throw new ArgumentException(Environment.GetResourceString("Argument_EncoderFallbackNotEmpty",
                //                        EncodingName, encoder.Fallback.GetType()));
            }
            else
            {
                // If we aren't using default fallback then we may have a complicated count.
                fallback = EncoderFallback as EncoderReplacementFallback;
            }

            // prepare our end
            char *charEnd   = chars + charCount;
            byte *byteStart = bytes;
            char *charStart = chars;

            // See if we do the fast default or slightly slower fallback
            if (fallback != null && fallback.MaxCharCount == 1)
            {
                // Make sure our fallback character is valid first
                byte bReplacement = _mapUnicodeToBytes[fallback.DefaultString[0]];

                // Check for replacements in range, otherwise fall back to slow version.
                if (bReplacement != 0)
                {
                    // We should have exactly as many output bytes as input bytes, unless there's a leftover
                    // character, in which case we may need one more.

                    // If we had a leftover character we will have to add a ?  (This happens if they had a funky
                    // fallback last time, but not this time. We can't spit any out though,
                    // because with fallback encoder each surrogate is treated as a separate code point)
                    if (charLeftOver > 0)
                    {
                        // Have to have room
                        // Throw even if doing no throw version because this is just 1 char,
                        // so buffer will never be big enough
                        if (byteCount == 0)
                        {
                            ThrowBytesOverflow(encoder, true);
                        }

                        // This'll make sure we still have more room and also make sure our return value is correct.
                        *(bytes++) = bReplacement;
                        byteCount--;                // We used one of the ones we were counting.
                    }

                    // This keeps us from overrunning our output buffer
                    if (byteCount < charCount)
                    {
                        // Throw or make buffer smaller?
                        ThrowBytesOverflow(encoder, byteCount < 1);

                        // Just use what we can
                        charEnd = chars + byteCount;
                    }

                    // Simple way
                    while (chars < charEnd)
                    {
                        char ch2 = *chars;
                        chars++;

                        byte bTemp = _mapUnicodeToBytes[ch2];

                        // Check for fallback
                        if (bTemp == 0 && ch2 != (char)0)
                        {
                            *bytes = bReplacement;
                        }
                        else
                        {
                            *bytes = bTemp;
                        }

                        bytes++;
                    }

                    // Clear encoder
                    if (encoder != null)
                    {
                        encoder.charLeftOver = (char)0;
                        encoder.m_charsUsed  = (int)(chars - charStart);
                    }
                    return((int)(bytes - byteStart));
                }
            }

            // Slower version, have to do real fallback.

            // For fallback we may need a fallback buffer, we know we aren't default fallback
            EncoderFallbackBuffer fallbackBuffer = null;

            // prepare our end
            byte *byteEnd = bytes + byteCount;

            EncoderFallbackBufferHelper fallbackHelper = new EncoderFallbackBufferHelper(fallbackBuffer);

            // We may have a left over character from last time, try and process it.
            if (charLeftOver > 0)
            {
                // Since left over char was a surrogate, it'll have to be fallen back.
                // Get Fallback
                Debug.Assert(encoder != null, "[SBCSCodePageEncoding.GetBytes]Expect to have encoder if we have a charLeftOver");
                fallbackBuffer = encoder.FallbackBuffer;
                fallbackHelper = new EncoderFallbackBufferHelper(fallbackBuffer);


                fallbackHelper.InternalInitialize(chars, charEnd, encoder, true);

                // This will fallback a pair if *chars is a low surrogate
                fallbackHelper.InternalFallback(charLeftOver, ref chars);
                if (fallbackBuffer.Remaining > byteEnd - bytes)
                {
                    // Throw it, if we don't have enough for this we never will
                    ThrowBytesOverflow(encoder, true);
                }
            }

            // Now we may have fallback char[] already from the encoder fallback above

            // Go ahead and do it, including the fallback.
            char ch;

            while ((ch = (fallbackBuffer == null) ? '\0' : fallbackHelper.InternalGetNextChar()) != 0 ||
                   chars < charEnd)
            {
                // First unwind any fallback
                if (ch == 0)
                {
                    // No fallback, just get next char
                    ch = *chars;
                    chars++;
                }

                // get byte for this char
                byte bTemp = _mapUnicodeToBytes[ch];

                // Check for fallback, this'll catch surrogate pairs too.
                if (bTemp == 0 && ch != (char)0)
                {
                    // Get Fallback
                    if (fallbackBuffer == null)
                    {
                        // Create & init fallback buffer
                        if (encoder == null)
                        {
                            fallbackBuffer = EncoderFallback.CreateFallbackBuffer();
                        }
                        else
                        {
                            fallbackBuffer = encoder.FallbackBuffer;
                        }

                        fallbackHelper = new EncoderFallbackBufferHelper(fallbackBuffer);

                        // chars has moved so we need to remember figure it out so Exception fallback
                        // index will be correct
                        fallbackHelper.InternalInitialize(charEnd - charCount, charEnd, encoder, true);
                    }

                    // Make sure we have enough room.  Each fallback char will be 1 output char
                    // (or recursion exception will be thrown)
                    fallbackHelper.InternalFallback(ch, ref chars);
                    if (fallbackBuffer.Remaining > byteEnd - bytes)
                    {
                        // Didn't use this char, reset it
                        Debug.Assert(chars > charStart, "[SBCSCodePageEncoding.GetBytes]Expected chars to have advanced (fallback)");
                        chars--;
                        fallbackHelper.InternalReset();

                        // Throw it & drop this data
                        ThrowBytesOverflow(encoder, chars == charStart);
                        break;
                    }
                    continue;
                }

                // We'll use this one
                // Bounds check
                if (bytes >= byteEnd)
                {
                    // didn't use this char, we'll throw or use buffer
                    Debug.Assert(fallbackBuffer == null || fallbackHelper.bFallingBack == false, "[SBCSCodePageEncoding.GetBytes]Expected to NOT be falling back");
                    if (fallbackBuffer == null || fallbackHelper.bFallingBack == false)
                    {
                        Debug.Assert(chars > charStart, "[SBCSCodePageEncoding.GetBytes]Expected chars to have advanced (normal)");
                        chars--;                                        // don't use last char
                    }
                    ThrowBytesOverflow(encoder, chars == charStart);    // throw ?
                    break;                                              // don't throw, stop
                }

                // Go ahead and add it
                *bytes = bTemp;
                bytes++;
            }

            // encoder stuff if we have one
            if (encoder != null)
            {
                // Fallback stuck it in encoder if necessary, but we have to clear MustFlush cases
                if (fallbackBuffer != null && !fallbackHelper.bUsedEncoder)
                {
                    // Clear it in case of MustFlush
                    encoder.charLeftOver = (char)0;
                }

                // Set our chars used count
                encoder.m_charsUsed = (int)(chars - charStart);
            }

            // Expect Empty fallback buffer for SBCS
            Debug.Assert(fallbackBuffer == null || fallbackBuffer.Remaining == 0, "[SBCSEncoding.GetBytes]Expected Empty fallback buffer at end");

            return((int)(bytes - byteStart));
        }
Пример #4
0
        // GetByteCount
        // Note: We start by assuming that the output will be the same as count.  Having
        // an encoder or fallback may change that assumption
        public override unsafe int GetByteCount(char *chars, int count, EncoderNLS encoder)
        {
            // Just need to ASSERT, this is called by something else internal that checked parameters already
            Debug.Assert(count >= 0, "[SBCSCodePageEncoding.GetByteCount]count is negative");
            Debug.Assert(chars != null, "[SBCSCodePageEncoding.GetByteCount]chars is null");

            // Assert because we shouldn't be able to have a null encoder.
            Debug.Assert(EncoderFallback != null, "[SBCSCodePageEncoding.GetByteCount]Attempting to use null fallback");

            CheckMemorySection();

            // Need to test fallback
            EncoderReplacementFallback fallback = null;

            // Get any left over characters
            char charLeftOver = (char)0;

            if (encoder != null)
            {
                charLeftOver = encoder.charLeftOver;
                Debug.Assert(charLeftOver == 0 || char.IsHighSurrogate(charLeftOver),
                             "[SBCSCodePageEncoding.GetByteCount]leftover character should be high surrogate");
                fallback = encoder.Fallback as EncoderReplacementFallback;

                // Verify that we have no fallbackbuffer, actually for SBCS this is always empty, so just assert
                Debug.Assert(!encoder.m_throwOnOverflow || !encoder.InternalHasFallbackBuffer ||
                             encoder.FallbackBuffer.Remaining == 0,
                             "[SBCSCodePageEncoding.GetByteCount]Expected empty fallback buffer at start");
            }
            else
            {
                // If we aren't using default fallback then we may have a complicated count.
                fallback = EncoderFallback as EncoderReplacementFallback;
            }

            if ((fallback != null && fallback.MaxCharCount == 1) /* || bIsBestFit*/)
            {
                // Replacement fallback encodes surrogate pairs as two ?? (or two whatever), so return size is always
                // same as input size.
                // Note that no existing SBCS code pages map code points to supplementary characters, so this is easy.

                // We could however have 1 extra byte if the last call had an encoder and a funky fallback and
                // if we don't use the funky fallback this time.

                // Do we have an extra char left over from last time?
                if (charLeftOver > 0)
                {
                    count++;
                }

                return(count);
            }

            // It had a funky fallback, so it's more complicated
            // May need buffer later
            EncoderFallbackBuffer fallbackBuffer = null;

            // prepare our end
            int   byteCount = 0;
            char *charEnd   = chars + count;

            EncoderFallbackBufferHelper fallbackHelper = new EncoderFallbackBufferHelper(fallbackBuffer);

            // We may have a left over character from last time, try and process it.
            if (charLeftOver > 0)
            {
                // Since leftover char was a surrogate, it'll have to be fallen back.
                // Get fallback
                Debug.Assert(encoder != null, "[SBCSCodePageEncoding.GetByteCount]Expect to have encoder if we have a charLeftOver");
                fallbackBuffer = encoder.FallbackBuffer;
                fallbackHelper = new EncoderFallbackBufferHelper(fallbackBuffer);
                fallbackHelper.InternalInitialize(chars, charEnd, encoder, false);

                // This will fallback a pair if *chars is a low surrogate
                fallbackHelper.InternalFallback(charLeftOver, ref chars);
            }

            // Now we may have fallback char[] already from the encoder

            // Go ahead and do it, including the fallback.
            char ch;

            while ((ch = (fallbackBuffer == null) ? '\0' : fallbackHelper.InternalGetNextChar()) != 0 || chars < charEnd)
            {
                // First unwind any fallback
                if (ch == 0)
                {
                    // No fallback, just get next char
                    ch = *chars;
                    chars++;
                }

                // get byte for this char
                byte bTemp = _mapUnicodeToBytes[ch];

                // Check for fallback, this'll catch surrogate pairs too.
                if (bTemp == 0 && ch != (char)0)
                {
                    if (fallbackBuffer == null)
                    {
                        // Create & init fallback buffer
                        if (encoder == null)
                        {
                            fallbackBuffer = EncoderFallback.CreateFallbackBuffer();
                        }
                        else
                        {
                            fallbackBuffer = encoder.FallbackBuffer;
                        }

                        fallbackHelper = new EncoderFallbackBufferHelper(fallbackBuffer);

                        // chars has moved so we need to remember figure it out so Exception fallback
                        // index will be correct
                        fallbackHelper.InternalInitialize(charEnd - count, charEnd, encoder, false);
                    }

                    // Get Fallback
                    fallbackHelper.InternalFallback(ch, ref chars);
                    continue;
                }

                // We'll use this one
                byteCount++;
            }

            Debug.Assert(fallbackBuffer == null || fallbackBuffer.Remaining == 0,
                         "[SBCSEncoding.GetByteCount]Expected Empty fallback buffer at end");

            return((int)byteCount);
        }
Пример #5
0
        unsafe int InternalGetBytes(char *chars, int charLength, int charIndex, int charCount,
                                    byte[] bytes, int byteIndex,
                                    ref EncoderFallbackBuffer buffer,
                                    ref char [] fallback_chars)
        {
            if (bytes == null)
            {
                throw new ArgumentNullException("bytes");
            }
            if (charIndex < 0 || charIndex > charLength)
            {
                throw new ArgumentOutOfRangeException("charIndex", _("ArgRange_StringIndex"));
            }
            if (charCount < 0 || charCount > (charLength - charIndex))
            {
                throw new ArgumentOutOfRangeException("charCount", _("ArgRange_StringRange"));
            }
            if (byteIndex < 0 || byteIndex > bytes.Length)
            {
                throw new ArgumentOutOfRangeException("byteIndex", _("ArgRange_Array"));
            }
            if ((bytes.Length - byteIndex) < charCount)
            {
                throw new ArgumentException(_("Arg_InsufficientSpace"));
            }

            int  count = charCount;
            char ch;

            while (count-- > 0)
            {
                ch = chars [charIndex++];
                if (ch < (char)0x80)
                {
                    bytes [byteIndex++] = (byte)ch;
                }
                else
                {
                    if (buffer == null)
                    {
                        buffer = EncoderFallback.CreateFallbackBuffer();
                    }
                    if (Char.IsSurrogate(ch) && count > 1 &&
                        Char.IsSurrogate(chars [charIndex]))
                    {
                        buffer.Fallback(ch, chars [charIndex], charIndex++ - 1);
                    }
                    else
                    {
                        buffer.Fallback(ch, charIndex - 1);
                    }
                    if (fallback_chars == null || fallback_chars.Length < buffer.Remaining)
                    {
                        fallback_chars = new char [buffer.Remaining];
                    }
                    for (int i = 0; i < fallback_chars.Length; i++)
                    {
                        fallback_chars [i] = buffer.GetNextChar();
                    }
                    byteIndex += GetBytes(fallback_chars, 0,
                                          fallback_chars.Length, bytes, byteIndex,
                                          ref buffer, ref fallback_chars);
                }
            }
            return(charCount);
        }
	unsafe static char [] GetFallbackChars (char *chars, char *start, EncoderFallback fallback, ref EncoderFallbackBuffer buffer)
	{
		if (buffer == null)
			buffer = fallback.CreateFallbackBuffer ();

		buffer.Fallback (*chars, (int) (chars - start));

		char [] fallback_chars = new char [buffer.Remaining];
		for (int i = 0; i < fallback_chars.Length; i++)
			fallback_chars [i] = buffer.GetNextChar ();

		buffer.Reset ();

		return fallback_chars;
	}
Пример #7
0
        int GetBytes(char[] chars, int charIndex, int charCount,
                     byte[] bytes, int byteIndex,
                     ref EncoderFallbackBuffer buffer,
                     ref char [] fallback_chars)
        {
#endif
            if (chars == null)
            {
                throw new ArgumentNullException("chars");
            }
            if (bytes == null)
            {
                throw new ArgumentNullException("bytes");
            }
            if (charIndex < 0 || charIndex > chars.Length)
            {
                throw new ArgumentOutOfRangeException("charIndex", _("ArgRange_Array"));
            }
            if (charCount < 0 || charCount > (chars.Length - charIndex))
            {
                throw new ArgumentOutOfRangeException("charCount", _("ArgRange_Array"));
            }
            if (byteIndex < 0 || byteIndex > bytes.Length)
            {
                throw new ArgumentOutOfRangeException("byteIndex", _("ArgRange_Array"));
            }
            if ((bytes.Length - byteIndex) < charCount)
            {
                throw new ArgumentException(_("Arg_InsufficientSpace"));
            }
            int  count = charCount;
            char ch;
            while (count-- > 0)
            {
                ch = chars [charIndex++];
                if (ch < (char)0x0100)
                {
                    bytes [byteIndex++] = (byte)ch;
                }
                else if (ch >= '\uFF01' && ch <= '\uFF5E')
                {
                    bytes [byteIndex++] = (byte)(ch - 0xFEE0);
                }
                else
                {
#if NET_2_0
                    if (buffer == null)
                    {
                        buffer = EncoderFallback.CreateFallbackBuffer();
                    }
                    if (Char.IsSurrogate(ch) && count > 1 &&
                        Char.IsSurrogate(chars [charIndex]))
                    {
                        buffer.Fallback(ch, chars [charIndex], charIndex++ - 1);
                    }
                    else
                    {
                        buffer.Fallback(ch, charIndex - 1);
                    }
                    if (fallback_chars == null || fallback_chars.Length < buffer.Remaining)
                    {
                        fallback_chars = new char [buffer.Remaining];
                    }
                    for (int i = 0; i < fallback_chars.Length; i++)
                    {
                        fallback_chars [i] = buffer.GetNextChar();
                    }
                    byteIndex += GetBytes(fallback_chars, 0,
                                          fallback_chars.Length, bytes, byteIndex,
                                          ref buffer, ref fallback_chars);
#else
                    bytes [byteIndex++] = (byte)'?';
#endif
                }
            }
            return(charCount);
        }