/deps/rabbit/src/pid_recomposition.erl

https://github.com/rabbitmq/rabbitmq-server · Erlang · 71 lines · 47 code · 10 blank · 14 comment · 0 complexity · c1a8ff26b24fbd2b70d18a86bd55d136 MD5 · raw file

  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-2022 VMware, Inc. or its affiliates. All rights reserved.
  6. %%
  7. -module(pid_recomposition).
  8. %% API
  9. -export([
  10. to_binary/1,
  11. from_binary/1,
  12. decompose/1,
  13. recompose/1
  14. ]).
  15. -define(TTB_PREFIX, 131).
  16. -define(NEW_PID_EXT, 88).
  17. -define(PID_EXT, 103).
  18. -define(ATOM_UTF8_EXT, 118).
  19. -define(SMALL_ATOM_UTF8_EXT, 119).
  20. %%
  21. %% API
  22. %%
  23. -spec decompose(pid()) -> #{atom() => any()}.
  24. decompose(Pid) ->
  25. from_binary(term_to_binary(Pid, [{minor_version, 2}])).
  26. -spec from_binary(binary()) -> #{atom() => any()}.
  27. from_binary(Bin) ->
  28. PidData = case Bin of
  29. %% Erlang 23+
  30. <<?TTB_PREFIX, ?NEW_PID_EXT, Val0/binary>> -> Val0;
  31. %% Erlang 22
  32. <<?TTB_PREFIX, ?PID_EXT, Val1/binary>> -> Val1
  33. end,
  34. {Node, Rest2} = case PidData of
  35. <<?ATOM_UTF8_EXT, AtomLen:16/integer, Node0:AtomLen/binary, Rest1/binary>> ->
  36. {Node0, Rest1};
  37. <<?SMALL_ATOM_UTF8_EXT, AtomLen/integer, Node0:AtomLen/binary, Rest1/binary>> ->
  38. {Node0, Rest1}
  39. end,
  40. {ID, Serial, Creation} = case Rest2 of
  41. %% NEW_PID_EXT on Erlang 23+
  42. <<ID0:32/integer, Serial0:32/integer, Creation0:32/integer>> ->
  43. {ID0, Serial0, Creation0};
  44. %% PID_EXT on Erlang 22
  45. <<ID1:32/integer, Serial1:32/integer, Creation1:8/integer>> ->
  46. {ID1, Serial1, Creation1}
  47. end,
  48. #{
  49. node => binary_to_atom(Node, utf8),
  50. id => ID,
  51. serial => Serial,
  52. creation => Creation
  53. }.
  54. -spec to_binary(#{atom() => any()}) -> binary().
  55. to_binary(#{node := Node, id := ID, serial := Serial, creation := Creation}) ->
  56. BinNode = atom_to_binary(Node, utf8),
  57. NodeLen = byte_size(BinNode),
  58. <<?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>>.
  59. -spec recompose(#{atom() => any()}) -> pid().
  60. recompose(M) ->
  61. binary_to_term(to_binary(M)).