diff options
| author | Rafael H. Schloming <rhs@apache.org> | 2007-10-10 13:24:24 +0000 |
|---|---|---|
| committer | Rafael H. Schloming <rhs@apache.org> | 2007-10-10 13:24:24 +0000 |
| commit | 89cc15c84947df5b19efaf4c8e4d46b62559f96e (patch) | |
| tree | b13bd36f6e97712eb7adbff1b0e44bdbc470fe30 /qpid/java/common | |
| parent | bcee10ba757312614d9dcb57681ef4a19ef652f4 (diff) | |
| download | qpid-python-89cc15c84947df5b19efaf4c8e4d46b62559f96e.tar.gz | |
added support (currently disabled) for packed encoding
git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk@583468 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'qpid/java/common')
9 files changed, 296 insertions, 85 deletions
diff --git a/qpid/java/common/generate b/qpid/java/common/generate index 2920d2af42..f3a53ee8da 100755 --- a/qpid/java/common/generate +++ b/qpid/java/common/generate @@ -37,6 +37,30 @@ class Output: def line(self, l = ""): self.lines.append(l) + def getter(self, type, method, variable, pre = None): + self.line(" public final %s %s() {" % (type, method)) + if pre: + self.line(" %s;" % pre) + self.line(" return %s;" % variable) + self.line(" }") + + def setter(self, type, method, variable, value = None, pre = None, + post = None): + if value: + params = "" + else: + params = "%s value" % type + value = "value" + + self.line(" public final %s %s(%s) {" % (self.name, method, params)) + if pre: + self.line(" %s;" % pre) + self.line(" this.%s = %s;" % (variable, value)) + if post: + self.line(" %s;" % post) + self.line(" return this;") + self.line(" }") + def write(self): dir = os.path.join(self.dir, *self.package.split(".")) if not os.path.exists(dir): @@ -107,6 +131,15 @@ TYPES = { "void": "Void" } +DEFAULTS = { + "longlong": "0", + "long": "0", + "short": "0", + "octet": "0", + "timestamp": "0", + "bit": "false" + } + TRACKS = { "connection": "Frame.L1", "session": "Frame.L2", @@ -211,15 +244,39 @@ def jtype(type): else: return TYPES[type] +def jclass(jt): + idx = jt.find('<') + if idx > 0: + return jt[:idx] + else: + return jt + +REFS = { + "boolean": "Boolean", + "byte": "Byte", + "short": "Short", + "int": "Integer", + "long": "Long", + "float": "Float", + "double": "Double", + "char": "Character" +} + +def jref(jt): + return REFS.get(jt, jt) + + OPTIONS = {} class Struct: - def __init__(self, node, name, base, type, track, content): + def __init__(self, node, name, base, type, size, pack, track, content): self.node = node self.name = name self.base = base self.type = type + self.size = size + self.pack = pack self.track = track self.content = content self.fields = [] @@ -249,34 +306,42 @@ class Struct: out.line(" public static final int TYPE = %d;" % self.type) out.line() - out.line(" public int getEncodedType() {") if self.type == None: - out.line(" throw new UnsupportedOperationException();") + pre = "if (true) throw new UnsupportedOperationException()" + value = "0" else: - out.line(" return TYPE;") - out.line(" }") + pre = None + value = "TYPE" + out.getter("int", "getEncodedType", value, pre = pre) + + out.line() + out.getter("int", "getSizeWidth", self.size) + out.line() + out.getter("int", "getPackWidth", self.pack) + + if self.ticket: + out.getter("boolean", "hasTicket", "true") + else: + out.getter("boolean", "hasTicket", "false"); if self.base == "Method": out.line() - out.line(" public boolean hasPayload() {") if self.content: - out.line(" return true;") + out.getter("boolean", "hasPayload", "true") else: - out.line(" return false;") - out.line(" }") + out.getter("boolean", "hasPayload", "false") out.line() - out.line(" public byte getEncodedTrack() {") - out.line(" return %s;" % self.track) - out.line(" }") + out.getter("byte", "getEncodedTrack", self.track) out.line() - out.line(" private static final List<Field<?>> FIELDS = new ArrayList<Field<?>>();") - out.line(" public List<Field<?>> getFields() { return FIELDS; }") + out.line(" private static final List<Field<?,?>> FIELDS = new ArrayList<Field<?,?>>();") + out.line(" public List<Field<?,?>> getFields() { return FIELDS; }") out.line() out.line() for type, name in self.fields: + out.line(" private boolean has_%s;" % name) out.line(" private %s %s;" % (jtype(type), name)) if self.fields: @@ -288,7 +353,7 @@ class Struct: opts = False for type, name in self.fields: if not OPTIONS.has_key(name): - out.line(" this.%s = %s;" % (name, name)) + out.line(" %s(%s);" % (camel(1, "set", name), name)) else: opts = True if opts: @@ -307,7 +372,7 @@ class Struct: out.line(" }") for type, name in self.fields: if OPTIONS.has_key(name): - out.line(" this.%s = _%s;" % (name, name)) + out.line(" %s(_%s);" % (camel(1, "set", name), name)) out.line(" }") out.line() @@ -318,65 +383,52 @@ class Struct: index = 0 for type, name in self.fields: out.line() - out.line(" public %s %s() {" % (jtype(type), camel(1, "get", name))) - out.line(" return %s;" % name) - out.line(" }") - out.line(" public %s %s(%s value) {" % - (self.name, camel(1, "set", name), jtype(type))) - out.line(" this.%s = value;" % name) - out.line(" return this;") - out.line(" }") - out.line(" public %s %s(%s value) {" % (self.name, name, jtype(type))) - out.line(" this.%s = value;" % name) - out.line(" return this;") - out.line(" }") + out.getter("boolean", camel(1, "has", name), "has_" + name) + out.setter("boolean", camel(1, "clear", name), "has_" + name, "false", + post = "this.%s = %s" % (name, DEFAULTS.get(type, "null"))) + out.getter(jtype(type), camel(1, "get", name), name) + for mname in (camel(1, "set", name), name): + out.setter(jtype(type), mname, name, + post = "this.has_%s = true" % name) + out.line() out.line(' static {') - out.line(' FIELDS.add(new Field<%s>(%s.class, "%s", %d) {' % - (self.name, self.name, name, index)) - out.line(' public Object get(Object struct) {') - out.line(' return check(struct).%s;' % name) + ftype = jref(jclass(jtype(type))) + out.line(' FIELDS.add(new Field<%s,%s>(%s.class, %s.class, "%s", %d) {' % + (self.name, ftype, self.name, ftype, name, index)) + out.line(' public boolean has(Object struct) {') + out.line(' return check(struct).has_%s;' % name) out.line(' }') - out.line(' public void read(Decoder dec, Object struct) {') -# out.line(' check(struct).%s = dec.read%s();' % (name, camel(0, type))) + out.line(' public void has(Object struct, boolean value) {') + out.line(' check(struct).has_%s = value;' % name) out.line(' }') - out.line(' public void write(Encoder enc, Object struct) {') -# out.line(' enc.write%s(check(struct).%s);' % (camel(0, type), name)) + out.line(' public %s get(Object struct) {' % ftype) + out.line(' return check(struct).%s();' % camel(1, "get", name)) out.line(' }') - out.line(' });') - out.line(' }') - index += 1; - - out.line() - out.line(" public void read(Decoder dec, byte major, byte minor) {") - if self.ticket: - out.line(" dec.readShort();") - for type, name in self.fields: + out.line(' public void read(Decoder dec, Object struct) {') if TYPES.has_key(type): - out.line(" %s = dec.read%s();" % (name, camel(0, type))) + out.line(' check(struct).%s = dec.read%s();' % (name, camel(0, type))) elif STRUCTS.has_key(type): - out.line(" %s = new %s();" % (name, STRUCTS[type])) - out.line(" %s.read(dec, major, minor);" % name) + out.line(' check(struct).%s = new %s();' % (name, STRUCTS[type])) + out.line(' check(struct).%s.read(dec);' % name) else: raise Exception("unknown type: %s" % type) - out.line(" }") - - out.line() - out.line(" public void write(Encoder enc, byte major, byte minor) {") - if self.ticket: - out.line(" enc.writeShort(0);") - for type, name in self.fields: + out.line(' }') + out.line(' public void write(Encoder enc, Object struct) {') if TYPES.has_key(type): - out.line(" enc.write%s(%s);" % (camel(0, type), name)) + out.line(' enc.write%s(check(struct).%s);' % (camel(0, type), name)) elif STRUCTS.has_key(type): - out.line(" if (%s == null) {" % name) - out.line(" new %s().write(enc, major, minor);" % jtype(type)) - out.line(" } else {") - out.line(" %s.write(enc, major, minor);" % name) - out.line(" }") + out.line(" if (check(struct).%s == null) {" % name) + out.line(" new %s().write(enc);" % jtype(type)) + out.line(" } else {") + out.line(' check(struct).%s.write(enc);' % name) + out.line(" }") else: raise Exception("unknown type: %s" % type) - out.line(" }") + out.line(' }') + out.line(' });') + out.line(' }') + index += 1; out.line("}") @@ -407,6 +459,16 @@ class Struct: CLASSES = {"file": False, "basic": False, "stream": False, "tunnel": False} +PACK_WIDTHS = { + None: 2, + "octet": 1, + "short": 2, + "long": 4 + } + +SIZE_WIDTHS = PACK_WIDTHS.copy() +SIZE_WIDTHS[None] = 0 + class Visitor(mllib.transforms.Visitor): def __init__(self): @@ -416,7 +478,7 @@ class Visitor(mllib.transforms.Visitor): if CLASSES.get(m.parent["@name"], True): name = camel(0, m.parent["@name"], m["@name"]) type = int(m.parent["@index"])*256 + int(m["@index"]) - self.structs.append((name, "Method", type, m)) + self.structs.append((name, "Method", type, 0, 2, m)) self.descend(m) def do_domain(self, d): @@ -428,7 +490,8 @@ class Visitor(mllib.transforms.Visitor): type = None else: type = int(st) - self.structs.append((name, "Struct", type, s)) + self.structs.append((name, "Struct", type, SIZE_WIDTHS[s["size"]], + PACK_WIDTHS[s["pack"]], s)) self.descend(d) def do_result(self, r): @@ -436,7 +499,8 @@ class Visitor(mllib.transforms.Visitor): if s: name = camel(0, r.parent.parent["@name"], r.parent["@name"], "Result") type = int(r.parent.parent["@index"]) * 256 + int(s["@type"]) - self.structs.append((name, "Result", type, s)) + self.structs.append((name, "Result", type, SIZE_WIDTHS[s["size"]], + PACK_WIDTHS[s["pack"]], s)) self.descend(r) v = Visitor() @@ -445,8 +509,8 @@ spec.dispatch(v) opts = Output(out_dir, out_pkg, "Option") opts.line("public enum Option {") structs = [] -for name, base, typecode, m in v.structs: - struct = Struct(m, name, base, typecode, +for name, base, typecode, size, pack, m in v.structs: + struct = Struct(m, name, base, typecode, size, pack, TRACKS.get(m.parent["@name"], "Frame.L4"), m["@content"] == "1") for f in m.query["field"]: diff --git a/qpid/java/common/src/main/java/org/apache/qpidity/ToyClient.java b/qpid/java/common/src/main/java/org/apache/qpidity/ToyClient.java index f3f7338c07..67f34f9bde 100644 --- a/qpid/java/common/src/main/java/org/apache/qpidity/ToyClient.java +++ b/qpid/java/common/src/main/java/org/apache/qpidity/ToyClient.java @@ -117,6 +117,7 @@ class ToyClient extends SessionDelegate Future<QueueQueryResult> future = ssn.queueQuery("asdf"); System.out.println(future.get().getQueue()); + ssn.sync(); ssn.close(); conn.close(); } diff --git a/qpid/java/common/src/main/java/org/apache/qpidity/transport/Field.java b/qpid/java/common/src/main/java/org/apache/qpidity/transport/Field.java index 8c16b60779..ebbd59288b 100644 --- a/qpid/java/common/src/main/java/org/apache/qpidity/transport/Field.java +++ b/qpid/java/common/src/main/java/org/apache/qpidity/transport/Field.java @@ -29,41 +29,52 @@ import org.apache.qpidity.transport.codec.Encoder; * */ -public abstract class Field<T> +public abstract class Field<C,T> { - private final Class<T> container; + private final Class<C> container; + private final Class<T> type; private final String name; private final int index; - Field(Class<T> container, String name, int index) + Field(Class<C> container, Class<T> type, String name, int index) { this.container = container; + this.type = type; this.name = name; this.index = index; } - public Class<T> getContainer() + public final Class<C> getContainer() { return container; } - public String getName() + public final Class<T> getType() + { + return type; + } + + public final String getName() { return name; } - public int getIndex() + public final int getIndex() { return index; } - protected T check(Object struct) + protected final C check(Object struct) { return container.cast(struct); } - public abstract Object get(Object struct); + public abstract boolean has(Object struct); + + public abstract void has(Object struct, boolean value); + + public abstract T get(Object struct); public abstract void read(Decoder dec, Object struct); diff --git a/qpid/java/common/src/main/java/org/apache/qpidity/transport/Struct.java b/qpid/java/common/src/main/java/org/apache/qpidity/transport/Struct.java index 185615fda4..b87512284f 100644 --- a/qpid/java/common/src/main/java/org/apache/qpidity/transport/Struct.java +++ b/qpid/java/common/src/main/java/org/apache/qpidity/transport/Struct.java @@ -22,7 +22,9 @@ package org.apache.qpidity.transport; import java.util.List; +import org.apache.qpidity.transport.codec.Decoder; import org.apache.qpidity.transport.codec.Encodable; +import org.apache.qpidity.transport.codec.Encoder; /** @@ -39,10 +41,127 @@ public abstract class Struct implements Encodable return StructFactory.create(type); } - public abstract List<Field<?>> getFields(); + public abstract List<Field<?,?>> getFields(); public abstract int getEncodedType(); + public abstract int getSizeWidth(); + + public abstract int getPackWidth(); + + public abstract boolean hasTicket(); + + private final boolean isBit(Field<?,?> f) + { + return f.getType().equals(Boolean.class); + } + + private final boolean encoded(Field<?,?> f) + { + // XXX: remove to enable packed encoding + if (true) { return true; } + return !isBit(f) && f.has(this); + } + + private final int getFlagWidth() + { + return (getFields().size() + 7)/8; + } + + private final int getPaddWidth() + { + int pw = getPackWidth() - getFlagWidth(); + assert pw > 0; + return pw; + } + + public final void read(Decoder dec) + { + List<Field<?,?>> fields = getFields(); + + assert fields.size() <= 8*getPackWidth(); + + // XXX: remove to enable packed encoding + if (false) + { + for (Field<?,?> f : fields) + { + if (isBit(f)) + { + f.has(this, true); + f.read(dec, this); + } + else + { + f.has(this, dec.readBit()); + } + } + + for (int i = 0; i < getPaddWidth(); i++) + { + short padd = dec.readOctet(); + if (padd != 0x0) + { + throw new IllegalStateException("urecognized value in reserved bytes: " + padd); + } + } + } + + if (hasTicket()) + { + dec.readShort(); + } + + for (Field<?,?> f : fields) + { + if (encoded(f)) + { + f.read(dec, this); + } + } + } + + public final void write(Encoder enc) + { + List<Field<?,?>> fields = getFields(); + + assert fields.size() <= 8*getPackWidth(); + + // XXX: remove to enable packed encoding + if (false) + { + for (Field<?,?> f : fields) + { + if (isBit(f)) + { + f.write(enc, this); + } + else + { + enc.writeBit(f.has(this)); + } + } + + for (int i = 0; i < getPaddWidth(); i++) + { + enc.writeOctet((short) 0x0); + } + } + + if (hasTicket()) + { + enc.writeShort(0x0); + } + + for (Field<?,?> f : fields) + { + if (encoded(f)) + { + f.write(enc, this); + } + } + } + public String toString() { StringBuilder str = new StringBuilder(); @@ -50,8 +169,17 @@ public abstract class Struct implements Encodable str.append("("); boolean first = true; - for (Field<?> f : getFields()) + for (Field<?,?> f : getFields()) { + // XXX: remove when packed encoding is enabled + if (false) + { + if (!f.has(this)) + { + continue; + } + } + if (first) { first = false; diff --git a/qpid/java/common/src/main/java/org/apache/qpidity/transport/codec/AbstractDecoder.java b/qpid/java/common/src/main/java/org/apache/qpidity/transport/codec/AbstractDecoder.java index 2855986f90..e5997d6642 100644 --- a/qpid/java/common/src/main/java/org/apache/qpidity/transport/codec/AbstractDecoder.java +++ b/qpid/java/common/src/main/java/org/apache/qpidity/transport/codec/AbstractDecoder.java @@ -88,6 +88,12 @@ abstract class AbstractDecoder implements Decoder } boolean result = (bits & (1 << nbits++)) != 0; + + if (nbits == 8) + { + clearBits(); + } + return result; } @@ -191,7 +197,7 @@ abstract class AbstractDecoder implements Decoder { int type = readShort(); Struct result = Struct.create(type); - result.read(this, major, minor); + result.read(this); return result; } } diff --git a/qpid/java/common/src/main/java/org/apache/qpidity/transport/codec/AbstractEncoder.java b/qpid/java/common/src/main/java/org/apache/qpidity/transport/codec/AbstractEncoder.java index 8e68a0f2b6..68c2b3c952 100644 --- a/qpid/java/common/src/main/java/org/apache/qpidity/transport/codec/AbstractEncoder.java +++ b/qpid/java/common/src/main/java/org/apache/qpidity/transport/codec/AbstractEncoder.java @@ -236,13 +236,14 @@ abstract class AbstractEncoder implements Encoder { SizeEncoder sizer = new SizeEncoder(major, minor); sizer.writeShort(s.getEncodedType()); - s.write(sizer, major, minor); + s.write(sizer); + sizer.flush(); size = sizer.getSize(); } writeLong(size); writeShort(s.getEncodedType()); - s.write(this, major, minor); + s.write(this); } } diff --git a/qpid/java/common/src/main/java/org/apache/qpidity/transport/codec/Encodable.java b/qpid/java/common/src/main/java/org/apache/qpidity/transport/codec/Encodable.java index 54fdd2768e..60c2ea97b8 100644 --- a/qpid/java/common/src/main/java/org/apache/qpidity/transport/codec/Encodable.java +++ b/qpid/java/common/src/main/java/org/apache/qpidity/transport/codec/Encodable.java @@ -30,8 +30,8 @@ package org.apache.qpidity.transport.codec; public interface Encodable { - void write(Encoder enc, byte major, byte minor); + void write(Encoder enc); - void read(Decoder dec, byte major, byte minor); + void read(Decoder dec); } diff --git a/qpid/java/common/src/main/java/org/apache/qpidity/transport/network/Assembler.java b/qpid/java/common/src/main/java/org/apache/qpidity/transport/network/Assembler.java index d12cd003a9..8375e3f845 100644 --- a/qpid/java/common/src/main/java/org/apache/qpidity/transport/network/Assembler.java +++ b/qpid/java/common/src/main/java/org/apache/qpidity/transport/network/Assembler.java @@ -167,7 +167,7 @@ public class Assembler implements Receiver<NetworkEvent>, NetworkDelegate case Frame.METHOD: int methodType = dec.readShort(); Method method = Method.create(methodType); - method.read(dec, major, minor); + method.read(dec); return method; case Frame.HEADER: List<Struct> structs = new ArrayList(); diff --git a/qpid/java/common/src/main/java/org/apache/qpidity/transport/network/Disassembler.java b/qpid/java/common/src/main/java/org/apache/qpidity/transport/network/Disassembler.java index faaf8bfe4c..8f95dc0234 100644 --- a/qpid/java/common/src/main/java/org/apache/qpidity/transport/network/Disassembler.java +++ b/qpid/java/common/src/main/java/org/apache/qpidity/transport/network/Disassembler.java @@ -118,14 +118,14 @@ public class Disassembler implements Sender<ConnectionEvent>, { SizeEncoder sizer = new SizeEncoder(major, minor); sizer.writeShort(method.getEncodedType()); - method.write(sizer, major, minor); + method.write(sizer); sizer.flush(); int size = sizer.getSize(); ByteBuffer buf = ByteBuffer.allocate(size); BBEncoder enc = new BBEncoder(major, minor, buf); enc.writeShort(method.getEncodedType()); - method.write(enc, major, minor); + method.write(enc); enc.flush(); buf.flip(); |
