package org.gscript.interop; import java.io.DataInputStream; import java.io.IOException; import java.io.InputStream; import java.nio.ByteBuffer; import java.nio.ByteOrder; import android.content.Intent; import android.net.Uri; import android.os.Bundle; public class InteropMessage { static final String LOG_TAG = "InteropMessage"; static final int ACTION_BYTES = 256; static final int DATA_BYTES = 512; static final int EXTRAS_BYTES = 4; static final int HEADER_SIZE = ACTION_BYTES + DATA_BYTES + EXTRAS_BYTES; static final int EXTRA_KEY_BYTES = 256; static final int EXTRA_TYPE_BYTES = 4; static final int EXTRA_SIZE_BYTES = 4; static final int EXTRA_SIZE = EXTRA_KEY_BYTES + EXTRA_TYPE_BYTES + EXTRA_SIZE_BYTES; static final int EXTRA_TYPE_INT = 0; static final int EXTRA_TYPE_STRING = 1; String action; String data; Bundle extras = new Bundle(); String bytesToString(byte[] bytes, int offset, int length) { for (int i = offset; i < (offset + length); ++i) { if (bytes[i] == 0) { return new String(bytes, offset, ((i) - offset)); } } return new String(bytes, offset, offset+length); } public InteropMessage(InputStream in) { ByteBuffer intBuffer = ByteBuffer.allocate(4); intBuffer.order(ByteOrder.nativeOrder()); DataInputStream dataInput = new DataInputStream(in); /* get header (action, data, extra_size) */ byte[] bytes = new byte[HEADER_SIZE]; try { dataInput.readFully(bytes, 0, HEADER_SIZE); } catch (IOException e) { return; } int offset = 0; action = bytesToString(bytes, offset, ACTION_BYTES); offset += ACTION_BYTES; data = bytesToString(bytes, offset, DATA_BYTES); intBuffer.put(bytes, HEADER_SIZE - 4, 4); int extrasCount = intBuffer.getInt(0); /* get extras */ byte[] extraBytes = new byte[EXTRA_SIZE]; for (int i = 0; i < extrasCount; ++i) { try { dataInput.readFully(extraBytes, 0, EXTRA_SIZE); } catch (IOException e) { return; } String extraKey = bytesToString(extraBytes, 0, EXTRA_KEY_BYTES); intBuffer.clear(); intBuffer.put(extraBytes, EXTRA_SIZE - 8, 4); int extraType = intBuffer.getInt(0); intBuffer.clear(); intBuffer.put(extraBytes, EXTRA_SIZE - 4, 4); /* get extra data */ int extraDataSize = intBuffer.getInt(0); byte[] extraData = new byte[extraDataSize]; try { dataInput.readFully(extraData, 0, extraDataSize); } catch (IOException e) { return; } switch (extraType) { case EXTRA_TYPE_INT: intBuffer.clear(); intBuffer.put(extraData, 0, 4); int intVal = intBuffer.getInt(0); extras.putInt(extraKey, intVal); break; case EXTRA_TYPE_STRING: String stringVal = bytesToString(extraData, 0, extraDataSize); extras.putString(extraKey, stringVal); break; } } } @Override public String toString() { return String.format("InteropMessage [ %s %s ]", action, data); } public Intent toIntent() { return new Intent(action).setData(Uri.parse(data)).putExtras(extras); } }