diff options
author | Matt Garnes <matt@cyngn.com> | 2015-04-06 18:25:47 -0700 |
---|---|---|
committer | Gerrit Code Review <gerrit@cyanogenmod.org> | 2015-04-10 22:31:57 +0000 |
commit | 748753da0d3f16c750180566540980bc82ce750c (patch) | |
tree | 19220b6c9e392443296fbefd3d9fba0eb141fbc5 /src | |
parent | 3650ca2b315f16f1b66d59bdf836a446a97343df (diff) | |
download | android_packages_apps_CMFileManager-748753da0d3f16c750180566540980bc82ce750c.tar.gz android_packages_apps_CMFileManager-748753da0d3f16c750180566540980bc82ce750c.tar.bz2 android_packages_apps_CMFileManager-748753da0d3f16c750180566540980bc82ce750c.zip |
Detect text encoding with juniversalchardet.
- When opening files in the built in editor for display, detect the
encoding with juniversalchardet, so that the correct encoding will be
used.
- Use byte buffers to back ShellConsole instead of StringBuffers
Change-Id: I85fa567ef589a82f1c8604f1f215647376c31c9a
(cherry picked from commit 55c55835d3bd685dde542b4f5952ce401542ab84)
Diffstat (limited to 'src')
12 files changed, 133 insertions, 82 deletions
diff --git a/src/com/cyanogenmod/filemanager/activities/EditorActivity.java b/src/com/cyanogenmod/filemanager/activities/EditorActivity.java index 9e42defc..7866102e 100644 --- a/src/com/cyanogenmod/filemanager/activities/EditorActivity.java +++ b/src/com/cyanogenmod/filemanager/activities/EditorActivity.java @@ -68,7 +68,12 @@ import com.cyanogenmod.filemanager.ash.SyntaxHighlightFactory; import com.cyanogenmod.filemanager.ash.SyntaxHighlightProcessor; import com.cyanogenmod.filemanager.commands.AsyncResultListener; import com.cyanogenmod.filemanager.commands.WriteExecutable; +import com.cyanogenmod.filemanager.commands.shell.InvalidCommandDefinitionException; +import com.cyanogenmod.filemanager.console.Console; +import com.cyanogenmod.filemanager.console.ConsoleAllocException; import com.cyanogenmod.filemanager.console.ConsoleBuilder; +import com.cyanogenmod.filemanager.console.InsufficientPermissionsException; +import com.cyanogenmod.filemanager.console.java.JavaConsole; import com.cyanogenmod.filemanager.model.FileSystemObject; import com.cyanogenmod.filemanager.preferences.FileManagerSettings; import com.cyanogenmod.filemanager.preferences.Preferences; @@ -85,11 +90,13 @@ import com.cyanogenmod.filemanager.util.FileHelper; import com.cyanogenmod.filemanager.util.MediaHelper; import com.cyanogenmod.filemanager.util.ResourcesHelper; import com.cyanogenmod.filemanager.util.StringHelper; +import org.mozilla.universalchardet.UniversalDetector; import java.io.BufferedReader; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; +import java.io.IOException; import java.io.OutputStream; import java.io.StringReader; import java.util.ArrayList; @@ -273,12 +280,19 @@ public class EditorActivity extends Activity implements TextWatcher { long mSize; FileSystemObject mReadFso; OnProgressListener mListener; + boolean mDetectEncoding = false; + UniversalDetector mDetector; + String mDetectedEncoding; /** * Constructor of <code>AsyncReader</code>. For enclosing access. */ - public AsyncReader() { + public AsyncReader(boolean detectEncoding) { super(); + mDetectEncoding = detectEncoding; + if (mDetectEncoding) { + mDetector = new UniversalDetector(null); + } } /** @@ -298,6 +312,9 @@ public class EditorActivity extends Activity implements TextWatcher { if (!cancelled && StringHelper.isBinaryData(mByteBuffer.toByteArray())) { EditorActivity.this.mBinary = true; EditorActivity.this.mReadOnly = true; + } else if (mDetector != null) { + mDetector.dataEnd(); + mDetectedEncoding = mDetector.getDetectedCharset(); } } @@ -319,6 +336,9 @@ public class EditorActivity extends Activity implements TextWatcher { try { if (result == null) return; byte[] partial = (byte[]) result; + if (mDetectEncoding) { + mDetector.handleData(partial, 0, partial.length); + } this.mByteBuffer.write(partial, 0, partial.length); this.mSize += partial.length; if (this.mListener != null && this.mReadFso != null) { @@ -1087,7 +1107,7 @@ public class EditorActivity extends Activity implements TextWatcher { try { while (true) { // Configure the reader - this.mReader = new AsyncReader(); + this.mReader = new AsyncReader(true); this.mReader.mReadFso = fso; this.mReader.mListener = new OnProgressListener() { @Override @@ -1098,7 +1118,8 @@ public class EditorActivity extends Activity implements TextWatcher { }; // Execute the command (read the file) - CommandHelper.read(activity, fso.getFullPath(), this.mReader, null); + CommandHelper.read(activity, fso.getFullPath(), this.mReader, + null); // Wait for synchronized (this.mReader.mSync) { @@ -1132,7 +1153,13 @@ public class EditorActivity extends Activity implements TextWatcher { } Log.i(TAG, "Bytes read: " + data.length()); //$NON-NLS-1$ } else { - final String data = new String(this.mReader.mByteBuffer.toByteArray()); + String data; + if (this.mReader.mDetectedEncoding != null) { + data = new String(this.mReader.mByteBuffer.toByteArray(), + this.mReader.mDetectedEncoding); + } else { + data = new String(this.mReader.mByteBuffer.toByteArray()); + } this.mReader.mBuffer = new SpannableStringBuilder(data); Log.i(TAG, "Bytes read: " + data.getBytes().length); //$NON-NLS-1$ } diff --git a/src/com/cyanogenmod/filemanager/commands/shell/AsyncResultProgram.java b/src/com/cyanogenmod/filemanager/commands/shell/AsyncResultProgram.java index 7c0a6f78..a340b78f 100644 --- a/src/com/cyanogenmod/filemanager/commands/shell/AsyncResultProgram.java +++ b/src/com/cyanogenmod/filemanager/commands/shell/AsyncResultProgram.java @@ -47,7 +47,7 @@ public abstract class AsyncResultProgram /** * @hide */ - final List<String> mPartialData; + final List<byte[]> mPartialData; /** * @hide */ @@ -97,7 +97,7 @@ public abstract class AsyncResultProgram if (mAsyncResultListener instanceof ConcurrentAsyncResultListener) { ((ConcurrentAsyncResultListener) mAsyncResultListener).onRegister(); } - this.mPartialData = Collections.synchronizedList(new ArrayList<String>()); + this.mPartialData = Collections.synchronizedList(new ArrayList<byte[]>()); this.mPartialDataType = Collections.synchronizedList(new ArrayList<Byte>()); this.mTempBuffer = new StringBuffer(); this.mOnCancelListener = null; @@ -169,12 +169,12 @@ public abstract class AsyncResultProgram /** * Method that parse the result of a program invocation. * - * @param partialIn A partial standard input buffer (incremental buffer) + * @param input A partial standard input buffer (incremental buffer) * @hide */ - public final void onRequestParsePartialResult(String partialIn) { + public final void onRequestParsePartialResult(byte[] input) { + String partialIn = new String(input); synchronized (this.mSync) { - String data = partialIn; String rest = ""; //$NON-NLS-1$ if (parseOnlyCompleteLines()) { int pos = partialIn.lastIndexOf(FileHelper.NEWLINE); @@ -185,12 +185,11 @@ public abstract class AsyncResultProgram } //Retrieve the data - data = this.mTempBuffer.append(partialIn.substring(0, pos + 1)).toString(); rest = partialIn.substring(pos + 1); } this.mPartialDataType.add(STDIN); - this.mPartialData.add(data); + this.mPartialData.add(input); this.mTempBuffer = new StringBuffer(rest); this.mSync.notify(); } @@ -220,7 +219,7 @@ public abstract class AsyncResultProgram } this.mPartialDataType.add(STDERR); - this.mPartialData.add(data); + this.mPartialData.add(data.getBytes()); this.mTempBuffer = new StringBuffer(rest); this.mSync.notify(); } @@ -381,7 +380,7 @@ public abstract class AsyncResultProgram AsyncResultProgram.this.mSync.wait(); while (AsyncResultProgram.this.mPartialData.size() > 0) { Byte type = AsyncResultProgram.this.mPartialDataType.remove(0); - String data = AsyncResultProgram.this.mPartialData.remove(0); + byte[] data = AsyncResultProgram.this.mPartialData.remove(0); try { if (type.compareTo(STDIN) == 0) { AsyncResultProgram.this.onParsePartialResult(data); diff --git a/src/com/cyanogenmod/filemanager/commands/shell/AsyncResultProgramListener.java b/src/com/cyanogenmod/filemanager/commands/shell/AsyncResultProgramListener.java index 158023c3..11622ff3 100644 --- a/src/com/cyanogenmod/filemanager/commands/shell/AsyncResultProgramListener.java +++ b/src/com/cyanogenmod/filemanager/commands/shell/AsyncResultProgramListener.java @@ -48,12 +48,12 @@ public interface AsyncResultProgramListener { * * @param partialIn A partial standard input buffer (incremental buffer) */ - void onParsePartialResult(String partialIn); + void onParsePartialResult(byte[] partialIn); /** * Method invoked when a parse of new error results are needed. * * @param partialErr A partial standard err buffer (incremental buffer) */ - void onParseErrorPartialResult(String partialErr); + void onParseErrorPartialResult(byte[] partialErr); } diff --git a/src/com/cyanogenmod/filemanager/commands/shell/ChecksumCommand.java b/src/com/cyanogenmod/filemanager/commands/shell/ChecksumCommand.java index 97fbea39..7b37815c 100644 --- a/src/com/cyanogenmod/filemanager/commands/shell/ChecksumCommand.java +++ b/src/com/cyanogenmod/filemanager/commands/shell/ChecksumCommand.java @@ -89,8 +89,9 @@ public class ChecksumCommand extends AsyncResultProgram implements ChecksumExecu * {@inheritDoc} */ @Override - public void onParsePartialResult(final String partialIn) { - if (partialIn == null || partialIn.length() ==0) return; + public void onParsePartialResult(final byte[] in) { + String partialIn = new String(in); + if (partialIn == null || partialIn.length() == 0) return; boolean endsWithNewLine = partialIn.endsWith("\n"); //$NON-NLS-1$ String[] lines = partialIn.split("\n"); //$NON-NLS-1$ @@ -98,7 +99,7 @@ public class ChecksumCommand extends AsyncResultProgram implements ChecksumExecu lines[0] = this.mPartial + lines[0]; // Return all the lines, except the last - for (int i = 0; i < lines.length-1; i++) { + for (int i = 0; i < lines.length - 1; i++) { if (getAsyncResultListener() != null) { String data = processPartialResult(lines[i]); if (data != null) { @@ -110,7 +111,7 @@ public class ChecksumCommand extends AsyncResultProgram implements ChecksumExecu // Return the last line? if (endsWithNewLine) { if (getAsyncResultListener() != null) { - String data = processPartialResult(lines[lines.length-1]); + String data = processPartialResult(lines[lines.length - 1]); if (data != null) { getAsyncResultListener().onPartialResult(data); } @@ -118,7 +119,7 @@ public class ChecksumCommand extends AsyncResultProgram implements ChecksumExecu this.mPartial = ""; //$NON-NLS-1$ } else { // Save the partial for next calls - this.mPartial = lines[lines.length-1]; + this.mPartial = lines[lines.length - 1]; } } @@ -126,7 +127,7 @@ public class ChecksumCommand extends AsyncResultProgram implements ChecksumExecu * {@inheritDoc} */ @Override - public void onParseErrorPartialResult(String partialErr) {/**NON BLOCK**/} + public void onParseErrorPartialResult(byte[] partialErr) {/**NON BLOCK**/} /** * {@inheritDoc} diff --git a/src/com/cyanogenmod/filemanager/commands/shell/CompressCommand.java b/src/com/cyanogenmod/filemanager/commands/shell/CompressCommand.java index 1659fa20..54e81315 100644 --- a/src/com/cyanogenmod/filemanager/commands/shell/CompressCommand.java +++ b/src/com/cyanogenmod/filemanager/commands/shell/CompressCommand.java @@ -202,7 +202,8 @@ public class CompressCommand extends AsyncResultProgram implements CompressExecu * {@inheritDoc} */ @Override - public void onParsePartialResult(final String partialIn) { + public void onParsePartialResult(final byte[] in) { + String partialIn = new String(in); if (partialIn == null || partialIn.length() ==0) return; boolean endsWithNewLine = partialIn.endsWith("\n"); //$NON-NLS-1$ String[] lines = partialIn.split("\n"); //$NON-NLS-1$ @@ -240,7 +241,7 @@ public class CompressCommand extends AsyncResultProgram implements CompressExecu * {@inheritDoc} */ @Override - public void onParseErrorPartialResult(String partialErr) {/**NON BLOCK**/} + public void onParseErrorPartialResult(byte[] partialErr) {/**NON BLOCK**/} /** * {@inheritDoc} diff --git a/src/com/cyanogenmod/filemanager/commands/shell/ExecCommand.java b/src/com/cyanogenmod/filemanager/commands/shell/ExecCommand.java index c66cef9f..82c4e28f 100644 --- a/src/com/cyanogenmod/filemanager/commands/shell/ExecCommand.java +++ b/src/com/cyanogenmod/filemanager/commands/shell/ExecCommand.java @@ -65,7 +65,8 @@ public class ExecCommand extends AsyncResultProgram implements ExecExecutable { * {@inheritDoc} */ @Override - public void onParsePartialResult(final String partialIn) { + public void onParsePartialResult(byte[] in) { + String partialIn = new String(in); //If a listener is defined, then send the partial result if (partialIn != null && partialIn.length() > 0) { if (getAsyncResultListener() != null) { @@ -78,7 +79,8 @@ public class ExecCommand extends AsyncResultProgram implements ExecExecutable { * {@inheritDoc} */ @Override - public void onParseErrorPartialResult(String partialErr) { + public void onParseErrorPartialResult(byte[] in) { + String partialErr = new String(in); //If a listener is defined, then send the partial result if (partialErr != null && partialErr.length() > 0) { if (getAsyncResultListener() != null) { diff --git a/src/com/cyanogenmod/filemanager/commands/shell/FindCommand.java b/src/com/cyanogenmod/filemanager/commands/shell/FindCommand.java index 4857a3e3..dfad941f 100644 --- a/src/com/cyanogenmod/filemanager/commands/shell/FindCommand.java +++ b/src/com/cyanogenmod/filemanager/commands/shell/FindCommand.java @@ -84,7 +84,8 @@ public class FindCommand extends AsyncResultProgram implements FindExecutable { * {@inheritDoc} */ @Override - public void onParsePartialResult(final String partialIn) { + public void onParsePartialResult(byte[] in) { + String partialIn = new String(in); // Check the in buffer to extract information final List<FileSystemObject> partialFiles = new ArrayList<FileSystemObject>(); @@ -144,7 +145,7 @@ public class FindCommand extends AsyncResultProgram implements FindExecutable { * {@inheritDoc} */ @Override - public void onParseErrorPartialResult(String partialErr) {/**NON BLOCK**/} + public void onParseErrorPartialResult(byte[] partialErr) {/**NON BLOCK**/} /** * {@inheritDoc} diff --git a/src/com/cyanogenmod/filemanager/commands/shell/FolderUsageCommand.java b/src/com/cyanogenmod/filemanager/commands/shell/FolderUsageCommand.java index 134a3e34..9fc6d1bd 100644 --- a/src/com/cyanogenmod/filemanager/commands/shell/FolderUsageCommand.java +++ b/src/com/cyanogenmod/filemanager/commands/shell/FolderUsageCommand.java @@ -90,7 +90,8 @@ public class FolderUsageCommand extends AsyncResultProgram implements FolderUsag * {@inheritDoc} */ @Override - public void onParsePartialResult(final String partialIn) { + public void onParsePartialResult(byte[] in) { + String partialIn = new String(in); // Check the in buffer to extract information BufferedReader br = null; @@ -224,7 +225,7 @@ public class FolderUsageCommand extends AsyncResultProgram implements FolderUsag * {@inheritDoc} */ @Override - public void onParseErrorPartialResult(String partialErr) {/**NON BLOCK**/} + public void onParseErrorPartialResult(byte[] partialErr) {/**NON BLOCK**/} /** * {@inheritDoc} diff --git a/src/com/cyanogenmod/filemanager/commands/shell/ReadCommand.java b/src/com/cyanogenmod/filemanager/commands/shell/ReadCommand.java index cd2232ba..c75f6a46 100644 --- a/src/com/cyanogenmod/filemanager/commands/shell/ReadCommand.java +++ b/src/com/cyanogenmod/filemanager/commands/shell/ReadCommand.java @@ -61,11 +61,11 @@ public class ReadCommand extends AsyncResultProgram implements ReadExecutable { * {@inheritDoc} */ @Override - public void onParsePartialResult(final String partialIn) { + public void onParsePartialResult(byte[] in) { //If a listener is defined, then send the partial result - if (partialIn != null && partialIn.length() > 0) { + if (in != null && in.length > 0) { if (getAsyncResultListener() != null) { - getAsyncResultListener().onPartialResult(partialIn.getBytes()); + getAsyncResultListener().onPartialResult(in); } } } @@ -74,7 +74,7 @@ public class ReadCommand extends AsyncResultProgram implements ReadExecutable { * {@inheritDoc} */ @Override - public void onParseErrorPartialResult(String partialErr) {/**NON BLOCK**/} + public void onParseErrorPartialResult(byte[] partialErr) {/**NON BLOCK**/} /** * {@inheritDoc} diff --git a/src/com/cyanogenmod/filemanager/commands/shell/UncompressCommand.java b/src/com/cyanogenmod/filemanager/commands/shell/UncompressCommand.java index 4e77fdc7..bf5450b2 100644 --- a/src/com/cyanogenmod/filemanager/commands/shell/UncompressCommand.java +++ b/src/com/cyanogenmod/filemanager/commands/shell/UncompressCommand.java @@ -191,7 +191,8 @@ public class UncompressCommand extends AsyncResultProgram implements UncompressE * {@inheritDoc} */ @Override - public void onParsePartialResult(final String partialIn) { + public void onParsePartialResult(byte[] in) { + String partialIn = new String(in); if (partialIn == null || partialIn.length() ==0) return; boolean endsWithNewLine = partialIn.endsWith("\n"); //$NON-NLS-1$ String[] lines = partialIn.split("\n"); //$NON-NLS-1$ @@ -228,7 +229,7 @@ public class UncompressCommand extends AsyncResultProgram implements UncompressE * {@inheritDoc} */ @Override - public void onParseErrorPartialResult(String partialErr) {/**NON BLOCK**/} + public void onParseErrorPartialResult(byte[] partialErr) {/**NON BLOCK**/} /** * {@inheritDoc} diff --git a/src/com/cyanogenmod/filemanager/commands/shell/WriteCommand.java b/src/com/cyanogenmod/filemanager/commands/shell/WriteCommand.java index 51c0800c..8ee8727e 100644 --- a/src/com/cyanogenmod/filemanager/commands/shell/WriteCommand.java +++ b/src/com/cyanogenmod/filemanager/commands/shell/WriteCommand.java @@ -128,13 +128,13 @@ public class WriteCommand extends AsyncResultProgram implements WriteExecutable * {@inheritDoc} */ @Override - public void onParsePartialResult(final String partialIn) {/**NON BLOCK**/} + public void onParsePartialResult(final byte[] partialIn) {/**NON BLOCK**/} /** * {@inheritDoc} */ @Override - public void onParseErrorPartialResult(String partialErr) {/**NON BLOCK**/} + public void onParseErrorPartialResult(byte[] partialErr) {/**NON BLOCK**/} /** * {@inheritDoc} diff --git a/src/com/cyanogenmod/filemanager/console/shell/ShellConsole.java b/src/com/cyanogenmod/filemanager/console/shell/ShellConsole.java index 7a1f5a9e..88006079 100644 --- a/src/com/cyanogenmod/filemanager/console/shell/ShellConsole.java +++ b/src/com/cyanogenmod/filemanager/console/shell/ShellConsole.java @@ -46,6 +46,7 @@ import com.cyanogenmod.filemanager.model.Identity; import com.cyanogenmod.filemanager.util.CommandHelper; import com.cyanogenmod.filemanager.util.FileHelper; +import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; @@ -118,11 +119,11 @@ public abstract class ShellConsole extends Console implements Program.ProgramLis /** * @hide */ - StringBuffer mSbIn = null; + ByteArrayOutputStream mSbIn = null; /** * @hide */ - StringBuffer mSbErr = null; + ByteArrayOutputStream mSbErr = null; private final SecureRandom mRandom; private String mStartControlPattern; @@ -151,8 +152,8 @@ public abstract class ShellConsole extends Console implements Program.ProgramLis this.mBufferSize = DEFAULT_BUFFER; //Restart the buffers - this.mSbIn = new StringBuffer(); - this.mSbErr = new StringBuffer(); + this.mSbIn = new ByteArrayOutputStream(); + this.mSbErr = new ByteArrayOutputStream(); //Generate an aleatory secure random generator try { @@ -472,12 +473,13 @@ public abstract class ShellConsole extends Console implements Program.ProgramLis //Saves the active command reference this.mActiveCommand = program; + final boolean async = program instanceof AsyncResultProgram; //Reset the buffers this.mStarted = false; this.mCancelled = false; - this.mSbIn = new StringBuffer(); - this.mSbErr = new StringBuffer(); + this.mSbIn = new ByteArrayOutputStream(); + this.mSbErr = new ByteArrayOutputStream(); //Random start/end identifiers String startId1 = @@ -505,7 +507,7 @@ public abstract class ShellConsole extends Console implements Program.ProgramLis //Is asynchronous program? Then set asynchronous program.setProgramListener(this); - if (program instanceof AsyncResultProgram) { + if (async) { ((AsyncResultProgram)program).setOnCancelListener(this); ((AsyncResultProgram)program).setOnEndListener(this); } @@ -582,15 +584,15 @@ public abstract class ShellConsole extends Console implements Program.ProgramLis } //End partial results? - if (program instanceof AsyncResultProgram) { + if (async) { synchronized (this.mPartialSync) { ((AsyncResultProgram)program).onRequestEndParsePartialResult(this.mCancelled); } } //Retrieve exit code - int exitCode = getExitCode(this.mSbIn); - if (program instanceof AsyncResultProgram) { + int exitCode = getExitCode(this.mSbIn, async); + if (async) { synchronized (this.mPartialSync) { ((AsyncResultProgram)program).onRequestExitCode(exitCode); } @@ -674,7 +676,7 @@ public abstract class ShellConsole extends Console implements Program.ProgramLis public void run() { final ShellConsole shell = ShellConsole.this; int read = 0; - StringBuffer sb = null; + ByteArrayOutputStream sb = null; try { while (shell.mActive) { //Read only one byte with active wait @@ -688,27 +690,30 @@ public abstract class ShellConsole extends Console implements Program.ProgramLis shell.mActiveCommand != null && shell.mActiveCommand instanceof AsyncResultProgram; if (!async || sb == null) { - sb = new StringBuffer(); + sb = new ByteArrayOutputStream(); } if (!shell.mCancelled) { - shell.mSbIn.append((char)r); + shell.mSbIn.write(r); if (!shell.mStarted) { shell.mStarted = isCommandStarted(shell.mSbIn); if (shell.mStarted) { - sb = new StringBuffer(shell.mSbIn.toString()); + byte[] bytes = shell.mSbIn.toByteArray(); + sb = new ByteArrayOutputStream(); + sb.write(bytes, 0, bytes.length); if (async) { synchronized (shell.mPartialSync) { ((AsyncResultProgram) shell.mActiveCommand). - onRequestStartParsePartialResult(); + onRequestStartParsePartialResult(); } } } else { - sb.append(shell.mSbIn.toString()); + byte[] data = shell.mSbIn.toByteArray(); + sb.write(data, 0, data.length); } } else { - sb.append((char)r); + sb.write(r); } // New data received @@ -724,11 +729,11 @@ public abstract class ShellConsole extends Console implements Program.ProgramLis String partial = sb.toString(); int cc = shell.mEndControlPattern.length(); if (partial.length() >= cc) { - program.onRequestParsePartialResult(partial); + program.onRequestParsePartialResult(sb.toByteArray()); shell.toStdIn(partial); // Reset the temp buffer - sb = new StringBuffer(); + sb = new ByteArrayOutputStream(); } } @@ -740,7 +745,7 @@ public abstract class ShellConsole extends Console implements Program.ProgramLis ((AsyncResultProgram)shell.mActiveCommand); String partial = sb.toString(); if (program != null) { - program.onRequestParsePartialResult(partial); + program.onRequestParsePartialResult(sb.toByteArray()); } shell.toStdIn(partial); } @@ -773,11 +778,13 @@ public abstract class ShellConsole extends Console implements Program.ProgramLis if (shell.mCancelled) continue; final String s = new String(data, 0, read); - shell.mSbIn.append(s); + shell.mSbIn.write(data, 0, read); if (!shell.mStarted) { shell.mStarted = isCommandStarted(shell.mSbIn); if (shell.mStarted) { - sb = new StringBuffer(shell.mSbIn.toString()); + byte[] bytes = shell.mSbIn.toByteArray(); + sb = new ByteArrayOutputStream(); + sb.write(bytes, 0, bytes.length); if (async) { synchronized (shell.mPartialSync) { AsyncResultProgram p = @@ -788,10 +795,11 @@ public abstract class ShellConsole extends Console implements Program.ProgramLis } } } else { - sb.append(shell.mSbIn.toString()); + byte[] bytes = shell.mSbIn.toByteArray(); + sb.write(bytes, 0, bytes.length); } } else { - sb.append(s); + sb.write(data, 0, read); } // New data received @@ -807,12 +815,12 @@ public abstract class ShellConsole extends Console implements Program.ProgramLis int cc = shell.mEndControlPattern.length(); if (partial.length() >= cc) { if (program != null) { - program.onRequestParsePartialResult(partial); + program.onRequestParsePartialResult(sb.toByteArray()); } shell.toStdIn(partial); // Reset the temp buffer - sb = new StringBuffer(); + sb = new ByteArrayOutputStream(); } } @@ -824,7 +832,7 @@ public abstract class ShellConsole extends Console implements Program.ProgramLis ((AsyncResultProgram)shell.mActiveCommand); String partial = sb.toString(); if (program != null) { - program.onRequestParsePartialResult(partial); + program.onRequestParsePartialResult(sb.toByteArray()); } shell.toStdIn(partial); } @@ -910,10 +918,10 @@ public abstract class ShellConsole extends Console implements Program.ProgramLis shell.mActiveCommand != null && shell.mActiveCommand instanceof AsyncResultProgram; - StringBuffer sb = new StringBuffer(); + ByteArrayOutputStream sb = new ByteArrayOutputStream(); if (!shell.mCancelled) { - shell.mSbErr.append((char)r); - sb.append((char)r); + shell.mSbErr.write(r); + sb.write(r); //Notify asynchronous partial data if (shell.mStarted && async) { @@ -946,8 +954,8 @@ public abstract class ShellConsole extends Console implements Program.ProgramLis // Add to stderr String s = new String(data, 0, read); - shell.mSbErr.append(s); - sb.append(s); + shell.mSbErr.write(data, 0, read); + sb.write(data, 0, read); //Notify asynchronous partial data if (async) { @@ -1091,12 +1099,15 @@ public abstract class ShellConsole extends Console implements Program.ProgramLis * @return boolean If the command has started * @hide */ - boolean isCommandStarted(StringBuffer stdin) { + boolean isCommandStarted(ByteArrayOutputStream stdin) { if (stdin == null) return false; + final String str = stdin.toString(); Pattern pattern = Pattern.compile(this.mStartControlPattern); - Matcher matcher = pattern.matcher(stdin.toString()); + Matcher matcher = pattern.matcher(str); + byte[] data = stdin.toByteArray(); if (matcher.find()) { - stdin.replace(0, matcher.end(), ""); //$NON-NLS-1$ + stdin.reset(); + stdin.write(data, matcher.end(), data.length - matcher.end()); return true; } return false; @@ -1110,7 +1121,7 @@ public abstract class ShellConsole extends Console implements Program.ProgramLis * @return boolean If the command has finished * @hide */ - boolean isCommandFinished(StringBuffer stdin, StringBuffer partial) { + boolean isCommandFinished(ByteArrayOutputStream stdin, ByteArrayOutputStream partial) { Pattern pattern = Pattern.compile(this.mEndControlPattern); if (stdin == null) return false; Matcher matcher = pattern.matcher(stdin.toString()); @@ -1119,7 +1130,9 @@ public abstract class ShellConsole extends Console implements Program.ProgramLis if (ret && partial != null) { matcher = pattern.matcher(partial.toString()); if (matcher.find()) { - partial.replace(matcher.start(), matcher.end(), ""); //$NON-NLS-1$ + byte[] data = partial.toByteArray(); + partial.reset(); + partial.write(data, 0, matcher.start()); } } return ret; @@ -1141,7 +1154,7 @@ public abstract class ShellConsole extends Console implements Program.ProgramLis * @param stdin The standard in buffer * @return int The exit code of the last executed command */ - private int getExitCode(StringBuffer stdin) { + private int getExitCode(ByteArrayOutputStream stdin, boolean async) { // If process was cancelled, don't expect a exit code. // Returns always 143 code if (this.mCancelled) { @@ -1149,11 +1162,14 @@ public abstract class ShellConsole extends Console implements Program.ProgramLis } // Parse the stdin seeking exit code pattern - String txt = stdin.toString(); Pattern pattern = Pattern.compile(this.mEndControlPattern); - Matcher matcher = pattern.matcher(txt); + Matcher matcher = pattern.matcher(stdin.toString()); if (matcher.find()) { - this.mSbIn = new StringBuffer(txt.substring(0, matcher.start())); + if (!async) { + byte[] data = stdin.toByteArray(); + mSbIn.reset(); + mSbIn.write(data, 0, matcher.start()); + } String exitTxt = matcher.group(); return Integer.parseInt( exitTxt.substring( @@ -1170,10 +1186,12 @@ public abstract class ShellConsole extends Console implements Program.ProgramLis * @param sb The buffer to trim * @hide */ - @SuppressWarnings("static-method") void trimBuffer(StringBuffer sb) { - final int bufferSize = 200; - if (sb.length() > bufferSize) { - sb.delete(0, sb.length() - bufferSize); + @SuppressWarnings("static-method") void trimBuffer(ByteArrayOutputStream sb) { + final int bufferSize = mEndControlPattern.length(); + if (sb.size() > bufferSize) { + byte[] data = sb.toByteArray(); + sb.reset(); + sb.write(data, data.length - bufferSize, bufferSize); } } |