Mercurial > 510Connectbot
annotate src/com/five_ten_sg/connectbot/service/Relay.java @ 396:1f625669d89d
Added tag stable-1.9.0.6 for changeset 74d527fe7f5f
author | Carl Byington <carl@five-ten-sg.com> |
---|---|
date | Fri, 19 Sep 2014 15:27:51 -0700 |
parents | 766176d84e73 |
children |
rev | line source |
---|---|
0 | 1 /* |
2 * ConnectBot: simple, powerful, open-source SSH client for Android | |
3 * Copyright 2007 Kenny Root, Jeffrey Sharkey | |
4 * | |
5 * Licensed under the Apache License, Version 2.0 (the "License"); | |
6 * you may not use this file except in compliance with the License. | |
7 * You may obtain a copy of the License at | |
8 * | |
9 * http://www.apache.org/licenses/LICENSE-2.0 | |
10 * | |
11 * Unless required by applicable law or agreed to in writing, software | |
12 * distributed under the License is distributed on an "AS IS" BASIS, | |
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
14 * See the License for the specific language governing permissions and | |
15 * limitations under the License. | |
16 */ | |
17 | |
18 package com.five_ten_sg.connectbot.service; | |
19 | |
20 import java.io.IOException; | |
21 import java.nio.ByteBuffer; | |
22 import java.nio.CharBuffer; | |
23 import java.nio.charset.Charset; | |
24 import java.nio.charset.CharsetDecoder; | |
25 import java.nio.charset.CoderResult; | |
26 import java.nio.charset.CodingErrorAction; | |
227
2dd627df4dfb
delay testChanged() by 10ms for async transports; sendScreen resets watch area to the entire screen
Carl Byington <carl@five-ten-sg.com>
parents:
112
diff
changeset
|
27 import java.util.Timer; |
2dd627df4dfb
delay testChanged() by 10ms for async transports; sendScreen resets watch area to the entire screen
Carl Byington <carl@five-ten-sg.com>
parents:
112
diff
changeset
|
28 import java.util.TimerTask; |
0 | 29 |
30 import org.apache.harmony.niochar.charset.additional.IBM437; | |
31 | |
32 import com.five_ten_sg.connectbot.transport.AbsTransport; | |
33 import android.graphics.Paint; | |
34 import android.text.AndroidCharacter; | |
35 import android.util.Log; | |
36 import de.mud.terminal.vt320; | |
37 | |
38 /** | |
39 * @author Kenny Root | |
40 */ | |
41 public class Relay implements Runnable { | |
42 private static final String TAG = "ConnectBot.Relay"; | |
43 | |
44 private static final int BUFFER_SIZE = 4096; | |
45 | |
46 private TerminalBridge bridge; | |
47 | |
48 private Charset currentCharset; | |
49 private CharsetDecoder decoder; | |
50 | |
51 private AbsTransport transport; | |
52 | |
53 private vt320 buffer; | |
54 | |
55 private ByteBuffer byteBuffer; | |
56 private CharBuffer charBuffer; | |
57 | |
58 private byte[] byteArray; | |
59 private char[] charArray; | |
60 | |
61 private void eastAsianWidthMeasure(char[] charArray, int start, int end, | |
62 byte[] wideAttribute, Paint paint, int charWidth) { | |
63 AndroidCharacter.getEastAsianWidths(charArray, start, end - start, wideAttribute); | |
64 } | |
65 | |
66 public Relay(TerminalBridge bridge, AbsTransport transport, vt320 buffer, String encoding) { | |
67 setCharset(encoding); | |
68 this.bridge = bridge; | |
69 this.transport = transport; | |
70 this.buffer = buffer; | |
71 } | |
72 | |
73 public void setCharset(String encoding) { | |
74 Log.d("ConnectBot.Relay", "changing charset to " + encoding); | |
75 Charset charset; | |
76 | |
77 if (encoding.equals("CP437")) | |
78 charset = new IBM437("IBM437", | |
79 new String[] { "IBM437", "CP437" }); | |
80 else | |
81 charset = Charset.forName(encoding); | |
82 | |
83 if (charset == currentCharset || charset == null) | |
84 return; | |
85 | |
86 CharsetDecoder newCd = charset.newDecoder(); | |
87 newCd.onUnmappableCharacter(CodingErrorAction.REPLACE); | |
88 newCd.onMalformedInput(CodingErrorAction.REPLACE); | |
89 currentCharset = charset; | |
90 | |
91 synchronized (this) { | |
92 decoder = newCd; | |
93 } | |
94 } | |
95 | |
96 public Charset getCharset() { | |
97 return currentCharset; | |
98 } | |
99 | |
100 public void run() { | |
101 byteBuffer = ByteBuffer.allocate(BUFFER_SIZE); | |
102 charBuffer = CharBuffer.allocate(BUFFER_SIZE); | |
103 /* for East Asian character widths */ | |
104 byte[] wideAttribute = new byte[BUFFER_SIZE]; | |
105 byteArray = byteBuffer.array(); | |
106 charArray = charBuffer.array(); | |
107 CoderResult result; | |
108 int bytesRead = 0; | |
109 byteBuffer.limit(0); | |
110 int bytesToRead; | |
111 int offset; | |
112 int charWidth; | |
227
2dd627df4dfb
delay testChanged() by 10ms for async transports; sendScreen resets watch area to the entire screen
Carl Byington <carl@five-ten-sg.com>
parents:
112
diff
changeset
|
113 Timer timer = new Timer("relay.blocker", true); |
234
766176d84e73
delay testChanged() by 10ms for async transports
Carl Byington <carl@five-ten-sg.com>
parents:
233
diff
changeset
|
114 TimerTask task = null; |
0 | 115 |
116 try { | |
117 while (true) { | |
118 charWidth = bridge.charWidth; | |
119 bytesToRead = byteBuffer.capacity() - byteBuffer.limit(); | |
120 offset = byteBuffer.arrayOffset() + byteBuffer.limit(); | |
112 | 121 |
227
2dd627df4dfb
delay testChanged() by 10ms for async transports; sendScreen resets watch area to the entire screen
Carl Byington <carl@five-ten-sg.com>
parents:
112
diff
changeset
|
122 if (transport.willBlock()) { |
234
766176d84e73
delay testChanged() by 10ms for async transports
Carl Byington <carl@five-ten-sg.com>
parents:
233
diff
changeset
|
123 task = new TimerTask() { |
766176d84e73
delay testChanged() by 10ms for async transports
Carl Byington <carl@five-ten-sg.com>
parents:
233
diff
changeset
|
124 public void run() { |
766176d84e73
delay testChanged() by 10ms for async transports
Carl Byington <carl@five-ten-sg.com>
parents:
233
diff
changeset
|
125 buffer.testChanged(); |
766176d84e73
delay testChanged() by 10ms for async transports
Carl Byington <carl@five-ten-sg.com>
parents:
233
diff
changeset
|
126 } |
766176d84e73
delay testChanged() by 10ms for async transports
Carl Byington <carl@five-ten-sg.com>
parents:
233
diff
changeset
|
127 }; |
227
2dd627df4dfb
delay testChanged() by 10ms for async transports; sendScreen resets watch area to the entire screen
Carl Byington <carl@five-ten-sg.com>
parents:
112
diff
changeset
|
128 timer.schedule(task, 10); // 10 ms delay |
228
c9a7f33b53a8
delay testChanged() by 10ms for async transports
Carl Byington <carl@five-ten-sg.com>
parents:
227
diff
changeset
|
129 } |
112 | 130 |
0 | 131 bytesRead = transport.read(byteArray, offset, bytesToRead); |
234
766176d84e73
delay testChanged() by 10ms for async transports
Carl Byington <carl@five-ten-sg.com>
parents:
233
diff
changeset
|
132 |
766176d84e73
delay testChanged() by 10ms for async transports
Carl Byington <carl@five-ten-sg.com>
parents:
233
diff
changeset
|
133 if (task != null) { |
766176d84e73
delay testChanged() by 10ms for async transports
Carl Byington <carl@five-ten-sg.com>
parents:
233
diff
changeset
|
134 task.cancel(); |
766176d84e73
delay testChanged() by 10ms for async transports
Carl Byington <carl@five-ten-sg.com>
parents:
233
diff
changeset
|
135 task = null; |
766176d84e73
delay testChanged() by 10ms for async transports
Carl Byington <carl@five-ten-sg.com>
parents:
233
diff
changeset
|
136 } |
227
2dd627df4dfb
delay testChanged() by 10ms for async transports; sendScreen resets watch area to the entire screen
Carl Byington <carl@five-ten-sg.com>
parents:
112
diff
changeset
|
137 |
0 | 138 if (bytesRead > 0) { |
139 byteBuffer.limit(byteBuffer.limit() + bytesRead); | |
140 | |
141 synchronized (this) { | |
142 result = decoder.decode(byteBuffer, charBuffer, false); | |
143 } | |
144 | |
145 if (result.isUnderflow() && | |
146 byteBuffer.limit() == byteBuffer.capacity()) { | |
147 byteBuffer.compact(); | |
148 byteBuffer.limit(byteBuffer.position()); | |
149 byteBuffer.position(0); | |
150 } | |
151 | |
152 offset = charBuffer.position(); | |
153 eastAsianWidthMeasure(charArray, 0, offset, wideAttribute, bridge.defaultPaint, charWidth); | |
154 buffer.putString(charArray, wideAttribute, 0, charBuffer.position()); | |
155 bridge.propagateConsoleText(charArray, charBuffer.position()); | |
156 charBuffer.clear(); | |
157 bridge.redraw(); | |
158 } | |
159 } | |
160 } | |
161 catch (IOException e) { | |
162 Log.e(TAG, "Problem while handling incoming data in relay thread", e); | |
163 } | |
227
2dd627df4dfb
delay testChanged() by 10ms for async transports; sendScreen resets watch area to the entire screen
Carl Byington <carl@five-ten-sg.com>
parents:
112
diff
changeset
|
164 |
2dd627df4dfb
delay testChanged() by 10ms for async transports; sendScreen resets watch area to the entire screen
Carl Byington <carl@five-ten-sg.com>
parents:
112
diff
changeset
|
165 timer.cancel(); |
0 | 166 } |
167 } |