Advertisement
Help Keep Boards Alive. Support us by going ad free today. See here: https://subscriptions.boards.ie/.
If we do not hit our goal we will be forced to close the site.

Current status: https://keepboardsalive.com/

Annual subs are best for most impact. If you are still undecided on going Ad Free - you can also donate using the Paypal Donate option. All contribution helps. Thank you.
https://www.boards.ie/group/1878-subscribers-forum

Private Group for paid up members of Boards.ie. Join the club.

Assign ByteInputStream to InputStream keeping bind to terminal emulator

  • 17-12-2012 11:04AM
    #1
    Moderators, Science, Health & Environment Moderators, Social & Fun Moderators, Society & Culture Moderators Posts: 60,119 Mod ✭✭✭✭


    I am trying to connect to a terminal emulator using a library in android, this will connect to a serial device and should show me sent/received data. To attach to a terminal session I need to provide an inputStream to setTermIn(InputStream) and an outputStream to setTermOut(OutputStream).

    I initialize and attach some streams like so in onCreate(), these are just initial streams and are not attached to the data I want to be sending/receiving.
    private OutputStream bos;
    private InputStream bis;
    
    ...
    
    byte[] a = new byte[4096];
    bis = new ByteArrayInputStream(a);
    bos = new ByteArrayOutputStream();
    session.setTermIn(bis);
    session.setTermOut(bos);
    /* Attach the TermSession to the EmulatorView. */
    mEmulatorView.attachSession(session);
    

    I now want to assign the streams to data as I send and receive data. In The sendData() method, which I call every time I press enter, I have:
    public void sendData(byte[] data)
    {
            bos = new ByteArrayOutputStream(data.length);         
    }
    

    and in the onReceiveData() method, called every time data is received over serial:
    public void onDataReceived(int id, byte[] data)
    {
            bis = new ByteArrayInputStream(data);           
    }
    

    However a ByteArrayInputStream can only ever have the data that was given to it, so it constantly needs to be created as data is sent and received. Now the problem is, I want this data to appear on the terminal, but when I assign bis to the data, it is no longer attached like it was when I called mEmulatorView.attachSession(session);

    Is there a way to update what bis is pointing to without breaking the bind that bis has to the terminal?


Comments

  • Closed Accounts Posts: 3,981 ✭✭✭[-0-]


    Unrelated, but why are you using a restricted byte array of 4096? What if the data sent or returned is larger than this?

    I wrote an application to SSH to remote hosts and run some greps - often returning lots of data.

    In order to handle this I use an InputStream and I just build a String based on the data returned.
    try{
        		session = connectionInfo.getSession();
        		if(!session.isConnected()) {session.connect();}
        		
        		   	ChannelExec channelExec = (ChannelExec) session.openChannel("exec");
    		    	channelExec.setPty(true);
    		    	//logger.info("command : "+command);
    		    	System.out.println("command : "+command);
    		    	channelExec.setCommand(command);
    		    	InputStream inputStream = channelExec.getInputStream();
    		    	channelExec.connect();
    		    	
    		    	while (channelExec.isClosed()!=true) {
    		
    		            try {
    		              output+=streamToString(inputStream);
    		
    		                } 
    		            catch (Exception e) {
    		              // TODO Auto-generated catch block
    		              e.printStackTrace();
    		             }
    		            
    		           
    		    	  }
    		    	
        			
    		   }
    
                       catch(Exception e){
    		    	
    		    	e.printStackTrace();
    		    	
    		    	}
    
    public static String streamToString(InputStream input)throws Exception 
        { 
        	String output = ""; 
        	while(input.available()>0) 
        	{ 
        		output += ((char)(input.read())); 
        	} 
        	return output; 
        }
    

    I'm sure you could do something similar when handling data returned from the command prompt.

    Off topic - but I hope it helps you when you get to that area of your code.


  • Moderators, Science, Health & Environment Moderators, Social & Fun Moderators, Society & Culture Moderators Posts: 60,119 Mod ✭✭✭✭Tar.Aldarion


    Thanks, I'll have a look through that! Will probably help later on. I set it to a random number at first as I was just initializing it, when i send and receive data a new stream is made of that size. There is no size to base it off when initializing it. A ByteArrayInputStream can only ever have the data you initialize it with.

    My problem is not as described in the OP as I thought I fixed that but the issue still happens. i probably fixed a problem that I have not gotten to yet! Here I can update the data by calling this class and don't have to make a new stream:

    import java.io.ByteArrayInputStream;
    import java.io.IOException;
    import java.io.InputStream;
    
    
    //Wrap the ByteArrayInputStream adding the functionality I need.
    public class MyBAIsWrapper extends InputStream{
    	
    	private ByteArrayInputStream wrapped;
    
    	   public MyBAIsWrapper(byte[] data) {
    	       wrapped=new ByteArrayInputStream(data);
    	   }
    
    	   //Method to refresh with new data
    	   public void renew(byte[] newData) {
    	       wrapped=new ByteArrayInputStream(newData);
    	   }
    
    	   //implement the InputStreamMethods calling the corresponding methods on wrapped
    	   public int read() throws IOException {
    	      return wrapped.read();
    	   }
    
    	   public int read(byte[] b) throws IOException {
    	       return wrapped.read(b);
    	   }
    
    	   //and so on
    
    }
    

    The original problem has something to do with setting the initial streams to the terminal, as I can not write anything to the screen even if I don't change the streams. The initial stream isn't working right.

    So below the terminal will come up with hello written in it, nothing else will be written.
    TermSession session = new TermSession();
    
            byte[] a = new byte[]{'h','e', 'l', 'l', 'o'};
            bis = new ByteArrayInputStream(a);
            bos = new ByteArrayOutputStream();
            session.write("testTWO");
            session.setTermIn(bis);
            session.setTermOut(bos);
            session.write("testONE");
    
            /* Attach the TermSession to the EmulatorView. */
            mEmulatorView.attachSession(session);
            mSession = session;
            try {
                bos.write(a);
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            session.write("test");
    


Advertisement