[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[GNUnet-SVN] r18223 - in gnunet-java: . src/org/gnunet/construct src/org
From: |
gnunet |
Subject: |
[GNUnet-SVN] r18223 - in gnunet-java: . src/org/gnunet/construct src/org/gnunet/messages src/org/gnunet/util test/org/gnunet/construct |
Date: |
Sun, 20 Nov 2011 20:41:29 +0100 |
Author: dold
Date: 2011-11-20 20:41:29 +0100 (Sun, 20 Nov 2011)
New Revision: 18223
Added:
gnunet-java/src/org/gnunet/construct/FieldLocation.java
gnunet-java/src/org/gnunet/construct/FixedSizeArrayParser.java
gnunet-java/src/org/gnunet/construct/Location.java
gnunet-java/src/org/gnunet/construct/ObjectParser.java
gnunet-java/src/org/gnunet/construct/Parser.java
gnunet-java/src/org/gnunet/construct/RefLocation.java
gnunet-java/src/org/gnunet/construct/SignedIntegerParser.java
gnunet-java/src/org/gnunet/construct/StringParser.java
gnunet-java/src/org/gnunet/construct/UnsignedIntegerParser.java
gnunet-java/src/org/gnunet/construct/VariableSizeArrayParser.java
gnunet-java/src/org/gnunet/messages/ComplexTestMessage.java
gnunet-java/src/org/gnunet/messages/SimpleTestMessage.java
Removed:
gnunet-java/src/org/gnunet/construct/FixedSizeByteArray.java
gnunet-java/src/org/gnunet/construct/TotalSize.java
gnunet-java/src/org/gnunet/construct/VariableSizeByteArray.java
gnunet-java/src/org/gnunet/construct/ZeroTerminatedUtf8String.java
gnunet-java/src/org/gnunet/construct/uint16_t.java
gnunet-java/src/org/gnunet/construct/uint32_t.java
gnunet-java/src/org/gnunet/construct/uint64_t.java
gnunet-java/src/org/gnunet/construct/uint8_t.java
Modified:
gnunet-java/ISSUES
gnunet-java/src/org/gnunet/construct/Construct.java
gnunet-java/src/org/gnunet/messages/MessageHeader.java
gnunet-java/src/org/gnunet/messages/RelativeTimeNBO.java
gnunet-java/src/org/gnunet/util/Configuration.java
gnunet-java/src/org/gnunet/util/Scheduler.java
gnunet-java/src/org/gnunet/util/TransmitReadyNotify.java
gnunet-java/test/org/gnunet/construct/ConstructTest.java
Log:
partially implemented construct, scheduler
Modified: gnunet-java/ISSUES
===================================================================
--- gnunet-java/ISSUES 2011-11-19 20:26:33 UTC (rev 18222)
+++ gnunet-java/ISSUES 2011-11-20 19:41:29 UTC (rev 18223)
@@ -45,4 +45,15 @@
* exception handling in statically used classes (scheduler)
* solution: singleton?
+
+
+
+
+
+
+
+ * advantages of the "new" parsing/unparsing package
+ * parsers are decoupled from annotations
+ * => parsers could be pre-compiled
+ * parsers are only constructed once per class
\ No newline at end of file
Modified: gnunet-java/src/org/gnunet/construct/Construct.java
===================================================================
--- gnunet-java/src/org/gnunet/construct/Construct.java 2011-11-19 20:26:33 UTC
(rev 18222)
+++ gnunet-java/src/org/gnunet/construct/Construct.java 2011-11-20 19:41:29 UTC
(rev 18223)
@@ -1,10 +1,18 @@
package org.gnunet.construct;
import java.lang.annotation.Annotation;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
import java.lang.reflect.Array;
import java.lang.reflect.Field;
+import java.math.BigInteger;
+import java.nio.ByteBuffer;
import org.grothoff.Runabout;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
/**
* A version of Python's construct library for Java.
@@ -15,149 +23,148 @@
* annotations (int16, int32, uint64, etc.)
* @TODO error handling (exceptions?), documentation
* @TODO performance evaluation
+ * @TODO add an Order(n) annotation if there's a java implementation out there
+ * that reorders fields
*/
public class Construct {
- /**
- * Given a byte array with a message, parse it into an object of type
c. The
- * fields of the class are expected to be annotated with annotations
from
- * the construct package.
- *
- * @param data
- * serialized binary object data
- * @param offset
- * where the message starts in data
- * @param c
- * desired object type to return
- * @return instance of the desired object type
- * @throws RuntimeException
- * (ugh)
- */
- public static <T> T parse_as(byte[] data, int offset, Class<T> c) {
- Deserializer<T> des = new Deserializer<T>(data, offset, c);
- Field[] fs = c.getFields();
- for (Field f : fs) {
- Annotation[] as = f.getAnnotations();
- des.setField(f);
- for (Annotation a : as)
- des.visitAppropriate(a);
- }
- return des.o;
- }
+ private static final Logger logger = LoggerFactory
+ .getLogger(Construct.class);
- /**
- * Serialize a given message object to a binary byte array. The fields
of
- * the object are expected to be annotated with annotations from the
- * construct package.
- *
- * @param o
- * object to serialize
- * @param data
- * where to write the binary object data
- * @param offset
- * where to start writing data
- * @return number of bytes written to data, -1 on error
- */
- public static int write_to(Object o, byte[] data, int offset) {
- return -1;
- }
+ @Retention(RetentionPolicy.RUNTIME)
+ @Target(ElementType.FIELD)
+ public @interface Nested {
+ }
- /**
- * Compute the size of a serialized message object.
- *
- * @param o
- * object to serialize
- * @return number of bytes required, -1 on error
- */
- public static int compute_binary_size(Object o) {
- return -1;
- }
+ /**
+ * Acceptable targets: byte, short, int, long, BigInteger.
+ *
+ * @author flodo
+ *
+ */
+ @Retention(RetentionPolicy.RUNTIME)
+ @Target(ElementType.FIELD)
+ public @interface SignedInteger {
+ /**
+ * number of bits in this signed integer, only multiples of 8 are
+ * permitted.
+ */
+ int value() default 4;
+ }
- public static class Deserializer<T> extends Runabout {
+ @Retention(RetentionPolicy.RUNTIME)
+ @Target(ElementType.FIELD)
+ public @interface TotalSize {
- final byte[] data;
+ }
- int offset;
+ @Retention(RetentionPolicy.RUNTIME)
+ @Target(ElementType.FIELD)
+ public @interface FixedSizeArray {
+ int length();
+ }
- int total_size = -1;
+ @Retention(RetentionPolicy.RUNTIME)
+ @Target(ElementType.FIELD)
+ public @interface UnsignedInteger {
+ int value() default 4;
- final T o;
+ // if useSignBit is true, the sign bit may be used to store a bit
+ // of an unsigned number (this makes the number negative), if
useSignBit
+ // is false
+ // an error is signaled if the sign of the target field is on
+ boolean useSignBit() default true;
+ }
- Field f;
+ @Retention(RetentionPolicy.RUNTIME)
+ @Target(ElementType.FIELD)
+ public @interface VariableSizeArray {
+ // set to empty string to make the array extend to fill the available
+ // space
+ String lengthField();
+ }
- private Deserializer(byte[] data, int offset, Class<T> c) {
- this.data = data;
- this.offset = offset;
- try {
- this.o = c.newInstance();
- } catch (IllegalAccessException iae) {
- throw new RuntimeException(iae);
- } catch (InstantiationException ie) {
- throw new RuntimeException(ie);
- }
- }
+ @Retention(RetentionPolicy.RUNTIME)
+ public @interface ZeroTerminatedString {
- private void setField(Field f) {
- this.f = f;
- }
+ String charset() default "UTF-8";
+ }
- public void visitDefault(Object o) {
- for (Annotation a : o.getClass().getAnnotations())
- visitAppropriate(a);
- }
+ public <T> T parse(Parser p, byte[] data, int offset) {
+ RefLocation rl = new RefLocation();
+ Location[] locs = { rl };
+ p.parse(data, offset, locs);
+ return (T) rl.get();
+ }
- public void visit(TotalSize ts) {
- // FIXME: can we be sure that this annotation is
processed last
- // (we can assume that it is added as the last
annotation to the
- // respective field, but can the compiler/runtime
reorder
- // annotations?)
- try {
- this.total_size = f.getInt(o);
- } catch (IllegalAccessException iae) {
- throw new RuntimeException(iae);
- }
- }
+ public ObjectParser makeParser(Class cls) {
+ ObjectParser op = new ObjectParser(cls);
- public void visit(uint8_t ui) {
- try {
- f.setInt(o, data[offset]);
- // FIXME: this is wrong (not unsigned), just for
- // illustration...
- offset++;
- } catch (IllegalAccessException iae) {
- throw new RuntimeException(iae);
- }
- }
+ for (Field f : cls.getFields()) {
+ Annotation[] anns = f.getAnnotations();
+ for (int i = 0; i < anns.length; ++i) {
+ Annotation ann = anns[i];
+ if (ann instanceof SignedInteger) {
+ SignedInteger a = (SignedInteger) ann;
+ op.add(new SignedIntegerParser(a.value()), f);
+ } else if (ann instanceof UnsignedInteger) {
+ UnsignedInteger a = (UnsignedInteger) ann;
+ op.add(new UnsignedIntegerParser(a.value()), f);
+ } else if (ann instanceof TotalSize) {
+ op.addSizeField(f);
+ }
+ }
+ }
+ return op;
+ }
- public void visit(uint16_t ui) {
- try {
- f.setInt(o, data[offset] + data[offset] << 8);
- // FIXME: this is wrong (not proper
deserialization),
- // just for illustration...
- offset += 2;
- } catch (IllegalAccessException iae) {
- throw new RuntimeException(iae);
- }
- }
+ /**
+ * Given a byte array with a message, parse it into an object of type c.
The
+ * fields of the class are expected to be annotated with annotations from
+ * the construct package.
+ *
+ * @param data
+ * serialized binary object data
+ * @param offset
+ * where the message starts in data
+ * @param c
+ * desired object type to return
+ * @return instance of the desired object type
+ * @throws RuntimeException
+ * (ugh)
+ */
+ // how to deal with combined annotations?
+ public static <T> T parse_as(byte[] data, int offset, Class<T> c) {
+
- public void visit(FixedSizeByteArray fsba) {
- int length = fsba.length();
- Class ac = f.getClass();
- Class componentType = ac.getComponentType();
- Object array = Array.newInstance(componentType, length);
- for (int i = 0; i < length; i++) {
- Object element = parse_as(data, offset,
componentType);
- offset += compute_binary_size(element);
- Array.set(array, i, element);
- }
- try {
- f.set(o, array);
- } catch (IllegalAccessException iae) {
- throw new RuntimeException(iae);
- }
- }
+ return null;
- // FIXME: many more 'visit' methods should be added here...
+ }
- }
+ /**
+ * Serialize a given message object to a binary byte array. The fields of
+ * the object are expected to be annotated with annotations from the
+ * construct package.
+ *
+ * @param o
+ * object to serialize
+ * @param data
+ * where to write the binary object data
+ * @param offset
+ * where to start writing data
+ * @return number of bytes written to data, -1 on error
+ */
+ public static int write_to(Object o, ByteBuffer buf) {
+ return -1;
+ }
+ /**
+ * Compute the size of a serialized message object.
+ *
+ * @param o
+ * object to serialize
+ * @return number of bytes required, -1 on error
+ */
+ public static int compute_binary_size(Object o) {
+ return -1;
+ }
}
Added: gnunet-java/src/org/gnunet/construct/FieldLocation.java
===================================================================
--- gnunet-java/src/org/gnunet/construct/FieldLocation.java
(rev 0)
+++ gnunet-java/src/org/gnunet/construct/FieldLocation.java 2011-11-20
19:41:29 UTC (rev 18223)
@@ -0,0 +1,41 @@
+package org.gnunet.construct;
+
+import java.lang.reflect.Field;
+
+public class FieldLocation implements Location {
+ private Field f;
+ private Object o;
+
+ public FieldLocation(Field f, Object o) {
+ this.f = f;
+ this.o = o;
+ }
+
+ @Override
+ public void put(Object v) {
+ try {
+ f.set(o, v);
+ } catch (IllegalArgumentException e) {
+ throw new RuntimeException();
+ } catch (IllegalAccessException e) {
+ throw new RuntimeException();
+ }
+ }
+
+ @Override
+ public Class getType() {
+ return f.getType();
+ }
+
+ @Override
+ public Object get() {
+ try {
+ return f.get(o);
+ } catch (IllegalArgumentException e) {
+ throw new RuntimeException();
+ } catch (IllegalAccessException e) {
+ throw new RuntimeException();
+ }
+ }
+
+}
Added: gnunet-java/src/org/gnunet/construct/FixedSizeArrayParser.java
===================================================================
--- gnunet-java/src/org/gnunet/construct/FixedSizeArrayParser.java
(rev 0)
+++ gnunet-java/src/org/gnunet/construct/FixedSizeArrayParser.java
2011-11-20 19:41:29 UTC (rev 18223)
@@ -0,0 +1,33 @@
+package org.gnunet.construct;
+
+public class FixedSizeArrayParser implements Parser {
+
+ private Parser p;
+ private int size;
+
+ public FixedSizeArrayParser(int size, Parser p) {
+ this.p = p;
+ this.size = size;
+ }
+
+ @Override
+ public int parse(byte[] src_data, int offset, Location[] dst) {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+ @Override
+ public int unparse(byte[] dst_data, int offset, Location[] src) {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+ @Override
+ public int estimateSize(Location[] args) {
+ Location[] a = {};
+ return p.estimateSize(a) * size;
+ }
+
+
+
+}
Deleted: gnunet-java/src/org/gnunet/construct/FixedSizeByteArray.java
===================================================================
--- gnunet-java/src/org/gnunet/construct/FixedSizeByteArray.java
2011-11-19 20:26:33 UTC (rev 18222)
+++ gnunet-java/src/org/gnunet/construct/FixedSizeByteArray.java
2011-11-20 19:41:29 UTC (rev 18223)
@@ -1,12 +0,0 @@
-package org.gnunet.construct;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
address@hidden(RetentionPolicy.RUNTIME)
address@hidden(ElementType.FIELD)
-public @interface FixedSizeByteArray {
- int length();
-}
Added: gnunet-java/src/org/gnunet/construct/Location.java
===================================================================
--- gnunet-java/src/org/gnunet/construct/Location.java
(rev 0)
+++ gnunet-java/src/org/gnunet/construct/Location.java 2011-11-20 19:41:29 UTC
(rev 18223)
@@ -0,0 +1,15 @@
+package org.gnunet.construct;
+
+/**
+ *
+ *
+ * @author dold
+ *
+ */
+public interface Location {
+ void put(Object o);
+
+ Object get();
+
+ Class getType();
+}
Added: gnunet-java/src/org/gnunet/construct/ObjectParser.java
===================================================================
--- gnunet-java/src/org/gnunet/construct/ObjectParser.java
(rev 0)
+++ gnunet-java/src/org/gnunet/construct/ObjectParser.java 2011-11-20
19:41:29 UTC (rev 18223)
@@ -0,0 +1,125 @@
+package org.gnunet.construct;
+
+import java.lang.reflect.Field;
+import java.util.LinkedList;
+import java.util.List;
+
+class ParserRecord {
+ Parser p;
+ Field[] args;
+
+ public ParserRecord(Parser p, Field[] args) {
+ this.p = p;
+ this.args = args;
+ }
+}
+
+public class ObjectParser implements Parser {
+
+ // parser with arguments
+ List<ParserRecord> parser_records = new LinkedList<ParserRecord>();
+
+ List<Field> size_fields = new LinkedList<Field>();
+
+ private Class cls;
+
+ public ObjectParser(Class cls) {
+ this.cls = cls;
+ }
+
+ public void add(Parser p, Field... fields) {
+ parser_records.add(new ParserRecord(p, fields));
+ }
+
+ /**
+ * Add a field which serves as storage for the byte size of the whole
object
+ *
+ * @param f
+ * the relevant field
+ */
+ public void addSizeField(Field f) {
+ size_fields.add(f);
+ }
+
+ /**
+ * Create locations from the Object's fields we are interested in
+ *
+ * @param pr
+ * @param obj
+ * @return
+ */
+ private Location[] getLocs(Field[] fs, Object obj) {
+ Location[] locs = new Location[fs.length];
+ for (int i = 0; i < locs.length; ++i) {
+ locs[i] = new FieldLocation(fs[i], obj);
+ }
+ return locs;
+ }
+
+ public int parse(byte[] data, int offset, Location[] dest) {
+ assert dest.length == 1;
+
+ Location loc = dest[0];
+
+ int parsed = 0;
+ // create new object
+ Object obj;
+ try {
+ obj = cls.newInstance();
+ } catch (IllegalAccessException iae) {
+ throw new RuntimeException(iae);
+ } catch (InstantiationException ie) {
+ throw new RuntimeException(ie);
+ }
+
+ for (ParserRecord pr : this.parser_records) {
+ // create locations from record
+ Location[] locs = getLocs(pr.args, obj);
+ int x = pr.p.parse(data, offset, locs);
+ assert x >= 0;
+ parsed += x;
+ }
+
+ for (Field f : size_fields) {
+ try {
+ f.set(obj, parsed);
+ } catch (IllegalArgumentException e) {
+ throw new RuntimeException();
+ } catch (IllegalAccessException e) {
+ throw new RuntimeException();
+ }
+ }
+
+ loc.put(obj);
+
+ return parsed;
+ }
+
+ public int unparse(byte[] data, int offset, Location[] dest) {
+ assert dest.length == 1;
+ Object obj = dest[0].get();
+
+ int parsed = 0;
+
+ for (ParserRecord pr : this.parser_records) {
+ parsed += pr.p
+ .unparse(data, offset + parsed, getLocs(pr.args, obj));
+ }
+ return parsed;
+ }
+
+ @Override
+ public int estimateSize(Location[] args) {
+ assert args.length == 1;
+ Object obj = args[0];
+ int size = 0;
+ for (ParserRecord pr : this.parser_records) {
+ // create locations from record
+ Location[] locs = getLocs(pr.args, obj);
+ int x = pr.p.estimateSize(locs);
+ assert x >= 0;
+ size += x;
+ }
+ return size;
+ }
+}
Added: gnunet-java/src/org/gnunet/construct/Parser.java
===================================================================
--- gnunet-java/src/org/gnunet/construct/Parser.java
(rev 0)
+++ gnunet-java/src/org/gnunet/construct/Parser.java 2011-11-20 19:41:29 UTC
(rev 18223)
@@ -0,0 +1,33 @@
+package org.gnunet.construct;
+
+public interface Parser {
+
+
+ /**
+ *
+ *
+ * @param src_data
+ * @param offset
+ * @param dst
+ * @return number of bytes parsed
+ */
+ public int parse(byte[] src_data, int offset, Location[] dst);
+
+ /**
+ *
+ * @param dst_data
+ * @param offset
+ * @param src
+ * @return number of bytes unparsed
+ */
+ public int unparse(byte[] dst_data, int offset, Location[] src);
+
+
+ /**
+ *
+ * @param args
+ * @return
+ */
+ public int estimateSize(Location[] args);
+
+}
Added: gnunet-java/src/org/gnunet/construct/RefLocation.java
===================================================================
--- gnunet-java/src/org/gnunet/construct/RefLocation.java
(rev 0)
+++ gnunet-java/src/org/gnunet/construct/RefLocation.java 2011-11-20
19:41:29 UTC (rev 18223)
@@ -0,0 +1,30 @@
+package org.gnunet.construct;
+
+public class RefLocation implements Location {
+ private Object obj;
+ private Class cls;
+
+ public RefLocation() {
+ this.cls = Object.class;
+ }
+
+ public RefLocation(Class cls) {
+ this.cls = cls;
+ }
+
+ @Override
+ public void put(Object o) {
+ this.obj = o;
+ }
+
+ @Override
+ public Object get() {
+ return obj;
+ }
+
+ @Override
+ public Class getType() {
+ return cls;
+ }
+
+}
Added: gnunet-java/src/org/gnunet/construct/SignedIntegerParser.java
===================================================================
--- gnunet-java/src/org/gnunet/construct/SignedIntegerParser.java
(rev 0)
+++ gnunet-java/src/org/gnunet/construct/SignedIntegerParser.java
2011-11-20 19:41:29 UTC (rev 18223)
@@ -0,0 +1,72 @@
+package org.gnunet.construct;
+
+import java.math.BigInteger;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class SignedIntegerParser implements Parser {
+ private static final Logger logger = LoggerFactory
+ .getLogger(SignedIntegerParser.class);
+
+ private final int byte_size;
+
+ public SignedIntegerParser(int byte_size) {
+ this.byte_size = byte_size;
+ }
+
+
+ public int parse(byte[] data, int offset, Location[] dest) {
+ assert dest.length == 1;
+
+ Location loc = dest[0];
+
+ byte[] num_data = new byte[byte_size];
+
+ System.arraycopy(data, offset, num_data, 0, byte_size);
+ offset += byte_size;
+
+ BigInteger num = new BigInteger(num_data);
+
+ if (loc.getType().equals(BigInteger.class)) {
+ loc.put(num);
+ } else {
+
+ int bit_size;
+ if (loc.getType().equals(Integer.TYPE)) {
+ loc.put(num.intValue());
+ bit_size = 32;
+ } else if (loc.getType().equals(Long.TYPE)) {
+ loc.put(num.longValue());
+ bit_size = 64;
+ } else if (loc.getType().equals(Short.class)) {
+ loc.put(num.shortValue());
+ bit_size = 16;
+ } else if (loc.getType().equals(Byte.class)) {
+ loc.put(num.byteValue());
+ bit_size = 8;
+ } else {
+ throw new RuntimeException(
+ "construct: target type not supported");
+ }
+
+ if (num.bitLength() > bit_size) {
+ logger.warn("construct: number truncated");
+ }
+ }
+ return byte_size;
+ }
+
+ @Override
+ public int unparse(byte[] dst_data, int offset, Location[] src) {
+ assert src.length == 1;
+ Location loc = src[0];
+
+ return 0;
+ }
+
+ @Override
+ public int estimateSize(Location[] args) {
+ return byte_size;
+ }
+}
Added: gnunet-java/src/org/gnunet/construct/StringParser.java
===================================================================
--- gnunet-java/src/org/gnunet/construct/StringParser.java
(rev 0)
+++ gnunet-java/src/org/gnunet/construct/StringParser.java 2011-11-20
19:41:29 UTC (rev 18223)
@@ -0,0 +1,51 @@
+package org.gnunet.construct;
+
+import java.io.UnsupportedEncodingException;
+
+public class StringParser implements Parser {
+
+ String cset;
+
+ public StringParser() {
+ this.cset = "UTF-8";
+ }
+
+ public StringParser(String charset) {
+ this.cset = charset;
+ }
+
+ @Override
+ public int parse(byte[] src_data, int offset, Location[] dst) {
+ assert dst.length == 1;
+ Location loc = dst[0];
+ int length = 0;
+ while (src_data[offset+length] != 0) {
+ length++;
+ }
+
+ byte[] str_data = new byte[length];
+ String str;
+ try {
+ str = new String(str_data, cset);
+ } catch (UnsupportedEncodingException e) {
+ throw new RuntimeException();
+ }
+ loc.put(str);
+
+ return length;
+ }
+
+ @Override
+ public int unparse(byte[] dst_data, int offset, Location[] src) {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+ @Override
+ public int estimateSize(Location[] args) {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+
+}
Deleted: gnunet-java/src/org/gnunet/construct/TotalSize.java
===================================================================
--- gnunet-java/src/org/gnunet/construct/TotalSize.java 2011-11-19 20:26:33 UTC
(rev 18222)
+++ gnunet-java/src/org/gnunet/construct/TotalSize.java 2011-11-20 19:41:29 UTC
(rev 18223)
@@ -1,13 +0,0 @@
-package org.gnunet.construct;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-
address@hidden(RetentionPolicy.RUNTIME)
address@hidden(ElementType.FIELD)
-public @interface TotalSize {
-
-}
Added: gnunet-java/src/org/gnunet/construct/UnsignedIntegerParser.java
===================================================================
--- gnunet-java/src/org/gnunet/construct/UnsignedIntegerParser.java
(rev 0)
+++ gnunet-java/src/org/gnunet/construct/UnsignedIntegerParser.java
2011-11-20 19:41:29 UTC (rev 18223)
@@ -0,0 +1,73 @@
+package org.gnunet.construct;
+
+import java.math.BigInteger;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class UnsignedIntegerParser implements Parser {
+ private static final Logger logger = LoggerFactory
+ .getLogger(SignedIntegerParser.class);
+
+ private final int byte_size;
+
+ public UnsignedIntegerParser(int byte_size) {
+ this.byte_size = byte_size;
+ }
+
+
+ public int parse(byte[] data, int offset, Location[] dest) {
+ assert dest.length == 1;
+
+ Location loc = dest[0];
+
+ // prepend zero, if data has the sign bit set
+ byte[] num_data = new byte[byte_size + 1];
+
+ System.arraycopy(data, offset, num_data, 1, byte_size);
+ offset += byte_size;
+
+ BigInteger num = new BigInteger(num_data);
+
+ if (loc.getType().equals(BigInteger.class)) {
+ loc.put(num);
+ } else {
+
+ int bit_size;
+ if (loc.getType().equals(Integer.TYPE)) {
+ loc.put(num.intValue());
+ bit_size = 32;
+ } else if (loc.getType().equals(Long.TYPE)) {
+ loc.put(num.longValue());
+ bit_size = 64;
+ } else if (loc.getType().equals(Short.TYPE)) {
+ loc.put(num.shortValue());
+ bit_size = 16;
+ } else if (loc.getType().equals(Byte.TYPE)) {
+ loc.put(num.byteValue());
+ bit_size = 8;
+ } else {
+ throw new RuntimeException(
+ "construct: target type not supported: " +
loc.getType());
+ }
+
+ // +1 is because java has only signed numbers
+ if (num.bitLength() + 1 > bit_size) {
+ logger.warn("construct: number truncated");
+ }
+ }
+ return byte_size;
+ }
+
+ @Override
+ public int unparse(byte[] dst_data, int offset, Location[] src) {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+
+ @Override
+ public int estimateSize(Location[] args) {
+ return byte_size;
+ }
+}
Added: gnunet-java/src/org/gnunet/construct/VariableSizeArrayParser.java
===================================================================
--- gnunet-java/src/org/gnunet/construct/VariableSizeArrayParser.java
(rev 0)
+++ gnunet-java/src/org/gnunet/construct/VariableSizeArrayParser.java
2011-11-20 19:41:29 UTC (rev 18223)
@@ -0,0 +1,34 @@
+package org.gnunet.construct;
+
+public class VariableSizeArrayParser implements Parser {
+ private Parser p;
+
+ public VariableSizeArrayParser(Parser p) {
+ this.p = p;
+ }
+
+ @Override
+ public int parse(byte[] src_data, int offset, Location[] dst) {
+ assert dst.length == 2;
+ Location loc = dst[0];
+ int size = ((Integer) dst[1].get()).intValue();
+
+
+
+ return 0;
+ }
+
+ @Override
+ public int unparse(byte[] dst_data, int offset, Location[] src) {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+ @Override
+ public int estimateSize(Location[] args) {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+
+}
Deleted: gnunet-java/src/org/gnunet/construct/VariableSizeByteArray.java
===================================================================
--- gnunet-java/src/org/gnunet/construct/VariableSizeByteArray.java
2011-11-19 20:26:33 UTC (rev 18222)
+++ gnunet-java/src/org/gnunet/construct/VariableSizeByteArray.java
2011-11-20 19:41:29 UTC (rev 18223)
@@ -1,8 +0,0 @@
-package org.gnunet.construct;
-
-public @interface VariableSizeByteArray {
- // set to empty string to make the array extend to fill the available
space
- String lengthField();
-
- String memberType();
-}
Deleted: gnunet-java/src/org/gnunet/construct/ZeroTerminatedUtf8String.java
===================================================================
--- gnunet-java/src/org/gnunet/construct/ZeroTerminatedUtf8String.java
2011-11-19 20:26:33 UTC (rev 18222)
+++ gnunet-java/src/org/gnunet/construct/ZeroTerminatedUtf8String.java
2011-11-20 19:41:29 UTC (rev 18223)
@@ -1,9 +0,0 @@
-package org.gnunet.construct;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
address@hidden(RetentionPolicy.RUNTIME)
-public @interface ZeroTerminatedUtf8String {
-
-}
Deleted: gnunet-java/src/org/gnunet/construct/uint16_t.java
===================================================================
--- gnunet-java/src/org/gnunet/construct/uint16_t.java 2011-11-19 20:26:33 UTC
(rev 18222)
+++ gnunet-java/src/org/gnunet/construct/uint16_t.java 2011-11-20 19:41:29 UTC
(rev 18223)
@@ -1,18 +0,0 @@
-package org.gnunet.construct;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-
-/**
- * 16-bit @UnsignedInteger in network byte order.
- *
- * @author grothoff
- */
address@hidden(RetentionPolicy.RUNTIME)
address@hidden(ElementType.FIELD)
-public @interface uint16_t {
-
-}
Deleted: gnunet-java/src/org/gnunet/construct/uint32_t.java
===================================================================
--- gnunet-java/src/org/gnunet/construct/uint32_t.java 2011-11-19 20:26:33 UTC
(rev 18222)
+++ gnunet-java/src/org/gnunet/construct/uint32_t.java 2011-11-20 19:41:29 UTC
(rev 18223)
@@ -1,17 +0,0 @@
-package org.gnunet.construct;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-/**
- * 16-bit @UnsignedInteger in network byte order.
- *
- * @author grothoff
- */
address@hidden(RetentionPolicy.RUNTIME)
address@hidden(ElementType.FIELD)
-public @interface uint32_t {
-
-}
Deleted: gnunet-java/src/org/gnunet/construct/uint64_t.java
===================================================================
--- gnunet-java/src/org/gnunet/construct/uint64_t.java 2011-11-19 20:26:33 UTC
(rev 18222)
+++ gnunet-java/src/org/gnunet/construct/uint64_t.java 2011-11-20 19:41:29 UTC
(rev 18223)
@@ -1,17 +0,0 @@
-package org.gnunet.construct;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-/**
- * 16-bit @UnsignedInteger in network byte order.
- *
- * @author grothoff
- */
address@hidden(RetentionPolicy.RUNTIME)
address@hidden(ElementType.FIELD)
-public @interface uint64_t {
-
-}
Deleted: gnunet-java/src/org/gnunet/construct/uint8_t.java
===================================================================
--- gnunet-java/src/org/gnunet/construct/uint8_t.java 2011-11-19 20:26:33 UTC
(rev 18222)
+++ gnunet-java/src/org/gnunet/construct/uint8_t.java 2011-11-20 19:41:29 UTC
(rev 18223)
@@ -1,18 +0,0 @@
-package org.gnunet.construct;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-
-/**
- * 8-bit @UnsignedInteger in network byte order.
- *
- * @author grothoff
- */
address@hidden(RetentionPolicy.RUNTIME)
address@hidden(ElementType.FIELD)
-public @interface uint8_t {
-
-}
Added: gnunet-java/src/org/gnunet/messages/ComplexTestMessage.java
===================================================================
--- gnunet-java/src/org/gnunet/messages/ComplexTestMessage.java
(rev 0)
+++ gnunet-java/src/org/gnunet/messages/ComplexTestMessage.java 2011-11-20
19:41:29 UTC (rev 18223)
@@ -0,0 +1,74 @@
+package org.gnunet.messages;
+
+import org.gnunet.construct.Construct.FixedSizeArray;
+import org.gnunet.construct.Construct.Nested;
+import org.gnunet.construct.Construct.TotalSize;
+import org.gnunet.construct.Construct.UnsignedInteger;
+import org.gnunet.construct.Construct.VariableSizeArray;
+import org.gnunet.construct.Construct.ZeroTerminatedString;
+import org.gnunet.construct.FixedSizeArrayParser;
+import org.gnunet.construct.ObjectParser;
+import org.gnunet.construct.StringParser;
+import org.gnunet.construct.UnsignedIntegerParser;
+import org.gnunet.construct.VariableSizeArrayParser;
+
+public class ComplexTestMessage {
+
+ @UnsignedInteger(2)
+ int someNumber;
+
+ @FixedSizeArray(length = 5)
+ @UnsignedInteger(2)
+ int[] someArray;
+
+ @Nested
+ SimpleTestMessage msg;
+
+
+ @UnsignedInteger(2)
+ int stringTableSize;
+
+ @VariableSizeArray(lengthField = "stringTableSize")
+ @ZeroTerminatedString(charset = "UTF-8")
+ String[] stringTable;
+
+
+ @TotalSize
+ int mySize;
+
+ @TotalSize
+ @UnsignedInteger(2)
+ int storedMySize;
+
+ // this should work fully automatic
+ public static ObjectParser makeParser() throws SecurityException,
+ NoSuchFieldException {
+
+ ObjectParser p = new ObjectParser(ComplexTestMessage.class);
+
+ p.add(new UnsignedIntegerParser(2),
+ ComplexTestMessage.class.getField("someNumber"));
+
+ FixedSizeArrayParser ap = new FixedSizeArrayParser(5,
+ new UnsignedIntegerParser(2));
+
+ p.add(ap, ComplexTestMessage.class.getField("someArray"));
+
+ VariableSizeArrayParser lp = new VariableSizeArrayParser(
+ new StringParser());
+
+ // arguments: resulting array, array length
+ p.add(lp, ComplexTestMessage.class.getField("stringTable"),
+ ComplexTestMessage.class.getField("stringTableSize"));
+
+ p.addSizeField(ComplexTestMessage.class.getField("mySize"));
+
+ p.add(new UnsignedIntegerParser(2),
+ ComplexTestMessage.class.getField("storedMySize"));
+
+ p.addSizeField(ComplexTestMessage.class.getField("storedMySize"));
+
+ return p;
+ }
+
+}
Modified: gnunet-java/src/org/gnunet/messages/MessageHeader.java
===================================================================
--- gnunet-java/src/org/gnunet/messages/MessageHeader.java 2011-11-19
20:26:33 UTC (rev 18222)
+++ gnunet-java/src/org/gnunet/messages/MessageHeader.java 2011-11-20
19:41:29 UTC (rev 18223)
@@ -1,16 +1,24 @@
package org.gnunet.messages;
-import org.gnunet.construct.TotalSize;
-import org.gnunet.construct.uint16_t;
+import org.gnunet.construct.Construct.TotalSize;
+import org.gnunet.construct.Construct.UnsignedInteger;
+import org.gnunet.construct.Parser;
+import org.gnunet.construct.ObjectParser;
public class MessageHeader {
- @uint16_t
+ @UnsignedInteger(2)
@TotalSize
public int size;
- @uint16_t
+ @UnsignedInteger(2)
public int type;
+
+
+ public Parser getParser() {
+ ObjectParser p = new ObjectParser();
+ //p.addParser(new UnsignedIntegerParser(2, new FieldDest))
+ }
}
Modified: gnunet-java/src/org/gnunet/messages/RelativeTimeNBO.java
===================================================================
--- gnunet-java/src/org/gnunet/messages/RelativeTimeNBO.java 2011-11-19
20:26:33 UTC (rev 18222)
+++ gnunet-java/src/org/gnunet/messages/RelativeTimeNBO.java 2011-11-20
19:41:29 UTC (rev 18223)
@@ -1,18 +1,27 @@
package org.gnunet.messages;
-import org.gnunet.construct.uint64_t;
+import org.gnunet.construct.UnsignedInteger;
+import org.gnunet.util.RelativeTime;
public class RelativeTimeNBO {
/**
- * Value__ still in Java-byte order, needs to be converted to Network byte
order by the Construct class.
+ * Value__ still in Java-byte order, needs to be converted to Network byte
+ * order by the Construct class.
*/
- @uint64_t
+ @UnsignedInteger(64)
public long value__;
-
- public RelativeTimeNBO (long value)
- {
+
+ public RelativeTimeNBO(long value) {
this.value__ = value;
}
+ public RelativeTimeNBO(RelativeTime t) {
+ if (t.equals(RelativeTime.FOREVER)) {
+ this.value__ = -1;
+ } else {
+ this.value__ = t.getMilliseconds();
+ }
+ }
+
}
Added: gnunet-java/src/org/gnunet/messages/SimpleTestMessage.java
===================================================================
--- gnunet-java/src/org/gnunet/messages/SimpleTestMessage.java
(rev 0)
+++ gnunet-java/src/org/gnunet/messages/SimpleTestMessage.java 2011-11-20
19:41:29 UTC (rev 18223)
@@ -0,0 +1,29 @@
+package org.gnunet.messages;
+
+import org.gnunet.construct.Construct.UnsignedInteger;
+import org.gnunet.construct.ObjectParser;
+import org.gnunet.construct.UnsignedIntegerParser;
+
+public class SimpleTestMessage {
+
+ @UnsignedInteger(2)
+ public short v;
+
+ public static ObjectParser getParser() {
+ ObjectParser op = new ObjectParser(SimpleTestMessage.class);
+
+ try {
+ op.add(new UnsignedIntegerParser(2),
SimpleTestMessage.class.getField("v"));
+ } catch (SecurityException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (NoSuchFieldException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+
+
+ return op;
+ }
+
+}
Modified: gnunet-java/src/org/gnunet/util/Configuration.java
===================================================================
--- gnunet-java/src/org/gnunet/util/Configuration.java 2011-11-19 20:26:33 UTC
(rev 18222)
+++ gnunet-java/src/org/gnunet/util/Configuration.java 2011-11-20 19:41:29 UTC
(rev 18223)
@@ -319,7 +319,7 @@
public Map<String, String> getSection(String s) {
Map<String, String> m = sections.get(s);
if (m == null) {
- return null;
+ throw new ParsingError("configuration section not found");
}
return Collections.unmodifiableMap(m);
}
Modified: gnunet-java/src/org/gnunet/util/Scheduler.java
===================================================================
--- gnunet-java/src/org/gnunet/util/Scheduler.java 2011-11-19 20:26:33 UTC
(rev 18222)
+++ gnunet-java/src/org/gnunet/util/Scheduler.java 2011-11-20 19:41:29 UTC
(rev 18223)
@@ -27,16 +27,13 @@
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.spi.SelectorProvider;
-import java.util.Comparator;
-import java.util.EnumMap;
+import java.util.ArrayList;
import java.util.EnumSet;
import java.util.LinkedList;
import java.util.List;
-import java.util.Map;
import java.util.PriorityQueue;
import java.util.Queue;
import java.util.Set;
-import java.util.TreeSet;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -51,7 +48,7 @@
.getLogger(Scheduler.class);
public enum Priority {
- IDLE, BACKGROUND, DEFAULT, HIGH, UI, URGENT, SHUTDOWN;
+ IDLE, BACKGROUND, DEFAULT, HIGH, UI, URGENT, SHUTDOWN, _COUNT;
static public final Priority KEEP = null;
}
@@ -59,29 +56,36 @@
STARTUP, SHUTDOWN, TIMEOUT, READ_READY, WRITE_READY, PREREQ_DONE
}
+ // tasks that are waiting for a delay to pass, will be moved to 'pending'
+ // eventually
+ private static Queue<TimeoutTask> pending_timeout = new
PriorityQueue<TimeoutTask>();
+
+ // tasks that may be waiting for an event
private static List<TaskIdentifier> pending = new
LinkedList<TaskIdentifier>();
- private static Queue<TimeoutTask> pending_timeout = new
PriorityQueue<TimeoutTask>();
-
+ // only valid while a task is executing
private static TaskIdentifier active_task;
+
+
+ static Priority current_priority;
+ static boolean current_liveness;
- private static Priority current_priority;
- private static boolean current_liveness;
-
+
+ // number of tasks in the ready queue
private static int ready_count = 0;
- // fast / implemented with arrays, according to java docs
- private static Map<Priority, LinkedList<TaskIdentifier>> ready = new
EnumMap<Priority, LinkedList<TaskIdentifier>>(
- Priority.class);
-
+ // for every priority, there is a list of tasks that is definitely ready to
+ // run
+ private static ArrayList<LinkedList<TaskIdentifier>> ready = new
ArrayList<LinkedList<TaskIdentifier>>(
+ Priority._COUNT.ordinal());
static {
- for (Priority e : Priority.values()) {
- ready.put(e, new LinkedList<TaskIdentifier>());
+ for (int i = 0; i < ready.size(); ++i) {
+ ready.set(i, new LinkedList<TaskIdentifier>());
}
}
private static Selector selector;
- {
+ static {
try {
selector = SelectorProvider.provider().openSelector();
} catch (IOException e) {
@@ -91,11 +95,11 @@
}
}
- private static RelativeTime timeout;
-
public static interface Task {
public void run(Context ctx);
+ // the context of a task is set in the task identifier once a task is
+ // moved into the ready queue
public static class Context {
EnumSet<Reason> reasons = EnumSet.noneOf(Reason.class);
Set<Channel> readableSet = null;
@@ -119,12 +123,13 @@
TaskIdentifier(Task t, Priority priority, boolean liveness,
TaskIdentifier prereq) {
this.task = t;
- this.priority = (priority == null) ? current_priority : priority;
+ this.priority = (priority == null) ? active_task.priority :
priority;
this.liveness = liveness;
this.prereq = prereq;
}
- void run(Task.Context ctx) {
+ void run() {
+ active_task = this;
task.run(ctx);
}
@@ -182,7 +187,7 @@
* the same priority.
*/
public static void addContinuation(Task task, EnumSet<Reason> reason) {
- assert current_priority != null;
+ assert active_task == null || active_task.priority != null;
TaskIdentifier tid = new TaskIdentifier(task, Priority.KEEP,
current_liveness, null);
queueReady(tid);
@@ -224,7 +229,7 @@
}
- TimeoutTask tid = new TimeoutTask(t, p, current_liveness, prereq,
delay);
+ TimeoutTask tid = new TimeoutTask(t, p, active_task.liveness, prereq,
delay);
return tid;
@@ -282,14 +287,13 @@
public static void run(Task task) throws IOException {
current_priority = Priority.DEFAULT;
current_liveness = true;
-
- timeout = RelativeTime.FOREVER;
-
+
+ RelativeTime timeout = RelativeTime.FOREVER;
+
addContinuation(task, EnumSet.of(Reason.STARTUP));
while (checkLiveness()) {
-
if (ready_count > 0) {
timeout = RelativeTime.ZERO;
} else {
@@ -297,7 +301,7 @@
}
AbsoluteTime now = AbsoluteTime.now();
-
+
while (true) {
TimeoutTask t = pending_timeout.peek();
@@ -328,22 +332,39 @@
private static void register(TimeoutTask t) {
// register with selector
-
+ throw new UnsupportedOperationException();
+
}
private static void queueReady(TaskIdentifier tid) {
assert tid.priority != null;
- ready.get(tid.priority).add(tid);
+ ready.get(tid.priority.ordinal()).add(tid);
ready_count++;
}
+ /*-
+ * Execute tasks until there either
+ * - there are no ready tasks
+ * - there is a pending task (which may be of higher priority)
+ */
private static void runReady() {
do {
if (ready_count == 0) {
return;
}
- } while (false /* ....todo */);
+ // in contrast to the c implementation, p<=0 right here
+ for (int p = Priority._COUNT.ordinal(); p <= 0; p--) {
+ TaskIdentifier tid = ready.get(p).pollFirst();
+ if (tid == null) {
+ break;
+ } else {
+ ready_count--;
+ tid.run();
+ }
+ }
+ } while (pending.size() == 0);
+
}
/**
Modified: gnunet-java/src/org/gnunet/util/TransmitReadyNotify.java
===================================================================
--- gnunet-java/src/org/gnunet/util/TransmitReadyNotify.java 2011-11-19
20:26:33 UTC (rev 18222)
+++ gnunet-java/src/org/gnunet/util/TransmitReadyNotify.java 2011-11-20
19:41:29 UTC (rev 18223)
@@ -21,7 +21,7 @@
package org.gnunet.util;
-import java.nio.Buffer;
+import java.nio.ByteBuffer;
public interface TransmitReadyNotify {
@@ -33,6 +33,6 @@
*/
// (buffer is initially at mark, data up to limit can be send at once,
// capacity may not be exceeded
- public void transmit(Buffer buf);
+ public void transmit(ByteBuffer buf);
}
Modified: gnunet-java/test/org/gnunet/construct/ConstructTest.java
===================================================================
--- gnunet-java/test/org/gnunet/construct/ConstructTest.java 2011-11-19
20:26:33 UTC (rev 18222)
+++ gnunet-java/test/org/gnunet/construct/ConstructTest.java 2011-11-20
19:41:29 UTC (rev 18223)
@@ -1,16 +1,34 @@
package org.gnunet.construct;
import org.gnunet.messages.MessageHeader;
+import org.gnunet.messages.SimpleTestMessage;
import org.junit.Test;
public class ConstructTest {
@Test
- public void testParse_as() {
- byte[] data = { 3, 4, 5, 6 };
- MessageHeader mh = Construct.parse_as(data, 0,
MessageHeader.class);
- assert mh.size == 1536;
- assert mh.type == 2560;
+ public void test_SimpleTestMessage_1() {
+
+ ObjectParser op = SimpleTestMessage.getParser();
+
+ /*
+ SimpleTestMessage stm = new SimpleTestMessage();
+ stm.v = 0xAB;
+ op.unparse(data, offset, dest)
+
+ */
+
+ RefLocation loc = new RefLocation();
+ Location[] locs = {loc};
+
+ byte[] a = {0x01, 0x01};
+
+ op.parse(a, 0, locs);
+
+ SimpleTestMessage m = (SimpleTestMessage) loc.get();
+
+ System.out.println(""+m.v);
+
}
}
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [GNUnet-SVN] r18223 - in gnunet-java: . src/org/gnunet/construct src/org/gnunet/messages src/org/gnunet/util test/org/gnunet/construct,
gnunet <=