public override void Write(decimal value, NpgsqlWriteBuffer buf, NpgsqlParameter parameter) { if (value == 0M) { buf.WriteInt64(0); return; } var negative = value < 0; if (negative) { value = -value; } int numGroups, weight, fractionDigits; GetNumericHeader(value, out numGroups, out weight, out fractionDigits); buf.WriteInt16(numGroups); buf.WriteInt16(weight); buf.WriteInt16(negative ? 0x4000 : 0x0000); buf.WriteInt16(fractionDigits); for (int i = 0, pos = weight + 7; i < numGroups; i++, pos--) { buf.WriteInt16((ushort)(value / Decimals[pos])); value %= Decimals[pos]; } }
/// <inheritdoc /> public override void Write(Guid value, NpgsqlWriteBuffer buf, NpgsqlParameter?parameter) { var raw = new GuidRaw(value); buf.WriteInt32(raw.Data1); buf.WriteInt16(raw.Data2); buf.WriteInt16(raw.Data3); buf.WriteInt64(raw.Data4, BitConverter.IsLittleEndian); }
public override void Write(Guid value, NpgsqlWriteBuffer buf, NpgsqlParameter parameter) { // TODO: Allocation... investigate alternatives? var bytes = value.ToByteArray(); buf.WriteInt32(BitConverter.ToInt32(bytes, 0)); buf.WriteInt16(BitConverter.ToInt16(bytes, 4)); buf.WriteInt16(BitConverter.ToInt16(bytes, 6)); buf.WriteBytes(bytes, 8, 8); }
/// <inheritdoc /> public override void Write(decimal value, NpgsqlWriteBuffer buf, NpgsqlParameter?parameter) { var weight = 0; var groupCount = 0; Span <short> groups = stackalloc short[MaxGroupCount]; var raw = new DecimalRaw(value); if (raw.Low != 0 || raw.Mid != 0 || raw.High != 0) { var scale = raw.Scale; weight = -scale / MaxGroupScale - 1; uint remainder; var scaleChunk = scale % MaxGroupScale; if (scaleChunk > 0) { var divisor = DecimalRaw.Powers10[scaleChunk]; var multiplier = DecimalRaw.Powers10[MaxGroupScale - scaleChunk]; remainder = DecimalRaw.Divide(ref raw, divisor) * multiplier; if (remainder != 0) { weight--; goto WriteGroups; } } while ((remainder = DecimalRaw.Divide(ref raw, MaxGroupSize)) == 0) { weight++; } WriteGroups: groups[groupCount++] = (short)remainder; while (raw.Low != 0 || raw.Mid != 0 || raw.High != 0) { groups[groupCount++] = (short)DecimalRaw.Divide(ref raw, MaxGroupSize); } } buf.WriteInt16(groupCount); buf.WriteInt16(groupCount + weight); buf.WriteInt16(raw.Negative ? SignNegative : SignPositive); buf.WriteInt16(raw.Scale); while (groupCount > 0) { buf.WriteInt16(groups[--groupCount]); } }
public void Write(BigInteger value, NpgsqlWriteBuffer buf, NpgsqlParameter parameter) { var sig = value.Sign; var groups = new List <short>(MaxGroupCount); var weight = 0; var raw = sig * value; if (!raw.IsZero) { weight = -1; BigInteger remainder; do { remainder = raw % MaxGroupSize; raw = (raw - remainder) / MaxGroupSize; if (!remainder.IsZero) { break; } weight++; } while (true); groups.Add((short)remainder); while (!raw.IsZero) { remainder = raw % MaxGroupSize; raw = (raw - remainder) / MaxGroupSize; groups.Add((short)remainder); } } buf.WriteInt16(groups.Count); buf.WriteInt16(groups.Count + weight); buf.WriteInt16(sig > 0 ? SignPositive : SignNegative); buf.WriteInt16(0); for (var i = groups.Count - 1; i >= 0; i--) { buf.WriteInt16(groups[i]); } }
async Task StartRow(bool async, CancellationToken cancellationToken = default) { CheckReady(); if (_column != -1 && _column != NumColumns) { ThrowHelper.ThrowInvalidOperationException_BinaryImportParametersMismatch(NumColumns, _column); } if (_buf.WriteSpaceLeft < 2) { await _buf.Flush(async, cancellationToken); } _buf.WriteInt16(NumColumns); _column = 0; _rowsImported++; }
internal PgServerMock WriteRowDescription(params FieldDescription[] fields) { CheckDisposed(); _writeBuffer.WriteByte((byte)BackendMessageCode.RowDescription); _writeBuffer.WriteInt32(4 + 2 + fields.Sum(f => Encoding.GetByteCount(f.Name) + 1 + 18)); _writeBuffer.WriteInt16(fields.Length); foreach (var field in fields) { _writeBuffer.WriteNullTerminatedString(field.Name); _writeBuffer.WriteUInt32(field.TableOID); _writeBuffer.WriteInt16(field.ColumnAttributeNumber); _writeBuffer.WriteUInt32(field.TypeOID); _writeBuffer.WriteInt16(field.TypeSize); _writeBuffer.WriteInt32(field.TypeModifier); _writeBuffer.WriteInt16((short)field.FormatCode); } return(this); }
/// <inheritdoc /> public override async Task Write(NpgsqlTsVector vector, NpgsqlWriteBuffer buf, NpgsqlLengthCache?lengthCache, NpgsqlParameter?parameter, bool async) { if (buf.WriteSpaceLeft < 4) { await buf.Flush(async); } buf.WriteInt32(vector.Count); foreach (var lexeme in vector) { if (buf.WriteSpaceLeft < MaxSingleLexemeBytes) { await buf.Flush(async); } buf.WriteString(lexeme.Text); buf.WriteByte(0); buf.WriteInt16(lexeme.Count); for (var i = 0; i < lexeme.Count; i++) { buf.WriteInt16(lexeme[i].Value); } } }
internal override async Task Write(NpgsqlWriteBuffer buf, bool async) { Debug.Assert(Statement != null && Statement.All(c => c < 128)); var queryByteLen = _encoding.GetByteCount(Query); if (buf.WriteSpaceLeft < 1 + 4 + Statement.Length + 1) { await buf.Flush(async); } var messageLength = 1 + // Message code 4 + // Length Statement.Length + 1 + // Null terminator queryByteLen + 1 + // Null terminator 2 + // Number of parameters ParameterTypeOIDs.Count * 4; buf.WriteByte(Code); buf.WriteInt32(messageLength - 1); buf.WriteNullTerminatedString(Statement); await buf.WriteString(Query, queryByteLen, async); if (buf.WriteSpaceLeft < 1 + 2) { await buf.Flush(async); } buf.WriteByte(0); // Null terminator for the query buf.WriteInt16((short)ParameterTypeOIDs.Count); foreach (var t in ParameterTypeOIDs) { if (buf.WriteSpaceLeft < 4) { await buf.Flush(async); } buf.WriteInt32((int)t); } }
public void Write(string value, NpgsqlWriteBuffer buf, NpgsqlParameter parameter) { Debug.Assert(parameter != null); buf.WriteInt16((short)parameter.ConvertedValue); }
internal override async Task Write(NpgsqlWriteBuffer buf, bool async) { Debug.Assert(Statement != null && Statement.All(c => c < 128)); Debug.Assert(Portal != null && Portal.All(c => c < 128)); var headerLength = 1 + // Message code 4 + // Message length 1 + // Portal is always empty (only a null terminator) Statement.Length + 1 + 2; // Number of parameter format codes that follow if (buf.WriteSpaceLeft < headerLength) { Debug.Assert(buf.Size >= headerLength, "Buffer too small for Bind header"); await buf.Flush(async); } var formatCodesSum = 0; var paramsLength = 0; foreach (var p in InputParameters) { formatCodesSum += (int)p.FormatCode; p.LengthCache?.Rewind(); paramsLength += p.ValidateAndGetLength(); } var formatCodeListLength = formatCodesSum == 0 ? 0 : formatCodesSum == InputParameters.Count ? 1 : InputParameters.Count; var messageLength = headerLength + 2 * formatCodeListLength + // List of format codes 2 + // Number of parameters 4 * InputParameters.Count + // Parameter lengths paramsLength + // Parameter values 2 + // Number of result format codes 2 * (UnknownResultTypeList?.Length ?? 1); // Result format codes buf.WriteByte(Code); buf.WriteInt32(messageLength - 1); Debug.Assert(Portal == string.Empty); buf.WriteByte(0); // Portal is always empty buf.WriteNullTerminatedString(Statement); buf.WriteInt16(formatCodeListLength); // 0 length implicitly means all-text, 1 means all-binary, >1 means mix-and-match if (formatCodeListLength == 1) { if (buf.WriteSpaceLeft < 2) { await buf.Flush(async); } buf.WriteInt16((short)FormatCode.Binary); } else if (formatCodeListLength > 1) { foreach (var p in InputParameters) { if (buf.WriteSpaceLeft < 2) { await buf.Flush(async); } buf.WriteInt16((short)p.FormatCode); } } if (buf.WriteSpaceLeft < 2) { await buf.Flush(async); } buf.WriteInt16(InputParameters.Count); foreach (var param in InputParameters) { param.LengthCache?.Rewind(); await param.WriteWithLength(buf, async); } if (UnknownResultTypeList != null) { if (buf.WriteSpaceLeft < 2 + UnknownResultTypeList.Length * 2) { await buf.Flush(async); } buf.WriteInt16(UnknownResultTypeList.Length); foreach (var t in UnknownResultTypeList) { buf.WriteInt16(t ? 0 : 1); } } else { if (buf.WriteSpaceLeft < 4) { await buf.Flush(async); } buf.WriteInt16(1); buf.WriteInt16(AllResultTypesAreUnknown ? 0 : 1); } }
/// <inheritdoc /> public void Write(float value, NpgsqlWriteBuffer buf, NpgsqlParameter?parameter) => buf.WriteInt16((short)value);
/// <inheritdoc /> public void Write(sbyte value, NpgsqlWriteBuffer buf, NpgsqlParameter?parameter) => buf.WriteInt16(value);
/// <inheritdoc /> public override void Write(short value, NpgsqlWriteBuffer buf, NpgsqlParameter?parameter) => buf.WriteInt16(value);
public void Write(double value, NpgsqlWriteBuffer buf, NpgsqlParameter parameter) => buf.WriteInt16(checked ((short)value));
public void Write(decimal value, NpgsqlWriteBuffer buf, NpgsqlParameter parameter) => buf.WriteInt16((short)value);
public override async Task Write(NpgsqlTsQuery query, NpgsqlWriteBuffer buf, NpgsqlLengthCache lengthCache, NpgsqlParameter parameter, bool async) { var numTokens = GetTokenCount(query); if (buf.WriteSpaceLeft < 4) { await buf.Flush(async); } buf.WriteInt32(numTokens); if (numTokens == 0) { return; } _stack.Push(query); while (_stack.Count > 0) { if (buf.WriteSpaceLeft < 2) { await buf.Flush(async); } if (_stack.Peek().Kind == NpgsqlTsQuery.NodeKind.Lexeme && buf.WriteSpaceLeft < MaxSingleTokenBytes) { await buf.Flush(async); } var node = _stack.Pop(); buf.WriteByte(node.Kind == NpgsqlTsQuery.NodeKind.Lexeme ? (byte)1 : (byte)2); if (node.Kind != NpgsqlTsQuery.NodeKind.Lexeme) { buf.WriteByte((byte)node.Kind); if (node.Kind == NpgsqlTsQuery.NodeKind.Not) { _stack.Push(((NpgsqlTsQueryNot)node).Child); } else { if (node.Kind == NpgsqlTsQuery.NodeKind.Phrase) { buf.WriteInt16(((NpgsqlTsQueryFollowedBy)node).Distance); } _stack.Push(((NpgsqlTsQueryBinOp)node).Right); _stack.Push(((NpgsqlTsQueryBinOp)node).Left); } } else { var lexemeNode = (NpgsqlTsQueryLexeme)node; buf.WriteByte((byte)lexemeNode.Weights); buf.WriteByte(lexemeNode.IsPrefixSearch ? (byte)1 : (byte)0); buf.WriteString(lexemeNode.Text); buf.WriteByte(0); } } _stack.Clear(); }