aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKenny Root <kenny@the-b.org>2009-06-12 10:46:21 +0000
committerKenny Root <kenny@the-b.org>2009-06-12 10:46:21 +0000
commit9821fd17d0b1f10c87bcfa8e1bf3ff481b2c65b6 (patch)
tree7e558d50b50349d95423ba359fefaa2d867e71a3
parentec2a6fca2efac964efbcb302913fb8af68e60294 (diff)
downloadconnectbot-9821fd17d0b1f10c87bcfa8e1bf3ff481b2c65b6.tar.gz
connectbot-9821fd17d0b1f10c87bcfa8e1bf3ff481b2c65b6.tar.bz2
connectbot-9821fd17d0b1f10c87bcfa8e1bf3ff481b2c65b6.zip
Charset changes
* Simplify charset decoding * Allow changing of charsets while host is connected git-svn-id: https://connectbot.googlecode.com/svn/trunk/connectbot@285 df292f66-193f-0410-a5fc-6d59da041ff2
-rw-r--r--src/org/connectbot/HostEditorActivity.java50
-rw-r--r--src/org/connectbot/service/Relay.java103
-rw-r--r--src/org/connectbot/service/TerminalBridge.java9
3 files changed, 64 insertions, 98 deletions
diff --git a/src/org/connectbot/HostEditorActivity.java b/src/org/connectbot/HostEditorActivity.java
index 9f38ecc..70dd5b3 100644
--- a/src/org/connectbot/HostEditorActivity.java
+++ b/src/org/connectbot/HostEditorActivity.java
@@ -26,16 +26,23 @@ import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
+import org.connectbot.bean.HostBean;
+import org.connectbot.service.TerminalBridge;
+import org.connectbot.service.TerminalManager;
import org.connectbot.util.HostDatabase;
import org.connectbot.util.PubkeyDatabase;
+import android.content.ComponentName;
import android.content.ContentValues;
+import android.content.Context;
import android.content.Intent;
+import android.content.ServiceConnection;
import android.content.SharedPreferences;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
+import android.os.IBinder;
import android.preference.CheckBoxPreference;
import android.preference.ListPreference;
import android.preference.Preference;
@@ -199,25 +206,28 @@ public class HostEditorActivity extends PreferenceActivity implements OnSharedPr
}
-
@Override
public SharedPreferences getSharedPreferences(String name, int mode) {
//Log.d(this.getClass().toString(), String.format("getSharedPreferences(name=%s)", name));
return this.pref;
}
+ protected static final String TAG = "ConnectBot.HostEditorActivity";
+
protected HostDatabase hostdb = null;
private PubkeyDatabase pubkeydb = null;
private CursorPreferenceHack pref;
- private String[] colorValues;
- private String[] colors;
+ private ServiceConnection connection;
+
+ private HostBean host;
+ protected TerminalBridge hostBridge;
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
- long id = this.getIntent().getLongExtra(Intent.EXTRA_TITLE, -1);
+ long hostId = this.getIntent().getLongExtra(Intent.EXTRA_TITLE, -1);
// TODO: we could pass through a specific ContentProvider uri here
//this.getPreferenceManager().setSharedPreferencesName(uri);
@@ -225,7 +235,27 @@ public class HostEditorActivity extends PreferenceActivity implements OnSharedPr
this.hostdb = new HostDatabase(this);
this.pubkeydb = new PubkeyDatabase(this);
- this.pref = new CursorPreferenceHack(HostDatabase.TABLE_HOSTS, id);
+ host = hostdb.findHostById(hostId);
+
+ connection = new ServiceConnection() {
+ public void onServiceConnected(ComponentName className, IBinder service) {
+ TerminalManager bound = ((TerminalManager.TerminalBinder) service).getService();
+
+ for (TerminalBridge bridge: bound.bridges) {
+ if (bridge.host.equals(host)) {
+ hostBridge = bridge;
+ Log.d(TAG, "Found host bridge; charset updates will be made live");
+ break;
+ }
+ }
+ }
+
+ public void onServiceDisconnected(ComponentName name) {
+ hostBridge = null;
+ }
+ };
+
+ this.pref = new CursorPreferenceHack(HostDatabase.TABLE_HOSTS, hostId);
this.pref.registerOnSharedPreferenceChangeListener(this);
this.addPreferencesFromResource(R.xml.host_prefs);
@@ -272,6 +302,9 @@ public class HostEditorActivity extends PreferenceActivity implements OnSharedPr
@Override
public void onStart() {
super.onStart();
+
+ bindService(new Intent(this, TerminalManager.class), connection, Context.BIND_AUTO_CREATE);
+
if(this.hostdb == null)
this.hostdb = new HostDatabase(this);
@@ -283,6 +316,9 @@ public class HostEditorActivity extends PreferenceActivity implements OnSharedPr
@Override
public void onStop() {
super.onStop();
+
+ unbindService(connection);
+
if(this.hostdb != null) {
this.hostdb.close();
this.hostdb = null;
@@ -332,6 +368,10 @@ public class HostEditorActivity extends PreferenceActivity implements OnSharedPr
// update values on changed preference
this.updateSummaries();
+ // Our CursorPreferenceHack always send null keys, so try to set charset anyway
+ if (hostBridge != null)
+ hostBridge.setCharset(sharedPreferences
+ .getString(HostDatabase.FIELD_HOST_ENCODING, HostDatabase.ENCODING_DEFAULT));
}
}
diff --git a/src/org/connectbot/service/Relay.java b/src/org/connectbot/service/Relay.java
index 942de88..3bb89b9 100644
--- a/src/org/connectbot/service/Relay.java
+++ b/src/org/connectbot/service/Relay.java
@@ -26,7 +26,6 @@ import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
-import java.nio.charset.CoderResult;
import java.nio.charset.CodingErrorAction;
import android.util.Log;
@@ -52,8 +51,8 @@ public class Relay implements Runnable {
private TerminalBridge bridge;
+ private Charset currentCharset;
private CharsetDecoder decoder;
- private CharsetDecoder replacer;
private Session session;
@@ -78,22 +77,22 @@ public class Relay implements Runnable {
}
public void setCharset(String encoding) {
+ Log.d("ConnectBot.Relay", "changing charset to " + encoding);
Charset charset;
if (encoding.equals(Cp437.NAME))
charset = new Cp437();
else
charset = Charset.forName(encoding);
+ if (charset == currentCharset)
+ return;
+
CharsetDecoder newCd = charset.newDecoder();
newCd.onUnmappableCharacter(CodingErrorAction.REPLACE);
- newCd.onMalformedInput(CodingErrorAction.REPORT);
-
- CharsetDecoder newReplacer = charset.newDecoder();
- newReplacer.onUnmappableCharacter(CodingErrorAction.REPLACE);
- newReplacer.onMalformedInput(CodingErrorAction.REPLACE);
+ newCd.onMalformedInput(CodingErrorAction.REPLACE);
+ currentCharset = charset;
decoder = newCd;
- replacer = newReplacer;
}
public void run() {
@@ -104,7 +103,6 @@ public class Relay implements Runnable {
charArray = charBuffer.array();
int bytesRead = 0;
- int offset = 0;
int newConditions = 0;
@@ -113,28 +111,12 @@ public class Relay implements Runnable {
newConditions = session.waitForCondition(CONDITIONS, 0);
if ((newConditions & ChannelCondition.STDOUT_DATA) != 0) {
while (stdout.available() > 0) {
- bytesRead = offset + stdout.read(byteArray, offset, BUFFER_SIZE - offset);
+ bytesRead = stdout.read(byteArray, 0, BUFFER_SIZE);
byteBuffer.position(0);
byteBuffer.limit(bytesRead);
-
- CoderResult coderResult = decoder.decode(byteBuffer, charBuffer, true);
-
- while (byteBuffer.position() < bytesRead) {
- if (coderResult.isMalformed())
- skipMalformedBytes(bytesRead, coderResult);
-
- coderResult = decoder.decode(byteBuffer, charBuffer, true);
- }
-
- if (coderResult.isMalformed())
- offset = discardMalformedBytes(bytesRead, coderResult);
- else {
- // No errors at all.
- buffer.putString(charArray, 0, charBuffer.position());
- offset = 0;
- }
-
+ decoder.decode(byteBuffer, charBuffer, false);
+ buffer.putString(charArray, 0, charBuffer.position());
charBuffer.clear();
}
@@ -156,69 +138,4 @@ public class Relay implements Runnable {
}
}
}
-
- /**
- * @param stream
-\ * @throws IOException
- */
- private void logAndDiscard(InputStream stream) throws IOException {
- while (stream.available() > 0) {
- int n = stream.read(byteArray);
- byteBuffer.position(0);
- byteBuffer.limit(n);
- replacer.decode(byteBuffer, charBuffer, false);
- // TODO I don't know.. do we want this? We were ignoring it before
- Log.d(TAG, String.format("Read data from stream: %s", new String(charArray, 0, charBuffer.position())));
- charBuffer.clear();
- }
- }
-
- /**
- * @param n
- * @param cr
- * @return
- */
- private int discardMalformedBytes(int n, CoderResult cr) {
- int offset;
- /* If we still have malformed input, save the bytes for the next
- * read and try to parse it again.
- */
- offset = n - byteBuffer.position() + cr.length();
- System.arraycopy(byteArray, byteBuffer.position() - cr.length(), byteArray, 0, offset);
- Log.d(TAG, String.format("Copying out %d chars at %d: 0x%02x",
- offset, byteBuffer.position() - cr.length(),
- byteArray[byteBuffer.position() - cr.length()]
- ));
- return offset;
- }
-
- /**
- * @param numReadBytes
- * @param errorResult
- */
- private void skipMalformedBytes(int numReadBytes, CoderResult errorResult) {
- int curpos = byteBuffer.position() - errorResult.length();
-
- if (curpos > 0) {
- /* There is good data before the malformed section, so
- * pass this on immediately.
- */
- buffer.putString(charArray, 0, charBuffer.position());
- }
-
- byteBuffer.position(curpos);
- byteBuffer.limit(curpos + errorResult.length());
-
- charBuffer.clear();
- replacer.decode(byteBuffer, charBuffer, true);
-
- buffer.putString(charArray, 0, charBuffer.position());
-
- curpos += errorResult.length();
-
- byteBuffer.position(curpos);
- byteBuffer.limit(numReadBytes);
-
- charBuffer.clear();
- }
}
diff --git a/src/org/connectbot/service/TerminalBridge.java b/src/org/connectbot/service/TerminalBridge.java
index 82d1ce5..ec0a35c 100644
--- a/src/org/connectbot/service/TerminalBridge.java
+++ b/src/org/connectbot/service/TerminalBridge.java
@@ -604,6 +604,15 @@ public class TerminalBridge implements VDUDisplay, OnKeyListener, InteractiveCal
}
/**
+ * Sets the encoding used by the terminal. If the connection is live,
+ * then the character set is changed for the next read.
+ * @param encoding the canonical name of the character encoding
+ */
+ public void setCharset(String encoding) {
+ relay.setCharset(encoding);
+ }
+
+ /**
* Convenience method for writing a line into the underlying MUD buffer.
* Should never be called once the session is established.
*/