Christopher Piro | 094823a | 2007-07-18 00:26:12 +0000 | [diff] [blame] | 1 | %%% 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 Piro | c3c6c0c | 2007-08-01 23:42:12 +0000 | [diff] [blame] | 18 | -export([attr/4, super/0, inspect/1]). |
Christopher Piro | 094823a | 2007-07-18 00:26:12 +0000 | [diff] [blame] | 19 | |
Christopher Piro | 42fe4b9 | 2007-10-02 00:24:07 +0000 | [diff] [blame^] | 20 | -export([new/0, new/1, new/2, |
| 21 | effectful_setHandle/2, effectful_open/1, |
Christopher Piro | 094823a | 2007-07-18 00:26:12 +0000 | [diff] [blame] | 22 | 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 | |
| 41 | super() -> |
| 42 | tTransport. |
| 43 | |
| 44 | %%% inspect(This) -> string() |
| 45 | |
| 46 | inspect(This) -> |
| 47 | ?FORMAT_ATTR(host) ++ ", " ++ |
| 48 | ?FORMAT_ATTR(port) ++ ", " ++ |
| 49 | ?FORMAT_ATTR(handle). |
| 50 | |
| 51 | %%% |
| 52 | %%% class methods |
| 53 | %%% |
| 54 | |
| 55 | new(Host, Port) -> |
| 56 | Super = (super()):new(), |
| 57 | #?MODULE{super=Super, host=Host, port=Port, handle=nil}. |
| 58 | |
| 59 | new(Host) -> |
| 60 | new(Host, 9090). |
| 61 | |
| 62 | new() -> |
| 63 | new("localhost", 9090). |
| 64 | |
| 65 | %%% |
| 66 | %%% instance methods |
| 67 | %%% |
| 68 | |
| 69 | effectful_setHandle(This, Handle) -> |
| 70 | {ok, oop:set(This, handle, Handle)}. |
| 71 | |
| 72 | effectful_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 | |
| 87 | isOpen(This) -> |
| 88 | oop:get(This, handle) /= nil. |
| 89 | |
| 90 | write(This, Str) -> |
| 91 | Handle = oop:get(This, handle), |
| 92 | Val = gen_tcp:send(Handle, Str), |
| 93 | |
Christopher Piro | 5b3a8f7 | 2007-08-01 22:27:37 +0000 | [diff] [blame] | 94 | %% error_logger:info_msg("WRITE |~p| (~p)", [Str,Val]), |
Christopher Piro | 094823a | 2007-07-18 00:26:12 +0000 | [diff] [blame] | 95 | |
| 96 | case Val of |
| 97 | {error, _} -> |
| 98 | throw(tTransportException:new(?tTransportException_NOT_OPEN, "in write")); |
| 99 | ok -> |
| 100 | ok |
| 101 | end. |
| 102 | |
| 103 | read(This, Sz) -> |
| 104 | Handle = oop:get(This, handle), |
| 105 | case gen_tcp:recv(Handle, Sz) of |
| 106 | {ok, []} -> |
| 107 | Host = oop:get(This, host), |
| 108 | Port = oop:get(This, port), |
| 109 | throw(tTransportException:new(?tTransportException_UNKNOWN, "TSocket: Could not read " ++ Sz ++ "bytes from " ++ Host ++ ":" ++ Port)); |
| 110 | {ok, Data} -> |
| 111 | Data; |
| 112 | {error, Error} -> |
Christopher Piro | 094823a | 2007-07-18 00:26:12 +0000 | [diff] [blame] | 113 | exit(tTransportException:new(?tTransportException_NOT_OPEN, "in tSocket:read/2: gen_tcp:recv")) |
| 114 | end. |
| 115 | |
| 116 | effectful_close(This) -> |
| 117 | case oop:get(This, handle) of |
| 118 | nil -> |
| 119 | {ok, This}; |
| 120 | Handle -> |
| 121 | gen_tcp:close(Handle), |
| 122 | {ok, oop:set(This, handle, nil)} |
| 123 | end. |