]>
Commit | Line | Data |
---|---|---|
f67539c2 TL |
1 | open Thrift |
2 | ||
3 | module T = Transport | |
4 | ||
5 | let c_0xff_32 = Int32.of_string "0xff" | |
6 | ||
7 | (* Copied from OCamlnet rtypes.ml *) | |
8 | let encode_frame_size x = | |
9 | let s = String.create 4 in | |
10 | let n3 = Int32.to_int (Int32.shift_right_logical x 24) land 0xff in | |
11 | let n2 = Int32.to_int (Int32.shift_right_logical x 16) land 0xff in | |
12 | let n1 = Int32.to_int (Int32.shift_right_logical x 8) land 0xff in | |
13 | let n0 = Int32.to_int (Int32.logand x c_0xff_32) in | |
14 | String.unsafe_set s 0 (Char.unsafe_chr n3); | |
15 | String.unsafe_set s 1 (Char.unsafe_chr n2); | |
16 | String.unsafe_set s 2 (Char.unsafe_chr n1); | |
17 | String.unsafe_set s 3 (Char.unsafe_chr n0); | |
18 | s | |
19 | ||
20 | let decode_frame_size s = | |
21 | let n3 = Int32.of_int (Char.code s.[0]) in | |
22 | let n2 = Int32.of_int (Char.code s.[1]) in | |
23 | let n1 = Int32.of_int (Char.code s.[2]) in | |
24 | let n0 = Int32.of_int (Char.code s.[3]) in | |
25 | Int32.logor | |
26 | (Int32.shift_left n3 24) | |
27 | (Int32.logor | |
28 | (Int32.shift_left n2 16) | |
29 | (Int32.logor | |
30 | (Int32.shift_left n1 8) | |
31 | n0)) | |
32 | ||
33 | class t ?(max_length=Sys.max_string_length) (transport: T.t) = | |
34 | object (self) | |
35 | inherit T.t | |
36 | ||
37 | method isOpen = transport#isOpen | |
38 | method opn = transport#opn | |
39 | method close = transport#close | |
40 | ||
41 | val mutable read_buf = None | |
42 | val mutable read_buf_offset = 0 | |
43 | val mutable write_buf = "" | |
44 | ||
45 | method private read_frame = | |
46 | let len_buf = String.create 4 in | |
47 | assert (transport#readAll len_buf 0 4 = 4); | |
48 | ||
49 | let size = Int32.to_int (decode_frame_size len_buf) in | |
50 | ||
51 | (if size < 0 | |
52 | then failwith (Printf.sprintf "Read a negative frame size (%i)!" size)); | |
53 | ||
54 | (if size > max_length | |
55 | then failwith (Printf.sprintf "Frame size (%i) larger than max length (%i)!" size max_length)); | |
56 | ||
57 | let buf = String.create size in | |
58 | assert (transport#readAll buf 0 size = size); | |
59 | read_buf <- Some buf; | |
60 | read_buf_offset <- 0 | |
61 | ||
62 | method private read_from_frame frame buf off len = | |
63 | let to_copy = min len ((String.length frame) - read_buf_offset) in | |
64 | String.blit frame read_buf_offset buf off to_copy; | |
65 | read_buf_offset <- read_buf_offset + to_copy; | |
66 | to_copy | |
67 | ||
68 | method read buf off len = | |
69 | match read_buf with | |
70 | | Some frame -> | |
71 | let i = self#read_from_frame frame buf off len in | |
72 | if i > 0 | |
73 | then i | |
74 | else begin | |
75 | self#read_frame; | |
76 | self#read_from_frame frame buf off len | |
77 | end | |
78 | | None -> | |
79 | self#read_frame; | |
80 | self#read buf off len | |
81 | ||
82 | method write buf off len = | |
83 | write_buf <- write_buf ^ (String.sub buf off len) | |
84 | ||
85 | method flush = | |
86 | let encoded_size = encode_frame_size (Int32.of_int (String.length write_buf)) in | |
87 | transport#write encoded_size 0 (String.length encoded_size); | |
88 | transport#write write_buf 0 (String.length write_buf); | |
89 | transport#flush; | |
90 | write_buf <- "" | |
91 | end | |
92 | ||
93 |