public string Next()
        {
            var str = NativeMethods.uenum_unext(this, out var length, out var e);

            ExceptionFromErrorCode.ThrowIfError(e);

            return(str == IntPtr.Zero ? null : Marshal.PtrToStringUni(str, length));
        }
示例#2
0
        /// <summary>
        /// Returns the timezone data version currently used by ICU.
        /// </summary>
        /// <returns>the version string, such as "2007f"</returns>
        public static string GetTZDataVersion()
        {
            var ptr = NativeMethods.ucal_getTZDataVersion(out ErrorCode errorCode);

            ExceptionFromErrorCode.ThrowIfError(errorCode);

            return(Marshal.PtrToStringAnsi(ptr));
        }
示例#3
0
        /// <summary>
        /// Get a visual-to-logical index map (array) for the characters in the BiDi (paragraph or line) object.
        /// </summary>
        /// <returns>An array of <see cref="ResultLength"/>indexes which will reflect the reordering of the character</returns>
        public int[] GetVisualMap()
        {
            var map = new int[ResultLength];

            NativeMethods.ubidi_getVisualMap(_biDi, map, out var errorCode);
            ExceptionFromErrorCode.ThrowIfError(errorCode, "Get visual map failed! " + errorCode);
            return(map);
        }
示例#4
0
        /// <summary>
        /// Get an ICU Transliterator.
        /// </summary>
        /// <param name="id">a valid transliterator ID</param>
        /// <param name="dir">the desired direction</param>
        /// <param name="rules">the transliterator rules. If <c>null</c> then a system transliterator
        /// matching the ID is returned.</param>
        /// <returns>
        /// A Transliterator class instance. Be sure to call the instance's `Dispose` method to clean up.
        /// </returns>
        public static Transliterator CreateInstance(string id, UTransDirection dir = UTransDirection.Forward, string rules = null)
        {
            var handle = NativeMethods.utrans_openU(id, dir, rules, out _, out var status);

            ExceptionFromErrorCode.ThrowIfError(status);

            return(new Transliterator(handle));
        }
示例#5
0
        /// <summary>
        /// Returns a reordered string for a piece of text (one or more paragraphs) set by <see cref="SetPara(string, byte, byte[])"/> or
        /// for a line of text set by <see cref="SetLine(int, int)"/>.
        /// </summary>
        /// <param name="options">Options for the reordering that control how the reordered text is written.</param>
        /// <returns>The reordered string</returns>
        public string GetReordered(CallReorderingOptions options)
        {
            var buff = new char[ProcessedLength * 2];
            var len  = NativeMethods.ubidi_writeReordered(_biDi, buff, buff.Length * 2, (ushort)options, out var errorCode);

            ExceptionFromErrorCode.ThrowIfError(errorCode, "BiDi reordering failed! " + errorCode);

            return(new string(buff, 0, len));
        }
示例#6
0
        /// <summary>
        /// constructor
        /// </summary>
        /// <param name="regexp">a unicode regular expression</param>
        /// <param name="flags">a bitOred URegexpFlag</param>
        public RegexMatcher(string regexp, URegexpFlag flags = URegexpFlag.NONE)
        {
            _regexp = regexp;
            ErrorCode  e;
            ParseError parseError;

            _regexMatcher = NativeMethods.uregex_open(_regexp, _regexp.Length, (uint)flags, out parseError, out e);
            ExceptionFromErrorCode.ThrowIfError(e);
        }
示例#7
0
        /// <summary>
        /// Get an enumeration of levels for each character.
        /// </summary>
        /// <returns></returns>
        public IEnumerable <byte> GetLevels()
        {
            var levels = NativeMethods.ubidi_getLevels(_biDi, out var errorCode);

            ExceptionFromErrorCode.ThrowIfError(errorCode, "BiDi level retrieval failed! " + errorCode);

            var ret = new byte[ProcessedLength];

            Marshal.Copy(levels, ret, 0, ret.Length);
            return(ret);
        }
示例#8
0
        /// <summary>
        /// Reverse a Right-To-Left run of Unicode text.
        /// </summary>
        /// <param name="str">The RTL text.</param>
        /// <param name="options">Options for the reordering that control how the reordered text is written.</param>
        /// <returns>The reversed string</returns>
        public static string ReverseString(string str, CallReorderingOptions options)
        {
            if (str == null)
            {
                return("");
            }

            var buff = new char[str.Length];
            var len  = NativeMethods.ubidi_writeReverse(str, str.Length, buff, buff.Length, (ushort)options, out var errorCode);

            ExceptionFromErrorCode.ThrowIfError(errorCode, "BiDi reversing failed! " + errorCode);

            return(new string(buff, 0, len));
        }
示例#9
0
        /// <summary>
        /// Perform the Unicode Bidi algorithm.
        /// </summary>
        /// <param name="text">The text that the Bidi algorithm will be performed on</param>
        /// <param name="paraLevel">Specifies the default level for the text; it is typically 0 (LTR) or 1 (RTL)</param>
        /// <param name="embeddingLevels">May be used to preset the embedding and override levels, ignoring characters like LRE and PDF in the text;
        /// a level overrides the directional property of its corresponding (same index) character if the level has the UBIDI_LEVEL_OVERRIDE bit set</param>
        /// <remarks>
        /// This function takes a piece of plain text containing one or more paragraphs, with or without externally specified embedding levels from styled
        /// text and computes the left-right-directionality of each character.
        ///
        /// If the entire text is all of the same directionality, then the function may not perform all the steps described by the algorithm, i.e.,
        /// some levels may not be the same as if all steps were performed.This is not relevant for unidirectional text.
        ///
        /// For example, in pure LTR text with numbers the numbers would get a resolved level of 2 higher than the surrounding text according to the
        /// algorithm.This implementation may set all resolved levels to the same value in such a case.
        ///
        /// The text can be composed of multiple paragraphs. Occurrence of a block separator in the text terminates a paragraph, and whatever comes
        /// next starts a new paragraph.The exception to this rule is when a Carriage Return (CR) is followed by a Line Feed (LF). Both CR and LF are
        /// block separators, but in that case, the pair of characters is considered as terminating the preceding paragraph, and a new paragraph will
        /// be started by a character coming after the LF.
        /// </remarks>
        public void SetPara(string text, byte paraLevel, byte[] embeddingLevels)
        {
            if (_para != IntPtr.Zero)
            {
                Marshal.FreeHGlobal(_para);
                _para = IntPtr.Zero;
            }

            if (text == null)
            {
                throw new ArgumentNullException(nameof(text));
            }

            // icu BiDi expects the para pointer to live for the life of the structure, so we have to stash it
            _para = Marshal.StringToHGlobalUni(text);
            NativeMethods.ubidi_setPara(_biDi, _para, text.Length, paraLevel, embeddingLevels, out var errorCode);
            ExceptionFromErrorCode.ThrowIfError(errorCode, "BiDi analysis failed! " + errorCode);
        }
示例#10
0
        private static string GetString(Func <IntPtr, int, Tuple <ErrorCode, int> > lambda,
                                        bool isUnicodeString = false, int initialLength = 255)
        {
            var length = initialLength;
            var resPtr = Marshal.AllocCoTaskMem(length * 2);

            try
            {
                var(err, outLength) = lambda(resPtr, length);
                if (err != ErrorCode.BUFFER_OVERFLOW_ERROR && err != ErrorCode.STRING_NOT_TERMINATED_WARNING)
                {
                    ExceptionFromErrorCode.ThrowIfError(err);
                }
                if (outLength >= length)
                {
                    err = ErrorCode.NoErrors;                   // ignore possible U_BUFFER_OVERFLOW_ERROR or STRING_NOT_TERMINATED_WARNING
                    Marshal.FreeCoTaskMem(resPtr);
                    length           = outLength + 1;           // allow room for the terminating NUL (FWR-505)
                    resPtr           = Marshal.AllocCoTaskMem(length * 2);
                    (err, outLength) = lambda(resPtr, length);
                }

                ExceptionFromErrorCode.ThrowIfError(err);

                if (outLength < 0)
                {
                    return(null);
                }

                var result = isUnicodeString
                                        ? Marshal.PtrToStringUni(resPtr)
                                        : Marshal.PtrToStringAnsi(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);
            }
        }
示例#11
0
        /// <summary>
        /// Returns a string in a resource that has a given <paramref name="key"/>.
        /// </summary>
        /// <param name="key">The name of the string to retrieve</param>
        /// <returns>A string containing the requested string, or <c>string.Empty</c> if the
        /// string was not found (or if that key represented a different type of data, such as a
        /// number or a resource bundle subsection). May also throw an Exception in exceptional
        /// error situations.</returns>
        /// <remarks>This procedure works only with table resources.</remarks>
        public string GetStringByKey(string key)
        {
            if (IsNull)
            {
                return(string.Empty);
            }

            var resultPtr = NativeMethods.ures_getStringByKey(_ResourceBundle, key,
                                                              out var len, out var status);

            if (status.IsFailure())
            {
                if (status == ErrorCode.MISSING_RESOURCE_ERROR || status == ErrorCode.INVALID_FORMAT_ERROR)
                {
                    return(string.Empty);
                }
                ExceptionFromErrorCode.ThrowIfError(status, $"- GetStringByKey failed for key {key}");
            }
            return(resultPtr == IntPtr.Zero ? string.Empty : Marshal.PtrToStringUni(resultPtr, len));
        }
示例#12
0
        private static IEnumerable <TimeZone> CreateTimeZoneList(Func <Tuple <SafeEnumeratorHandle, ErrorCode> > enumeratorSource)
        {
            List <TimeZone> timeZones = new List <TimeZone>();

            (SafeEnumeratorHandle enumerator, ErrorCode errorCode) = enumeratorSource();
            ExceptionFromErrorCode.ThrowIfError(errorCode);
            try
            {
                string timezoneId = enumerator.Next();
                while (timezoneId != null)
                {
                    timeZones.Add(new TimeZone(timezoneId));
                    timezoneId = enumerator.Next();
                }
            }
            finally
            {
                enumerator.Dispose();
            }
            return(timeZones);
        }
示例#13
0
 /// <summary>
 /// Constructs a new MessageFormat using the given pattern and locale.
 /// </summary>
 /// <param name="pattern">Pattern used to construct object. </param>
 /// <param name="localeId">The locale to use for formatting dates and numbers. </param>
 /// <remarks>If the pattern cannot be parsed, an exception is thrown.</remarks>
 public MessageFormatter(string pattern, string localeId)
 {
     _Formatter = NativeMethods.umsg_open(pattern, pattern.Length, localeId,
                                          out var parseError, out var status);
     ExceptionFromErrorCode.ThrowIfError(status);
 }
示例#14
0
 /// <summary>
 /// Sets a BiDi object to contain the reordering information, especially the resolved levels, for all the characters in a line of text.
 /// </summary>
 /// <param name="start">The line's first index into the text</param>
 /// <param name="limit">Position just behind the line's last index into the text (its last index +1)</param>
 /// <returns></returns>
 public BiDi SetLine(int start, int limit)
 {
     NativeMethods.ubidi_setLine(_biDi, start, limit, out var lineBidi, out var errorCode);
     ExceptionFromErrorCode.ThrowIfError(errorCode, "BiDi line creation failed! " + errorCode);
     return(new BiDi(lineBidi));
 }
示例#15
0
 /// <summary>
 /// Get a paragraph, given the index of this paragraph.
 /// </summary>
 /// <param name="paraIndex">The number of the paragraph, in the range [0..<see cref="CountParagraphs"/>-1]</param>
 /// <param name="paraStart">Will receive the index of the first character of the paragraph in the text</param>
 /// <param name="paraLimit">Will receive the limit of the paragraph</param>
 /// <param name="paraLevel">Will receive the level of the paragraph</param>
 public void GetParagraphByIndex(int paraIndex, out int paraStart, out int paraLimit, out byte paraLevel)
 {
     NativeMethods.ubidi_getParagraphByIndex(_biDi, paraIndex, out paraStart, out paraLimit, out paraLevel, out var errorCode);
     ExceptionFromErrorCode.ThrowIfError(errorCode, "Paragraph retrieval failed! " + errorCode);
 }
示例#16
0
 /// <summary>
 /// Sets the default time zone to be the specified time zone.
 /// </summary>
 /// <param name="timezone">The given timezone. </param>
 public static void SetDefault(TimeZone timezone)
 {
     NativeMethods.ucal_setDefaultTimeZone(timezone.Id, out ErrorCode errorCode);
     ExceptionFromErrorCode.ThrowIfError(errorCode);
 }
示例#17
0
 /// <summary>
 /// Creates a new BiDi object with preallocated memory for internal structures.
 /// </summary>
 /// <param name="maxLength">The maximum text or line length that internal memory will be preallocated for</param>
 /// <param name="maxRunCount">The maximum anticipated number of same-level runs that internal memory will be preallocated for</param>
 public BiDi(int maxLength, int maxRunCount)
 {
     _biDi = NativeMethods.ubidi_openSized(maxLength, maxRunCount, out var errorCode);
     ExceptionFromErrorCode.ThrowIfError(errorCode, "Creating BiDi object failed! " + errorCode);
 }
示例#18
0
 /// <summary>
 /// Constructor
 /// </summary>
 /// <param name="packageName">The packageName and locale together point to an ICU udata
 /// object, as defined by udata_open( packageName, "res", locale, err) or equivalent.
 /// Typically, packageName will refer to a (.dat) file, or to a package registered with
 /// udata_setAppData(). Using a full file or directory pathname for packageName is
 /// deprecated.</param>
 /// <param name="locale">This is the locale this resource bundle is for.</param>
 public ResourceBundle(string packageName, string locale)
 {
     _ResourceBundle = NativeMethods.ures_open(packageName, locale, out var errorCode);
     ExceptionFromErrorCode.ThrowIfError(errorCode);
 }