From e0ba5becd0052cabe0cfa997dd35d7362bf2c472 Mon Sep 17 00:00:00 2001 From: "Rafael H. Schloming" Date: Sun, 14 Oct 2007 02:21:59 +0000 Subject: 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 --- .../java/org/apache/qpidity/transport/Echo.java | 82 ++++++++++++++ .../java/org/apache/qpidity/transport/Struct.java | 64 +++++++---- .../qpidity/transport/codec/AbstractDecoder.java | 43 +++++-- .../qpidity/transport/codec/AbstractEncoder.java | 123 +++++++++++---------- .../apache/qpidity/transport/codec/Decoder.java | 1 + .../apache/qpidity/transport/codec/Encoder.java | 1 + .../qpidity/transport/codec/SizeEncoder.java | 15 ++- .../org/apache/qpidity/transport/codec/Sizer.java | 75 +++++++++++++ 8 files changed, 315 insertions(+), 89 deletions(-) create mode 100644 qpid/java/common/src/main/java/org/apache/qpidity/transport/Echo.java create mode 100644 qpid/java/common/src/main/java/org/apache/qpidity/transport/codec/Sizer.java (limited to 'qpid/java/common/src') 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> getFields(); + public abstract int getStructType(); - public abstract int getEncodedType(); + public abstract List> 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> 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> 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 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 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 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 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 table) {}; + public void writeSequence(List sequence) {}; + public void writeArray(List array) {}; + + public int getSize() { return 0; } + + public int size() { return 0; } + }; + + int getSize(); + + int size(); + +} -- cgit v1.2.1