protected object?GetValue(string s, int n, ref int i) { if (i < n) { var c = s[i - 1]; if (c == '"' || c == '\'') { return(GetString(s, n, ref i)); } if (c == '{') { var d = new Document(); i = d.Fields(s, i, n); return(d); } if (c == '[') { var d = new DocArray(); i = d.Items(s, i, n); return(d); } if (i + 4 < n && s.Substring(i, 4) == "true") { i += 4; return(true); } if (i + 5 < n && s.Substring(i, 5) == "false") { i += 5; return(false); } if (i + 4 < n && s.Substring(i, 4) == "null") { i += 4; return(null); } var sg = c == '-'; if (sg && i < n) { c = s[i++]; } var whole = Shareable.Integer.Zero; var Ten = new Shareable.Integer(10); if (Char.IsDigit(c)) { i--; whole = new Shareable.Integer(GetHex(s, n, ref i)); while (i < n && Char.IsDigit(s[i])) { whole = whole * Ten + new Shareable.Integer(GetHex(s, n, ref i)); } } else { goto bad; } if (i >= n || (s[i] != '.' && s[i] != 'e' && s[i] != 'E')) { if (whole.CompareTo(Shareable.Integer.intMax) < 0) { return(sg ? (int)-whole : (int)whole); } if (whole.CompareTo(Shareable.Integer.longMax) < 0) { return(sg ? (long)-whole : (long)whole); } return(sg ? -whole : whole); } int scale = 0; if (s[i] == '.') { if (++i >= n || !Char.IsDigit(s[i])) { throw new DocumentException("decimal part expected"); } while (i < n && Char.IsDigit(s[i])) { whole = whole * Ten + new Shareable.Integer(GetHex(s, n, ref i)); scale++; } } if (i >= n || (s[i] != 'e' && s[i] != 'E')) { var m = (decimal)whole; while (scale-- > 0) { m /= 10M; } return(sg ? -m : m); } if (++i >= n) { throw new DocumentException("exponent part expected"); } var esg = s[i] == '-'; if ((s[i] == '-' || s[i] == '+') && (++i >= n || !Char.IsDigit(s[i]))) { throw new DocumentException("exponent part expected"); } var exp = 0; while (i < n && Char.IsDigit(s[i])) { exp = exp * 10 + GetHex(s, n, ref i); } if (esg) { exp = -exp; } var dr = (double)whole * Math.Pow(10.0, exp - scale); return(sg ? -dr : dr); } bad: throw new DocumentException("Value expected at " + (i - 1)); }
internal static object?GetValue(byte t, byte[] b, ref int i) { object?tv = null; switch (t) { case 1: { tv = BitConverter.ToDouble(b, i); i += 8; break; } case 2: { var n = GetLength(b, i); i += 4; tv = Encoding.UTF8.GetString(b, i, n - 1); i += n; break; } case 3: { tv = new Document(b, i); i += GetLength(b, i); break; } case 4: { tv = new DocArray(b, i); i += GetLength(b, i); break; } case 5: { var n = GetLength(b, i); var r = new byte[n]; for (int j = 0; j < n; j++) { r[j] = b[i + j + 4]; } tv = r; i += n; break; } case 7: { var r = new byte[12]; for (int j = 0; j < 12; j++) { r[j] = b[i + j]; } tv = new ObjectId(r); i += 12; break; } case 8: { tv = b[i] != 0; i++; break; } case 9: { tv = BitConverter.ToInt64(b, i); i += 8; break; } case 16: { tv = (long)BitConverter.ToInt32(b, i); i += 4; break; } case 18: { tv = BitConverter.ToInt64(b, i); i += 8; break; } case 19: // decimal type added for Pyrrho { var n = GetLength(b, i); i += 4; tv = decimal.Parse(Encoding.UTF8.GetString(b, i, n - 1)); i += n; break; } } return(tv); }