Пример #1
0
        internal override unsafe int GetChars(byte *bytes, int byteCount,
                                              char *chars, int charCount, DecoderNLS baseDecoder)
        {
            Debug.Assert(chars != null, "[UTF32Encoding.GetChars]chars!=null");
            Debug.Assert(bytes != null, "[UTF32Encoding.GetChars]bytes!=null");
            Debug.Assert(byteCount >= 0, "[UTF32Encoding.GetChars]byteCount >=0");
            Debug.Assert(charCount >= 0, "[UTF32Encoding.GetChars]charCount >=0");

            UTF32Decoder decoder = (UTF32Decoder)baseDecoder;

            // None so far!
            char *charStart = chars;
            char *charEnd   = chars + charCount;

            byte *byteStart = bytes;
            byte *byteEnd   = bytes + byteCount;

            // See if there's anything in our decoder (but don't clear it yet)
            int  readCount = 0;
            uint iChar     = 0;

            // For fallback we may need a fallback buffer
            DecoderFallbackBuffer fallbackBuffer = null;
            char *charsForFallback;

            // See if there's anything in our decoder
            if (decoder != null)
            {
                readCount      = decoder.readByteCount;
                iChar          = (uint)decoder.iChar;
                fallbackBuffer = baseDecoder.FallbackBuffer;

                // Shouldn't have anything in fallback buffer for GetChars
                // (don't have to check m_throwOnOverflow for chars)
                Debug.Assert(fallbackBuffer.Remaining == 0,
                             "[UTF32Encoding.GetChars]Expected empty fallback buffer at start");
            }
            else
            {
                fallbackBuffer = this.decoderFallback.CreateFallbackBuffer();
            }

            // Set our internal fallback interesting things.
            fallbackBuffer.InternalInitialize(bytes, chars + charCount);

            // Loop through our input, 4 characters at a time!
            while (bytes < byteEnd)
            {
                // Get our next character
                if (bigEndian)
                {
                    // Scoot left and add it to the bottom
                    iChar <<= 8;
                    iChar  += *(bytes++);
                }
                else
                {
                    // Scoot right and add it to the top
                    iChar >>= 8;
                    iChar  += (uint)(*(bytes++)) << 24;
                }

                readCount++;

                // See if we have all the bytes yet
                if (readCount < 4)
                {
                    continue;
                }

                // Have the bytes
                readCount = 0;

                // See if its valid to encode
                if (iChar > 0x10FFFF || (iChar >= 0xD800 && iChar <= 0xDFFF))
                {
                    // Need to fall back these 4 bytes
                    byte[] fallbackBytes;
                    if (bigEndian)
                    {
                        fallbackBytes = new byte[] {
                            unchecked ((byte)(iChar >> 24)), unchecked ((byte)(iChar >> 16)),
                            unchecked ((byte)(iChar >> 8)), unchecked ((byte)(iChar))
                        };
                    }
                    else
                    {
                        fallbackBytes = new byte[] {
                            unchecked ((byte)(iChar)), unchecked ((byte)(iChar >> 8)),
                            unchecked ((byte)(iChar >> 16)), unchecked ((byte)(iChar >> 24))
                        };
                    }

                    // Chars won't be updated unless this works.
                    charsForFallback = chars;
                    bool fallbackResult = fallbackBuffer.InternalFallback(fallbackBytes, bytes, ref charsForFallback);
                    chars = charsForFallback;

                    if (!fallbackResult)
                    {
                        // Couldn't fallback, throw or wait til next time
                        // We either read enough bytes for bytes-=4 to work, or we're
                        // going to throw in ThrowCharsOverflow because chars == charStart
                        Debug.Assert(bytes >= byteStart + 4 || chars == charStart,
                                     "[UTF32Encoding.GetChars]Expected to have consumed bytes or throw (bad surrogate)");
                        bytes -= 4;                                      // get back to where we were
                        iChar  = 0;                                      // Remembering nothing
                        fallbackBuffer.InternalReset();
                        ThrowCharsOverflow(decoder, chars == charStart); // Might throw, if no chars output
                        break;                                           // Stop here, didn't throw
                    }

                    // Ignore the illegal character
                    iChar = 0;
                    continue;
                }


                // Ok, we have something we can add to our output
                if (iChar >= 0x10000)
                {
                    // Surrogates take 2
                    if (chars >= charEnd - 1)
                    {
                        // Throwing or stopping
                        // We either read enough bytes for bytes-=4 to work, or we're
                        // going to throw in ThrowCharsOverflow because chars == charStart
                        Debug.Assert(bytes >= byteStart + 4 || chars == charStart,
                                     "[UTF32Encoding.GetChars]Expected to have consumed bytes or throw (surrogate)");
                        bytes -= 4;                                      // get back to where we were
                        iChar  = 0;                                      // Remembering nothing
                        ThrowCharsOverflow(decoder, chars == charStart); // Might throw, if no chars output
                        break;                                           // Stop here, didn't throw
                    }

                    *(chars++) = GetHighSurrogate(iChar);
                    iChar      = GetLowSurrogate(iChar);
                }
                // Bounds check for normal character
                else if (chars >= charEnd)
                {
                    // Throwing or stopping
                    // We either read enough bytes for bytes-=4 to work, or we're
                    // going to throw in ThrowCharsOverflow because chars == charStart
                    Debug.Assert(bytes >= byteStart + 4 || chars == charStart,
                                 "[UTF32Encoding.GetChars]Expected to have consumed bytes or throw (normal char)");
                    bytes -= 4;                                      // get back to where we were
                    iChar  = 0;                                      // Remembering nothing
                    ThrowCharsOverflow(decoder, chars == charStart); // Might throw, if no chars output
                    break;                                           // Stop here, didn't throw
                }

                // Add the rest of the surrogate or our normal character
                *(chars++) = (char)iChar;

                // iChar is back to 0
                iChar = 0;
            }

            // See if we have something left over that has to be decoded
            if (readCount > 0 && (decoder == null || decoder.MustFlush))
            {
                // Oops, there's something left over with no place to go.
                byte[] fallbackBytes = new byte[readCount];
                int    tempCount     = readCount;
                if (bigEndian)
                {
                    while (tempCount > 0)
                    {
                        fallbackBytes[--tempCount] = unchecked ((byte)iChar);
                        iChar >>= 8;
                    }
                }
                else
                {
                    while (tempCount > 0)
                    {
                        fallbackBytes[--tempCount] = unchecked ((byte)(iChar >> 24));
                        iChar <<= 8;
                    }
                }

                charsForFallback = chars;
                bool fallbackResult = fallbackBuffer.InternalFallback(fallbackBytes, bytes, ref charsForFallback);
                chars = charsForFallback;

                if (!fallbackResult)
                {
                    // Couldn't fallback.
                    fallbackBuffer.InternalReset();
                    ThrowCharsOverflow(decoder, chars == charStart);// Might throw, if no chars output
                    // Stop here, didn't throw, backed up, so still nothing in buffer
                }
                else
                {
                    // Don't clear our decoder unless we could fall it back.
                    // If we caught the if above, then we're a convert() and will catch this next time.
                    readCount = 0;
                    iChar     = 0;
                }
            }

            // Remember any left over stuff, clearing buffer as well for MustFlush
            if (decoder != null)
            {
                decoder.iChar         = (int)iChar;
                decoder.readByteCount = readCount;
                decoder.m_bytesUsed   = (int)(bytes - byteStart);
            }

            // Shouldn't have anything in fallback buffer for GetChars
            // (don't have to check m_throwOnOverflow for chars)
            Debug.Assert(fallbackBuffer.Remaining == 0,
                         "[UTF32Encoding.GetChars]Expected empty fallback buffer at end");

            // Return our count
            return((int)(chars - charStart));
        }
Пример #2
0
        internal override unsafe int GetChars(byte *bytes, int byteCount, char *chars, int charCount, DecoderNLS baseDecoder)
        {
            UTF32Decoder          decoder        = (UTF32Decoder)baseDecoder;
            char *                chPtr          = chars;
            char *                chPtr2         = chars + charCount;
            byte *                numPtr         = bytes;
            byte *                numPtr2        = bytes + byteCount;
            int                   readByteCount  = 0;
            uint                  iChar          = 0;
            DecoderFallbackBuffer fallbackBuffer = null;

            if (decoder != null)
            {
                readByteCount  = decoder.readByteCount;
                iChar          = (uint)decoder.iChar;
                fallbackBuffer = baseDecoder.FallbackBuffer;
            }
            else
            {
                fallbackBuffer = base.decoderFallback.CreateFallbackBuffer();
            }
            fallbackBuffer.InternalInitialize(bytes, chars + charCount);
            while (bytes < numPtr2)
            {
                if (this.bigEndian)
                {
                    iChar = iChar << 8;
                    bytes++;
                    iChar += bytes[0];
                }
                else
                {
                    iChar = iChar >> 8;
                    bytes++;
                    iChar += (uint)(bytes[0] << 0x18);
                }
                readByteCount++;
                if (readByteCount >= 4)
                {
                    readByteCount = 0;
                    if ((iChar > 0x10ffff) || ((iChar >= 0xd800) && (iChar <= 0xdfff)))
                    {
                        byte[] buffer2;
                        if (this.bigEndian)
                        {
                            buffer2 = new byte[] { (byte)(iChar >> 0x18), (byte)(iChar >> 0x10), (byte)(iChar >> 8), (byte)iChar };
                        }
                        else
                        {
                            buffer2 = new byte[] { (byte)iChar, (byte)(iChar >> 8), (byte)(iChar >> 0x10), (byte)(iChar >> 0x18) };
                        }
                        if (!fallbackBuffer.InternalFallback(buffer2, bytes, ref chars))
                        {
                            bytes -= 4;
                            iChar  = 0;
                            fallbackBuffer.InternalReset();
                            base.ThrowCharsOverflow(decoder, chars == chPtr);
                            break;
                        }
                        iChar = 0;
                    }
                    else
                    {
                        if (iChar >= 0x10000)
                        {
                            if (chars >= (chPtr2 - 1))
                            {
                                bytes -= 4;
                                iChar  = 0;
                                base.ThrowCharsOverflow(decoder, chars == chPtr);
                                break;
                            }
                            chars++;
                            chars[0] = this.GetHighSurrogate(iChar);
                            iChar    = this.GetLowSurrogate(iChar);
                        }
                        else if (chars >= chPtr2)
                        {
                            bytes -= 4;
                            iChar  = 0;
                            base.ThrowCharsOverflow(decoder, chars == chPtr);
                            break;
                        }
                        chars++;
                        chars[0] = (char)iChar;
                        iChar    = 0;
                    }
                }
            }
            if ((readByteCount > 0) && ((decoder == null) || decoder.MustFlush))
            {
                byte[] buffer3 = new byte[readByteCount];
                int    num3    = readByteCount;
                if (!this.bigEndian)
                {
                    while (num3 > 0)
                    {
                        buffer3[--num3] = (byte)(iChar >> 0x18);
                        iChar           = iChar << 8;
                    }
                }
                else
                {
                    while (num3 > 0)
                    {
                        buffer3[--num3] = (byte)iChar;
                        iChar           = iChar >> 8;
                    }
                }
                if (!fallbackBuffer.InternalFallback(buffer3, bytes, ref chars))
                {
                    fallbackBuffer.InternalReset();
                    base.ThrowCharsOverflow(decoder, chars == chPtr);
                }
                else
                {
                    readByteCount = 0;
                    iChar         = 0;
                }
            }
            if (decoder != null)
            {
                decoder.iChar         = (int)iChar;
                decoder.readByteCount = readByteCount;
                decoder.m_bytesUsed   = (int)((long)((bytes - numPtr) / 1));
            }
            return((int)((long)((chars - chPtr) / 2)));
        }
Пример #3
0
        internal override unsafe int GetCharCount(byte *bytes, int count, DecoderNLS baseDecoder)
        {
            Debug.Assert(bytes != null, "[UTF32Encoding.GetCharCount]bytes!=null");
            Debug.Assert(count >= 0, "[UTF32Encoding.GetCharCount]count >=0");

            UTF32Decoder decoder = (UTF32Decoder)baseDecoder;

            // None so far!
            int   charCount = 0;
            byte *end       = bytes + count;
            byte *byteStart = bytes;

            // Set up decoder
            int  readCount = 0;
            uint iChar     = 0;

            // For fallback we may need a fallback buffer
            DecoderFallbackBuffer fallbackBuffer = null;

            // See if there's anything in our decoder
            if (decoder != null)
            {
                readCount      = decoder.readByteCount;
                iChar          = (uint)decoder.iChar;
                fallbackBuffer = decoder.FallbackBuffer;

                // Shouldn't have anything in fallback buffer for GetCharCount
                // (don't have to check m_throwOnOverflow for chars or count)
                Debug.Assert(fallbackBuffer.Remaining == 0,
                             "[UTF32Encoding.GetCharCount]Expected empty fallback buffer at start");
            }
            else
            {
                fallbackBuffer = this.decoderFallback.CreateFallbackBuffer();
            }

            // Set our internal fallback interesting things.
            fallbackBuffer.InternalInitialize(byteStart, null);

            // Loop through our input, 4 characters at a time!
            while (bytes < end && charCount >= 0)
            {
                // Get our next character
                if (bigEndian)
                {
                    // Scoot left and add it to the bottom
                    iChar <<= 8;
                    iChar  += *(bytes++);
                }
                else
                {
                    // Scoot right and add it to the top
                    iChar >>= 8;
                    iChar  += (uint)(*(bytes++)) << 24;
                }

                readCount++;

                // See if we have all the bytes yet
                if (readCount < 4)
                {
                    continue;
                }

                // Have the bytes
                readCount = 0;

                // See if its valid to encode
                if (iChar > 0x10FFFF || (iChar >= 0xD800 && iChar <= 0xDFFF))
                {
                    // Need to fall back these 4 bytes
                    byte[] fallbackBytes;
                    if (bigEndian)
                    {
                        fallbackBytes = new byte[] {
                            unchecked ((byte)(iChar >> 24)), unchecked ((byte)(iChar >> 16)),
                            unchecked ((byte)(iChar >> 8)), unchecked ((byte)(iChar))
                        };
                    }
                    else
                    {
                        fallbackBytes = new byte[] {
                            unchecked ((byte)(iChar)), unchecked ((byte)(iChar >> 8)),
                            unchecked ((byte)(iChar >> 16)), unchecked ((byte)(iChar >> 24))
                        };
                    }

                    charCount += fallbackBuffer.InternalFallback(fallbackBytes, bytes);

                    // Ignore the illegal character
                    iChar = 0;
                    continue;
                }

                // Ok, we have something we can add to our output
                if (iChar >= 0x10000)
                {
                    // Surrogates take 2
                    charCount++;
                }

                // Add the rest of the surrogate or our normal character
                charCount++;

                // iChar is back to 0
                iChar = 0;
            }

            // See if we have something left over that has to be decoded
            if (readCount > 0 && (decoder == null || decoder.MustFlush))
            {
                // Oops, there's something left over with no place to go.
                byte[] fallbackBytes = new byte[readCount];
                if (bigEndian)
                {
                    while (readCount > 0)
                    {
                        fallbackBytes[--readCount] = unchecked ((byte)iChar);
                        iChar >>= 8;
                    }
                }
                else
                {
                    while (readCount > 0)
                    {
                        fallbackBytes[--readCount] = unchecked ((byte)(iChar >> 24));
                        iChar <<= 8;
                    }
                }

                charCount += fallbackBuffer.InternalFallback(fallbackBytes, bytes);
            }

            // Check for overflows.
            if (charCount < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(count), Environment.GetResourceString("ArgumentOutOfRange_GetByteCountOverflow"));
            }

            // Shouldn't have anything in fallback buffer for GetCharCount
            // (don't have to check m_throwOnOverflow for chars or count)
            Debug.Assert(fallbackBuffer.Remaining == 0,
                         "[UTF32Encoding.GetCharCount]Expected empty fallback buffer at end");

            // Return our count
            return(charCount);
        }
Пример #4
0
        internal override unsafe int GetCharCount(byte *bytes, int count, DecoderNLS baseDecoder)
        {
            UTF32Decoder          decoder        = (UTF32Decoder)baseDecoder;
            int                   num            = 0;
            byte *                numPtr         = bytes + count;
            byte *                byteStart      = bytes;
            int                   readByteCount  = 0;
            uint                  iChar          = 0;
            DecoderFallbackBuffer fallbackBuffer = null;

            if (decoder != null)
            {
                readByteCount  = decoder.readByteCount;
                iChar          = (uint)decoder.iChar;
                fallbackBuffer = decoder.FallbackBuffer;
            }
            else
            {
                fallbackBuffer = base.decoderFallback.CreateFallbackBuffer();
            }
            fallbackBuffer.InternalInitialize(byteStart, null);
            while ((bytes < numPtr) && (num >= 0))
            {
                if (this.bigEndian)
                {
                    iChar = iChar << 8;
                    bytes++;
                    iChar += bytes[0];
                }
                else
                {
                    iChar = iChar >> 8;
                    bytes++;
                    iChar += (uint)(bytes[0] << 0x18);
                }
                readByteCount++;
                if (readByteCount >= 4)
                {
                    readByteCount = 0;
                    if ((iChar > 0x10ffff) || ((iChar >= 0xd800) && (iChar <= 0xdfff)))
                    {
                        byte[] buffer2;
                        if (this.bigEndian)
                        {
                            buffer2 = new byte[] { (byte)(iChar >> 0x18), (byte)(iChar >> 0x10), (byte)(iChar >> 8), (byte)iChar };
                        }
                        else
                        {
                            buffer2 = new byte[] { (byte)iChar, (byte)(iChar >> 8), (byte)(iChar >> 0x10), (byte)(iChar >> 0x18) };
                        }
                        num  += fallbackBuffer.InternalFallback(buffer2, bytes);
                        iChar = 0;
                    }
                    else
                    {
                        if (iChar >= 0x10000)
                        {
                            num++;
                        }
                        num++;
                        iChar = 0;
                    }
                }
            }
            if ((readByteCount > 0) && ((decoder == null) || decoder.MustFlush))
            {
                byte[] buffer3 = new byte[readByteCount];
                if (!this.bigEndian)
                {
                    while (readByteCount > 0)
                    {
                        buffer3[--readByteCount] = (byte)(iChar >> 0x18);
                        iChar = iChar << 8;
                    }
                }
                else
                {
                    while (readByteCount > 0)
                    {
                        buffer3[--readByteCount] = (byte)iChar;
                        iChar = iChar >> 8;
                    }
                }
                num += fallbackBuffer.InternalFallback(buffer3, bytes);
            }
            if (num < 0)
            {
                throw new ArgumentOutOfRangeException("count", Environment.GetResourceString("ArgumentOutOfRange_GetByteCountOverflow"));
            }
            return(num);
        }