This is a read-only archive of the old Scratch 1.x Forums.
Try searching the current Scratch discussion forums.

#1 2012-08-21 14:24:23

TheSuccessor
Scratcher
Registered: 2010-04-23
Posts: 1000+

ScratchInputStream and ScratchOutputStream

So, there's existing and fairly widely used code for mesh communication with Python. I'm not aware of any such Java code, however, so I wrote these two classes.

ScratchInputStream.java:

Code:

import java.io.FilterInputStream;
import java.io.IOException;
import java.io.InputStream;

public class ScratchInputStream extends FilterInputStream {

    private int remaining;

    public ScratchInputStream(InputStream in){
        super(in);
        remaining = 0;
    }

    public int read() throws IOException {
        byte[] data = new byte[1];
        int read;
        while((read = read(data)) == 0);
        if(read == -1) return -1;
        return data[0] & 0xff;
    }

    public String nextMessage() throws IOException {
        return new String(readFull());
    }

    public byte[] readFull() throws IOException {
        int size = readSizeField();
        if(size == -1) return null;
        byte[] data = new byte[size];
        int off = 0;
        while(true){
            int read = in.read(data, off, size - off);
            if(read == -1) return null;
            off += read;
            if(off < size) continue;
            return data;
        }
    }

    public int read(byte[] b, int off, int len) throws IOException {
        if(len <= 0) return 0;
        if(remaining > 0){
            int read = in.read(b, off, Math.min(len, remaining));
            remaining -= read;
            return read;
        }
        int size = readSizeField();
        if(size == -1) return -1;
        int read = in.read(b, off, Math.min(len, size));
        remaining = size - read;
        return read;
    }

    private int readSizeField() throws IOException {
        byte[] sizefield = new byte[4];
        int read = in.read(sizefield);
        if(read == -1) return -1;
        if(read < 4) throw new IOException("Failed to read size field!");
        return (sizefield[0] & 0xff) << 24 |
                (sizefield[1] & 0xff) << 16 |
                (sizefield[2] & 0xff) << 8 |
                (sizefield[3] & 0xff);
    }

    public long skip(long n){
        throw new UnsupportedOperationException();
    }

    public void mark(int readlimit){}
    public void reset(){}

    public boolean markSupported(){
        return false;
    }

}

ScratchOutputStream.java:

Code:

import java.io.FilterOutputStream;
import java.io.IOException;
import java.io.OutputStream;

public class ScratchOutputStream extends FilterOutputStream {

    public ScratchOutputStream(OutputStream out){
        super(out);
    }

    public void write(int b) throws IOException {
        write(new byte[]{(byte) (b & 0xff)});
    }

    public void write(byte[] b, int off, int len) throws IOException {
        out.write(new byte[]{
                (byte) ((len << 24) & 0xff),
                (byte) ((len << 16) & 0xff),
                (byte) ((len << 8) & 0xff),
                (byte) (len & 0xff),
        });
        out.write(b, off, len);
    }

    public void write(String s) throws IOException {
        write(s.getBytes());
    }

    public void broadcast(String s) throws IOException {
        write("broadcast \"" + s + "\"");
    }

    public void sensorUpdate(String name, Object value) throws IOException {
        write("sensor-update \"" + name + "\" " +
                ((value instanceof Number) ? value.toString() : "\"" + value.toString() + "\""));
    }

}

Assuming you already have a socket which is connected to Scratch, usage is something like the following:

Code:

try {
    in = new ScratchInputStream(sock.getInputStream());
    out = new ScratchOutputStream(sock.getOutputStream());

    out.sendMessage("broadcast \"test\""); //Or use out.broadcast("test")
    System.out.println(in.nextMessage()); //Blocks until enough data is available
} catch (IOException e) {
    e.printStackTrace();
}

Hopefully you'll find these useful!  smile


/* No comment */

Offline

 

#2 2012-08-21 15:16:01

MathWizz
Scratcher
Registered: 2009-08-31
Posts: 1000+

Re: ScratchInputStream and ScratchOutputStream

Ah! Very nice.  big_smile


http://block.site90.net/scratch.mit/text.php?size=30&amp;text=%20A%20signature!&amp;color=333333

Offline

 

#3 2012-08-21 15:31:25

TheSuccessor
Scratcher
Registered: 2010-04-23
Posts: 1000+

Re: ScratchInputStream and ScratchOutputStream

MathWizz wrote:

Ah! Very nice.  big_smile

Thanks  smile


/* No comment */

Offline

 

Board footer