/// <inheritdoc /> public override async ValueTask <decimal> Read(NpgsqlReadBuffer buf, int len, bool async, FieldDescription?fieldDescription = null) { await buf.Ensure(4 *sizeof(short), async); var result = new DecimalRaw(); var groups = buf.ReadInt16(); var weight = buf.ReadInt16() - groups + 1; var sign = buf.ReadUInt16(); if ((sign & SignSpecialMask) == SignSpecialMask) { throw sign switch { SignNan => new InvalidCastException("Numeric NaN not supported by System.Decimal"), SignPinf => new InvalidCastException("Numeric Infinity not supported by System.Decimal"), SignNinf => new InvalidCastException("Numeric -Infinity not supported by System.Decimal"), _ => new InvalidCastException($"Numeric special value {sign} not supported by System.Decimal") }; } if (sign == SignNegative) { DecimalRaw.Negate(ref result); } var scale = buf.ReadInt16(); if (scale < 0 is var exponential && exponential) { scale = (short)(-scale); } else { result.Scale = scale; } if (scale > MaxDecimalScale) { throw new OverflowException("Numeric value does not fit in a System.Decimal"); } var scaleDifference = exponential ? weight * MaxGroupScale : weight * MaxGroupScale + scale; if (groups > MaxGroupCount) { throw new OverflowException("Numeric value does not fit in a System.Decimal"); } await buf.Ensure(groups *sizeof(ushort), async); if (groups == MaxGroupCount) { while (groups-- > 1) { DecimalRaw.Multiply(ref result, MaxGroupSize); DecimalRaw.Add(ref result, buf.ReadUInt16()); } var group = buf.ReadUInt16(); var groupSize = DecimalRaw.Powers10[-scaleDifference]; if (group % groupSize != 0) { throw new OverflowException("Numeric value does not fit in a System.Decimal"); } DecimalRaw.Multiply(ref result, MaxGroupSize / groupSize); DecimalRaw.Add(ref result, group / groupSize); } else { while (groups-- > 0) { DecimalRaw.Multiply(ref result, MaxGroupSize); DecimalRaw.Add(ref result, buf.ReadUInt16()); } if (scaleDifference < 0) { DecimalRaw.Divide(ref result, DecimalRaw.Powers10[-scaleDifference]); } else { while (scaleDifference > 0) { var scaleChunk = Math.Min(DecimalRaw.MaxUInt32Scale, scaleDifference); DecimalRaw.Multiply(ref result, DecimalRaw.Powers10[scaleChunk]); scaleDifference -= scaleChunk; } } } return(result.Value); }
public override async ValueTask <NpgsqlTsQuery> Read(NpgsqlReadBuffer buf, int len, bool async, FieldDescription?fieldDescription = null, CancellationToken cancellationToken = default) { await buf.Ensure(4, async, cancellationToken); var numTokens = buf.ReadInt32(); if (numTokens == 0) { return(new NpgsqlTsQueryEmpty()); } NpgsqlTsQuery?value = null; var nodes = new Stack <Tuple <NpgsqlTsQuery, int> >(); len -= 4; for (var tokenPos = 0; tokenPos < numTokens; tokenPos++) { await buf.Ensure(Math.Min(len, MaxSingleTokenBytes), async, cancellationToken); var readPos = buf.ReadPosition; var isOper = buf.ReadByte() == 2; if (isOper) { var operKind = (NpgsqlTsQuery.NodeKind)buf.ReadByte(); if (operKind == NpgsqlTsQuery.NodeKind.Not) { var node = new NpgsqlTsQueryNot(null); InsertInTree(node, nodes, ref value); nodes.Push(new Tuple <NpgsqlTsQuery, int>(node, 0)); } else { var node = operKind switch { NpgsqlTsQuery.NodeKind.And => (NpgsqlTsQuery) new NpgsqlTsQueryAnd(null, null), NpgsqlTsQuery.NodeKind.Or => new NpgsqlTsQueryOr(null, null), NpgsqlTsQuery.NodeKind.Phrase => new NpgsqlTsQueryFollowedBy(null, buf.ReadInt16(), null), _ => throw new InvalidOperationException($"Internal Npgsql bug: unexpected value {operKind} of enum {nameof(NpgsqlTsQuery.NodeKind)}. Please file a bug.") }; InsertInTree(node, nodes, ref value); nodes.Push(new Tuple <NpgsqlTsQuery, int>(node, 2)); nodes.Push(new Tuple <NpgsqlTsQuery, int>(node, 1)); } } else { var weight = (NpgsqlTsQueryLexeme.Weight)buf.ReadByte(); var prefix = buf.ReadByte() != 0; var str = buf.ReadNullTerminatedString(); InsertInTree(new NpgsqlTsQueryLexeme(str, weight, prefix), nodes, ref value); } len -= buf.ReadPosition - readPos; } if (nodes.Count != 0) { throw new InvalidOperationException("Internal Npgsql bug, please report."); } return(value !);
/// <inheritdoc /> public override decimal Read(NpgsqlReadBuffer buf, int len, FieldDescription?fieldDescription = null) { var result = new DecimalRaw(); var groups = buf.ReadInt16(); var weight = buf.ReadInt16() - groups + 1; var sign = buf.ReadUInt16(); if (sign == SignNan) { throw new InvalidCastException("Numeric NaN not supported by System.Decimal"); } if (sign == SignNegative) { DecimalRaw.Negate(ref result); } var scale = buf.ReadInt16(); if (scale > MaxDecimalScale) { throw new OverflowException("Numeric value does not fit in a System.Decimal"); } result.Scale = scale; var scaleDifference = scale + weight * MaxGroupScale; if (groups == MaxGroupCount) { while (groups-- > 1) { DecimalRaw.Multiply(ref result, MaxGroupSize); DecimalRaw.Add(ref result, buf.ReadUInt16()); } var group = buf.ReadUInt16(); var groupSize = DecimalRaw.Powers10[-scaleDifference]; if (group % groupSize != 0) { throw new OverflowException("Numeric value does not fit in a System.Decimal"); } DecimalRaw.Multiply(ref result, MaxGroupSize / groupSize); DecimalRaw.Add(ref result, group / groupSize); } else { while (groups-- > 0) { DecimalRaw.Multiply(ref result, MaxGroupSize); DecimalRaw.Add(ref result, buf.ReadUInt16()); } if (scaleDifference < 0) { DecimalRaw.Divide(ref result, DecimalRaw.Powers10[-scaleDifference]); } else { while (scaleDifference > 0) { var scaleChunk = Math.Min(DecimalRaw.MaxUInt32Scale, scaleDifference); DecimalRaw.Multiply(ref result, DecimalRaw.Powers10[scaleChunk]); scaleDifference -= scaleChunk; } } } return(result.Value); }
/// <inheritdoc /> public override short Read(NpgsqlReadBuffer buf, int len, FieldDescription?fieldDescription = null) => buf.ReadInt16();
BigInteger INpgsqlSimpleTypeHandler <BigInteger> .Read(NpgsqlReadBuffer buf, int len, FieldDescription fieldDescription) { var result = new BigInteger(); var groups = buf.ReadInt16(); var weight = buf.ReadInt16() - groups + 1; var sign = buf.ReadUInt16(); if (sign == SignNan) { throw new NpgsqlSafeReadException(new InvalidCastException("Numeric NaN not supported by System.Numerics.BigInteger")); } var scale = buf.ReadInt16(); if (scale > 0) { throw new NpgsqlSafeReadException(new OverflowException("Numeric value does not fit in a System.Numerics.BigInteger")); } try { var scaleDifference = scale + weight * MaxGroupScale; if (groups == MaxGroupCount) { while (groups-- > 1) { result = result * MaxGroupSize; result = result + buf.ReadUInt16(); } var group = buf.ReadUInt16(); var groupSize = DecimalRaw.Powers10[-scaleDifference]; if (group % groupSize != 0) { throw new NpgsqlSafeReadException(new OverflowException("Numeric value does not fit in a System.Numerics.BigInteger")); } result = result * (MaxGroupSize / groupSize); result = result + (group / groupSize); } else { while (groups-- > 0) { result = result * MaxGroupSize; result = result + buf.ReadUInt16(); } if (scaleDifference < 0) { result = result / (BigInteger)Math.Pow(10, -scaleDifference); } else { while (scaleDifference > 0) { var scaleChunk = Math.Min(DecimalRaw.MaxUInt32Scale, scaleDifference); result = result * (BigInteger)Math.Pow(10, scaleChunk); scaleDifference -= scaleChunk; } } } } catch (OverflowException e) { throw new NpgsqlSafeReadException(e); } if (sign == SignNegative) { result = result * -1; } return(result); }