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 2167 additions and 48 deletions
package se.lth.control.labcomm2014;
public class SigSampleDef extends SigTypeDef{
SigSampleDef(SigTypeDef td) {
super(td.getName(), td.getType());
}
@Override
public boolean isSampleDef() {
return true;
}
public String defType() {
return "sample";
}
}
package se.lth.control.labcomm2014;
import java.io.PrintStream;
import java.util.List;
import java.util.LinkedList;
import java.util.Iterator;
public class SigStructType extends DataType {
private List<SigField> fields;
SigStructType(int nSigFields) {
super("struct", Constant.STRUCT);
this.fields = new LinkedList<SigField>();
}
public SigStructType() {
this("struct");
}
protected SigStructType(String name) {
super(name, Constant.STRUCT);
this.fields = new LinkedList<SigField>();
}
public SigField[] getFields() {
return fields.toArray(new SigField[0]);
}
public Iterator<SigField> getFieldIterator() {
return fields.iterator();
}
public void addField(String name, DataType type) {
fields.add(new SigField(name, type));
}
public void addField(SigField f) {
fields.add(f);
}
public boolean isStruct() {
return true;
}
public boolean isVoid() {
return fields.size() == 0;
}
public String toString() {
if(isVoid()) { //void type is empty struct
return "void";
} else {
StringBuilder sb = new StringBuilder();
sb.append("struct {\n");
for(SigField f : fields) {
sb.append(f.toString());
sb.append(";\n");
}
sb.append("}");
return sb.toString();
}
}
public void accept(SignatureSymbolVisitor v) {
v.visit(this);
}
public void print(PrintStream out, String indent) {
out.println("struct {");
String newIndent=indent+" ";
out.print(newIndent);
Iterator<SigField> it = getFieldIterator();
while(it.hasNext()) {
it.next().print(out, newIndent);
if(it.hasNext()) {
out.print(newIndent);
}
}
out.print(indent+"}");
}
}
package se.lth.control.labcomm2014;
import java.util.HashSet;
import java.util.Iterator;
public class SigTypeDef{
private String name;
private DataType type;
protected HashSet<SigTypeDef> deps;
SigTypeDef(SigTypeDef td) {
this(td.getName(), td.getType());
this.deps = new HashSet<SigTypeDef>(td.deps);
}
SigTypeDef( String name){
this.name = name;
this.deps = new HashSet<SigTypeDef>();
}
SigTypeDef(String name, DataType type) {
this(name);
this.type = type;
}
void addDependency(SigTypeDef d) {
deps.add(d);
}
HashSet<SigTypeDef> getDependencies() {
return deps;
}
Iterator<SigTypeDef> getDepIterator() {
return deps.iterator();
}
/** To be overridden in SigSampleDef
*/
public boolean isSampleDef() {
return false;
}
public String defType() {
return "typedef";
}
void setType(DataType type) {
this.type = type;
}
public DataType getType() {
if(type==null) {
System.out.println("******** WARNING! SigTypeDef.getType returning null");
}
return type;
}
int getIndex() {
return 0;
}
public String getName() {
return name;
}
public String toString() {
return type.toString();
}
public int hashCode() {
return name.hashCode();
}
public boolean equals(Object o) {
if(! (o instanceof SigTypeDef)){
return false;
} else {
SigTypeDef other = (SigTypeDef) o;
return other.getIndex() == getIndex() && other.name.equals(name);
}
}
public void accept(SignatureSymbolVisitor v) {
type.accept(v);
}
}
package se.lth.control.labcomm2014;
public class SigUserType extends DataType {
public String toString() {
return getName();
}
public SigUserType(String name) {
super(name, 0);
}
public boolean isUserType() {
return true;
}
public void accept(SignatureSymbolVisitor v) {
v.visit(this);
}
}
package se.lth.control.labcomm2014;
public interface SignatureSymbol{
public void accept(SignatureSymbolVisitor v);
}
package se.lth.control.labcomm2014;
/* An interface for using Visitor pattern to traverse
* the type tree
*/
public interface SignatureSymbolVisitor {
void visit(TypeSymbol s);
void visit(SampleSymbol s);
void visit(NameSymbol s);
void visit(SigPrimitiveType t);
//sampleRefs are sent as primitive types
//Put this back if that is changed to SampleRefType
//void visit(SampleRefType t);
void visit(SigStructType t);
void visit(SigField t);
void visit(SigArrayType t);
void visit(SigUserType t);
}
package se.lth.control.labcomm2014;
import java.io.IOException;
import java.io.ByteArrayOutputStream;
import java.io.ByteArrayInputStream;
import java.util.Iterator;
import java.util.NoSuchElementException;
import se.lth.control.labcomm2014.Decoder;
import se.lth.control.labcomm2014.DecoderChannel;
import se.lth.control.labcomm2014.SampleDispatcher;
import se.lth.control.labcomm2014.SampleHandler;
public class TypeBinding implements BuiltinType {
private int sampleIndex;
private int typeIndex;
public TypeBinding(int sampleIndex, int typeIndex) {
this.sampleIndex = sampleIndex;
this.typeIndex = typeIndex;
}
public int getSampleIndex() {
return sampleIndex;
}
public int getTypeIndex() {
return typeIndex;
}
public boolean isSelfBinding() {
return typeIndex == Constant.TYPE_BIND_SELF;
}
public interface Handler extends SampleHandler {
public void handle_TypeBinding(TypeBinding value) throws Exception;
}
public static void register(Decoder d, Handler h) throws IOException {
d.register(Dispatcher.singleton(), h);
}
public static void register(Encoder e) throws IOException {
register(e,false);
}
public static void register(Encoder e, boolean sendMetaData) throws IOException {
throw new IOException("cannot send TypeDefs");
}
static class Dispatcher implements SampleDispatcher<TypeBinding> {
private static Dispatcher singleton;
public synchronized static Dispatcher singleton() {
if(singleton==null) singleton=new Dispatcher();
return singleton;
}
public Class<TypeBinding> getSampleClass() {
return TypeBinding.class;
}
public String getName() {
return "TypeBinding";
}
public byte getTypeDeclTag() {
throw new Error("Should not be called");
}
public boolean isSample() {
throw new Error("Should not be called");
}
public boolean hasStaticSignature() {
throw new Error("Should not be called");
}
public byte[] getSignature() {
return null; // not used for matching
}
public int getNumIntentions() {
return 0;
}
public byte[] getIntentionBytes() {
return null; // not used for matching
}
public void encodeTypeDef(Encoder e, int index) throws IOException{
throw new Error("Should not be called");
}
public void registerTypeDeps(Encoder e) throws IOException{
throw new Error("Should not be called");
}
public void decodeAndHandle(Decoder d,
SampleHandler h) throws Exception {
((Handler)h).handle_TypeBinding(TypeBinding.decode(d));
}
public boolean hasDependencies() {
return false;
}
public Iterator<SampleDispatcher> getDependencyIterator() {
return new Iterator<SampleDispatcher>() {
public boolean hasNext() {
return false;
}
public SampleDispatcher next() throws NoSuchElementException {
throw new NoSuchElementException();
}
public void remove() throws UnsupportedOperationException {
throw new UnsupportedOperationException();
}
};
}
public DataType getDataType() {
throw new Error("not implemented");
}
}
public static void encode(Encoder e, TypeBinding value) throws IOException {
throw new Error("Should not be called");
}
/* HERE BE DRAGONS!
* This exposes (and relies on the stability of) indices that are
* internal to a decoder.
*
* The SAMPLE_DEF and TYPE_DEF must already have been received for the
* indices to be known, so this can be changed to instead return
* references to the SampleDispactcher corresponding to the sample type
* and the matching TypeDef.
*
* Sketch:
*
* SampleDispatcher sd = d.getDispatcherForId(sampleIndex);
* TypeDef td = d.getTypeDefForId(typeIndex);
*
* return new TypeBinding(sd, td);
*
* assuming that the Decoder keeps a registry for TypeDefs
*/
public static TypeBinding decode(Decoder d) throws IOException {
TypeBinding result;
int sampleIndex = d.decodePacked32();
int typeIndex = d.decodePacked32();
result = new TypeBinding(sampleIndex, typeIndex);
return result;
}
}
package se.lth.control.labcomm2014;
import java.io.IOException;
import java.io.ByteArrayOutputStream;
import java.io.ByteArrayInputStream;
import java.util.Iterator;
import java.util.NoSuchElementException;
import se.lth.control.labcomm2014.Decoder;
import se.lth.control.labcomm2014.DecoderChannel;
import se.lth.control.labcomm2014.SampleDispatcher;
import se.lth.control.labcomm2014.SampleHandler;
public class TypeDef implements BuiltinType {
private int index;
private String name;
private byte signature[];
public int getIndex() {
return index;
}
public String getName() {
return name;
}
public String toString() {
return getName();
}
public byte[] getSignature() {
return signature;
}
public void dump() {
System.out.print("=== TypeDef "+getName()+"( "+Integer.toHexString(getIndex())+") : ");
for (byte b : signature) {
System.out.print(String.format("0x%02X ", b));
}
System.out.println();
}
public interface Handler extends SampleHandler {
public void handle_TypeDef(TypeDef value) throws Exception;
}
public static void register(Decoder d, Handler h) throws IOException {
d.register(Dispatcher.singleton(), h);
}
public static void register(Encoder e) throws IOException {
register(e,false);
}
public static void register(Encoder e, boolean sendMetaData) throws IOException {
throw new IOException("cannot send TypeDefs");
}
static class Dispatcher implements SampleDispatcher<TypeDef> {
private static Dispatcher singleton;
public synchronized static Dispatcher singleton() {
if(singleton==null) singleton=new Dispatcher();
return singleton;
}
public Class<TypeDef> getSampleClass() {
return TypeDef.class;
}
public String getName() {
return "TypeDef";
}
public byte getTypeDeclTag() {
throw new Error("Should not be called");
}
public boolean isSample() {
throw new Error("Should not be called");
}
public boolean hasStaticSignature() {
throw new Error("Should not be called");
}
/** return the flat signature. Intended use is on decoder side */
public byte[] getSignature() {
return null; // not used for matching
}
public int getNumIntentions() {
return 0;
}
public byte[] getIntentionBytes() {
return new byte[0];
}
public void encodeTypeDef(Encoder e, int index) throws IOException{
throw new Error("Should not be called");
}
public void registerTypeDeps(Encoder e) throws IOException{
throw new Error("Should not be called");
}
// public boolean canDecodeAndHandle() {
// return true;
// }
public void decodeAndHandle(Decoder d,
SampleHandler h) throws Exception {
((Handler)h).handle_TypeDef(TypeDef.decode(d));
}
public boolean hasDependencies() {
return false;
}
public Iterator<SampleDispatcher> getDependencyIterator() {
return new Iterator<SampleDispatcher>() {
public boolean hasNext() {
return false;
}
public SampleDispatcher next() throws NoSuchElementException {
throw new NoSuchElementException();
}
public void remove() throws UnsupportedOperationException {
throw new UnsupportedOperationException();
}
};
}
public DataType getDataType() {
throw new Error("not implemented");
}
}
public static void encode(Encoder e, TypeDef value) throws IOException {
throw new Error("Should not be called");
}
protected TypeDef() {
}
public TypeDef(int index, String name, byte sig[]) {
this.index = index;
this.name = name;
this.signature = sig;
}
public static TypeDef decode(Decoder d) throws IOException {
TypeDef result;
int index = d.decodePacked32();
int numIntentions = d.decodePacked32();
if(numIntentions != 1) {
System.out.println("WARNING: #intentions == "+numIntentions);
}
int keylen = d.decodePacked32();
if(keylen != 0) {
System.out.println("WARNING: keylen == "+keylen);
}
String name = d.decodeString();
int siglen= d.decodePacked32();
byte sig[] = new byte[siglen];
for(int i=0; i<siglen;i++){
sig[i] = d.decodeByte();
}
result = new TypeDef(index, name, sig);
return result;
}
}
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.Decoder;
import se.lth.control.labcomm2014.DecoderChannel;
import se.lth.control.labcomm2014.TypeDef;
import se.lth.control.labcomm2014.TypeBinding;
public class TypeDefParser implements TypeDef.Handler, TypeBinding.Handler {
static class SelfBinding extends TypeDef {
private int sampleIndex;
private Decoder decoder;
private byte[] dummy = new byte[0];
public String toString() {return "self";}
public String getName() {
if(decoder instanceof DecoderChannel) {
DecoderChannel dc = (DecoderChannel) decoder;
return dc.getSampleName(sampleIndex);
} else {
return "self";
}
}
public int getIndex() {return 0;}
public byte[] getSignature() {
if(decoder instanceof DecoderChannel) {
DecoderChannel dc = (DecoderChannel) decoder;
return dc.getSampleSignature(sampleIndex);
} else {
return dummy;
}
}
public SelfBinding(int sampleIndex, Decoder decoder) {
super();
this.sampleIndex = sampleIndex;
this.decoder = decoder;
}
}
public interface TypeDefListener {
void onTypeDef(SigTypeDef d);
}
private HashMap<Integer,TypeDef> typeDefs;
private HashMap<Integer,Integer> typeBindings;
private HashSet<TypeDefListener> listeners;
private LinkedList<ParsedSampleDef> sampleDefs;
private HashMap<Integer,ParsedTypeDef> pts;
private Decoder decoder;
protected TypeDefParser(Decoder d) {
this.decoder = d;
typeDefs = new HashMap<Integer,TypeDef>();
typeBindings = new HashMap<Integer,Integer>();
listeners = new HashSet<TypeDefListener>();
sampleDefs = new LinkedList<ParsedSampleDef>();
pts = new HashMap<Integer,ParsedTypeDef>();
}
public void addListener(TypeDefListener l) {
listeners.add(l);
}
public Iterator<ParsedSampleDef> sampleDefIterator() {
return sampleDefs.iterator();
}
public void handle_TypeDef(TypeDef d) throws java.io.IOException {
System.out.println("handle_TypeDef: "+d.getIndex());
typeDefs.put(d.getIndex(), d);
ParsedTypeDef td = parseSignatureTD(d);
pts.put(d.getIndex(), td);
}
public void handle_TypeBinding(TypeBinding d) throws java.io.IOException {
TypeDef td;
if(d.isSelfBinding()){
td = new SelfBinding(d.getSampleIndex(), decoder);
} else {
typeBindings.put(d.getSampleIndex(), d.getTypeIndex());
td = getTypeDefForIndex(d.getSampleIndex());
}
System.out.println("handle_TypeBinding: "+d.getSampleIndex());
ParsedSampleDef result = parseSignature(td);
sampleDefs.add(result);
Iterator<TypeDefListener> it = listeners.iterator();
while(it.hasNext()){
notifyListener(it.next(), result);
}
}
private void notifyListener(TypeDefListener l, ParsedTypeDef d) {
l.onTypeDef(d);
if(d instanceof ParsedSampleDef) {
for(SigTypeDef dep : ((ParsedSampleDef)d).getDependencies()) {
//do we want to change ParseTypeDef to have dependencies,
//and do recursion here?
//if so, do notifyListener(l, dep);
l.onTypeDef(dep);
}
}
}
private TypeDef getTypeDefForIndex(int sampleIndex) {
return typeDefs.get(typeBindings.get(sampleIndex));
}
/** Factory method for use by application programs:
* registers a TypeDefParser for handling TypeDef and TypeBinding
* on the Decoder d.
*
* @return a new TypeDefParser registered on d
*/
public static TypeDefParser registerTypeDefParser(Decoder d) throws java.io.IOException {
TypeDefParser res = new TypeDefParser(d);
TypeDef.register(d,res);
TypeBinding.register(d,res);
return res;
}
public LinkedList<SignatureSymbol> symbolify() {
LinkedList<SignatureSymbol> result = new LinkedList<SignatureSymbol>();
Iterator<ParsedSampleDef> sdi = sampleDefIterator();
while(sdi.hasNext()) {
SigTypeDef sd = sdi.next();
result.add(new SampleSymbol());
result.add(sd.getType());
result.add(new NameSymbol(sd.getName()));
Iterator<SigTypeDef> di = sd.getDepIterator();
while(di.hasNext()) {
SigTypeDef d = di.next();
result.add(new TypeSymbol());
result.add(d.getType());
result.add(new NameSymbol(d.getName()));
}
}
return result;
}
public String symbolString() {
Iterator<SignatureSymbol> i = symbolify().iterator();
StringBuilder sb = new StringBuilder();
while(i.hasNext()) {
sb.append(i.next().toString());
}
return sb.toString();
}
// SampleRefType currently not sent, se above
// public class SampleRefType extends DataType {
// public void accept(SignatureSymbolVisitor v) {
// v.visit(this);
// }
//
// public String toString() {
// return "sample";}
// }
private class ParserState {
private ByteArrayInputStream bis;
private DataInputStream in;
private TypeDef current;
private ParsedTypeDef currentParsed;
private LinkedList<TypeDef> typeStack;
ParsedTypeDef newTypeDef() {
currentParsed =new ParsedTypeDef(getCurrentIndex(), getCurrentName());
return currentParsed;
}
private ParserState() {
typeStack = new LinkedList<TypeDef>();
}
ParserState(int typeIdx) {
this();
pushType(typeIdx);
}
ParserState(TypeDef td) {
this();
pushType(td);
}
ParserState(byte sig[]) {
this();
bis= new ByteArrayInputStream(sig);
in = new DataInputStream(bis);
}
void pushType(TypeDef td) {
if(!typeStack.contains(td)) {
typeStack.push(td);
}
}
void pushType(int typeIdx) {
if(typeIdx >= 0x40 && !typeStack.contains(typeIdx)) {
typeStack.push(typeDefs.get(typeIdx));
}
}
void popType() {
TypeDef td2 = typeStack.pop();
current = td2;
bis =new ByteArrayInputStream(td2.getSignature());
in = new DataInputStream(bis);
}
boolean moreTypes() {
return !typeStack.isEmpty();
}
int getCurrentIndex() {
return current.getIndex();
}
String getCurrentName() {
return current.getName();
}
void addTypeUse(int tag) {
SigTypeDef td = pts.get(tag);
if(td != null) {
currentParsed.addDependency(td);
} else {
System.out.println("******* WARNING: TypeDefParser:addTypeUse ("+tag+"): null???");
}
}
/** return name, (if any, or "") for now */
String decodeIntentions() throws IOException {
int n = decodePacked32() & 0xffffffff;
if(n==0) return "";
String name = "";
for(int i=0; i<n;i++) {
int klen = decodePacked32() & 0xffffffff;
byte[] kchars = new byte[klen];
for(int k=0; k<klen; k++) {
kchars[k] = in.readByte();
}
int vlen = decodePacked32() & 0xffffffff;
byte[] vchars = new byte[vlen];
for(int j=0; j<vlen; j++) {
vchars[j] = in.readByte();
}
if(klen==0) {
name = new String(vchars);
}
}
return name;
}
String decodeString() throws IOException {
int len = decodePacked32() & 0xffffffff;
byte[] chars = new byte[len];
for(int i=0; i<len; i++) {
chars[i] = in.readByte();
}
return new String(chars);
}
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);
}
void skipBytes(int len) throws IOException {
for(int i=0; i<len; i++) {
in.readByte();
}
}
}
private ParsedTypeDef parseSignatureTD(TypeDef td) throws IOException{
return parseSignatureTD(td, new ParserState(td));
}
private ParsedTypeDef parseSignatureTD(TypeDef td, ParserState s) throws IOException{
ParsedTypeDef result=null;
s.popType();
result = parseTypeDef(s);
return result;
}
public ParsedSampleDef parseSignature(TypeDef td) throws IOException{
ParserState s = new ParserState(td);
ParsedSampleDef result=null;
try {
result = new ParsedSampleDef(parseSignatureTD(td,s));
// while(s.moreTypes()) {
// s.popType();
// result.addDependency(parseTypeDef(s));
// }
} catch(java.io.EOFException ex) {
System.out.println("EOF: self_binding");
}
return result;
}
private SigArrayType parseArray(ParserState in) throws IOException {
int numIdx = in.decodePacked32();
int idx[] = new int[numIdx];
for(int i=0; i<numIdx; i++){
idx[i] = in.decodePacked32();
}
int type = in.decodePacked32();
DataType elementType = lookupType(type, in);
SigArrayType result = new SigArrayType(elementType, idx);
for(int i=0; i<numIdx; i++){
idx[i] = in.decodePacked32();
}
return result;
}
private SigStructType parseStruct(ParserState in) throws IOException {
int numSigFields = in.decodePacked32();
SigStructType result = new SigStructType(numSigFields);
for(int i=0; i<numSigFields; i++) {
result.addField(parseSigField(in));
}
return result;
}
private SigField parseSigField(ParserState in) throws IOException {
String name = in.decodeIntentions();
return new SigField(name, parseType(in, false));
}
private DataType lookupType(int tag, ParserState in) {
DataType result;
if(tag >= Constant.FIRST_USER_INDEX) {
TypeDef td = typeDefs.get(tag);
result = new SigUserType(td.getName());
in.addTypeUse(tag);
in.pushType(tag);
// sampleRefs are sent as primitive types, see above
// } else if(tag == Constant.SAMPLE) {
// result = new SampleRefType();
} else {
result = new SigPrimitiveType(tag);
}
return result;
}
private ParsedSampleDef parseSampleTypeDef(ParserState in) throws IOException {
ParsedTypeDef td = parseTypeDef(in, true);
return new ParsedSampleDef(td);
}
private ParsedTypeDef parseTypeDef(ParserState in) throws IOException {
return parseTypeDef(in, false);
}
private void addParsedTypeDef(ParsedTypeDef td) {
int idx = td.getIndex();
if(idx>=0x40) {
pts.put(idx, td);
}
}
private ParsedTypeDef parseTypeDef(ParserState in, boolean parseIntentions) throws IOException {
ParsedTypeDef result = in.newTypeDef();
result.setType(parseType(in, false));
addParsedTypeDef(result);
return result;
}
private DataType parseType(ParserState in, boolean parseIntentions) throws IOException {
if(parseIntentions) {
String intentions = in.decodeIntentions();
if(intentions.length()>0) {
System.out.println("parseType intentions ("+intentions);
} else {
System.out.println("no intentions");
}
} else {
// System.out.println("not parsing intentions");
}
int tag = in.decodePacked32();
DataType result = null;
switch(tag) {
case 0:
System.out.println("SELF");
break;
case Constant.ARRAY:
result = parseArray(in);
break;
case Constant.STRUCT:
result = parseStruct(in);
break;
default:
result = lookupType(tag, in);
break;
}
return result;
}
}
package se.lth.control.labcomm2014;
public class TypeSymbol implements SignatureSymbol {
public String toString() {
return "typedef ";
}
public void accept(SignatureSymbolVisitor v){
v.visit(this);
}
}
package se.lth.control.labcomm2014;
import java.io.PrintStream;
public class VoidType extends SigStructType{
public VoidType() {
super("void");
}
public void print(PrintStream out, String indent) {
out.print("void");
}
}
package se.lth.control.labcomm;
package se.lth.control.labcomm2014;
import java.io.IOException;
public interface LabCommWriter {
public interface Writer {
public void write(byte[] data) throws IOException;
......
package se.lth.control.labcomm;
package se.lth.control.labcomm2014;
import java.io.OutputStream;
import java.io.IOException;
class WriterWrapper implements LabCommWriter{
class WriterWrapper implements Writer{
private OutputStream os;
......
.PHONY: all
all:
.PHONY: test
test:
.PHONY: clean
clean:
find . -name '*.pyc' -exec rm {} \;
.PHONY: distclean
distclean: clean
import labcomm.LabComm
from labcomm.StreamReader import StreamReader
from labcomm.StreamWriter import StreamWriter
Decoder = labcomm.LabComm.Decoder
Encoder = labcomm.LabComm.Encoder
sample = labcomm.LabComm.sample
typedef = labcomm.LabComm.typedef
array = labcomm.LabComm.array
struct = labcomm.LabComm.struct
primitive = labcomm.LabComm.primitive
BOOLEAN = labcomm.LabComm.BOOLEAN
BYTE = labcomm.LabComm.BYTE
SHORT = labcomm.LabComm.SHORT
INTEGER = labcomm.LabComm.INTEGER
LONG = labcomm.LabComm.LONG
FLOAT = labcomm.LabComm.FLOAT
DOUBLE = labcomm.LabComm.DOUBLE
STRING = labcomm.LabComm.STRING
decl_from_signature = labcomm.LabComm.decl_from_signature
try:
import labcomm.TreeModel
TreeModel = labcomm.TreeModel.TreeModel
except:
pass
#!/usr/bin/python
#
# All packets follows the following layout
# LabComm2014 packet has the following layout
#
# +----+----+----+----+
# | id |
# | id (packed32)
# +----+----+----+----+
# | length (packed32)
# +----+----+----+----+
# | data
# | ...
# +----+--
#
# Data layouts for packets
# LabComm2014 SAMPLE_DEF:
#
# +----+----+----+----+
# | id = 0x02 (packed32)
# +----+----+----+----+
# | length (packed32)
# +----+----+----+----+
# | type number (packed32)
# +----+----+----+----+
# | type name (UTF8)
# | ...
# +----+----+----+----+
# | signature length (packed32)
# +----+----+----+----+
# | type signature
# | ...
# +----+--
#
# TYPEDEF:
# LabComm2014 SAMPLE_REF:
#
# +----+----+----+----+
# | id = 0x00000001 |
# | id = 0x03 (packed32)
# +----+----+----+----+
# | type number |
# | length (packed32)
# +----+----+----+----+
# | type number (packed32)
# +----+----+----+----+
# | type name (UTF8)
# | ...
# +----+----+----+----+
# | signature length (packed32)
# +----+----+----+----+
# | type signature
# | ...
# +----+--
#
# LabComm2014 TYPE_DEF: (as SAMPLE_DEF, but signatures are hierarchical,
# i.e., may contain references to other types
#
# +----+----+----+----+
# | id = 0x04 (packed32)
# +----+----+----+----+
# | length (packed32)
# +----+----+----+----+
# | type number (packed32)
# +----+----+----+----+
# | type name (UTF8)
# | ...
# +----+----+----+----+
# | type
# | signature length (packed32)
# +----+----+----+----+
# | type signature
# | ...
# +----+--
#
# LabComm2014 TYPE_BINDING
#
# +----+----+----+----+
# | id = 0x05 (packed32)
# +----+----+----+----+
# | length (packed32)
# +----+----+----+----+
# | sample number (packed32)
# +----+----+----+----+
# | type number (packed32)
# +----+----+----+----+
#
# LabComm2014 User data:
#
# +----+----+----+----+
# | id >= 0x00000040 (packed32)
# +----+----+----+----+
# | length (packed32)
# +----+----+----+----+
# | user data
# | ...
# +----+--
#
#
# SAMPLE:
# LabComm2006 packets has the following layout
#
# +----+----+----+----+
# | id |
# +----+----+----+----+
# | data
# | ...
# +----+--
#
# LabComm2006 SAMPLE:
#
# +----+----+----+----+
# | id = 0x00000002 |
......@@ -36,20 +109,20 @@
# | type name (UTF8)
# | ...
# +----+----+----+----+
# | type
# | type signature
# | ...
# +----+--
#
#
# User data:
# LabComm2006 User data:
#
# +----+----+----+----+
# | id >= 0x00000060 |
# | id >= 0x00000040 |
# +----+----+----+----+
# | user data
# | ...
# +----+--
#
#
#?? | field1 name
#?? | (length + UTF8)...
......@@ -87,23 +160,31 @@
#?? | fieldN data |
#?? | ... |
#?? +----+----+----+----+
#
#
# type numbers and lengths do not have a fixed lenght, but are packed into
# sequences of 7 bit chunks, represented in bytes with the high bit meaning
#
#
# type numbers and lengths do not have a fixed lenght, but are packed into
# sequences of 7 bit chunks, represented in bytes with the high bit meaning
# that more data is to come.
import types
import struct as packer
VERSION = "LabComm2013"
DEFAULT_VERSION = "LabComm2014"
i_TYPEDEF = 0x01
i_SAMPLE = 0x02
# Allowed packet tags
i_VERSION = 0x01
i_SAMPLE_DEF = 0x02
i_SAMPLE_REF = 0x03
i_TYPE_DEF = 0x04
i_TYPE_BINDING= 0x05
i_PRAGMA = 0x3f
i_USER = 0x40 # ..0xffffffff
# Predefined types
i_ARRAY = 0x10
i_STRUCT = 0x11
i_BOOLEAN = 0x20
i_BOOLEAN = 0x20
i_BYTE = 0x21
i_SHORT = 0x22
i_INTEGER = 0x23
......@@ -111,26 +192,62 @@ i_LONG = 0x24
i_FLOAT = 0x25
i_DOUBLE = 0x26
i_STRING = 0x27
i_SAMPLE = 0x28
# Version testing
def usePacketLength(version):
return version in [ None, "LabComm2014" ]
i_USER = 0x40
class length_encoder:
def __init__(self, encoder):
self.encoder = encoder
self.version = encoder.version
self.data = ""
def write(self, data):
self.data += data
def __enter__(self):
return Encoder(writer=self, version=None, codec=self.encoder)
def __exit__(self, type, value, traceback):
if usePacketLength(self.version):
self.encoder.encode_packed32(len(self.data))
self.encoder.pack("%ds" % len(self.data), self.data)
def indent(i, s):
return ("\n%s" % (" " * i)).join(s.split("\n"))
#
# Base type for all decl's
#
class type_decl(object):
pass
#
# Primitive types
#
class primitive(object):
class primitive(type_decl):
def decode_decl(self, decoder):
return self
def __eq__(self, other):
return self.__class__ == other.__class__
def __ne__(self, other):
return not self.__eq__(other)
def __hash__(self):
return hash(self.__class__)
class BOOLEAN(primitive):
def encode_decl(self, encoder):
return encoder.encode_type(i_BOOLEAN)
def encode(self, encoder, value):
return encoder.encode_boolean(value)
def decode(self, decoder, obj=None):
return decoder.decode_boolean()
......@@ -146,10 +263,10 @@ class BYTE(primitive):
def encode(self, encoder, value):
return encoder.encode_byte(value)
def decode(self, decoder, obj=None):
return decoder.decode_byte()
def new_instance(self):
return 0
......@@ -162,10 +279,10 @@ class SHORT(primitive):
def encode(self, encoder, value):
return encoder.encode_short(value)
def decode(self, decoder, obj=None):
return decoder.decode_short()
def new_instance(self):
return 0
......@@ -178,10 +295,10 @@ class INTEGER(primitive):
def encode(self, encoder, value):
return encoder.encode_int(value)
def decode(self, decoder, obj=None):
return decoder.decode_int()
def new_instance(self):
return 0
......@@ -194,10 +311,10 @@ class LONG(primitive):
def encode(self, encoder, value):
return encoder.encode_long(value)
def decode(self, decoder, obj=None):
return decoder.decode_long()
def new_instance(self):
return long(0)
......@@ -210,10 +327,10 @@ class FLOAT(primitive):
def encode(self, encoder, value):
return encoder.encode_float(value)
def decode(self, decoder, obj=None):
return decoder.decode_float()
def new_instance(self):
return 0.0
......@@ -226,10 +343,10 @@ class DOUBLE(primitive):
def encode(self, encoder, value):
return encoder.encode_double(value)
def decode(self, decoder, obj=None):
return decoder.decode_double()
def new_instance(self):
return 0.0
......@@ -242,39 +359,76 @@ class STRING(primitive):
def encode(self, encoder, value):
return encoder.encode_string(value)
def decode(self, decoder, obj=None):
return decoder.decode_string()
def new_instance(self):
return ""
def __repr__(self):
return "labcomm.STRING()"
class SAMPLE(primitive):
def encode_decl(self, encoder):
return encoder.encode_type(i_SAMPLE)
def encode(self, encoder, value):
if not isinstance(value, type_decl):
# Probably trying to encode a sample class, grab signature
value = value.signature
return encoder.encode_int(encoder.ref_to_index.get(value, 0))
def decode(self, decoder, obj=None):
return decoder.decode_ref()
def new_instance(self):
return ""
def __repr__(self):
return "labcomm.SAMPLE()"
# helper function
def dict_to_sorted_tuple(d):
tmpL = zip(d.keys(), d.values())
tmpL.sort()
return tuple(tmpL)
#
# Aggregate types
#
class sample_or_typedef(object):
def __init__(self, name, decl):
self.name = name
class sampledef_or_sampleref_or_typedef(type_decl):
def __init__(self, intentions={}, decl=None):
self.intentionDict = dict(intentions)
self.name = self.intentionDict.get('', None)
self.intentions = tuple(sorted(self.intentionDict.iteritems()))
self.decl = decl
def encode_decl_tail(self, encoder):
encoder.encode_type_number(self)
encoder.encode_string(self.name)
encoder.encode_type_number(self.decl)
def encode_decl(self, encoder):
encoder.encode_type(self.type_index)
with length_encoder(encoder) as e1:
e1.encode_type(self.get_index(encoder))
# XXX: temporary hack for intentions
e1.encode_intentions(self.intentions)
with length_encoder(e1) as e2:
self.decl.encode_decl(e2)
def encode(self, encoder, object):
self.decl.encode(encoder, object)
def encode(self, encoder, value):
self.decl.encode(encoder, value)
def decode_decl(self, decoder):
index = decoder.decode_type_number()
name = decoder.decode_string()
# XXX: temporary hack for intentions
# assume the name is the only intention
ints = decoder.decode_intentions()
if usePacketLength(decoder.version):
length = decoder.decode_packed32()
decl = decoder.decode_decl()
result = self.__class__.__new__(self.__class__)
result.__init__(name, decl)
decoder.add_decl(result, index)
result.__init__(intentions=ints, decl=decl)
self.add_index(decoder, index, result)
return result
def decode(self, decoder, obj=None):
......@@ -285,30 +439,81 @@ class sample_or_typedef(object):
def new_instance(self):
return self.decl.new_instance()
def __repr__(self):
return "'%s', %s" % (self.name, self.decl)
def __eq__(self, other):
return (self.__class__ == other.__class__ and
self.name == other.name and
self.decl == other.decl)
class sample(sample_or_typedef):
def encode_decl(self, encoder):
encoder.encode_type(i_SAMPLE)
self.encode_decl_tail(encoder)
def __ne__(self, other):
return not self.__eq__(other)
def __hash__(self):
return hash(self.__class__) ^ hash(self.name) ^ hash(self.decl)
def __repr__(self):
return "labcomm.sample(%s)" % super(sample, self).__repr__()
class typedef(sample_or_typedef):
return "%s('%s', %s)" % (self.type_name, self.name, self.decl)
class sample_def(sampledef_or_sampleref_or_typedef):
type_index = i_SAMPLE_DEF
type_name = 'sample'
def get_index(self, encoder):
return encoder.decl_to_index[self]
def add_index(self, decoder, index, decl):
decoder.add_decl(decl, index)
def rename(self, name):
newIntentions = dict(self.intentionDict)
newIntentions['']=name
return sample_def(newIntentions, decl=self.decl)
class sample_ref(sampledef_or_sampleref_or_typedef):
type_index = i_SAMPLE_REF
type_name = 'sample_ref'
def __init__(self, intentions={}, decl=None, sample=None):
self.intentionDict = dict(intentions)
self.name = self.intentionDict.get('', None) # XXX should we allow nameless?
self.decl = decl
self.intentions=tuple(sorted(self.intentionDict.iteritems()))
if sample == None and self.name != None and decl != None:
self.sample = sample_def(intentions, decl)
else:
self.sample = sample
def get_index(self, encoder):
return encoder.ref_to_index[self.sample]
def add_index(self, decoder, index, decl):
decoder.add_ref(decl, index)
class typedef(sampledef_or_sampleref_or_typedef):
type_index = i_TYPE_DEF
type_name = 'typedef'
def encode_decl(self, encoder):
encoder.encode_type(i_TYPEDEF)
self.encode_decl_tail(encoder)
self.decl.encode_decl(encoder)
def __repr__(self):
return "labcomm.typedef(%s)" % super(typedef, self).__repr__()
class array(object):
def encode(self, encoder, value):
self.decl.encode(encoder, value)
class array(type_decl):
def __init__(self, indices, decl):
self.indices = indices
self.indices = tuple(indices)
self.decl = decl
def __eq__(self, other):
return (self.__class__ == other.__class__ and
self.indices == other.indices and
self.decl == other.decl)
def __ne__(self, other):
return not self.__eq__(other)
def __hash__(self):
return hash(self.__class__) ^ hash(self.indices) ^ hash(self.decl)
def encode_decl(self, encoder):
encoder.encode_type(i_ARRAY)
encoder.encode_packed32(len(self.indices))
......@@ -316,19 +521,27 @@ class array(object):
encoder.encode_packed32(i)
encoder.encode_type_number(self.decl)
def min_max_shape(self, l, depth=0, shape=[]):
if isinstance(l, list):
def min_max_shape(self, l, depth, shape):
if isinstance(l, types.StringTypes):
return shape
try:
length = len(l)
if len(shape) <= depth:
shape.append((length, length))
pass
else:
(low, high) = shape[depth]
low = min(low, length)
high = max(high, length)
shape[depth] = (low, high)
pass
for e in l:
shape = self.min_max_shape(e, depth + 1, shape)
return shape
pass
pass
except TypeError:
pass
return shape
def shape(self, l):
shape = self.min_max_shape(l, 0, [])
......@@ -339,11 +552,10 @@ class array(object):
result.append(low)
return result
def encode_indices(self, encoder, value):
depth = len(self.indices)
shape = self.shape(value)
#if len(shape) != len(self.indices):
if len(shape) < len(self.indices):
raise Exception("Actual dimension %s differs from declared %s" %
(shape, self.indices))
......@@ -356,12 +568,12 @@ class array(object):
return depth
def encode_value(self, encoder, value, depth):
if depth and isinstance(value, list):
if depth:
for e in value:
self.encode_value(encoder, e, depth - 1)
else:
self.decl.encode(encoder, value)
def encode(self, encoder, value):
depth = self.encode_indices(encoder, value)
self.encode_value(encoder, value, depth)
......@@ -400,7 +612,7 @@ class array(object):
for i in range(indices[0]):
result.append(self.new_instance_value(indices[1:]))
return result
def new_instance(self):
indices = []
for i in self.indices:
......@@ -408,71 +620,96 @@ class array(object):
i = decoder.decode_packed32()
indices.append(i)
return self.new_instance_value(indices)
def __repr__(self):
return "labcomm.array(%s,\n %s)" % (
self.indices, indent(4, self.decl.__repr__()))
class struct:
class struct(type_decl):
def __init__(self, field):
self.field = field
self.field = tuple(field)
def __eq__(self, other):
return (self.__class__ == other.__class__ and
self.field == other.field)
def __ne__(self, other):
return not self.__eq__(other)
def __hash__(self):
return hash(self.__class__) ^ hash(self.field)
def encode_decl(self, encoder):
encoder.encode_type(i_STRUCT)
encoder.encode_packed32(len(self.field))
for (name, decl) in self.field:
encoder.encode_string(name)
encoder.encode_type_number(decl)
#type.encode_decl(encoder)
for (intentions, decl) in self.field:
encoder.encode_intentions(intentions)
encoder.encode_type_number(decl)
def encode(self, encoder, obj):
if isinstance(obj, dict):
for (name, decl) in self.field:
decl.encode(encoder, obj[name])
else:
for (name, decl) in self.field:
try:
# hack to get names as keys in the obj:
tmp_foo = zip (map(lambda x:dict(x)[''],obj.keys()), obj.values())
tmp_obj = dict(tmp_foo)
for (intentions, decl) in self.field:
tmp = dict(intentions)
name = tmp['']
decl.encode(encoder, tmp_obj[name])
except AttributeError:
print "HERE BE DRAGONS! hack to get duck-typing example to work"
for (intentions, decl) in self.field:
tmp = dict(intentions)
name = tmp['']
print "trying to encode [%s] " % (name)
decl.encode(encoder, getattr(obj, name))
def decode_decl(self, decoder):
n_field = decoder.decode_packed32()
field = []
for i in range(n_field):
name = decoder.decode_string()
ints = decoder.decode_intentions()
decl = decoder.decode_decl()
field.append((name, decl))
field.append((ints, decl))
return struct(field)
def decode(self, decoder, obj=None):
if obj == None:
obj = decoder.create_object()
for (name, decl) in self.field:
obj.__setattr__(name, decl.decode(decoder))
for (intentions, decl) in self.field:
#name = dict(intentions)['']
obj.__setattr__(intentions, decl.decode(decoder))
return obj
def new_instance(self):
result = anonymous_object()
for (name, decl) in self.field:
for (intentions, decl) in self.field:
name = dict(intentions)['']
result.__setattr__(name, decl.new_instance())
return result
def __repr__(self):
delim = ""
result = "labcomm.struct(["
for (name, decl) in self.field:
for (intentions, decl) in self.field:
try:
name = dict(intentions)['']
except:
name = '(no name)'
result += "%s\n ('%s', %s)" % (delim, name, decl)
delim = ","
result += "\n])"
return result
SAMPLE = sample(None, None)
TYPEDEF = typedef(None, None)
SAMPLE_DEF = sample_def()
SAMPLE_REF = sample_ref()
ARRAY = array(None, None)
STRUCT = struct({})
ARRAY = array([], None)
STRUCT = struct([])
class anonymous_object(dict):
def __setattr__(self, name, value):
if name.startswith("_"):
# XXX HERE BE DRAGONS! Is this OK:
if (str(name)).startswith("_"):
super(anonymous_object, self).__setattr__(name, value)
else:
self[name] = value
......@@ -484,18 +721,23 @@ class anonymous_object(dict):
return self[name]
class Codec(object):
def __init__(self):
self.type_to_name = {}
self.name_to_type = {}
self.index_to_decl = {}
self.decl_to_index = {}
self.name_to_decl = {}
self.decl_index = i_USER
self.predefined_types()
def __init__(self, codec=None):
self.type_to_name = codec and codec.type_to_name or {}
self.name_to_type = codec and codec.name_to_type or {}
self.index_to_decl = codec and codec.index_to_decl or {}
self.decl_to_index = codec and codec.decl_to_index or {}
self.name_to_decl = codec and codec.name_to_decl or {}
self.index_to_ref = codec and codec.index_to_ref or {}
self.ref_to_index = codec and codec.ref_to_index or {}
self.name_to_ref = codec and codec.name_to_ref or {}
self.decl_index = codec and codec.decl_index or i_USER
self.ref_index = codec and codec.ref_index or i_USER
if not codec:
self.predefined_types()
def predefined_types(self):
self.add_decl(TYPEDEF, i_TYPEDEF)
self.add_decl(SAMPLE, i_SAMPLE)
self.add_decl(SAMPLE_DEF, i_SAMPLE_DEF)
self.add_decl(SAMPLE_REF, i_SAMPLE_REF)
self.add_decl(ARRAY, i_ARRAY)
self.add_decl(STRUCT, i_STRUCT)
......@@ -508,9 +750,12 @@ class Codec(object):
self.add_decl(FLOAT(), i_FLOAT)
self.add_decl(DOUBLE(), i_DOUBLE)
self.add_decl(STRING(), i_STRING)
self.add_decl(SAMPLE(), i_SAMPLE)
def add_decl(self, decl, index=0):
if index == 0:
if decl in self.decl_to_index:
return False
index = self.decl_index
self.decl_index += 1
self.index_to_decl[index] = decl
......@@ -519,7 +764,25 @@ class Codec(object):
self.name_to_decl[decl.name] = decl
except:
pass
return True
def add_ref(self, ref, index=0):
if not isinstance(ref, type_decl):
# Probably trying to register a sample class, grab signature
ref = ref.signature
if index == 0:
if ref.sample in self.ref_to_index:
return False
index = self.ref_index
self.ref_index += 1
self.index_to_ref[index] = ref.sample
self.ref_to_index[ref.sample] = index
try:
self.name_to_ref[ref.sample.name] = ref.sample
except:
pass
return True
def add_binding(self, name, decl):
self.type_to_name[decl] = name
self.name_to_type[name] = decl
......@@ -533,51 +796,82 @@ class Codec(object):
if i >= i_USER and isinstance(e, sample):
result.append(e)
return result
class Encoder(Codec):
def __init__(self, writer):
super(Encoder, self).__init__()
def __init__(self, writer, version=DEFAULT_VERSION, codec=None):
super(Encoder, self).__init__(codec)
self.writer = writer
self.writer.start(self, VERSION)
self.version = version
if self.version in [ "LabComm2014" ]:
self.encode_type(i_VERSION)
with length_encoder(self) as e:
e.encode_string(version)
elif self.version in [ None, "LabComm2006" ]:
pass
else:
raise Exception("Unsupported labcomm version %s" % self.version)
def pack(self, format, *args):
self.writer.write(packer.pack(format, *args))
def add_decl(self, decl, index=0):
super(Encoder, self).add_decl(decl, index)
if not isinstance(decl, type_decl):
decl = decl.signature
if index == 0:
decl.encode_decl(self)
self.writer.mark()
self.writer.mark_begin(decl, None)
if super(Encoder, self).add_decl(decl, index):
decl.encode_decl(self)
self.writer.mark_end(decl, None)
def add_ref(self, ref, index=0):
if not isinstance(ref, type_decl):
# Trying to register a sample class
ref = ref.signature
decl = sample_ref(intentions=ref.intentions, decl=ref.decl, sample=ref)
if index == 0:
self.writer.mark_begin(ref, None)
if super(Encoder, self).add_ref(decl, index):
decl.encode_decl(self)
self.writer.mark_end(ref, None)
def encode(self, object, decl=None):
if decl == None:
name = self.type_to_name[object.__class__]
decl = self.name_to_decl[name]
if not isinstance(decl, type_decl):
decl = decl.signature
self.writer.mark_begin(decl, object)
self.encode_type_number(decl)
decl.encode(self, object)
self.writer.mark()
with length_encoder(self) as e:
decl.encode(e, object)
self.writer.mark_end(decl, object)
def encode_type_number(self, decl):
try:
self.encode_type(self.decl_to_index[decl])
except KeyError:
decl.encode_decl(self)
def encode_packed32(self, v):
v = v & 0xffffffff
tmp = [ v & 0x7f ]
v = v >> 7
while v:
tmp.append(v & 0x7f | 0x80)
if self.version in [ None, "LabComm2014" ]:
v = v & 0xffffffff
tmp = [ v & 0x7f ]
v = v >> 7
for c in reversed(tmp):
self.encode_byte(c)
while v:
tmp.append(v & 0x7f | 0x80)
v = v >> 7
for c in reversed(tmp):
self.encode_byte(c)
elif self.version == "LabComm2006" :
v = v & 0xffffffff
self.encode_int(v)
else :
raise Exception("Unsupported labcomm version %s" % self.version)
def encode_type(self, index):
self.encode_packed32(index)
# self.pack("!i", index)
def encode_boolean(self, v):
if v:
self.pack("!b", 1)
......@@ -585,7 +879,7 @@ class Encoder(Codec):
self.pack("!b", 0)
def encode_byte(self, v):
self.pack("!b", v)
self.pack("!B", v)
def encode_short(self, v):
self.pack("!h", v)
......@@ -606,14 +900,26 @@ class Encoder(Codec):
s = v.encode("utf8")
self.encode_packed32(len(s));
self.pack("%ds" % len(s),s)
# self.pack("!i%ds" % len(s), len(s), s)
def encode_intentions(self, intentions):
self.encode_packed32(len(intentions))
try:
for (k,v) in intentions:
self.encode_string(k)
self.encode_string(v)
except:
print "WARNING! encode_intentions: don't know what to do with %s" % intentions
class Decoder(Codec):
def __init__(self, reader):
def __init__(self, reader, version=DEFAULT_VERSION):
super(Decoder, self).__init__()
self.reader = reader
self.reader.start(self, VERSION)
self.version = version
self.handlers = {}
def register_handler(self, decl, handler):
self.handlers[decl] = handler
def unpack(self, format):
size = packer.calcsize(format)
data = ""
......@@ -627,15 +933,73 @@ class Decoder(Codec):
result = self.index_to_decl[index]
if index < i_USER:
result = result.decode_decl(self)
else:
raise Exception('Should not be used')
return result
def skip(self, length):
for _ in xrange(length):
self.decode_byte()
# kludge, should really check if the index exists in self.version
def skip_or_raise(self, length, index):
if usePacketLength(self.version):
self.skip(length)
else:
raise Exception("Invalid type index %d" % index)
def runOne(self):
data,decl = self.decode()
# decode any signatures until next sample
while data == None:
data,decl = self.decode()
if decl:
if data != None:
if decl in self.handlers:
handler = self.handlers[decl]
handler(data)
else:
print ("No handler for %s" % decl.name )
for key, value in self.handlers.iteritems():
if key == decl:
print "but value %s == decl %s" % (key,decl)
print "hashes %d : %d" % (hash(key),hash(decl))
raise Exception()
def decode(self):
value = None
index = self.decode_type_number()
decl = self.index_to_decl[index]
if index == i_TYPEDEF or index == i_SAMPLE:
decl = decl.decode_decl(self)
while True:
index = self.decode_type_number()
if usePacketLength(self.version):
length = self.decode_packed32()
if index != i_VERSION:
break
else:
other_version = self.decode_string()
if self.version != other_version:
raise Exception("LabComm version mismatch %s != %s" %
(version, other_version))
if index == i_SAMPLE_DEF:
decl = self.index_to_decl[index].decode_decl(self)
value = None
elif index == i_SAMPLE_REF:
decl = self.index_to_decl[index].decode_decl(self)
value = None
elif index == i_TYPE_DEF:
self.skip_or_raise(length, index)
decl = None
value = None
elif index == i_TYPE_BINDING:
self.skip_or_raise(length, index)
decl = None
value = None
elif index == i_PRAGMA:
self.skip_or_raise(length, index)
decl = None
value = None
elif index < i_USER:
raise Exception("Invalid type index %d" % index)
else:
decl = self.index_to_decl[index]
value = decl.decode(self)
self.reader.mark(value, decl)
return (value, decl)
......@@ -652,44 +1016,62 @@ class Decoder(Codec):
result = anonymous_object()
return result
def decode_packed32(self):
result = 0
while True:
tmp = self.decode_byte()
result = (result << 7) | (tmp & 0x7f)
if (tmp & 0x80) == 0:
break
return result
if self.version in [ "LabComm2013", "LabComm2014" ] :
result = 0
while True:
tmp = self.decode_byte()
result = (result << 7) | (tmp & 0x7f)
if (tmp & 0x80) == 0:
break
return result
elif self.version == "LabComm2006" :
return self.decode_int()
else :
raise Exception("Unsupported labcomm version %s" % self.version)
def decode_type_number(self):
return self.decode_packed32()
def decode_boolean(self):
return self.unpack("!b") != 0
def decode_byte(self):
return self.unpack("!b")
return self.unpack("!B")
def decode_short(self):
return self.unpack("!h")
def decode_int(self):
return self.unpack("!i")
def decode_long(self):
return self.unpack("!q")
def decode_float(self):
return self.unpack("!f")
def decode_double(self):
return self.unpack("!d")
def decode_string(self):
length = self.decode_packed32()
length = self.decode_packed32()
return self.unpack("!%ds" % length).decode("utf8")
def decode_ref(self):
index = self.decode_int()
return self.index_to_ref.get(index, None)
def decode_intentions(self):
numIntentions = self.decode_packed32()
res = {}
for i in range(numIntentions):
key = self.decode_string()
val = self.decode_string()
res[key] = val
result = dict_to_sorted_tuple(res)
return result
class signature_reader:
def __init__(self, signature):
......@@ -699,7 +1081,7 @@ class signature_reader:
result = self.signature[0:count]
self.signature = self.signature[count:]
return result
def decl_from_signature(signature):
decoder = Decoder(signature_reader(signature))
t = decoder.decode_decl()
......
......@@ -4,13 +4,6 @@ class StreamReader:
self.stream = stream
pass
def start(self, decoder, version):
other_version = decoder.decode_string()
if version != other_version:
raise Exception("LabComm version mismatch %s != %s" %
(version, other_version))
pass
def read(self, count):
result = self.stream.read(count)
if len(result) == 0:
......
......@@ -4,15 +4,14 @@ class StreamWriter:
self.stream = stream
pass
def start(self, encoder, version):
encoder.encode_string(version)
pass
def write(self, data):
self.stream.write(data)
pass
def mark(self):
def mark_begin(self, decl, value):
pass
def mark_end(self, decl, value):
self.stream.flush()
pass
......
__all__ = [ 'LabComm' ]
import LabComm
from StreamReader import StreamReader
from StreamWriter import StreamWriter
Decoder = LabComm.Decoder
Encoder = LabComm.Encoder
sample = LabComm.sample_def
sample_def = LabComm.sample_def
sample_ref = LabComm.sample_ref
typedef = LabComm.typedef
array = LabComm.array
struct = LabComm.struct
primitive = LabComm.primitive
BOOLEAN = LabComm.BOOLEAN
BYTE = LabComm.BYTE
SHORT = LabComm.SHORT
INTEGER = LabComm.INTEGER
LONG = LabComm.LONG
FLOAT = LabComm.FLOAT
DOUBLE = LabComm.DOUBLE
STRING = LabComm.STRING
SAMPLE = LabComm.SAMPLE
decl_from_signature = LabComm.decl_from_signature
labcomm2014-*.src.rpm
rpmbuild