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:
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