blob: 850c3b92082c06d7704ee49a02069f7a30431bcf [file] [log] [blame]
Christopher Piro2f5afce2007-06-29 07:17:33 +00001-module(tSocket).
2
3-include("thrift/thrift.hrl").
4-include("thrift/transport/tTransportException.hrl").
5% -include("thrift/transport/tTransport.hrl").
6-include("thrift/transport/tSocket.hrl").
7
8-export([new/0, new/1, new/2, setHandle_MUTABLE/2, open_MUTABLE/1, isOpen/1, write/2, read/2, close_MUTABLE/1, readAll/2]).
9
10new(Host, Port) ->
11 #tSocket{host=Host, port=Port, handle=nil}. % WATCH
12
13new() -> new("localhost", 9090).
14new(Host) -> new(Host, 9090).
15
16setHandle_MUTABLE(This, Handle) ->
17 This#tSocket{handle=Handle}.
18
19open_MUTABLE(This) ->
20 Host = This#tSocket.host,
21 Port = This#tSocket.port,
22 Options = [],
23
24 case gen_tcp:connect(Host, Port, Options) of
25 {error, _} ->
26 throw(tTransportException:new(
27 ?tTransportException_NOT_OPEN,
28 "Could not connect to " ++ Host ++ ":" ++ Port)
29 ),
30 {error, This}; % cpiro not reached?
31 {ok, Socket} ->
32 {ok, This#tSocket{handle=Socket}}
33 end.
34
35handle(This) ->
36 This#tSocket.handle.
37
38isOpen(This) ->
39 handle(This) /= nil.
40
41write(This, Str) ->
42 Val = gen_tcp:send(handle(This), Str),
43
44 %% io:format("WRITE |~p|(~p)~n", [Str,Val]),
45
46 case Val of
47 {error, _} ->
48 throw(tTransportException:new(?tTransportException_NOT_OPEN, "in write"));
49 ok ->
50 ok
51 end.
52
53read(This, Sz) ->
54 case gen_tcp:recv(handle(This), Sz) of
55 {ok, []} ->
56 { Host, Port } = { This#tSocket.host, This#tSocket.port },
57 throw(tTransportException:new(?tTransportException_UNKNOWN, "TSocket: Could not read " ++ Sz ++ "bytes from " ++ Host ++ ":" ++ Port));
58 {ok, Data} ->
59 Data;
60 {error, Error} ->
61 io:format("in tSocket:read/2: gen_tcp:recv(~p, ~p) => {error, ~p}~n",
62 [handle(This), Sz, Error]),
63 throw(tTransportException:new(?tTransportException_NOT_OPEN, "in tSocket:read/2: gen_tcp:recv"))
64 end.
65
66close_MUTABLE(This) ->
67 if
68 This#tSocket.handle == nil ->
69 This;
70 true ->
71 gen_tcp:close(handle(This)),
72 This#tSocket{handle=nil}
73 end.
74
75readAll(This, Sz) ->
76 readAll_loop(This, Sz, "", 0).
77
78readAll_loop(This, Sz, Buff, Have) ->
79 if
80 Have < Sz ->
81 Chunk = ?M1(This, read, Sz - Have),
82
83 %% man gen_tcp:
84 %% exactly Length bytes are returned, or an error;
85 %% possibly discarding less than Length bytes of data when
86 %% the socket gets closed from the other side.
87
88 %% io:format("READ |~p|~n", [Chunk]),
89
90 Have1 = Have + (Sz-Have), % length(Chunk)
91 Buff1 = Buff ++ Chunk, % TODO: ++ efficiency?
92 readAll_loop(This, Sz, Buff1, Have1);
93 true ->
94 Buff
95 end.
96