/// <inheritdoc /> protected internal override int ValidateAndGetLength <TAny>(TAny value, ref NpgsqlLengthCache?lengthCache, NpgsqlParameter?parameter) { if (typeof(TAny) == typeof(string) || typeof(TAny) == typeof(char[]) || typeof(TAny) == typeof(ArraySegment <char>) || typeof(TAny) == typeof(char) || typeof(TAny) == typeof(byte[])) { return(_textHandler.ValidateAndGetLength(value, ref lengthCache, parameter) + _headerLen); } if (typeof(TAny) == typeof(JsonDocument)) { if (lengthCache == null) { lengthCache = new NpgsqlLengthCache(1); } if (lengthCache.IsPopulated) { return(lengthCache.Get()); } var data = SerializeJsonDocument((JsonDocument)(object)value !); if (parameter != null) { parameter.ConvertedValue = data; } return(lengthCache.Set(data.Length + _headerLen)); } // User POCO, need to serialize. At least internally ArrayPool buffers are used... var s = JsonSerializer.Serialize(value, _serializerOptions); if (parameter != null) { parameter.ConvertedValue = s; } return(_textHandler.ValidateAndGetLength(s, ref lengthCache, parameter) + _headerLen); }
public int ValidateAndGetLength(Polygon value, ref NpgsqlLengthCache lengthCache, NpgsqlParameter parameter) { var lines = value.Coordinates; var length = SizeOfHeaderWithLength + SizeOfLength * lines.Count; if (GetSrid(value.CRS) != 0) { length += sizeof(int); } var hasZ = false; for (var i = 0; i < lines.Count; ++i) { var coordinates = lines[i].Coordinates; if (NotValid(coordinates, out var lineHasZ)) { throw AllOrNoneCoordiantesMustHaveZ(parameter, nameof(Polygon)); } if (hasZ != lineHasZ) { if (i == 0) { hasZ = lineHasZ; } else { throw AllOrNoneCoordiantesMustHaveZ(parameter, nameof(LineString)); } } length += coordinates.Count * SizeOfPoint(hasZ); } return(length); }
public override Task Write(T value, NpgsqlWriteBuffer buf, NpgsqlLengthCache lengthCache, NpgsqlParameter parameter, bool async) => _wrappedHandler.Write(value, buf, lengthCache, parameter, async);
/// <inheritdoc /> public override int ValidateAndGetLength(byte[] value, ref NpgsqlLengthCache lengthCache, NpgsqlParameter parameter) => parameter == null || parameter.Size <= 0 || parameter.Size >= value.Length ? value.Length : parameter.Size;
public int ValidateAndGetLength(bool value, ref NpgsqlLengthCache lengthCache, NpgsqlParameter parameter) => 5;
public override int ValidateAndGetLength(BitArray value, ref NpgsqlLengthCache lengthCache, NpgsqlParameter parameter) => 4 + (value.Length + 7) / 8;
public Task Write(PostgisGeometryCollection value, NpgsqlWriteBuffer buf, NpgsqlLengthCache lengthCache, NpgsqlParameter parameter, bool async) => Write((PostgisGeometry)value, buf, lengthCache, parameter, async);
public override async Task Write(PostgisGeometry value, NpgsqlWriteBuffer buf, NpgsqlLengthCache lengthCache, NpgsqlParameter parameter, bool async) { // Common header if (value.SRID == 0) { if (buf.WriteSpaceLeft < 5) { await buf.Flush(async); } buf.WriteByte(0); // We choose to ouput only XDR structure buf.WriteInt32((int)value.Identifier); } else { if (buf.WriteSpaceLeft < 9) { await buf.Flush(async); } buf.WriteByte(0); buf.WriteInt32((int)((uint)value.Identifier | (uint)EwkbModifiers.HasSRID)); buf.WriteInt32((int)value.SRID); } switch (value.Identifier) { case WkbIdentifier.Point: if (buf.WriteSpaceLeft < 16) { await buf.Flush(async); } var p = (PostgisPoint)value; buf.WriteDouble(p.X); buf.WriteDouble(p.Y); return; case WkbIdentifier.LineString: var l = (PostgisLineString)value; if (buf.WriteSpaceLeft < 4) { await buf.Flush(async); } buf.WriteInt32(l.PointCount); for (var ipts = 0; ipts < l.PointCount; ipts++) { if (buf.WriteSpaceLeft < 16) { await buf.Flush(async); } buf.WriteDouble(l[ipts].X); buf.WriteDouble(l[ipts].Y); } return; case WkbIdentifier.Polygon: var pol = (PostgisPolygon)value; if (buf.WriteSpaceLeft < 4) { await buf.Flush(async); } buf.WriteInt32(pol.RingCount); for (var irng = 0; irng < pol.RingCount; irng++) { if (buf.WriteSpaceLeft < 4) { await buf.Flush(async); } buf.WriteInt32(pol[irng].Length); for (var ipts = 0; ipts < pol[irng].Length; ipts++) { if (buf.WriteSpaceLeft < 16) { await buf.Flush(async); } buf.WriteDouble(pol[irng][ipts].X); buf.WriteDouble(pol[irng][ipts].Y); } } return; case WkbIdentifier.MultiPoint: var mp = (PostgisMultiPoint)value; if (buf.WriteSpaceLeft < 4) { await buf.Flush(async); } buf.WriteInt32(mp.PointCount); for (var ipts = 0; ipts < mp.PointCount; ipts++) { if (buf.WriteSpaceLeft < 21) { await buf.Flush(async); } buf.WriteByte(0); buf.WriteInt32((int)WkbIdentifier.Point); buf.WriteDouble(mp[ipts].X); buf.WriteDouble(mp[ipts].Y); } return; case WkbIdentifier.MultiLineString: var ml = (PostgisMultiLineString)value; if (buf.WriteSpaceLeft < 4) { await buf.Flush(async); } buf.WriteInt32(ml.LineCount); for (var irng = 0; irng < ml.LineCount; irng++) { if (buf.WriteSpaceLeft < 9) { await buf.Flush(async); } buf.WriteByte(0); buf.WriteInt32((int)WkbIdentifier.LineString); buf.WriteInt32(ml[irng].PointCount); for (var ipts = 0; ipts < ml[irng].PointCount; ipts++) { if (buf.WriteSpaceLeft < 16) { await buf.Flush(async); } buf.WriteDouble(ml[irng][ipts].X); buf.WriteDouble(ml[irng][ipts].Y); } } return; case WkbIdentifier.MultiPolygon: var mpl = (PostgisMultiPolygon)value; if (buf.WriteSpaceLeft < 4) { await buf.Flush(async); } buf.WriteInt32(mpl.PolygonCount); for (var ipol = 0; ipol < mpl.PolygonCount; ipol++) { if (buf.WriteSpaceLeft < 9) { await buf.Flush(async); } buf.WriteByte(0); buf.WriteInt32((int)WkbIdentifier.Polygon); buf.WriteInt32(mpl[ipol].RingCount); for (var irng = 0; irng < mpl[ipol].RingCount; irng++) { if (buf.WriteSpaceLeft < 4) { await buf.Flush(async); } buf.WriteInt32(mpl[ipol][irng].Length); for (var ipts = 0; ipts < mpl[ipol][irng].Length; ipts++) { if (buf.WriteSpaceLeft < 16) { await buf.Flush(async); } buf.WriteDouble(mpl[ipol][irng][ipts].X); buf.WriteDouble(mpl[ipol][irng][ipts].Y); } } } return; case WkbIdentifier.GeometryCollection: var coll = (PostgisGeometryCollection)value; if (buf.WriteSpaceLeft < 4) { await buf.Flush(async); } buf.WriteInt32(coll.GeometryCount); foreach (var x in coll) { await Write(x, buf, lengthCache, null, async); } return; default: throw new InvalidOperationException("Unknown Postgis identifier."); } }
/// <summary> /// Responsible for validating that a value represents a value of the correct and which can be /// written for PostgreSQL - if the value cannot be written for any reason, an exception shold be thrown. /// Also returns the byte length needed to write the value. /// </summary> /// <param name="value">The value to be written to PostgreSQL</param> /// <param name="lengthCache"> /// If the byte length calculation is costly (e.g. for UTF-8 strings), its result can be stored in the /// length cache to be reused in the writing process, preventing recalculation. /// </param> /// <param name="parameter"> /// The <see cref="NpgsqlParameter"/> instance where this value resides. Can be used to access additional /// information relevant to the write process (e.g. <see cref="NpgsqlParameter.Size"/>). /// </param> /// <returns>The number of bytes required to write the value.</returns> protected internal abstract int ValidateObjectAndGetLength([CanBeNull] object value, ref NpgsqlLengthCache lengthCache, NpgsqlParameter parameter);
/// <summary> /// Called to write the value of a generic <see cref="NpgsqlParameter{T}"/>. /// </summary> internal abstract Task WriteWithLengthInternal <TAny>([CanBeNull] TAny value, NpgsqlWriteBuffer buf, NpgsqlLengthCache lengthCache, NpgsqlParameter parameter, bool async);
/// <summary> /// Called to validate and get the length of a value of a generic <see cref="NpgsqlParameter{T}"/>. /// </summary> protected internal abstract int ValidateAndGetLength <TAny>([CanBeNull] TAny value, ref NpgsqlLengthCache lengthCache, NpgsqlParameter parameter);
protected override Task WriteWithLength <T2>(T2 value, NpgsqlWriteBuffer buf, NpgsqlLengthCache lengthCache, NpgsqlParameter parameter, bool async) { buf.WriteInt32(ValidateAndGetLength(value, ref lengthCache, parameter)); return(Write(value, buf, lengthCache, parameter, async)); }
protected internal override Task WriteObjectWithLength(object value, NpgsqlWriteBuffer buf, NpgsqlLengthCache lengthCache, NpgsqlParameter parameter, bool async) => value == null || value is DBNull ? WriteWithLengthInternal <DBNull>(null, buf, lengthCache, parameter, async) : WriteWithLengthInternal(value, buf, lengthCache, parameter, async);
protected internal override int ValidateAndGetLength <TAny>(TAny value, ref NpgsqlLengthCache lengthCache, NpgsqlParameter parameter) => ValidateAndGetLength(value, ref lengthCache, parameter);
protected internal override int ValidateObjectAndGetLength(object value, ref NpgsqlLengthCache lengthCache, NpgsqlParameter parameter) => value == null || value is DBNull ? -1 : ValidateAndGetLength(value, ref lengthCache, parameter);
public int ValidateAndGetLength(PostgisGeometryCollection value, ref NpgsqlLengthCache lengthCache, NpgsqlParameter parameter) => value.GetLen(true);
public int ValidateAndGetLength(byte[] value, ref NpgsqlLengthCache lengthCache, NpgsqlParameter parameter) => value.Length;
/// <summary> /// Writes a value to the provided buffer, using either sync or async I/O. /// </summary> /// <param name="value">The value to write.</param> /// <param name="buf">The buffer to which to write.</param> /// <param name="lengthCache"></param> /// <param name="parameter"> /// The <see cref="NpgsqlParameter"/> instance where this value resides. Can be used to access additional /// information relevant to the write process (e.g. <see cref="NpgsqlParameter.Size"/>). /// </param> /// <param name="async">If I/O is required to read the full length of the value, whether it should be performed synchronously or asynchronously.</param> protected internal abstract Task WriteObjectWithLength([CanBeNull] object value, NpgsqlWriteBuffer buf, NpgsqlLengthCache lengthCache, NpgsqlParameter parameter, bool async);
public Task Write(PostgisMultiLineString value, NpgsqlWriteBuffer buf, NpgsqlLengthCache lengthCache, NpgsqlParameter parameter, bool async) => Write((PostgisGeometry)value, buf, lengthCache, parameter, async);
protected internal override Task WriteObjectWithLength(object value, NpgsqlWriteBuffer buf, NpgsqlLengthCache lengthCache, NpgsqlParameter parameter, bool async) { if (value == null || value is DBNull) { return(base.WriteObjectWithLength(value, buf, lengthCache, parameter, async)); } buf.WriteInt32(ValidateObjectAndGetLength(value, ref lengthCache, parameter)); return(base.Write( value is string asString ? asString : (string)parameter.ConvertedValue, buf, lengthCache, parameter, async)); }
public Task Write(byte[] value, NpgsqlWriteBuffer buf, NpgsqlLengthCache lengthCache, NpgsqlParameter parameter, bool async) => _byteaHandler == null ? throw new NpgsqlException("Bytea handler was not found during initialization of PostGIS handler") : _byteaHandler.Write(value, buf, lengthCache, parameter, async);
// Allow writing anything that is a string or can be converted to one via the unknown type handler public override int ValidateAndGetLength <T2>(T2 value, ref NpgsqlLengthCache lengthCache, NpgsqlParameter parameter) => ValidateObjectAndGetLength(value, ref lengthCache, parameter);
public int ValidateAndGetLength(BitVector32 value, ref NpgsqlLengthCache lengthCache, NpgsqlParameter parameter) => value.Data == 0 ? 4 : 8;
public override async Task Write(NpgsqlRange <TElement> value, NpgsqlWriteBuffer buf, NpgsqlLengthCache lengthCache, NpgsqlParameter parameter, bool async) { if (buf.WriteSpaceLeft < 1) { await buf.Flush(async); } buf.WriteByte((byte)value.Flags); if (value.IsEmpty) { return; } if (!value.LowerBoundInfinite) { await ElementHandler.WriteWithLengthInternal(value.LowerBound, buf, lengthCache, null, async); } if (!value.UpperBoundInfinite) { await ElementHandler.WriteWithLengthInternal(value.UpperBound, buf, lengthCache, null, async); } }
public override async Task Write(ArraySegment <char> value, NpgsqlWriteBuffer buf, NpgsqlLengthCache lengthCache, NpgsqlParameter parameter, bool async) { if (buf.WriteSpaceLeft < 1) { await buf.Flush(async); } buf.WriteByte(JsonbProtocolVersion); await base.Write(value, buf, lengthCache, parameter, async); }
public override int ValidateAndGetLength(PostgisGeometry value, ref NpgsqlLengthCache lengthCache, NpgsqlParameter parameter) => value.GetLen(true);
protected override Task WriteObjectWithLength(object value, NpgsqlWriteBuffer buf, NpgsqlLengthCache lengthCache, NpgsqlParameter parameter, bool async) { if (parameter?.ConvertedValue != null) { value = parameter.ConvertedValue; } var s = value as string ?? JsonConvert.SerializeObject(value); return(base.WriteObjectWithLength(s, buf, lengthCache, parameter, async)); }
public int ValidateAndGetLength(PostgisPolygon value, ref NpgsqlLengthCache lengthCache, NpgsqlParameter parameter) => value.GetLen(true);
/// <inheritdoc /> public int ValidateAndGetLength(ArraySegment <byte> value, ref NpgsqlLengthCache lengthCache, NpgsqlParameter parameter) => parameter == null || parameter.Size <= 0 || parameter.Size >= value.Count ? value.Count : parameter.Size;
public int ValidateAndGetLength(PostgisMultiLineString value, ref NpgsqlLengthCache lengthCache, NpgsqlParameter parameter) => value.GetLen(true);