123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102 |
- -module(porttest).
- -behavior(gen_server).
- -export([
- hello/0,
- factorial/1
- ]).
- -export([
- start_link/0,
- stop/0
- ]).
- -export([
- init/1,
- handle_call/3,
- handle_cast/2,
- terminate/2
- ]).
- -record(state, {port}).
- start_link() ->
- gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).
- stop() ->
- gen_server:call(?MODULE, stop).
- hello() ->
- gen_server:call(?MODULE, hello).
- factorial(N) when is_integer(N), N >= 0 ->
- case gen_server:call(?MODULE, {factorial, N}) of
- {ok, Result} when is_integer(Result) -> Result;
- {error, _} = Error -> Error
- end;
- factorial(_) ->
- {error, badarg}.
- %% helper
- parse_result("error:" ++ Rest) ->
- {error, list_to_binary(Rest)};
- parse_result(Str) ->
- case string:to_integer(Str) of
- {Int, []} -> {ok, Int};
- _ -> {error, badarg}
- end.
- init([]) ->
- Path = "./porttest", %% compiled zig program
- Port = open_port({spawn, Path}, [binary, exit_status]),
- {ok, #state{port = Port}}.
- handle_call(hello, _From, State) ->
- Port = State#state.port,
- Cmd = <<"hello">>,
- port_command(Port, <<(byte_size(Cmd)):16, Cmd/binary>>),
- receive
- {Port, {data, <<_Len:16, Resp/binary>>}} ->
- {reply, binary_to_list(Resp), State}
- after 5000 ->
- {reply, {error, timeout}, State}
- end;
- handle_call({factorial, N}, _From, State) ->
- Port = State#state.port,
- BinCmd = <<"factorial ", (integer_to_binary(N))/binary>>,
- port_command(Port, <<(byte_size(BinCmd)):16, BinCmd/binary>>),
- receive
- {Port, {data, <<_Len:16, Resp/binary>>}} ->
- Reply = parse_result( binary_to_list(Resp) ),
- {reply, Reply, State}
- after 5000 ->
- {reply, {error, timeout}, State}
- end;
- handle_call(stop, _From, State) ->
- Port = State#state.port,
- port_close(Port),
- {stop, normal, ok, State}.
- handle_cast(_Msg, State) ->
- {noreply, State}.
- terminate(_Reason, _State) ->
- ok.
|