diff options
| author | Rafael H. Schloming <rhs@apache.org> | 2007-10-14 02:21:59 +0000 |
|---|---|---|
| committer | Rafael H. Schloming <rhs@apache.org> | 2007-10-14 02:21:59 +0000 |
| commit | e0ba5becd0052cabe0cfa997dd35d7362bf2c472 (patch) | |
| tree | 5c55f1dd6be53c4032be45ba422dacca1ded197f /qpid/java/common | |
| parent | 2a10deef36eec1b8df9ec52dfb44a72eee7059a8 (diff) | |
| download | qpid-python-e0ba5becd0052cabe0cfa997dd35d7362bf2c472.tar.gz | |
Enabled packed struct encoding in python, cpp, and java. Also fixed computation of required byte credit in Message.cpp.
git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk@584474 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'qpid/java/common')
9 files changed, 340 insertions, 131 deletions
diff --git a/qpid/java/common/generate b/qpid/java/common/generate index f3a53ee8da..701efe03a9 100755 --- a/qpid/java/common/generate +++ b/qpid/java/common/generate @@ -11,6 +11,12 @@ spec_file = sys.argv[3] spec = mllib.xml_parse(spec_file) +def jbool(b): + if b: + return "true" + else: + return "false" + class Output: def __init__(self, dir, package, name): @@ -37,11 +43,12 @@ class Output: def line(self, l = ""): self.lines.append(l) - def getter(self, type, method, variable, pre = None): + def getter(self, type, method, value, pre = None): + self.line() self.line(" public final %s %s() {" % (type, method)) if pre: self.line(" %s;" % pre) - self.line(" return %s;" % variable) + self.line(" return %s;" % value) self.line(" }") def setter(self, type, method, variable, value = None, pre = None, @@ -52,6 +59,7 @@ class Output: params = "%s value" % type value = "value" + self.line() self.line(" public final %s %s(%s) {" % (self.name, method, params)) if pre: self.line(" %s;" % pre) @@ -301,37 +309,15 @@ class Struct: def impl(self, out): out.line("public class %s extends %s {" % (self.name, self.base)) - if self.type != None: - out.line() - out.line(" public static final int TYPE = %d;" % self.type) - - out.line() - if self.type == None: - pre = "if (true) throw new UnsupportedOperationException()" - value = "0" - else: - pre = None - value = "TYPE" - out.getter("int", "getEncodedType", value, pre = pre) - out.line() + out.line(" public static final int TYPE = %d;" % self.type) + out.getter("int", "getStructType", "TYPE") 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"); + out.getter("boolean", "hasTicket", jbool(self.ticket)) if self.base == "Method": - out.line() - if self.content: - out.getter("boolean", "hasPayload", "true") - else: - out.getter("boolean", "hasPayload", "false") - - out.line() + out.getter("boolean", "hasPayload", jbool(self.content)) out.getter("byte", "getEncodedTrack", self.track) out.line() @@ -382,7 +368,6 @@ class Struct: index = 0 for type, name in self.fields: - 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"))) @@ -409,8 +394,8 @@ class Struct: if TYPES.has_key(type): out.line(' check(struct).%s = dec.read%s();' % (name, camel(0, type))) elif STRUCTS.has_key(type): - out.line(' check(struct).%s = new %s();' % (name, STRUCTS[type])) - out.line(' check(struct).%s.read(dec);' % name) + out.line(' check(struct).%s = (%s) dec.readStruct(%s.TYPE);' % + (name, STRUCTS[type], STRUCTS[type])) else: raise Exception("unknown type: %s" % type) out.line(' }') @@ -418,11 +403,8 @@ class Struct: if TYPES.has_key(type): out.line(' enc.write%s(check(struct).%s);' % (camel(0, type), name)) elif STRUCTS.has_key(type): - 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(" }") + out.line(' enc.writeStruct(%s.TYPE, check(struct).%s);' % + (STRUCTS[type], name)) else: raise Exception("unknown type: %s" % type) out.line(' }') @@ -473,6 +455,7 @@ class Visitor(mllib.transforms.Visitor): def __init__(self): self.structs = [] + self.untyped = -1 def do_method(self, m): if CLASSES.get(m.parent["@name"], True): @@ -487,11 +470,12 @@ class Visitor(mllib.transforms.Visitor): name = camel(0, d["@name"]) st = s["@type"] if st in (None, "none", ""): - type = None + type = self.untyped + self.untyped -= 1 else: type = int(st) - self.structs.append((name, "Struct", type, SIZE_WIDTHS[s["size"]], - PACK_WIDTHS[s["pack"]], s)) + self.structs.append((name, "Struct", type, SIZE_WIDTHS[s["@size"]], + PACK_WIDTHS[s["@pack"]], s)) self.descend(d) def do_result(self, r): @@ -499,8 +483,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, SIZE_WIDTHS[s["size"]], - PACK_WIDTHS[s["pack"]], s)) + self.structs.append((name, "Result", type, SIZE_WIDTHS[s["@size"]], + PACK_WIDTHS[s["@pack"]], s)) self.descend(r) v = Visitor() @@ -540,7 +524,6 @@ fct.line("class StructFactory {") fct.line(" public static Struct create(int type) {") fct.line(" switch (type) {") for s in structs: - if s.type == None: continue fct.line(" case %s.TYPE:" % s.name) fct.line(" return new %s();" % s.name) fct.line(" default:") diff --git a/qpid/java/common/src/main/java/org/apache/qpidity/transport/Echo.java b/qpid/java/common/src/main/java/org/apache/qpidity/transport/Echo.java new file mode 100644 index 0000000000..03a684dd47 --- /dev/null +++ b/qpid/java/common/src/main/java/org/apache/qpidity/transport/Echo.java @@ -0,0 +1,82 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpidity.transport; + +import java.io.IOException; +import java.nio.ByteBuffer; + +import org.apache.qpidity.transport.network.mina.MinaHandler; + + +/** + * Echo + * + */ + +public class Echo extends SessionDelegate +{ + + private MessageTransfer xfr = null; + + public void messageTransfer(Session ssn, MessageTransfer xfr) + { + this.xfr = xfr; + ssn.invoke(xfr); + } + + public void header(Session ssn, Header hdr) + { + ssn.header(hdr); + } + + public void data(Session ssn, Data data) + { + for (ByteBuffer buf : data.getFragments()) + { + ssn.data(buf); + } + if (data.isLast()) + { + ssn.endData(); + } + + // XXX: should be able to get command-id from any segment + ssn.processed(xfr); + } + + public static final void main(String[] args) throws IOException + { + ConnectionDelegate delegate = new ConnectionDelegate() + { + public SessionDelegate getSessionDelegate() + { + return new Echo(); + } + }; + + //hack + delegate.setUsername("guest"); + delegate.setPassword("guest"); + + MinaHandler.accept("0.0.0.0", 5672, delegate); + } + +} 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 b87512284f..d13af88127 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 @@ -41,14 +41,24 @@ public abstract class Struct implements Encodable return StructFactory.create(type); } - public abstract List<Field<?,?>> getFields(); + public abstract int getStructType(); - public abstract int getEncodedType(); + public abstract List<Field<?,?>> getFields(); public abstract int getSizeWidth(); public abstract int getPackWidth(); + public final int getEncodedType() + { + int type = getStructType(); + if (type < 0) + { + throw new UnsupportedOperationException(); + } + return type; + } + public abstract boolean hasTicket(); private final boolean isBit(Field<?,?> f) @@ -56,11 +66,21 @@ public abstract class Struct implements Encodable return f.getType().equals(Boolean.class); } + private final boolean packed() + { + if (this instanceof Method) + { + return false; + } + else + { + return true; + } + } + private final boolean encoded(Field<?,?> f) { - // XXX: remove to enable packed encoding - if (true) { return true; } - return !isBit(f) && f.has(this); + return !packed() || !isBit(f) && f.has(this); } private final int getFlagWidth() @@ -75,14 +95,23 @@ public abstract class Struct implements Encodable return pw; } + private final int getFlagCount() + { + return 8*getPackWidth(); + } + + private final int getReservedFlagCount() + { + return getFlagCount() - getFields().size(); + } + public final void read(Decoder dec) { List<Field<?,?>> fields = getFields(); - assert fields.size() <= 8*getPackWidth(); + assert fields.size() <= getFlagCount(); - // XXX: remove to enable packed encoding - if (false) + if (packed()) { for (Field<?,?> f : fields) { @@ -97,12 +126,11 @@ public abstract class Struct implements Encodable } } - for (int i = 0; i < getPaddWidth(); i++) + for (int i = 0; i < getReservedFlagCount(); i++) { - short padd = dec.readOctet(); - if (padd != 0x0) + if (dec.readBit()) { - throw new IllegalStateException("urecognized value in reserved bytes: " + padd); + throw new IllegalStateException("reserved flag true"); } } } @@ -125,10 +153,9 @@ public abstract class Struct implements Encodable { List<Field<?,?>> fields = getFields(); - assert fields.size() <= 8*getPackWidth(); + assert fields.size() <= getFlagCount(); - // XXX: remove to enable packed encoding - if (false) + if (packed()) { for (Field<?,?> f : fields) { @@ -142,9 +169,9 @@ public abstract class Struct implements Encodable } } - for (int i = 0; i < getPaddWidth(); i++) + for (int i = 0; i < getReservedFlagCount(); i++) { - enc.writeOctet((short) 0x0); + enc.writeBit(false); } } @@ -171,8 +198,7 @@ public abstract class Struct implements Encodable boolean first = true; for (Field<?,?> f : getFields()) { - // XXX: remove when packed encoding is enabled - if (false) + if (packed()) { if (!f.has(this)) { 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 e5997d6642..0e06b9e88c 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 @@ -186,6 +186,22 @@ abstract class AbstractDecoder implements Decoder throw new Error("Deprecated"); } + public Struct readStruct(int type) + { + Struct st = Struct.create(type); + int width = st.getSizeWidth(); + if (false && width > 0) + { + long size = readSize(width); + if (size == 0) + { + return null; + } + } + st.read(this); + return st; + } + public Struct readLongStruct() { long size = readLong(); @@ -270,17 +286,22 @@ abstract class AbstractDecoder implements Decoder } else { - switch (t.width) - { - case 1: - return readOctet(); - case 2: - return readShort(); - case 4: - return readLong(); - default: - throw new IllegalStateException("irregular width: " + t); - } + return readSize(t.width); + } + } + + private long readSize(int width) + { + switch (width) + { + case 1: + return readOctet(); + case 2: + return readShort(); + case 4: + return readLong(); + default: + throw new IllegalStateException("illegal width: " + width); } } 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 06e44fb1c6..e2b5cd41b8 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 @@ -61,20 +61,19 @@ abstract class AbstractEncoder implements Encoder ENCODINGS.put(byte[].class, Type.LONG_BINARY); } + // XXX: no longer need major/minor private final byte major; private final byte minor; - private final boolean calcsize; - protected AbstractEncoder(byte major, byte minor, boolean calcsize) + protected AbstractEncoder(byte major, byte minor) { this.major = major; this.minor = minor; - this.calcsize = calcsize; } - protected AbstractEncoder(byte major, byte minor) + protected Sizer sizer() { - this(major, minor, true); + return new SizeEncoder(major, minor); } protected abstract void doPut(byte b); @@ -224,25 +223,45 @@ abstract class AbstractEncoder implements Encoder throw new Error("Deprecated"); } - public void writeLongStruct(Struct s) + public void writeStruct(int type, Struct s) { + boolean empty = false; if (s == null) { - writeLong(0); + s = Struct.create(type); + empty = true; } - else + + int width = s.getSizeWidth(); + if (false && width > 0) { - int size = 0; - if (calcsize) + if (empty) { - SizeEncoder sizer = new SizeEncoder(major, minor); - sizer.writeShort(s.getEncodedType()); + writeSize(width, 0); + } + else + { + Sizer sizer = sizer(); s.write(sizer); - sizer.flush(); - size = sizer.getSize(); + writeSize(width, sizer.size()); } + } - writeLong(size); + s.write(this); + } + + public void writeLongStruct(Struct s) + { + if (s == null) + { + writeLong(0); + } + else + { + Sizer sizer = sizer(); + sizer.writeShort(s.getEncodedType()); + s.write(sizer); + writeLong(sizer.size()); writeShort(s.getEncodedType()); s.write(this); } @@ -308,15 +327,10 @@ abstract class AbstractEncoder implements Encoder return; } - int size = 0; - if (calcsize) - { - SizeEncoder sizer = new SizeEncoder(major, minor); - sizer.writeTableEntries(table); - size = sizer.getSize(); - } - - writeLong(size); + Sizer sizer = sizer(); + sizer.writeTable(table); + // XXX: - 4 + writeLong(sizer.size() - 4); writeTableEntries(table); } @@ -335,15 +349,10 @@ abstract class AbstractEncoder implements Encoder public void writeSequence(List<Object> sequence) { - int size = 0; - if (calcsize) - { - SizeEncoder sizer = new SizeEncoder(major, minor); - sizer.writeSequenceEntries(sequence); - size = sizer.getSize(); - } - - writeLong(size); + Sizer sizer = sizer(); + sizer.writeSequence(sequence); + // XXX: - 4 + writeLong(sizer.size() - 4); writeSequenceEntries(sequence); } @@ -359,15 +368,10 @@ abstract class AbstractEncoder implements Encoder public void writeArray(List<Object> array) { - int size = 0; - if (calcsize) - { - SizeEncoder sizer = new SizeEncoder(major, minor); - sizer.writeArrayEntries(array); - size = sizer.getSize(); - } - - writeLong(size); + Sizer sizer = sizer(); + sizer.writeArray(array); + // XXX: -4 + writeLong(sizer.size() - 4); writeArrayEntries(array); } @@ -405,21 +409,26 @@ abstract class AbstractEncoder implements Encoder } else { - // XXX: should check lengths - switch (t.width) - { - case 1: - writeOctet((short) size); - break; - case 2: - writeShort(size); - break; - case 4: - writeLong(size); - break; - default: - throw new IllegalStateException("irregular width: " + t); - } + writeSize(t.width, size); + } + } + + private void writeSize(int width, int size) + { + // XXX: should check lengths + switch (width) + { + case 1: + writeOctet((short) size); + break; + case 2: + writeShort(size); + break; + case 4: + writeLong(size); + break; + default: + throw new IllegalStateException("illegal width: " + width); } } diff --git a/qpid/java/common/src/main/java/org/apache/qpidity/transport/codec/Decoder.java b/qpid/java/common/src/main/java/org/apache/qpidity/transport/codec/Decoder.java index 36cc13b7db..f0738e0a91 100644 --- a/qpid/java/common/src/main/java/org/apache/qpidity/transport/codec/Decoder.java +++ b/qpid/java/common/src/main/java/org/apache/qpidity/transport/codec/Decoder.java @@ -53,6 +53,7 @@ public interface Decoder String readContent(); + Struct readStruct(int type); Struct readLongStruct(); Map<String,Object> readTable(); diff --git a/qpid/java/common/src/main/java/org/apache/qpidity/transport/codec/Encoder.java b/qpid/java/common/src/main/java/org/apache/qpidity/transport/codec/Encoder.java index 5490bdd904..1b2fe0213e 100644 --- a/qpid/java/common/src/main/java/org/apache/qpidity/transport/codec/Encoder.java +++ b/qpid/java/common/src/main/java/org/apache/qpidity/transport/codec/Encoder.java @@ -55,6 +55,7 @@ public interface Encoder void writeContent(String c); + void writeStruct(int type, Struct s); void writeLongStruct(Struct s); void writeTable(Map<String,Object> table); diff --git a/qpid/java/common/src/main/java/org/apache/qpidity/transport/codec/SizeEncoder.java b/qpid/java/common/src/main/java/org/apache/qpidity/transport/codec/SizeEncoder.java index 4f39709554..aba269ef08 100644 --- a/qpid/java/common/src/main/java/org/apache/qpidity/transport/codec/SizeEncoder.java +++ b/qpid/java/common/src/main/java/org/apache/qpidity/transport/codec/SizeEncoder.java @@ -31,7 +31,7 @@ import java.util.Map; * @author Rafael H. Schloming */ -public class SizeEncoder extends AbstractEncoder +public class SizeEncoder extends AbstractEncoder implements Sizer { private int size; @@ -41,10 +41,15 @@ public class SizeEncoder extends AbstractEncoder } public SizeEncoder(byte major, byte minor, int size) { - super(major, minor, false); + super(major, minor); this.size = size; } + protected Sizer sizer() + { + return Sizer.NULL; + } + public int getSize() { return size; } @@ -53,6 +58,12 @@ public class SizeEncoder extends AbstractEncoder this.size = size; } + public int size() + { + flush(); + return getSize(); + } + protected void doPut(byte b) { size += 1; diff --git a/qpid/java/common/src/main/java/org/apache/qpidity/transport/codec/Sizer.java b/qpid/java/common/src/main/java/org/apache/qpidity/transport/codec/Sizer.java new file mode 100644 index 0000000000..b98bf98239 --- /dev/null +++ b/qpid/java/common/src/main/java/org/apache/qpidity/transport/codec/Sizer.java @@ -0,0 +1,75 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpidity.transport.codec; + +import java.util.List; +import java.util.Map; +import java.util.UUID; + +import org.apache.qpidity.transport.RangeSet; +import org.apache.qpidity.transport.Struct; + + +/** + * Sizer + * + */ + +public interface Sizer extends Encoder +{ + + public static final Sizer NULL = new Sizer() + { + public void flush() {}; + + public void writeBit(boolean b) {}; + public void writeOctet(short b) {}; + public void writeShort(int s) {}; + public void writeLong(long i) {}; + public void writeLonglong(long l) {}; + + public void writeTimestamp(long l) {}; + + public void writeShortstr(String s) {}; + public void writeLongstr(String s) {}; + + public void writeRfc1982LongSet(RangeSet ranges) {}; + public void writeUuid(UUID uuid) {}; + + public void writeContent(String c) {}; + + public void writeStruct(int type, Struct s) {}; + public void writeLongStruct(Struct s) {}; + + public void writeTable(Map<String,Object> table) {}; + public void writeSequence(List<Object> sequence) {}; + public void writeArray(List<Object> array) {}; + + public int getSize() { return 0; } + + public int size() { return 0; } + }; + + int getSize(); + + int size(); + +} |
