Skip to content

Commit

Permalink
Merge pull request #6 from work-capital/master
Browse files Browse the repository at this point in the history
A new missing NaN type in mongo
  • Loading branch information
emerleite authored Mar 13, 2018
2 parents e56836d + b4b8606 commit 2628f17
Show file tree
Hide file tree
Showing 4 changed files with 83 additions and 2 deletions.
31 changes: 30 additions & 1 deletion lib/bson/decoder.ex
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,32 @@ defmodule BSON.Decoder do
map
end

defp type(@type_float, <<float::float64, rest::binary>>) do
def documents(binary),
do: documents(binary, [])
def documents("", acc),
do: Enum.reverse(acc)
def documents(binary, acc) do
{doc, rest} = document(binary)
documents(rest, [doc|acc])
end

defp type(@type_float, <<0, 0, 0, 0, 0, 0, 240::little-integer-size(8), 127::little-integer-size(8), rest::binary>>) do
{:inf, rest}
end

defp type(@type_float, <<0, 0, 0, 0, 0, 0, 240::little-integer-size(8), 255::little-integer-size(8), rest::binary>>) do
{:"-inf", rest}
end

defp type(@type_float, <<0, 0, 0, 0, 0, 0, 248::little-integer-size(8), 127::little-integer-size(8), rest::binary>>) do
{:NaN, rest}
end

defp type(@type_float, <<1, 0, 0, 0, 0, 0, 240::little-integer-size(8), 127::little-integer-size(8), rest::binary>>) do
{:NaN, rest}
end

defp type(@type_float, <<float::little-float64, rest::binary>>) do
{float, rest}
end

Expand All @@ -30,6 +55,10 @@ defmodule BSON.Decoder do
{%BSON.Binary{binary: binary, subtype: subtype}, rest}
end

defp type(@type_undefined, rest) do
{nil, rest}
end

defp type(@type_objectid, <<binary::binary(12), rest::binary>>) do
{%BSON.ObjectId{value: binary}, rest}
end
Expand Down
14 changes: 13 additions & 1 deletion lib/bson/encoder.ex
Original file line number Diff line number Diff line change
Expand Up @@ -59,14 +59,23 @@ defmodule BSON.Encoder do
def encode(value) when is_map(value),
do: document(value)

def encode(:inf),
do: <<0, 0, 0, 0, 0, 0, 240::little-integer-size(8), 127::little-integer-size(8)>>

def encode(:"-inf"),
do: <<0, 0, 0, 0, 0, 0, 240::little-integer-size(8), 255::little-integer-size(8)>>

def encode(:NaN),
do: <<0, 0, 0, 0, 0, 0, 248::little-integer-size(8), 127::little-integer-size(8)>>

def encode(value) when is_atom(value),
do: encode(Atom.to_string(value))

def encode(value) when is_binary(value),
do: [<<byte_size(value)+1::int32>>, value, 0x00]

def encode(value) when is_float(value),
do: <<value::float64>>
do: <<value::little-float64>>

def encode(value) when is_int32(value),
do: <<value::int32>>
Expand Down Expand Up @@ -126,6 +135,9 @@ defmodule BSON.Encoder do
defp type(nil), do: @type_null
defp type(:BSON_min), do: @type_min
defp type(:BSON_max), do: @type_max
defp type(:inf), do: @type_float
defp type(:"-inf"), do: @type_float
defp type(:NaN), do: @type_float
defp type(value) when is_boolean(value), do: @type_bool
defp type(value) when is_float(value), do: @type_float
defp type(value) when is_atom(value), do: @type_string
Expand Down
1 change: 1 addition & 0 deletions lib/bson/utils.ex
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ defmodule BSON.Utils do
@type_document 0x03
@type_array 0x04
@type_binary 0x05
@type_undefined 0x06
@type_objectid 0x07
@type_bool 0x08
@type_datetime 0x09
Expand Down
39 changes: 39 additions & 0 deletions test/bson/types_test.exs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
defmodule BSON.TypesTest do
use ExUnit.Case, async: true

import BSON, only: [decode: 1]

test "inspect BSON.Binary" do
value = %BSON.Binary{binary: <<1, 2, 3>>}
assert inspect(value) == "#BSON.Binary<010203>"
Expand Down Expand Up @@ -39,4 +41,41 @@ defmodule BSON.TypesTest do
value = %BSON.Timestamp{value: 1412180887}
assert inspect(value) == "#BSON.Timestamp<1412180887>"
end

@mapPosInf %{"a" => :inf}
@binPosInf <<16, 0, 0, 0, 1, 97, 0, 0, 0, 0, 0, 0, 0, 240::little-integer-size(8), 127::little-integer-size(8), 0>>

@mapNegInf %{"a" => :"-inf"}
@binNegInf <<16, 0, 0, 0, 1, 97, 0, 0, 0, 0, 0, 0, 0, 240::little-integer-size(8), 255::little-integer-size(8), 0>>

@mapNaN %{"a" => :NaN}
@binNaN <<16, 0, 0, 0, 1, 97, 0, 0, 0, 0, 0, 0, 0, 248::little-integer-size(8), 127::little-integer-size(8), 0>>

test "decode float NaN" do
assert decode(@binNaN) == @mapNaN
end

test "encode float NaN" do
assert encode(@mapNaN) == @binNaN
end

test "decode float positive Infinity" do
assert decode(@binPosInf) == @mapPosInf
end

test "encode float positive Infinity" do
assert encode(@mapPosInf) == @binPosInf
end

test "decode float negative Infinity" do
assert decode(@binNegInf) == @mapNegInf
end

test "encode float negative Infinity" do
assert encode(@mapNegInf) == @binNegInf
end

defp encode(value) do
value |> BSON.encode |> IO.iodata_to_binary
end
end

0 comments on commit 2628f17

Please sign in to comment.