blob: c2bf920d79f00087e02a7cb05909de6e01e133bc [file] [log] [blame]
Christopher Piro094823a2007-07-18 00:26:12 +00001%%% Copyright (c) 2007- Facebook
2%%% Distributed under the Thrift Software License
3%%%
4%%% See accompanying file LICENSE or visit the Thrift site at:
5%%% http://developers.facebook.com/thrift/
6
7-module(tSocket).
8
9-include("oop.hrl").
10
11-include("thrift.hrl").
12-include("transport/tTransportException.hrl").
13% -include("transport/tTransport.hrl").
14-include("transport/tSocket.hrl").
15
16-behavior(oop).
17
Christopher Piroc3c6c0c2007-08-01 23:42:12 +000018-export([attr/4, super/0, inspect/1]).
Christopher Piro094823a2007-07-18 00:26:12 +000019
Christopher Piroc7fd7632007-10-02 00:05:04 +000020-export([new/0, new/1, new/2,
21 effectful_setHandle/2, effectful_open/1,
Christopher Piro094823a2007-07-18 00:26:12 +000022 isOpen/1, write/2, read/2, effectful_close/1]).
23
24%%%
25%%% define attributes
26%%% 'super' is required unless ?MODULE is a base class
27%%%
28
29?DEFINE_ATTR(super);
30?DEFINE_ATTR(host);
31?DEFINE_ATTR(port);
32?DEFINE_ATTR(handle).
33
34%%%
35%%% behavior callbacks
36%%%
37
38%%% super() -> SuperModule = atom()
39%%% | none
40
41super() ->
42 tTransport.
43
44%%% inspect(This) -> string()
45
46inspect(This) ->
47 ?FORMAT_ATTR(host) ++ ", " ++
48 ?FORMAT_ATTR(port) ++ ", " ++
49 ?FORMAT_ATTR(handle).
50
51%%%
52%%% class methods
53%%%
54
55new(Host, Port) ->
56 Super = (super()):new(),
57 #?MODULE{super=Super, host=Host, port=Port, handle=nil}.
58
59new(Host) ->
60 new(Host, 9090).
61
62new() ->
63 new("localhost", 9090).
64
65%%%
66%%% instance methods
67%%%
68
69effectful_setHandle(This, Handle) ->
70 {ok, oop:set(This, handle, Handle)}.
71
72effectful_open(This) ->
73 Host = oop:get(This, host),
74 Port = oop:get(This, port),
75 Options = [],
76
77 case gen_tcp:connect(Host, Port, Options) of
78 {error, _} ->
79 exit(tTransportException:new(
80 ?tTransportException_NOT_OPEN,
81 "Could not connect to " ++ Host ++ ":" ++ Port)
82 );
83 {ok, Socket} ->
84 {ok, oop:set(This, handle, Socket)}
85 end.
86
87isOpen(This) ->
88 oop:get(This, handle) /= nil.
89
90write(This, Str) ->
91 Handle = oop:get(This, handle),
92 Val = gen_tcp:send(Handle, Str),
93
Christopher Piroc7fd7632007-10-02 00:05:04 +000094 %% DEBUG
95 %% error_logger:info_msg("tSocket: wrote ~p~n", [Str]),
96
Christopher Piro5b3a8f72007-08-01 22:27:37 +000097 %% error_logger:info_msg("WRITE |~p| (~p)", [Str,Val]),
Christopher Piro094823a2007-07-18 00:26:12 +000098
99 case Val of
100 {error, _} ->
101 throw(tTransportException:new(?tTransportException_NOT_OPEN, "in write"));
102 ok ->
103 ok
104 end.
105
106read(This, Sz) ->
107 Handle = oop:get(This, handle),
108 case gen_tcp:recv(Handle, Sz) of
109 {ok, []} ->
110 Host = oop:get(This, host),
111 Port = oop:get(This, port),
112 throw(tTransportException:new(?tTransportException_UNKNOWN, "TSocket: Could not read " ++ Sz ++ "bytes from " ++ Host ++ ":" ++ Port));
113 {ok, Data} ->
Christopher Piroc7fd7632007-10-02 00:05:04 +0000114 %% DEBUG
115 %% io:format("tSocket: read ~p~n", [Data]),
Christopher Piro094823a2007-07-18 00:26:12 +0000116 Data;
117 {error, Error} ->
Christopher Piro094823a2007-07-18 00:26:12 +0000118 exit(tTransportException:new(?tTransportException_NOT_OPEN, "in tSocket:read/2: gen_tcp:recv"))
119 end.
120
121effectful_close(This) ->
122 case oop:get(This, handle) of
123 nil ->
124 {ok, This};
125 Handle ->
126 gen_tcp:close(Handle),
127 {ok, oop:set(This, handle, nil)}
128 end.