public CBORObject ValidateObject(CBORObject obj) { if (obj.Type == CBORType.TextString) { throw new CBORException("Not a text string"); } return obj; }
public CBORObject ValidateObject(CBORObject obj) { if (obj.Type != CBORType.Array || obj.Count < 1) { throw new CBORException("Not an array, or is an empty array."); } return obj; }
public CBORObject ValidateObject(CBORObject obj) { if (!obj.IsFinite) { throw new CBORException("Not a valid date"); } return obj; }
public CBORObject ValidateObject(CBORObject obj) { #if DEBUG if (obj == null) { throw new ArgumentNullException("obj"); } #endif return obj; }
private void Parse(byte[] bytes) { var cborObject = CBORObject.DecodeFromBytes(bytes); var list = cborObject.ConvertToList(); if (list.Count == 3) { header = list.ElementAt(0); payload = list.ElementAt(1); signature = list.ElementAt(2); } }
public CBORObject ValidateObject(CBORObject obj) { #if DEBUG if (obj == null) { throw new ArgumentNullException("obj"); } #endif if (!obj.IsIntegral || !obj.CanFitInInt64() || obj.Sign < 0) { throw new CBORException("Not a 64-bit unsigned integer"); } return obj; }
private Org.BouncyCastle.Math.BigInteger ConvertBigNum(PeterO.Cbor.CBORObject cbor) { byte[] rgb = cbor.GetByteString(); byte[] rgb2 = new byte[rgb.Length + 2]; rgb2[0] = 0; rgb2[1] = 0; for (int i = 0; i < rgb.Length; i++) { rgb2[i + 2] = rgb[i]; } return(new Org.BouncyCastle.Math.BigInteger(rgb2)); }
public CBORObject ValidateObject(CBORObject obj) { #if DEBUG if (obj == null) { throw new ArgumentNullException("obj"); } #endif // Return this object without tag 28 #if DEBUG if (!obj.HasTag(28)) { throw new ArgumentException("doesn't satisfy obj.HasTag(28)"); } #endif return obj.UntagOne(); }
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)); } }
internal static void WriteJSONToInternal( CBORObject obj, StringOutput writer, JSONOptions options, IList <CBORObject> stack) { if (obj.IsNumber) { writer.WriteString(CBORNumber.FromCBORObject(obj).ToJSONString()); return; } switch (obj.Type) { case CBORType.Integer: case CBORType.FloatingPoint: { CBORObject untaggedObj = obj.Untag(); writer.WriteString( CBORNumber.FromCBORObject(untaggedObj).ToJSONString()); break; } case CBORType.Boolean: { if (obj.IsTrue) { writer.WriteString("true"); return; } if (obj.IsFalse) { writer.WriteString("false"); return; } return; } case CBORType.SimpleValue: { writer.WriteString("null"); return; } case CBORType.ByteString: { byte[] byteArray = obj.GetByteString(); if (byteArray.Length == 0) { writer.WriteString("\"\""); return; } writer.WriteCodePoint((int)'\"'); if (obj.HasTag(22)) { // Base64 with padding Base64.WriteBase64( writer, byteArray, 0, byteArray.Length, true); } else if (obj.HasTag(23)) { // Write as base16 for (int i = 0; i < byteArray.Length; ++i) { writer.WriteCodePoint((int)Hex16[(byteArray[i] >> 4) & 15]); writer.WriteCodePoint((int)Hex16[byteArray[i] & 15]); } } else { // Base64url no padding Base64.WriteBase64URL( writer, byteArray, 0, byteArray.Length, false); } writer.WriteCodePoint((int)'\"'); break; } case CBORType.TextString: { string thisString = obj.AsString(); if (thisString.Length == 0) { writer.WriteString("\"\""); return; } writer.WriteCodePoint((int)'\"'); WriteJSONStringUnquoted(thisString, writer, options); writer.WriteCodePoint((int)'\"'); break; } case CBORType.Array: { writer.WriteCodePoint((int)'['); for (var i = 0; i < obj.Count; ++i) { if (i > 0) { writer.WriteCodePoint((int)','); } bool pop = CheckCircularRef(stack, obj, obj[i]); WriteJSONToInternal(obj[i], writer, options, stack); PopRefIfNeeded(stack, pop); } writer.WriteCodePoint((int)']'); break; } case CBORType.Map: { var first = true; var hasNonStringKeys = false; ICollection <KeyValuePair <CBORObject, CBORObject> > entries = obj.Entries; foreach (KeyValuePair <CBORObject, CBORObject> entry in entries) { CBORObject key = entry.Key; if (key.Type != CBORType.TextString || key.IsTagged) { // treat a non-text-string item or a tagged item // as having non-string keys hasNonStringKeys = true; break; } } if (!hasNonStringKeys) { writer.WriteCodePoint((int)'{'); foreach (KeyValuePair <CBORObject, CBORObject> entry in entries) { CBORObject key = entry.Key; CBORObject value = entry.Value; if (!first) { writer.WriteCodePoint((int)','); } writer.WriteCodePoint((int)'\"'); WriteJSONStringUnquoted(key.AsString(), writer, options); writer.WriteCodePoint((int)'\"'); writer.WriteCodePoint((int)':'); bool pop = CheckCircularRef(stack, obj, value); WriteJSONToInternal(value, writer, options, stack); PopRefIfNeeded(stack, pop); first = false; } writer.WriteCodePoint((int)'}'); } else { // This map has non-string keys IDictionary <string, CBORObject> stringMap = new Dictionary <string, CBORObject>(); // Copy to a map with String keys, since // some keys could be duplicates // when serialized to strings foreach (KeyValuePair <CBORObject, CBORObject> entry in entries) { CBORObject key = entry.Key; CBORObject value = entry.Value; string str = null; switch (key.Type) { case CBORType.TextString: str = key.AsString(); break; case CBORType.Array: case CBORType.Map: { var sb = new StringBuilder(); var sw = new StringOutput(sb); bool pop = CheckCircularRef(stack, obj, key); WriteJSONToInternal(key, sw, options, stack); PopRefIfNeeded(stack, pop); str = sb.ToString(); break; } default: str = key.ToJSONString(options); break; } if (stringMap.ContainsKey(str)) { throw new CBORException( "Duplicate JSON string equivalents of map" + "\u0020keys"); } stringMap[str] = value; } first = true; writer.WriteCodePoint((int)'{'); foreach (KeyValuePair <string, CBORObject> entry in stringMap) { string key = entry.Key; CBORObject value = entry.Value; if (!first) { writer.WriteCodePoint((int)','); } writer.WriteCodePoint((int)'\"'); WriteJSONStringUnquoted((string)key, writer, options); writer.WriteCodePoint((int)'\"'); writer.WriteCodePoint((int)':'); bool pop = CheckCircularRef(stack, obj, value); WriteJSONToInternal(value, writer, options, stack); PopRefIfNeeded(stack, pop); first = false; } writer.WriteCodePoint((int)'}'); } break; } default: throw new InvalidOperationException("Unexpected item" + "\u0020type"); } }
internal static CBORObject ParseJSONNumber( char[] 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) { char 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); } char 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."); } }
private CBORObject ParseJSONObject(int depth) { // Assumes that the last character read was '{' if (depth > 1000) { this.RaiseError("Too deeply nested"); } int c; CBORObject key = null; CBORObject obj; var nextChar = new int[1]; var seenComma = false; var myHashMap = new Dictionary <CBORObject, CBORObject>(); while (true) { c = this.SkipWhitespaceJSON(); switch (c) { case -1: this.RaiseError("A JSON object must end with '}'"); break; case '}': if (seenComma) { // Situation like '{"0"=>1,}' this.RaiseError("Trailing comma"); return(null); } return(CBORObject.FromRaw(myHashMap)); default: { // Read the next string if (c < 0) { this.RaiseError("Unexpected end of data"); return(null); } if (c != '"') { this.RaiseError("Expected a string as a key"); return(null); } // Parse a string that represents the object's key. // The tokenizer already checked the string for invalid // surrogate pairs, so just call the CBORObject // constructor directly obj = CBORObject.FromRaw(this.NextJSONString()); key = obj; if (!this.options.AllowDuplicateKeys && myHashMap.ContainsKey(obj)) { this.RaiseError("Key already exists: " + key); return(null); } break; } } if (this.SkipWhitespaceJSON() != ':') { this.RaiseError("Expected a ':' after a key"); } // NOTE: Will overwrite existing value myHashMap[key] = this.NextJSONValue( this.SkipWhitespaceJSON(), nextChar, depth); switch (nextChar[0]) { case ',': seenComma = true; break; case '}': return(CBORObject.FromRaw(myHashMap)); default: this.RaiseError("Expected a ',' or '}'"); break; } } }
public CBORObject ValidateObject(CBORObject obj) { return(ConvertToDecimalFrac(obj, false, this.extended)); }
private CBORObject ReadStringArrayMap(int type, long uadditional) { bool canonical = this.options.Ctap2Canonical; if (type == 2) // Byte string { if ((uadditional >> 31) != 0) { throw new CBORException("Length of " + ToUnsignedEInteger(uadditional).ToString() + " is bigger" + "\u0020than supported"); } int hint = (uadditional > Int32.MaxValue || (uadditional >> 63) != 0) ? Int32.MaxValue : (int)uadditional; byte[] data = ReadByteData(this.stream, uadditional, null); return(this.ObjectFromByteArray(data, hint)); } if (type == 3) // Text string { if ((uadditional >> 31) != 0) { throw new CBORException("Length of " + ToUnsignedEInteger(uadditional).ToString() + " is bigger" + "\u0020than 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"); } CBORObject cbor = CBORObject.FromRaw(builder.ToString()); if (this.stringRefs != null) { int hint = (uadditional > Int32.MaxValue || (uadditional >> 63) != 0) ? Int32.MaxValue : (int)uadditional; this.stringRefs.AddStringIfNeeded(cbor, hint); } return(cbor); } if (type == 4) // Array { if (this.options.Ctap2Canonical && this.depth >= 4) { throw new CBORException("Depth too high in canonical CBOR"); } CBORObject cbor = CBORObject.NewArray(); if ((uadditional >> 31) != 0) { throw new CBORException("Length of " + ToUnsignedEInteger(uadditional).ToString() + " is bigger than" + "\u0020supported"); } if (PropertyMap.ExceedsKnownLength(this.stream, uadditional)) { throw new CBORException("Remaining data too small for array" + "\u0020length"); } ++this.depth; for (long i = 0; i < uadditional; ++i) { cbor.Add( this.ReadInternal()); } --this.depth; return(cbor); } if (type == 5) // Map, type 5 { if (this.options.Ctap2Canonical && this.depth >= 4) { throw new CBORException("Depth too high in canonical CBOR"); } CBORObject cbor = CBORObject.NewMap(); if ((uadditional >> 31) != 0) { throw new CBORException("Length of " + ToUnsignedEInteger(uadditional).ToString() + " is bigger than" + "\u0020supported"); } if (PropertyMap.ExceedsKnownLength(this.stream, uadditional)) { throw new CBORException("Remaining data too small for map" + "\u0020length"); } CBORObject lastKey = null; IComparer <CBORObject> comparer = CBORCanonical.Comparer; for (long i = 0; i < uadditional; ++i) { ++this.depth; CBORObject key = this.ReadInternal(); CBORObject value = this.ReadInternal(); --this.depth; if (this.options.Ctap2Canonical && lastKey != null) { int cmp = comparer.Compare(lastKey, key); if (cmp > 0) { throw new CBORException("Map key not in canonical order"); } else if (cmp == 0) { throw new CBORException("Duplicate map key"); } } if (!this.options.AllowDuplicateKeys) { if (cbor.ContainsKey(key)) { throw new CBORException("Duplicate key already exists"); } } lastKey = key; cbor[key] = value; } return(cbor); } return(null); }
/// <summary>Converts this object's value to a CBOR object.</summary> /// <returns>A CBOR object that stores this object's value.</returns> public CBORObject ToCBORObject() { return(CBORObject.FromObject(this.value)); }
public static CBORObject BuildCBORArray(int[] dimensions) { int zeroPos = dimensions.Length; for (var i = 0; i < dimensions.Length; ++i) { if (dimensions[i] == 0) { { zeroPos = i; } break; } } int arraydims = zeroPos - 1; if (arraydims <= 0) { return(CBORObject.NewArray()); } var stack = new CBORObject[zeroPos]; var index = new int[zeroPos]; var stackpos = 0; CBORObject ret = CBORObject.NewArray(); stack[0] = ret; index[0] = 0; for (var i = 0; i < dimensions[0]; ++i) { ret.Add(CBORObject.NewArray()); } ++stackpos; while (stackpos > 0) { int curindex = index[stackpos - 1]; if (curindex < stack[stackpos - 1].Count) { CBORObject subobj = stack[stackpos - 1][curindex]; if (stackpos < zeroPos) { stack[stackpos] = subobj; index[stackpos] = 0; for (var i = 0; i < dimensions[stackpos]; ++i) { subobj.Add(CBORObject.NewArray()); } ++index[stackpos - 1]; ++stackpos; } else { ++index[stackpos - 1]; } } else { --stackpos; } } return(ret); }
public CBORObject ValidateObject(CBORObject obj) { return(CBORTag2.ConvertToBigNum(obj, true)); }
private CBORObject NextJSONValue( int firstChar, int[] nextChar, int depth) { int c = firstChar; CBORObject obj = null; if (c < 0) { this.RaiseError("Unexpected end of data"); } switch (c) { case '"': { // Parse a string // The tokenizer already checked the string for invalid // surrogate pairs, so just call the CBORObject // constructor directly obj = CBORObject.FromRaw(this.NextJSONString()); nextChar[0] = this.SkipWhitespaceJSON(); return(obj); } case '{': { // Parse an object obj = this.ParseJSONObject(depth + 1); nextChar[0] = this.SkipWhitespaceJSON(); return(obj); } case '[': { // Parse an array obj = this.ParseJSONArray(depth + 1); nextChar[0] = this.SkipWhitespaceJSON(); return(obj); } case 't': { // Parse true if (this.endPos - this.index <= 2 || (((int)this.bytes[this.index]) & 0xFF) != 'r' || (((int)this.bytes[this.index + 1]) & 0xFF) != 'u' || (((int)this.bytes[this.index + 2]) & 0xFF) != 'e') { this.RaiseError("Value can't be parsed."); } this.index += 3; nextChar[0] = this.SkipWhitespaceJSON(); return(CBORObject.True); } case 'f': { // Parse false if (this.endPos - this.index <= 3 || (((int)this.bytes[this.index]) & 0xFF) != 'a' || (((int)this.bytes[this.index + 1]) & 0xFF) != 'l' || (((int)this.bytes[this.index + 2]) & 0xFF) != 's' || (((int)this.bytes[this.index + 3]) & 0xFF) != 'e') { this.RaiseError("Value can't be parsed."); } this.index += 4; nextChar[0] = this.SkipWhitespaceJSON(); return(CBORObject.False); } case 'n': { // Parse null if (this.endPos - this.index <= 2 || (((int)this.bytes[this.index]) & 0xFF) != 'u' || (((int)this.bytes[this.index + 1]) & 0xFF) != 'l' || (((int)this.bytes[this.index + 2]) & 0xFF) != 'l') { this.RaiseError("Value can't be parsed."); } this.index += 3; nextChar[0] = this.SkipWhitespaceJSON(); return(CBORObject.Null); } case '-': { // Parse a negative number return(this.NextJSONNegativeNumber(nextChar)); } case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': { // Parse a nonnegative number return(this.NextJSONNonnegativeNumber(c, nextChar)); } default: this.RaiseError("Value can't be parsed."); break; } return(null); }
private CBORObject NextJSONNonnegativeNumber(int c, int[] nextChar) { // Assumes the last character read was a digit CBORObject obj = null; string str; int cval = c - '0'; int cstart = c; int startIndex = this.index - 1; var needObj = true; int numberStartIndex = this.index - 1; c = this.index < this.endPos ? ((int)this.bytes[this.index++]) & 0xff : -1; if (!(c == '-' || c == '+' || c == '.' || (c >= '0' && c <= '9') || c == 'e' || c == 'E')) { // Optimize for common case where JSON number // is a single digit without sign or exponent obj = CBORDataUtilities.ParseSmallNumber(cval, this.options); needObj = false; } else if (c >= '0' && c <= '9') { int csecond = c; if (cstart == '0') { // Leading zero followed by any digit is not allowed this.RaiseError("JSON number can't be parsed."); } cval = (cval * 10) + (int)(c - '0'); c = this.index < this.endPos ? ((int)this.bytes[this.index++]) & 0xff : -1; if (c >= '0' && c <= '9') { var digits = 2; while (digits < 9 && (c >= '0' && c <= '9')) { cval = (cval * 10) + (int)(c - '0'); c = this.index < this.endPos ? ((int)this.bytes[this.index++]) & 0xff : -1; ++digits; } if (!(c == 'e' || c == 'E' || c == '.' || (c >= '0' && c <= '9'))) { // All-digit number that's short enough obj = CBORDataUtilities.ParseSmallNumber(cval, this.options); needObj = false; } } else if (!(c == '-' || c == '+' || c == '.' || c == 'e' || c == 'E')) { // Optimize for common case where JSON number // is two digits without sign, decimal point, or exponent obj = CBORDataUtilities.ParseSmallNumber(cval, this.options); needObj = false; } } if (needObj) { while (c == '-' || c == '+' || c == '.' || (c >= '0' && c <= '9') || c == 'e' || c == 'E') { c = this.index < this.endPos ? ((int)this.bytes[this.index++]) & 0xff : -1; } // check if character can validly appear after a JSON number if (c != ',' && c != ']' && c != '}' && c != -1 && c != 0x20 && c != 0x0a && c != 0x0d && c != 0x09) { this.RaiseError("Invalid character after JSON number"); } int numberEndIndex = c < 0 ? this.endPos : this.index - 1; var ssb = new StringBuilder(numberEndIndex - startIndex); int ki; for (ki = startIndex; ki < numberEndIndex; ++ki) { ssb.Append((char)(((int)this.bytes[ki]) & 0xff)); } str = ssb.ToString(); obj = CBORDataUtilities.ParseJSONNumber(str, this.options); if (obj == null) { string errstr = (str.Length <= 100) ? str : (str.Substring(0, 100) + "..."); this.RaiseError("JSON number can't be parsed. " + errstr); } } if (c == -1 || (c != 0x20 && c != 0x0a && c != 0x0d && c != 0x09)) { nextChar[0] = c; } else { nextChar[0] = this.SkipWhitespaceJSON(); } return(obj); }
internal static string ToStringHelper(CBORObject obj, int depth) { StringBuilder sb = null; string simvalue = null; CBORType type = obj.Type; CBORObject curobject; if (obj.IsTagged) { if (sb == null) { if (type == CBORType.TextString) { // The default capacity of StringBuilder may be too small // for many strings, so set a suggested capacity // explicitly string str = obj.AsString(); sb = new StringBuilder(Math.Min(str.Length, 4096) + 16); } else { sb = new StringBuilder(); } } // Append opening tags if needed curobject = obj; while (curobject.IsTagged) { EInteger ei = curobject.MostOuterTag; sb.Append(ei.ToString()); sb.Append('('); curobject = curobject.UntagOne(); } } switch (type) { case CBORType.SimpleValue: sb = sb ?? new StringBuilder(); if (obj.IsUndefined) { sb.Append("undefined"); } else if (obj.IsNull) { sb.Append("null"); } else { sb.Append("simple("); int thisItemInt = obj.SimpleValue; char c; if (thisItemInt >= 100) { // NOTE: '0'-'9' have ASCII code 0x30-0x39 c = (char)(0x30 + ((thisItemInt / 100) % 10)); sb.Append(c); } if (thisItemInt >= 10) { c = (char)(0x30 + ((thisItemInt / 10) % 10)); sb.Append(c); c = (char)(0x30 + (thisItemInt % 10)); } else { c = (char)(0x30 + thisItemInt); } sb.Append(c); sb.Append(')'); } break; case CBORType.Boolean: case CBORType.Integer: simvalue = obj.Untag().ToJSONString(); if (sb == null) { return(simvalue); } sb.Append(simvalue); break; case CBORType.FloatingPoint: { long bits = obj.AsDoubleBits(); simvalue = bits == DoubleNegInfinity ? "-Infinity" : ( bits == DoublePosInfinity ? "Infinity" : ( CBORUtilities.DoubleBitsNaN(bits) ? "NaN" : obj.Untag().ToJSONString())); if (sb == null) { return(simvalue); } sb.Append(simvalue); break; } case CBORType.ByteString: { sb = sb ?? new StringBuilder(); sb.Append("h'"); byte[] data = obj.GetByteString(); int length = data.Length; for (var i = 0; i < length; ++i) { sb.Append(HexAlphabet[(data[i] >> 4) & 15]); sb.Append(HexAlphabet[data[i] & 15]); } sb.Append((char)0x27); break; } case CBORType.TextString: { sb = sb == null ? new StringBuilder() : sb; sb.Append('\"'); string ostring = obj.AsString(); sb.Append(ostring); sb.Append('\"'); break; } case CBORType.Array: { sb = sb ?? new StringBuilder(); var first = true; sb.Append('['); if (depth >= 50) { sb.Append("..."); } else { for (var i = 0; i < obj.Count; ++i) { if (!first) { sb.Append(", "); } sb.Append(ToStringHelper(obj[i], depth + 1)); first = false; } } sb.Append(']'); break; } case CBORType.Map: { sb = sb ?? new StringBuilder(); var first = true; sb.Append('{'); if (depth >= 50) { sb.Append("..."); } else { ICollection <KeyValuePair <CBORObject, CBORObject> > entries = obj.Entries; foreach (KeyValuePair <CBORObject, CBORObject> entry in entries) { CBORObject key = entry.Key; CBORObject value = entry.Value; if (!first) { sb.Append(", "); } sb.Append(ToStringHelper(key, depth + 1)); sb.Append(": "); sb.Append(ToStringHelper(value, depth + 1)); first = false; } } sb.Append('}'); break; } default: { sb = sb ?? new StringBuilder(); sb.Append("???"); break; } } // Append closing tags if needed curobject = obj; while (curobject.IsTagged) { sb.Append(')'); curobject = curobject.UntagOne(); } return(sb.ToString()); }
public static CBORObject Subtract(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 && Int64.MaxValue + valueB < valueA) || (valueB > 0 && Int64.MinValue + valueB > 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.Subtract(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.Subtract(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.Subtract(e2))); } else { EInteger b1 = CBORObject.GetNumberInterface(typeA).AsEInteger(objA); EInteger b2 = CBORObject.GetNumberInterface(typeB).AsEInteger(objB); return(CBORObject.FromObject(b1 - (EInteger)b2)); } }
internal static ICBORNumber GetNumberInterface(CBORObject obj) { CBORNumber num = CBORNumber.FromCBORObject(obj); return((num == null) ? null : num.GetNumberInterface()); }
private static CBORNumber BignumToNumber(CBORObject o) { if (o.Type != CBORType.ByteString) { return(null); // "Byte array expected"); } bool negative = o.HasMostInnerTag(3); byte[] data = o.GetByteString(); if (data.Length <= 7) { long x = 0; for (var i = 0; i < data.Length; ++i) { x <<= 8; x |= ((long)data[i]) & 0xff; } if (negative) { x = -x; --x; } return(new CBORNumber(Kind.Integer, x)); } int neededLength = data.Length; byte[] bytes; EInteger bi; var extended = false; if (((data[0] >> 7) & 1) != 0) { // Increase the needed length // if the highest bit is set, to // distinguish negative and positive // values ++neededLength; extended = true; } bytes = new byte[neededLength]; for (var i = 0; i < data.Length; ++i) { bytes[i] = data[data.Length - 1 - i]; if (negative) { bytes[i] = (byte)((~((int)bytes[i])) & 0xff); } } if (extended) { bytes[bytes.Length - 1] = negative ? (byte)0xff : (byte)0; } bi = EInteger.FromBytes(bytes, true); if (bi.CanFitInInt64()) { return(new CBORNumber(Kind.Integer, bi.ToInt64Checked())); } else { return(new CBORNumber(Kind.EInteger, bi)); } }
public static object TypeToObject( CBORObject objThis, Type t, CBORTypeMapper mapper, PODOptions options, int depth) { if (t.Equals(typeof(int))) { return(objThis.AsInt32()); } if (t.Equals(typeof(short))) { return(objThis.AsInt16()); } if (t.Equals(typeof(ushort))) { return(objThis.AsUInt16()); } if (t.Equals(typeof(byte))) { return(objThis.AsByte()); } if (t.Equals(typeof(sbyte))) { return(objThis.AsSByte()); } if (t.Equals(typeof(long))) { return(objThis.AsInt64()); } if (t.Equals(typeof(uint))) { return(objThis.AsUInt32()); } if (t.Equals(typeof(ulong))) { return(objThis.AsUInt64()); } if (t.Equals(typeof(double))) { return(objThis.AsDouble()); } if (t.Equals(typeof(decimal))) { return(objThis.AsDecimal()); } if (t.Equals(typeof(float))) { return(objThis.AsSingle()); } if (t.Equals(typeof(bool))) { return(objThis.AsBoolean()); } if (t.Equals(typeof(char))) { if (objThis.Type == CBORType.TextString) { string s = objThis.AsString(); if (s.Length != 1) { throw new CBORException("Can't convert to char"); } return(s[0]); } if (objThis.IsIntegral && objThis.CanTruncatedIntFitInInt32()) { int c = objThis.AsInt32(); if (c < 0 || c >= 0x10000) { throw new CBORException("Can't convert to char"); } return((char)c); } throw new CBORException("Can't convert to char"); } if (t.Equals(typeof(DateTime))) { return(new CBORDateConverter().FromCBORObject(objThis)); } if (t.Equals(typeof(Guid))) { return(new CBORUuidConverter().FromCBORObject(objThis)); } if (t.Equals(typeof(Uri))) { return(new CBORUriConverter().FromCBORObject(objThis)); } if (t.Equals(typeof(EDecimal))) { return(objThis.AsEDecimal()); } if (t.Equals(typeof(EFloat))) { return(objThis.AsEFloat()); } if (t.Equals(typeof(EInteger))) { return(objThis.AsEInteger()); } if (t.Equals(typeof(ERational))) { return(objThis.AsERational()); } if (IsAssignableFrom(typeof(Enum), t)) { return(ObjectToEnum(objThis, t)); } if (objThis.Type == CBORType.ByteString) { if (t.Equals(typeof(byte[]))) { byte[] bytes = objThis.GetByteString(); var byteret = new byte[bytes.Length]; Array.Copy(bytes, 0, byteret, 0, byteret.Length); return(byteret); } } if (objThis.Type == CBORType.Array) { Type objectType = typeof(object); var isList = false; object listObject = null; #if NET40 || NET20 if (IsAssignableFrom(typeof(Array), t)) { Type elementType = t.GetElementType(); Array array = Array.CreateInstance( elementType, GetDimensions(objThis)); return(FillArray(array, elementType, objThis, mapper, options, depth)); } if (t.IsGenericType) { Type td = t.GetGenericTypeDefinition(); isList = td.Equals(typeof(List <>)) || td.Equals(typeof(IList <>)) || td.Equals(typeof(ICollection <>)) || td.Equals(typeof(IEnumerable <>)); } isList = isList && t.GetGenericArguments().Length == 1; if (isList) { objectType = t.GetGenericArguments()[0]; Type listType = typeof(List <>).MakeGenericType(objectType); listObject = Activator.CreateInstance(listType); } #else if (IsAssignableFrom(typeof(Array), t)) { Type elementType = t.GetElementType(); Array array = Array.CreateInstance( elementType, GetDimensions(objThis)); return(FillArray(array, elementType, objThis, mapper, options, depth)); } if (t.GetTypeInfo().IsGenericType) { Type td = t.GetGenericTypeDefinition(); isList = (td.Equals(typeof(List <>)) || td.Equals(typeof(IList <>)) || td.Equals(typeof(ICollection <>)) || td.Equals(typeof(IEnumerable <>))); } isList = (isList && t.GenericTypeArguments.Length == 1); if (isList) { objectType = t.GenericTypeArguments[0]; Type listType = typeof(List <>).MakeGenericType(objectType); listObject = Activator.CreateInstance(listType); } #endif if (listObject == null) { if (t.Equals(typeof(IList)) || t.Equals(typeof(ICollection)) || t.Equals(typeof(IEnumerable))) { listObject = new List <object>(); objectType = typeof(object); } } if (listObject != null) { System.Collections.IList ie = (System.Collections.IList)listObject; foreach (CBORObject value in objThis.Values) { ie.Add(value.ToObject(objectType, mapper, options, depth + 1)); } return(listObject); } } if (objThis.Type == CBORType.Map) { var isDict = false; Type keyType = null; Type valueType = null; object dictObject = null; #if NET40 || NET20 isDict = t.IsGenericType; if (t.IsGenericType) { Type td = t.GetGenericTypeDefinition(); isDict = td.Equals(typeof(Dictionary <,>)) || td.Equals(typeof(IDictionary <,>)); } // DebugUtility.Log("list=" + isDict); isDict = isDict && t.GetGenericArguments().Length == 2; // DebugUtility.Log("list=" + isDict); if (isDict) { keyType = t.GetGenericArguments()[0]; valueType = t.GetGenericArguments()[1]; Type listType = typeof(Dictionary <,>).MakeGenericType( keyType, valueType); dictObject = Activator.CreateInstance(listType); } #else isDict = (t.GetTypeInfo().IsGenericType); if (t.GetTypeInfo().IsGenericType) { Type td = t.GetGenericTypeDefinition(); isDict = (td.Equals(typeof(Dictionary <,>)) || td.Equals(typeof(IDictionary <,>))); } //DebugUtility.Log("list=" + isDict); isDict = (isDict && t.GenericTypeArguments.Length == 2); //DebugUtility.Log("list=" + isDict); if (isDict) { keyType = t.GenericTypeArguments[0]; valueType = t.GenericTypeArguments[1]; Type listType = typeof(Dictionary <,>).MakeGenericType( keyType, valueType); dictObject = Activator.CreateInstance(listType); } #endif if (dictObject == null) { if (t.Equals(typeof(IDictionary))) { dictObject = new Dictionary <object, object>(); keyType = typeof(object); valueType = typeof(object); } } if (dictObject != null) { System.Collections.IDictionary idic = (System.Collections.IDictionary)dictObject; foreach (CBORObject key in objThis.Keys) { CBORObject value = objThis[key]; idic.Add( key.ToObject(keyType, mapper, options, depth + 1), value.ToObject(valueType, mapper, options, depth + 1)); } return(dictObject); } if (mapper != null) { if (!mapper.FilterTypeName(t.FullName)) { throw new CBORException("Type " + t.FullName + " not supported"); } } else { if (t.FullName != null && (StartsWith(t.FullName, "Microsoft.Win32." ) || StartsWith(t.FullName, "System.IO."))) { throw new CBORException("Type " + t.FullName + " not supported"); } if (StartsWith(t.FullName, "System.") && !HasCustomAttribute(t, "System.SerializableAttribute")) { throw new CBORException("Type " + t.FullName + " not supported"); } } var values = new List <KeyValuePair <string, CBORObject> >(); foreach (string key in PropertyMap2.GetPropertyNames( t, options != null ? options.UseCamelCase : true)) { if (objThis.ContainsKey(key)) { CBORObject cborValue = objThis[key]; var dict = new KeyValuePair <string, CBORObject>( key, cborValue); values.Add(dict); } } return(PropertyMap2.ObjectWithProperties( t, values, mapper, options, depth)); } else { throw new CBORException(); } }
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 " + CBORUtilities.BigIntToString(bigintAdditional) + " 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 " + CBORUtilities.BigIntToString(bigintAdditional) + " 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 " + CBORUtilities.BigIntToString(bigintAdditional) + " 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 " + CBORUtilities.BigIntToString(bigintAdditional) + " 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); } 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"); }
private static bool IsUntaggedInteger(CBORObject o) { return(!o.IsTagged && o.Type == CBORType.Integer); }
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; CBORObject fixedObject; if (this.options.Ctap2Canonical) { if (additional >= 0x1c) { // NOTE: Includes stop byte and indefinite length data items throw new CBORException("Invalid canonical CBOR encountered"); } // Check if this represents a fixed object (NOTE: All fixed objects // comply with CTAP2 canonical CBOR). fixedObject = CBORObject.GetFixedObject(firstbyte); if (fixedObject != null) { return(fixedObject); } 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 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" + "\u0020than 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"); }
private static bool IsUntaggedIntegerOrBignum(CBORObject o) { return(IsUntaggedInteger(o) || ((o.HasOneTag(2) || o.HasOneTag(3)) && o.Type == CBORType.ByteString)); }
private CBORObject NextJSONValue( int firstChar, int[] nextChar, int depth) { string str; int c = firstChar; CBORObject obj = null; if (c < 0) { this.RaiseError("Unexpected end of data"); } switch (c) { case '"': { // Parse a string // The tokenizer already checked the string for invalid // surrogate pairs, so just call the CBORObject // constructor directly obj = CBORObject.FromRaw(this.NextJSONString()); nextChar[0] = this.SkipWhitespaceJSON(); return(obj); } case '{': { // Parse an object obj = this.ParseJSONObject(depth + 1); nextChar[0] = this.SkipWhitespaceJSON(); return(obj); } case '[': { // Parse an array obj = this.ParseJSONArray(depth + 1); nextChar[0] = this.SkipWhitespaceJSON(); return(obj); } case 't': { // Parse true if ((c = this.ReadChar()) != 'r' || (c = this.ReadChar()) != 'u' || (c = this.ReadChar()) != 'e') { this.RaiseError("Value can't be parsed."); } c = this.ReadChar(); if (c == 0x20 || c == 0x0a || c == 0x0d || c == 0x09) { nextChar[0] = this.SkipWhitespaceJSON(); } else if (this.jsonSequenceMode && depth == 0) { nextChar[0] = c; this.RaiseError("JSON whitespace expected after top-level " + "number in JSON sequence"); } else { nextChar[0] = c; } return(CBORObject.True); } case 'f': { // Parse false if ((c = this.ReadChar()) != 'a' || (c = this.ReadChar()) != 'l' || (c = this.ReadChar()) != 's' || (c = this.ReadChar()) != 'e') { this.RaiseError("Value can't be parsed."); } c = this.ReadChar(); if (c == 0x20 || c == 0x0a || c == 0x0d || c == 0x09) { nextChar[0] = this.SkipWhitespaceJSON(); } else if (this.jsonSequenceMode && depth == 0) { nextChar[0] = c; this.RaiseError("JSON whitespace expected after top-level " + "number in JSON sequence"); } else { nextChar[0] = c; } return(CBORObject.False); } case 'n': { // Parse null if ((c = this.ReadChar()) != 'u' || (c = this.ReadChar()) != 'l' || (c = this.ReadChar()) != 'l') { this.RaiseError("Value can't be parsed."); } c = this.ReadChar(); if (c == 0x20 || c == 0x0a || c == 0x0d || c == 0x09) { nextChar[0] = this.SkipWhitespaceJSON(); } else if (this.jsonSequenceMode && depth == 0) { nextChar[0] = c; this.RaiseError("JSON whitespace expected after top-level " + "number in JSON sequence"); } else { nextChar[0] = c; } return(CBORObject.Null); } case '-': { // Parse a negative number return(this.NextJSONNegativeNumber(nextChar, depth)); } case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': { // Parse a nonnegative number int cval = c - '0'; int cstart = c; var needObj = true; c = this.ReadChar(); if (!(c == '-' || c == '+' || c == '.' || (c >= '0' && c <= '9') || c == 'e' || c == 'E')) { // Optimize for common case where JSON number // is a single digit without sign or exponent obj = CBORDataUtilities.ParseSmallNumber(cval, this.options); needObj = false; } else if (c >= '0' && c <= '9') { int csecond = c; if (cstart == '0') { // Leading zero followed by any digit is not allowed this.RaiseError("JSON number can't be parsed."); } cval = (cval * 10) + (int)(c - '0'); c = this.ReadChar(); if (c >= '0' && c <= '9') { var digits = 2; var ctmp = new int[10]; ctmp[0] = cstart; ctmp[1] = csecond; while (digits < 9 && (c >= '0' && c <= '9')) { cval = (cval * 10) + (int)(c - '0'); ctmp[digits++] = c; c = this.ReadChar(); } if (c == 'e' || c == 'E' || c == '.' || (c >= '0' && c <= '9')) { // Not an all-digit number, or too long this.sb = this.sb ?? new StringBuilder(); this.sb.Remove(0, this.sb.Length); for (var vi = 0; vi < digits; ++vi) { this.sb.Append((char)ctmp[vi]); } } else { obj = CBORDataUtilities.ParseSmallNumber(cval, this.options); needObj = false; } } else if (!(c == '-' || c == '+' || c == '.' || c == 'e' || c == 'E')) { // Optimize for common case where JSON number // is two digits without sign, decimal point, or exponent obj = CBORDataUtilities.ParseSmallNumber(cval, this.options); needObj = false; } else { this.sb = this.sb ?? new StringBuilder(); this.sb.Remove(0, this.sb.Length); this.sb.Append((char)cstart); this.sb.Append((char)csecond); } } else { this.sb = this.sb ?? new StringBuilder(); this.sb.Remove(0, this.sb.Length); this.sb.Append((char)cstart); } if (needObj) { var charbuf = new char[32]; var charbufptr = 0; while ( c == '-' || c == '+' || c == '.' || (c >= '0' && c <= '9') || c == 'e' || c == 'E') { charbuf[charbufptr++] = (char)c; if (charbufptr >= 32) { this.sb.Append(charbuf, 0, 32); charbufptr = 0; } c = this.ReadChar(); } if (charbufptr > 0) { this.sb.Append(charbuf, 0, charbufptr); } // check if character can validly appear after a JSON number if (c != ',' && c != ']' && c != '}' && c != -1 && c != 0x20 && c != 0x0a && c != 0x0d && c != 0x09) { this.RaiseError("Invalid character after JSON number"); } str = this.sb.ToString(); obj = CBORDataUtilities.ParseJSONNumber(str, this.options); if (obj == null) { string errstr = (str.Length <= 100) ? str : (str.Substring(0, 100) + "..."); this.RaiseError("JSON number can't be parsed. " + errstr); } } if (c == 0x20 || c == 0x0a || c == 0x0d || c == 0x09) { nextChar[0] = this.SkipWhitespaceJSON(); } else if (this.jsonSequenceMode && depth == 0) { nextChar[0] = c; this.RaiseError("JSON whitespace expected after top-level " + "number in JSON sequence"); } else { nextChar[0] = c; } return(obj); } default: this.RaiseError("Value can't be parsed."); break; } return(null); }
public CBORObject ValidateObject(CBORObject obj) { return CBORTag2.ConvertToBigNum(obj, true); }
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)); } }
private CBORObject NextJSONNonnegativeNumber(int c, int[] nextChar) { // Assumes the last character read was a digit CBORObject obj = null; int cval = c - '0'; int cstart = c; int startIndex = this.index - 1; var needObj = true; int numberStartIndex = this.index - 1; // DebugUtility.Log("js=" + (jstring)); c = this.index < this.endPos ? ((int)this.jstring[this.index++]) & 0xffff : -1; if (!(c == '-' || c == '+' || c == '.' || (c >= '0' && c <= '9') || c == 'e' || c == 'E')) { // Optimize for common case where JSON number // is a single digit without sign or exponent obj = CBORDataUtilities.ParseSmallNumber(cval, this.options); needObj = false; } else if (c >= '0' && c <= '9') { int csecond = c; if (cstart == '0') { // Leading zero followed by any digit is not allowed this.RaiseError("JSON number can't be parsed."); } cval = (cval * 10) + (int)(c - '0'); c = this.index < this.endPos ? ((int)this.jstring[this.index++]) : -1; if (c >= '0' && c <= '9') { var digits = 2; while (digits < 9 && (c >= '0' && c <= '9')) { cval = (cval * 10) + (int)(c - '0'); c = this.index < this.endPos ? ((int)this.jstring[this.index++]) : -1; ++digits; } if (!(c == 'e' || c == 'E' || c == '.' || (c >= '0' && c <= '9'))) { // All-digit number that's short enough obj = CBORDataUtilities.ParseSmallNumber(cval, this.options); needObj = false; } } else if (!(c == '-' || c == '+' || c == '.' || c == 'e' || c == 'E')) { // Optimize for common case where JSON number // is two digits without sign, decimal point, or exponent obj = CBORDataUtilities.ParseSmallNumber(cval, this.options); needObj = false; } } if (needObj) { // NOTE: Differs from CBORJson2, notably because the whole // rest of the string is checked whether the beginning of the rest // is a JSON number var endIndex = new int[1]; endIndex[0] = numberStartIndex; obj = CBORDataUtilities.ParseJSONNumber( this.jstring, numberStartIndex, this.endPos - numberStartIndex, this.options, endIndex); int numberEndIndex = endIndex[0]; this.index = numberEndIndex >= this.endPos ? this.endPos : (numberEndIndex + 1); if (obj == null) { int strlen = numberEndIndex - numberStartIndex; string errstr = this.jstring.Substring(numberStartIndex, Math.Min(100, strlen)); if (strlen > 100) { errstr += "..."; } this.RaiseError("JSON number can't be parsed. " + errstr); } #if DEBUG if (numberEndIndex < numberStartIndex) { throw new ArgumentException("numberEndIndex (" + numberEndIndex + ") is not greater or equal to " + numberStartIndex); } #endif c = numberEndIndex >= this.endPos ? -1 : this.jstring[numberEndIndex]; // check if character can validly appear after a JSON number if (c != ',' && c != ']' && c != '}' && c != -1 && c != 0x20 && c != 0x0a && c != 0x0d && c != 0x09) { this.RaiseError("Invalid character after JSON number"); } // DebugUtility.Log("endIndex="+endIndex[0]+", "+ // this.jstring.Substring(endIndex[0], // Math.Min(20, this.endPos-endIndex[0]))); } if (c == -1 || (c != 0x20 && c != 0x0a && c != 0x0d && c != 0x09)) { nextChar[0] = c; } else { nextChar[0] = this.SkipWhitespaceJSON(); } return(obj); }
public static CBORObject FromObject(ulong value) { return(CBORObject.FromObject(UInt64ToEInteger(value))); }
private static CBORNumber BigFracToNumber( CBORObject o, int tagName) { if (o.Type != CBORType.Array) { return(null); // "Big fraction must be an array"); } if (tagName == 268 || tagName == 269) { if (o.Count != 3) { return(null); // "Extended big fraction requires exactly 3 items"); } if (!IsUntaggedInteger(o[2])) { return(null); // "Third item must be an integer"); } } else { if (o.Count != 2) { return(null); // "Big fraction requires exactly 2 items"); } } if (tagName == 4 || tagName == 5) { if (!IsUntaggedInteger(o[0])) { return(null); // "Exponent is not an integer"); } } else { if (!IsUntaggedIntegerOrBignum(o[0])) { return(null); // "Exponent is not an integer or bignum"); } } if (!IsUntaggedIntegerOrBignum(o[1])) { return(null); // "Mantissa is not an integer or bignum"); } EInteger exponent = IntegerOrBignum(o[0]); EInteger mantissa = IntegerOrBignum(o[1]); bool isdec = tagName == 4 || tagName == 264 || tagName == 268; EDecimal edec = isdec ? EDecimal.Create(mantissa, exponent) : null; EFloat efloat = !isdec?EFloat.Create(mantissa, exponent) : null; if (tagName == 268 || tagName == 269) { if (mantissa.Sign < 0) { return(null); // "Mantissa may not be negative"); } if (!o[2].CanValueFitInInt32()) { return(null); // "Invalid options"); } int options = o[2].AsInt32Value(); switch (options) { case 0: break; case 1: if (isdec) { edec = edec.Negate(); } else { efloat = efloat.Negate(); } break; case 2: if (!exponent.IsZero || !mantissa.IsZero) { return(null); // "invalid values"); } if (isdec) { edec = EDecimal.PositiveInfinity; } else { efloat = EFloat.PositiveInfinity; } break; case 3: if (!exponent.IsZero || !mantissa.IsZero) { return(null); // "invalid values"); } if (isdec) { edec = EDecimal.NegativeInfinity; } else { efloat = EFloat.NegativeInfinity; } break; case 4: case 5: case 6: case 7: if (!exponent.IsZero) { return(null); // "invalid values"); } if (isdec) { edec = EDecimal.CreateNaN( mantissa, options >= 6, options == 5 || options == 7, null); } else { efloat = EFloat.CreateNaN( mantissa, options >= 6, options == 5 || options == 7, null); } break; default: return(null); // "Invalid options"); } } if (isdec) { return(CBORNumber.FromObject(edec)); } else { return(CBORNumber.FromObject(efloat)); } }
private static CBORNumber RationalToNumber( CBORObject o, int tagName) { if (o.Type != CBORType.Array) { return(null); // "Big fraction must be an array"; } if (tagName == 270) { if (o.Count != 3) { return(null); // "Extended big fraction requires exactly 3 items"; } if (!IsUntaggedInteger(o[2])) { return(null); // "Third item must be an integer"; } } else { if (o.Count != 2) { return(null); // "Big fraction requires exactly 2 items"; } } if (!IsUntaggedIntegerOrBignum(o[0])) { return(null); // "Numerator is not an integer or bignum"; } if (!IsUntaggedIntegerOrBignum(o[1])) { return(null); // "Denominator is not an integer or bignum"); } EInteger numerator = IntegerOrBignum(o[0]); EInteger denominator = IntegerOrBignum(o[1]); if (denominator.Sign <= 0) { return(null); // "Denominator may not be negative or zero"); } ERational erat = ERational.Create(numerator, denominator); if (tagName == 270) { if (numerator.Sign < 0) { return(null); // "Numerator may not be negative"); } if (!o[2].CanValueFitInInt32()) { return(null); // "Invalid options"; } int options = o[2].AsInt32Value(); switch (options) { case 0: break; case 1: erat = erat.Negate(); break; case 2: if (!numerator.IsZero || denominator.CompareTo(1) != 0) { return(null); // "invalid values"); } erat = ERational.PositiveInfinity; break; case 3: if (!numerator.IsZero || denominator.CompareTo(1) != 0) { return(null); // "invalid values"); } erat = ERational.NegativeInfinity; break; case 4: case 5: case 6: case 7: if (denominator.CompareTo(1) != 0) { return(null); // "invalid values"); } erat = ERational.CreateNaN( numerator, options >= 6, options == 5 || options == 7); break; default: return(null); // "Invalid options"); } } return(CBORNumber.FromObject(erat)); }
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))); } }
public ParticipantObject(CBORObject cborObject) { _jsonString = cborObject.ToJSONString(); }
private static bool CheckRationalToNumber( CBORObject o, int tagName) { if (o.Type != CBORType.Array) { return(false); } if (tagName == 270) { if (o.Count != 3) { return(false); } if (!IsUntaggedInteger(o[2])) { return(false); } } else { if (o.Count != 2) { return(false); } } if (!IsUntaggedIntegerOrBignum(o[0])) { return(false); } if (!IsUntaggedIntegerOrBignum(o[1])) { return(false); } EInteger denominator = IntegerOrBignum(o[1]); if (denominator.Sign <= 0) { return(false); } if (tagName == 270) { EInteger numerator = IntegerOrBignum(o[0]); if (numerator.Sign < 0 || !o[2].CanValueFitInInt32()) { return(false); } int options = o[2].AsInt32Value(); switch (options) { case 0: case 1: return(true); case 2: case 3: return(numerator.IsZero && denominator.CompareTo(1) == 0); case 4: case 5: case 6: case 7: return(denominator.CompareTo(1) == 0); default: return(false); } } return(true); }
private static bool CheckBigFracToNumber( CBORObject o, int tagName) { if (o.Type != CBORType.Array) { return(false); } if (tagName == 268 || tagName == 269) { if (o.Count != 3) { return(false); } if (!IsUntaggedInteger(o[2])) { return(false); } } else { if (o.Count != 2) { return(false); } } if (tagName == 4 || tagName == 5) { if (!IsUntaggedInteger(o[0])) { return(false); } } else { if (!IsUntaggedIntegerOrBignum(o[0])) { return(false); } } if (!IsUntaggedIntegerOrBignum(o[1])) { return(false); } if (tagName == 268 || tagName == 269) { EInteger exponent = IntegerOrBignum(o[0]); EInteger mantissa = IntegerOrBignum(o[1]); if (mantissa.Sign < 0 || !o[2].CanValueFitInInt32()) { return(false); } int options = o[2].AsInt32Value(); switch (options) { case 0: case 1: return(true); case 2: case 3: return(exponent.IsZero && mantissa.IsZero); case 4: case 5: case 6: case 7: return(exponent.IsZero); default: return(false); } } return(true); }
public CBORObject ValidateObject(CBORObject obj) { return CBORTag5.ConvertToDecimalFrac(obj, true, this.extended); }