1%% This Source Code Form is subject to the terms of the Mozilla Public 2%% License, v. 2.0. If a copy of the MPL was not distributed with this 3%% file, You can obtain one at https://mozilla.org/MPL/2.0/. 4%% 5%% Copyright (c) 2007-2021 VMware, Inc. or its affiliates. All rights reserved. 6%% 7 8-module(pid_recomposition). 9 10 11%% API 12-export([ 13 to_binary/1, 14 from_binary/1, 15 decompose/1, 16 recompose/1 17]). 18 19-define(TTB_PREFIX, 131). 20 21-define(NEW_PID_EXT, 88). 22-define(PID_EXT, 103). 23-define(ATOM_UTF8_EXT, 118). 24-define(SMALL_ATOM_UTF8_EXT, 119). 25 26%% 27%% API 28%% 29 30-spec decompose(pid()) -> #{atom() => any()}. 31decompose(Pid) -> 32 from_binary(term_to_binary(Pid, [{minor_version, 2}])). 33 34-spec from_binary(binary()) -> #{atom() => any()}. 35from_binary(Bin) -> 36 PidData = case Bin of 37 %% Erlang 23+ 38 <<?TTB_PREFIX, ?NEW_PID_EXT, Val0/binary>> -> Val0; 39 %% Erlang 22 40 <<?TTB_PREFIX, ?PID_EXT, Val1/binary>> -> Val1 41 end, 42 {Node, Rest2} = case PidData of 43 <<?ATOM_UTF8_EXT, AtomLen:16/integer, Node0:AtomLen/binary, Rest1/binary>> -> 44 {Node0, Rest1}; 45 <<?SMALL_ATOM_UTF8_EXT, AtomLen/integer, Node0:AtomLen/binary, Rest1/binary>> -> 46 {Node0, Rest1} 47 end, 48 {ID, Serial, Creation} = case Rest2 of 49 %% NEW_PID_EXT on Erlang 23+ 50 <<ID0:32/integer, Serial0:32/integer, Creation0:32/integer>> -> 51 {ID0, Serial0, Creation0}; 52 %% PID_EXT on Erlang 22 53 <<ID1:32/integer, Serial1:32/integer, Creation1:8/integer>> -> 54 {ID1, Serial1, Creation1} 55 end, 56 #{ 57 node => binary_to_atom(Node, utf8), 58 id => ID, 59 serial => Serial, 60 creation => Creation 61 }. 62 63-spec to_binary(#{atom() => any()}) -> binary(). 64to_binary(#{node := Node, id := ID, serial := Serial, creation := Creation}) -> 65 BinNode = atom_to_binary(Node, utf8), 66 NodeLen = byte_size(BinNode), 67 <<?TTB_PREFIX:8/unsigned, ?NEW_PID_EXT:8/unsigned, ?ATOM_UTF8_EXT:8/unsigned, NodeLen:16/unsigned, BinNode/binary, ID:32, Serial:32, Creation:32>>. 68 69-spec recompose(#{atom() => any()}) -> pid(). 70recompose(M) -> 71 binary_to_term(to_binary(M)). 72