mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-07-26 02:15:31 +02:00
NEW - bug 224989: Support contributed services over Terminal connections
https://bugs.eclipse.org/bugs/show_bug.cgi?id=224989
This commit is contained in:
parent
b1a9596b9d
commit
c18cb2eaa9
2 changed files with 338 additions and 0 deletions
|
@ -0,0 +1,175 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2007 Wind River Systems, Inc. and others.
|
||||||
|
* All rights reserved. This program and the accompanying materials
|
||||||
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-v10.html
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* Michael Scharf (Wind River) - initial API and implementation
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.tm.internal.terminal.connector;
|
||||||
|
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
|
||||||
|
import junit.framework.TestCase;
|
||||||
|
|
||||||
|
public class TerminalToRemoteInjectionOutputStreamTest extends TestCase {
|
||||||
|
final static String ENCODING="UTF-8";
|
||||||
|
/**
|
||||||
|
* This class escapes strings coming on the original
|
||||||
|
* terminal..
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
class CleverInterceptor extends TerminalToRemoteInjectionOutputStream.Interceptor {
|
||||||
|
|
||||||
|
public void close() throws IOException {
|
||||||
|
}
|
||||||
|
public void write(int b) throws IOException {
|
||||||
|
fOriginal.write('[');
|
||||||
|
fOriginal.write(b);
|
||||||
|
fOriginal.write(']');
|
||||||
|
}
|
||||||
|
public void write(byte[] b, int off, int len) throws IOException {
|
||||||
|
fOriginal.write('[');
|
||||||
|
fOriginal.write(b,off,len);
|
||||||
|
fOriginal.write(']');
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
class NullInterceptor extends TerminalToRemoteInjectionOutputStream.Interceptor {
|
||||||
|
}
|
||||||
|
public void testClose() throws UnsupportedEncodingException, IOException {
|
||||||
|
ByteArrayOutputStream bs=new ByteArrayOutputStream();
|
||||||
|
TerminalToRemoteInjectionOutputStream s= new TerminalToRemoteInjectionOutputStream(bs);
|
||||||
|
s.write("begin:".getBytes(ENCODING));
|
||||||
|
assertEquals("begin:", new String(bs.toByteArray(),ENCODING));
|
||||||
|
OutputStream os1=s.grabOutput();
|
||||||
|
os1.write('x');
|
||||||
|
s.write('A');
|
||||||
|
os1.write('y');
|
||||||
|
s.write('B');
|
||||||
|
os1.close();
|
||||||
|
|
||||||
|
s.write('-');
|
||||||
|
OutputStream os=s.grabOutput();
|
||||||
|
// make sure the closed output does not inject anything
|
||||||
|
try {
|
||||||
|
os1.write('k');
|
||||||
|
fail("...");
|
||||||
|
} catch (Exception e) {
|
||||||
|
}
|
||||||
|
os.write('X');
|
||||||
|
s.write('a');
|
||||||
|
os.write('Y');
|
||||||
|
// make sure the closed output does not inject anything
|
||||||
|
try {
|
||||||
|
os1.write('l');
|
||||||
|
fail("...");
|
||||||
|
} catch (Exception e) {
|
||||||
|
}
|
||||||
|
s.write('b');
|
||||||
|
os.close();
|
||||||
|
assertEquals("begin:xyAB-XYab", new String(bs.toByteArray(),ENCODING));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testFlush() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testWriteInt() throws UnsupportedEncodingException, IOException {
|
||||||
|
ByteArrayOutputStream bs=new ByteArrayOutputStream();
|
||||||
|
TerminalToRemoteInjectionOutputStream s= new TerminalToRemoteInjectionOutputStream(bs);
|
||||||
|
s.write("begin:".getBytes(ENCODING));
|
||||||
|
assertEquals("begin:", new String(bs.toByteArray(),ENCODING));
|
||||||
|
OutputStream os=s.grabOutput();
|
||||||
|
os.write('x');
|
||||||
|
s.write('A');
|
||||||
|
os.write('y');
|
||||||
|
s.write('B');
|
||||||
|
s.close();
|
||||||
|
assertEquals("begin:xyAB", new String(bs.toByteArray(),ENCODING));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testWriteByteArray() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testWriteByteArrayIntInt() {
|
||||||
|
}
|
||||||
|
public void testGrabOutput() throws UnsupportedEncodingException, IOException {
|
||||||
|
ByteArrayOutputStream bs=new ByteArrayOutputStream();
|
||||||
|
TerminalToRemoteInjectionOutputStream s= new TerminalToRemoteInjectionOutputStream(bs);
|
||||||
|
s.write("begin:".getBytes(ENCODING));
|
||||||
|
assertEquals("begin:", new String(bs.toByteArray(),ENCODING));
|
||||||
|
OutputStream os1=s.grabOutput();
|
||||||
|
OutputStream os2;
|
||||||
|
try {
|
||||||
|
os2=s.grabOutput();
|
||||||
|
fail("should fail until the foirst output is closed");
|
||||||
|
} catch (IOException e) {
|
||||||
|
}
|
||||||
|
os1.close();
|
||||||
|
os2=s.grabOutput();
|
||||||
|
assertEquals("begin:", new String(bs.toByteArray(),ENCODING));
|
||||||
|
os2.write("Test".getBytes(ENCODING));
|
||||||
|
assertEquals("begin:Test", new String(bs.toByteArray(),ENCODING));
|
||||||
|
s.write(" west".getBytes(ENCODING));
|
||||||
|
assertEquals("begin:Test", new String(bs.toByteArray(),ENCODING));
|
||||||
|
os2.write(" the".getBytes(ENCODING));
|
||||||
|
assertEquals("begin:Test the", new String(bs.toByteArray(),ENCODING));
|
||||||
|
os2.close();
|
||||||
|
assertEquals("begin:Test the west", new String(bs.toByteArray(),ENCODING));
|
||||||
|
s.write('!');
|
||||||
|
assertEquals("begin:Test the west!", new String(bs.toByteArray(),ENCODING));
|
||||||
|
|
||||||
|
}
|
||||||
|
public void testGrabOutputWithCleverInterceptor() throws UnsupportedEncodingException, IOException {
|
||||||
|
ByteArrayOutputStream bs=new ByteArrayOutputStream();
|
||||||
|
TerminalToRemoteInjectionOutputStream s= new TerminalToRemoteInjectionOutputStream(bs);
|
||||||
|
s.write("begin:".getBytes(ENCODING));
|
||||||
|
assertEquals("begin:", new String(bs.toByteArray(),ENCODING));
|
||||||
|
// the injector escapes the output coming from the main stream
|
||||||
|
OutputStream os=s.grabOutput(new CleverInterceptor());
|
||||||
|
assertEquals("begin:", new String(bs.toByteArray(),ENCODING));
|
||||||
|
os.write("Test".getBytes(ENCODING));
|
||||||
|
assertEquals("begin:Test", new String(bs.toByteArray(),ENCODING));
|
||||||
|
s.write(" west".getBytes(ENCODING));
|
||||||
|
assertEquals("begin:Test[ west]", new String(bs.toByteArray(),ENCODING));
|
||||||
|
os.write(" the".getBytes(ENCODING));
|
||||||
|
assertEquals("begin:Test[ west] the", new String(bs.toByteArray(),ENCODING));
|
||||||
|
s.write('x');
|
||||||
|
assertEquals("begin:Test[ west] the[x]", new String(bs.toByteArray(),ENCODING));
|
||||||
|
os.close();
|
||||||
|
assertEquals("begin:Test[ west] the[x]", new String(bs.toByteArray(),ENCODING));
|
||||||
|
s.write('!');
|
||||||
|
assertEquals("begin:Test[ west] the[x]!", new String(bs.toByteArray(),ENCODING));
|
||||||
|
|
||||||
|
}
|
||||||
|
public void testGrabOutputWithNullInterceptor() throws UnsupportedEncodingException, IOException {
|
||||||
|
ByteArrayOutputStream bs=new ByteArrayOutputStream();
|
||||||
|
TerminalToRemoteInjectionOutputStream s= new TerminalToRemoteInjectionOutputStream(bs);
|
||||||
|
s.write("begin:".getBytes(ENCODING));
|
||||||
|
assertEquals("begin:", new String(bs.toByteArray(),ENCODING));
|
||||||
|
// bytes written to the main stream are ignored while the injector
|
||||||
|
// is active
|
||||||
|
OutputStream os=s.grabOutput(new NullInterceptor());
|
||||||
|
assertEquals("begin:", new String(bs.toByteArray(),ENCODING));
|
||||||
|
os.write("Test".getBytes(ENCODING));
|
||||||
|
assertEquals("begin:Test", new String(bs.toByteArray(),ENCODING));
|
||||||
|
s.write(" west".getBytes(ENCODING));
|
||||||
|
assertEquals("begin:Test", new String(bs.toByteArray(),ENCODING));
|
||||||
|
os.write(" the".getBytes(ENCODING));
|
||||||
|
assertEquals("begin:Test the", new String(bs.toByteArray(),ENCODING));
|
||||||
|
s.write('x');
|
||||||
|
assertEquals("begin:Test the", new String(bs.toByteArray(),ENCODING));
|
||||||
|
os.close();
|
||||||
|
assertEquals("begin:Test the", new String(bs.toByteArray(),ENCODING));
|
||||||
|
s.write('!');
|
||||||
|
assertEquals("begin:Test the!", new String(bs.toByteArray(),ENCODING));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,163 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2007 Wind River Systems, Inc. and others.
|
||||||
|
* All rights reserved. This program and the accompanying materials
|
||||||
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-v10.html
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* Michael Scharf (Wind River) - initial API and implementation
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.tm.internal.terminal.connector;
|
||||||
|
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.FilterOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
|
||||||
|
class TerminalToRemoteInjectionOutputStream extends FilterOutputStream {
|
||||||
|
/**
|
||||||
|
* This class handles bytes written to the {@link TerminalToRemoteInjectionOutputStream}.
|
||||||
|
*/
|
||||||
|
static abstract public class Interceptor {
|
||||||
|
protected OutputStream fOriginal;
|
||||||
|
/**
|
||||||
|
* @param original the injection into the original stream begins
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
public void begin(OutputStream original) throws IOException {
|
||||||
|
fOriginal=original;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @param b a byte was written to the {@link TerminalToRemoteInjectionOutputStream}.
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
public void write(int b) throws IOException {
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @param b bytes written to the {@link TerminalToRemoteInjectionOutputStream}.
|
||||||
|
* @param off the start offset in the data.
|
||||||
|
* @param len the number of bytes to write.
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
public void write(byte[] b, int off, int len) throws IOException {
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* The injection into the normal stream ends.
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
public void close() throws IOException {
|
||||||
|
}
|
||||||
|
public void flush() {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
static public class BufferInterceptor extends Interceptor {
|
||||||
|
private final ByteArrayOutputStream fBuffer=new ByteArrayOutputStream();
|
||||||
|
public void close() throws IOException {
|
||||||
|
fOriginal.write(fBuffer.toByteArray());
|
||||||
|
}
|
||||||
|
public void write(byte[] b, int off, int len) throws IOException {
|
||||||
|
fBuffer.write(b, off, len);
|
||||||
|
}
|
||||||
|
public void write(int b) throws IOException {
|
||||||
|
fBuffer.write(b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private class TerminalFilterOutputStream extends OutputStream {
|
||||||
|
final private Object fLock=TerminalToRemoteInjectionOutputStream.this;
|
||||||
|
public void close() throws IOException {
|
||||||
|
synchronized(fLock) {
|
||||||
|
if(fInjection==this) {
|
||||||
|
flush();
|
||||||
|
ungrabOutput();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public void write(byte[] b, int off, int len) throws IOException {
|
||||||
|
synchronized(fLock) {
|
||||||
|
checkStream();
|
||||||
|
out.write(b, off, len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public void write(byte[] b) throws IOException {
|
||||||
|
synchronized(fLock) {
|
||||||
|
checkStream();
|
||||||
|
out.write(b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public void flush() throws IOException {
|
||||||
|
synchronized(fLock) {
|
||||||
|
checkStream();
|
||||||
|
out.flush();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public void write(int b) throws IOException {
|
||||||
|
synchronized(fLock) {
|
||||||
|
checkStream();
|
||||||
|
out.write(b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private void checkStream() throws IOException {
|
||||||
|
if(fInjection!=this)
|
||||||
|
throw new IOException("Stream is closed"); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private Interceptor fInterceptor;
|
||||||
|
private TerminalFilterOutputStream fInjection;
|
||||||
|
public TerminalToRemoteInjectionOutputStream(OutputStream out) {
|
||||||
|
super(out);
|
||||||
|
}
|
||||||
|
synchronized protected void ungrabOutput() throws IOException {
|
||||||
|
if(fInterceptor!=null) {
|
||||||
|
fInterceptor.close();
|
||||||
|
fInterceptor=null;
|
||||||
|
fInjection=null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* There can only be one injection stream active at a time. You must call close on the
|
||||||
|
* returned output stream to end the injection.
|
||||||
|
* @param interceptor This is used handle bytes sent while the injection stream is active.
|
||||||
|
* @return a output stream that can be used to write to the decorated stream.
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
public synchronized OutputStream grabOutput(Interceptor interceptor) throws IOException {
|
||||||
|
if(fInjection!=null) {
|
||||||
|
throw new IOException("Buffer in use"); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
fInterceptor=interceptor;
|
||||||
|
fInterceptor.begin(out);
|
||||||
|
fInjection=new TerminalFilterOutputStream();
|
||||||
|
return fInjection;
|
||||||
|
}
|
||||||
|
/** See {@link #grabOutput(TerminalToRemoteInjectionOutputStream.Interceptor)}.
|
||||||
|
* @return injection output stream
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
public synchronized OutputStream grabOutput() throws IOException {
|
||||||
|
return grabOutput(new BufferInterceptor());
|
||||||
|
}
|
||||||
|
synchronized public void close() throws IOException {
|
||||||
|
if(fInjection!=null) {
|
||||||
|
fInjection.close();
|
||||||
|
}
|
||||||
|
super.close();
|
||||||
|
}
|
||||||
|
synchronized public void flush() throws IOException {
|
||||||
|
if(fInterceptor!=null)
|
||||||
|
fInterceptor.flush();
|
||||||
|
out.flush();
|
||||||
|
}
|
||||||
|
synchronized public void write(byte[] b, int off, int len) throws IOException {
|
||||||
|
if(fInterceptor!=null)
|
||||||
|
fInterceptor.write(b, off, len);
|
||||||
|
else
|
||||||
|
out.write(b, off, len);
|
||||||
|
}
|
||||||
|
synchronized public void write(int b) throws IOException {
|
||||||
|
if(fInterceptor!=null)
|
||||||
|
fInterceptor.write(b);
|
||||||
|
else
|
||||||
|
out.write(b);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue