]>
Commit | Line | Data |
---|---|---|
f67539c2 TL |
1 | /* |
2 | * Licensed to the Apache Software Foundation (ASF) under one | |
3 | * or more contributor license agreements. See the NOTICE file | |
4 | * distributed with this work for additional information | |
5 | * regarding copyright ownership. The ASF licenses this file | |
6 | * to you under the Apache License, Version 2.0 (the | |
7 | * "License"); you may not use this file except in compliance | |
8 | * with the License. You may obtain a copy of the License at | |
9 | * | |
10 | * http://www.apache.org/licenses/LICENSE-2.0 | |
11 | * | |
12 | * Unless required by applicable law or agreed to in writing, | |
13 | * software distributed under the License is distributed on an | |
14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | |
15 | * KIND, either express or implied. See the License for the | |
16 | * specific language governing permissions and limitations | |
17 | * under the License. | |
18 | */ | |
19 | ||
20 | package org.apache.thrift.transport; | |
21 | ||
22 | import org.apache.thrift.transport.*; | |
23 | ||
24 | import haxe.io.Eof; | |
25 | import haxe.io.Bytes; | |
26 | import haxe.io.BytesBuffer; | |
27 | import haxe.io.BytesOutput; | |
28 | import haxe.io.BytesInput; | |
29 | ||
30 | ||
31 | /** | |
32 | * TFramedTransport is a buffered TTransport that ensures a fully read message | |
33 | * every time by preceding messages with a 4-byte frame size. | |
34 | */ | |
35 | class TFramedTransport extends TTransport | |
36 | { | |
37 | public static inline var DEFAULT_MAX_LENGTH = 16384000; | |
38 | ||
39 | var maxLength_ : Int; | |
40 | ||
41 | /** | |
42 | * Underlying transport | |
43 | */ | |
44 | var transport_ : TTransport = null; | |
45 | ||
46 | /** | |
47 | * Buffer for output | |
48 | */ | |
49 | var writeBuffer_ : BytesOutput = new BytesOutput(); | |
50 | ||
51 | /** | |
52 | * Buffer for input | |
53 | */ | |
54 | var readBuffer_ : BytesInput = null; | |
55 | ||
56 | /** | |
57 | * Constructor wraps around another transport | |
58 | */ | |
59 | public function new( transport : TTransport, maxLength : Int = DEFAULT_MAX_LENGTH) { | |
60 | transport_ = transport; | |
61 | maxLength_ = maxLength; | |
62 | } | |
63 | ||
64 | public override function open() : Void { | |
65 | transport_.open(); | |
66 | } | |
67 | ||
68 | public override function isOpen() : Bool { | |
69 | return transport_.isOpen(); | |
70 | } | |
71 | ||
72 | public override function close() : Void { | |
73 | transport_.close(); | |
74 | } | |
75 | ||
76 | public override function read(buf : BytesBuffer, off : Int, len : Int) : Int { | |
77 | try { | |
78 | var data = Bytes.alloc(len); | |
79 | ||
80 | if ((readBuffer_ != null) && (readBuffer_.position < readBuffer_.length)) { | |
81 | var got : Int = readBuffer_.readBytes(data, off, len); | |
82 | if (got > 0) { | |
83 | buf.addBytes(data,0,got); | |
84 | return got; | |
85 | }; | |
86 | }; | |
87 | ||
88 | // Read another frame of data | |
89 | readFrame(); | |
90 | ||
91 | var got = readBuffer_.readBytes(data, off, len); | |
92 | buf.addBytes(data,0,got); | |
93 | return got; | |
94 | } | |
95 | catch (eof : Eof) { | |
96 | throw new TTransportException(TTransportException.END_OF_FILE, 'Can\'t read $len bytes!'); | |
97 | } | |
98 | } | |
99 | ||
100 | ||
101 | function readFrameSize() : Int { | |
102 | try { | |
103 | var buffer = new BytesBuffer(); | |
104 | var len = transport_.readAll( buffer, 0, 4); | |
105 | var inp = new BytesInput( buffer.getBytes(), 0, 4); | |
106 | inp.bigEndian = true; | |
107 | return inp.readInt32(); | |
108 | } | |
109 | catch(eof : Eof) { | |
110 | throw new TTransportException(TTransportException.END_OF_FILE, 'Can\'t read 4 bytes!'); | |
111 | } | |
112 | } | |
113 | ||
114 | ||
115 | function readFrame() : Void { | |
116 | var size : Int = readFrameSize(); | |
117 | ||
118 | if (size < 0) { | |
119 | throw new TTransportException(TTransportException.UNKNOWN, 'Read a negative frame size ($size)!'); | |
120 | }; | |
121 | if (size > maxLength_) { | |
122 | throw new TTransportException(TTransportException.UNKNOWN, 'Frame size ($size) larger than max length ($maxLength_)!'); | |
123 | }; | |
124 | ||
125 | try { | |
126 | var buffer = new BytesBuffer(); | |
127 | size = transport_.readAll( buffer, 0, size); | |
128 | readBuffer_ = new BytesInput( buffer.getBytes(), 0, size); | |
129 | readBuffer_.bigEndian = true; | |
130 | } | |
131 | catch(eof : Eof) { | |
132 | throw new TTransportException(TTransportException.END_OF_FILE, 'Can\'t read $size bytes!'); | |
133 | } | |
134 | } | |
135 | ||
136 | public override function write(buf : Bytes, off : Int, len : Int) : Void { | |
137 | writeBuffer_.writeBytes(buf, off, len); | |
138 | } | |
139 | ||
140 | function writeFrameSize(len : Int) : Void { | |
141 | var out = new BytesOutput(); | |
142 | out.bigEndian = true; | |
143 | out.writeInt32(len); | |
144 | transport_.write(out.getBytes(), 0, 4); | |
145 | } | |
146 | ||
147 | public override function flush( callback : Dynamic->Void =null) : Void { | |
148 | var buf : Bytes = writeBuffer_.getBytes(); | |
149 | var len : Int = buf.length; | |
150 | writeBuffer_ = new BytesOutput(); | |
151 | ||
152 | writeFrameSize(len); | |
153 | transport_.write(buf, 0, len); | |
154 | transport_.flush(callback); | |
155 | } | |
156 | } | |
157 | ||
158 |