Ejemplo n.º 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);
            }

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

            try
            {
                ErrorCode err;
                int       outLength = NativeMethods.unorm_normalize(src, src.Length, mode, 0, 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);
                    NativeMethods.unorm_normalize(src, src.Length, mode, 0, resPtr, length, out err);
                }
                if (err > 0)
                {
                    throw new Exception("Normalizer.Normalize() failed with code " + err);
                }

                string 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);
            }
        }