/// <summary> /// Creates a Unicode set from the given pattern /// </summary> /// <param name="pattern">A string specifying what characters are in the set. Null pattern returns an empty set</param> /// <returns>Unicode set of characters.</returns> public static IEnumerable <string> ToCharacters(string pattern) { if (string.IsNullOrEmpty(pattern)) { return(new string[] { }); // return Enumerable.Empty<string>(); } var err = ErrorCode.ZERO_ERROR; IntPtr result = NativeMethods.uset_openPattern(pattern, -1, ref err); try { if (err != ErrorCode.NoErrors) { throw new ArgumentException("pattern"); } var output = new List <string>(); // Parse the number of items in the Unicode set for (int i = 0; i < NativeMethods.uset_getItemCount(result); i++) { int startChar, endChar; int strLength = NativeMethods.uset_getItem(result, i, out startChar, out endChar, IntPtr.Zero, 0, ref err); if (strLength == 0) { // Add a character range to the set for (int j = startChar; j <= endChar; j++) { output.Add(((char)j).ToString(CultureInfo.InvariantCulture)); } } else { // Add a multiple-character string to the set IntPtr buffer = Marshal.AllocCoTaskMem(strLength * 2); try { err = ErrorCode.ZERO_ERROR; strLength = NativeMethods.uset_getItem(result, i, out startChar, out endChar, buffer, strLength, ref err); if (err > ErrorCode.NoErrors) { throw new Exception("UnicodeSet.ToCharacters() failed with code " + err); } output.Add(Marshal.PtrToStringUni(buffer, strLength)); } finally { Marshal.FreeCoTaskMem(buffer); } } } return(output); } finally { NativeMethods.uset_close(result); } }
/// <summary> /// Creates a Unicode set from the given pattern /// </summary> /// <param name="pattern">A string specifying what characters are in the set. Null pattern returns an empty set</param> /// <returns>Unicode set of characters.</returns> public static IEnumerable <string> ToCharacters(string pattern) { if (string.IsNullOrEmpty(pattern)) { return(Enumerable.Empty <string>()); } var uset = NativeMethods.uset_openPattern(pattern, -1, out var err); try { if (err.IsFailure()) { throw new ArgumentException(nameof(pattern)); } var output = new List <string>(); // Parse the number of items in the Unicode set var itemCount = NativeMethods.uset_getItemCount(uset); for (var i = 0; i < itemCount; i++) { var strLength = NativeMethods.uset_getItem(uset, i, out var startChar, out var endChar, IntPtr.Zero, 0, out err); if (strLength == 0 && err.IsSuccess()) { // Add a character range to the set for (var j = startChar; j <= endChar; j++) { output.Add(char.ConvertFromUtf32(j)); } } else { // Add a multiple-character string to the set var index = i; output.Add(NativeMethods.GetUnicodeString((ptr, length) => { length = NativeMethods.uset_getItem(uset, index, out startChar, out endChar, ptr, length, out var errorCode); return(new Tuple <ErrorCode, int>(errorCode, length)); }, strLength * 2)); } } return(output); } finally { NativeMethods.uset_close(uset); } }