/// <param name="buf">the buffer into which to write the message.</param> /// <param name="directBuf"> /// an option buffer that, if returned, will be written to the server directly, bypassing our /// NpgsqlBuffer. This is an optimization hack for bytea. /// </param> /// <returns> /// Whether there was enough space in the buffer to contain the entire message. /// If false, the buffer should be flushed and write should be called again. /// </returns> internal abstract bool Write(NpgsqlBuffer buf, ref DirectBuffer directBuf);
void DoWrite <T>(TypeHandler handler, T value) { if (_buf.WriteSpaceLeft < 4) { Flush(); } EnsureDataMessage(); var asObject = (object)value; // TODO: Implement boxless writing in the future if (asObject == null) { _buf.WriteInt32(-1); _column++; return; } var asSimple = handler as ISimpleTypeWriter; if (asSimple != null) { var len = asSimple.ValidateAndGetLength(asObject); _buf.WriteInt32(len); if (_buf.WriteSpaceLeft < len) { Contract.Assume(_buf.Size >= len); FlushAndStartDataMessage(); } asSimple.Write(asObject, _buf); _column++; return; } var asChunking = handler as IChunkingTypeWriter; if (asChunking != null) { _lengthCache.Clear(); var len = asChunking.ValidateAndGetLength(asObject, ref _lengthCache); _buf.WriteInt32(len); _lengthCache.Rewind(); _lengthCache.Get(); // Hack asChunking.PrepareWrite(asObject, _buf, _lengthCache); var directBuf = new DirectBuffer(); while (!asChunking.Write(ref directBuf)) { FlushAndStartDataMessage(); // The following is an optimization hack for writing large byte arrays without passing // through our buffer if (directBuf.Buffer != null) { len = directBuf.Size == 0 ? directBuf.Buffer.Length : directBuf.Size; _buf.WriteInt32(len); Flush(); _buf.Underlying.Write(directBuf.Buffer, directBuf.Offset, len); directBuf.Buffer = null; directBuf.Size = 0; } } _column++; return; } throw PGUtil.ThrowIfReached(); }
public override bool Write(ref DirectBuffer directBuf) { Contract.Ensures(Contract.Result <bool>() == false || directBuf.Buffer == null); return(default(bool)); }
void DoWrite <T>(TypeHandler handler, T value) { try { if (_buf.WriteSpaceLeft < 4) { FlushAndStartDataMessage(); } var asObject = (object)value; // TODO: Implement boxless writing in the future if (asObject == null) { _buf.WriteInt32(-1); _column++; return; } _dummyParam.ConvertedValue = null; var asSimple = handler as ISimpleTypeWriter; if (asSimple != null) { var len = asSimple.ValidateAndGetLength(asObject, _dummyParam); _buf.WriteInt32(len); if (_buf.WriteSpaceLeft < len) { Contract.Assume(_buf.Size >= len); FlushAndStartDataMessage(); } asSimple.Write(asObject, _buf, _dummyParam); _column++; return; } var asChunking = handler as IChunkingTypeWriter; if (asChunking != null) { _lengthCache.Clear(); var len = asChunking.ValidateAndGetLength(asObject, ref _lengthCache, _dummyParam); _buf.WriteInt32(len); // If the type handler used the length cache, rewind it to skip the first position: // it contains the entire value length which we already have in len. if (_lengthCache.Position > 0) { _lengthCache.Rewind(); _lengthCache.Position++; } asChunking.PrepareWrite(asObject, _buf, _lengthCache, _dummyParam); var directBuf = new DirectBuffer(); while (!asChunking.Write(ref directBuf)) { Flush(); // The following is an optimization hack for writing large byte arrays without passing // through our buffer if (directBuf.Buffer != null) { len = directBuf.Size == 0 ? directBuf.Buffer.Length : directBuf.Size; _buf.WritePosition = 1; _buf.WriteInt32(len + 4); _buf.Flush(); _writingDataMsg = false; _buf.Underlying.Write(directBuf.Buffer, directBuf.Offset, len); directBuf.Buffer = null; directBuf.Size = 0; } EnsureDataMessage(); } _column++; return; } throw PGUtil.ThrowIfReached(); } catch { _connector.Break(); Cleanup(); throw; } }
public abstract bool Write(ref DirectBuffer directBuf);