polygon.ex (1401B)
1 defmodule Postgrex.Extensions.Polygon do 2 @moduledoc false 3 import Postgrex.BinaryUtils, warn: false 4 use Postgrex.BinaryExtension, send: "poly_send" 5 alias Postgrex.Extensions.Polygon 6 alias Postgrex.Extensions.Point 7 8 def encode(_) do 9 quote location: :keep, generated: true do 10 %Postgrex.Polygon{vertices: vertices} when is_list(vertices) -> 11 len = length(vertices) 12 13 vert = 14 Enum.reduce(vertices, [], fn v, acc -> 15 [acc | Point.encode_point(v, Postgrex.Polygon)] 16 end) 17 18 # 32 bits for len, 64 for each x and each y 19 nbytes = 4 + 16 * len 20 21 [<<nbytes::int32()>>, <<len::int32()>> | vert] 22 23 other -> 24 raise DBConnection.EncodeError, Postgrex.Utils.encode_msg(other, Postgrex.Polygon) 25 end 26 end 27 28 def decode(_) do 29 quote location: :keep do 30 <<nbytes::int32(), polygon_data::binary-size(nbytes)>> -> 31 vertices = Polygon.decode_vertices(polygon_data) 32 %Postgrex.Polygon{vertices: vertices} 33 end 34 end 35 36 # n vertices, 128 bits for each vertex - 64 for x, 64 for y 37 def decode_vertices(<<n::int32(), vert_data::binary-size(n)-unit(128)>>) do 38 decode_vertices(vert_data, []) 39 end 40 41 defp decode_vertices(<<>>, v), do: Enum.reverse(v) 42 43 defp decode_vertices(<<x::float64(), y::float64(), rest::bits>>, v) do 44 decode_vertices(rest, [%Postgrex.Point{x: x, y: y} | v]) 45 end 46 end