[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[GNUnet-SVN] r20588 - in gnunet-java: . .idea .idea/libraries src/org/gn
From: |
gnunet |
Subject: |
[GNUnet-SVN] r20588 - in gnunet-java: . .idea .idea/libraries src/org/gnunet src/org/gnunet/construct src/org/gnunet/construct/parsers src/org/gnunet/dht src/org/gnunet/nse src/org/gnunet/statistics src/org/gnunet/util test/org/gnunet/construct |
Date: |
Sun, 18 Mar 2012 14:42:47 +0100 |
Author: dold
Date: 2012-03-18 14:42:47 +0100 (Sun, 18 Mar 2012)
New Revision: 20588
Added:
gnunet-java/src/org/gnunet/construct/ReflectUtil.java
gnunet-java/src/org/gnunet/dht/
gnunet-java/src/org/gnunet/dht/DistributedHashTable.java
gnunet-java/src/org/gnunet/util/GnunetHash.java
gnunet-java/src/org/gnunet/util/GnunetMessage.java
gnunet-java/src/org/gnunet/util/PeerIdentity.java
Removed:
gnunet-java/src/org/gnunet/construct/parsers/FieldParser.java
gnunet-java/update-msgtypes.sh
Modified:
gnunet-java/.idea/libraries/lib.xml
gnunet-java/.idea/misc.xml
gnunet-java/ISSUES
gnunet-java/gnunet-java.eml
gnunet-java/src/org/gnunet/construct/Construct.java
gnunet-java/src/org/gnunet/construct/MessageLoader.java
gnunet-java/src/org/gnunet/construct/MsgMap.txt
gnunet-java/src/org/gnunet/construct/parsers/ByteFillParser.java
gnunet-java/src/org/gnunet/construct/parsers/DoubleParser.java
gnunet-java/src/org/gnunet/construct/parsers/FillParser.java
gnunet-java/src/org/gnunet/construct/parsers/FixedSizeArrayParser.java
gnunet-java/src/org/gnunet/construct/parsers/IntegerParser.java
gnunet-java/src/org/gnunet/construct/parsers/NestedParser.java
gnunet-java/src/org/gnunet/construct/parsers/Parser.java
gnunet-java/src/org/gnunet/construct/parsers/SequenceParser.java
gnunet-java/src/org/gnunet/construct/parsers/StringParser.java
gnunet-java/src/org/gnunet/construct/parsers/UnionParser.java
gnunet-java/src/org/gnunet/construct/parsers/VariableSizeArrayParser.java
gnunet-java/src/org/gnunet/nse/NetworkSizeEstimation.java
gnunet-java/src/org/gnunet/statistics/Statistics.java
gnunet-java/src/org/gnunet/util/Client.java
gnunet-java/src/org/gnunet/util/MessageReceiver.java
gnunet-java/src/org/gnunet/util/MessageTransmitter.java
gnunet-java/src/org/gnunet/util/Resolver.java
gnunet-java/src/org/gnunet/util/Scheduler.java
gnunet-java/test/org/gnunet/construct/ConstructTest.java
gnunet-java/test/org/gnunet/construct/UnionTest.java
Log:
* refactored the Construct library to use ByteBuffer internally, some other
fixes to the construct library
* clients can now handle disconnects correctly, implemented in NSE
* started implementation of the DHT api
Modified: gnunet-java/.idea/libraries/lib.xml
===================================================================
--- gnunet-java/.idea/libraries/lib.xml 2012-03-17 16:31:42 UTC (rev 20587)
+++ gnunet-java/.idea/libraries/lib.xml 2012-03-18 13:42:47 UTC (rev 20588)
@@ -4,7 +4,6 @@
<root url="jar://$PROJECT_DIR$/lib/slf4j-api-1.6.4.jar!/" />
<root url="jar://$PROJECT_DIR$/lib/slf4j-log4j12-1.6.4.jar!/" />
<root url="jar://$PROJECT_DIR$/lib/log4j-1.2.16.jar!/" />
- <root url="jar://$PROJECT_DIR$/lib/annotations.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
Modified: gnunet-java/.idea/misc.xml
===================================================================
--- gnunet-java/.idea/misc.xml 2012-03-17 16:31:42 UTC (rev 20587)
+++ gnunet-java/.idea/misc.xml 2012-03-18 13:42:47 UTC (rev 20588)
@@ -10,7 +10,7 @@
<default-html-doctype>http://www.w3.org/1999/xhtml</default-html-doctype>
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_6"
assert-keyword="true" jdk-15="true" project-jdk-name="1.6"
project-jdk-type="JavaSDK">
- <output url="file://$PROJECT_DIR$/out" />
+ <output url="file://$PROJECT_DIR$/build" />
</component>
<component name="SvnBranchConfigurationManager">
<option name="myConfigurationMap">
Modified: gnunet-java/ISSUES
===================================================================
--- gnunet-java/ISSUES 2012-03-17 16:31:42 UTC (rev 20587)
+++ gnunet-java/ISSUES 2012-03-18 13:42:47 UTC (rev 20588)
@@ -229,5 +229,73 @@
* should we introduce a general interface "Cancelable" for requests?
* what is the persistence in statistics? (esp. in the watch message)
* general api question: should callbacks have their corresponding request
handler passed?
-
-
\ No newline at end of file
+
+
+
+ ====================================================
+
+ * regarding IzPack:
+ * are there really any advantages over just shipping a zip-file?
+ * no way to extend the $PATH, local ~/bin/ directory does not exist on e.g.
ubuntu
+
+
+
+
+ * where should stuff like PeerIdentity and HashCode/GnunetHash go?
+
+ * should there be a more elegant / convenient way to handle Enums/EnumSets?
+ * is the use of enums desireable anyway? (java enums are not very flexible /
you have to implement
+ a construtor everytime you want to use custom values)
+ * a simple way to do this would be to allow enums for @Integer-annotated
fields
+ * this would only allow us to access the ordinal of the enum value
+ * otherwise every enum would have to implement an interface like IntEnum
(enums in java cannot use extends)
+
+
+ * what is the purpose of the GNUNET_BLOCK_evaluate function?
+ * does is just check the validity of blocks / block requests?
+ * who is responsible for processing a query for a specific block type?
+ * what is a HELLO, what is a transport?
+
+
+proposal:
+
+change
+
address@hidden(SomeMessage.MSG_ID)
+public class SomeMessage extends Message {
+ public static final int MSG_ID = 12345;
+
+ @Nested
+ MessageHeader header;
+ @Uint16
+ int someValue
+ @Nested
+ SomeOtherMessage msg;
+}
+
+to
+
address@hidden(12345)
+public class SomeMessage extends GnunetMessageBody {
+ @Uint16
+ int someValue
+ @Nested
+ SomeOtherMessage msg;
+}
+
+Advantages:
+ * the user doesn't have to take care of the message header (the message
header is redundant anyways)
+ * no need to define the MSG_ID constant in every Message
+ * no extra code for MessageId, simpler annotation processing, simpler
MsgMap.txt
+ * with the current implementation it is not trivial to insert the message
header automatically,
+ Union/UnionCase already implements this.
+
+
+public class GnunetMessage implements Message {
+ MessageHeader header;
+ @Union(tag = "header.msgType")
+ GnunetMessageBody body;
+
+}
+
+public interface GnunetMessageBody extends MessageUnion { }
\ No newline at end of file
Modified: gnunet-java/gnunet-java.eml
===================================================================
--- gnunet-java/gnunet-java.eml 2012-03-17 16:31:42 UTC (rev 20587)
+++ gnunet-java/gnunet-java.eml 2012-03-18 13:42:47 UTC (rev 20588)
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<component>
- <output-test url="file://$MODULE_DIR$/bin"/>
+ <output-test url="file://$MODULE_DIR$/build"/>
<contentEntry url="file://$MODULE_DIR$">
<testFolder url="file://$MODULE_DIR$/test"/>
</contentEntry>
Modified: gnunet-java/src/org/gnunet/construct/Construct.java
===================================================================
--- gnunet-java/src/org/gnunet/construct/Construct.java 2012-03-17 16:31:42 UTC
(rev 20587)
+++ gnunet-java/src/org/gnunet/construct/Construct.java 2012-03-18 13:42:47 UTC
(rev 20588)
@@ -7,52 +7,30 @@
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
-import java.math.BigInteger;
+import java.nio.ByteBuffer;
import java.util.*;
/**
- * A version of Python's construct library for Java.
- *
* @author Christian Grothoff
*/
public class Construct {
- private static HashMap<Class<? extends Message>, Parser> parserCache = new
HashMap<Class<? extends Message>, Parser>();
+ private static HashMap<Class<? extends Message>, Parser> parserCache = new
HashMap<Class<? extends Message>, Parser>(100);
/**
- * Given a byte array with a message, parse it into an object of type c.
The
+ * Given a byte buffer 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 srcBuf buffer with the serialized binary data
* @param c desired object type to return
* @return instance of the desired object type
*/
- public static <T extends Message> T parseAs(byte[] data, int offset,
- Class<T> c) {
- T m;
+ public static <T extends Message> T parseAs(ByteBuffer srcBuf, Class<T> c)
{
+ T m = ReflectUtil.justInstantiate(c);
+ getParser(c).parse(srcBuf, 0, m, m);
- /*
- if (c.isMemberClass()) {
- throw new InterfaceViolationException("cannot instantiaze member
class " + c.getCanonicalName()
- + ": please make it static)");
- }
- */
-
-
- try {
- m = c.newInstance();
- } catch (InstantiationException e) {
- throw new InterfaceViolationException("Cannot instantiate " + c);
- } catch (IllegalAccessException e) {
- throw new InterfaceViolationException(
- String.format("Cannot instantiate Message %s (illegal
access)", c));
- }
-
- getParser(c).parse(data, offset, 0, m, m);
-
return m;
}
@@ -134,7 +112,7 @@
// the parser we are actually generating, used by the caller, set as
// return value of
// the runabout invocation
- FieldParser parser;
+ Parser parser;
// where are we currently, seen from the root message object
List<Field> path = new LinkedList<Field>();
@@ -145,16 +123,36 @@
private ParserGenerator() {
}
- public void visit(Union u) {
- try {
- parser = new UnionParser(frameSizePath, u.optional(),
field.getType().getCanonicalName(),
- c.getField(u.tag()), field);
- } catch (NoSuchFieldException e) {
- throw new InterfaceViolationException(String.format("field
'%s' does not exist in class '%s'", u.tag(), c));
+ private static List<Field> getFieldPathFromString(final String p,
final Class root) {
+ Class current = root;
+
+ String[] components = p.split("[.]");
+
+ List<Field> fp = new ArrayList<Field>(components.length);
+ for (String member : components) {
+ Field f;
+ try {
+ f = current.getField(member);
+ } catch (NoSuchFieldException e) {
+ throw new InterfaceViolationException("invalid field path,
component " + member + " not found");
+ }
+
+ fp.add(f);
+
+ current = f.getType();
}
+ return fp;
+
}
+ public void visit(Union u) {
+ parser = new UnionParser(frameSizePath, u.optional(),
field.getType().getCanonicalName(),
+ getFieldPathFromString(u.tag(), c), field);
+
+
+ }
+
public void visit(FrameSize ts) {
frameSizePath = new LinkedList<Field>(path);
@@ -296,13 +294,12 @@
* construct package.
*
* @param o object to serialize
- * @param data where to write the binary object data
- * @param offset where to start writing data
+ * @param dstBuf where to write the binary object data
* @return number of bytes written to data, -1 on error
*/
- public static int write(Message o, byte[] data, int offset) {
- Parser p = getParser(o.getClass());
- return p.write(data, offset, o);
+ public static int write(ByteBuffer dstBuf, Message msg) {
+ Parser p = getParser(msg.getClass());
+ return p.write(dstBuf, msg);
}
/**
@@ -321,97 +318,14 @@
public static byte[] toBinary(Message m) {
byte[] a = new byte[getSize(m)];
- write(m, a, 0);
+ ByteBuffer buf = ByteBuffer.wrap(a);
+ write(buf, m);
return a;
}
- public static void patchSizeFields(Message m) {
+ public static void patch(Message m) {
Parser p = getParser(m.getClass());
p.patch(m, p.getSize(m));
}
- // the following are utility methods for the java reflection api
-
- public static class ReflectionUtil {
- /**
- * assign an enum value to each numeric type we want to serialize in
- * order do switch statements on field types
- */
- public enum NumFieldType {
- BIGNUM, BYTE_PRIM, SHORT_PRIM, INT_PRIM, LONG_PRIM, CHAR_PRIM
- }
-
- /**
- * Get the corresponding NumFieldType for a Field if possible
- *
- * @param f a field of numeric type
- * @return the corresponding NumFieldType
- */
- public static NumFieldType getNumFieldType(Field f) {
- if (f.getType().equals(Long.TYPE)) {
- return NumFieldType.LONG_PRIM;
- } else if (f.getType().equals(java.lang.Integer.TYPE)) {
- return NumFieldType.INT_PRIM;
- } else if (f.getType().equals(Short.TYPE)) {
- return NumFieldType.SHORT_PRIM;
- } else if (f.getType().equals(Byte.TYPE)) {
- return NumFieldType.BYTE_PRIM;
- } else if (f.getType().equals(Character.TYPE)) {
- return NumFieldType.CHAR_PRIM;
- } else if (f.getType().equals(BigInteger.class)) {
- return NumFieldType.BIGNUM;
- } else {
- throw new InterfaceViolationException(
- "expected numeric type, got: " + f.getType());
- }
- }
-
- public static void setNumField(Object obj, NumFieldType ft, Field f,
long val) {
- try {
- switch (ft) {
- case LONG_PRIM:
- f.setLong(obj, val);
- break;
- case INT_PRIM:
- f.setInt(obj, (int) val);
- break;
- case SHORT_PRIM:
- f.setShort(obj, (short) val);
- break;
- case BYTE_PRIM:
- f.setByte(obj, (byte) val);
- break;
- case CHAR_PRIM:
- f.setChar(obj, (char) val);
- break;
- case BIGNUM:
- f.set(obj, BigInteger.valueOf(val));
- break;
- }
- } catch (IllegalArgumentException e) {
- throw new InterfaceViolationException("cannot access field");
- } catch (IllegalAccessException e) {
- throw new InterfaceViolationException("cannot access field");
- }
- }
-
- public static Object followFieldPath(List<Field> fl, Object obj,
- int depth) {
- for (int i = 0; i < depth; ++i) {
- try {
- obj = fl.get(i).get(obj);
- } catch (IllegalArgumentException e) {
- throw new RuntimeException();
- } catch (IllegalAccessException e) {
- throw new RuntimeException();
- }
- }
- return obj;
- }
-
- public static Object followFieldPath(List<Field> fl, Object obj) {
- return followFieldPath(fl, obj, fl.size());
- }
- }
-
}
Modified: gnunet-java/src/org/gnunet/construct/MessageLoader.java
===================================================================
--- gnunet-java/src/org/gnunet/construct/MessageLoader.java 2012-03-17
16:31:42 UTC (rev 20587)
+++ gnunet-java/src/org/gnunet/construct/MessageLoader.java 2012-03-18
13:42:47 UTC (rev 20588)
@@ -29,9 +29,9 @@
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
-import java.lang.*;
import java.lang.Integer;
import java.net.URL;
+import java.nio.ByteBuffer;
import java.util.HashMap;
import java.util.Map;
@@ -87,7 +87,7 @@
}
}
- public static Message loadMessage(int type, byte[] data, int offset) {
+ public static Message loadMessage(int type, ByteBuffer dstBuf) {
String className = msgmap.get(type);
if (className == null) {
throw new MessageFormatException("don't know how to translate
message of type " + type);
@@ -101,7 +101,7 @@
throw new InternalLogicError(String.format("message class '%s' not
found in classpath", className));
}
- return Construct.parseAs(data, offset, msgClass);
+ return Construct.parseAs(dstBuf, msgClass);
}
public static Class loadUnionClass(String unionType, int type) {
Modified: gnunet-java/src/org/gnunet/construct/MsgMap.txt
===================================================================
--- gnunet-java/src/org/gnunet/construct/MsgMap.txt 2012-03-17 16:31:42 UTC
(rev 20587)
+++ gnunet-java/src/org/gnunet/construct/MsgMap.txt 2012-03-18 13:42:47 UTC
(rev 20588)
@@ -12,4 +12,4 @@
1|org.gnunet.construct.UnionTest.TestUnion=org.gnunet.construct.UnionTest$TestUnionCase1
0|org.gnunet.util.Resolver.AddressUnion=org.gnunet.util.Resolver$TextualAddress
1|org.gnunet.util.Resolver.AddressUnion=org.gnunet.util.Resolver$NumericAddress
-# generated 2012/02/23 21:30:09
+# generated 2012/03/17 23:22:37
Added: gnunet-java/src/org/gnunet/construct/ReflectUtil.java
===================================================================
--- gnunet-java/src/org/gnunet/construct/ReflectUtil.java
(rev 0)
+++ gnunet-java/src/org/gnunet/construct/ReflectUtil.java 2012-03-18
13:42:47 UTC (rev 20588)
@@ -0,0 +1,183 @@
+package org.gnunet.construct;
+
+
+import org.gnunet.exceptions.InterfaceViolationException;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.math.BigInteger;
+import java.util.List;
+
+public class ReflectUtil {
+ public static <T> T justInstantiate(Class<T> c) {
+ try {
+ return c.getConstructor().newInstance();
+ } catch (InstantiationException e) {
+ throw new InterfaceViolationException("Cannot instantiate " + c);
+ } catch (IllegalAccessException e) {
+ throw new InterfaceViolationException(
+ String.format("Cannot instantiate Message %s (illegal
access)", c));
+ } catch (NoSuchMethodException e) {
+ throw new InterfaceViolationException(
+ String.format("No suitable default constructor for class
%s", c));
+ } catch (InvocationTargetException e) {
+ throw new InterfaceViolationException(
+ String.format("Exception thrown while constructing object
of class %s", c));
+ }
+ }
+
+ /**
+ * assign an enum value to each numeric type we want to serialize in
+ * order do switch statements on field types
+ */
+ public enum NumFieldType {
+ BIGNUM, BYTE_PRIM, SHORT_PRIM, INT_PRIM, LONG_PRIM, CHAR_PRIM
+ }
+
+
+ /**
+ * Convenience wrapper for a field that stores a numeric value.
+ */
+ public static class NumField {
+ final private Field targetField;
+ final private NumFieldType targetType;
+
+
+ public NumFieldType getNumFieldType() {
+ return targetType;
+ }
+
+ public NumField(Field f) {
+ this.targetField = f;
+ if (f.getType().equals(Long.TYPE)) {
+ targetType = NumFieldType.LONG_PRIM;
+ } else if (f.getType().equals(java.lang.Integer.TYPE)) {
+ targetType = NumFieldType.INT_PRIM;
+ } else if (f.getType().equals(Short.TYPE)) {
+ targetType = NumFieldType.SHORT_PRIM;
+ } else if (f.getType().equals(Byte.TYPE)) {
+ targetType = NumFieldType.BYTE_PRIM;
+ } else if (f.getType().equals(Character.TYPE)) {
+ targetType = NumFieldType.CHAR_PRIM;
+ } else if (f.getType().equals(BigInteger.class)) {
+ targetType = NumFieldType.BIGNUM;
+ } else {
+ throw new InterfaceViolationException(
+ "expected numeric type, got: " + f.getType());
+ }
+ }
+
+ public void set(Object obj, long val) {
+ try {
+ switch (targetType) {
+ case LONG_PRIM:
+ targetField.setLong(obj, val);
+ break;
+ case INT_PRIM:
+ targetField.setInt(obj, (int) val);
+ break;
+ case SHORT_PRIM:
+ targetField.setShort(obj, (short) val);
+ break;
+ case BYTE_PRIM:
+ targetField.setByte(obj, (byte) val);
+ break;
+ case CHAR_PRIM:
+ targetField.setChar(obj, (char) val);
+ break;
+ case BIGNUM:
+ targetField.set(obj, BigInteger.valueOf(val));
+ break;
+ }
+ } catch (IllegalArgumentException e) {
+ throw new InterfaceViolationException("cannot access field");
+ } catch (IllegalAccessException e) {
+ throw new InterfaceViolationException("cannot access field");
+ }
+ }
+
+ public void set(Object obj, BigInteger val) {
+ try {
+ targetField.set(obj, val);
+ } catch (IllegalAccessException e) {
+ throw new InterfaceViolationException("cannot access field");
+ }
+ }
+
+ public long get(Object obj) {
+ try {
+ switch (targetType) {
+ case LONG_PRIM:
+ return targetField.getLong(obj);
+ case INT_PRIM:
+ return targetField.getInt(obj);
+ case SHORT_PRIM:
+ return targetField.getShort(obj);
+ case BYTE_PRIM:
+ return targetField.getByte(obj);
+ case CHAR_PRIM:
+ return targetField.getChar(obj);
+ case BIGNUM:
+ throw new RuntimeException("get() called on NumField
that is a BigInteger");
+ default:
+ throw new AssertionError("unreachable");
+ }
+ } catch (IllegalAccessException e) {
+ throw new InterfaceViolationException("cannot access field");
+ }
+ }
+
+ public BigInteger getBig(Object obj) {
+ if (isBig()) {
+ return (BigInteger) justGet(obj, targetField);
+ } else {
+ return BigInteger.valueOf(this.get(obj));
+ }
+ }
+
+ public boolean isBig() {
+ return targetType.equals(NumFieldType.BIGNUM);
+ }
+ }
+
+
+ public static Object followFieldPath(List<Field> fl, Object obj,
+ int depth) {
+ for (int i = 0; i < depth; ++i) {
+ try {
+ obj = fl.get(i).get(obj);
+ } catch (IllegalArgumentException e) {
+ throw new RuntimeException();
+ } catch (IllegalAccessException e) {
+ throw new RuntimeException();
+ }
+ }
+ return obj;
+ }
+
+ public static Object followFieldPath(List<Field> fl, Object obj) {
+ return followFieldPath(fl, obj, fl.size());
+ }
+
+ public static Object followFieldPathToParent(List<Field> fl, Object obj) {
+ return followFieldPath(fl, obj, fl.size() - 1);
+ }
+
+ public static Object justGet(Object obj, Field f) {
+ try {
+ return f.get(obj);
+ } catch (IllegalAccessException e) {
+ throw new InterfaceViolationException(
+ String.format("Cannot access private field %s in class
%s", f, obj.getClass()));
+ }
+ }
+
+ public static void justSet(Object obj, Field f, Object val) {
+ try {
+ f.set(obj, val);
+ } catch (IllegalAccessException e) {
+ throw new InterfaceViolationException(
+ String.format("Cannot access private field %s in class
%s", f, obj.getClass()));
+ }
+ }
+}
Modified: gnunet-java/src/org/gnunet/construct/parsers/ByteFillParser.java
===================================================================
--- gnunet-java/src/org/gnunet/construct/parsers/ByteFillParser.java
2012-03-17 16:31:42 UTC (rev 20587)
+++ gnunet-java/src/org/gnunet/construct/parsers/ByteFillParser.java
2012-03-18 13:42:47 UTC (rev 20588)
@@ -1,88 +1,83 @@
package org.gnunet.construct.parsers;
-import org.gnunet.construct.Construct;
-import org.gnunet.construct.Construct.ReflectionUtil;
import org.gnunet.construct.Message;
+import org.gnunet.construct.ReflectUtil;
+import org.gnunet.exceptions.MessageFormatException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.lang.reflect.Array;
import java.lang.reflect.Field;
+import java.nio.ByteBuffer;
import java.util.List;
/**
- * Parse an array that takes up all the available space.
+ * Parse a byte array that takes up all the remaining space in its frame.
* A 0-element array takes up no space.
* 'null' is an invalid value for a field of this type.
*
* @author Florian Dold
*
*/
-public class ByteFillParser extends FieldParser {
+public class ByteFillParser implements Parser {
private static final Logger logger = LoggerFactory
.getLogger(ByteFillParser.class);
+ /**
+ * The total size path stores where the total size field is located,
+ * relative to the frame object.
+ */
+ private final List<Field> totalSizePath;
+
+ private final ReflectUtil.NumField totalSizeField;
+
+ private final Field targetField;
- private List<Field> totalSizePath;
-
- private ReflectionUtil.NumFieldType totalSizeFieldType;
-
public ByteFillParser(List<Field> totalSizePath, Field field) {
- super(field);
+ targetField = field;
this.totalSizePath = totalSizePath;
- totalSizeFieldType = Construct.ReflectionUtil
- .getNumFieldType(totalSizePath.get(totalSizePath.size() - 1));
+ totalSizeField = new
ReflectUtil.NumField(totalSizePath.get(totalSizePath.size() - 1));
}
@Override
- public int getSize(final Message src) {
- return Array.getLength(getFieldValue(src));
+ public int getSize(Message src) {
+ return Array.getLength(ReflectUtil.justGet(src, targetField));
}
- private int getSizeFieldValue(Message m) {
- Object obj = Construct.ReflectionUtil.followFieldPath(totalSizePath,
m);
- return ((Number) obj).intValue();
- }
@Override
- public int parse(final byte[] srcData, final int offset, int frameOffset,
- Message frameObj, final Message dst) {
- int remaining = (frameOffset + getSizeFieldValue(frameObj)) - offset;
+ public int parse(ByteBuffer srcBuf, int frameOffset, Message frameObj,
Message dst) {
+ int frameSize = (int)
totalSizeField.get(ReflectUtil.followFieldPathToParent(totalSizePath,
frameObj));
+ int remaining = frameOffset + frameSize - srcBuf.position();
- if (remaining <= 0) {
- setFieldValue(dst, new byte[0]);
+ if (remaining < 0) {
+ throw new MessageFormatException("negative size remaining for
variable size message");
+ }
+
+ if (remaining == 0) {
+ ReflectUtil.justSet(dst, targetField, new byte[0]);
return 0;
}
byte[] a = new byte[remaining];
- System.arraycopy(srcData, offset, a, 0, remaining);
+ srcBuf.get(a);
- setFieldValue(dst, a);
+ ReflectUtil.justSet(dst, targetField, a);
return frameOffset;
}
@Override
- public int write(final byte[] dstData, final int offset, final Message
src) {
- byte[] a = (byte[]) getFieldValue(src);
- System.arraycopy(a, 0, dstData, offset, a.length);
+ public int write(ByteBuffer dstBuf, Message src) {
+ byte[] a = (byte[]) ReflectUtil.justGet(src, targetField);
+ dstBuf.put(a);
return a.length;
}
- /**
- * Currently every parser that uses a total size field sets the total size
- * field. This works, but is very redundant.
- */
@Override
public void patch(Message m, int frameSize) {
- Object obj = ReflectionUtil.followFieldPath(totalSizePath, m,
- totalSizePath.size() - 1);
- Field f = totalSizePath.get(totalSizePath.size() - 1);
-
- ReflectionUtil.setNumField(obj, totalSizeFieldType, f,
- frameSize);
+ totalSizeField.set(ReflectUtil.followFieldPathToParent(totalSizePath,
m), frameSize);
}
-
}
Modified: gnunet-java/src/org/gnunet/construct/parsers/DoubleParser.java
===================================================================
--- gnunet-java/src/org/gnunet/construct/parsers/DoubleParser.java
2012-03-17 16:31:42 UTC (rev 20587)
+++ gnunet-java/src/org/gnunet/construct/parsers/DoubleParser.java
2012-03-18 13:42:47 UTC (rev 20588)
@@ -7,40 +7,44 @@
import java.lang.reflect.Field;
import java.nio.ByteBuffer;
-public class DoubleParser extends FieldParser{
- public DoubleParser(final Field f) {
- super(f);
+public class DoubleParser implements Parser {
+
+ private final Field targetField;
+
+ public DoubleParser(Field f) {
+ targetField = f;
}
@Override
public int getSize(Message srcObj) {
- return 8;
+ return Double.SIZE / 8;
}
@Override
- public int parse(byte[] srcData, int offset, int frameOffset, Message
frameObj, Message dstObj) {
- double d = ByteBuffer.wrap(srcData, offset, 8).getDouble();
+ public int parse(ByteBuffer srcBuf, int frameOffset, Message frameObj,
Message dstObj) {
+ double d = srcBuf.getDouble();
try {
- field.setDouble(dstObj, d);
+ targetField.setDouble(dstObj, d);
} catch (IllegalAccessException e) {
throw new InternalLogicError("cannot access field (should have
been caught in Construct)");
}
- return 8;
+ return Double.SIZE / 8;
}
@Override
- public int write(byte[] dstData, int offset, Message srcObj) {
+ public int write(ByteBuffer dstBuf, Message srcObj) {
double d;
try {
- d = field.getDouble(srcObj);
+ d = targetField.getDouble(srcObj);
} catch (IllegalAccessException e) {
throw new InternalLogicError("field does not exist (should be
caught in Construct)");
}
- ByteBuffer.wrap(dstData, offset, 8).putDouble(d);
+ dstBuf.putDouble(d);
return 8;
}
@Override
public void patch(Message m, int frameSize) {
+ // nothing to do here
}
}
Deleted: gnunet-java/src/org/gnunet/construct/parsers/FieldParser.java
===================================================================
--- gnunet-java/src/org/gnunet/construct/parsers/FieldParser.java
2012-03-17 16:31:42 UTC (rev 20587)
+++ gnunet-java/src/org/gnunet/construct/parsers/FieldParser.java
2012-03-18 13:42:47 UTC (rev 20588)
@@ -1,43 +0,0 @@
-package org.gnunet.construct.parsers;
-
-import java.lang.reflect.Field;
-
-/**
- * Convenience super class for all parsers that store their result in the
field
- * of an object.
- *
- * @author Florian Dold
- *
- */
-public abstract class FieldParser implements Parser {
-
- protected final Field field;
-
- public FieldParser(final Field f) {
- this.field = f;
- }
-
- public Class getFieldType() {
- return field.getType();
- }
-
- public Object getFieldValue(final Object obj) {
- try {
- return field.get(obj);
- } catch (final IllegalArgumentException e) {
- throw new RuntimeException();
- } catch (final IllegalAccessException e) {
- throw new RuntimeException();
- }
- }
-
- public void setFieldValue(final Object obj, final Object val) {
- try {
- field.set(obj, val);
- } catch (final IllegalArgumentException e) {
- throw new RuntimeException(e);
- } catch (final IllegalAccessException e) {
- throw new RuntimeException();
- }
- }
-}
Modified: gnunet-java/src/org/gnunet/construct/parsers/FillParser.java
===================================================================
--- gnunet-java/src/org/gnunet/construct/parsers/FillParser.java
2012-03-17 16:31:42 UTC (rev 20587)
+++ gnunet-java/src/org/gnunet/construct/parsers/FillParser.java
2012-03-18 13:42:47 UTC (rev 20588)
@@ -1,119 +1,89 @@
package org.gnunet.construct.parsers;
-import org.gnunet.construct.Construct.ReflectionUtil;
import org.gnunet.construct.Message;
+import org.gnunet.construct.ReflectUtil;
+import org.gnunet.exceptions.InterfaceViolationException;
import java.lang.reflect.Array;
import java.lang.reflect.Field;
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
import java.util.List;
/**
* Parse an array that takes up all the available space.
- *
+ *
* @author Florian Dold
- *
*/
-public class FillParser extends FieldParser {
- private Parser elemParser;
-
- private List<Field> totalSizePath;
+public class FillParser implements Parser {
+ private final Parser elemParser;
- private ReflectionUtil.NumFieldType totalSizeFieldType;
+ private final Field targetField;
+ private final List<Field> totalSizePath;
+ private final ReflectUtil.NumField totalSizeField;
+
public FillParser(Parser p, List<Field> totalSizePath, Field field) {
- super(field);
+ targetField = field;
elemParser = p;
this.totalSizePath = totalSizePath;
- totalSizeFieldType = ReflectionUtil.getNumFieldType(totalSizePath
- .get(totalSizePath.size() - 1));
+ totalSizeField = new
ReflectUtil.NumField(totalSizePath.get(totalSizePath.size() - 1));
}
@Override
public int getSize(final Message src) {
int size = 0;
- final Object arr = getFieldValue(src);
-
+ final Object arr = ReflectUtil.justGet(src, targetField);
+
if (arr == null) {
throw new RuntimeException("array not initialized");
}
-
+
for (int i = 0; i < Array.getLength(arr); ++i) {
size += elemParser.getSize((Message) Array.get(arr, i));
}
return size;
}
- private int getSizeFieldValue(Message m) {
- Object obj = ReflectionUtil.followFieldPath(totalSizePath, m);
- return ((Number) obj).intValue();
- }
-
@Override
- public int parse(final byte[] srcData, final int offset, int frameOffset,
+ public int parse(ByteBuffer srcBuf, int frameOffset,
Message frameObj, final Message dstObj) {
- /*
- int remaining = getSizeFieldValue(dstObj) - frameOffset;
- int elemNumber;
- try {
- elemNumber = ((Number) sizeField.get(dstObj)).intValue();
- } catch (IllegalArgumentException e1) {
- throw new RuntimeException();
- } catch (IllegalAccessException e1) {
- throw new RuntimeException();
- }
-
+ final int frameSize = (int)
totalSizeField.get(ReflectUtil.followFieldPathToParent(totalSizePath,
frameObj));
+ int remaining = frameOffset + frameSize - srcBuf.position();
int size = 0;
- final Object arr = Array.newInstance(getFieldType().getComponentType(),
- elemNumber);
- setFieldValue(dstObj, arr);
+ ArrayList<Message> list = new ArrayList<Message>(10);
- for (int i = 0; i < elemNumber; ++i) {
- Message elemObj;
- try {
- elemObj = (Message) getFieldType().getComponentType()
- .newInstance();
- } catch (final InstantiationException e) {
- throw new RuntimeException();
- } catch (final IllegalAccessException e) {
- throw new RuntimeException();
- }
-
- Array.set(arr, i, elemObj);
-
- size += elemParser.parse(srcData, offset + size,
- frameOffset - size, elemObj);
+ while (remaining > 0) {
+ Message next = ReflectUtil.justInstantiate((Class<Message>)
targetField.getType().getComponentType());
+ int s = elemParser.parse(srcBuf, frameOffset, frameObj, next);
+ size += s;
+ remaining -= s;
}
+ try {
+ targetField.set(dstObj, list.toArray());
+ } catch (IllegalAccessException e) {
+ throw new InterfaceViolationException("cannot acces field");
+ }
+
return size;
- */
- throw new UnsupportedOperationException("not yet implemented");
}
@Override
- public int write(final byte[] dstData, final int offset, final Message
src) {
+ public int write(final ByteBuffer dstBuf, final Message src) {
int size = 0;
- final Object arr = getFieldValue(src);
+ final Object arr = ReflectUtil.justGet(src, targetField);
for (int i = 0; i < Array.getLength(arr); ++i) {
- size += elemParser.write(dstData, offset + size,
- (Message) Array.get(arr, i));
+ size += elemParser.write(dstBuf, (Message) Array.get(arr, i));
}
return size;
}
-
- /**
- * Currently every parser that uses a total size field sets the total size
field.
- * This works, but is very redundant.
- */
@Override
public void patch(Message m, int frameSize) {
- Object obj = ReflectionUtil.followFieldPath(totalSizePath, m,
- totalSizePath.size() - 1);
- Field f = totalSizePath.get(totalSizePath.size() - 1);
-
- ReflectionUtil.setNumField(obj, totalSizeFieldType, f, frameSize);
+ totalSizeField.set(ReflectUtil.followFieldPathToParent(totalSizePath,
m), frameSize);
}
}
Modified: gnunet-java/src/org/gnunet/construct/parsers/FixedSizeArrayParser.java
===================================================================
--- gnunet-java/src/org/gnunet/construct/parsers/FixedSizeArrayParser.java
2012-03-17 16:31:42 UTC (rev 20587)
+++ gnunet-java/src/org/gnunet/construct/parsers/FixedSizeArrayParser.java
2012-03-18 13:42:47 UTC (rev 20588)
@@ -1,19 +1,23 @@
package org.gnunet.construct.parsers;
import org.gnunet.construct.Message;
+import org.gnunet.construct.ReflectUtil;
import java.lang.reflect.Array;
import java.lang.reflect.Field;
+import java.nio.ByteBuffer;
-public class FixedSizeArrayParser extends FieldParser {
+public class FixedSizeArrayParser implements Parser {
- private final FieldParser elemParser;
+ private final Parser elemParser;
+ private final Field targetField;
+
private final int elemNumber;
public FixedSizeArrayParser(final int elemNumber,
- final FieldParser elemParser, final Field f) {
- super(f);
+ final Parser elemParser, final Field f) {
+ targetField = f;
this.elemNumber = elemNumber;
this.elemParser = elemParser;
}
@@ -21,12 +25,12 @@
@Override
public int getSize(final Message srcObj) {
int size = 0;
- final Object arr = getFieldValue(srcObj);
-
+ final Object arr = ReflectUtil.justGet(srcObj, targetField);
+
if (arr == null) {
throw new RuntimeException("array not initialized");
}
-
+
for (int i = 0; i < Array.getLength(arr); ++i) {
size += elemParser.getSize((Message) Array.get(arr, i));
}
@@ -34,52 +38,39 @@
}
@Override
- public int parse(final byte[] srcData, final int offset, int frameOffset,
+ public int parse(ByteBuffer srcBuf, int frameOffset,
Message frameObj, final Message dstObj) {
int size = 0;
- final Object arr = Array.newInstance(getFieldType().getComponentType(),
- elemNumber);
- setFieldValue(dstObj, arr);
+ final Object arr =
Array.newInstance(targetField.getType().getComponentType(), elemNumber);
+ ReflectUtil.justSet(dstObj, targetField, arr);
for (int i = 0; i < elemNumber; ++i) {
- Message elemObj;
- try {
- elemObj = (Message) getFieldType().getComponentType()
- .newInstance();
- } catch (final InstantiationException e) {
- throw new RuntimeException();
- } catch (final IllegalAccessException e) {
- throw new RuntimeException();
- }
-
+ Message elemObj =
ReflectUtil.justInstantiate((Class<Message>)targetField.getType().getComponentType());
Array.set(arr, i, elemObj);
-
- size += elemParser.parse(srcData, offset + size,
- frameOffset - size, null, elemObj);
+
+ size += elemParser.parse(srcBuf, frameOffset - size, frameObj,
elemObj);
}
return size;
}
@Override
- public int write(final byte[] dstData, final int offset,
- final Message srcObj) {
+ public int write(final ByteBuffer dstBuf,
+ final Message srcObj) {
int size = 0;
- final Object arr = getFieldValue(srcObj);
+ final Object arr = ReflectUtil.justGet(srcObj, targetField);
for (int i = 0; i < Array.getLength(arr); ++i) {
- size += elemParser.write(dstData, offset + size,
- (Message) Array.get(arr, i));
+ size += elemParser.write(dstBuf, (Message) Array.get(arr, i));
}
return size;
}
@Override
public void patch(Message m, int frameSize) {
- final Object arr = getFieldValue(m);
+ final Object arr = ReflectUtil.justGet(m, targetField);
for (int i = 0; i < Array.getLength(arr); ++i) {
elemParser.patch((Message) Array.get(arr, i), frameSize);
}
-
}
}
Modified: gnunet-java/src/org/gnunet/construct/parsers/IntegerParser.java
===================================================================
--- gnunet-java/src/org/gnunet/construct/parsers/IntegerParser.java
2012-03-17 16:31:42 UTC (rev 20587)
+++ gnunet-java/src/org/gnunet/construct/parsers/IntegerParser.java
2012-03-18 13:42:47 UTC (rev 20588)
@@ -1,13 +1,13 @@
package org.gnunet.construct.parsers;
-import org.gnunet.construct.Construct.ReflectionUtil;
import org.gnunet.construct.Message;
+import org.gnunet.construct.ReflectUtil;
import java.lang.reflect.Field;
import java.math.BigInteger;
-import java.util.Arrays;
+import java.nio.ByteBuffer;
-public class IntegerParser extends FieldParser {
+public class IntegerParser implements Parser {
public static final boolean UNSIGNED = false;
public static final boolean SIGNED = true;
@@ -16,15 +16,15 @@
private final boolean isSigned;
- private ReflectionUtil.NumFieldType ft;
+ private final ReflectUtil.NumField targetField;
+
public IntegerParser(final int byteSize, final boolean isSigned,
final Field f) {
- super(f);
this.byteSize = byteSize;
this.isSigned = isSigned;
- ft = ReflectionUtil.getNumFieldType(f);
+ targetField = new ReflectUtil.NumField(f);
}
@Override
@@ -33,186 +33,103 @@
}
@Override
- public int parse(final byte[] srcData, int offset, int frameOffset,
- Message frameObj, final Message dstObj) {
- try {
- switch (ft) {
- case BYTE_PRIM:
- field.setByte(dstObj, readByte(srcData, offset));
- break;
- case SHORT_PRIM:
- field.setShort(dstObj, (short) readLong(srcData, offset));
- break;
- case INT_PRIM:
- field.setInt(dstObj, (int) readLong(srcData, offset));
- break;
- case LONG_PRIM:
- field.setLong(dstObj, readLong(srcData, offset));
- break;
- case BIGNUM:
- case CHAR_PRIM:
- throw new UnsupportedOperationException("not yet
implemented");
- default:
- throw new RuntimeException("invalid member type");
- }
-
- } catch (IllegalArgumentException e) {
- throw new RuntimeException(e);
- } catch (IllegalAccessException e) {
- throw new RuntimeException();
+ public int parse(final ByteBuffer srcBuf, int frameOffset, Message
frameObj, final Message dstObj) {
+ if (targetField.isBig()) {
+ targetField.set(dstObj, readBigInteger(srcBuf));
+ } else {
+ targetField.set(dstObj, readLong(srcBuf));
}
-
return byteSize;
}
@Override
- public int write(final byte[] dstData, final int offset,
- final Message srcObj) {
-
- try {
- switch (ft) {
- case BYTE_PRIM:
- writeInt(field.getInt(srcObj), dstData, offset);
- break;
- case INT_PRIM:
- writeInt(field.getInt(srcObj), dstData, offset);
- break;
- case SHORT_PRIM:
- writeShort(field.getShort(srcObj), dstData, offset);
- break;
- case LONG_PRIM:
- writeLong(field.getLong(srcObj), dstData, offset);
- break;
- case BIGNUM:
- case CHAR_PRIM:
- throw new UnsupportedOperationException("not yet
implemented");
- default:
- throw new RuntimeException("invalid member type: ");
- }
- } catch (IllegalArgumentException e) {
- throw new RuntimeException();
- } catch (IllegalAccessException e) {
- throw new RuntimeException();
+ public int write(final ByteBuffer dstBuf, final Message srcObj) {
+ if (targetField.isBig()) {
+ writeBitInteger(targetField.getBig(srcObj), dstBuf);
+ } else {
+ // todo: error checking on numeric overflow, if requested
+ writeLong(targetField.get(srcObj), dstBuf);
}
-
return byteSize;
}
+
+
@Override
public void patch(Message m, int frameSize) {
+ // nothing to do
}
- public void writeByte(byte val, byte[] data, int offset) {
- // fill with zeroes if byteSize is too large for a byte
- Arrays.fill(data, offset, offset + (byteSize - 1), (byte) 0);
- data[offset + (byteSize - 1)] = val;
- if (isSigned) {
- byte sign = (byte) (val & 0x80);
- // remove the sign bit sign
- data[offset + (byteSize - 1)] &= ~sign;
- // ... and put it in the right place (lowest byte)
- data[offset] |= sign;
- }
- }
- public void writeShort(short val, byte[] data, int offset) {
- Arrays.fill(data, offset, offset + (byteSize - 1), (byte) 0);
- data[offset + (byteSize - 1)] = (byte) (val & 0xFF);
- if (byteSize >= 2) {
- val >>= 8;
- data[offset + (byteSize - 2)] = (byte) (val & 0xFF);
- }
- if (isSigned) {
- byte sign = (byte) (val & 0x80);
- // remove the sign bit sign
- data[offset + (byteSize - 1)] &= ~sign;
- // ... and put it in the right place (lowest byte)
- data[offset] |= sign;
- }
- }
+ public void writeLong(final long val, final ByteBuffer dstBuf) {
- public void writeInt(int val, byte[] data, int offset) {
- Arrays.fill(data, offset, offset + (byteSize - 1), (byte) 0);
- data[offset + (byteSize - 1)] = (byte) (val & 0xFF);
- for (int i = 2; i <= 4; ++i) {
- if (byteSize - i < 0) {
- break;
- }
- val >>= 8;
- data[offset + (byteSize - i)] = (byte) (val & 0xFF);
+ long myval = val;
+
+ //DBG
+ int startPos = dstBuf.position();
+
+
+ // position of the last byte we are responsible to write
+ int last = dstBuf.position() + byteSize - 1;
+
+ while (last >= dstBuf.position()) {
+ dstBuf.put(last, (byte) (myval & 0xFF));
+ myval >>>= 8;
+ last -= 1;
}
+
if (isSigned) {
- byte sign = (byte) (val & 0x80);
- // remove the sign bit sign
- data[offset + (byteSize - 1)] &= ~sign;
+ // a long has 8 bytes, shift by 7 bytes (non-arithmetically) to
get the sign
+ byte sign = (byte) ((val >>> (7*8)) & 0x80);
+ // remove the sign bit from the buffer
+ dstBuf.put(dstBuf.position() + byteSize - 1, (byte)
(dstBuf.get(dstBuf.position() + byteSize - 1) & ~sign));
// ... and put it in the right place (lowest byte)
- data[offset] |= sign;
- }
- }
+ dstBuf.put(dstBuf.position(), (byte)
(dstBuf.get(dstBuf.position()) | sign));
- public void writeLong(long val, byte[] data, int offset) {
- Arrays.fill(data, offset, offset + (byteSize - 1), (byte) 0);
- data[offset + (byteSize - 1)] = (byte) (val & 0xFF);
- for (int i = 2; i <= 8; ++i) {
- if (byteSize - i < 0) {
- break;
- }
- val >>= 8;
- data[offset + (byteSize - i)] = (byte) (val & 0xFF);
}
- if (isSigned) {
- byte sign = (byte) (val & 0x80);
- // remove the sign bit sign
- data[offset + (byteSize - 1)] &= ~sign;
- // ... and put it in the right place (lowest byte)
- data[offset] |= sign;
- }
+
+ dstBuf.position(dstBuf.position() + byteSize);
}
- public byte readByte(byte[] data, int offset) {
- byte val;
- val = data[offset + (byteSize - 1)];
- if (isSigned) {
- // explicitly OR sign bit to the right place if the source buffer
is
- // too large
- byte sign = (byte) (data[offset] & 0x80);
- val |= sign;
- }
- return val;
+ private void writeBitInteger(BigInteger big, ByteBuffer dstBuf) {
+ throw new UnsupportedOperationException("not yet implemented");
}
- public long readLong(byte[] data, int offset) {
+ public long readLong(ByteBuffer srcBuf) {
long val = 0;
+
+ final int first = srcBuf.position();
+ final int last = first + byteSize - 1;
- int pos = offset;
- while (pos < offset + byteSize - 1) {
- byte b = data[pos];
+ // read all bytes except the last
+ while (srcBuf.position() != last) {
+ byte b = srcBuf.get();
+ // byte b may be signed, if so interpret it as unsigned byte;
store it in an int
int s = b >= 0 ? b : (256 + b);
val |= s;
val <<= 8;
-
- pos += 1;
}
- byte b = data[pos];
+ // read the last byte, we don't have to shift val after that
+ byte b = srcBuf.get();
int s = b >= 0 ? b : (256 + b);
val |= s;
if (isSigned) {
// explicitly OR sign bit to the right place if the source buffer
is
// too large
- long sign = (data[offset] & 0x80);
+ long sign = (srcBuf.get(first) & 0x80);
val |= (sign << 7);
}
+
return val;
}
- public BigInteger readBigInteger(byte[] data, int offset) {
- // todo: implement
- return null;
+ public BigInteger readBigInteger(final ByteBuffer srcBuf) {
+ throw new UnsupportedOperationException("not yet implemented");
}
}
Modified: gnunet-java/src/org/gnunet/construct/parsers/NestedParser.java
===================================================================
--- gnunet-java/src/org/gnunet/construct/parsers/NestedParser.java
2012-03-17 16:31:42 UTC (rev 20587)
+++ gnunet-java/src/org/gnunet/construct/parsers/NestedParser.java
2012-03-18 13:42:47 UTC (rev 20588)
@@ -1,21 +1,24 @@
package org.gnunet.construct.parsers;
-import org.gnunet.construct.Construct;
import org.gnunet.construct.Message;
+import org.gnunet.construct.ReflectUtil;
import org.gnunet.exceptions.MessageFormatException;
import java.lang.reflect.Field;
+import java.nio.ByteBuffer;
import java.util.List;
-public class NestedParser extends FieldParser {
+public class NestedParser implements Parser {
+ private final Field targetField;
+
private final Parser nestedParser;
private List<Field> frameSizePath;
boolean optional;
public NestedParser(final Parser p, List<Field> frameSizePath, boolean
optional, final Field f) {
- super(f);
+ targetField = f;
this.optional = optional;
this.nestedParser = p;
this.frameSizePath = frameSizePath;
@@ -23,49 +26,42 @@
@Override
public int getSize(final Message src) {
- Message inner = (Message) getFieldValue(src);
+ Message inner = (Message) ReflectUtil.justGet(src, targetField);
return nestedParser.getSize(inner);
}
private int getSizeFieldValue(Message m) {
- Object obj = Construct.ReflectionUtil.followFieldPath(frameSizePath,
m);
+ Object obj = ReflectUtil.followFieldPath(frameSizePath, m);
return ((Number) obj).intValue();
}
@Override
- public int parse(final byte[] src_data, final int offset,
- int frameOffset, Message frameObj, final Message dstObj) {
+ public int parse(final ByteBuffer srcBuf, int frameOffset, Message
frameObj, final Message dstObj) {
if (optional) {
- int remaining = (frameOffset + getSizeFieldValue(frameObj)) -
offset;
- if (remaining <= 0) {
+ int remaining = frameOffset + getSizeFieldValue(frameObj) -
srcBuf.position();
+ if (remaining < 0) {
+ throw new MessageFormatException("remaining size negative");
+ }
+ if (remaining == 0) {
if (!optional) {
throw new MessageFormatException("not optional");
}
- setFieldValue(dstObj, null);
+ ReflectUtil.justSet(dstObj, targetField, null);
return 0;
}
}
+ ReflectUtil.justSet(dstObj, targetField,
ReflectUtil.justInstantiate(targetField.getType()));
- try {
- setFieldValue(dstObj, getFieldType().newInstance());
- } catch (InstantiationException e) {
- throw new RuntimeException();
- } catch (IllegalAccessException e) {
- throw new RuntimeException();
- }
-
-
- return nestedParser.parse(src_data, offset, frameOffset,
- frameObj, (Message) getFieldValue(dstObj));
+ return nestedParser.parse(srcBuf, frameOffset,
+ frameObj, (Message) ReflectUtil.justGet(dstObj, targetField));
}
@Override
- public int write(final byte[] dst_data, final int offset, final Message
src) {
- return nestedParser.write(dst_data, offset,
- (Message) getFieldValue(src));
+ public int write(final ByteBuffer dstBuf, final Message src) {
+ return nestedParser.write(dstBuf, (Message) ReflectUtil.justGet(src,
targetField));
}
@Override
Modified: gnunet-java/src/org/gnunet/construct/parsers/Parser.java
===================================================================
--- gnunet-java/src/org/gnunet/construct/parsers/Parser.java 2012-03-17
16:31:42 UTC (rev 20587)
+++ gnunet-java/src/org/gnunet/construct/parsers/Parser.java 2012-03-18
13:42:47 UTC (rev 20588)
@@ -2,26 +2,28 @@
import org.gnunet.construct.Message;
+import java.nio.ByteBuffer;
+
public interface Parser {
/**
* Compute the exact size of the object's binary representation in bytes.
*
- * @param srcObj
- * @return
+ * @param srcObj a message object with all fields filled out appropriately
+ * @return the exact size of the object's binary representation in bytes
*/
public int getSize(Message srcObj);
/**
*
*
- * @param srcData
- * @param offset
- * @param frameStart start of the current frame, relative to the beginning
of srcData
- * @param frameObj
- address@hidden dstObj @return
+ * @param srcBuf the buffer containing the binary data to construct this
object
+ * @param frameStart start of the current frame, relative to the beginning
of srcBuf
+ * @param frameObj the object containing the dstObj, dstObj if dstObj
itself is the frame object
+ * @param dstObj the object whose members are written according according
to the data in srcBuf
+ * @return number of byres read from srcBuf
*/
- public int parse(byte[] srcData, int offset, int frameStart, Message
frameObj, Message dstObj);
+ public int parse(ByteBuffer srcBuf, int frameStart, Message frameObj,
Message dstObj);
/**
*
@@ -30,8 +32,16 @@
* @param srcObj
* @return
*/
- public int write(byte[] dstData, int offset, Message srcObj);
+ public int write(ByteBuffer dstBuf, Message srcObj);
+ /**
+ * Parser-dependent method; sets members of the Message m (or Messages
nested in m) which are
+ * values inferable by the parser.
+ * Examples: Union tags, size fields.
+ *
+ * @param m the message object to patch
+ * @param frameSize the size of the containing message
+ */
public void patch(Message m, int frameSize);
}
Modified: gnunet-java/src/org/gnunet/construct/parsers/SequenceParser.java
===================================================================
--- gnunet-java/src/org/gnunet/construct/parsers/SequenceParser.java
2012-03-17 16:31:42 UTC (rev 20587)
+++ gnunet-java/src/org/gnunet/construct/parsers/SequenceParser.java
2012-03-18 13:42:47 UTC (rev 20588)
@@ -2,6 +2,7 @@
import org.gnunet.construct.Message;
+import java.nio.ByteBuffer;
import java.util.LinkedList;
import java.util.List;
@@ -12,46 +13,46 @@
*/
public class SequenceParser implements Parser {
- private final List<FieldParser> childParsers = new
LinkedList<FieldParser>();
+ private final List<Parser> childParsers = new LinkedList<Parser>();
public SequenceParser() {
}
- public void add(final FieldParser p) {
+ public void add(final Parser p) {
childParsers.add(p);
}
@Override
public int getSize(final Message src) {
int size = 0;
- for (final FieldParser p : childParsers) {
+ for (final Parser p : childParsers) {
size += p.getSize(src);
}
return size;
}
@Override
- public int parse(final byte[] src_data, final int offset, int frameOffset,
+ public int parse(final ByteBuffer srcBuf, int frameOffset,
Message frameObj, final Message dst) {
int size = 0;
- for (final FieldParser p : childParsers) {
- size += p.parse(src_data, offset + size, frameOffset, frameObj,
dst);
+ for (final Parser p : childParsers) {
+ size += p.parse(srcBuf, frameOffset, frameObj, dst);
}
return size;
}
@Override
- public int write(final byte[] dst_data, final int offset, final Message
src) {
+ public int write(final ByteBuffer dstBuf, final Message src) {
int size = 0;
- for (final FieldParser p : childParsers) {
- size += p.write(dst_data, offset + size, src);
+ for (final Parser p : childParsers) {
+ size += p.write(dstBuf, src);
}
return size;
}
@Override
public void patch(Message m, int frameSize) {
- for (final FieldParser p : childParsers) {
+ for (final Parser p : childParsers) {
p.patch(m, frameSize);
}
}
Modified: gnunet-java/src/org/gnunet/construct/parsers/StringParser.java
===================================================================
--- gnunet-java/src/org/gnunet/construct/parsers/StringParser.java
2012-03-17 16:31:42 UTC (rev 20587)
+++ gnunet-java/src/org/gnunet/construct/parsers/StringParser.java
2012-03-18 13:42:47 UTC (rev 20588)
@@ -1,27 +1,29 @@
package org.gnunet.construct.parsers;
import org.gnunet.construct.Message;
+import org.gnunet.construct.ReflectUtil;
import org.gnunet.exceptions.InterfaceViolationException;
import org.gnunet.exceptions.MessageFormatException;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Field;
+import java.nio.ByteBuffer;
-public class StringParser extends FieldParser {
+public class StringParser implements Parser {
- String cset;
+ private final String cset;
+ private final boolean optional;
+ private final Field targetField;
- boolean optional;
-
public StringParser(final String charset, boolean optional, final Field f)
{
- super(f);
+ this.targetField = f;
this.optional = optional;
this.cset = charset;
}
@Override
public int getSize(final Message srcObj) {
- final String s = (String) getFieldValue(srcObj);
+ final String s = (String) ReflectUtil.justGet(srcObj, targetField);
if (s == null) {
if (optional) {
return 0;
@@ -38,24 +40,30 @@
}
@Override
- public int parse(final byte[] srcData, final int offset, int frameOffset,
Message frameObj, final Message dstObj) {
+ public int parse(final ByteBuffer srcBuf, int frameOffset, Message
frameObj, final Message dstObj) {
- if (srcData[offset] == 0) {
+ if (srcBuf.get(srcBuf.position()) == 0) {
if (!optional) {
throw new MessageFormatException("no data received for
non-optional string");
}
- setFieldValue(dstObj, null);
- return 0;
+ ReflectUtil.justSet(dstObj, targetField, null);
+ return 1;
}
int length = 0;
- while (srcData[offset + length] != 0) {
+
+
+ while (srcBuf.get(srcBuf.position() + length) != 0) {
length++;
}
final byte[] stringData = new byte[length];
+
+ srcBuf.get(stringData);
- System.arraycopy(srcData, offset, stringData, 0, length);
+ if (srcBuf.get() != 0) {
+ throw new AssertionError("programming error");
+ }
String str;
try {
@@ -64,14 +72,14 @@
throw new RuntimeException();
}
- setFieldValue(dstObj, str);
+ ReflectUtil.justSet(dstObj, targetField, str);
return length + 1;
}
@Override
- public int write(final byte[] dstData, final int offset, final Message
srcObj) {
- String s = (String) getFieldValue(srcObj);
+ public int write(final ByteBuffer dstBuf, final Message srcObj) {
+ String s = (String) ReflectUtil.justGet(srcObj, targetField);
if (s == null) {
if (!optional) {
@@ -87,10 +95,9 @@
throw new RuntimeException();
}
- System.arraycopy(b, 0, dstData, offset, b.length);
+ dstBuf.put(b);
+ dstBuf.put((byte) 0);
- dstData[offset + b.length] = 0;
-
// +1 for the 0-byte
return b.length + 1;
}
Modified: gnunet-java/src/org/gnunet/construct/parsers/UnionParser.java
===================================================================
--- gnunet-java/src/org/gnunet/construct/parsers/UnionParser.java
2012-03-17 16:31:42 UTC (rev 20587)
+++ gnunet-java/src/org/gnunet/construct/parsers/UnionParser.java
2012-03-18 13:42:47 UTC (rev 20588)
@@ -3,86 +3,85 @@
import org.gnunet.construct.Construct;
import org.gnunet.construct.Message;
import org.gnunet.construct.MessageLoader;
+import org.gnunet.construct.ReflectUtil;
import org.gnunet.exceptions.MessageFormatException;
import java.lang.reflect.Field;
+import java.nio.ByteBuffer;
import java.util.List;
-public class UnionParser extends FieldParser {
- private List<Field> frameSizePath;
+public class UnionParser implements Parser {
+ private final List<Field> frameSizePath;
- private Field unionTag;
- private String unionType;
+ private final Field targetField;
+ private final List<Field> unionTagPath;
+ private final ReflectUtil.NumField unionTagField;
+ private final String unionType;
+
boolean optional;
- public UnionParser(List<Field> frameSizePath, boolean optional, String
unionType, Field unionTag, Field f) {
- super(f);
+ public UnionParser(List<Field> frameSizePath, boolean optional, String
unionType, List<Field> unionTagPath, Field f) {
+ targetField = f;
this.optional = optional;
this.frameSizePath = frameSizePath;
- this.unionTag = unionTag;
+ this.unionTagPath = unionTagPath;
+ this.unionTagField = new
ReflectUtil.NumField(unionTagPath.get(unionTagPath.size() - 1));
this.unionType = unionType;
}
@Override
public int getSize(final Message src) {
- return Construct.getSize((Message) getFieldValue(src));
+ return Construct.getSize((Message) ReflectUtil.justGet(src,
targetField));
}
private int getSizeFieldValue(Message m) {
- Object obj = Construct.ReflectionUtil.followFieldPath(frameSizePath,
m);
+ Object obj = ReflectUtil.followFieldPath(frameSizePath, m);
return ((Number) obj).intValue();
}
@Override
- public int parse(final byte[] src_data, final int offset,
- int frameOffset, Message frameObj, final Message dstObj) {
+ public int parse(final ByteBuffer srcBuf, int frameOffset, Message
frameObj, final Message dstObj) {
if (optional) {
- int remaining = (frameOffset + getSizeFieldValue(frameObj)) -
offset;
+ int remaining = frameOffset + getSizeFieldValue(frameObj) -
srcBuf.position();
if (remaining <= 0) {
if (!optional) {
throw new MessageFormatException("not optional");
}
- setFieldValue(dstObj, null);
+ ReflectUtil.justSet(dstObj, targetField, null);
return 0;
}
}
- Class cls = null;
- try {
- cls = MessageLoader.loadUnionClass(unionType, ((Number)
unionTag.get(dstObj)).intValue());
- } catch (IllegalAccessException e) {
- throw new RuntimeException();
- }
- try {
- setFieldValue(dstObj, cls.newInstance());
- } catch (InstantiationException e) {
- throw new RuntimeException(e);
- //throw new InterfaceViolationException("cannot instantiate class
" + cls);
- } catch (IllegalAccessException e) {
+ final Class cls;
+ long unionTag =
unionTagField.get(ReflectUtil.followFieldPathToParent(unionTagPath, dstObj));
- }
+ cls = MessageLoader.loadUnionClass(unionType, (int) unionTag);
+ ReflectUtil.justSet(dstObj, targetField,
ReflectUtil.justInstantiate(cls));
- return Construct.getParser((Class<? extends Message>)
getFieldValue(dstObj).getClass())
- .parse(src_data, offset, frameOffset, frameObj, (Message)
getFieldValue(dstObj));
+ final Message theUnion = (Message) ReflectUtil.justGet(dstObj,
targetField);
+
+ return Construct.getParser(cls).parse(srcBuf, frameOffset, frameObj,
theUnion);
}
@Override
- public int write(final byte[] dst_data, final int offset, final Message
src) {
- return Construct.getParser((Class<? extends Message>)
getFieldValue(src).getClass())
- .write(dst_data, offset, (Message) getFieldValue(src));
+ public int write(final ByteBuffer dstBuf, final Message src) {
+ final Class currentUnionClass = ReflectUtil.justGet(src,
targetField).getClass();
+ final Parser p = Construct.getParser(currentUnionClass);
+
+ return p.write(dstBuf, (Message) ReflectUtil.justGet(src,
targetField));
}
@Override
public void patch(Message m, int frameSize) {
// todo: nested/opaque frames
- Parser p = Construct.getParser((Class<? extends Message>)
getFieldValue(m).getClass());
+ final Class currentUnionClass = ReflectUtil.justGet(m,
targetField).getClass();
+ final Parser p = Construct.getParser(currentUnionClass);
- p.patch((Message) getFieldValue(m), frameSize);
+ p.patch((Message) ReflectUtil.justGet(m, targetField), frameSize);
}
-
}
Modified:
gnunet-java/src/org/gnunet/construct/parsers/VariableSizeArrayParser.java
===================================================================
--- gnunet-java/src/org/gnunet/construct/parsers/VariableSizeArrayParser.java
2012-03-17 16:31:42 UTC (rev 20587)
+++ gnunet-java/src/org/gnunet/construct/parsers/VariableSizeArrayParser.java
2012-03-18 13:42:47 UTC (rev 20588)
@@ -1,33 +1,33 @@
package org.gnunet.construct.parsers;
-import org.gnunet.construct.Construct.ReflectionUtil;
import org.gnunet.construct.Message;
+import org.gnunet.construct.ReflectUtil;
import java.lang.reflect.Array;
import java.lang.reflect.Field;
+import java.nio.ByteBuffer;
-public class VariableSizeArrayParser extends FieldParser {
- private final FieldParser elemParser;
- private Field sizeField;
- private ReflectionUtil.NumFieldType ft;
+public class VariableSizeArrayParser implements Parser {
+ private final Field targetField;
+ private final Parser elemParser;
+ private ReflectUtil.NumField sizeField;
- public VariableSizeArrayParser(final FieldParser elemParser, Field
sizeField, Field arrayField) {
- super(arrayField);
+ public VariableSizeArrayParser(final Parser elemParser, Field sizeField,
Field arrayField) {
+ targetField = arrayField;
this.elemParser = elemParser;
- this.sizeField = sizeField;
- this.ft = ReflectionUtil.getNumFieldType(sizeField);
+ this.sizeField = new ReflectUtil.NumField(sizeField);
}
@Override
public int getSize(final Message src) {
int size = 0;
- final Object arr = getFieldValue(src);
-
+ final Object arr = ReflectUtil.justGet(src, targetField);
+
if (arr == null) {
throw new RuntimeException("array not initialized");
}
-
+
for (int i = 0; i < Array.getLength(arr); ++i) {
size += elemParser.getSize((Message) Array.get(arr, i));
}
@@ -35,57 +35,43 @@
}
@Override
- public int parse(final byte[] srcData, final int offset, int frameOffset,
Message frameObj, final Message dstObj) {
- int elemNumber;
- try {
- elemNumber = ((Number) sizeField.get(dstObj)).intValue();
- } catch (IllegalArgumentException e1) {
- throw new RuntimeException();
- } catch (IllegalAccessException e1) {
- throw new RuntimeException();
- }
-
+ public int parse(final ByteBuffer srcBuf, int frameOffset, Message
frameObj, final Message dstObj) {
+ final int elemNumber = (int) sizeField.get(dstObj);
+ final Class arrayElementType =
targetField.getType().getComponentType();
+
int size = 0;
- final Object arr = Array.newInstance(getFieldType().getComponentType(),
- elemNumber);
- setFieldValue(dstObj, arr);
+ final Object arr = Array.newInstance(arrayElementType, elemNumber);
+ ReflectUtil.justSet(dstObj, targetField, arr);
for (int i = 0; i < elemNumber; ++i) {
Message elemObj;
- try {
- elemObj = (Message) getFieldType().getComponentType()
- .newInstance();
- } catch (final InstantiationException e) {
- throw new RuntimeException();
- } catch (final IllegalAccessException e) {
- throw new RuntimeException();
- }
-
+
+ elemObj = (Message) ReflectUtil.justInstantiate(arrayElementType);
+
+
Array.set(arr, i, elemObj);
-
- size += elemParser.parse(srcData, offset + size,
- frameOffset - size, null, elemObj);
+
+ size += elemParser.parse(srcBuf, frameOffset - size, null,
elemObj);
}
return size;
}
@Override
- public int write(final byte[] dstData, final int offset, final Message
src) {
+ public int write(final ByteBuffer dstBuf, final Message src) {
int size = 0;
- final Object arr = getFieldValue(src);
+ final Object arr = ReflectUtil.justGet(src, targetField);
for (int i = 0; i < Array.getLength(arr); ++i) {
- size += elemParser.write(dstData, offset + size,
- (Message) Array.get(arr, i));
+ size += elemParser.write(dstBuf, (Message) Array.get(arr, i));
}
return size;
}
@Override
public void patch(Message m, int frameSize) {
- int size = Array.getLength(getFieldValue(m));
- ReflectionUtil.setNumField(m, ft, sizeField, size);
+ int size = Array.getLength(ReflectUtil.justGet(m, targetField));
+ sizeField.set(m, size);
}
}
Added: gnunet-java/src/org/gnunet/dht/DistributedHashTable.java
===================================================================
--- gnunet-java/src/org/gnunet/dht/DistributedHashTable.java
(rev 0)
+++ gnunet-java/src/org/gnunet/dht/DistributedHashTable.java 2012-03-18
13:42:47 UTC (rev 20588)
@@ -0,0 +1,196 @@
+package org.gnunet.dht;
+
+import org.gnunet.construct.Message;
+import org.gnunet.construct.MessageHeader;
+import org.gnunet.construct.Nested;
+import org.gnunet.construct.UInt32;
+import org.gnunet.util.*;
+import org.gnunet.util.getopt.Option;
+import org.gnunet.util.getopt.OptionAction;
+
+import java.util.EnumSet;
+import java.util.List;
+
+public class DistributedHashTable {
+
+ enum BlockType {
+ /**
+ * Any type of block, used as a wildcard when searching. Should
+ * never be attached to a specific block.
+ */
+ ANY(0),
+ /**
+ * Data block (leaf) in the CHK tree.
+ */
+ DBLOCK(1),
+ /**
+ * Inner block in the CHK tree.
+ */
+ IBLOCK(2),
+ /**
+ * Type of a block representing a keyword search result. Note that
+ * the values for KBLOCK, SBLOCK and NBLOCK must be consecutive.
+ */
+ KBLOCK(3),
+ /**
+ * Type of a block that is used to advertise content in a namespace.
+ */
+ SBLOCK(4),
+ /**
+ * Type of a block that is used to advertise a namespace.
+ */
+ NBLOCK(5),
+ /**
+ * Type of a block representing a block to be encoded on demand from
disk.
+ * Should never appear on the network directly.
+ */
+ FS_ONDEMAND(6),
+ /**
+ * Type of a block that contains a HELLO for a peer (for
+ * DHT find-peer operations).
+ */
+ DHT_HELLO(7),
+ /**
+ * Block for testing.
+ */
+ TEST(8),
+ /**
+ * Block for storing .gnunet-domains
+ */
+ DNS(10),
+ /**
+ * Block for storing record data
+ */
+ NAMERECORD(11);
+
+ private final int val;
+ BlockType(int i) {
+ val = i;
+ }
+ }
+
+ enum RouteOption {
+ /**
+ * Default. Do nothing special.
+ */
+ NONE(0),
+
+ /**
+ * Each peer along the way should look at 'enc' (otherwise
+ * only the k-peers closest to the key should look at it).
+ */
+ DEMULTIPLEX_EVERYWHERE(1),
+
+ /**
+ * We should keep track of the route that the message
+ * took in the P2P network.
+ */
+ RECORD_ROUTE(2),
+
+ /**
+ * This is a 'FIND-PEER' request, so approximate results are fine.
+ */
+ FIND_PEER(4),
+
+ /**
+ * Possible message option for query key randomization.
+ */
+ RO_BART(8);
+
+ private final int val;
+ RouteOption(int i) {
+ val = i;
+ }
+ }
+
+
+ public static class DHTClientGetMessage implements Message {
+ @Nested
+ public MessageHeader header;
+
+ @UInt32
+ public int options;
+
+ }
+
+
+ private Client client;
+
+ public DistributedHashTable(Configuration cfg) {
+ client = new Client("dht", cfg);
+ }
+
+ public interface Continuation {
+ public void done();
+ }
+
+ public interface ResultCallback {
+ public void handleResult(AbsoluteTime expiration, GnunetHash key,
+ List<PeerIdentity> getPath, List<PeerIdentity>
putPath,
+ BlockType type, byte[] data);
+ }
+
+
+
+
+ public void put(GnunetHash key, int replicationLevel, EnumSet<RouteOption>
routeOptions,
+ BlockType type, byte[] data, AbsoluteTime expiration,
+ RelativeTime timeout, Continuation cont) {
+
+ }
+
+ public Cancelable startGet(RelativeTime timeout, BlockType type,
GnunetHash key,
+ int replicatoin, EnumSet<RouteOption>
routeOptions,
+ byte[] xquery, ResultCallback cb) {
+ return null;
+ }
+
+
+
+ public static void main(String[] args) {
+ new Program(args) {
+ @Option(action = OptionAction.SET,
+ shortname = "p",
+ longname = "put",
+ description = "set a value in the DHT; default is get")
+ boolean modePut = false;
+
+ @Option(action = OptionAction.STORE_STRING,
+ shortname = "d",
+ longname = "data",
+ description = "data (only used with --put)")
+ String data=null;
+
+ @Option(action = OptionAction.STORE_STRING,
+ shortname = "k",
+ longname = "key",
+ description = "key used for the operation")
+ String key=null;
+
+ @Option(action = OptionAction.STORE_STRING,
+ shortname = "t",
+ longname = "type",
+ description = "type of data used in this operation")
+ String type=null;
+
+ @Option(action = OptionAction.STORE_STRING,
+ shortname = "e",
+ longname = "expire",
+ description = "expiration")
+ String expiration=null;
+
+
+ @Option(action = OptionAction.STORE_STRING,
+ shortname = "r",
+ longname = "replication",
+ description = "desired replication (only used with --put)")
+ String replication=null;
+
+
+
+ public void run() {
+
+ }
+ }.start();
+ }
+}
Modified: gnunet-java/src/org/gnunet/nse/NetworkSizeEstimation.java
===================================================================
--- gnunet-java/src/org/gnunet/nse/NetworkSizeEstimation.java 2012-03-17
16:31:42 UTC (rev 20587)
+++ gnunet-java/src/org/gnunet/nse/NetworkSizeEstimation.java 2012-03-18
13:42:47 UTC (rev 20588)
@@ -1,10 +1,12 @@
package org.gnunet.nse;
+import org.gnunet.construct.Double;
import org.gnunet.construct.*;
-import org.gnunet.construct.Double;
import org.gnunet.exceptions.MessageFormatException;
import org.gnunet.util.*;
+import org.gnunet.util.getopt.Option;
+import org.gnunet.util.getopt.OptionAction;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -27,6 +29,7 @@
private Client client;
+
@SuppressWarnings("InstanceVariableMayNotBeInitialized")
@MessageId(NSE_StartMessage.MSG_ID)
public static class NSE_StartMessage implements Message {
@@ -55,7 +58,6 @@
@Double
public double stdDeviation;
-
}
@@ -77,9 +79,14 @@
}
@Override
- public void handleTimeout() {
- // can't happen
- throw new RuntimeException("unreachable");
+ public void handleError(Client.ReceiveError e) {
+ if (e.equals(Client.ReceiveError.DISCONNECT)) {
+ logger.warn("NSE service disconnected us - trying to
reconnect");
+ } else {
+ throw new RuntimeException("unexpected receive error");
+ }
+ client.reconnect();
+ requestUpdate();
}
}
@@ -97,9 +104,8 @@
}
@Override
- public void handleTimeout() {
- // can't happen
- throw new AssertionError("unreachable");
+ public void handleError(Client.TransmitError error) {
+ throw new RuntimeException("unexpected transmitt error");
}
}
@@ -127,8 +133,6 @@
* A NSE_Subscriber receives updates from the service.
*/
public interface NSE_Subscriber {
-
-
public void update(AbsoluteTime timestamp, double estimate, double
deviation);
}
@@ -141,6 +145,7 @@
*/
public NSE_Subscription subscribe(NSE_Subscriber s) {
subscribers.add(s);
+ requestUpdate();
return new NSE_Subscription(s);
}
@@ -153,6 +158,9 @@
public NetworkSizeEstimation(Configuration cfg) {
client = new Client("nse", cfg);
logger.debug("lifeness in NSE ctor: {}",
Scheduler.getCurrentLifeness());
+ }
+
+ private void requestUpdate() {
client.notifyTransmitReady(RelativeTime.FOREVER, true, new
NSE_Transmitter());
}
@@ -161,19 +169,27 @@
*/
public void disconnect() {
disconnected = true;
- client.disconnect();
+ client.disconnect(false);
}
public static void main(String[] args) {
new Program(args) {
+ @Option(action = OptionAction.SET,
+ shortname = "w",
+ longname = "continuous",
+ description = "don't exit after the first estimation
response")
+ boolean cont = false;
+
public void run() {
final NetworkSizeEstimation svc = new
NetworkSizeEstimation(cfg);
NSE_Subscriber subscriber = new NSE_Subscriber() {
@Override
public void update(AbsoluteTime timestamp, double
estimate, double deviation) {
- System.out.println("est:" + estimate + " dev: " +
deviation + " t: ");
- svc.disconnect();
+ System.out.println("est:" + estimate + " dev: " +
deviation + " t: " + timestamp);
+ if (!cont) {
+ svc.disconnect();
+ }
}
};
@@ -181,8 +197,6 @@
}
}.start();
-
-
}
}
Modified: gnunet-java/src/org/gnunet/statistics/Statistics.java
===================================================================
--- gnunet-java/src/org/gnunet/statistics/Statistics.java 2012-03-17
16:31:42 UTC (rev 20587)
+++ gnunet-java/src/org/gnunet/statistics/Statistics.java 2012-03-18
13:42:47 UTC (rev 20588)
@@ -88,6 +88,10 @@
client.notifyTransmitReady(deadline.getRemaining(), true, new
MessageTransmitter() {
@Override
public void transmit(Client.MessageSink sink) {
+ if (sink == null) {
+ logger.error("unable to connect to statistics service");
+ return;
+ }
RequestMessage rm = new RequestMessage();
rm.header = new MessageHeader();
rm.statisticsName = name;
@@ -114,17 +118,21 @@
}
@Override
- public void handleTimeout() {
+ public void handleError(Client.ReceiveError e) {
logger.error("unable to read from statistics service");
}
- });
+
+ }
+ );
}
@Override
- public void handleTimeout() {
- logger.error("unable to connect to statistics service");
+ public void handleError(Client.TransmitError error) {
+ throw new RuntimeException("unexpected transmit error");
}
- });
+ }
+
+ );
return null;
}
@@ -136,6 +144,7 @@
public void onCompleted();
public void onTimeout();
+
}
@@ -145,6 +154,9 @@
@Override
public void transmit(Client.MessageSink sink) {
+ if (sink == null) {
+ cb.onTimeout();
+ }
SetMessage sm = new SetMessage();
sm.statisticName = name;
sm.subsystemName = subsystem;
@@ -159,8 +171,8 @@
}
@Override
- public void handleTimeout() {
- cb.onTimeout();
+ public void handleError(Client.TransmitError error) {
+ throw new RuntimeException("unexpected transmit error");
}
});
return new Cancelable() {
Modified: gnunet-java/src/org/gnunet/util/Client.java
===================================================================
--- gnunet-java/src/org/gnunet/util/Client.java 2012-03-17 16:31:42 UTC (rev
20587)
+++ gnunet-java/src/org/gnunet/util/Client.java 2012-03-18 13:42:47 UTC (rev
20588)
@@ -36,7 +36,6 @@
import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel;
import java.nio.channels.spi.SelectorProvider;
-import java.util.Arrays;
import java.util.LinkedList;
/**
@@ -46,26 +45,87 @@
private static final Logger logger = LoggerFactory
.getLogger(Client.class);
- private static final int INITIAL_BUFFER_SIZE = 128;
-
+ /**
+ * The underlying socket the client is using to talk with the service.
+ */
private SocketChannel chan = null;
- private LinkedList<InetAddress> addressList = new
LinkedList<InetAddress>();
- private RelativeTime connectBackoff = new RelativeTime(5);
-
+ /**
+ * The host and port this client should be connected to, according to the
configuration.
+ */
private String connectionHost;
private int connectionPort;
+
+ /**
+ * The list of possible IP addresses the service can be reached by.
+ */
+ private LinkedList<InetAddress> addressList = new
LinkedList<InetAddress>();
+ /**
+ * True if we are requesting or receiving IP addresses from the resolver
+ */
+ private boolean resolveActive = false;
+
+ /**
+ * The task that is currently used by the resolve mechanism.
+ */
+ private Cancelable resolveHandle = null;
+ private Cancelable connectHandle = null;
+
+
+ /**
+ * Initial value for connectBackoff.
+ * @see Client.connectBackoff
+ */
+ private final RelativeTime INITAL_BACKOFF = new RelativeTime(5);
+
+ /**
+ * Maximum value for connectBackoff.
+ * @see Client.connectBackoff
+ */
+ private final RelativeTime MAX_BACKOFF = RelativeTime.SECOND.multiply(5);
+
+
+ /**
+ * The time to wait after an error occured while connecting.
+ * Every time an error occurs while connecting, this value is doubled
until its maximum
+ * value (MAX_BACKOFF) has been reached. This strategy is called
exponential backoff.
+ */
+ private RelativeTime connectBackoff = INITAL_BACKOFF;
+
+ /**
+ * The ReceiveHelper responsible for receiving a whole message from the
service
+ * and calling the respective MessageReceiver.
+ */
private ReceiveHelper currentReceiveHelper = null;
- private ByteBuffer recvBuffer = ByteBuffer.allocate(INITIAL_BUFFER_SIZE);
+ /**
+ * The buffer with the (partial) message received from the service.
+ * Initially, this buffer has the size of the smallest possible messages,
but grows when
+ * receiving larger messages.
+ */
+ private ByteBuffer recvBuffer = ByteBuffer.allocate(MessageHeader.SIZE);
+
+
+ /**
+ * The handle for the current transmission. The current transmission either
+ * writes data to the channel or waits for the channel to connect
+ */
private TransmitHelper currentTransmitHelper = null;
+ /**
+ * The handle for the next transmission. The next transmission will become
the current
+ * transmission once the current transmission has completed.
+ * While nextTransmitHelper is not null, no new transmit requests may be
scheduled.
+ */
private TransmitHelper nextTransmitHelper = null;
- private Scheduler.TaskIdentifier nextTransmitTimeout = null;
- private Scheduler.TaskIdentifier currentTransmitTimeout = null;
- private ByteBuffer transmitBuffer =
ByteBuffer.allocate(INITIAL_BUFFER_SIZE);
- private boolean resolveActive;
+ /**
+ * The transmitters passed to transmitReadyNotify(...) write to this
buffer by calling
+ * methods on the MessageSink passed to the
Transmitter.transmit(MessageSink s) method.
+ * Initially, this buffer has the size of the smallest possible messages,
but grows when
+ * transmitting larger messages.
+ */
+ private ByteBuffer transmitBuffer =
ByteBuffer.allocate(MessageHeader.SIZE);
/**
@@ -73,24 +133,32 @@
*/
public interface TransmitHandle {
/**
- * Cancel a request for notification.
+ * Cancel a request for the transmit ready notification.
+ * This does *not* cancel a transmission that already has been started.
*/
public void cancel();
}
+ /**
+ * An interface that allows the Transmitter.transmit method to deliver
their messages
+ * to the client, which sends them to the service.
+ */
public interface MessageSink {
- public int getRemaining();
-
public void send(Message m);
}
+
+ /**
+ * A ReceiveHelper is responsible for receiving a whole
+ * gnunet message and call the respective MessageReceiver with the message
on success,
+ * and null on failure or timeout.
+ */
private class ReceiveHelper implements Task {
-
private MessageReceiver receiver;
private RelativeTime timeout;
- private boolean headerProcessed = false;
private MessageHeader msgh = null;
private Scheduler.TaskIdentifier recvTask = null;
+ private boolean finished = false;
public ReceiveHelper(MessageReceiver receiver, RelativeTime timeout) {
this.receiver = receiver;
@@ -99,43 +167,58 @@
public void dispatchMessage() {
assert msgh != null;
+ currentReceiveHelper = null;
+ finished = true;
logger.debug("dispatching message with " + recvBuffer.position() +
" bytes");
-
- // XXX: this is extremely slow, only preliminary for testing
- byte[] buf = Arrays.copyOf(recvBuffer.array(),
recvBuffer.position());
- receiver.process(MessageLoader.loadMessage(msgh.messageType, buf,
0));
+ recvBuffer.flip();
+ receiver.process(MessageLoader.loadMessage(msgh.messageType,
recvBuffer));
}
@Override
public void run(Scheduler.RunContext ctx) {
logger.debug("receiving in helper");
+ recvTask = null;
if (ctx.reasons.contains(Scheduler.Reason.TIMEOUT)) {
currentReceiveHelper = null;
- receiver.handleTimeout();
+ receiver.handleError(ReceiveError.TIMEOUT);
} else if (ctx.reasons.contains(Scheduler.Reason.READ_READY)) {
try {
int n = chan.read(recvBuffer);
if (n == -1) {
logger.error("end of stream in channel before complete
message, read {} bytes",
recvBuffer.position());
+ chan.close();
+ chan = null;
+ receiver.handleError(ReceiveError.DISCONNECT);
+ if (currentTransmitHelper != null
+ && currentTransmitHelper.autoRetry &&
!currentTransmitHelper.notifyDone()) {
+ logger.debug("reconnecting due to transmitter
autoRetry");
+ reconnect();
+ }
return;
}
logger.debug(String.format("chan read %s bytes", n));
} catch (IOException e) {
- throw new RuntimeException("read failed");
+ logger.error("read failed with exception:", e);
+ receiver.handleError(ReceiveError.MSG_FORMAT);
+ return;
}
if (recvBuffer.remaining() == 0) {
- if (headerProcessed) {
- currentReceiveHelper = null;
+ if (msgh != null) {
dispatchMessage();
} else {
- msgh = Construct.parseAs(recvBuffer.array(), 0,
MessageHeader.class);
- headerProcessed = true;
+ recvBuffer.rewind();
+ msgh = Construct.parseAs(recvBuffer,
MessageHeader.class);
if (msgh.messageSize > MessageHeader.SIZE) {
+ if (recvBuffer.capacity() < msgh.messageSize) {
+ ByteBuffer buf =
ByteBuffer.allocate(msgh.messageSize);
+ recvBuffer.flip();
+ buf.put(recvBuffer);
+ recvBuffer = buf;
+ }
recvBuffer.limit(msgh.messageSize);
schedule();
} else {
- currentReceiveHelper = null;
dispatchMessage();
}
}
@@ -150,31 +233,55 @@
private void schedule() {
recvTask = Scheduler.addRead(timeout, chan, this);
- logger.debug("receive task has lifeness {}",
recvTask.getLifeness());
}
public void cancel() {
+ if (finished) {
+ throw new InterfaceViolationException("canceling finished
receive");
+ }
if (recvTask != null) {
recvTask.cancel();
}
}
}
+
private class TransmitHelper implements Task, MessageSink {
- private MessageTransmitter transmitter;
+ private final MessageTransmitter transmitter;
+ private final boolean autoRetry;
+
+ private Scheduler.TaskIdentifier notifyTimeoutTask;
+
private Scheduler.TaskIdentifier transmitTask = null;
- private boolean desiredLifeness;
+ public TransmitHelper(final MessageTransmitter transmitter,
RelativeTime notifyTimeout, boolean autoRetry) {
+ this.transmitter = transmitter;
+ this.autoRetry = autoRetry;
- public TransmitHelper(MessageTransmitter transmitter, boolean
desiredLifeness) {
- this.transmitter = transmitter;
- this.desiredLifeness = desiredLifeness;
+ Scheduler.TaskBuilder b = new Scheduler.TaskBuilder();
+ b.withTask(new Task() {
+ @Override
+ public void run(Scheduler.RunContext ctx) {
+ transmitter.handleError(TransmitError.TIMEOUT);
+ }
+ });
+ b.withTimeout(notifyTimeout);
+ notifyTimeoutTask = Scheduler.add(b);
}
+ public boolean notifyDone() {
+ return notifyTimeoutTask == null;
+ }
+
public void cancel() {
if (transmitTask != null) {
transmitTask.cancel();
+ transmitTask = null;
}
+ if (notifyTimeoutTask != null) {
+ notifyTimeoutTask.cancel();
+ notifyTimeoutTask = null;
+ }
}
@Override
@@ -189,14 +296,7 @@
logger.debug("sent " + transmitBuffer.position() + "bytes
complete message");
if (nextTransmitHelper == null) {
currentTransmitHelper = null;
- if (currentTransmitTimeout != null) {
- throw new AssertionError("error in timeout logic");
- }
} else {
- if (currentTransmitTimeout != null) {
- throw new AssertionError("error in timeout logic");
- }
- nextTransmitTimeout.cancel();
currentTransmitHelper = nextTransmitHelper;
nextTransmitHelper.start();
nextTransmitHelper = null;
@@ -206,19 +306,16 @@
}
}
+ /**
+ * called to notify when we are ready to put new messages in the
transmit buffer
+ */
public void start() {
- Scheduler.TaskBuilder b = new Scheduler.TaskBuilder();
- b.withTask(new Task() {
- @Override
- public void run(Scheduler.RunContext ctx) {
- transmitBuffer.clear();
- transmitter.transmit(TransmitHelper.this);
- transmitBuffer.flip();
- schedule();
- }
- });
- b.withLifeness(desiredLifeness);
- Scheduler.add(b);
+ notifyTimeoutTask.cancel();
+ notifyTimeoutTask = null;
+ transmitBuffer.clear();
+ transmitter.transmit(TransmitHelper.this);
+ transmitBuffer.flip();
+ schedule();
}
@@ -227,19 +324,20 @@
// of a message, only the max. wait time before transmission.
// cancel must be called on the transmitTask if we disconnect
Scheduler.TaskBuilder b = new Scheduler.TaskBuilder();
-
b.withTimeout(RelativeTime.FOREVER).withSelectWrite(chan).withTask(this).withLifeness(desiredLifeness);
- Scheduler.add(b);
+
b.withTimeout(RelativeTime.FOREVER).withSelectWrite(chan).withTask(this);
+ this.transmitTask = Scheduler.add(b);
}
@Override
- public int getRemaining() {
- throw new UnsupportedOperationException("not yet implemented");
- }
-
- @Override
public void send(Message m) {
byte[] b = Construct.toBinary(m);
logger.debug("sending msg size=" + b.length);
+ if (transmitBuffer.remaining() < b.length) {
+ ByteBuffer buf = ByteBuffer.allocate(b.length +
transmitBuffer.capacity());
+ transmitBuffer.flip();
+ buf.put(transmitBuffer);
+ transmitBuffer = buf;
+ }
transmitBuffer.put(b);
}
}
@@ -258,7 +356,7 @@
throw new ConfigurationException(String.format("'%s' is not a
valid port", port));
}
connectionPort = port;
- // ditto for hostname
+ // get the hostname from the configuration
connectionHost = cfg.getValueString(serviceName, "HOSTNAME");
// todo: further validity checks
if (connectionHost.isEmpty()) {
@@ -298,15 +396,7 @@
if (resolveActive) {
return;
}
- Scheduler.TaskBuilder b = new Scheduler.TaskBuilder();
- b.withTask(new Task() {
- @Override
- public void run(Scheduler.RunContext ctx) {
- Resolver.getInstance().resolveHostname(connectionHost,
RelativeTime.FOREVER, new AddressHandler());
- }
- });
- b.withLifeness(false);
- Scheduler.add(b);
+ resolveHandle = Resolver.getInstance().resolveHostname(connectionHost,
RelativeTime.FOREVER, new AddressHandler());
}
private void connectDelayed() {
@@ -315,16 +405,18 @@
@Override
public void run(Scheduler.RunContext ctx) {
logger.debug("calling connect from delayed task");
+ connectHandle = null;
connect();
}
});
b.withTimeout(connectBackoff);
- Scheduler.add(b);
+ connectHandle = Scheduler.add(b);
}
private void increaseBackoff() {
connectBackoff = RelativeTime.min(connectBackoff.multiply(2), new
RelativeTime(5000));
}
+
private void connectNextAddress() {
if (addressList.isEmpty()) {
@@ -340,6 +432,7 @@
b.withTask(new Task() {
@Override
public void run(Scheduler.RunContext ctx) {
+ connectHandle = null;
if (ctx.reasons.contains(Scheduler.Reason.SHUTDOWN)) {
return;
}
@@ -354,18 +447,16 @@
connectDelayed();
}
if (connected) {
+ //connectBackoff = INITAL_BACKOFF;
if (currentTransmitHelper != null) {
- currentTransmitTimeout.cancel();
- currentTransmitTimeout = null;
currentTransmitHelper.start();
}
}
}
});
- b.withLifeness(false);
b.withSelectConnect(chan);
b.withTimeout(RelativeTime.FOREVER);
- Scheduler.add(b);
+ connectHandle = Scheduler.add(b);
} catch (IOException e) {
logger.debug("unable to connect: {}", e);
increaseBackoff();
@@ -375,6 +466,9 @@
}
}
+ /**
+ * Open a channel for this connection in non-blocking mode
+ */
private void openChannel() {
try {
chan = SelectorProvider.provider().openSocketChannel();
@@ -390,11 +484,21 @@
connectNextAddress();
}
+ public void reconnect() {
+ if (currentReceiveHelper != null) {
+ currentReceiveHelper.cancel();
+ currentReceiveHelper = null;
+ }
+
+ if (connectHandle == null && (chan == null || !chan.isOpen() ||
!chan.isConnected())) {
+ connect();
+ }
+ }
+
public interface ReceiveHandle {
public void cancel();
}
-
/**
* Receive one message from the service.
*
@@ -424,8 +528,8 @@
}
- public Scheduler.TaskIdentifier scheduleTransmitTimeout(final
MessageTransmitter t, RelativeTime timeout,
- final boolean
forCurrent) {
+ private Scheduler.TaskIdentifier scheduleTransmitTimeout(final
MessageTransmitter t, RelativeTime timeout,
+ final boolean
forCurrent) {
Scheduler.TaskBuilder b = new Scheduler.TaskBuilder();
b.withTask(new Task() {
@Override
@@ -437,7 +541,7 @@
nextTransmitHelper.cancel();
nextTransmitHelper = null;
}
- t.handleTimeout();
+ t.transmit(null);
}
});
b.withTimeout(timeout);
@@ -449,14 +553,14 @@
* Ask the client to call us once it is able to send a message.
*
* @param size number of bytes to send
- * @param timeout after how long should we give up (and call
- * notify with buf NULL and size 0)?
+ * @param timeout after how long should we give up (and call
transmitter.transmit(null))
* @param autoRetry if the connection to the service dies, should we
- * automatically re-connectStep and retry (within the
deadline period)
- * or should we immediately fail in this case? Pass
GNUNET_YES
+ * automatically reconnect and retry (within the
deadline period)
+ * or should we immediately fail in this case? Pass
true
* if the caller does not care about temporary
connection errors,
* for example because the protocol is stateless
- * @param transmitter ...
+ * @param transmitter the MessageTransmitter object to call once the
client is ready to transmit or
+ * when the timeout is over.
* @return a handle that can be used to cancel the transmit request
*/
public TransmitHandle notifyTransmitReady(RelativeTime timeout,
@@ -466,8 +570,15 @@
"previous transmit request must have completed before
calling notifyTransmitReady again");
}
+ // negative timeout
if (timeout.getMilliseconds() <= 0) {
- transmitter.handleTimeout();
+ transmitter.handleError(TransmitError.TIMEOUT);
+ return new TransmitHandle() {
+ @Override
+ public void cancel() {
+ throw new InterfaceViolationException("cancel() called on
timed-out TransmitHandle");
+ }
+ };
}
logger.debug("notifyTransmitReady with timeout {}", timeout);
@@ -475,22 +586,17 @@
logger.debug("lifeness notifyTransmitReady {}",
Scheduler.getCurrentLifeness());
- final TransmitHelper transmit = new TransmitHelper(transmitter,
Scheduler.getCurrentLifeness());
+ final TransmitHelper transmit = new TransmitHelper(transmitter,
timeout, autoRetry);
if (currentTransmitHelper == null) {
currentTransmitHelper = transmit;
if (chan.isConnected()) {
- currentTransmitTimeout = null;
currentTransmitHelper.start();
- } else {
- currentTransmitTimeout = scheduleTransmitTimeout(transmitter,
timeout, true);
}
} else {
nextTransmitHelper = transmit;
- nextTransmitTimeout = scheduleTransmitTimeout(transmitter,
timeout, false);
}
-
return new TransmitHandle() {
@Override
public void cancel() {
@@ -505,21 +611,35 @@
* todo: introduce finishPendingWrites parameter
*/
public void disconnect() {
- if (currentTransmitHelper != null) {
- currentTransmitHelper.cancel();
+ disconnect(false);
+ }
+
+ public void disconnect(boolean finishPendingWrites) {
+ if (!finishPendingWrites || !currentTransmitHelper.notifyDone()) {
+ if (currentTransmitHelper != null) {
+ currentTransmitHelper.cancel();
+ currentReceiveHelper = null;
+ }
}
- if (currentTransmitTimeout != null) {
- currentTransmitTimeout.cancel();
- }
+
if (nextTransmitHelper != null) {
nextTransmitHelper.cancel();
+ nextTransmitHelper = null;
}
- if (nextTransmitTimeout != null) {
- nextTransmitTimeout.cancel();
- }
if (currentReceiveHelper != null) {
currentReceiveHelper.cancel();
+ currentReceiveHelper = null;
}
+
+ if (resolveHandle != null) {
+ resolveHandle.cancel();
+ resolveHandle = null;
+ }
+
+ if (connectHandle != null) {
+ connectHandle.cancel();
+ connectHandle = null;
+ }
}
@@ -529,4 +649,11 @@
disconnect();
}
+ public enum ReceiveError {
+ TIMEOUT, DISCONNECT, MSG_FORMAT
+ }
+
+ public enum TransmitError {
+ TIMEOUT, DISCONNECT
+ }
}
Added: gnunet-java/src/org/gnunet/util/GnunetHash.java
===================================================================
--- gnunet-java/src/org/gnunet/util/GnunetHash.java
(rev 0)
+++ gnunet-java/src/org/gnunet/util/GnunetHash.java 2012-03-18 13:42:47 UTC
(rev 20588)
@@ -0,0 +1,5 @@
+package org.gnunet.util;
+
+
+public class GnunetHash {
+}
Added: gnunet-java/src/org/gnunet/util/GnunetMessage.java
===================================================================
--- gnunet-java/src/org/gnunet/util/GnunetMessage.java
(rev 0)
+++ gnunet-java/src/org/gnunet/util/GnunetMessage.java 2012-03-18 13:42:47 UTC
(rev 20588)
@@ -0,0 +1,36 @@
+package org.gnunet.util;
+
+
+import org.gnunet.construct.*;
+
+public class GnunetMessage implements Message {
+ public final int MINIMAL_SIZE = Header.SIZE;
+
+ public static class Header {
+ public static final int SIZE = 4;
+
+ @FrameSize
+ @UInt16
+ public int messageSize;
+
+ @UInt16
+ public int messageType;
+ }
+
+ public static interface Body extends MessageUnion {
+ }
+
+ public static GnunetMessage fromBody(Body b) {
+ GnunetMessage msg = new GnunetMessage();
+ msg.header = new Header();
+ msg.header.messageSize = Header.SIZE + Construct.getSize(b);
+
+ return msg;
+ }
+
+ @Nested
+ public Header header;
+
+ @Union(tag = "header.messageType", optional = true)
+ public Body body;
+}
Modified: gnunet-java/src/org/gnunet/util/MessageReceiver.java
===================================================================
--- gnunet-java/src/org/gnunet/util/MessageReceiver.java 2012-03-17
16:31:42 UTC (rev 20587)
+++ gnunet-java/src/org/gnunet/util/MessageReceiver.java 2012-03-18
13:42:47 UTC (rev 20588)
@@ -32,13 +32,9 @@
/**
* Method to call when we receive a message from the service.
*
- * @param msg
- * message received, NULL on deadline or fatal error
+ * @param msg message received, null on deadline or fatal error
*/
public void process(Message msg);
- /**
- * Method to call on deadline.
- */
- public void handleTimeout();
+ public void handleError(Client.ReceiveError e);
}
Modified: gnunet-java/src/org/gnunet/util/MessageTransmitter.java
===================================================================
--- gnunet-java/src/org/gnunet/util/MessageTransmitter.java 2012-03-17
16:31:42 UTC (rev 20587)
+++ gnunet-java/src/org/gnunet/util/MessageTransmitter.java 2012-03-18
13:42:47 UTC (rev 20588)
@@ -1,7 +1,13 @@
package org.gnunet.util;
public interface MessageTransmitter {
+ /**
+ * Called when the client is ready to transmit messages, or on
timeout/error.
+ *
+ * @param sink A message sink that receives messages to be transmitted by
the client,
+ * or null on timeout/error.
+ */
public void transmit(Client.MessageSink sink);
- public void handleTimeout();
+ void handleError(Client.TransmitError error);
}
Added: gnunet-java/src/org/gnunet/util/PeerIdentity.java
===================================================================
--- gnunet-java/src/org/gnunet/util/PeerIdentity.java
(rev 0)
+++ gnunet-java/src/org/gnunet/util/PeerIdentity.java 2012-03-18 13:42:47 UTC
(rev 20588)
@@ -0,0 +1,5 @@
+package org.gnunet.util;
+
+
+public class PeerIdentity {
+}
Modified: gnunet-java/src/org/gnunet/util/Resolver.java
===================================================================
--- gnunet-java/src/org/gnunet/util/Resolver.java 2012-03-17 16:31:42 UTC
(rev 20587)
+++ gnunet-java/src/org/gnunet/util/Resolver.java 2012-03-18 13:42:47 UTC
(rev 20588)
@@ -14,7 +14,6 @@
import java.net.Inet6Address;
import java.net.InetAddress;
import java.net.UnknownHostException;
-import java.util.Arrays;
import java.util.LinkedList;
public class Resolver {
@@ -214,7 +213,7 @@
}
}
- public class ResolveHandle {
+ public class ResolveHandle implements Cancelable {
private String hostname;
private AbsoluteTime deadline;
private AddressCallback cb;
@@ -322,6 +321,9 @@
new MessageTransmitter() {
@Override
public void transmit(Client.MessageSink sink) {
+ if (sink == null) {
+ onTimeout(rh);
+ }
sink.send(req);
rh.transmitTask = null;
@@ -354,18 +356,20 @@
}
@Override
- public void handleTimeout() {
- logger.debug("timeout in recv");
- onTimeout(rh);
+ public void handleError(Client.ReceiveError e) {
+ if (e.equals(Client.ReceiveError.TIMEOUT)) {
+ onTimeout(rh);
+ } else {
+ throw new RuntimeException("unexpected
receive error");
+ }
}
});
}
@Override
- public void handleTimeout() {
- logger.debug("timeout in notifyTransmitReady");
- onTimeout(rh);
+ public void handleError(Client.TransmitError error) {
+ throw new RuntimeException("unexpected transmit
error");
}
});
}
Modified: gnunet-java/src/org/gnunet/util/Scheduler.java
===================================================================
--- gnunet-java/src/org/gnunet/util/Scheduler.java 2012-03-17 16:31:42 UTC
(rev 20587)
+++ gnunet-java/src/org/gnunet/util/Scheduler.java 2012-03-18 13:42:47 UTC
(rev 20588)
@@ -79,7 +79,7 @@
/**
* A TaskIdentifier represents a Task that will execute or has already
been executed.
*/
- public static class TaskIdentifier implements Comparable<TaskIdentifier> {
+ public static class TaskIdentifier implements Comparable<TaskIdentifier>,
Cancelable {
private final Task task;
private TaskIdentifier prereq;
private RunContext ctx = new RunContext();
@@ -157,7 +157,7 @@
this.lifeness = true;
}
- void run() {
+ private void run() {
TaskIdentifier old = activeTask;
activeTask = this;
task.run(ctx);
@@ -176,11 +176,6 @@
return lifeness;
}
- public void setLifeness(boolean newLifeness) {
- lifeness = newLifeness;
- }
-
-
@Override
public int compareTo(TaskIdentifier other) {
return this.deadline.compareTo(other.deadline);
@@ -238,7 +233,7 @@
}
- public void deregister() {
+ private void deregister() {
if (this.rs != null) {
for (SelectableChannel sc : this.rs) {
deregisterOne(sc, SelectionKey.OP_READ);
Modified: gnunet-java/test/org/gnunet/construct/ConstructTest.java
===================================================================
--- gnunet-java/test/org/gnunet/construct/ConstructTest.java 2012-03-17
16:31:42 UTC (rev 20587)
+++ gnunet-java/test/org/gnunet/construct/ConstructTest.java 2012-03-18
13:42:47 UTC (rev 20588)
@@ -4,28 +4,34 @@
import org.junit.Test;
import java.math.BigInteger;
+import java.nio.ByteBuffer;
public class ConstructTest {
@Test
public void test_ByteFillMessage() {
- System.out.println("testing ByteFillMessage");
ByteFillMessage bfm = new ByteFillMessage();
bfm.header = new MessageHeader();
bfm.someValue = 42;
- bfm.rest = new byte[] {1,2,3,4,5,6,7,100};
+ bfm.rest = new byte[] {1,2,3,4,5,6,7,100, 8};
- Construct.patchSizeFields(bfm);
+ Construct.patch(bfm);
bfm.header.messageSize = Construct.getSize(bfm);
+
+ bfm.header.messageType = 42;
System.out.println(bfm.header.messageSize);
byte[] data = Construct.toBinary(bfm);
+
+ Assert.assertEquals(Construct.getSize(bfm), data.length);
+
+ System.out.println("data size: " + data.length);
- ByteFillMessage bfm2 = Construct.parseAs(data, 0,
ByteFillMessage.class);
+ ByteFillMessage bfm2 = Construct.parseAs(ByteBuffer.wrap(data),
ByteFillMessage.class);
Assert.assertArrayEquals(bfm.rest, bfm2.rest);
}
@@ -43,7 +49,7 @@
byte[] a = Construct.toBinary(vtm);
- VarTestMessage vtm2 = Construct.parseAs(a, 0, VarTestMessage.class);
+ VarTestMessage vtm2 = Construct.parseAs(ByteBuffer.wrap(a),
VarTestMessage.class);
Assert.assertEquals(vtm2.length, 5);
for (int i = 0; i < 5; ++i) {
@@ -66,7 +72,7 @@
}
byte[] a = Construct.toBinary(stm);
- SimpleTestMessage stm2 = Construct.parseAs(a, 0,
+ SimpleTestMessage stm2 = Construct.parseAs(ByteBuffer.wrap(a),
SimpleTestMessage.class);
Assert.assertEquals(stm.v1, stm2.v1);
@@ -93,7 +99,7 @@
strm.num2 = 80;
byte[] a = Construct.toBinary(strm);
- StringMessage strm2 = Construct.parseAs(a, 0, StringMessage.class);
+ StringMessage strm2 = Construct.parseAs(ByteBuffer.wrap(a),
StringMessage.class);
for (byte b : a) {
System.out.print((char) b);
@@ -114,13 +120,13 @@
qm.varsize = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
14, 15 };
- Construct.patchSizeFields(qm);
+ Construct.patch(qm);
byte[] a = Construct.toBinary(qm);
Assert.assertEquals(a.length, qm.header.messageSize);
- QueryMessage qm2 = Construct.parseAs(a, 0, QueryMessage.class);
+ QueryMessage qm2 = Construct.parseAs(ByteBuffer.wrap(a),
QueryMessage.class);
Assert.assertEquals(qm.header.messageSize, qm2.header.messageSize);
Assert.assertEquals(qm.header.messageType, qm2.header.messageType);
@@ -136,11 +142,11 @@
stm.someValue = 42;
stm.rest = new byte[] { 1, 2, 3, 4, 5 };
- Construct.patchSizeFields(stm);
+ Construct.patch(stm);
byte[] a = Construct.toBinary(stm);
- SizeTestMessage stm2 = Construct.parseAs(a, 0, SizeTestMessage.class);
+ SizeTestMessage stm2 = Construct.parseAs(ByteBuffer.wrap(a),
SizeTestMessage.class);
Assert.assertEquals(stm.someValue, stm2.someValue);
Assert.assertEquals(stm.totalSize, stm2.totalSize);
@@ -157,7 +163,7 @@
byte[] a = Construct.toBinary(h1);
- MessageHeader h2 = Construct.parseAs(a, 0, MessageHeader.class);
+ MessageHeader h2 = Construct.parseAs(ByteBuffer.wrap(a),
MessageHeader.class);
byte[] b = Construct.toBinary(h2);
Modified: gnunet-java/test/org/gnunet/construct/UnionTest.java
===================================================================
--- gnunet-java/test/org/gnunet/construct/UnionTest.java 2012-03-17
16:31:42 UTC (rev 20587)
+++ gnunet-java/test/org/gnunet/construct/UnionTest.java 2012-03-18
13:42:47 UTC (rev 20588)
@@ -1,8 +1,11 @@
package org.gnunet.construct;
+import org.junit.Assert;
import org.junit.Test;
+import java.nio.ByteBuffer;
+
public class UnionTest {
public static interface TestUnion extends MessageUnion {}
@@ -37,8 +40,13 @@
byte[] a = Construct.toBinary(utm);
System.out.println(a.length);
+ System.out.println(Construct.getSize(utm));
+
- UnionTestMessage utm2 = Construct.parseAs(a, 0,
UnionTestMessage.class);
+ UnionTestMessage utm2 = Construct.parseAs(ByteBuffer.wrap(a),
UnionTestMessage.class);
+
+
+ Assert.assertEquals(((TestUnionCase0) utm.instance).val,
((TestUnionCase0) utm2.instance).val);
}
}
Deleted: gnunet-java/update-msgtypes.sh
===================================================================
--- gnunet-java/update-msgtypes.sh 2012-03-17 16:31:42 UTC (rev 20587)
+++ gnunet-java/update-msgtypes.sh 2012-03-18 13:42:47 UTC (rev 20588)
@@ -1,13 +0,0 @@
-#!/bin/sh
-
-# collect all source files
-find ./src/ ./test/ -name "*.java" > sources.txt
-
-# run annotation processor
-javac -cp "./bin/:./lib/*" -processor
org.gnunet.construct.MessageIdAnnotationProcessor -proc:only -s src @sources.txt
-
-if [ $? ] ; then
- rm sources.txt
-else
- exit 1
-fi
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [GNUnet-SVN] r20588 - in gnunet-java: . .idea .idea/libraries src/org/gnunet src/org/gnunet/construct src/org/gnunet/construct/parsers src/org/gnunet/dht src/org/gnunet/nse src/org/gnunet/statistics src/org/gnunet/util test/org/gnunet/construct,
gnunet <=