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; 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); #if DEBUG if (( (EDecimal)obj.ToObject( typeof(EDecimal))).CompareToValue(EDecimal.FromInt32(cval)) != 0) { this.RaiseError(String.Empty + obj); } #endif 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); #if DEBUG if (( (EDecimal)obj.ToObject( typeof(EDecimal))).CompareToValue(EDecimal.FromInt32(cval)) != 0) { this.RaiseError(String.Empty + obj); } #endif 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; obj = CBORDataUtilities.ParseJSONNumber( this.bytes, numberStartIndex, numberEndIndex - numberStartIndex, this.options); #if DEBUG if (this.options.NumberConversion == JSONOptions.ConversionMode.Full && ( (EDecimal)obj.ToObject( typeof(EDecimal))).CompareToValue(EDecimal.FromString(this.bytes, numberStartIndex, numberEndIndex - numberStartIndex)) != 0) { this.RaiseError(String.Empty + obj); } #endif if (obj == null) { string errstr = String.Empty; // 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); }
private string TryGetDateTimeFieldsInternal( CBORObject obj, EInteger[] year, int[] lesserFields) { if (obj == null) { return("Object is null"); } if (year == null) { throw new ArgumentNullException(nameof(year)); } EInteger[] outYear = year; if (outYear.Length < 1) { throw new ArgumentException("\"year\" + \"'s length\" (" + outYear.Length + ") is not greater or equal to 1"); } if (lesserFields == null) { throw new ArgumentNullException(nameof(lesserFields)); } if (lesserFields.Length < 7) { throw new ArgumentException("\"lesserFields\" + \"'s length\" (" + lesserFields.Length + ") is not greater or equal to 7"); } if (this.convType == ConversionType.UntaggedNumber) { if (obj.IsTagged) { return("May not be tagged"); } CBORObject untagobj = obj; if (!untagobj.IsNumber) { return("Not a finite number"); } CBORNumber num = untagobj.AsNumber(); if (!num.IsFinite()) { return("Not a finite number"); } if (num.CompareTo(Int64.MinValue) < 0 || num.CompareTo(Int64.MaxValue) > 0) { return("Too big or small to fit a DateTime"); } if (num.CanFitInInt64()) { CBORUtilities.BreakDownSecondsSinceEpoch( num.ToInt64Checked(), outYear, lesserFields); } else { EDecimal dec; dec = (EDecimal)untagobj.ToObject(typeof(EDecimal)); CBORUtilities.BreakDownSecondsSinceEpoch( dec, outYear, lesserFields); } return(null); // no error } if (obj.HasMostOuterTag(0)) { string str = obj.AsString(); try { CBORUtilities.ParseAtomDateTimeString(str, outYear, lesserFields); return(null); // no error } catch (OverflowException ex) { return(ex.Message); } catch (InvalidOperationException ex) { return(ex.Message); } catch (ArgumentException ex) { return(ex.Message); } } else if (obj.HasMostOuterTag(1)) { CBORObject untagobj = obj.UntagOne(); if (!untagobj.IsNumber) { return("Not a finite number"); } CBORNumber num = untagobj.AsNumber(); if (!num.IsFinite()) { return("Not a finite number"); } if (num.CanFitInInt64()) { CBORUtilities.BreakDownSecondsSinceEpoch( num.ToInt64Checked(), outYear, lesserFields); } else { EDecimal dec; dec = (EDecimal)untagobj.ToObject(typeof(EDecimal)); CBORUtilities.BreakDownSecondsSinceEpoch( dec, outYear, lesserFields); } return(null); // No error } return("Not tag 0 or 1"); }