Пример #1
0
        /// <summary>
        /// Normalize the string according to the given mode.
        /// </summary>
        /// <param name="src"></param>
        /// <param name="mode"></param>
        /// <returns></returns>
        public static string Normalize(string src, UNormalizationMode mode)
        {
            if (string.IsNullOrEmpty(src))
            {
                return(string.Empty);
            }

            var length = src.Length + 10;
            var resPtr = Marshal.AllocCoTaskMem(length * 2);

            try
            {
                ErrorCode err;
                var       normalizer = GetNormalizer(mode);
                var       outLength  = NativeMethods.unorm2_normalize(normalizer, src, src.Length, resPtr, length, out err);
                if (err > 0 && err != ErrorCode.BUFFER_OVERFLOW_ERROR)
                {
                    throw new Exception("Normalizer.Normalize() failed with code " + err);
                }
                if (outLength >= length)
                {
                    Marshal.FreeCoTaskMem(resPtr);
                    length    = outLength + 1;                  // allow room for the terminating NUL (FWR-505)
                    resPtr    = Marshal.AllocCoTaskMem(length * 2);
                    outLength = NativeMethods.unorm2_normalize(normalizer, src, src.Length, resPtr, length, out err);
                }
                if (err > 0)
                {
                    throw new Exception("Normalizer.Normalize() failed with code " + err);
                }

                var result = Marshal.PtrToStringUni(resPtr);
                // Strip any garbage left over at the end of the string.
                if (err == ErrorCode.STRING_NOT_TERMINATED_WARNING && result != null)
                {
                    return(result.Substring(0, outLength));
                }

                return(result);
            }
            finally
            {
                Marshal.FreeCoTaskMem(resPtr);
            }
        }