/// <include file='../../docs.xml'
        /// path='docs/doc[@name="M:FastInteger2.Multiply(System.Int32)"]/*'/>
        internal FastInteger2 Multiply(int val)
        {
            if (val == 0)
            {
                this.smallValue  = 0;
                this.integerMode = 0;
            }
            else
            {
                switch (this.integerMode)
                {
                case 0:
                    bool apos = this.smallValue > 0L;
                    bool bpos = val > 0L;
                    if (
                        (apos && ((!bpos && (Int32.MinValue / this.smallValue) > val) ||
                                  (bpos && this.smallValue > (Int32.MaxValue / val)))) ||
                        (!apos && ((!bpos && this.smallValue != 0L &&
                                    (Int32.MaxValue / this.smallValue) > val) ||
                                   (bpos && this.smallValue < (Int32.MinValue / val)))))
                    {
                        // would overflow, convert to large
                        if (apos && bpos)
                        {
                            // if both operands are nonnegative
                            // convert to mutable big integer
                            this.integerMode = 1;
                            this.mnum        = new MutableNumber(this.smallValue);
                            this.mnum.Multiply(val);
                        }
                        else
                        {
                            // if either operand is negative
                            // convert to big integer
                            this.integerMode = 2;
                            this.largeValue  = (EInteger)this.smallValue;
                            this.largeValue *= (EInteger)val;
                        }
                    }
                    else
                    {
                        smallValue *= val;
                    }
                    break;

                case 1:
                    if (val < 0)
                    {
                        this.integerMode = 2;
                        this.largeValue  = this.mnum.ToEInteger();
                        this.largeValue *= (EInteger)val;
                    }
                    else
                    {
                        mnum.Multiply(val);
                    }
                    break;

                case 2:
                    this.largeValue *= (EInteger)val;
                    break;

                default: throw new InvalidOperationException();
                }
            }
            return(this);
        }
Beispiel #2
0
        public static CBORObject Addition(CBORObject a, CBORObject b)
        {
            if (a == null)
            {
                throw new ArgumentNullException(nameof(a));
            }
            if (b == null)
            {
                throw new ArgumentNullException(nameof(b));
            }
            if (a.Type != CBORType.Number)
            {
                throw new ArgumentException("a.Type (" + a.Type +
                                            ") is not equal to " + CBORType.Number);
            }
            if (b.Type != CBORType.Number)
            {
                throw new ArgumentException("b.Type (" + b.Type +
                                            ") is not equal to " + CBORType.Number);
            }
            object objA  = a.ThisItem;
            object objB  = b.ThisItem;
            int    typeA = a.ItemType;
            int    typeB = b.ItemType;

            if (typeA == CBORObject.CBORObjectTypeInteger && typeB ==
                CBORObject.CBORObjectTypeInteger)
            {
                var valueA = (long)objA;
                var valueB = (long)objB;
                if ((valueA < 0 && valueB < Int64.MinValue - valueA) ||
                    (valueA > 0 && valueB > Int64.MaxValue - valueA))
                {
                    // would overflow, convert to EInteger
                    return(CBORObject.FromObject(((EInteger)valueA) +
                                                 (EInteger)valueB));
                }
                return(CBORObject.FromObject(valueA + valueB));
            }
            if (typeA == CBORObject.CBORObjectTypeExtendedRational ||
                typeB == CBORObject.CBORObjectTypeExtendedRational)
            {
                ERational e1 =
                    CBORObject.GetNumberInterface(typeA).AsExtendedRational(objA);
                ERational e2 =
                    CBORObject.GetNumberInterface(typeB).AsExtendedRational(objB);
                return(CBORObject.FromObject(e1.Add(e2)));
            }
            if (typeA == CBORObject.CBORObjectTypeExtendedDecimal ||
                typeB == CBORObject.CBORObjectTypeExtendedDecimal)
            {
                EDecimal e1 =
                    CBORObject.GetNumberInterface(typeA).AsExtendedDecimal(objA);
                EDecimal e2 =
                    CBORObject.GetNumberInterface(typeB).AsExtendedDecimal(objB);
                return(CBORObject.FromObject(e1.Add(e2)));
            }
            if (typeA == CBORObject.CBORObjectTypeExtendedFloat || typeB ==
                CBORObject.CBORObjectTypeExtendedFloat ||
                typeA == CBORObject.CBORObjectTypeDouble || typeB ==
                CBORObject.CBORObjectTypeDouble ||
                typeA == CBORObject.CBORObjectTypeSingle || typeB ==
                CBORObject.CBORObjectTypeSingle)
            {
                EFloat e1 =
                    CBORObject.GetNumberInterface(typeA).AsExtendedFloat(objA);
                EFloat e2 = CBORObject.GetNumberInterface(typeB).AsExtendedFloat(objB);
                return(CBORObject.FromObject(e1.Add(e2)));
            }
            else
            {
                EInteger b1 = CBORObject.GetNumberInterface(typeA).AsEInteger(objA);
                EInteger b2 = CBORObject.GetNumberInterface(typeB).AsEInteger(objB);
                return(CBORObject.FromObject(b1 + (EInteger)b2));
            }
        }
Beispiel #3
0
        public static CBORObject Divide(CBORObject a, CBORObject b)
        {
            if (a == null)
            {
                throw new ArgumentNullException(nameof(a));
            }
            if (b == null)
            {
                throw new ArgumentNullException(nameof(b));
            }
            if (a.Type != CBORType.Number)
            {
                throw new ArgumentException("a.Type (" + a.Type +
                                            ") is not equal to " + CBORType.Number);
            }
            if (b.Type != CBORType.Number)
            {
                throw new ArgumentException("b.Type (" + b.Type +
                                            ") is not equal to " + CBORType.Number);
            }
            object objA  = a.ThisItem;
            object objB  = b.ThisItem;
            int    typeA = a.ItemType;
            int    typeB = b.ItemType;

            if (typeA == CBORObject.CBORObjectTypeInteger && typeB ==
                CBORObject.CBORObjectTypeInteger)
            {
                var valueA = (long)objA;
                var valueB = (long)objB;
                if (valueB == 0)
                {
                    return((valueA == 0) ? CBORObject.NaN : ((valueA < 0) ?
                                                             CBORObject.NegativeInfinity : CBORObject.PositiveInfinity));
                }
                if (valueA == Int64.MinValue && valueB == -1)
                {
                    return(CBORObject.FromObject(valueA).Negate());
                }
                long quo = valueA / valueB;
                long rem = valueA - (quo * valueB);
                return((rem == 0) ? CBORObject.FromObject(quo) :
                       CBORObject.FromObject(
                           ERational.Create(
                               (EInteger)valueA,
                               (EInteger)valueB)));
            }
            if (typeA == CBORObject.CBORObjectTypeExtendedRational ||
                typeB == CBORObject.CBORObjectTypeExtendedRational)
            {
                ERational e1 =
                    CBORObject.GetNumberInterface(typeA).AsExtendedRational(objA);
                ERational e2 =
                    CBORObject.GetNumberInterface(typeB).AsExtendedRational(objB);
                return(CBORObject.FromObject(e1.Divide(e2)));
            }
            if (typeA == CBORObject.CBORObjectTypeExtendedDecimal ||
                typeB == CBORObject.CBORObjectTypeExtendedDecimal)
            {
                EDecimal e1 =
                    CBORObject.GetNumberInterface(typeA).AsExtendedDecimal(objA);
                EDecimal e2 =
                    CBORObject.GetNumberInterface(typeB).AsExtendedDecimal(objB);
                if (e1.IsZero && e2.IsZero)
                {
                    return(CBORObject.NaN);
                }
                EDecimal eret = e1.Divide(e2, null);
                // If either operand is infinity or NaN, the result
                // is already exact. Likewise if the result is a finite number.
                if (!e1.IsFinite || !e2.IsFinite || eret.IsFinite)
                {
                    return(CBORObject.FromObject(eret));
                }
                ERational er1 =
                    CBORObject.GetNumberInterface(typeA).AsExtendedRational(objA);
                ERational er2 =
                    CBORObject.GetNumberInterface(typeB).AsExtendedRational(objB);
                return(CBORObject.FromObject(er1.Divide(er2)));
            }
            if (typeA == CBORObject.CBORObjectTypeExtendedFloat || typeB ==
                CBORObject.CBORObjectTypeExtendedFloat ||
                typeA == CBORObject.CBORObjectTypeDouble || typeB ==
                CBORObject.CBORObjectTypeDouble ||
                typeA == CBORObject.CBORObjectTypeSingle || typeB ==
                CBORObject.CBORObjectTypeSingle)
            {
                EFloat e1 =
                    CBORObject.GetNumberInterface(typeA).AsExtendedFloat(objA);
                EFloat e2 = CBORObject.GetNumberInterface(typeB).AsExtendedFloat(objB);
                if (e1.IsZero && e2.IsZero)
                {
                    return(CBORObject.NaN);
                }
                EFloat eret = e1.Divide(e2, null);
                // If either operand is infinity or NaN, the result
                // is already exact. Likewise if the result is a finite number.
                if (!e1.IsFinite || !e2.IsFinite || eret.IsFinite)
                {
                    return(CBORObject.FromObject(eret));
                }
                ERational er1 =
                    CBORObject.GetNumberInterface(typeA).AsExtendedRational(objA);
                ERational er2 =
                    CBORObject.GetNumberInterface(typeB).AsExtendedRational(objB);
                return(CBORObject.FromObject(er1.Divide(er2)));
            }
            else
            {
                EInteger b1 = CBORObject.GetNumberInterface(typeA).AsEInteger(objA);
                EInteger b2 = CBORObject.GetNumberInterface(typeB).AsEInteger(objB);
                if (b2.IsZero)
                {
                    return(b1.IsZero ? CBORObject.NaN : ((b1.Sign < 0) ?
                                                         CBORObject.NegativeInfinity : CBORObject.PositiveInfinity));
                }
                EInteger bigrem;
                EInteger bigquo;
                {
                    EInteger[] divrem = b1.DivRem(b2);
                    bigquo = divrem[0];
                    bigrem = divrem[1];
                }
                return(bigrem.IsZero ? CBORObject.FromObject(bigquo) :
                       CBORObject.FromObject(ERational.Create(b1, b2)));
            }
        }
Beispiel #4
0
 /// <include file='../docs.xml'
 /// path='docs/doc[@name="M:PeterO.BigInteger.fromRadixString(System.String,System.Int32)"]/*'/>
 public static BigInteger fromRadixString(string str, int radix)
 {
     return(new BigInteger(EInteger.FromRadixString(str, radix)));
 }
Beispiel #5
0
 /// <include file='../docs.xml'
 /// path='docs/doc[@name="M:PeterO.BigInteger.valueOf(System.Int64)"]/*'/>
 public static BigInteger valueOf(long longerValue)
 {
     return(new BigInteger(EInteger.FromInt64(longerValue)));
 }
Beispiel #6
0
        internal static CBORObject ParseJSONNumber(
            byte[] chars,
            int offset,
            int count,
            JSONOptions options,
            int[] endOfNumber)
        {
            if (chars == null || chars.Length == 0 || count <= 0)
            {
                return(null);
            }
            if (offset < 0 || offset > chars.Length)
            {
                return(null);
            }
            if (count > chars.Length || chars.Length - offset < count)
            {
                return(null);
            }
            JSONOptions opt = options ?? CBORDataUtilities.DefaultOptions;
            bool        preserveNegativeZero = options.PreserveNegativeZero;

            JSONOptions.ConversionMode kind = options.NumberConversion;
            int endPos        = offset + count;
            int initialOffset = offset;
            var negative      = false;

            if (chars[initialOffset] == '-')
            {
                ++offset;
                negative = true;
            }
            int numOffset              = offset;
            var haveDecimalPoint       = false;
            var haveDigits             = false;
            var haveDigitsAfterDecimal = false;
            var haveExponent           = false;
            int i = offset;
            var decimalPointPos = -1;
            // Check syntax
            int k = i;

            if (endPos - 1 > k && chars[k] == '0' && chars[k + 1] >= '0' &&
                chars[k + 1] <= '9')
            {
                if (endOfNumber != null)
                {
                    endOfNumber[0] = k + 2;
                }
                return(null);
            }
            for (; k < endPos; ++k)
            {
                byte c = chars[k];
                if (c >= '0' && c <= '9')
                {
                    haveDigits              = true;
                    haveDigitsAfterDecimal |= haveDecimalPoint;
                }
                else if (c == '.')
                {
                    if (!haveDigits || haveDecimalPoint)
                    {
                        // no digits before the decimal point,
                        // or decimal point already seen
                        if (endOfNumber != null)
                        {
                            endOfNumber[0] = k;
                        }
                        return(null);
                    }
                    haveDecimalPoint = true;
                    decimalPointPos  = k;
                }
                else if (c == 'E' || c == 'e')
                {
                    ++k;
                    haveExponent = true;
                    break;
                }
                else
                {
                    if (endOfNumber != null)
                    {
                        endOfNumber[0] = k;
                        // Check if character can validly appear after a JSON number
                        if (c != ',' && c != ']' && c != '}' &&
                            c != 0x20 && c != 0x0a && c != 0x0d && c != 0x09)
                        {
                            return(null);
                        }
                        else
                        {
                            endPos = k;
                            break;
                        }
                    }
                    return(null);
                }
            }
            if (!haveDigits || (haveDecimalPoint && !haveDigitsAfterDecimal))
            {
                if (endOfNumber != null)
                {
                    endOfNumber[0] = k;
                }
                return(null);
            }
            var exponentPos = -1;
            var negativeExp = false;

            if (haveExponent)
            {
                haveDigits = false;
                if (k == endPos)
                {
                    if (endOfNumber != null)
                    {
                        endOfNumber[0] = k;
                    }
                    return(null);
                }
                byte c = chars[k];
                if (c == '+')
                {
                    ++k;
                }
                else if (c == '-')
                {
                    negativeExp = true;
                    ++k;
                }
                for (; k < endPos; ++k)
                {
                    c = chars[k];
                    if (c >= '0' && c <= '9')
                    {
                        if (exponentPos < 0 && c != '0')
                        {
                            exponentPos = k;
                        }
                        haveDigits = true;
                    }
                    else if (endOfNumber != null)
                    {
                        endOfNumber[0] = k;
                        // Check if character can validly appear after a JSON number
                        if (c != ',' && c != ']' && c != '}' &&
                            c != 0x20 && c != 0x0a && c != 0x0d && c != 0x09)
                        {
                            return(null);
                        }
                        else
                        {
                            endPos = k;
                            break;
                        }
                    }
                    else
                    {
                        return(null);
                    }
                }
                if (!haveDigits)
                {
                    if (endOfNumber != null)
                    {
                        endOfNumber[0] = k;
                    }
                    return(null);
                }
            }
            if (endOfNumber != null)
            {
                endOfNumber[0] = endPos;
            }
            if (exponentPos >= 0 && endPos - exponentPos > 20)
            {
                // Exponent too high for precision to overcome (which
                // has a length no bigger than Int32.MaxValue, which is 10 digits
                // long)
                if (negativeExp)
                {
                    // underflow
                    if (kind == JSONOptions.ConversionMode.Double ||
                        kind == JSONOptions.ConversionMode.IntOrFloat)
                    {
                        if (!negative)
                        {
                            return(CBORObject.FromFloatingPointBits(0, 2));
                        }
                        else
                        {
                            return(CBORObject.FromFloatingPointBits(0x8000, 2));
                        }
                    }
                    else if (kind ==
                             JSONOptions.ConversionMode.IntOrFloatFromDouble)
                    {
                        return(CBORObject.FromObject(0));
                    }
                }
                else
                {
                    // overflow
                    if (kind == JSONOptions.ConversionMode.Double ||
                        kind == JSONOptions.ConversionMode.IntOrFloatFromDouble ||
                        kind == JSONOptions.ConversionMode.IntOrFloat)
                    {
                        return(CBORObject.FromFloatingPointBits(
                                   negative ? DoubleNegInfinity : DoublePosInfinity,
                                   8));
                    }
                    else if (kind == JSONOptions.ConversionMode.Decimal128)
                    {
                        return(CBORObject.FromObject(negative ?
                                                     EDecimal.NegativeInfinity : EDecimal.PositiveInfinity));
                    }
                }
            }
            if (!haveExponent && !haveDecimalPoint &&
                (endPos - numOffset) <= 16)
            {
                // Very common case of all-digit JSON number strings
                // less than 2^53 (with or without number sign)
                long v  = 0L;
                int  vi = numOffset;
                for (; vi < endPos; ++vi)
                {
                    v = (v * 10) + (int)(chars[vi] - '0');
                }
                if ((v != 0 || !negative) && v < (1L << 53) - 1)
                {
                    if (negative)
                    {
                        v = -v;
                    }
                    if (kind == JSONOptions.ConversionMode.Double)
                    {
                        return(CBORObject.FromFloatingPointBits(EFloat.FromInt64(v).ToDoubleBits(), 8));
                    }
                    else if (kind == JSONOptions.ConversionMode.Decimal128)
                    {
                        return(CBORObject.FromObject(EDecimal.FromInt64(v)));
                    }
                    else
                    {
                        return(CBORObject.FromObject(v));
                    }
                }
            }
            if (kind == JSONOptions.ConversionMode.Full)
            {
                if (!haveDecimalPoint && !haveExponent)
                {
                    EInteger ei = EInteger.FromSubstring(chars, initialOffset, endPos);
                    if (preserveNegativeZero && ei.IsZero && negative)
                    {
                        // TODO: In next major version, change to EDecimal.NegativeZero
                        return(CBORObject.FromFloatingPointBits(0x8000, 2));
                    }
                    return(CBORObject.FromObject(ei));
                }
                if (!haveExponent && haveDecimalPoint)
                {
                    // No more than 18 digits plus one decimal point (which
                    // should fit a long)
                    long lv         = 0L;
                    int  expo       = -(endPos - (decimalPointPos + 1));
                    int  vi         = numOffset;
                    var  digitCount = 0;
                    for (; vi < decimalPointPos; ++vi)
                    {
                        if (digitCount < 0 || digitCount >= 18)
                        {
                            digitCount = -1;
                            break;
                        }
                        else if (digitCount > 0 || chars[vi] != '0')
                        {
                            ++digitCount;
                        }
                        lv = checked ((lv * 10) + (int)(chars[vi] - '0'));
                    }
                    for (vi = decimalPointPos + 1; vi < endPos; ++vi)
                    {
                        if (digitCount < 0 || digitCount >= 18)
                        {
                            digitCount = -1;
                            break;
                        }
                        else if (digitCount > 0 || chars[vi] != '0')
                        {
                            ++digitCount;
                        }
                        lv = checked ((lv * 10) + (int)(chars[vi] - '0'));
                    }
                    if (negative)
                    {
                        lv = -lv;
                    }
                    if (digitCount >= 0 && (!negative || lv != 0))
                    {
                        if (expo == 0)
                        {
                            return(CBORObject.FromObject(lv));
                        }
                        else
                        {
                            CBORObject cbor = CBORObject.FromArrayBackedObject(
                                new CBORObject[] {
                                CBORObject.FromObject(expo),
                                CBORObject.FromObject(lv),
                            });
                            return(cbor.WithTag(4));
                        }
                    }
                }
                // DebugUtility.Log("convfull " + chars.Substring(initialOffset, endPos -
                // initialOffset));
                EDecimal ed = EDecimal.FromString(
                    chars,
                    initialOffset,
                    endPos - initialOffset);
                if (ed.IsZero && negative)
                {
                    if (ed.Exponent.IsZero)
                    {
                        // TODO: In next major version, use EDecimal
                        // for preserveNegativeZero
                        return(preserveNegativeZero ?
                               CBORObject.FromFloatingPointBits(0x8000, 2) :
                               CBORObject.FromObject(0));
                    }
                    else if (!preserveNegativeZero)
                    {
                        return(CBORObject.FromObject(ed.Negate()));
                    }
                    else
                    {
                        return(CBORObject.FromObject(ed));
                    }
                }
                else
                {
                    return(ed.Exponent.IsZero ? CBORObject.FromObject(ed.Mantissa) :
                           CBORObject.FromObject(ed));
                }
            }
            else if (kind == JSONOptions.ConversionMode.Double)
            {
                EFloat ef = EFloat.FromString(
                    chars,
                    initialOffset,
                    endPos - initialOffset,
                    EContext.Binary64);
                long lb = ef.ToDoubleBits();
                if (!preserveNegativeZero && (lb == 1L << 63 || lb == 0L))
                {
                    lb = 0L;
                }
                return(CBORObject.FromFloatingPointBits(lb, 8));
            }
            else if (kind == JSONOptions.ConversionMode.Decimal128)
            {
                EDecimal ed = EDecimal.FromString(
                    chars,
                    initialOffset,
                    endPos - initialOffset,
                    EContext.Decimal128);
                if (!preserveNegativeZero && ed.IsNegative && ed.IsZero)
                {
                    ed = ed.Negate();
                }
                return(CBORObject.FromObject(ed));
            }
            else if (kind == JSONOptions.ConversionMode.IntOrFloatFromDouble)
            {
                EFloat ef = EFloat.FromString(
                    chars,
                    initialOffset,
                    endPos - initialOffset,
                    EContext.Binary64);
                long lb = ef.ToDoubleBits();
                return((!CBORUtilities.IsBeyondSafeRange(lb) &&
                        CBORUtilities.IsIntegerValue(lb)) ?
                       CBORObject.FromObject(CBORUtilities.GetIntegerValue(lb)) :
                       CBORObject.FromFloatingPointBits(lb, 8));
            }
            else if (kind == JSONOptions.ConversionMode.IntOrFloat)
            {
                EContext ctx = EContext.Binary64.WithBlankFlags();
                EFloat   ef  = EFloat.FromString(
                    chars,
                    initialOffset,
                    endPos - initialOffset,
                    ctx);
                long lb = ef.ToDoubleBits();
                if ((ctx.Flags & EContext.FlagInexact) != 0)
                {
                    // Inexact conversion to double, meaning that the string doesn't
                    // represent an integer in [-(2^53)+1, 2^53), which is representable
                    // exactly as double, so treat as ConversionMode.Double
                    if (!preserveNegativeZero && (lb == 1L << 63 || lb == 0L))
                    {
                        lb = 0L;
                    }
                    return(CBORObject.FromFloatingPointBits(lb, 8));
                }
                else
                {
                    // Exact conversion; treat as ConversionMode.IntToFloatFromDouble
                    return((!CBORUtilities.IsBeyondSafeRange(lb) &&
                            CBORUtilities.IsIntegerValue(lb)) ?
                           CBORObject.FromObject(CBORUtilities.GetIntegerValue(lb)) :
                           CBORObject.FromFloatingPointBits(lb, 8));
                }
            }
            else
            {
                throw new ArgumentException("Unsupported conversion kind.");
            }
        }
Beispiel #7
0
 internal static BigInteger ToLegacy(EInteger ei)
 {
     return(new BigInteger(ei));
 }
Beispiel #8
0
        /*
         * // Example: Apple Time is a 32-bit unsigned integer
         * // of the number of seconds since the start of 1904.
         * // EInteger appleTime = GetNumberOfDaysProlepticGregorian(
         *   // year, // month
         *   //,
         *   day)
         * // .Subtract(GetNumberOfDaysProlepticGregorian(
         * // EInteger.FromInt32(1904),
         * 1 // ,
         * s1));*/
        public static EInteger GetNumberOfDaysProlepticGregorian(
            EInteger year,
            int month,
            int mday)
        {
            // NOTE: month = 1 is January, year = 1 is year 1
            if (month <= 0 || month > 12)
            {
                throw new ArgumentOutOfRangeException(nameof(month));
            }
            if (mday <= 0 || mday > 31)
            {
                throw new ArgumentOutOfRangeException(nameof(mday));
            }
            EInteger numDays   = EInteger.Zero;
            var      startYear = 1970;

            if (year.CompareTo(startYear) < 0)
            {
                EInteger ei   = EInteger.FromInt32(startYear - 1);
                EInteger diff = ei.Subtract(year);

                if (diff.CompareTo(401) > 0)
                {
                    EInteger blocks = diff.Subtract(401).Divide(400);
                    numDays = numDays.Subtract(blocks.Multiply(146097));
                    diff    = diff.Subtract(blocks.Multiply(400));
                    ei      = ei.Subtract(blocks.Multiply(400));
                }

                numDays = numDays.Subtract(diff.Multiply(365));
                var decrement = 1;
                for (;
                     ei.CompareTo(year) > 0;
                     ei = ei.Subtract(decrement))
                {
                    if (decrement == 1 && ei.Remainder(4).Sign == 0)
                    {
                        decrement = 4;
                    }
                    if (!(ei.Remainder(4).Sign != 0 || (
                              ei.Remainder(100).Sign == 0 && ei.Remainder(400).Sign !=
                              0)))
                    {
                        numDays = numDays.Subtract(1);
                    }
                }
                if (year.Remainder(4).Sign != 0 || (
                        year.Remainder(100).Sign == 0 && year.Remainder(400).Sign != 0))
                {
                    numDays = numDays.Subtract(365 - ValueNormalToMonth[month])
                              .Subtract(ValueNormalDays[month] - mday + 1);
                }
                else
                {
                    numDays = numDays
                              .Subtract(366 - ValueLeapToMonth[month])
                              .Subtract(ValueLeapDays[month] - mday + 1);
                }
            }
            else
            {
                bool isNormalYear = year.Remainder(4).Sign != 0 ||
                                    (year.Remainder(100).Sign == 0 && year.Remainder(400).Sign != 0);

                EInteger ei = EInteger.FromInt32(startYear);
                if (ei.Add(401).CompareTo(year) < 0)
                {
                    EInteger y2 = year.Subtract(2);
                    numDays = numDays.Add(
                        y2.Subtract(startYear).Divide(400).Multiply(146097));
                    ei = y2.Subtract(
                        y2.Subtract(startYear).Remainder(400));
                }

                EInteger diff = year.Subtract(ei);
                numDays = numDays.Add(diff.Multiply(365));
                EInteger eileap = ei;
                if (ei.Remainder(4).Sign != 0)
                {
                    eileap = eileap.Add(4 - eileap.Remainder(4).ToInt32Checked());
                }
                numDays = numDays.Add(year.Subtract(eileap).Add(3).Divide(4));
                if (ei.Remainder(100).Sign != 0)
                {
                    ei = ei.Add(100 - ei.Remainder(100).ToInt32Checked());
                }
                while (ei.CompareTo(year) < 0)
                {
                    if (ei.Remainder(400).Sign != 0)
                    {
                        numDays = numDays.Subtract(1);
                    }
                    ei = ei.Add(100);
                }
                int yearToMonth = isNormalYear ? ValueNormalToMonth[month - 1] :
                                  ValueLeapToMonth[month - 1];
                numDays = numDays.Add(yearToMonth)
                          .Add(mday - 1);
            }
            return(numDays);
        }
Beispiel #9
0
        public static string ToAtomDateTimeString(
            EInteger bigYear,
            int[] lesserFields)
        {
            if (lesserFields[6] != 0)
            {
                throw new NotSupportedException(
                          "Local time offsets not supported");
            }
            int smallYear = bigYear.ToInt32Checked();

            if (smallYear < 0)
            {
                throw new ArgumentException("year(" + smallYear +
                                            ") is not greater or equal to 0");
            }
            if (smallYear > 9999)
            {
                throw new ArgumentException("year(" + smallYear +
                                            ") is not less or equal to 9999");
            }
            int month       = lesserFields[0];
            int day         = lesserFields[1];
            int hour        = lesserFields[2];
            int minute      = lesserFields[3];
            int second      = lesserFields[4];
            int fracSeconds = lesserFields[5];
            var charbuf     = new char[32];

            charbuf[0]  = (char)('0' + ((smallYear / 1000) % 10));
            charbuf[1]  = (char)('0' + ((smallYear / 100) % 10));
            charbuf[2]  = (char)('0' + ((smallYear / 10) % 10));
            charbuf[3]  = (char)('0' + (smallYear % 10));
            charbuf[4]  = '-';
            charbuf[5]  = (char)('0' + ((month / 10) % 10));
            charbuf[6]  = (char)('0' + (month % 10));
            charbuf[7]  = '-';
            charbuf[8]  = (char)('0' + ((day / 10) % 10));
            charbuf[9]  = (char)('0' + (day % 10));
            charbuf[10] = 'T';
            charbuf[11] = (char)('0' + ((hour / 10) % 10));
            charbuf[12] = (char)('0' + (hour % 10));
            charbuf[13] = ':';
            charbuf[14] = (char)('0' + ((minute / 10) % 10));
            charbuf[15] = (char)('0' + (minute % 10));
            charbuf[16] = ':';
            charbuf[17] = (char)('0' + ((second / 10) % 10));
            charbuf[18] = (char)('0' + (second % 10));
            var charbufLength = 19;

            if (fracSeconds > 0)
            {
                charbuf[19] = '.';
                ++charbufLength;
                var digitdiv = 100000000;
                var index    = 20;
                while (digitdiv > 0 && fracSeconds != 0)
                {
                    int digit = (fracSeconds / digitdiv) % 10;
                    fracSeconds     -= digit * digitdiv;
                    charbuf[index++] = (char)('0' + digit);
                    ++charbufLength;
                    digitdiv /= 10;
                }
                charbuf[index] = 'Z';
                ++charbufLength;
            }
            else
            {
                charbuf[19] = 'Z';
                ++charbufLength;
            }
            return(new String(charbuf, 0, charbufLength));
        }
Beispiel #10
0
 private static EInteger FloorMod(EInteger a, EInteger n)
 {
     return(a.Subtract(FloorDiv(a, n).Multiply(n)));
 }
Beispiel #11
0
 public static void GetNormalizedPartProlepticGregorian(
     EInteger year,
     int month,
     EInteger day,
     EInteger[] dest)
 {
     // NOTE: This method assumes month is 1 to 12
     if (month <= 0 || month > 12)
     {
         throw new ArgumentOutOfRangeException(nameof(month));
     }
     int[] dayArray = (year.Remainder(4).Sign != 0 || (
                           year.Remainder(100).Sign == 0 && year.Remainder(400).Sign !=
                           0)) ?
                      ValueNormalDays : ValueLeapDays;
     if (day.CompareTo(101) > 0)
     {
         EInteger count = day.Subtract(100).Divide(146097);
         day  = day.Subtract(count.Multiply(146097));
         year = year.Add(count.Multiply(400));
     }
     while (true)
     {
         EInteger days = EInteger.FromInt32(dayArray[month]);
         if (day.Sign > 0 && day.CompareTo(days) <= 0)
         {
             break;
         }
         if (day.CompareTo(days) > 0)
         {
             day = day.Subtract(days);
             if (month == 12)
             {
                 month    = 1;
                 year     = year.Add(1);
                 dayArray = (year.Remainder(4).Sign != 0 || (
                                 year.Remainder(100).Sign == 0 &&
                                 year.Remainder(400).Sign != 0)) ? ValueNormalDays :
                            ValueLeapDays;
             }
             else
             {
                 ++month;
             }
         }
         if (day.Sign <= 0)
         {
             --month;
             if (month <= 0)
             {
                 year  = year.Add(-1);
                 month = 12;
             }
             dayArray = (year.Remainder(4).Sign != 0 || (
                             year.Remainder(100).Sign == 0 &&
                             year.Remainder(400).Sign != 0)) ? ValueNormalDays :
                        ValueLeapDays;
             day = day.Add(dayArray[month]);
         }
     }
     dest[0] = year;
     dest[1] = EInteger.FromInt32(month);
     dest[2] = day;
 }
Beispiel #12
0
 private static EInteger FloorDiv(EInteger a, EInteger n)
 {
     return(a.Sign >= 0 ? a.Divide(n) : EInteger.FromInt32(-1).Subtract(
                EInteger.FromInt32(-1).Subtract(a).Divide(n)));
 }
Beispiel #13
0
        internal FastInteger2 Add(FastInteger2 val)
        {
            EInteger valValue;

            switch (this.integerMode)
            {
            case 0:
                if (val.integerMode == 0)
                {
                    if ((this.smallValue < 0 && (int)val.smallValue < Int32.MinValue
                         - this.smallValue) ||
                        (this.smallValue > 0 && (int)val.smallValue > Int32.MaxValue
                         - this.smallValue))
                    {
                        // would overflow
                        if (val.smallValue >= 0)
                        {
                            this.integerMode = 1;
                            this.mnum        = new MutableNumber(this.smallValue);
                            this.mnum.Add(val.smallValue);
                        }
                        else
                        {
                            this.integerMode = 2;
                            this.largeValue  = (EInteger)this.smallValue;
                            this.largeValue += (EInteger)val.smallValue;
                        }
                    }
                    else
                    {
                        this.smallValue += val.smallValue;
                    }
                }
                else
                {
                    integerMode = 2;
                    largeValue  = (EInteger)smallValue;
                    valValue    = val.AsBigInteger();
                    largeValue += (EInteger)valValue;
                }
                break;

            case 1:
                if (val.integerMode == 0 && val.smallValue >= 0)
                {
                    this.mnum.Add(val.smallValue);
                }
                else
                {
                    integerMode = 2;
                    largeValue  = mnum.ToEInteger();
                    valValue    = val.AsBigInteger();
                    largeValue += (EInteger)valValue;
                }
                break;

            case 2:
                valValue         = val.AsBigInteger();
                this.largeValue += (EInteger)valValue;
                break;

            default: throw new InvalidOperationException();
            }
            return(this);
        }
Beispiel #14
0
        /// <include file='../../docs.xml'
        /// path='docs/doc[@name="M:FastInteger2.Subtract(FastInteger2)"]/*'/>
        internal FastInteger2 Subtract(FastInteger2 val)
        {
            EInteger valValue;

            switch (this.integerMode)
            {
            case 0:
                if (val.integerMode == 0)
                {
                    int vsv = val.smallValue;
                    if ((vsv < 0 && Int32.MaxValue + vsv < this.smallValue) ||
                        (vsv > 0 && Int32.MinValue + vsv > this.smallValue))
                    {
                        // would overflow, convert to large
                        this.integerMode = 2;
                        this.largeValue  = (EInteger)this.smallValue;
                        this.largeValue -= (EInteger)vsv;
                    }
                    else
                    {
                        this.smallValue -= vsv;
                    }
                }
                else
                {
                    integerMode = 2;
                    largeValue  = (EInteger)smallValue;
                    valValue    = val.AsBigInteger();
                    largeValue -= (EInteger)valValue;
                }
                break;

            case 1:
                if (val.integerMode == 1)
                {
                    // NOTE: Mutable numbers are
                    // currently always zero or positive
                    this.mnum.Subtract(val.mnum);
                }
                else if (val.integerMode == 0 && val.smallValue >= 0)
                {
                    mnum.SubtractInt(val.smallValue);
                }
                else
                {
                    integerMode = 2;
                    largeValue  = mnum.ToEInteger();
                    valValue    = val.AsBigInteger();
                    largeValue -= (EInteger)valValue;
                }
                break;

            case 2:
                valValue         = val.AsBigInteger();
                this.largeValue -= (EInteger)valValue;
                break;

            default: throw new InvalidOperationException();
            }
            return(this);
        }
Beispiel #15
0
        public static StringAndBigInt Generate(
            IRandomGenExtended rand,
            int radix,
            int maxNumDigits)
        {
            if (radix < 2)
            {
                throw new ArgumentException("radix(" + radix +
                                            ") is less than 2");
            }
            if (radix > 36)
            {
                throw new ArgumentException("radix(" + radix +
                                            ") is more than 36");
            }
            EInteger bv        = EInteger.Zero;
            var      sabi      = new StringAndBigInt();
            int      numDigits = 1 + rand.GetInt32(maxNumDigits);
            var      negative  = false;
            var      builder   = new StringBuilder();

            if (rand.GetInt32(2) == 0)
            {
                builder.Append('-');
                negative = true;
            }
            int      radixpowint = radix * radix * radix * radix;
            EInteger radixpow4   = EInteger.FromInt32(radixpowint);
            EInteger radixpow1   = EInteger.FromInt32(radix);
            var      count       = 0;

            for (int i = 0; i < numDigits - 4; i += 4)
            {
                int digitvalues = rand.GetInt32(radixpowint);
                int digit       = digitvalues % radix;
                digitvalues /= radix;
                int digit2 = digitvalues % radix;
                digitvalues /= radix;
                int digit3 = digitvalues % radix;
                digitvalues /= radix;
                int digit4 = digitvalues % radix;
                digitvalues /= radix;
                count       += 4;
                int bits = rand.GetInt32(16);
                if ((bits & 0x01) == 0)
                {
                    builder.Append(ValueDigits[digit]);
                }
                else
                {
                    builder.Append(ValueDigitsLower[digit]);
                }
                if ((bits & 0x02) == 0)
                {
                    builder.Append(ValueDigits[digit2]);
                }
                else
                {
                    builder.Append(ValueDigitsLower[digit2]);
                }
                if ((bits & 0x04) == 0)
                {
                    builder.Append(ValueDigits[digit3]);
                }
                else
                {
                    builder.Append(ValueDigitsLower[digit3]);
                }
                if ((bits & 0x08) == 0)
                {
                    builder.Append(ValueDigits[digit4]);
                }
                else
                {
                    builder.Append(ValueDigitsLower[digit4]);
                }
                int digits = (((((digit * radix) + digit2) *
                                radix) + digit3) * radix) + digit4;
                bv *= radixpow4;
                var bigintTmp = (EInteger)digits;
                bv += bigintTmp;
            }
            for (int i = count; i < numDigits; ++i)
            {
                int digit = rand.GetInt32(radix);
                if (rand.GetInt32(2) == 0)
                {
                    builder.Append(ValueDigits[digit]);
                }
                else
                {
                    builder.Append(ValueDigitsLower[digit]);
                }
                bv *= radixpow1;
                var bigintTmp = (EInteger)digit;
                bv += bigintTmp;
            }
            if (negative)
            {
                bv = -bv;
            }
            sabi.bigintValue = bv;
            sabi.stringValue = builder.ToString();
            return(sabi);
        }
Beispiel #16
0
        public static EInteger BigIntegerFromDouble(double dbl)
        {
            long lvalue = BitConverter.ToInt64(
                BitConverter.GetBytes((double)dbl),
                0);
            int  value0        = unchecked ((int)(lvalue & 0xffffffffL));
            int  value1        = unchecked ((int)((lvalue >> 32) & 0xffffffffL));
            var  floatExponent = (int)((value1 >> 20) & 0x7ff);
            bool neg           = (value1 >> 31) != 0;

            if (floatExponent == 2047)
            {
                throw new OverflowException("Value is infinity or NaN");
            }
            value1 &= 0xfffff; // Mask out the exponent and sign
            if (floatExponent == 0)
            {
                ++floatExponent;
            }
            else
            {
                value1 |= 0x100000;
            }
            if ((value1 | value0) != 0)
            {
                while ((value0 & 1) == 0)
                {
                    value0 >>= 1;
                    value0  &= 0x7fffffff;
                    value0   = unchecked (value0 | (value1 << 31));
                    value1 >>= 1;
                    ++floatExponent;
                }
            }
            floatExponent -= 1075;
            var      bytes = new byte[9];
            EInteger bigmantissa;

            bytes[0]    = (byte)(value0 & 0xff);
            bytes[1]    = (byte)((value0 >> 8) & 0xff);
            bytes[2]    = (byte)((value0 >> 16) & 0xff);
            bytes[3]    = (byte)((value0 >> 24) & 0xff);
            bytes[4]    = (byte)(value1 & 0xff);
            bytes[5]    = (byte)((value1 >> 8) & 0xff);
            bytes[6]    = (byte)((value1 >> 16) & 0xff);
            bytes[7]    = (byte)((value1 >> 24) & 0xff);
            bytes[8]    = (byte)0;
            bigmantissa = EInteger.FromBytes(bytes, true);
            if (floatExponent == 0)
            {
                if (neg)
                {
                    bigmantissa = -bigmantissa;
                }
                return(bigmantissa);
            }
            if (floatExponent > 0)
            {
                // Value is an integer
                bigmantissa <<= floatExponent;
                if (neg)
                {
                    bigmantissa = -(EInteger)bigmantissa;
                }
                return(bigmantissa);
            }
            else
            {
                // Value has a fractional part
                int exp = -floatExponent;
                bigmantissa >>= exp;
                if (neg)
                {
                    bigmantissa = -(EInteger)bigmantissa;
                }
                return(bigmantissa);
            }
        }
Beispiel #17
0
        public CBORObject ReadForFirstByte(int firstbyte)
        {
            if (this.depth > 500)
            {
                throw new CBORException("Too deeply nested");
            }
            if (firstbyte < 0)
            {
                throw new CBORException("Premature end of data");
            }
            if (firstbyte == 0xff)
            {
                throw new CBORException("Unexpected break code encountered");
            }
            int  type       = (firstbyte >> 5) & 0x07;
            int  additional = firstbyte & 0x1f;
            long uadditional;

            if (this.options.Ctap2Canonical)
            {
                if (additional >= 0x1c)
                {
                    // NOTE: Includes stop byte and indefinite length data items
                    throw new CBORException("Invalid canonical CBOR encountered");
                }
                if (type == 6)
                {
                    throw new CBORException("Tags not allowed in canonical CBOR");
                }
                uadditional = ReadDataLength(this.stream, firstbyte, type, type == 7);
                if (type == 0)
                {
                    return((uadditional >> 63) != 0 ?
                           CBORObject.FromObject(ToUnsignedEInteger(uadditional)) :
                           CBORObject.FromObject(uadditional));
                }
                else if (type == 1)
                {
                    return((uadditional >> 63) != 0 ?

                           CBORObject.FromObject(
                               ToUnsignedEInteger(uadditional).Add(1).Negate())
:
                           CBORObject.FromObject((-uadditional) - 1L));
                }
                else if (type == 7)
                {
                    if (additional < 24)
                    {
                        return(CBORObject.FromSimpleValue(additional));
                    }
                    else if (additional == 24 && uadditional < 32)
                    {
                        throw new CBORException("Invalid simple value encoding");
                    }
                    else if (additional == 24)
                    {
                        return(CBORObject.FromSimpleValue((int)uadditional));
                    }
                    else if (additional == 25)
                    {
                        return(CBORObject.FromFloatingPointBits(uadditional, 2));
                    }
                    else if (additional == 26)
                    {
                        return(CBORObject.FromFloatingPointBits(uadditional, 4));
                    }
                    else if (additional == 27)
                    {
                        return(CBORObject.FromFloatingPointBits(uadditional, 8));
                    }
                }
                else if (type >= 2 && type <= 5)
                {
                    return(this.ReadStringArrayMap(type, uadditional));
                }
                throw new CBORException("Unexpected data encountered");
            }
            int expectedLength = CBORObject.GetExpectedLength(firstbyte);

            // Data checks
            if (expectedLength == -1)
            {
                // if the head byte is invalid
                throw new CBORException("Unexpected data encountered");
            }
            // Check if this represents a fixed object
            CBORObject fixedObject = CBORObject.GetFixedObject(firstbyte);

            if (fixedObject != null)
            {
                return(fixedObject);
            }
            // Read fixed-length data
            byte[] data = null;
            if (expectedLength != 0)
            {
                data = new byte[expectedLength];
                // include the first byte because GetFixedLengthObject
                // will assume it exists for some head bytes
                data[0] = unchecked ((byte)firstbyte);
                if (expectedLength > 1 &&
                    this.stream.Read(data, 1, expectedLength - 1) != expectedLength
                    - 1)
                {
                    throw new CBORException("Premature end of data");
                }
                CBORObject cbor = CBORObject.GetFixedLengthObject(firstbyte, data);
                if (this.stringRefs != null && (type == 2 || type == 3))
                {
                    this.stringRefs.AddStringIfNeeded(cbor, expectedLength - 1);
                }
                return(cbor);
            }
            if (additional == 31)
            {
                // Indefinite-length for major types 2 to 5 (other major
                // types were already handled in the call to
                // GetFixedLengthObject).
                switch (type)
                {
                case 2: {
                    // Streaming byte string
                    using (var ms = new MemoryStream()) {
                        // Requires same type as this one
                        while (true)
                        {
                            int nextByte = this.stream.ReadByte();
                            if (nextByte == 0xff)
                            {
                                // break if the "break" code was read
                                break;
                            }
                            long len = ReadDataLength(this.stream, nextByte, 2);
                            if ((len >> 63) != 0 || len > Int32.MaxValue)
                            {
                                throw new CBORException("Length" + ToUnsignedEInteger(len) +
                                                        " is bigger than supported ");
                            }
                            if (nextByte != 0x40)
                            {
                                // NOTE: 0x40 means the empty byte string
                                ReadByteData(this.stream, len, ms);
                            }
                        }
                        if (ms.Position > Int32.MaxValue)
                        {
                            throw new
                                  CBORException("Length of bytes to be streamed is bigger than supported ");
                        }
                        data = ms.ToArray();
                        return(CBORObject.FromRaw(data));
                    }
                }

                case 3: {
                    // Streaming text string
                    var builder = new StringBuilder();
                    while (true)
                    {
                        int nextByte = this.stream.ReadByte();
                        if (nextByte == 0xff)
                        {
                            // break if the "break" code was read
                            break;
                        }
                        long len = ReadDataLength(this.stream, nextByte, 3);
                        if ((len >> 63) != 0 || len > Int32.MaxValue)
                        {
                            throw new CBORException("Length" + ToUnsignedEInteger(len) +
                                                    " is bigger than supported");
                        }
                        if (nextByte != 0x60)
                        {
                            // NOTE: 0x60 means the empty string
                            if (PropertyMap.ExceedsKnownLength(this.stream, len))
                            {
                                throw new CBORException("Premature end of data");
                            }
                            switch (
                                DataUtilities.ReadUtf8(
                                    this.stream,
                                    (int)len,
                                    builder,
                                    false))
                            {
                            case -1:
                                throw new CBORException("Invalid UTF-8");

                            case -2:
                                throw new CBORException("Premature end of data");
                            }
                        }
                    }
                    return(CBORObject.FromRaw(builder.ToString()));
                }

                case 4: {
                    CBORObject cbor    = CBORObject.NewArray();
                    var        vtindex = 0;
                    // Indefinite-length array
                    while (true)
                    {
                        int headByte = this.stream.ReadByte();
                        if (headByte < 0)
                        {
                            throw new CBORException("Premature end of data");
                        }
                        if (headByte == 0xff)
                        {
                            // Break code was read
                            break;
                        }
                        ++this.depth;
                        CBORObject o = this.ReadForFirstByte(
                            headByte);
                        --this.depth;
                        cbor.Add(o);
                        ++vtindex;
                    }
                    return(cbor);
                }

                case 5: {
                    CBORObject cbor = CBORObject.NewMap();
                    // Indefinite-length map
                    while (true)
                    {
                        int headByte = this.stream.ReadByte();
                        if (headByte < 0)
                        {
                            throw new CBORException("Premature end of data");
                        }
                        if (headByte == 0xff)
                        {
                            // Break code was read
                            break;
                        }
                        ++this.depth;
                        CBORObject key   = this.ReadForFirstByte(headByte);
                        CBORObject value = this.ReadInternal();
                        --this.depth;
                        if (!this.options.AllowDuplicateKeys)
                        {
                            if (cbor.ContainsKey(key))
                            {
                                throw new CBORException("Duplicate key already exists");
                            }
                        }
                        cbor[key] = value;
                    }
                    return(cbor);
                }

                default: throw new CBORException("Unexpected data encountered");
                }
            }
            EInteger bigintAdditional = EInteger.Zero;

            uadditional = ReadDataLength(this.stream, firstbyte, type);
            // The following doesn't check for major types 0 and 1,
            // since all of them are fixed-length types and are
            // handled in the call to GetFixedLengthObject.
            if (type >= 2 && type <= 5)
            {
                return(this.ReadStringArrayMap(type, uadditional));
            }
            if (type == 6) // Tagged item
            {
                var haveFirstByte = false;
                var newFirstByte  = -1;
                if (this.options.ResolveReferences && (uadditional >> 32) == 0)
                {
                    // NOTE: HandleItemTag treats only certain tags up to 256 specially
                    this.HandleItemTag(uadditional);
                }
                ++this.depth;
                CBORObject o = haveFirstByte ? this.ReadForFirstByte(
                    newFirstByte) : this.ReadInternal();
                --this.depth;
                if ((uadditional >> 63) != 0)
                {
                    return(CBORObject.FromObjectAndTag(o,
                                                       ToUnsignedEInteger(uadditional)));
                }
                if (uadditional < 65536)
                {
                    if (this.options.ResolveReferences)
                    {
                        int uaddl = uadditional >= 257 ? 257 : (uadditional < 0 ? 0 :
                                                                (int)uadditional);
                        switch (uaddl)
                        {
                        case 256:
                            // string tag
                            this.stringRefs.Pop();
                            break;

                        case 25:
                            // stringref tag
                            if (o.IsTagged || o.Type != CBORType.Integer)
                            {
                                throw new CBORException("stringref must be an unsigned" +
                                                        "\u0020integer");
                            }
                            return(this.stringRefs.GetString(o.AsEIntegerValue()));
                        }
                    }
                    return(CBORObject.FromObjectAndTag(
                               o,
                               (int)uadditional));
                }
                return(CBORObject.FromObjectAndTag(
                           o,
                           (EInteger)uadditional));
            }
            throw new CBORException("Unexpected data encountered");
        }
Beispiel #18
0
        public static EDecimal RandomEDecimal(IRandomGenExtended r, string[]
                                              decimalString)
        {
            if (r == null)
            {
                throw new ArgumentNullException(nameof(r));
            }
            if (r.GetInt32(100) == 0)
            {
                int x = r.GetInt32(3);
                if (x == 0)
                {
                    if (decimalString != null)
                    {
                        decimalString[0] = "Infinity";
                    }
                    return(EDecimal.PositiveInfinity);
                }
                if (x == 1)
                {
                    if (decimalString != null)
                    {
                        decimalString[0] = "-Infinity";
                    }
                    return(EDecimal.NegativeInfinity);
                }
                if (x == 2)
                {
                    if (decimalString != null)
                    {
                        decimalString[0] = "NaN";
                    }
                    return(EDecimal.NaN);
                }
                // Signaling NaN currently not generated because
                // it doesn't round-trip as well
            }
            if (r.GetInt32(100) < 30)
            {
                string str = RandomDecimalString(r);
                if (str.Length < 500)
                {
                    if (decimalString != null)
                    {
                        decimalString[0] = str;
                    }
                    return(EDecimal.FromString(str));
                }
            }
            EInteger emant = RandomEInteger(r);
            EInteger eexp  = null;

            if (r.GetInt32(100) < 95)
            {
                int exp = (r.GetInt32(100) < 80) ? (r.GetInt32(50) - 25) :
                          (r.GetInt32(5000) - 2500);
                eexp = EInteger.FromInt32(exp);
            }
            else
            {
                eexp = RandomEInteger(r);
            }
            EDecimal ed = EDecimal.Create(emant, eexp);

            if (decimalString != null)
            {
                decimalString[0] = emant.ToString() + "E" + eexp.ToString();
            }
            return(ed);
        }
Beispiel #19
0
// Inappropriate to mark these obsolete; they're
// just non-publicly-visible methods to convert to
// and from legacy arbitrary-precision classes
#pragma warning disable 618
        public static BigInteger ToLegacy(EInteger ei)
        {
            return(BigInteger.ToLegacy(ei));
        }
Beispiel #20
0
        public void TestBuiltInTags()
        {
            // As of 4.0, nearly all tags are no longer converted to native objects; thus,
            // DecodeFromBytes no longer fails when such tags are encountered but
            // have the wrong format (though it can fail for other reasons).
            // Tag 2, bignums
            byte[]     bytes;
            var        secondbytes = new byte[] { 0, 0x20, 0x60, 0x80, 0xa0, 0xe0 };
            var        firstbytes  = new byte[] { 0xc2, 0xc3, 0xc4, 0xc5 };
            CBORObject cbor;

            foreach (byte firstbyte in firstbytes)
            {
                foreach (byte secondbyte in secondbytes)
                {
                    bytes = new byte[] { firstbyte, secondbyte };
                    cbor  = CBORObject.DecodeFromBytes(bytes);
                    Assert.IsFalse(cbor.IsNumber, cbor.ToString());
                }
            }
            cbor = CBORObject.DecodeFromBytes(new byte[] {
                0xd8, 0x1e, 0x9f, 0x01,
                0x01, 0xff,
            });
            Assert.IsTrue(cbor.IsNumber, cbor.ToString());

            cbor = CBORObject.DecodeFromBytes(new byte[] {
                0xd8, 0x1e, 0x9f, 0x01,
                0x01, 0x01, 0xff,
            });
            Assert.IsFalse(cbor.IsNumber, cbor.ToString());
            cbor = CBORObject.DecodeFromBytes(new byte[] {
                0xd8, 0x1e, 0x9f, 0x01,
                0xff,
            });
            Assert.IsFalse(cbor.IsNumber, cbor.ToString());

            cbor = CBORObject.DecodeFromBytes(new byte[] {
                0xd9, 0x01, 0x0e, 0x9f,
                0x01,
                0x01, 0xff,
            });
            Assert.IsFalse(cbor.IsNumber, cbor.ToString());

            cbor = CBORObject.DecodeFromBytes(new byte[] {
                0xd9, 0x01, 0x0e, 0x9f,
                0x01,
                0x01, 0x01, 0xff,
            });
            Assert.IsTrue(cbor.IsNumber, cbor.ToString());
            cbor = CBORObject.DecodeFromBytes(new byte[] {
                0xd9, 0x01, 0x0e, 0x9f,
                0x01,
                0xff,
            });
            Assert.IsFalse(cbor.IsNumber, cbor.ToString());

            cbor = CBORObject.DecodeFromBytes(
                new byte[] { 0xd8, 0x1e, 0x9f, 0xff, });
            Assert.IsFalse(cbor.IsNumber, cbor.ToString());

            cbor = CBORObject.DecodeFromBytes(
                new byte[] { 0xd9, 0x01, 0x0e, 0x9f, 0xff, });
            Assert.IsFalse(cbor.IsNumber, cbor.ToString());
            cbor = CBORObject.DecodeFromBytes(new byte[] {
                0xc4, 0x9f, 0x00, 0x00,
                0xff,
            });
            Assert.IsTrue(cbor.IsNumber, cbor.ToString());
            cbor = CBORObject.DecodeFromBytes(new byte[] {
                0xc5, 0x9f, 0x00, 0x00,
                0xff,
            });
            Assert.IsTrue(cbor.IsNumber, cbor.ToString());
            cbor = CBORObject.DecodeFromBytes(new byte[] {
                0xc4, 0x9f, 0x00, 0x00,
                0x00,
                0xff,
            });
            Assert.IsFalse(cbor.IsNumber, cbor.ToString());
            cbor = CBORObject.DecodeFromBytes(new byte[] {
                0xc5, 0x9f, 0x00,
                0x00, 0x00,
                0xff,
            });
            Assert.IsFalse(cbor.IsNumber, cbor.ToString());
            cbor = CBORObject.DecodeFromBytes(new byte[] {
                0xc4, 0x9f, 0x00,
                0xff,
            });
            Assert.IsFalse(cbor.IsNumber, cbor.ToString());
            cbor = CBORObject.DecodeFromBytes(new byte[] {
                0xc5, 0x9f, 0x00,
                0xff,
            });
            Assert.IsFalse(cbor.IsNumber, cbor.ToString());
            cbor = CBORObject.DecodeFromBytes(new byte[] { 0xc4, 0x9f, 0xff, });
            Assert.IsFalse(cbor.IsNumber, cbor.ToString());
            cbor = CBORObject.DecodeFromBytes(new byte[] { 0xc5, 0x9f, 0xff, });
            Assert.IsFalse(cbor.IsNumber, cbor.ToString());
            cbor = CBORObject.DecodeFromBytes(new byte[] { 0xc4, 0x81, 0x00, });
            Assert.IsFalse(cbor.IsNumber, cbor.ToString());
            cbor = CBORObject.DecodeFromBytes(new byte[] { 0xc5, 0x81, 0x00, });
            Assert.IsFalse(cbor.IsNumber, cbor.ToString());
            {
                object objectTemp  = EInteger.Zero;
                object objectTemp2 = CBORObject.DecodeFromBytes(new byte[] {
                    0xc2,
                    0x40,
                }).ToObject(typeof(EInteger));
                Assert.AreEqual(objectTemp, objectTemp2);
            }
            {
                object objectTemp  = EInteger.FromString("-1");
                object objectTemp2 = CBORObject.DecodeFromBytes(new byte[] {
                    0xc3,
                    0x41, 0x00,
                }).ToObject(typeof(EInteger));
                Assert.AreEqual(objectTemp, objectTemp2);
            }
            {
                object objectTemp  = EInteger.FromString("-1");
                object objectTemp2 = CBORObject.DecodeFromBytes(new byte[] {
                    0xc3,
                    0x40,
                }).ToObject(typeof(EInteger));
                Assert.AreEqual(objectTemp, objectTemp2);
            }
        }
Beispiel #21
0
 /// <include file='../docs.xml'
 /// path='docs/doc[@name="M:PeterO.BigInteger.fromBytes(System.Byte[],System.Boolean)"]/*'/>
 public static BigInteger fromBytes(byte[] bytes, bool littleEndian)
 {
     return(new BigInteger(EInteger.FromBytes(bytes, littleEndian)));
 }
Beispiel #22
0
 public void TestNegativeBigInts()
 {
     {
         object objectTemp  = EInteger.FromString("-257");
         object objectTemp2 = CBORObject.DecodeFromBytes(new byte[] {
             0xc3,
             0x42, 1,
             0,
         }).ToObject(typeof(EInteger));
         Assert.AreEqual(objectTemp, objectTemp2);
     }
     {
         object objectTemp  = EInteger.FromString("-65537");
         object objectTemp2 = CBORObject.DecodeFromBytes(new byte[] {
             0xc3,
             0x43, 1,
             0, 0,
         }).ToObject(typeof(EInteger));
         Assert.AreEqual(objectTemp, objectTemp2);
     }
     {
         object objectTemp  = EInteger.FromString("-16777217");
         object objectTemp2 = CBORObject.DecodeFromBytes(new byte[] {
             0xc3, 0x44,
             1,
             0, 0, 0,
         }).ToObject(typeof(EInteger));
         Assert.AreEqual(objectTemp, objectTemp2);
     }
     {
         object objectTemp  = EInteger.FromString("-4294967297");
         object objectTemp2 = CBORObject.DecodeFromBytes(new byte[] {
             0xc3, 0x45,
             1,
             0, 0, 0, 0,
         }).ToObject(typeof(EInteger));
         Assert.AreEqual(objectTemp, objectTemp2);
     }
     {
         object objectTemp  = EInteger.FromString("-1099511627777");
         object objectTemp2 = CBORObject.DecodeFromBytes(new byte[] {
             0xc3, 0x46,
             1,
             0, 0, 0, 0, 0,
         }).ToObject(typeof(EInteger));
         Assert.AreEqual(objectTemp, objectTemp2);
     }
     {
         object objectTemp  = EInteger.FromString("-281474976710657");
         object objectTemp2 = CBORObject.DecodeFromBytes(new byte[] {
             0xc3, 0x47,
             1,
             0, 0, 0, 0,
             0, 0,
         }).ToObject(typeof(EInteger));
         Assert.AreEqual(objectTemp, objectTemp2);
     }
     {
         object objectTemp  = EInteger.FromString("-72057594037927937");
         object objectTemp2 = CBORObject.DecodeFromBytes(new byte[] {
             0xc3, 0x48,
             1,
             0, 0, 0, 0,
             0, 0, 0,
         }).ToObject(typeof(EInteger));
         Assert.AreEqual(objectTemp, objectTemp2);
     }
     {
         object objectTemp  = EInteger.FromString("-18446744073709551617");
         object objectTemp2 = CBORObject.DecodeFromBytes(new byte[] {
             0xc3, 0x49,
             1,
             0, 0, 0, 0, 0, 0, 0, 0,
         }).ToObject(typeof(EInteger));
         Assert.AreEqual(objectTemp, objectTemp2);
     }
     {
         object objectTemp  = EInteger.FromString("-4722366482869645213697");
         object objectTemp2 = CBORObject.DecodeFromBytes(new byte[] {
             0xc3, 0x4a,
             1,
             0, 0, 0, 0, 0, 0, 0, 0, 0,
         }).ToObject(typeof(EInteger));
         Assert.AreEqual(objectTemp, objectTemp2);
     }
 }
Beispiel #23
0
 /// <include file='../docs.xml'
 /// path='docs/doc[@name="M:PeterO.BigInteger.fromString(System.String)"]/*'/>
 public static BigInteger fromString(string str)
 {
     return(new BigInteger(EInteger.FromString(str)));
 }
 public static IntegerNumber ToNumber(this EInteger value)
 => Number.Create(value);
Beispiel #25
0
        public CBORObject ReadForFirstByte(
            int firstbyte,
            CBORTypeFilter filter)
        {
            if (this.depth > 500)
            {
                throw new CBORException("Too deeply nested");
            }
            if (firstbyte < 0)
            {
                throw new CBORException("Premature end of data");
            }
            if (firstbyte == 0xff)
            {
                throw new CBORException("Unexpected break code encountered");
            }
            int type           = (firstbyte >> 5) & 0x07;
            int additional     = firstbyte & 0x1f;
            int expectedLength = CBORObject.GetExpectedLength(firstbyte);

            // Data checks
            if (expectedLength == -1)
            {
                // if the head byte is invalid
                throw new CBORException("Unexpected data encountered");
            }
            if (filter != null)
            {
                // Check for valid major types if asked
                if (!filter.MajorTypeMatches(type))
                {
                    throw new CBORException("Unexpected data type encountered");
                }
                if (firstbyte >= 0xe0 && firstbyte <= 0xff && firstbyte != 0xf9 &&
                    firstbyte != 0xfa && firstbyte != 0xfb)
                {
                    if (!filter.NonFPSimpleValueAllowed())
                    {
                        throw new CBORException("Unexpected data type encountered");
                    }
                }
            }
            // Check if this represents a fixed object
            CBORObject fixedObject = CBORObject.GetFixedObject(firstbyte);

            if (fixedObject != null)
            {
                return(fixedObject);
            }
            // Read fixed-length data
            byte[] data = null;
            if (expectedLength != 0)
            {
                data = new byte[expectedLength];
                // include the first byte because GetFixedLengthObject
                // will assume it exists for some head bytes
                data[0] = unchecked ((byte)firstbyte);
                if (expectedLength > 1 &&
                    this.stream.Read(data, 1, expectedLength - 1) != expectedLength
                    - 1)
                {
                    throw new CBORException("Premature end of data");
                }
                CBORObject cbor = CBORObject.GetFixedLengthObject(firstbyte, data);
                if (this.stringRefs != null && (type == 2 || type == 3))
                {
                    this.stringRefs.AddStringIfNeeded(cbor, expectedLength - 1);
                }
                return(cbor);
            }
            var      uadditional      = (long)additional;
            EInteger bigintAdditional = EInteger.Zero;
            var      hasBigAdditional = false;

            data = new byte[8];
            var lowAdditional = 0;

            switch (firstbyte & 0x1f)
            {
            case 24: {
                int tmp = this.stream.ReadByte();
                if (tmp < 0)
                {
                    throw new CBORException("Premature end of data");
                }
                lowAdditional = tmp;
                uadditional   = lowAdditional;
                break;
            }

            case 25: {
                if (this.stream.Read(data, 0, 2) != 2)
                {
                    throw new CBORException("Premature end of data");
                }
                lowAdditional  = ((int)(data[0] & (int)0xff)) << 8;
                lowAdditional |= (int)(data[1] & (int)0xff);
                uadditional    = lowAdditional;
                break;
            }

            case 26: {
                if (this.stream.Read(data, 0, 4) != 4)
                {
                    throw new CBORException("Premature end of data");
                }
                uadditional  = ((long)(data[0] & (long)0xff)) << 24;
                uadditional |= ((long)(data[1] & (long)0xff)) << 16;
                uadditional |= ((long)(data[2] & (long)0xff)) << 8;
                uadditional |= (long)(data[3] & (long)0xff);
                break;
            }

            case 27: {
                if (this.stream.Read(data, 0, 8) != 8)
                {
                    throw new CBORException("Premature end of data");
                }
                if ((((int)data[0]) & 0x80) != 0)
                {
                    // Won't fit in a signed 64-bit number
                    var uabytes = new byte[9];
                    uabytes[0]       = data[7];
                    uabytes[1]       = data[6];
                    uabytes[2]       = data[5];
                    uabytes[3]       = data[4];
                    uabytes[4]       = data[3];
                    uabytes[5]       = data[2];
                    uabytes[6]       = data[1];
                    uabytes[7]       = data[0];
                    uabytes[8]       = 0;
                    hasBigAdditional = true;
                    bigintAdditional = EInteger.FromBytes(uabytes, true);
                }
                else
                {
                    uadditional  = ((long)(data[0] & (long)0xff)) << 56;
                    uadditional |= ((long)(data[1] & (long)0xff)) << 48;
                    uadditional |= ((long)(data[2] & (long)0xff)) << 40;
                    uadditional |= ((long)(data[3] & (long)0xff)) << 32;
                    uadditional |= ((long)(data[4] & (long)0xff)) << 24;
                    uadditional |= ((long)(data[5] & (long)0xff)) << 16;
                    uadditional |= ((long)(data[6] & (long)0xff)) << 8;
                    uadditional |= (long)(data[7] & (long)0xff);
                }
                break;
            }
            }
            // The following doesn't check for major types 0 and 1,
            // since all of them are fixed-length types and are
            // handled in the call to GetFixedLengthObject.
            if (type == 2) // Byte string
            {
                if (additional == 31)
                {
                    // Streaming byte string
                    using (var ms = new MemoryStream()) {
                        // Requires same type as this one
                        while (true)
                        {
                            int nextByte = this.stream.ReadByte();
                            if (nextByte == 0xff)
                            {
                                // break if the "break" code was read
                                break;
                            }
                            long len = ReadDataLength(this.stream, nextByte, 2);
                            if ((len >> 63) != 0 || len > Int32.MaxValue)
                            {
                                throw new CBORException("Length" + ToUnsignedBigInteger(len) +
                                                        " is bigger than supported ");
                            }
                            if (nextByte != 0x40)
                            {
                                // NOTE: 0x40 means the empty byte string
                                ReadByteData(this.stream, len, ms);
                            }
                        }
                        if (ms.Position > Int32.MaxValue)
                        {
                            throw new
                                  CBORException("Length of bytes to be streamed is bigger than supported ");
                        }
                        data = ms.ToArray();
                        return(new CBORObject(
                                   CBORObject.CBORObjectTypeByteString,
                                   data));
                    }
                }
                else
                {
                    if (hasBigAdditional)
                    {
                        throw new CBORException("Length of " +
                                                bigintAdditional.ToString() + " is bigger than supported");
                    }
                    if (uadditional > Int32.MaxValue)
                    {
                        throw new CBORException("Length of " +
                                                CBORUtilities.LongToString(uadditional) +
                                                " is bigger than supported");
                    }
                    data = ReadByteData(this.stream, uadditional, null);
                    var cbor = new CBORObject(CBORObject.CBORObjectTypeByteString, data);
                    if (this.stringRefs != null)
                    {
                        int hint = (uadditional > Int32.MaxValue || hasBigAdditional) ?
                                   Int32.MaxValue : (int)uadditional;
                        this.stringRefs.AddStringIfNeeded(cbor, hint);
                    }
                    return(cbor);
                }
            }
            if (type == 3) // Text string
            {
                if (additional == 31)
                {
                    // Streaming text string
                    var builder = new StringBuilder();
                    while (true)
                    {
                        int nextByte = this.stream.ReadByte();
                        if (nextByte == 0xff)
                        {
                            // break if the "break" code was read
                            break;
                        }
                        long len = ReadDataLength(this.stream, nextByte, 3);
                        if ((len >> 63) != 0 || len > Int32.MaxValue)
                        {
                            throw new CBORException("Length" + ToUnsignedBigInteger(len) +
                                                    " is bigger than supported");
                        }
                        if (nextByte != 0x60)
                        {
                            // NOTE: 0x60 means the empty string
                            if (PropertyMap.ExceedsKnownLength(this.stream, len))
                            {
                                throw new CBORException("Premature end of data");
                            }
                            switch (
                                DataUtilities.ReadUtf8(
                                    this.stream,
                                    (int)len,
                                    builder,
                                    false))
                            {
                            case -1:
                                throw new CBORException("Invalid UTF-8");

                            case -2:
                                throw new CBORException("Premature end of data");
                            }
                        }
                    }
                    return(new CBORObject(
                               CBORObject.CBORObjectTypeTextString,
                               builder.ToString()));
                }
                else
                {
                    if (hasBigAdditional)
                    {
                        throw new CBORException("Length of " +
                                                bigintAdditional.ToString() + " is bigger than supported");
                    }
                    if (uadditional > Int32.MaxValue)
                    {
                        throw new CBORException("Length of " +
                                                CBORUtilities.LongToString(uadditional) +
                                                " is bigger than supported");
                    }
                    if (PropertyMap.ExceedsKnownLength(this.stream, uadditional))
                    {
                        throw new CBORException("Premature end of data");
                    }
                    var builder = new StringBuilder();
                    switch (
                        DataUtilities.ReadUtf8(
                            this.stream,
                            (int)uadditional,
                            builder,
                            false))
                    {
                    case -1:
                        throw new CBORException("Invalid UTF-8");

                    case -2:
                        throw new CBORException("Premature end of data");
                    }
                    var cbor = new CBORObject(
                        CBORObject.CBORObjectTypeTextString,
                        builder.ToString());
                    if (this.stringRefs != null)
                    {
                        int hint = (uadditional > Int32.MaxValue || hasBigAdditional) ?
                                   Int32.MaxValue : (int)uadditional;
                        this.stringRefs.AddStringIfNeeded(cbor, hint);
                    }
                    return(cbor);
                }
            }
            if (type == 4) // Array
            {
                CBORObject cbor = CBORObject.NewArray();
                if (additional == 31)
                {
                    var vtindex = 0;
                    // Indefinite-length array
                    while (true)
                    {
                        int headByte = this.stream.ReadByte();
                        if (headByte < 0)
                        {
                            throw new CBORException("Premature end of data");
                        }
                        if (headByte == 0xff)
                        {
                            // Break code was read
                            break;
                        }
                        if (filter != null && !filter.ArrayIndexAllowed(vtindex))
                        {
                            throw new CBORException("Array is too long");
                        }
                        ++this.depth;
                        CBORObject o = this.ReadForFirstByte(
                            headByte,
                            filter == null ? null : filter.GetSubFilter(vtindex));
                        --this.depth;
                        cbor.Add(o);
                        ++vtindex;
                    }
                    return(cbor);
                }
                if (hasBigAdditional)
                {
                    throw new CBORException("Length of " +
                                            bigintAdditional.ToString() + " is bigger than supported");
                }
                if (uadditional > Int32.MaxValue)
                {
                    throw new CBORException("Length of " +
                                            CBORUtilities.LongToString(uadditional) +
                                            " is bigger than supported");
                }
                if (filter != null && !filter.ArrayLengthMatches(uadditional))
                {
                    throw new CBORException("Array is too long");
                }
                if (PropertyMap.ExceedsKnownLength(this.stream, uadditional))
                {
                    throw new CBORException("Remaining data too small for array length");
                }
                ++this.depth;
                for (long i = 0; i < uadditional; ++i)
                {
                    cbor.Add(
                        this.Read(filter == null ? null : filter.GetSubFilter(i)));
                }
                --this.depth;
                return(cbor);
            }
            if (type == 5) // Map, type 5
            {
                CBORObject cbor = CBORObject.NewMap();
                if (additional == 31)
                {
                    // Indefinite-length map
                    while (true)
                    {
                        int headByte = this.stream.ReadByte();
                        if (headByte < 0)
                        {
                            throw new CBORException("Premature end of data");
                        }
                        if (headByte == 0xff)
                        {
                            // Break code was read
                            break;
                        }
                        ++this.depth;
                        CBORObject key   = this.ReadForFirstByte(headByte, null);
                        CBORObject value = this.Read(null);
                        --this.depth;
                        if (this.policy == CBORDuplicatePolicy.Disallow)
                        {
                            if (cbor.ContainsKey(key))
                            {
                                throw new CBORException("Duplicate key already exists: " + key);
                            }
                        }
                        cbor[key] = value;
                    }
                    return(cbor);
                }
                if (hasBigAdditional)
                {
                    throw new CBORException("Length of " +
                                            bigintAdditional.ToString() + " is bigger than supported");
                }
                if (uadditional > Int32.MaxValue)
                {
                    throw new CBORException("Length of " +
                                            CBORUtilities.LongToString(uadditional) +
                                            " is bigger than supported");
                }
                if (PropertyMap.ExceedsKnownLength(this.stream, uadditional))
                {
                    throw new CBORException("Remaining data too small for map length");
                }
                for (long i = 0; i < uadditional; ++i)
                {
                    ++this.depth;
                    CBORObject key   = this.Read(null);
                    CBORObject value = this.Read(null);
                    --this.depth;
                    if (this.policy == CBORDuplicatePolicy.Disallow)
                    {
                        if (cbor.ContainsKey(key))
                        {
                            throw new CBORException("Duplicate key already exists: " + key);
                        }
                    }
                    cbor[key] = value;
                }
                return(cbor);
            }
            if (type == 6) // Tagged item
            {
                ICBORTag taginfo       = null;
                var      haveFirstByte = false;
                var      newFirstByte  = -1;
                if (!hasBigAdditional)
                {
                    if (filter != null && !filter.TagAllowed(uadditional))
                    {
                        throw new CBORException("Unexpected tag encountered: " +
                                                uadditional);
                    }
                    int uad = uadditional >= 257 ? 257 : (uadditional < 0 ? 0 :
                                                          (int)uadditional);
                    switch (uad)
                    {
                    case 256:
                        // Tag 256: String namespace
                        this.stringRefs = this.stringRefs ?? (new StringRefs());
                        this.stringRefs.Push();
                        break;

                    case 25:
                        // String reference
                        if (this.stringRefs == null)
                        {
                            throw new CBORException("No stringref namespace");
                        }
                        break;

                    case 28:
                    case 29:
                        this.hasSharableObjects = true;
                        break;
                    }

                    taginfo = CBORObject.FindTagConverterLong(uadditional);
                }
                else
                {
                    if (filter != null && !filter.TagAllowed(bigintAdditional))
                    {
                        throw new CBORException("Unexpected tag encountered: " +
                                                uadditional);
                    }
          #pragma warning disable 618

                    taginfo = CBORObject.FindTagConverter(bigintAdditional);
                }
                ++this.depth;
                CBORObject o = haveFirstByte ? this.ReadForFirstByte(
                    newFirstByte,
                    taginfo == null ? null : taginfo.GetTypeFilter()) :
                               this.Read(taginfo == null ? null : taginfo.GetTypeFilter());
                --this.depth;
                if (hasBigAdditional)
                {
                    return(CBORObject.FromObjectAndTag(o, bigintAdditional));
                }
                if (uadditional < 65536)
                {
                    int uaddl = uadditional >= 257 ? 257 : (uadditional < 0 ? 0 :
                                                            (int)uadditional);
                    switch (uaddl)
                    {
                    case 256:
                        // string tag
                        this.stringRefs.Pop();
                        break;

                    case 25:
                        // stringref tag
                        return(this.stringRefs.GetString(o.AsEInteger()));
                    }

                    return(CBORObject.FromObjectAndTag(
                               o,
                               (int)uadditional));
                }
                return(CBORObject.FromObjectAndTag(
                           o,
                           (EInteger)uadditional));
            }
            throw new CBORException("Unexpected data encountered");
        }
Beispiel #26
0
 private static EInteger RandomYear(IRandomGenExtended irg)
 {
     return(EInteger.FromInt32(irg.GetInt32(9998) + 1));
 }
Beispiel #27
0
        public static CBORObject Multiply(CBORObject a, CBORObject b)
        {
            if (a == null)
            {
                throw new ArgumentNullException(nameof(a));
            }
            if (b == null)
            {
                throw new ArgumentNullException(nameof(b));
            }
            if (a.Type != CBORType.Number)
            {
                throw new ArgumentException("a.Type (" + a.Type +
                                            ") is not equal to " + CBORType.Number);
            }
            if (b.Type != CBORType.Number)
            {
                throw new ArgumentException("b.Type (" + b.Type +
                                            ") is not equal to " + CBORType.Number);
            }
            object objA  = a.ThisItem;
            object objB  = b.ThisItem;
            int    typeA = a.ItemType;
            int    typeB = b.ItemType;

            if (typeA == CBORObject.CBORObjectTypeInteger && typeB ==
                CBORObject.CBORObjectTypeInteger)
            {
                var  valueA = (long)objA;
                var  valueB = (long)objB;
                bool apos   = valueA > 0L;
                bool bpos   = valueB > 0L;
                if (
                    (apos && ((!bpos && (Int64.MinValue / valueA) > valueB) ||
                              (bpos && valueA > (Int64.MaxValue / valueB)))) ||
                    (!apos && ((!bpos && valueA != 0L &&
                                (Int64.MaxValue / valueA) > valueB) ||
                               (bpos && valueA < (Int64.MinValue / valueB)))))
                {
                    // would overflow, convert to EInteger
                    var bvalueA = (EInteger)valueA;
                    var bvalueB = (EInteger)valueB;
                    return(CBORObject.FromObject(bvalueA * (EInteger)bvalueB));
                }
                return(CBORObject.FromObject(valueA * valueB));
            }
            if (typeA == CBORObject.CBORObjectTypeExtendedRational ||
                typeB == CBORObject.CBORObjectTypeExtendedRational)
            {
                ERational e1 =
                    CBORObject.GetNumberInterface(typeA).AsExtendedRational(objA);
                ERational e2 =
                    CBORObject.GetNumberInterface(typeB).AsExtendedRational(objB);
                return(CBORObject.FromObject(e1.Multiply(e2)));
            }
            if (typeA == CBORObject.CBORObjectTypeExtendedDecimal ||
                typeB == CBORObject.CBORObjectTypeExtendedDecimal)
            {
                EDecimal e1 =
                    CBORObject.GetNumberInterface(typeA).AsExtendedDecimal(objA);
                EDecimal e2 =
                    CBORObject.GetNumberInterface(typeB).AsExtendedDecimal(objB);
                return(CBORObject.FromObject(e1.Multiply(e2)));
            }
            if (typeA == CBORObject.CBORObjectTypeExtendedFloat || typeB ==
                CBORObject.CBORObjectTypeExtendedFloat ||
                typeA == CBORObject.CBORObjectTypeDouble || typeB ==
                CBORObject.CBORObjectTypeDouble ||
                typeA == CBORObject.CBORObjectTypeSingle || typeB ==
                CBORObject.CBORObjectTypeSingle)
            {
                EFloat e1 =
                    CBORObject.GetNumberInterface(typeA).AsExtendedFloat(objA);
                EFloat e2 = CBORObject.GetNumberInterface(typeB).AsExtendedFloat(objB);
                return(CBORObject.FromObject(e1.Multiply(e2)));
            }
            else
            {
                EInteger b1 = CBORObject.GetNumberInterface(typeA).AsEInteger(objA);
                EInteger b2 = CBORObject.GetNumberInterface(typeB).AsEInteger(objB);
                return(CBORObject.FromObject(b1 * (EInteger)b2));
            }
        }
Beispiel #28
0
 private static EInteger RandomExpandedYear(IRandomGenExtended irg)
 {
     return(EInteger.FromInt32(irg.GetInt32(1000000) - 500000));
 }
Beispiel #29
0
        public static CBORObject Remainder(CBORObject a, CBORObject b)
        {
            if (a == null)
            {
                throw new ArgumentNullException(nameof(a));
            }
            if (b == null)
            {
                throw new ArgumentNullException(nameof(b));
            }
            if (a.Type != CBORType.Number)
            {
                throw new ArgumentException("a.Type (" + a.Type +
                                            ") is not equal to " + CBORType.Number);
            }
            if (b.Type != CBORType.Number)
            {
                throw new ArgumentException("b.Type (" + b.Type +
                                            ") is not equal to " + CBORType.Number);
            }
            object objA  = a.ThisItem;
            object objB  = b.ThisItem;
            int    typeA = a.ItemType;
            int    typeB = b.ItemType;

            if (typeA == CBORObject.CBORObjectTypeInteger && typeB ==
                CBORObject.CBORObjectTypeInteger)
            {
                var valueA = (long)objA;
                var valueB = (long)objB;
                return((valueA == Int64.MinValue && valueB == -1) ?
                       CBORObject.FromObject(0) : CBORObject.FromObject(valueA % valueB));
            }
            if (typeA == CBORObject.CBORObjectTypeExtendedRational ||
                typeB == CBORObject.CBORObjectTypeExtendedRational)
            {
                ERational e1 =
                    CBORObject.GetNumberInterface(typeA).AsExtendedRational(objA);
                ERational e2 =
                    CBORObject.GetNumberInterface(typeB).AsExtendedRational(objB);
                return(CBORObject.FromObject(e1.Remainder(e2)));
            }
            if (typeA == CBORObject.CBORObjectTypeExtendedDecimal ||
                typeB == CBORObject.CBORObjectTypeExtendedDecimal)
            {
                EDecimal e1 =
                    CBORObject.GetNumberInterface(typeA).AsExtendedDecimal(objA);
                EDecimal e2 =
                    CBORObject.GetNumberInterface(typeB).AsExtendedDecimal(objB);
                return(CBORObject.FromObject(e1.Remainder(e2, null)));
            }
            if (typeA == CBORObject.CBORObjectTypeExtendedFloat || typeB ==
                CBORObject.CBORObjectTypeExtendedFloat ||
                typeA == CBORObject.CBORObjectTypeDouble || typeB ==
                CBORObject.CBORObjectTypeDouble ||
                typeA == CBORObject.CBORObjectTypeSingle || typeB ==
                CBORObject.CBORObjectTypeSingle)
            {
                EFloat e1 =
                    CBORObject.GetNumberInterface(typeA).AsExtendedFloat(objA);
                EFloat e2 = CBORObject.GetNumberInterface(typeB).AsExtendedFloat(objB);
                return(CBORObject.FromObject(e1.Remainder(e2, null)));
            }
            else
            {
                EInteger b1 = CBORObject.GetNumberInterface(typeA).AsEInteger(objA);
                EInteger b2 = CBORObject.GetNumberInterface(typeB).AsEInteger(objB);
                return(CBORObject.FromObject(b1 % (EInteger)b2));
            }
        }
Beispiel #30
0
 internal static FastIntegerFixed FromBig(EInteger bigintVal)
 {
     return(bigintVal.CanFitInInt32() ?
            FromInt32(bigintVal.ToInt32Unchecked()) : new
            FastIntegerFixed(IntegerMode.LargeValue, 0, bigintVal));
 }