public override bool Write(ref DirectBuffer directBuf) { if (_lexemePos == -1) { if (_writeBuf.WriteSpaceLeft < 4) { return(false); } _writeBuf.WriteInt32(_value.Count); _lexemePos = 0; } for (; _lexemePos < _value.Count; _lexemePos++) { if (_writeBuf.WriteSpaceLeft < MaxSingleLexemeBytes) { return(false); } _writeBuf.WriteString(_value[_lexemePos].Text); _writeBuf.WriteByte(0); _writeBuf.WriteInt16(_value[_lexemePos].Count); for (var i = 0; i < _value[_lexemePos].Count; i++) { _writeBuf.WriteInt16(_value[_lexemePos][i]._val); } } return(true); }
protected override async Task Write(object value, WriteBuffer buf, LengthCache lengthCache, NpgsqlParameter parameter, bool async, CancellationToken cancellationToken) { var vector = (NpgsqlTsVector)value; if (buf.WriteSpaceLeft < 4) { await buf.Flush(async, cancellationToken); } buf.WriteInt32(vector.Count); foreach (var lexeme in vector) { if (buf.WriteSpaceLeft < MaxSingleLexemeBytes) { await buf.Flush(async, cancellationToken); } buf.WriteString(lexeme.Text); buf.WriteByte(0); buf.WriteInt16(lexeme.Count); for (var i = 0; i < lexeme.Count; i++) { buf.WriteInt16(lexeme[i].Value); } } }
public override void Write(object value, WriteBuffer buf, NpgsqlParameter parameter) { var num = (decimal)(parameter?.ConvertedValue ?? value); if (num == 0M) { buf.WriteInt64(0); } else { bool negative = num < 0; if (negative) { num = -num; } int numGroups, weight, fractionDigits; GetNumericHeader(num, 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)(num / Decimals[pos])); num %= Decimals[pos]; } } }
protected override void Write(object value, WriteBuffer buf, NpgsqlParameter parameter = null) { if (parameter?.ConvertedValue != null) { value = parameter.ConvertedValue; } var bytes = ((Guid)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); }
internal void WriteStartup(Dictionary <string, string> parameters) { var len = sizeof(int) + // Length sizeof(int) + // Protocol version sizeof(byte); // Trailing zero byte foreach (var kvp in parameters) { len += PGUtil.UTF8Encoding.GetByteCount(kvp.Key) + 1 + PGUtil.UTF8Encoding.GetByteCount(kvp.Value) + 1; } // Should really never happen, just in case if (len > WriteBuffer.Size) { throw new Exception("Startup message bigger than buffer"); } WriteBuffer.WriteInt32(len); WriteBuffer.WriteInt16(ProtocolVersion.MAJOR); WriteBuffer.WriteInt16(ProtocolVersion.MINOR); foreach (var kv in parameters) { WriteBuffer.WriteString(kv.Key); WriteBuffer.WriteByte(0); WriteBuffer.WriteString(kv.Value); WriteBuffer.WriteByte(0); } WriteBuffer.WriteByte(0); }
public override void Write(object value, WriteBuffer buf, NpgsqlParameter parameter) { if (parameter?.ConvertedValue != null) { value = parameter.ConvertedValue; } buf.WriteInt16((short)value); }
internal override async Task Write(WriteBuffer buf, bool async, CancellationToken cancellationToken) { 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, cancellationToken); } 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, cancellationToken); if (buf.WriteSpaceLeft < 1 + 2) { await buf.Flush(async, cancellationToken); } 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, cancellationToken); } buf.WriteInt32((int)t); } }
internal async Task WriteBind( List <NpgsqlParameter> parameters, string portal, string statement, bool allResultTypesAreUnknown, bool[]?unknownResultTypeList, bool async, CancellationToken cancellationToken = default) { Debug.Assert(statement.All(c => c < 128)); Debug.Assert(portal.All(c => c < 128)); var headerLength = sizeof(byte) + // Message code sizeof(int) + // Message length sizeof(byte) + // Portal is always empty (only a null terminator) statement.Length + sizeof(byte) + // Statement name plus null terminator sizeof(ushort); // Number of parameter format codes that follow if (WriteBuffer.WriteSpaceLeft < headerLength) { Debug.Assert(WriteBuffer.Size >= headerLength, "Write buffer too small for Bind header"); await Flush(async, cancellationToken); } var formatCodesSum = 0; var paramsLength = 0; for (var paramIndex = 0; paramIndex < parameters.Count; paramIndex++) { var param = parameters[paramIndex]; formatCodesSum += (int)param.FormatCode; param.LengthCache?.Rewind(); paramsLength += param.ValidateAndGetLength(); } var formatCodeListLength = formatCodesSum == 0 ? 0 : formatCodesSum == parameters.Count ? 1 : parameters.Count; var messageLength = headerLength + sizeof(short) * formatCodeListLength + // List of format codes sizeof(short) + // Number of parameters sizeof(int) * parameters.Count + // Parameter lengths paramsLength + // Parameter values sizeof(short) + // Number of result format codes sizeof(short) * (unknownResultTypeList?.Length ?? 1); // Result format codes WriteBuffer.WriteByte(FrontendMessageCode.Bind); WriteBuffer.WriteInt32(messageLength - 1); Debug.Assert(portal == string.Empty); WriteBuffer.WriteByte(0); // Portal is always empty WriteBuffer.WriteNullTerminatedString(statement); WriteBuffer.WriteInt16(formatCodeListLength); // 0 length implicitly means all-text, 1 means all-binary, >1 means mix-and-match if (formatCodeListLength == 1) { if (WriteBuffer.WriteSpaceLeft < 2) { await Flush(async, cancellationToken); } WriteBuffer.WriteInt16((short)FormatCode.Binary); } else if (formatCodeListLength > 1) { for (var paramIndex = 0; paramIndex < parameters.Count; paramIndex++) { if (WriteBuffer.WriteSpaceLeft < 2) { await Flush(async, cancellationToken); } WriteBuffer.WriteInt16((short)parameters[paramIndex].FormatCode); } } if (WriteBuffer.WriteSpaceLeft < 2) { await Flush(async, cancellationToken); } WriteBuffer.WriteUInt16((ushort)parameters.Count); for (var paramIndex = 0; paramIndex < parameters.Count; paramIndex++) { var param = parameters[paramIndex]; param.LengthCache?.Rewind(); await param.WriteWithLength(WriteBuffer, async, cancellationToken); } if (unknownResultTypeList != null) { if (WriteBuffer.WriteSpaceLeft < 2 + unknownResultTypeList.Length * 2) { await Flush(async, cancellationToken); } WriteBuffer.WriteInt16(unknownResultTypeList.Length); foreach (var t in unknownResultTypeList) { WriteBuffer.WriteInt16(t ? 0 : 1); } } else { if (WriteBuffer.WriteSpaceLeft < 4) { await Flush(async, cancellationToken); } WriteBuffer.WriteInt16(1); WriteBuffer.WriteInt16(allResultTypesAreUnknown ? 0 : 1); } }
internal bool Write(WriteBuffer buf, ref DirectBuffer directBuf) { Contract.Requires(Statement != null && Statement.All(c => c < 128)); Contract.Requires(Portal != null && Portal.All(c => c < 128)); switch (_state) { case State.Header: var formatCodesSum = InputParameters.Select(p => p.FormatCode).Sum(c => (int)c); _formatCodeListLength = formatCodesSum == 0 ? 0 : formatCodesSum == InputParameters.Count ? 1 : InputParameters.Count; var headerLength = 1 + // Message code 4 + // Message length Portal.Length + 1 + Statement.Length + 1 + 2; // Number of parameter format codes that follow if (buf.WriteSpaceLeft < headerLength) { Contract.Assume(buf.Size >= headerLength, "Buffer too small for Bind header"); return(false); } foreach (var c in InputParameters.Select(p => p.LengthCache).Where(c => c != null)) { c.Rewind(); } var messageLength = headerLength + 2 * _formatCodeListLength + // List of format codes 2 + // Number of parameters 4 * InputParameters.Count + // Parameter lengths InputParameters.Select(p => p.ValidateAndGetLength()).Sum() + // Parameter values 2 + // Number of result format codes 2 * (UnknownResultTypeList?.Length ?? 1); // Result format codes buf.WriteByte(Code); buf.WriteInt32(messageLength - 1); buf.WriteBytesNullTerminated(Encoding.ASCII.GetBytes(Portal)); buf.WriteBytesNullTerminated(Encoding.ASCII.GetBytes(Statement)); buf.WriteInt16(_formatCodeListLength); _paramIndex = 0; _state = State.ParameterFormatCodes; goto case State.ParameterFormatCodes; case State.ParameterFormatCodes: // 0 length implicitly means all-text, 1 means all-binary, >1 means mix-and-match if (_formatCodeListLength == 1) { if (buf.WriteSpaceLeft < 2) { return(false); } buf.WriteInt16((short)FormatCode.Binary); } else if (_formatCodeListLength > 1) { for (; _paramIndex < InputParameters.Count; _paramIndex++) { if (buf.WriteSpaceLeft < 2) { return(false); } buf.WriteInt16((short)InputParameters[_paramIndex].FormatCode); } } if (buf.WriteSpaceLeft < 2) { return(false); } buf.WriteInt16(InputParameters.Count); _paramIndex = 0; _state = State.ParameterValues; goto case State.ParameterValues; case State.ParameterValues: if (!WriteParameters(buf, ref directBuf)) { return(false); } _state = State.ResultFormatCodes; goto case State.ResultFormatCodes; case State.ResultFormatCodes: if (UnknownResultTypeList != null) { if (buf.WriteSpaceLeft < 2 + UnknownResultTypeList.Length * 2) { return(false); } buf.WriteInt16(UnknownResultTypeList.Length); foreach (var t in UnknownResultTypeList) { buf.WriteInt16(t ? 0 : 1); } } else { if (buf.WriteSpaceLeft < 4) { return(false); } buf.WriteInt16(1); buf.WriteInt16(AllResultTypesAreUnknown ? 0 : 1); } _state = State.Done; return(true); default: throw PGUtil.ThrowIfReached(); } }
internal bool Write(WriteBuffer buf, ref DirectBuffer directBuf) { Contract.Requires(Statement != null && Statement.All(c => c < 128)); Contract.Requires(Portal != null && Portal.All(c => c < 128)); switch (_state) { case State.Header: var formatCodesSum = InputParameters.Select(p => p.FormatCode).Sum(c => (int)c); _formatCodeListLength = formatCodesSum == 0 ? 0 : formatCodesSum == InputParameters.Count ? 1 : InputParameters.Count; var headerLength = 1 + // Message code 4 + // Message length Portal.Length + 1 + Statement.Length + 1 + 2; // Number of parameter format codes that follow if (buf.WriteSpaceLeft < headerLength) { Contract.Assume(buf.Size >= headerLength, "Buffer too small for Bind header"); return false; } foreach (var c in InputParameters.Select(p => p.LengthCache).Where(c => c != null)) c.Rewind(); var messageLength = headerLength + 2 * _formatCodeListLength + // List of format codes 2 + // Number of parameters 4 * InputParameters.Count + // Parameter lengths InputParameters.Select(p => p.ValidateAndGetLength()).Sum() + // Parameter values 2 + // Number of result format codes 2 * (UnknownResultTypeList?.Length ?? 1); // Result format codes buf.WriteByte(Code); buf.WriteInt32(messageLength-1); buf.WriteBytesNullTerminated(Encoding.ASCII.GetBytes(Portal)); buf.WriteBytesNullTerminated(Encoding.ASCII.GetBytes(Statement)); buf.WriteInt16(_formatCodeListLength); _paramIndex = 0; _state = State.ParameterFormatCodes; goto case State.ParameterFormatCodes; case State.ParameterFormatCodes: // 0 length implicitly means all-text, 1 means all-binary, >1 means mix-and-match if (_formatCodeListLength == 1) { if (buf.WriteSpaceLeft < 2) return false; buf.WriteInt16((short)FormatCode.Binary); } else if (_formatCodeListLength > 1) for (; _paramIndex < InputParameters.Count; _paramIndex++) { if (buf.WriteSpaceLeft < 2) return false; buf.WriteInt16((short)InputParameters[_paramIndex].FormatCode); } _state = State.ParameterCount; goto case State.ParameterCount; case State.ParameterCount: if (buf.WriteSpaceLeft < 2) return false; buf.WriteInt16(InputParameters.Count); _paramIndex = 0; _state = State.ParameterValues; goto case State.ParameterValues; case State.ParameterValues: if (!WriteParameters(buf, ref directBuf)) return false; _state = State.ResultFormatCodes; goto case State.ResultFormatCodes; case State.ResultFormatCodes: if (UnknownResultTypeList != null) { if (buf.WriteSpaceLeft < 2 + UnknownResultTypeList.Length * 2) return false; buf.WriteInt16(UnknownResultTypeList.Length); foreach (var t in UnknownResultTypeList) buf.WriteInt16(t ? 0 : 1); } else { if (buf.WriteSpaceLeft < 4) return false; buf.WriteInt16(1); buf.WriteInt16(AllResultTypesAreUnknown ? 0 : 1); } _state = State.Done; return true; default: throw PGUtil.ThrowIfReached(); } }
internal override bool Write(WriteBuffer buf) { Contract.Requires(Statement != null); switch (_state) { case State.WroteNothing: _statementNameBytes = Statement.Length == 0 ? PGUtil.EmptyBuffer : _encoding.GetBytes(Statement); _queryLen = _encoding.GetByteCount(Query); if (buf.WriteSpaceLeft < 1 + 4 + _statementNameBytes.Length + 1) { return(false); } var messageLength = 1 + // Message code 4 + // Length _statementNameBytes.Length + 1 + // Null terminator _queryLen + 1 + // Null terminator 2 + // Number of parameters ParameterTypeOIDs.Count * 4; buf.WriteByte(Code); buf.WriteInt32(messageLength - 1); buf.WriteBytesNullTerminated(_statementNameBytes); goto case State.WroteHeader; case State.WroteHeader: _state = State.WroteHeader; if (_queryLen <= buf.WriteSpaceLeft) { buf.WriteString(Query); goto case State.WroteQuery; } if (_queryLen <= buf.Size) { // String can fit entirely in an empty buffer. Flush and retry rather than // going into the partial writing flow below (which requires ToCharArray()) return(false); } _queryChars = Query.ToCharArray(); _charPos = 0; goto case State.WritingQuery; case State.WritingQuery: _state = State.WritingQuery; int charsUsed; bool completed; buf.WriteStringChunked(_queryChars, _charPos, _queryChars.Length - _charPos, true, out charsUsed, out completed); if (!completed) { _charPos += charsUsed; return(false); } goto case State.WroteQuery; case State.WroteQuery: _state = State.WroteQuery; if (buf.WriteSpaceLeft < 1 + 2) { return(false); } buf.WriteByte(0); // Null terminator for the query buf.WriteInt16((short)ParameterTypeOIDs.Count); goto case State.WritingParameterTypes; case State.WritingParameterTypes: _state = State.WritingParameterTypes; for (; _parameterTypePos < ParameterTypeOIDs.Count; _parameterTypePos++) { if (buf.WriteSpaceLeft < 4) { return(false); } buf.WriteInt32((int)ParameterTypeOIDs[_parameterTypePos]); } _state = State.WroteAll; return(true); default: throw PGUtil.ThrowIfReached(); } }
internal override bool Write(WriteBuffer buf) { Contract.Requires(Statement != null); switch (_state) { case State.WroteNothing: _statementNameBytes = Statement.Length == 0 ? PGUtil.EmptyBuffer : _encoding.GetBytes(Statement); _queryLen = _encoding.GetByteCount(Query); if (buf.WriteSpaceLeft < 1 + 4 + _statementNameBytes.Length + 1) { return false; } var messageLength = 1 + // Message code 4 + // Length _statementNameBytes.Length + 1 + // Null terminator _queryLen + 1 + // Null terminator 2 + // Number of parameters ParameterTypeOIDs.Count * 4; buf.WriteByte(Code); buf.WriteInt32(messageLength - 1); buf.WriteBytesNullTerminated(_statementNameBytes); goto case State.WroteHeader; case State.WroteHeader: _state = State.WroteHeader; if (_queryLen <= buf.WriteSpaceLeft) { buf.WriteString(Query); goto case State.WroteQuery; } if (_queryLen <= buf.Size) { // String can fit entirely in an empty buffer. Flush and retry rather than // going into the partial writing flow below (which requires ToCharArray()) return false; } _queryChars = Query.ToCharArray(); _charPos = 0; goto case State.WritingQuery; case State.WritingQuery: _state = State.WritingQuery; int charsUsed; bool completed; buf.WriteStringChunked(_queryChars, _charPos, _queryChars.Length - _charPos, true, out charsUsed, out completed); if (!completed) { _charPos += charsUsed; return false; } goto case State.WroteQuery; case State.WroteQuery: _state = State.WroteQuery; if (buf.WriteSpaceLeft < 1 + 2) { return false; } buf.WriteByte(0); // Null terminator for the query buf.WriteInt16((short)ParameterTypeOIDs.Count); goto case State.WritingParameterTypes; case State.WritingParameterTypes: _state = State.WritingParameterTypes; for (; _parameterTypePos < ParameterTypeOIDs.Count; _parameterTypePos++) { if (buf.WriteSpaceLeft < 4) { return false; } buf.WriteInt32((int)ParameterTypeOIDs[_parameterTypePos]); } _state = State.WroteAll; return true; default: throw PGUtil.ThrowIfReached(); } }
internal override async Task Write(WriteBuffer buf, bool async, CancellationToken cancellationToken) { 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, cancellationToken); } 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, cancellationToken); } buf.WriteInt16((short)FormatCode.Binary); } else if (formatCodeListLength > 1) { foreach (NpgsqlParameter p in InputParameters) { if (buf.WriteSpaceLeft < 2) { await buf.Flush(async, cancellationToken); } buf.WriteInt16((short)p.FormatCode); } } if (buf.WriteSpaceLeft < 2) { await buf.Flush(async, cancellationToken); } buf.WriteInt16(InputParameters.Count); foreach (var param in InputParameters) { param.LengthCache?.Rewind(); await param.WriteWithLength(buf, async, cancellationToken); } if (UnknownResultTypeList != null) { if (buf.WriteSpaceLeft < 2 + UnknownResultTypeList.Length * 2) { await buf.Flush(async, cancellationToken); } buf.WriteInt16(UnknownResultTypeList.Length); foreach (var t in UnknownResultTypeList) { buf.WriteInt16(t ? 0 : 1); } } else { if (buf.WriteSpaceLeft < 4) { await buf.Flush(async, cancellationToken); } buf.WriteInt16(1); buf.WriteInt16(AllResultTypesAreUnknown ? 0 : 1); } }