blob: 850c3b92082c06d7704ee49a02069f7a30431bcf [file] [log] [blame]
-module(tSocket).
-include("thrift/thrift.hrl").
-include("thrift/transport/tTransportException.hrl").
% -include("thrift/transport/tTransport.hrl").
-include("thrift/transport/tSocket.hrl").
-export([new/0, new/1, new/2, setHandle_MUTABLE/2, open_MUTABLE/1, isOpen/1, write/2, read/2, close_MUTABLE/1, readAll/2]).
new(Host, Port) ->
#tSocket{host=Host, port=Port, handle=nil}. % WATCH
new() -> new("localhost", 9090).
new(Host) -> new(Host, 9090).
setHandle_MUTABLE(This, Handle) ->
This#tSocket{handle=Handle}.
open_MUTABLE(This) ->
Host = This#tSocket.host,
Port = This#tSocket.port,
Options = [],
case gen_tcp:connect(Host, Port, Options) of
{error, _} ->
throw(tTransportException:new(
?tTransportException_NOT_OPEN,
"Could not connect to " ++ Host ++ ":" ++ Port)
),
{error, This}; % cpiro not reached?
{ok, Socket} ->
{ok, This#tSocket{handle=Socket}}
end.
handle(This) ->
This#tSocket.handle.
isOpen(This) ->
handle(This) /= nil.
write(This, Str) ->
Val = gen_tcp:send(handle(This), Str),
%% io:format("WRITE |~p|(~p)~n", [Str,Val]),
case Val of
{error, _} ->
throw(tTransportException:new(?tTransportException_NOT_OPEN, "in write"));
ok ->
ok
end.
read(This, Sz) ->
case gen_tcp:recv(handle(This), Sz) of
{ok, []} ->
{ Host, Port } = { This#tSocket.host, This#tSocket.port },
throw(tTransportException:new(?tTransportException_UNKNOWN, "TSocket: Could not read " ++ Sz ++ "bytes from " ++ Host ++ ":" ++ Port));
{ok, Data} ->
Data;
{error, Error} ->
io:format("in tSocket:read/2: gen_tcp:recv(~p, ~p) => {error, ~p}~n",
[handle(This), Sz, Error]),
throw(tTransportException:new(?tTransportException_NOT_OPEN, "in tSocket:read/2: gen_tcp:recv"))
end.
close_MUTABLE(This) ->
if
This#tSocket.handle == nil ->
This;
true ->
gen_tcp:close(handle(This)),
This#tSocket{handle=nil}
end.
readAll(This, Sz) ->
readAll_loop(This, Sz, "", 0).
readAll_loop(This, Sz, Buff, Have) ->
if
Have < Sz ->
Chunk = ?M1(This, read, Sz - Have),
%% man gen_tcp:
%% exactly Length bytes are returned, or an error;
%% possibly discarding less than Length bytes of data when
%% the socket gets closed from the other side.
%% io:format("READ |~p|~n", [Chunk]),
Have1 = Have + (Sz-Have), % length(Chunk)
Buff1 = Buff ++ Chunk, % TODO: ++ efficiency?
readAll_loop(This, Sz, Buff1, Have1);
true ->
Buff
end.