Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • anders_blomdell/labcomm
  • klaren/labcomm
  • tommyo/labcomm
  • erikj/labcomm
  • sven/labcomm
5 results
Show changes
Showing
with 1010 additions and 168 deletions
package se.lth.control.labcomm;
public interface LabCommDispatcher {
public Class getSampleClass();
public String getName();
public byte[] getSignature();
public void decodeAndHandle(LabCommDecoder decoder,
LabCommHandler handler) throws Exception;
}
package se.lth.control.labcomm;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.OutputStream;
public class LabCommEncoderChannel implements LabCommEncoder {
private LabCommWriter writer;
private ByteArrayOutputStream bytes;
private DataOutputStream data;
private LabCommEncoderRegistry registry;
public LabCommEncoderChannel(LabCommWriter writer) {
this.writer = writer;
bytes = new ByteArrayOutputStream();
data = new DataOutputStream(bytes);
registry = new LabCommEncoderRegistry();
}
public LabCommEncoderChannel(OutputStream writer) {
this(new WriterWrapper(writer));
}
public void register(LabCommDispatcher dispatcher) throws IOException {
int index = registry.add(dispatcher);
encodePacked32(LabComm.SAMPLE);
encodePacked32(index);
encodeString(dispatcher.getName());
byte[] signature = dispatcher.getSignature();
for (int i = 0 ; i < signature.length ; i++) {
encodeByte(signature[i]);
}
end(null);
}
public void begin(Class<? extends LabCommSample> c) throws IOException {
encodePacked32(registry.getTag(c));
}
public void end(Class<? extends LabCommSample> c) throws IOException {
data.flush();
//XXX when writer was a stream, it was probably a bit more GC efficient:
//bytes.writeTo(writer);
writer.write(bytes.toByteArray());
bytes.reset();
}
public void encodeBoolean(boolean value) throws IOException{
data.writeBoolean(value);
}
public void encodeByte(byte value) throws IOException {
data.writeByte(value);
}
public void encodeShort(short value) throws IOException {
data.writeShort(value);
}
public void encodeInt(int value) throws IOException {
data.writeInt(value);
}
public void encodeLong(long value) throws IOException {
data.writeLong(value);
}
public void encodeFloat(float value) throws IOException {
data.writeFloat(value);
}
public void encodeDouble(double value) throws IOException {
data.writeDouble(value);
}
public void encodeString(String value) throws IOException {
//data.writeShort(0); // HACK...
//data.writeUTF(value);
//kludge, to replace above hack with packed length
ByteArrayOutputStream tmpb = new ByteArrayOutputStream();
DataOutputStream tmps = new DataOutputStream(tmpb);
tmps.writeUTF(value);
tmps.flush();
byte[] tmp = tmpb.toByteArray();
encodePacked32(tmp.length-2);
for (int i = 2 ; i < tmp.length ; i++) {
encodeByte(tmp[i]);
}
}
public void encodePacked32(long value) throws IOException {
long tmp = value;
while( tmp >= 0x80 ) {
encodeByte( (byte) ((tmp & 0x7f) | 0x80 ) );
tmp >>>= 7;
}
encodeByte( (byte) (tmp & 0x7f) );
}
}
package se.lth.control.labcomm;
public interface LabCommHandler {
}
\ No newline at end of file
package se.lth.control.labcomm;
public interface LabCommSample {
}
\ No newline at end of file
package se.lth.control.labcomm;
public interface LabCommType {
}
\ No newline at end of file
package se.lth.control.labcomm2014;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.EOFException;
import se.lth.control.labcomm2014.compiler.LabComm;
import se.lth.control.labcomm2014.compiler.LabCommParser;
import se.lth.control.labcomm2014.compiler.List;
import se.lth.control.labcomm2014.compiler.Specification;
import se.lth.control.labcomm2014.compiler.Decl;
import se.lth.control.labcomm2014.compiler.TypeDecl;
import se.lth.control.labcomm2014.compiler.SampleDecl;
import se.lth.control.labcomm2014.compiler.TypeInstance;
import se.lth.control.labcomm2014.compiler.DataType;
import se.lth.control.labcomm2014.compiler.VoidType;
import se.lth.control.labcomm2014.compiler.PrimType;
import se.lth.control.labcomm2014.compiler.UserType;
import se.lth.control.labcomm2014.compiler.StructType;
import se.lth.control.labcomm2014.compiler.Field;
import se.lth.control.labcomm2014.compiler.ArrayType;
import se.lth.control.labcomm2014.compiler.VariableArrayType;
import se.lth.control.labcomm2014.compiler.FixedArrayType;
import se.lth.control.labcomm2014.compiler.Dim;
import se.lth.control.labcomm2014.compiler.Exp;
import se.lth.control.labcomm2014.compiler.IntegerLiteral;
import se.lth.control.labcomm2014.compiler.VariableSize;
/** A class for building a JastAdd AST from the parsed types
* created by a TypeDefParser. This class depends on the LabComm compiler.
*/
public class ASTbuilder implements SignatureSymbolVisitor {
private LinkedList<DataType> typeStack;
private LinkedList<Field> fieldStack;
public ASTbuilder() {
this.typeStack = new LinkedList<DataType>();
this.fieldStack = new LinkedList<Field>();
}
private void assertStacksEmpty() throws RuntimeException {
if(!typeStack.isEmpty()) {
throw new RuntimeException("Error: type stack not empty");
}
if(!fieldStack.isEmpty()) {
throw new RuntimeException("Error: field stack not empty");
}
}
public void visit(TypeSymbol s){
throw new Error("not implemented? needed?");
}
public void visit(SampleSymbol s){
throw new Error("not implemented? needed?");
}
public void visit(NameSymbol s){
throw new Error("not implemented? needed?");
}
public void visit(SigPrimitiveType t){
typeStack.push(new PrimType(t.getName(), t.getTag()));
}
// SampleRefs are currently represented as primitive types,
// see comment in TypeDefParser
// public void visit(TypeDefParser.SampleRefType t){
// typeStack.push(new SampleRefType());
// }
public void visit(SigStructType t){
if(t.isVoid()) {
typeStack.push(new VoidType());
} else {
List<Field> tmpF = new List<Field>();
for( SigField f : t.getFields()) {
f.accept(this);
tmpF.add(fieldStack.pop());
}
typeStack.push(new StructType(tmpF));
}
}
public void visit(SigField t){
t.getType().accept(this);
fieldStack.push(new Field(new TypeInstance(typeStack.pop(),t.getName())));
}
public void visit(SigArrayType t){
boolean isFixed = true;
List<Exp> dim = new List<Exp>();
for(int i : t.getIdx()) {
if(i == 0) {
dim.add(new VariableSize());
isFixed = false;
} else {
dim.add(new IntegerLiteral(Integer.toString(i)));
}
}
t.getType().accept(this);
if(isFixed) {
typeStack.push(new FixedArrayType(typeStack.pop(), new Dim(dim)));
} else {
typeStack.push(new VariableArrayType(typeStack.pop(), new Dim(dim)));
}
}
public void visit(SigUserType t){
typeStack.push(new UserType(t.getName()));
}
public Decl makeDecl(SigTypeDef d) {
d.getType().accept(this);
Decl result = new TypeDecl(new TypeInstance(typeStack.pop(), d.getName()));
return result;
}
private Specification createAndCheckSpecification(List<Decl> ds) {
Specification p = new Specification(ds);
LinkedList errors = new LinkedList();
p.errorCheck(errors);
if(errors.isEmpty()) {
return p;
} else {
// This should not happen
// get errors and throw exception
StringBuilder sb = new StringBuilder();
for (Iterator iter = errors.iterator(); iter.hasNext(); ) {
String s = (String)iter.next();
sb.append(s);
}
throw new RuntimeException("Internal error: parsed labcomm declaration has errors: "+sb.toString());
}
}
public Specification makeSpecification(SigTypeDef d) {
assertStacksEmpty();
List<Decl> ds = new List<Decl>();
ds.add(makeDecl(d));
assertStacksEmpty();
return createAndCheckSpecification(ds);
}
public Decl makeDecl(SigSampleDef d) {
d.getType().accept(this);
Decl result = new SampleDecl(new TypeInstance(typeStack.pop(), d.getName()));
return result;
}
private void addAllDeps(List<Decl> ds, SigTypeDef d) {
Iterator<SigTypeDef> it = d.getDepIterator();
while(it.hasNext()){
SigTypeDef dd = it.next();
addAllDeps(ds,dd);
ds.add(makeDecl(dd));
}
}
public Specification makeSpecification(ParsedSampleDef d) {
assertStacksEmpty();
List<Decl> ds = new List<Decl>();
addAllDeps(ds, d);
ds.add(makeDecl(d));
assertStacksEmpty();
return createAndCheckSpecification(ds);
}
}
package se.lth.control.labcomm2014;
public interface BuiltinType extends SampleType{
}
package se.lth.control.labcomm;
package se.lth.control.labcomm2014;
public class LabComm {
public class Constant {
public static final String CURRENT_VERSION = "LabComm2014";
/*
* Allowed packet tags
*/
/*
* Predeclared aggregate type indices
*/
public static final int TYPEDEF = 0x01;
public static final int SAMPLE = 0x02;
public static final int VERSION = 0x01;
public static final int SAMPLE_DEF = 0x02;
public static final int SAMPLE_REF = 0x03;
public static final int TYPE_DEF = 0x04;
public static final int TYPE_BINDING = 0x05;
public static final int PRAGMA = 0x3f;
public static final int FIRST_USER_INDEX = 0x40; /* ..0xffffffff */
/*
* Predefined aggregate type indices
*/
public static final int ARRAY = 0x10;
public static final int STRUCT = 0x11;
......@@ -21,10 +35,12 @@ public class LabComm {
public static final int FLOAT = 0x25;
public static final int DOUBLE = 0x26;
public static final int STRING = 0x27;
public static final int SAMPLE = 0x28;
/*
* Start of
* Other predefined symbols
*/
public static final int FIRST_USER_INDEX = 0x60;
public static final int TYPE_BIND_SELF = 0x00;
}
package se.lth.control.labcomm2014;
import java.io.PrintStream;
import java.util.Iterator;
public abstract class DataType implements SignatureSymbol{
private final String name;
private final int typeTag;
public static String tagName(int typeTag) {
switch(typeTag) {
case Constant.BOOLEAN : return "boolean";
case Constant.BYTE : return "byte";
case Constant.SHORT : return "short";
case Constant.INT : return "int";
case Constant.LONG : return "long";
case Constant.FLOAT : return "float";
case Constant.DOUBLE : return "double";
case Constant.STRING : return "string";
case Constant.SAMPLE : return "sample";
}
throw new Error("not primitive type tag : " +Integer.toHexString(typeTag));
}
protected DataType(String name, int typeTag) {
this.name = name;
this.typeTag = typeTag;
}
// protected DataType(int typeTag) {
// this(tagName(typeTag), typeTag);
// }
//
public String getName() {
return name;
}
public int getTag() {
return typeTag;
}
public boolean isArray() {
return false;
}
public boolean isStruct(){
return false;
}
public boolean isUserType(){
return false;
}
public void addField(String name, DataType type) {
throw new Error("cannot add field to "+getClass().getSimpleName());
}
public final void print(PrintStream out) {
print(out, "");
}
public void print(PrintStream out, String indent) {
out.print(name);
}
private static void printDependencies(PrintStream out, SampleDispatcher sd, String indent) throws java.io.IOException {
Iterator<SampleDispatcher> it = sd.getDependencyIterator();
if(it.hasNext()) {
out.println(indent+"dependencies:");
}
while(it.hasNext()){
SampleDispatcher d = it.next();
printDataType(out, d, indent);
out.println(indent+"---");
}
}
public static void printDataType(PrintStream out, SampleDispatcher sd, String indent) throws java.io.IOException{
out.print(indent+"typedef ");
sd.getDataType().print(out,indent);
out.println(" "+sd.getName()+";");
printDependencies(out, sd, "...."+indent);
}
public static void printDataType(PrintStream out, SampleDispatcher sd) throws java.io.IOException{
printDataType(out, sd, "");
}
private static void printDependencies(PrintStream out, SigTypeDef td, String indent) throws java.io.IOException {
Iterator<SigTypeDef> it = td.getDepIterator();
if(it.hasNext()) {
out.println(indent+"dependencies:");
}
while(it.hasNext()){
SigTypeDef d = it.next();
printDataType(out, d, indent);
out.println(indent+"---");
}
}
public static void printDataType(PrintStream out, SigTypeDef d, String indent) throws java.io.IOException{
if(d==null) {
System.out.println("********* WARNING: printDataType(null)???");
return;
}
out.print(indent+d.defType()+" ");
d.getType().print(out,indent);
out.println(" "+d.getName()+";");
printDependencies(out, d, "...."+indent);
}
public static void printDataType(PrintStream out, SigTypeDef d) throws java.io.IOException{
printDataType(out, d, "");
}
}
package se.lth.control.labcomm;
package se.lth.control.labcomm2014;
import java.io.IOException;
public interface LabCommDecoder {
public interface Decoder {
public void register(LabCommDispatcher dispatcher,
LabCommHandler handler) throws IOException;
public void register(SampleDispatcher dispatcher,
SampleHandler handler) throws IOException;
public void registerSampleRef(SampleDispatcher dispatcher) throws IOException;
public boolean decodeBoolean() throws IOException;
public byte decodeByte() throws IOException;
public short decodeShort() throws IOException;
......@@ -15,5 +17,6 @@ public interface LabCommDecoder {
public double decodeDouble() throws IOException;
public String decodeString() throws IOException;
public int decodePacked32() throws IOException;
public Class decodeSampleRef() throws IOException;
}
package se.lth.control.labcomm2014;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.InputStream;
import java.io.IOException;
import java.io.EOFException;
public class DecoderChannel implements Decoder {
private DataInputStream in;
private DecoderRegistry def_registry = new DecoderRegistry();
private DecoderRegistry ref_registry = new DecoderRegistry();
public DecoderChannel(InputStream in) throws IOException {
this.in = new DataInputStream(in);
}
private byte[] decodeBytes() throws IOException {
int len = decodePacked32();
byte result[] = new byte[len];
for(int i=0; i<len; i++) {
result[i] = decodeByte();
}
return result;
}
private String decodeIntentions() throws IOException {
int numIntentions = decodePacked32();
String name = "";
for(int i = 0; i<numIntentions; i++) {
byte key[] = decodeBytes();
byte val[] = decodeBytes();
if(key.length == 0) {
name = new String(val);
}
}
return name;
}
private void processSampleDef() throws IOException {
int index = decodePacked32();
String name = decodeIntentions();
int signature_length = decodePacked32();
byte[] signature = new byte[signature_length];
ReadBytes(signature, signature_length);
def_registry.add(index, name, signature);
}
private void processSampleRef() throws IOException {
int index = decodePacked32();
String name = decodeIntentions();
int signature_length = decodePacked32();
byte[] signature = new byte[signature_length];
ReadBytes(signature, signature_length);
ref_registry.add(index, name, signature);
}
private void processTypeDef(int len) throws IOException {
try {
processSample(Constant.TYPE_DEF);
} catch(Exception ex) {
int idx = decodePacked32();
String name = decodeIntentions();
int siglen = decodePacked32();
for(int i=0; i<siglen; i++) {
byte b = decodeByte();
}
}
}
private void processTypeBinding(int len) throws IOException {
try {
processSample(Constant.TYPE_BINDING);
} catch(Exception ex) {
for(int i=0; i<len; i++) {
decodeByte();
}
}
}
private void processPragma(int len) throws IOException {
for(int i=0; i<len; i++) {
decodeByte();
}
}
private void processSample(int tag) throws IOException {
DecoderRegistry.Entry e = def_registry.get(tag);
if (e == null) {
throw new IOException("Unhandled tag " + tag);
}
SampleDispatcher d = e.getDispatcher();
if (d == null) {
throw new IOException("No dispatcher for '" + e.getName() + "'");
}
SampleHandler h = e.getHandler();
if (h == null) {
throw new IOException("No handler for '" + e.getName() +"'");
}
try {
//XXX why does decodeAndHandle throw Exception and not IOException?
d.decodeAndHandle(this, h);
} catch (IOException ex) {
throw ex;
} catch (Exception ex) {
ex.printStackTrace();
}
}
public void runOne() throws Exception {
boolean done = false;
while (!done) {
int tag = decodePacked32();
int length = decodePacked32();
switch (tag) {
case Constant.VERSION: {
String version = decodeString();
if (! version.equals(Constant.CURRENT_VERSION)) {
throw new IOException("LabComm version mismatch " +
version + " != " + Constant.CURRENT_VERSION);
}
} break;
case Constant.SAMPLE_DEF: {
processSampleDef();
} break;
case Constant.SAMPLE_REF: {
processSampleRef();
} break;
case Constant.TYPE_DEF: {
processTypeDef(length);
} break;
case Constant.TYPE_BINDING: {
processTypeBinding(length);
} break;
case Constant.PRAGMA: {
processPragma(length);
} break;
default: {
processSample(tag);
done = true;
}
}
}
}
public void run() throws Exception {
while (true) {
runOne();
}
}
public void register(SampleDispatcher dispatcher,
SampleHandler handler) throws IOException {
def_registry.add(dispatcher, handler);
}
public void registerSampleRef(SampleDispatcher dispatcher) throws IOException {
ref_registry.add(dispatcher, null);
}
private void ReadBytes(byte[] result, int length) throws IOException {
int offset = 0;
while (offset < length) {
int count = in.read(result, offset, length - offset);
if (count <= 0) {
throw new EOFException(
"End of stream reached with " +
(length - offset) + " bytes left to read");
}
offset += count;
}
}
public boolean decodeBoolean() throws IOException {
return in.readBoolean();
}
public byte decodeByte() throws IOException {
return in.readByte();
}
public short decodeShort() throws IOException {
return in.readShort();
}
public int decodeInt() throws IOException {
return in.readInt();
}
public long decodeLong() throws IOException {
return in.readLong();
}
public float decodeFloat() throws IOException {
return in.readFloat();
}
public double decodeDouble() throws IOException {
return in.readDouble();
}
public String decodeString() throws IOException {
//in.readShort(); // HACK
//return in.readUTF();
int len = decodePacked32() & 0xffffffff;
byte[] chars = new byte[len];
for(int i=0; i<len; i++) {
chars[i] = in.readByte();
}
return new String(chars);
}
public int decodePacked32() throws IOException {
long res=0;
byte i=0;
boolean cont=true;
do {
byte c = in.readByte();
res = (res << 7) | (c & 0x7f);
cont = (c & 0x80) != 0;
i++;
} while(cont);
return (int) (res & 0xffffffff);
}
public Class decodeSampleRef() throws IOException {
int index = in.readInt();
try {
DecoderRegistry.Entry e = ref_registry.get(index);
return e.getDispatcher().getSampleClass();
} catch (NullPointerException e) {
return null;
}
}
/* Package visible methods for use from TypeDefParser */
String getSampleName(int idx) {
DecoderRegistry.Entry e = def_registry.get(idx);
return e.getName();
}
byte[] getSampleSignature(int idx) {
DecoderRegistry.Entry e = def_registry.get(idx);
return e.getSignature();
}
}
package se.lth.control.labcomm;
package se.lth.control.labcomm2014;
import java.io.IOException;
import java.util.HashMap;
public class LabCommDecoderRegistry {
public class DecoderRegistry {
public static class Entry {
private LabCommDispatcher dispatcher;
private LabCommHandler handler;
private SampleDispatcher dispatcher;
private SampleHandler handler;
private int index;
private String name;
private byte[] signature;
public Entry(LabCommDispatcher dispatcher,
LabCommHandler handler) {
public Entry(SampleDispatcher dispatcher,
SampleHandler handler) {
this.dispatcher = dispatcher;
this.name = dispatcher.getName();
this.signature = dispatcher.getSignature();
......@@ -27,19 +27,19 @@ public class LabCommDecoderRegistry {
this.signature = signature;
}
public LabCommDispatcher getDispatcher() {
public SampleDispatcher getDispatcher() {
return dispatcher;
}
public void setDispatcher(LabCommDispatcher dispatcher) {
public void setDispatcher(SampleDispatcher dispatcher) {
this.dispatcher = dispatcher;
}
public LabCommHandler getHandler() {
public SampleHandler getHandler() {
return handler;
}
public void setHandler(LabCommHandler handler) {
public void setHandler(SampleHandler handler) {
this.handler = handler;
}
......@@ -51,6 +51,11 @@ public class LabCommDecoderRegistry {
return index;
}
// protected, for TypeDefParser...
byte[] getSignature() {
return signature;
}
public void setIndex(int index) throws IOException {
if (this.index != 0 && this.index != index) {
throw new IOException("Index mismatch " +
......@@ -89,13 +94,27 @@ public class LabCommDecoderRegistry {
private HashMap<Class, Entry> byClass;
private HashMap<Integer, Entry> byIndex;
public LabCommDecoderRegistry() {
public DecoderRegistry() {
byClass = new HashMap<Class, Entry>();
byIndex = new HashMap<Integer, Entry>();
}
public synchronized void add(LabCommDispatcher dispatcher,
LabCommHandler handler) throws IOException{
public synchronized void add(SampleDispatcher dispatcher,
SampleHandler handler) throws IOException{
//XXX kludge: special handling of predefined types
if(dispatcher.getSampleClass() == TypeDef.class){
Entry e = new Entry(dispatcher, handler);
e.setIndex(Constant.TYPE_DEF);
byClass.put(dispatcher.getSampleClass(), e);
byIndex.put(Integer.valueOf(Constant.TYPE_DEF), e);
//System.out.println("LCDecoderRegistry.add("+e.getName()+", "+e.getIndex()+")");
} else if(dispatcher.getSampleClass() == TypeBinding.class){
Entry e = new Entry(dispatcher, handler);
e.setIndex(Constant.TYPE_BINDING);
byClass.put(dispatcher.getSampleClass(), e);
byIndex.put(Integer.valueOf(Constant.TYPE_BINDING), e);
//System.out.println("LCDecoderRegistry.add("+e.getName()+", "+e.getIndex()+")");
} else {
Entry e = byClass.get(dispatcher.getSampleClass());
if (e != null) {
e.check(dispatcher.getName(), dispatcher.getSignature());
......@@ -114,6 +133,7 @@ public class LabCommDecoderRegistry {
byClass.put(dispatcher.getSampleClass(), e);
}
}
}
}
public synchronized void add(int index,
......@@ -141,4 +161,4 @@ public class LabCommDecoderRegistry {
return byIndex.get(Integer.valueOf(index));
}
}
\ No newline at end of file
}
package se.lth.control.labcomm;
package se.lth.control.labcomm2014;
import java.io.IOException;
public interface LabCommEncoder {
public interface Encoder {
public void register(SampleDispatcher dispatcher) throws IOException;
public void registerSampleRef(SampleDispatcher dispatcher) throws IOException;
public void begin(Class<? extends SampleType> c) throws IOException;
public void end(Class<? extends SampleType> c) throws IOException;
public void begin(int t) throws IOException;
public int getTypeId(Class<? extends SampleType> c) throws IOException;
public void register(LabCommDispatcher dispatcher) throws IOException;
public void begin(Class<? extends LabCommSample> c) throws IOException;
public void end(Class<? extends LabCommSample> c) throws IOException;
public void encodeBoolean(boolean value) throws IOException;
public void encodeByte(byte value) throws IOException;
public void encodeShort(short value) throws IOException;
......@@ -16,5 +21,6 @@ public interface LabCommEncoder {
public void encodeDouble(double value) throws IOException;
public void encodeString(String value) throws IOException;
public void encodePacked32(long value) throws IOException;
public void encodeSampleRef(Class value) throws IOException;
}
package se.lth.control.labcomm2014;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.OutputStream;
public class EncoderChannel implements Encoder {
private Writer writer;
private ByteArrayOutputStream bytes = new ByteArrayOutputStream();
private DataOutputStream data = new DataOutputStream(bytes);
private EncoderRegistry sample_def_registry = new EncoderRegistry();
private EncoderRegistry sample_ref_registry = new EncoderRegistry();
private EncoderRegistry type_def_registry = new EncoderRegistry();
private int current_tag;
private EncoderChannel(Writer writer, boolean emitVersion) throws IOException {
this.writer = writer;
if(emitVersion){
begin(Constant.VERSION);
encodeString(Constant.CURRENT_VERSION);
end(null);
}
}
public EncoderChannel(Writer writer) throws IOException {
this(writer, true);
}
public EncoderChannel(OutputStream writer) throws IOException {
this(new WriterWrapper(writer), true);
}
private EncoderChannel(OutputStream writer, boolean emitVersion) throws IOException {
this(new WriterWrapper(writer), emitVersion);
}
private void bindType(int sampleId, int typeId) throws IOException {
begin(Constant.TYPE_BINDING);
encodePacked32(sampleId);
encodePacked32(typeId);
end(null);
}
private void registerSample(SampleDispatcher dispatcher) throws IOException {
int index = sample_def_registry.add(dispatcher);
begin(dispatcher.getTypeDeclTag());
encodePacked32(index);
//HERE BE DRAGONS! numintentions does not include name
// encodePacked32(dispatcher.getNumIntentions()+1);
encodePacked32(1);
encodePacked32(0); // the empty key == name
encodeString(dispatcher.getName());
// byte[] intentions = dispatcher.getIntentionBytes();
// for (int k = 0 ; k < intentions.length ; k++) {
// encodeByte(intentions[k]);
// }
byte[] signature = dispatcher.getSignature();
encodePacked32(signature.length);
for (int i = 0 ; i < signature.length ; i++) {
encodeByte(signature[i]);
}
end(null);
int tindex;
if(dispatcher.hasDependencies()){
tindex = registerTypeDef(dispatcher);
} else {
tindex = Constant.TYPE_BIND_SELF;
}
bindType(index, tindex);
}
private static class WrappedEncoder extends EncoderChannel{
private Encoder wrapped;
public WrappedEncoder(Encoder e, OutputStream s, boolean emitVersion) throws IOException {
super(s,emitVersion);
this.wrapped = e;
}
public int getTypeId(Class<? extends SampleType> c) throws IOException{
return wrapped.getTypeId(c);
}
}
private int registerTypeDef(SampleDispatcher dispatcher) throws IOException {
// check if already registered
try {
return type_def_registry.getTag(dispatcher);
} catch (IOException e) {
//otherwise, add to the registry
int index = type_def_registry.add(dispatcher);
//wrap encoder to get encoded length of signature
ByteArrayOutputStream baos = new ByteArrayOutputStream();
EncoderChannel wrapped = new WrappedEncoder(this, baos, false);
dispatcher.encodeTypeDef(wrapped, index);
wrapped.flush();
byte b[] = baos.toByteArray();
begin(Constant.TYPE_DEF);
encodePacked32(index);
//HERE BE DRAGONS! numintentions does not include name
// encodePacked32(dispatcher.getNumIntentions()+1);
encodePacked32(1);
encodePacked32(0); // the empty key == name
encodeString(dispatcher.getName());
encodePacked32(b.length);
for(int i = 0; i<b.length; i++) {
encodeByte(b[i]);
}
end(null);
return index;
}
}
public void register(SampleDispatcher dispatcher) throws IOException {
switch (dispatcher.getTypeDeclTag()) {
case Constant.SAMPLE_DEF: {
registerSample(dispatcher);
break;
}
case Constant.TYPE_DEF: {
registerTypeDef(dispatcher);
break;
}
default:
throw new Error("Unknown typeDeclTag: "+dispatcher.getTypeDeclTag());
}
}
public void registerSampleRef(SampleDispatcher dispatcher) throws IOException {
System.err.println(dispatcher);
int index = sample_ref_registry.add(dispatcher);
begin(Constant.SAMPLE_REF);
encodePacked32(index);
//HERE BE DRAGONS! numintentions does not include name
// encodePacked32(dispatcher.getNumIntentions()+1);
encodePacked32(1);
encodePacked32(0); // the empty key == name
encodeString(dispatcher.getName());
byte[] signature = dispatcher.getSignature();
encodePacked32(signature.length);
for (int i = 0 ; i < signature.length ; i++) {
encodeByte(signature[i]);
}
end(null);
}
public void begin(int tag) {
current_tag = tag;
bytes.reset();
}
public void begin(Class<? extends SampleType> c) throws IOException {
begin(sample_def_registry.getTag(c));
}
/* aux. method used to allow nesting encoders to find encoded size */
private void flush() throws IOException{
data.flush();
writer.write(bytes.toByteArray());
bytes.reset();
}
public void end(Class<? extends SampleType> c) throws IOException {
data.flush();
WritePacked32(writer, current_tag);
WritePacked32(writer, bytes.size());
writer.write(bytes.toByteArray());
bytes.reset();
}
/**
* @return the id of a TYPE_DEF
*/
public int getTypeId(Class<? extends SampleType> c) throws IOException {
return type_def_registry.getTag(c);
}
private void WritePacked32(Writer s, long value) throws IOException {
byte[] tmp1 = new byte[5];
byte[] tmp2 = new byte[1];
long v = value & 0xffffffff;
int i;
for (i = 0 ; i == 0 || v != 0 ; i++, v = (v >> 7)) {
tmp1[i] = (byte)(v & 0x7f | (i!=0?0x80:0x00));
}
for (i = i - 1 ; i >= 0 ; i--) {
tmp2[0] = tmp1[i];
writer.write(tmp2);
}
}
public void encodeBoolean(boolean value) throws IOException{
data.writeBoolean(value);
}
public void encodeByte(byte value) throws IOException {
data.writeByte(value);
}
public void encodeShort(short value) throws IOException {
data.writeShort(value);
}
public void encodeInt(int value) throws IOException {
data.writeInt(value);
}
public void encodeLong(long value) throws IOException {
data.writeLong(value);
}
public void encodeFloat(float value) throws IOException {
data.writeFloat(value);
}
public void encodeDouble(double value) throws IOException {
data.writeDouble(value);
}
public void encodeString(String value) throws IOException {
ByteArrayOutputStream tmpb = new ByteArrayOutputStream();
DataOutputStream tmps = new DataOutputStream(tmpb);
tmps.writeUTF(value);
tmps.flush();
byte[] tmp = tmpb.toByteArray();
//the two first bytes written by writeUTF is the length of
//the string, so we skip those
encodePacked32(tmp.length-2);
for (int i = 2 ; i < tmp.length ; i++) {
encodeByte(tmp[i]);
}
}
public void encodePacked32(long value) throws IOException {
byte[] tmp = new byte[5];
long v = value & 0xffffffff;
int i;
for (i = 0 ; i == 0 || v != 0 ; i++, v = (v >> 7)) {
tmp[i] = (byte)(v & 0x7f);
}
for (i = i - 1 ; i >= 0 ; i--) {
encodeByte((byte)(tmp[i] | (i!=0?0x80:0x00)));
}
}
public void encodeSampleRef(Class value) throws IOException {
int index = 0;
try {
index = sample_ref_registry.getTag(value);
} catch (NullPointerException e) {
//we want to return 0 for unregistered ref types
}
data.writeInt(index);
}
}
package se.lth.control.labcomm;
package se.lth.control.labcomm2014;
import java.io.IOException;
import java.util.HashMap;
public class LabCommEncoderRegistry {
public class EncoderRegistry {
public static class Entry {
private LabCommDispatcher dispatcher;
private SampleDispatcher dispatcher;
private int index;
public Entry(LabCommDispatcher dispatcher, int index) {
public Entry(SampleDispatcher dispatcher, int index) {
this.dispatcher = dispatcher;
this.index = index;
}
public LabCommDispatcher getDispatcher() {
public SampleDispatcher getDispatcher() {
return dispatcher;
}
......@@ -25,14 +25,14 @@ public class LabCommEncoderRegistry {
}
private int userIndex = LabComm.FIRST_USER_INDEX;
private int userIndex = Constant.FIRST_USER_INDEX;
private HashMap<Class, Entry> byClass;
public LabCommEncoderRegistry() {
public EncoderRegistry() {
byClass = new HashMap<Class, Entry>();
}
public synchronized int add(LabCommDispatcher dispatcher) {
public synchronized int add(SampleDispatcher dispatcher) {
Entry e = byClass.get(dispatcher.getSampleClass());
if (e == null) {
e = new Entry(dispatcher, userIndex);
......@@ -42,7 +42,11 @@ public class LabCommEncoderRegistry {
return e.getIndex();
}
public int getTag(Class<? extends LabCommSample> sample) throws IOException {
public int getTag(SampleDispatcher d) throws IOException {
return getTag(d.getSampleClass());
}
public int getTag(Class<? extends SampleType> sample) throws IOException {
Entry e = byClass.get(sample);
if (e == null) {
throw new IOException("'" +
......@@ -52,4 +56,8 @@ public class LabCommEncoderRegistry {
return e.index;
}
}
\ No newline at end of file
public boolean contains(Class<? extends SampleType> sample) {
return byClass.containsKey(sample);
}
}
package se.lth.control.labcomm2014;
public class NameSymbol implements SignatureSymbol {
private String name;
public NameSymbol(String name) {
this.name = name;
}
public String toString() {
return name;
}
public void accept(SignatureSymbolVisitor v){
v.visit(this);
}
}
package se.lth.control.labcomm2014;
public class ParsedSampleDef extends ParsedTypeDef{
int idx;
ParsedSampleDef(ParsedTypeDef td) {
super(td);
}
@Override
public boolean isSampleDef() {
return true;
}
public String defType() {
return "sample";
}
}
package se.lth.control.labcomm2014;
public class ParsedTypeDef extends SigTypeDef{
private int idx;
ParsedTypeDef(int idx, String name){
super(name);
this.idx = idx;
}
ParsedTypeDef(int idx, String name, DataType type) {
super(name, type);
this.idx = idx;
}
ParsedTypeDef(ParsedTypeDef td) {
super(td);
this.idx = td.getIndex();
}
int getIndex() {
return idx;
}
}
package se.lth.control.labcomm;
package se.lth.control.labcomm2014;
public interface LabCommReader {
public interface Reader {
public void handle(byte[] data, int begin, int end);
......
package se.lth.control.labcomm2014;
public interface Sample extends SampleType {
public SampleDispatcher getDispatcher();
}