Current section

Files

Jump to
ywt_core src ywt_core_ffi.erl
Raw

src/ywt_core_ffi.erl

-module(ywt_core_ffi).
-export([decode_json_to_dynamic/1, is_base64url_unpadded/1, random_id/0]).
random_id() ->
binary:encode_hex(
crypto:strong_rand_bytes(16)).
is_base64url_unpadded(Bin) when is_binary(Bin) ->
byte_size(Bin) rem 4 =/= 1 andalso is_base64url_bytes(Bin).
is_base64url_bytes(<<>>) ->
true;
is_base64url_bytes(<<C, Rest/binary>>)
when C >= $A, C =< $Z;
C >= $a, C =< $z;
C >= $0, C =< $9;
C =:= $-;
C =:= $_ ->
is_base64url_bytes(Rest);
is_base64url_bytes(_) ->
false.
decode_json_to_dynamic(Json) ->
try
Decoders = #{object_finish => fun object_finish_keep_last/2},
case json:decode(Json, ok, Decoders) of
{Decoded, ok, <<>>} ->
{ok, Decoded};
{_, ok, <<ExtraByte, _/bits>>} ->
{error, {unexpected_byte, hex(ExtraByte)}}
end
catch
error:unexpected_end -> {error, unexpected_end_of_input};
error:{invalid_byte, InvalidByte} -> {error, {unexpected_byte, hex(InvalidByte)}};
error:{unexpected_sequence, Bytes} -> {error, {unexpected_sequence, Bytes}}
end.
object_finish_keep_last(Pairs, Acc) ->
{maps:from_list(lists:reverse(Pairs)), Acc}.
hex(I) ->
H = list_to_binary(integer_to_list(I, 16)),
<<"0x"/utf8, H/binary>>.