From 1fef82b3a736c4cf3d7bf22b1195595dbcddb7a1 Mon Sep 17 00:00:00 2001 From: "Rafael H. Schloming" Date: Thu, 4 Oct 2007 17:44:59 +0000 Subject: moved codec --> transport.codec to avoid conflicts with qpid namespace git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk/qpid@581973 13f79535-47bb-0310-9956-ffa450edef68 --- .../org/apache/qpidity/codec/AbstractDecoder.java | 381 -------------- .../org/apache/qpidity/codec/AbstractEncoder.java | 560 --------------------- .../java/org/apache/qpidity/codec/BBDecoder.java | 53 -- .../java/org/apache/qpidity/codec/BBEncoder.java | 52 -- .../java/org/apache/qpidity/codec/Decoder.java | 62 --- .../java/org/apache/qpidity/codec/Encodable.java | 37 -- .../java/org/apache/qpidity/codec/Encoder.java | 64 --- .../org/apache/qpidity/codec/FragmentDecoder.java | 111 ---- .../java/org/apache/qpidity/codec/SizeEncoder.java | 66 --- .../java/org/apache/qpidity/transport/Struct.java | 2 +- .../qpidity/transport/codec/AbstractDecoder.java | 381 ++++++++++++++ .../qpidity/transport/codec/AbstractEncoder.java | 560 +++++++++++++++++++++ .../apache/qpidity/transport/codec/BBDecoder.java | 53 ++ .../apache/qpidity/transport/codec/BBEncoder.java | 52 ++ .../apache/qpidity/transport/codec/Decoder.java | 62 +++ .../apache/qpidity/transport/codec/Encodable.java | 37 ++ .../apache/qpidity/transport/codec/Encoder.java | 64 +++ .../qpidity/transport/codec/FragmentDecoder.java | 111 ++++ .../qpidity/transport/codec/SizeEncoder.java | 66 +++ .../qpidity/transport/network/Assembler.java | 2 +- .../qpidity/transport/network/Disassembler.java | 4 +- 21 files changed, 1390 insertions(+), 1390 deletions(-) delete mode 100644 java/common/src/main/java/org/apache/qpidity/codec/AbstractDecoder.java delete mode 100644 java/common/src/main/java/org/apache/qpidity/codec/AbstractEncoder.java delete mode 100644 java/common/src/main/java/org/apache/qpidity/codec/BBDecoder.java delete mode 100644 java/common/src/main/java/org/apache/qpidity/codec/BBEncoder.java delete mode 100644 java/common/src/main/java/org/apache/qpidity/codec/Decoder.java delete mode 100644 java/common/src/main/java/org/apache/qpidity/codec/Encodable.java delete mode 100644 java/common/src/main/java/org/apache/qpidity/codec/Encoder.java delete mode 100644 java/common/src/main/java/org/apache/qpidity/codec/FragmentDecoder.java delete mode 100644 java/common/src/main/java/org/apache/qpidity/codec/SizeEncoder.java create mode 100644 java/common/src/main/java/org/apache/qpidity/transport/codec/AbstractDecoder.java create mode 100644 java/common/src/main/java/org/apache/qpidity/transport/codec/AbstractEncoder.java create mode 100644 java/common/src/main/java/org/apache/qpidity/transport/codec/BBDecoder.java create mode 100644 java/common/src/main/java/org/apache/qpidity/transport/codec/BBEncoder.java create mode 100644 java/common/src/main/java/org/apache/qpidity/transport/codec/Decoder.java create mode 100644 java/common/src/main/java/org/apache/qpidity/transport/codec/Encodable.java create mode 100644 java/common/src/main/java/org/apache/qpidity/transport/codec/Encoder.java create mode 100644 java/common/src/main/java/org/apache/qpidity/transport/codec/FragmentDecoder.java create mode 100644 java/common/src/main/java/org/apache/qpidity/transport/codec/SizeEncoder.java (limited to 'java/common/src') diff --git a/java/common/src/main/java/org/apache/qpidity/codec/AbstractDecoder.java b/java/common/src/main/java/org/apache/qpidity/codec/AbstractDecoder.java deleted file mode 100644 index f8d7146d6c..0000000000 --- a/java/common/src/main/java/org/apache/qpidity/codec/AbstractDecoder.java +++ /dev/null @@ -1,381 +0,0 @@ -/* - * - * 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.codec; - -import java.util.ArrayList; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.UUID; - -import org.apache.qpidity.transport.RangeSet; -import org.apache.qpidity.transport.Struct; -import org.apache.qpidity.transport.Type; - -import static org.apache.qpidity.transport.util.Functions.*; - - -/** - * AbstractDecoder - * - * @author Rafael H. Schloming - */ - -abstract class AbstractDecoder implements Decoder -{ - - private final byte major; - private final byte minor; - private int count; - - protected AbstractDecoder(byte major, byte minor) - { - this.major = major; - this.minor = minor; - this.count = 0; - } - - protected abstract byte doGet(); - - protected abstract void doGet(byte[] bytes); - - protected byte get() - { - clearBits(); - byte b = doGet(); - count += 1; - return b; - } - - protected void get(byte[] bytes) - { - clearBits(); - doGet(bytes); - count += bytes.length; - } - - protected short uget() - { - return (short) (0xFF & get()); - } - - private byte bits = 0x0; - private byte nbits = 0; - - public boolean readBit() - { - if (nbits == 0) - { - bits = get(); - } - - boolean result = (bits & (1 << nbits++)) != 0; - return result; - } - - private void clearBits() - { - bits = 0x0; - nbits = 0; - } - - public short readOctet() - { - return uget(); - } - - public int readShort() - { - int i = uget() << 8; - i |= uget(); - return i; - } - - public long readLong() - { - long l = uget() << 24; - l |= uget() << 16; - l |= uget() << 8; - l |= uget(); - return l; - } - - public long readLonglong() - { - long l = 0; - for (int i = 0; i < 8; i++) - { - l |= ((long) (0xFF & get())) << (56 - i*8); - } - return l; - } - - public long readTimestamp() - { - return readLonglong(); - } - - - public String readShortstr() - { - short size = readOctet(); - byte[] bytes = new byte[size]; - get(bytes); - return new String(bytes); - } - - public String readLongstr() - { - long size = readLong(); - byte[] bytes = new byte[(int) size]; - get(bytes); - return new String(bytes); - } - - public RangeSet readRfc1982LongSet() - { - int count = readShort()/8; - if (count == 0) - { - return null; - } - else - { - RangeSet ranges = new RangeSet(); - for (int i = 0; i < count; i++) - { - ranges.add(readLong(), readLong()); - } - return ranges; - } - } - - public UUID readUuid() - { - long msb = readLonglong(); - long lsb = readLonglong(); - return new UUID(msb, lsb); - } - - public String readContent() - { - throw new Error("Deprecated"); - } - - public Struct readLongStruct() - { - long size = readLong(); - if (size == 0) - { - return null; - } - else - { - int type = readShort(); - Struct result = Struct.create(type); - result.read(this, major, minor); - return result; - } - } - - public Map readTable() - { - long size = readLong(); - int start = count; - Map result = new LinkedHashMap(); - while (count < start + size) - { - String key = readShortstr(); - byte code = get(); - Type t = getType(code); - Object value = read(t); - result.put(key, value); - } - return result; - } - - public List readSequence() - { - long size = readLong(); - int start = count; - List result = new ArrayList(); - while (count < start + size) - { - byte code = get(); - Type t = getType(code); - Object value = read(t); - result.add(value); - } - return result; - } - - public List readArray() - { - long size = readLong(); - byte code = get(); - Type t = getType(code); - long count = readLong(); - - List result = new ArrayList(); - for (int i = 0; i < count; i++) - { - Object value = read(t); - result.add(value); - } - return result; - } - - private Type getType(byte code) - { - Type type = Type.get(code); - if (type == null) - { - throw new IllegalArgumentException("unknown code: " + code); - } - else - { - return type; - } - } - - private long readSize(Type t) - { - if (t.fixed) - { - return t.width; - } - else - { - switch (t.width) - { - case 1: - return readOctet(); - case 2: - return readShort(); - case 4: - return readLong(); - default: - throw new IllegalStateException("irregular width: " + t); - } - } - } - - private byte[] readBytes(Type t) - { - long size = readSize(t); - byte[] result = new byte[(int) size]; - get(result); - return result; - } - - private Object read(Type t) - { - switch (t) - { - case OCTET: - case UNSIGNED_BYTE: - return readOctet(); - case SIGNED_BYTE: - return get(); - case CHAR: - return (char) get(); - case BOOLEAN: - return get() > 0; - - case TWO_OCTETS: - case UNSIGNED_SHORT: - return readShort(); - - case SIGNED_SHORT: - return (short) readShort(); - - case FOUR_OCTETS: - case UNSIGNED_INT: - return readLong(); - - case UTF32_CHAR: - case SIGNED_INT: - return (int) readLong(); - - case FLOAT: - return Float.intBitsToFloat((int) readLong()); - - case EIGHT_OCTETS: - case SIGNED_LONG: - case UNSIGNED_LONG: - case DATETIME: - return readLonglong(); - - case DOUBLE: - long bits = readLonglong(); - System.out.println("double in: " + bits); - return Double.longBitsToDouble(bits); - - case SIXTEEN_OCTETS: - case THIRTY_TWO_OCTETS: - case SIXTY_FOUR_OCTETS: - case _128_OCTETS: - case SHORT_BINARY: - case BINARY: - case LONG_BINARY: - return readBytes(t); - - case UUID: - return readUuid(); - - case SHORT_STRING: - case SHORT_UTF8_STRING: - case SHORT_UTF16_STRING: - case SHORT_UTF32_STRING: - case STRING: - case UTF8_STRING: - case UTF16_STRING: - case UTF32_STRING: - case LONG_STRING: - case LONG_UTF8_STRING: - case LONG_UTF16_STRING: - case LONG_UTF32_STRING: - // XXX: need to do character conversion - return new String(readBytes(t)); - - case TABLE: - return readTable(); - case SEQUENCE: - return readSequence(); - case ARRAY: - return readArray(); - - case FIVE_OCTETS: - case DECIMAL: - case NINE_OCTETS: - case LONG_DECIMAL: - // XXX: what types are we supposed to use here? - return readBytes(t); - - case VOID: - return null; - - default: - return readBytes(t); - } - } - -} diff --git a/java/common/src/main/java/org/apache/qpidity/codec/AbstractEncoder.java b/java/common/src/main/java/org/apache/qpidity/codec/AbstractEncoder.java deleted file mode 100644 index 01cb13c687..0000000000 --- a/java/common/src/main/java/org/apache/qpidity/codec/AbstractEncoder.java +++ /dev/null @@ -1,560 +0,0 @@ -/* - * - * 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.codec; - -import java.nio.ByteBuffer; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.UUID; - -import org.apache.qpidity.transport.Range; -import org.apache.qpidity.transport.RangeSet; -import org.apache.qpidity.transport.Struct; -import org.apache.qpidity.transport.Type; - -import static org.apache.qpidity.transport.util.Functions.*; - - -/** - * AbstractEncoder - * - * @author Rafael H. Schloming - */ - -abstract class AbstractEncoder implements Encoder -{ - - private static Map,Type> ENCODINGS = new HashMap,Type>(); - static - { - ENCODINGS.put(String.class, Type.LONG_STRING); - ENCODINGS.put(Long.class, Type.SIGNED_LONG); - ENCODINGS.put(Integer.class, Type.SIGNED_INT); - ENCODINGS.put(Short.class, Type.SIGNED_SHORT); - ENCODINGS.put(Byte.class, Type.SIGNED_BYTE); - ENCODINGS.put(Map.class, Type.TABLE); - ENCODINGS.put(List.class, Type.SEQUENCE); - ENCODINGS.put(Float.class, Type.FLOAT); - ENCODINGS.put(Double.class, Type.DOUBLE); - ENCODINGS.put(Character.class, Type.CHAR); - ENCODINGS.put(byte[].class, Type.LONG_BINARY); - } - - private final byte major; - private final byte minor; - private final boolean calcsize; - - protected AbstractEncoder(byte major, byte minor, boolean calcsize) - { - this.major = major; - this.minor = minor; - this.calcsize = calcsize; - } - - protected AbstractEncoder(byte major, byte minor) - { - this(major, minor, true); - } - - protected abstract void doPut(byte b); - - protected abstract void doPut(ByteBuffer src); - - protected void put(byte b) - { - flushBits(); - doPut(b); - } - - protected void put(ByteBuffer src) - { - flushBits(); - doPut(src); - } - - protected void put(byte[] bytes) - { - put(ByteBuffer.wrap(bytes)); - } - - private byte bits = 0x0; - private byte nbits = 0; - - public void writeBit(boolean b) - { - if (b) - { - bits |= 1 << nbits; - } - - nbits += 1; - - if (nbits == 8) - { - flushBits(); - } - } - - private void flushBits() - { - if (nbits > 0) - { - doPut(bits); - bits = 0x0; - nbits = 0; - } - } - - public void flush() - { - flushBits(); - } - - public void writeOctet(short b) - { - assert b < 0x100; - - put((byte) b); - } - - public void writeShort(int s) - { - assert s < 0x10000; - - put(lsb(s >>> 8)); - put(lsb(s)); - } - - public void writeLong(long i) - { - assert i < 0x100000000L; - - put(lsb(i >>> 24)); - put(lsb(i >>> 16)); - put(lsb(i >>> 8)); - put(lsb(i)); - } - - public void writeLonglong(long l) - { - for (int i = 0; i < 8; i++) - { - put(lsb(l >> (56 - i*8))); - } - } - - - public void writeTimestamp(long l) - { - writeLonglong(l); - } - - - public void writeShortstr(String s) - { - if (s == null) { s = ""; } - if (s.length() > 255) { - throw new IllegalArgumentException(s); - } - writeOctet((short) s.length()); - put(ByteBuffer.wrap(s.getBytes())); - } - - public void writeLongstr(String s) - { - if (s == null) { s = ""; } - writeLong(s.length()); - put(ByteBuffer.wrap(s.getBytes())); - } - - - public void writeRfc1982LongSet(RangeSet ranges) - { - if (ranges == null) - { - writeShort((short) 0); - } - else - { - writeShort(ranges.size() * 8); - for (Range range : ranges) - { - writeLong(range.getLower()); - writeLong(range.getUpper()); - } - } - } - - public void writeUuid(UUID uuid) - { - long msb = 0; - long lsb = 0; - if (uuid != null) - { - msb = uuid.getMostSignificantBits(); - uuid.getLeastSignificantBits(); - } - writeLonglong(msb); - writeLonglong(lsb); - } - - public void writeContent(String c) - { - throw new Error("Deprecated"); - } - - public void writeLongStruct(Struct s) - { - if (s == null) - { - writeLong(0); - } - else - { - int size = 0; - if (calcsize) - { - SizeEncoder sizer = new SizeEncoder(major, minor); - sizer.writeShort(s.getEncodedType()); - s.write(sizer, major, minor); - size = sizer.getSize(); - } - - writeLong(size); - writeShort(s.getEncodedType()); - s.write(this, major, minor); - } - } - - private Type encoding(Object value) - { - if (value == null) - { - return Type.VOID; - } - - Class klass = value.getClass(); - Type type = resolve(klass); - - if (type == null) - { - throw new IllegalArgumentException - ("unable to resolve type: " + klass + ", " + value); - } - else - { - return type; - } - } - - private Type resolve(Class klass) - { - Type type = ENCODINGS.get(klass); - if (type != null) - { - return type; - } - - Class sup = klass.getSuperclass(); - if (sup != null) - { - type = resolve(klass.getSuperclass()); - - if (type != null) - { - return type; - } - } - - for (Class iface : klass.getInterfaces()) - { - type = resolve(iface); - if (type != null) - { - return type; - } - } - - return null; - } - - public void writeTable(Map table) - { - if (table == null) - { - writeLong(0); - return; - } - - int size = 0; - if (calcsize) - { - SizeEncoder sizer = new SizeEncoder(major, minor); - sizer.writeTableEntries(table); - size = sizer.getSize(); - } - - writeLong(size); - writeTableEntries(table); - } - - protected void writeTableEntries(Map table) - { - for (Map.Entry entry : table.entrySet()) - { - String key = entry.getKey(); - Object value = entry.getValue(); - Type type = encoding(value); - writeShortstr(key); - put(type.code); - write(type, value); - } - } - - public void writeSequence(List sequence) - { - int size = 0; - if (calcsize) - { - SizeEncoder sizer = new SizeEncoder(major, minor); - sizer.writeSequenceEntries(sequence); - size = sizer.getSize(); - } - - writeLong(size); - writeSequenceEntries(sequence); - } - - protected void writeSequenceEntries(List sequence) - { - for (Object value : sequence) - { - Type type = encoding(value); - put(type.code); - write(type, value); - } - } - - public void writeArray(List array) - { - int size = 0; - if (calcsize) - { - SizeEncoder sizer = new SizeEncoder(major, minor); - sizer.writeArrayEntries(array); - size = sizer.getSize(); - } - - writeLong(size); - writeArrayEntries(array); - } - - protected void writeArrayEntries(List array) - { - Type type; - - if (array.isEmpty()) - { - type = Type.VOID; - } - else - { - type = encoding(array.get(0)); - } - - put(type.code); - - for (Object value : array) - { - write(type, value); - } - } - - private void writeSize(Type t, int size) - { - if (t.fixed) - { - if (size != t.width) - { - throw new IllegalArgumentException - ("size does not match fixed width " + t.width + ": " + - size); - } - } - 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); - } - } - } - - private void writeBytes(Type t, byte[] bytes) - { - writeSize(t, bytes.length); - put(bytes); - } - - private T coerce(Class klass, Object value) - { - if (klass.isInstance(value)) - { - return klass.cast(value); - } - else - { - throw new IllegalArgumentException("" + value); - } - } - - private void write(Type t, Object value) - { - switch (t) - { - case OCTET: - case UNSIGNED_BYTE: - writeOctet(coerce(Short.class, value)); - break; - case SIGNED_BYTE: - put(coerce(Byte.class, value)); - break; - case CHAR: - put((byte) ((char)coerce(Character.class, value))); - break; - case BOOLEAN: - if (coerce(Boolean.class, value)) - { - put((byte) 1); - } - else - { - put((byte) 0); - } - break; - - case TWO_OCTETS: - case UNSIGNED_SHORT: - writeShort(coerce(Integer.class, value)); - break; - - case SIGNED_SHORT: - writeShort(coerce(Short.class, value)); - break; - - case FOUR_OCTETS: - case UNSIGNED_INT: - writeLong(coerce(Long.class, value)); - break; - - case UTF32_CHAR: - case SIGNED_INT: - writeLong(coerce(Integer.class, value)); - break; - - case FLOAT: - writeLong(Float.floatToIntBits(coerce(Float.class, value))); - break; - - case EIGHT_OCTETS: - case SIGNED_LONG: - case UNSIGNED_LONG: - case DATETIME: - writeLonglong(coerce(Long.class, value)); - break; - - case DOUBLE: - long bits = Double.doubleToLongBits(coerce(Double.class, value)); - System.out.println("double out: " + bits); - writeLonglong(bits); - break; - - case SIXTEEN_OCTETS: - case THIRTY_TWO_OCTETS: - case SIXTY_FOUR_OCTETS: - case _128_OCTETS: - case SHORT_BINARY: - case BINARY: - case LONG_BINARY: - writeBytes(t, coerce(byte[].class, value)); - break; - - case UUID: - writeUuid(coerce(UUID.class, value)); - break; - - case SHORT_STRING: - case SHORT_UTF8_STRING: - case SHORT_UTF16_STRING: - case SHORT_UTF32_STRING: - case STRING: - case UTF8_STRING: - case UTF16_STRING: - case UTF32_STRING: - case LONG_STRING: - case LONG_UTF8_STRING: - case LONG_UTF16_STRING: - case LONG_UTF32_STRING: - // XXX: need to do character conversion - writeBytes(t, coerce(String.class, value).getBytes()); - break; - - case TABLE: - writeTable((Map) coerce(Map.class, value)); - break; - case SEQUENCE: - writeSequence(coerce(List.class, value)); - break; - case ARRAY: - writeArray(coerce(List.class, value)); - break; - - case FIVE_OCTETS: - case DECIMAL: - case NINE_OCTETS: - case LONG_DECIMAL: - // XXX: what types are we supposed to use here? - writeBytes(t, coerce(byte[].class, value)); - break; - - case VOID: - break; - - default: - writeBytes(t, coerce(byte[].class, value)); - break; - } - } - -} diff --git a/java/common/src/main/java/org/apache/qpidity/codec/BBDecoder.java b/java/common/src/main/java/org/apache/qpidity/codec/BBDecoder.java deleted file mode 100644 index 111835882e..0000000000 --- a/java/common/src/main/java/org/apache/qpidity/codec/BBDecoder.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * - * 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.codec; - -import java.nio.ByteBuffer; - - -/** - * BBDecoder - * - * @author Rafael H. Schloming - */ - -public class BBDecoder extends AbstractDecoder -{ - - private final ByteBuffer in; - - public BBDecoder(byte major, byte minor, ByteBuffer in) - { - super(major, minor); - this.in = in; - } - - protected byte doGet() - { - return in.get(); - } - - protected void doGet(byte[] bytes) - { - in.get(bytes); - } - -} diff --git a/java/common/src/main/java/org/apache/qpidity/codec/BBEncoder.java b/java/common/src/main/java/org/apache/qpidity/codec/BBEncoder.java deleted file mode 100644 index 7aa21c5871..0000000000 --- a/java/common/src/main/java/org/apache/qpidity/codec/BBEncoder.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * - * 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.codec; - -import java.nio.ByteBuffer; - - -/** - * BBEncoder - * - * @author Rafael H. Schloming - */ - -public class BBEncoder extends AbstractEncoder -{ - - private final ByteBuffer out; - - public BBEncoder(byte major, byte minor, ByteBuffer out) { - super(major, minor); - this.out = out; - } - - protected void doPut(byte b) - { - out.put(b); - } - - protected void doPut(ByteBuffer src) - { - out.put(src); - } - -} diff --git a/java/common/src/main/java/org/apache/qpidity/codec/Decoder.java b/java/common/src/main/java/org/apache/qpidity/codec/Decoder.java deleted file mode 100644 index 9ed02cdb42..0000000000 --- a/java/common/src/main/java/org/apache/qpidity/codec/Decoder.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * - * 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.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; - - -/** - * Decoder - * - * @author Rafael H. Schloming - */ - -public interface Decoder -{ - - boolean readBit(); - short readOctet(); - int readShort(); - long readLong(); - long readLonglong(); - - long readTimestamp(); - - String readShortstr(); - String readLongstr(); - - RangeSet readRfc1982LongSet(); - UUID readUuid(); - - String readContent(); - - Struct readLongStruct(); - - Map readTable(); - List readSequence(); - List readArray(); - -} diff --git a/java/common/src/main/java/org/apache/qpidity/codec/Encodable.java b/java/common/src/main/java/org/apache/qpidity/codec/Encodable.java deleted file mode 100644 index b57c12fefe..0000000000 --- a/java/common/src/main/java/org/apache/qpidity/codec/Encodable.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * - * 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.codec; - - -/** - * Encodable - * - * @author Rafael H. Schloming - */ - -public interface Encodable -{ - - void write(Encoder enc, byte major, byte minor); - - void read(Decoder dec, byte major, byte minor); - -} diff --git a/java/common/src/main/java/org/apache/qpidity/codec/Encoder.java b/java/common/src/main/java/org/apache/qpidity/codec/Encoder.java deleted file mode 100644 index 1824a41895..0000000000 --- a/java/common/src/main/java/org/apache/qpidity/codec/Encoder.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * - * 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.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; - - -/** - * Encoder - * - * @author Rafael H. Schloming - */ - -public interface Encoder -{ - - void flush(); - - void writeBit(boolean b); - void writeOctet(short b); - void writeShort(int s); - void writeLong(long i); - void writeLonglong(long l); - - void writeTimestamp(long l); - - void writeShortstr(String s); - void writeLongstr(String s); - - void writeRfc1982LongSet(RangeSet ranges); - void writeUuid(UUID uuid); - - void writeContent(String c); - - void writeLongStruct(Struct s); - - void writeTable(Map table); - void writeSequence(List sequence); - void writeArray(List array); - -} diff --git a/java/common/src/main/java/org/apache/qpidity/codec/FragmentDecoder.java b/java/common/src/main/java/org/apache/qpidity/codec/FragmentDecoder.java deleted file mode 100644 index cc4489c8c3..0000000000 --- a/java/common/src/main/java/org/apache/qpidity/codec/FragmentDecoder.java +++ /dev/null @@ -1,111 +0,0 @@ -/* - * - * 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.codec; - -import java.nio.BufferUnderflowException; -import java.nio.ByteBuffer; - -import java.util.Iterator; - -import static java.lang.Math.*; - - -/** - * FragmentDecoder - * - * @author Rafael H. Schloming - */ - -public class FragmentDecoder extends AbstractDecoder -{ - - private final Iterator fragments; - private ByteBuffer current; - - public FragmentDecoder(byte major, byte minor, Iterator fragments) - { - super(major, minor); - this.fragments = fragments; - this.current = null; - } - - public boolean hasRemaining() - { - advance(); - return current != null || fragments.hasNext(); - } - - private void advance() - { - while (current == null && fragments.hasNext()) - { - current = fragments.next(); - if (current.hasRemaining()) - { - break; - } - else - { - current = null; - } - } - } - - private void preRead() - { - advance(); - - if (current == null) - { - throw new BufferUnderflowException(); - } - } - - private void postRead() - { - if (current.remaining() == 0) - { - current = null; - } - } - - protected byte doGet() - { - preRead(); - byte b = current.get(); - postRead(); - return b; - } - - protected void doGet(byte[] bytes) - { - int remaining = bytes.length; - while (remaining > 0) - { - preRead(); - int size = min(remaining, current.remaining()); - current.get(bytes, 0, size); - remaining -= size; - postRead(); - } - } - -} diff --git a/java/common/src/main/java/org/apache/qpidity/codec/SizeEncoder.java b/java/common/src/main/java/org/apache/qpidity/codec/SizeEncoder.java deleted file mode 100644 index 5d4066f850..0000000000 --- a/java/common/src/main/java/org/apache/qpidity/codec/SizeEncoder.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * - * 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.codec; - -import java.nio.ByteBuffer; - -import java.util.Map; - - -/** - * SizeEncoder - * - * @author Rafael H. Schloming - */ - -public class SizeEncoder extends AbstractEncoder -{ - - private int size; - - public SizeEncoder(byte major, byte minor) { - this(major, minor, 0); - } - - public SizeEncoder(byte major, byte minor, int size) { - super(major, minor, false); - this.size = size; - } - - public int getSize() { - return size; - } - - public void setSize(int size) { - this.size = size; - } - - protected void doPut(byte b) - { - size += 1; - } - - protected void doPut(ByteBuffer src) - { - size += src.remaining(); - } - -} diff --git a/java/common/src/main/java/org/apache/qpidity/transport/Struct.java b/java/common/src/main/java/org/apache/qpidity/transport/Struct.java index f6464780e7..a3a07e9ebe 100644 --- a/java/common/src/main/java/org/apache/qpidity/transport/Struct.java +++ b/java/common/src/main/java/org/apache/qpidity/transport/Struct.java @@ -20,7 +20,7 @@ */ package org.apache.qpidity.transport; -import org.apache.qpidity.codec.Encodable; +import org.apache.qpidity.transport.codec.Encodable; /** diff --git a/java/common/src/main/java/org/apache/qpidity/transport/codec/AbstractDecoder.java b/java/common/src/main/java/org/apache/qpidity/transport/codec/AbstractDecoder.java new file mode 100644 index 0000000000..25151c5bcf --- /dev/null +++ b/java/common/src/main/java/org/apache/qpidity/transport/codec/AbstractDecoder.java @@ -0,0 +1,381 @@ +/* + * + * 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.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.UUID; + +import org.apache.qpidity.transport.RangeSet; +import org.apache.qpidity.transport.Struct; +import org.apache.qpidity.transport.Type; + +import static org.apache.qpidity.transport.util.Functions.*; + + +/** + * AbstractDecoder + * + * @author Rafael H. Schloming + */ + +abstract class AbstractDecoder implements Decoder +{ + + private final byte major; + private final byte minor; + private int count; + + protected AbstractDecoder(byte major, byte minor) + { + this.major = major; + this.minor = minor; + this.count = 0; + } + + protected abstract byte doGet(); + + protected abstract void doGet(byte[] bytes); + + protected byte get() + { + clearBits(); + byte b = doGet(); + count += 1; + return b; + } + + protected void get(byte[] bytes) + { + clearBits(); + doGet(bytes); + count += bytes.length; + } + + protected short uget() + { + return (short) (0xFF & get()); + } + + private byte bits = 0x0; + private byte nbits = 0; + + public boolean readBit() + { + if (nbits == 0) + { + bits = get(); + } + + boolean result = (bits & (1 << nbits++)) != 0; + return result; + } + + private void clearBits() + { + bits = 0x0; + nbits = 0; + } + + public short readOctet() + { + return uget(); + } + + public int readShort() + { + int i = uget() << 8; + i |= uget(); + return i; + } + + public long readLong() + { + long l = uget() << 24; + l |= uget() << 16; + l |= uget() << 8; + l |= uget(); + return l; + } + + public long readLonglong() + { + long l = 0; + for (int i = 0; i < 8; i++) + { + l |= ((long) (0xFF & get())) << (56 - i*8); + } + return l; + } + + public long readTimestamp() + { + return readLonglong(); + } + + + public String readShortstr() + { + short size = readOctet(); + byte[] bytes = new byte[size]; + get(bytes); + return new String(bytes); + } + + public String readLongstr() + { + long size = readLong(); + byte[] bytes = new byte[(int) size]; + get(bytes); + return new String(bytes); + } + + public RangeSet readRfc1982LongSet() + { + int count = readShort()/8; + if (count == 0) + { + return null; + } + else + { + RangeSet ranges = new RangeSet(); + for (int i = 0; i < count; i++) + { + ranges.add(readLong(), readLong()); + } + return ranges; + } + } + + public UUID readUuid() + { + long msb = readLonglong(); + long lsb = readLonglong(); + return new UUID(msb, lsb); + } + + public String readContent() + { + throw new Error("Deprecated"); + } + + public Struct readLongStruct() + { + long size = readLong(); + if (size == 0) + { + return null; + } + else + { + int type = readShort(); + Struct result = Struct.create(type); + result.read(this, major, minor); + return result; + } + } + + public Map readTable() + { + long size = readLong(); + int start = count; + Map result = new LinkedHashMap(); + while (count < start + size) + { + String key = readShortstr(); + byte code = get(); + Type t = getType(code); + Object value = read(t); + result.put(key, value); + } + return result; + } + + public List readSequence() + { + long size = readLong(); + int start = count; + List result = new ArrayList(); + while (count < start + size) + { + byte code = get(); + Type t = getType(code); + Object value = read(t); + result.add(value); + } + return result; + } + + public List readArray() + { + long size = readLong(); + byte code = get(); + Type t = getType(code); + long count = readLong(); + + List result = new ArrayList(); + for (int i = 0; i < count; i++) + { + Object value = read(t); + result.add(value); + } + return result; + } + + private Type getType(byte code) + { + Type type = Type.get(code); + if (type == null) + { + throw new IllegalArgumentException("unknown code: " + code); + } + else + { + return type; + } + } + + private long readSize(Type t) + { + if (t.fixed) + { + return t.width; + } + else + { + switch (t.width) + { + case 1: + return readOctet(); + case 2: + return readShort(); + case 4: + return readLong(); + default: + throw new IllegalStateException("irregular width: " + t); + } + } + } + + private byte[] readBytes(Type t) + { + long size = readSize(t); + byte[] result = new byte[(int) size]; + get(result); + return result; + } + + private Object read(Type t) + { + switch (t) + { + case OCTET: + case UNSIGNED_BYTE: + return readOctet(); + case SIGNED_BYTE: + return get(); + case CHAR: + return (char) get(); + case BOOLEAN: + return get() > 0; + + case TWO_OCTETS: + case UNSIGNED_SHORT: + return readShort(); + + case SIGNED_SHORT: + return (short) readShort(); + + case FOUR_OCTETS: + case UNSIGNED_INT: + return readLong(); + + case UTF32_CHAR: + case SIGNED_INT: + return (int) readLong(); + + case FLOAT: + return Float.intBitsToFloat((int) readLong()); + + case EIGHT_OCTETS: + case SIGNED_LONG: + case UNSIGNED_LONG: + case DATETIME: + return readLonglong(); + + case DOUBLE: + long bits = readLonglong(); + System.out.println("double in: " + bits); + return Double.longBitsToDouble(bits); + + case SIXTEEN_OCTETS: + case THIRTY_TWO_OCTETS: + case SIXTY_FOUR_OCTETS: + case _128_OCTETS: + case SHORT_BINARY: + case BINARY: + case LONG_BINARY: + return readBytes(t); + + case UUID: + return readUuid(); + + case SHORT_STRING: + case SHORT_UTF8_STRING: + case SHORT_UTF16_STRING: + case SHORT_UTF32_STRING: + case STRING: + case UTF8_STRING: + case UTF16_STRING: + case UTF32_STRING: + case LONG_STRING: + case LONG_UTF8_STRING: + case LONG_UTF16_STRING: + case LONG_UTF32_STRING: + // XXX: need to do character conversion + return new String(readBytes(t)); + + case TABLE: + return readTable(); + case SEQUENCE: + return readSequence(); + case ARRAY: + return readArray(); + + case FIVE_OCTETS: + case DECIMAL: + case NINE_OCTETS: + case LONG_DECIMAL: + // XXX: what types are we supposed to use here? + return readBytes(t); + + case VOID: + return null; + + default: + return readBytes(t); + } + } + +} diff --git a/java/common/src/main/java/org/apache/qpidity/transport/codec/AbstractEncoder.java b/java/common/src/main/java/org/apache/qpidity/transport/codec/AbstractEncoder.java new file mode 100644 index 0000000000..3d62393640 --- /dev/null +++ b/java/common/src/main/java/org/apache/qpidity/transport/codec/AbstractEncoder.java @@ -0,0 +1,560 @@ +/* + * + * 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.nio.ByteBuffer; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.UUID; + +import org.apache.qpidity.transport.Range; +import org.apache.qpidity.transport.RangeSet; +import org.apache.qpidity.transport.Struct; +import org.apache.qpidity.transport.Type; + +import static org.apache.qpidity.transport.util.Functions.*; + + +/** + * AbstractEncoder + * + * @author Rafael H. Schloming + */ + +abstract class AbstractEncoder implements Encoder +{ + + private static Map,Type> ENCODINGS = new HashMap,Type>(); + static + { + ENCODINGS.put(String.class, Type.LONG_STRING); + ENCODINGS.put(Long.class, Type.SIGNED_LONG); + ENCODINGS.put(Integer.class, Type.SIGNED_INT); + ENCODINGS.put(Short.class, Type.SIGNED_SHORT); + ENCODINGS.put(Byte.class, Type.SIGNED_BYTE); + ENCODINGS.put(Map.class, Type.TABLE); + ENCODINGS.put(List.class, Type.SEQUENCE); + ENCODINGS.put(Float.class, Type.FLOAT); + ENCODINGS.put(Double.class, Type.DOUBLE); + ENCODINGS.put(Character.class, Type.CHAR); + ENCODINGS.put(byte[].class, Type.LONG_BINARY); + } + + private final byte major; + private final byte minor; + private final boolean calcsize; + + protected AbstractEncoder(byte major, byte minor, boolean calcsize) + { + this.major = major; + this.minor = minor; + this.calcsize = calcsize; + } + + protected AbstractEncoder(byte major, byte minor) + { + this(major, minor, true); + } + + protected abstract void doPut(byte b); + + protected abstract void doPut(ByteBuffer src); + + protected void put(byte b) + { + flushBits(); + doPut(b); + } + + protected void put(ByteBuffer src) + { + flushBits(); + doPut(src); + } + + protected void put(byte[] bytes) + { + put(ByteBuffer.wrap(bytes)); + } + + private byte bits = 0x0; + private byte nbits = 0; + + public void writeBit(boolean b) + { + if (b) + { + bits |= 1 << nbits; + } + + nbits += 1; + + if (nbits == 8) + { + flushBits(); + } + } + + private void flushBits() + { + if (nbits > 0) + { + doPut(bits); + bits = 0x0; + nbits = 0; + } + } + + public void flush() + { + flushBits(); + } + + public void writeOctet(short b) + { + assert b < 0x100; + + put((byte) b); + } + + public void writeShort(int s) + { + assert s < 0x10000; + + put(lsb(s >>> 8)); + put(lsb(s)); + } + + public void writeLong(long i) + { + assert i < 0x100000000L; + + put(lsb(i >>> 24)); + put(lsb(i >>> 16)); + put(lsb(i >>> 8)); + put(lsb(i)); + } + + public void writeLonglong(long l) + { + for (int i = 0; i < 8; i++) + { + put(lsb(l >> (56 - i*8))); + } + } + + + public void writeTimestamp(long l) + { + writeLonglong(l); + } + + + public void writeShortstr(String s) + { + if (s == null) { s = ""; } + if (s.length() > 255) { + throw new IllegalArgumentException(s); + } + writeOctet((short) s.length()); + put(ByteBuffer.wrap(s.getBytes())); + } + + public void writeLongstr(String s) + { + if (s == null) { s = ""; } + writeLong(s.length()); + put(ByteBuffer.wrap(s.getBytes())); + } + + + public void writeRfc1982LongSet(RangeSet ranges) + { + if (ranges == null) + { + writeShort((short) 0); + } + else + { + writeShort(ranges.size() * 8); + for (Range range : ranges) + { + writeLong(range.getLower()); + writeLong(range.getUpper()); + } + } + } + + public void writeUuid(UUID uuid) + { + long msb = 0; + long lsb = 0; + if (uuid != null) + { + msb = uuid.getMostSignificantBits(); + uuid.getLeastSignificantBits(); + } + writeLonglong(msb); + writeLonglong(lsb); + } + + public void writeContent(String c) + { + throw new Error("Deprecated"); + } + + public void writeLongStruct(Struct s) + { + if (s == null) + { + writeLong(0); + } + else + { + int size = 0; + if (calcsize) + { + SizeEncoder sizer = new SizeEncoder(major, minor); + sizer.writeShort(s.getEncodedType()); + s.write(sizer, major, minor); + size = sizer.getSize(); + } + + writeLong(size); + writeShort(s.getEncodedType()); + s.write(this, major, minor); + } + } + + private Type encoding(Object value) + { + if (value == null) + { + return Type.VOID; + } + + Class klass = value.getClass(); + Type type = resolve(klass); + + if (type == null) + { + throw new IllegalArgumentException + ("unable to resolve type: " + klass + ", " + value); + } + else + { + return type; + } + } + + private Type resolve(Class klass) + { + Type type = ENCODINGS.get(klass); + if (type != null) + { + return type; + } + + Class sup = klass.getSuperclass(); + if (sup != null) + { + type = resolve(klass.getSuperclass()); + + if (type != null) + { + return type; + } + } + + for (Class iface : klass.getInterfaces()) + { + type = resolve(iface); + if (type != null) + { + return type; + } + } + + return null; + } + + public void writeTable(Map table) + { + if (table == null) + { + writeLong(0); + return; + } + + int size = 0; + if (calcsize) + { + SizeEncoder sizer = new SizeEncoder(major, minor); + sizer.writeTableEntries(table); + size = sizer.getSize(); + } + + writeLong(size); + writeTableEntries(table); + } + + protected void writeTableEntries(Map table) + { + for (Map.Entry entry : table.entrySet()) + { + String key = entry.getKey(); + Object value = entry.getValue(); + Type type = encoding(value); + writeShortstr(key); + put(type.code); + write(type, value); + } + } + + public void writeSequence(List sequence) + { + int size = 0; + if (calcsize) + { + SizeEncoder sizer = new SizeEncoder(major, minor); + sizer.writeSequenceEntries(sequence); + size = sizer.getSize(); + } + + writeLong(size); + writeSequenceEntries(sequence); + } + + protected void writeSequenceEntries(List sequence) + { + for (Object value : sequence) + { + Type type = encoding(value); + put(type.code); + write(type, value); + } + } + + public void writeArray(List array) + { + int size = 0; + if (calcsize) + { + SizeEncoder sizer = new SizeEncoder(major, minor); + sizer.writeArrayEntries(array); + size = sizer.getSize(); + } + + writeLong(size); + writeArrayEntries(array); + } + + protected void writeArrayEntries(List array) + { + Type type; + + if (array.isEmpty()) + { + type = Type.VOID; + } + else + { + type = encoding(array.get(0)); + } + + put(type.code); + + for (Object value : array) + { + write(type, value); + } + } + + private void writeSize(Type t, int size) + { + if (t.fixed) + { + if (size != t.width) + { + throw new IllegalArgumentException + ("size does not match fixed width " + t.width + ": " + + size); + } + } + 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); + } + } + } + + private void writeBytes(Type t, byte[] bytes) + { + writeSize(t, bytes.length); + put(bytes); + } + + private T coerce(Class klass, Object value) + { + if (klass.isInstance(value)) + { + return klass.cast(value); + } + else + { + throw new IllegalArgumentException("" + value); + } + } + + private void write(Type t, Object value) + { + switch (t) + { + case OCTET: + case UNSIGNED_BYTE: + writeOctet(coerce(Short.class, value)); + break; + case SIGNED_BYTE: + put(coerce(Byte.class, value)); + break; + case CHAR: + put((byte) ((char)coerce(Character.class, value))); + break; + case BOOLEAN: + if (coerce(Boolean.class, value)) + { + put((byte) 1); + } + else + { + put((byte) 0); + } + break; + + case TWO_OCTETS: + case UNSIGNED_SHORT: + writeShort(coerce(Integer.class, value)); + break; + + case SIGNED_SHORT: + writeShort(coerce(Short.class, value)); + break; + + case FOUR_OCTETS: + case UNSIGNED_INT: + writeLong(coerce(Long.class, value)); + break; + + case UTF32_CHAR: + case SIGNED_INT: + writeLong(coerce(Integer.class, value)); + break; + + case FLOAT: + writeLong(Float.floatToIntBits(coerce(Float.class, value))); + break; + + case EIGHT_OCTETS: + case SIGNED_LONG: + case UNSIGNED_LONG: + case DATETIME: + writeLonglong(coerce(Long.class, value)); + break; + + case DOUBLE: + long bits = Double.doubleToLongBits(coerce(Double.class, value)); + System.out.println("double out: " + bits); + writeLonglong(bits); + break; + + case SIXTEEN_OCTETS: + case THIRTY_TWO_OCTETS: + case SIXTY_FOUR_OCTETS: + case _128_OCTETS: + case SHORT_BINARY: + case BINARY: + case LONG_BINARY: + writeBytes(t, coerce(byte[].class, value)); + break; + + case UUID: + writeUuid(coerce(UUID.class, value)); + break; + + case SHORT_STRING: + case SHORT_UTF8_STRING: + case SHORT_UTF16_STRING: + case SHORT_UTF32_STRING: + case STRING: + case UTF8_STRING: + case UTF16_STRING: + case UTF32_STRING: + case LONG_STRING: + case LONG_UTF8_STRING: + case LONG_UTF16_STRING: + case LONG_UTF32_STRING: + // XXX: need to do character conversion + writeBytes(t, coerce(String.class, value).getBytes()); + break; + + case TABLE: + writeTable((Map) coerce(Map.class, value)); + break; + case SEQUENCE: + writeSequence(coerce(List.class, value)); + break; + case ARRAY: + writeArray(coerce(List.class, value)); + break; + + case FIVE_OCTETS: + case DECIMAL: + case NINE_OCTETS: + case LONG_DECIMAL: + // XXX: what types are we supposed to use here? + writeBytes(t, coerce(byte[].class, value)); + break; + + case VOID: + break; + + default: + writeBytes(t, coerce(byte[].class, value)); + break; + } + } + +} diff --git a/java/common/src/main/java/org/apache/qpidity/transport/codec/BBDecoder.java b/java/common/src/main/java/org/apache/qpidity/transport/codec/BBDecoder.java new file mode 100644 index 0000000000..b3ee1080f9 --- /dev/null +++ b/java/common/src/main/java/org/apache/qpidity/transport/codec/BBDecoder.java @@ -0,0 +1,53 @@ +/* + * + * 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.nio.ByteBuffer; + + +/** + * BBDecoder + * + * @author Rafael H. Schloming + */ + +public class BBDecoder extends AbstractDecoder +{ + + private final ByteBuffer in; + + public BBDecoder(byte major, byte minor, ByteBuffer in) + { + super(major, minor); + this.in = in; + } + + protected byte doGet() + { + return in.get(); + } + + protected void doGet(byte[] bytes) + { + in.get(bytes); + } + +} diff --git a/java/common/src/main/java/org/apache/qpidity/transport/codec/BBEncoder.java b/java/common/src/main/java/org/apache/qpidity/transport/codec/BBEncoder.java new file mode 100644 index 0000000000..e40ba6ae4d --- /dev/null +++ b/java/common/src/main/java/org/apache/qpidity/transport/codec/BBEncoder.java @@ -0,0 +1,52 @@ +/* + * + * 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.nio.ByteBuffer; + + +/** + * BBEncoder + * + * @author Rafael H. Schloming + */ + +public class BBEncoder extends AbstractEncoder +{ + + private final ByteBuffer out; + + public BBEncoder(byte major, byte minor, ByteBuffer out) { + super(major, minor); + this.out = out; + } + + protected void doPut(byte b) + { + out.put(b); + } + + protected void doPut(ByteBuffer src) + { + out.put(src); + } + +} diff --git a/java/common/src/main/java/org/apache/qpidity/transport/codec/Decoder.java b/java/common/src/main/java/org/apache/qpidity/transport/codec/Decoder.java new file mode 100644 index 0000000000..36cc13b7db --- /dev/null +++ b/java/common/src/main/java/org/apache/qpidity/transport/codec/Decoder.java @@ -0,0 +1,62 @@ +/* + * + * 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; + + +/** + * Decoder + * + * @author Rafael H. Schloming + */ + +public interface Decoder +{ + + boolean readBit(); + short readOctet(); + int readShort(); + long readLong(); + long readLonglong(); + + long readTimestamp(); + + String readShortstr(); + String readLongstr(); + + RangeSet readRfc1982LongSet(); + UUID readUuid(); + + String readContent(); + + Struct readLongStruct(); + + Map readTable(); + List readSequence(); + List readArray(); + +} diff --git a/java/common/src/main/java/org/apache/qpidity/transport/codec/Encodable.java b/java/common/src/main/java/org/apache/qpidity/transport/codec/Encodable.java new file mode 100644 index 0000000000..54fdd2768e --- /dev/null +++ b/java/common/src/main/java/org/apache/qpidity/transport/codec/Encodable.java @@ -0,0 +1,37 @@ +/* + * + * 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; + + +/** + * Encodable + * + * @author Rafael H. Schloming + */ + +public interface Encodable +{ + + void write(Encoder enc, byte major, byte minor); + + void read(Decoder dec, byte major, byte minor); + +} diff --git a/java/common/src/main/java/org/apache/qpidity/transport/codec/Encoder.java b/java/common/src/main/java/org/apache/qpidity/transport/codec/Encoder.java new file mode 100644 index 0000000000..5490bdd904 --- /dev/null +++ b/java/common/src/main/java/org/apache/qpidity/transport/codec/Encoder.java @@ -0,0 +1,64 @@ +/* + * + * 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; + + +/** + * Encoder + * + * @author Rafael H. Schloming + */ + +public interface Encoder +{ + + void flush(); + + void writeBit(boolean b); + void writeOctet(short b); + void writeShort(int s); + void writeLong(long i); + void writeLonglong(long l); + + void writeTimestamp(long l); + + void writeShortstr(String s); + void writeLongstr(String s); + + void writeRfc1982LongSet(RangeSet ranges); + void writeUuid(UUID uuid); + + void writeContent(String c); + + void writeLongStruct(Struct s); + + void writeTable(Map table); + void writeSequence(List sequence); + void writeArray(List array); + +} diff --git a/java/common/src/main/java/org/apache/qpidity/transport/codec/FragmentDecoder.java b/java/common/src/main/java/org/apache/qpidity/transport/codec/FragmentDecoder.java new file mode 100644 index 0000000000..74c83001ce --- /dev/null +++ b/java/common/src/main/java/org/apache/qpidity/transport/codec/FragmentDecoder.java @@ -0,0 +1,111 @@ +/* + * + * 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.nio.BufferUnderflowException; +import java.nio.ByteBuffer; + +import java.util.Iterator; + +import static java.lang.Math.*; + + +/** + * FragmentDecoder + * + * @author Rafael H. Schloming + */ + +public class FragmentDecoder extends AbstractDecoder +{ + + private final Iterator fragments; + private ByteBuffer current; + + public FragmentDecoder(byte major, byte minor, Iterator fragments) + { + super(major, minor); + this.fragments = fragments; + this.current = null; + } + + public boolean hasRemaining() + { + advance(); + return current != null || fragments.hasNext(); + } + + private void advance() + { + while (current == null && fragments.hasNext()) + { + current = fragments.next(); + if (current.hasRemaining()) + { + break; + } + else + { + current = null; + } + } + } + + private void preRead() + { + advance(); + + if (current == null) + { + throw new BufferUnderflowException(); + } + } + + private void postRead() + { + if (current.remaining() == 0) + { + current = null; + } + } + + protected byte doGet() + { + preRead(); + byte b = current.get(); + postRead(); + return b; + } + + protected void doGet(byte[] bytes) + { + int remaining = bytes.length; + while (remaining > 0) + { + preRead(); + int size = min(remaining, current.remaining()); + current.get(bytes, 0, size); + remaining -= size; + postRead(); + } + } + +} diff --git a/java/common/src/main/java/org/apache/qpidity/transport/codec/SizeEncoder.java b/java/common/src/main/java/org/apache/qpidity/transport/codec/SizeEncoder.java new file mode 100644 index 0000000000..4f39709554 --- /dev/null +++ b/java/common/src/main/java/org/apache/qpidity/transport/codec/SizeEncoder.java @@ -0,0 +1,66 @@ +/* + * + * 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.nio.ByteBuffer; + +import java.util.Map; + + +/** + * SizeEncoder + * + * @author Rafael H. Schloming + */ + +public class SizeEncoder extends AbstractEncoder +{ + + private int size; + + public SizeEncoder(byte major, byte minor) { + this(major, minor, 0); + } + + public SizeEncoder(byte major, byte minor, int size) { + super(major, minor, false); + this.size = size; + } + + public int getSize() { + return size; + } + + public void setSize(int size) { + this.size = size; + } + + protected void doPut(byte b) + { + size += 1; + } + + protected void doPut(ByteBuffer src) + { + size += src.remaining(); + } + +} diff --git a/java/common/src/main/java/org/apache/qpidity/transport/network/Assembler.java b/java/common/src/main/java/org/apache/qpidity/transport/network/Assembler.java index 7bd82e7cf5..d12cd003a9 100644 --- a/java/common/src/main/java/org/apache/qpidity/transport/network/Assembler.java +++ b/java/common/src/main/java/org/apache/qpidity/transport/network/Assembler.java @@ -27,7 +27,7 @@ import java.util.Map; import java.nio.ByteBuffer; -import org.apache.qpidity.codec.FragmentDecoder; +import org.apache.qpidity.transport.codec.FragmentDecoder; import org.apache.qpidity.transport.ConnectionEvent; import org.apache.qpidity.transport.Data; diff --git a/java/common/src/main/java/org/apache/qpidity/transport/network/Disassembler.java b/java/common/src/main/java/org/apache/qpidity/transport/network/Disassembler.java index e7541490a5..faaf8bfe4c 100644 --- a/java/common/src/main/java/org/apache/qpidity/transport/network/Disassembler.java +++ b/java/common/src/main/java/org/apache/qpidity/transport/network/Disassembler.java @@ -20,8 +20,8 @@ */ package org.apache.qpidity.transport.network; -import org.apache.qpidity.codec.BBEncoder; -import org.apache.qpidity.codec.SizeEncoder; +import org.apache.qpidity.transport.codec.BBEncoder; +import org.apache.qpidity.transport.codec.SizeEncoder; import org.apache.qpidity.transport.ConnectionEvent; import org.apache.qpidity.transport.Data; -- cgit v1.2.1