1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-02 14:45:25 +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:
Michael Scharf 2008-04-15 20:19:09 +00:00
parent b1a9596b9d
commit c18cb2eaa9
2 changed files with 338 additions and 0 deletions

View file

@ -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));
}
}

View file

@ -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);
}
}