예제 #1
0
        // NOTE: The order of the parameters to this method is a work around for https://github.com/dotnet/corefx/issues/4455
        // and the underlying Mono bug: https://bugzilla.xamarin.com/show_bug.cgi?id=36052.
        // If changing the signature of this method, ensure this issue isn't regressing on Mono.
        private unsafe int EncodeIntoBuffer(char *buffer, int bufferLength, char *value, int valueLength, int firstCharacterToEncode)
        {
            int totalWritten = 0;

            if (firstCharacterToEncode > 0)
            {
                int bytesToCopy = firstCharacterToEncode + firstCharacterToEncode;
                //commont  by jyq in 2018.7.6
                //BufferInternal.MemoryCopy(value, buffer, bytesToCopy, bytesToCopy);
                totalWritten += firstCharacterToEncode;
                bufferLength -= firstCharacterToEncode;
                buffer       += firstCharacterToEncode;
            }

            int valueIndex = firstCharacterToEncode;

            char firstChar        = value[valueIndex];
            char secondChar       = firstChar;
            bool wasSurrogatePair = false;
            int  charsWritten;

            // this loop processes character pairs (in case they are surrogates).
            // there is an if block below to process single last character.
            for (int secondCharIndex = valueIndex + 1; secondCharIndex < valueLength; secondCharIndex++)
            {
                if (!wasSurrogatePair)
                {
                    firstChar = secondChar;
                }
                else
                {
                    firstChar = value[secondCharIndex - 1];
                }
                secondChar = value[secondCharIndex];

                if (!WillEncode(firstChar))
                {
                    wasSurrogatePair = false;
                    *buffer = firstChar;
                    buffer++;
                    bufferLength--;
                    totalWritten++;
                }
                else
                {
                    int nextScalar = UnicodeHelpers.GetScalarValueFromUtf16(firstChar, secondChar, out wasSurrogatePair);
                    if (!TryEncodeUnicodeScalar(nextScalar, buffer, bufferLength, out charsWritten))
                    {
                        throw new ArgumentException("Argument encoder does not implement MaxOutputCharsPerInputChar correctly.");
                    }

                    buffer       += charsWritten;
                    bufferLength -= charsWritten;
                    totalWritten += charsWritten;
                    if (wasSurrogatePair)
                    {
                        secondCharIndex++;
                    }
                }
            }

            if (!wasSurrogatePair)
            {
                firstChar = value[valueLength - 1];
                int nextScalar = UnicodeHelpers.GetScalarValueFromUtf16(firstChar, null, out wasSurrogatePair);
                if (!TryEncodeUnicodeScalar(nextScalar, buffer, bufferLength, out charsWritten))
                {
                    throw new ArgumentException("Argument encoder does not implement MaxOutputCharsPerInputChar correctly.");
                }

                buffer       += charsWritten;
                bufferLength -= charsWritten;
                totalWritten += charsWritten;
            }

            return(totalWritten);
        }