예제 #1
0
        /// <summary>
        /// Parse a string to long. String must not start with '0x'.
        /// Long can accomodate only 16 meaningful hex-decimals.
        /// </summary>
        /// <param name="str">string of hexadecimal characters [0-9a-fA-F]</param>
        /// <param name="value">result value</param>
        /// <returns>false if contains non-hex characters, or if number of meaningful hexnumbers is over 24.</returns>
        public static bool TryParseToULong(String str, out ulong value)
        {
            HexEnumerator stream = new HexEnumerator(str.GetEnumerator());

            // Calculate hex character count
            int count = 0;
            // Calculate meaningful number characters
            int meaningfulDigits = 0;

            for (int i = 0; i < 999 && stream.MoveNext(); i++)
            {
                // Got non-hex value.
                if (stream.Current < 0)
                {
                    value = default(ulong); return(false);
                }
                // Start calculating after first non-zero.
                if (meaningfulDigits > 0 || stream.Current != 0)
                {
                    meaningfulDigits++;
                }
                // Total character count.
                count++;
            }

            // Found non-zero value.
            if (stream.Error)
            {
                value = default(ulong); return(false);
            }

            // Restart
            stream.Reset();

            // Too many characters
            if (meaningfulDigits >= 17)
            {
                value = default(ulong); return(false);
            }

            value = 0UL;
            while (count > 16 && stream.MoveNext())
            {
                // long can fit 64bit value, any non-zero over 64bits cannot be parsed.
                if (stream.Current != 0)
                {
                    value = default(ulong); return(false);
                }
                count--;
            }
            while (count > 0 && stream.MoveNext())
            {
                ulong hex = (ulong)stream.Current;
                value = value << 4 | hex;
                count--;
            }

            return(true);
        }
예제 #2
0
        /// <summary>
        /// Parse a string to uint. String must not start with '0x'.
        /// UInt can accomodate only 8 meaningful hex-decimals.
        /// </summary>
        /// <param name="str">string of hexadecimal characters [0-9a-fA-F]</param>
        /// <param name="startIndex">character start index</param>
        /// <returns>value</returns>
        /// <exception cref="System.FormatException"></exception>
        public static uint ToUInt(String str, int startIndex = 0)
        {
            CharEnumerator enumr = str.GetEnumerator();

            for (int i = 0; i < startIndex; i++)
            {
                if (!enumr.MoveNext())
                {
                    throw new FormatException("End of stream before startIndex.");
                }
            }
            HexEnumerator stream = new HexEnumerator(enumr);

            // Calculate hex character count
            int count = 0;
            // Calculate meaningful number characters
            int meaningfulDigits = 0;

            for (int i = 0; i < 999 && stream.MoveNext(); i++)
            {
                // Got non-hex value.
                if (stream.Current < 0)
                {
                    throw new System.FormatException("Unexpected character in hex stream.");
                }
                // Start calculating after first non-zero.
                if (meaningfulDigits > 0 || stream.Current != 0)
                {
                    meaningfulDigits++;
                }
                // Total character count.
                count++;
            }

            // Found non-zero value.
            if (stream.Error)
            {
                if (stream.Current < 0)
                {
                    throw new System.FormatException("Unexpected character in hex stream.");
                }
            }

            // Restart
            stream.Reset();
            for (int i = 0; i < startIndex; i++)
            {
                enumr.MoveNext();
            }

            // Too many characters
            if (meaningfulDigits >= 9)
            {
                throw new System.FormatException("Hex value too large to fit into decimal.");
            }

            uint value = 0U;

            while (count > 8 && stream.MoveNext())
            {
                // long can fit 64bit value, any non-zero over 64bits cannot be parsed.
                if (stream.Current != 0)
                {
                    throw new System.FormatException("Hex value too large to fit into decimal.");
                }
                count--;
            }
            while (count > 0 && stream.MoveNext())
            {
                uint hex = (uint)stream.Current;
                value = value << 4 | hex;
                count--;
            }

            return(value);
        }
예제 #3
0
        /// <summary>
        /// Try to parse a string to decimal number.
        /// String must not start with '0x'.
        /// Decimal can accomodate only 24 meaningful hexnumbers.
        /// Although, the string can precede any number of zeroes, e.g. "0000000000000000000000000000000000000000000000000000000000000123123abff".
        /// </summary>
        /// <param name="str">string of hexadecimal characters [0-9a-fA-F]</param>
        /// <param name="value">result value</param>
        /// <returns>false if contains non-hex characters, or if number of meaningful hexnumbers is over 24.</returns>
        public static bool TryParseToDecimal(String str, out decimal value)
        {
            HexEnumerator stream = new HexEnumerator(str.GetEnumerator());

            // Calculate hex character count
            int count = 0;
            // Calculate meaningful number characters
            int meaningfulDigits = 0;

            for (int i = 0; i < 999 && stream.MoveNext(); i++)
            {
                // Got non-hex value.
                if (stream.Current < 0)
                {
                    value = 0; return(false);
                }
                // Start calculating after first non-zero.
                if (meaningfulDigits > 0 || stream.Current != 0)
                {
                    meaningfulDigits++;
                }
                // Total character count.
                count++;
            }

            // Found non-zero value.
            if (stream.Error)
            {
                value = 0; return(false);
            }

            // Restart
            stream.Reset();

            // Too many characters
            if (meaningfulDigits >= 25)
            {
                value = 0; return(false);
            }

            int lo = 0, mid = 0, hi = 0;

            while (count > 24 && stream.MoveNext())
            {
                // decimal can fit 96bit value, any non-zero over 96bits cannot be parsed.
                if (stream.Current != 0)
                {
                    value = 0; return(false);
                }
                count--;
            }
            while (count > 16 && stream.MoveNext())
            {
                hi = (hi << 4) | stream.Current;
                count--;
            }
            while (count > 8 && stream.MoveNext())
            {
                mid = (mid << 4) | stream.Current;
                count--;
            }
            while (count > 0 && stream.MoveNext())
            {
                lo = (lo << 4) | stream.Current;
                count--;
            }

            value = new decimal(lo, mid, hi, false, 0);
            return(!stream.Error);
        }