summaryrefslogtreecommitdiff
path: root/lib/erl/src/thrift_file_transport.erl
blob: 5ac2dbe1f81b26f28ab388ce07f4b1abf2c505da (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
%%
%% Licensed to the Apache Software Foundation (ASF) under one
%% or more contributor license agreements. See the NOTICE file
%% distributed with this work for additional information
%% regarding copyright ownership. The ASF licenses this file
%% to you under the Apache License, Version 2.0 (the
%% "License"); you may not use this file except in compliance
%% with the License. You may obtain a copy of the License at
%%
%%   http://www.apache.org/licenses/LICENSE-2.0
%%
%% Unless required by applicable law or agreed to in writing,
%% software distributed under the License is distributed on an
%% "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
%% KIND, either express or implied. See the License for the
%% specific language governing permissions and limitations
%% under the License.
%%

-module(thrift_file_transport).

-behaviour(thrift_transport).

-export([new_reader/1,
         new/1,
         new/2,
         write/2, read/2, flush/1, close/1]).

-record(t_file_transport, {device,
                           should_close = true,
                           mode = write}).

%%%% CONSTRUCTION   %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

new_reader(Filename) ->
    case file:open(Filename, [read, binary, {read_ahead, 1024*1024}]) of
        {ok, IODevice} ->
            new(IODevice, [{should_close, true}, {mode, read}]);
        Error -> Error
    end.

new(Device) ->
    new(Device, []).

%% Device :: io_device()
%%
%% Device should be opened in raw and binary mode.
new(Device, Opts) when is_list(Opts) ->
    State = parse_opts(Opts, #t_file_transport{device = Device}),
    thrift_transport:new(?MODULE, State).


%% Parse options
parse_opts([{should_close, Bool} | Rest], State) when is_boolean(Bool) ->
    parse_opts(Rest, State#t_file_transport{should_close = Bool});
parse_opts([{mode, Mode} | Rest], State)
  when Mode =:= write;
       Mode =:= read ->
    parse_opts(Rest, State#t_file_transport{mode = Mode});
parse_opts([], State) ->
     State.


%%%% TRANSPORT IMPL %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

write(#t_file_transport{device = Device, mode = write}, Data) ->
    file:write(Device, Data);
write(_T, _D) ->
    {error, read_mode}.


read(#t_file_transport{device = Device, mode = read}, Len)
  when is_integer(Len), Len >= 0 ->
    file:read(Device, Len);
read(_T, _D) ->
    {error, read_mode}.

flush(#t_file_transport{device = Device, mode = write}) ->
    file:sync(Device).

close(#t_file_transport{device = Device, should_close = SC}) ->
    case SC of
        true ->
            file:close(Device);
        false ->
            ok
    end.