[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[GNUnet-SVN] r18411 - in gnunet-java: . .settings src/org/gnunet/constru
From: |
gnunet |
Subject: |
[GNUnet-SVN] r18411 - in gnunet-java: . .settings src/org/gnunet/construct src/org/gnunet/construct/parsers src/org/gnunet/messages src/org/gnunet/service src/org/gnunet/util src/org/gnunet/util/datastructures test/org/gnunet/construct |
Date: |
Thu, 1 Dec 2011 02:00:29 +0100 |
Author: dold
Date: 2011-12-01 02:00:29 +0100 (Thu, 01 Dec 2011)
New Revision: 18411
Added:
gnunet-java/src/org/gnunet/construct/ByteFill.java
gnunet-java/src/org/gnunet/construct/Fill.java
gnunet-java/src/org/gnunet/construct/FixedSizeArray.java
gnunet-java/src/org/gnunet/construct/FrameSize.java
gnunet-java/src/org/gnunet/construct/Int16.java
gnunet-java/src/org/gnunet/construct/Int32.java
gnunet-java/src/org/gnunet/construct/Int64.java
gnunet-java/src/org/gnunet/construct/Int8.java
gnunet-java/src/org/gnunet/construct/Integer.java
gnunet-java/src/org/gnunet/construct/Nested.java
gnunet-java/src/org/gnunet/construct/UInt16.java
gnunet-java/src/org/gnunet/construct/UInt32.java
gnunet-java/src/org/gnunet/construct/UInt64.java
gnunet-java/src/org/gnunet/construct/UInt8.java
gnunet-java/src/org/gnunet/construct/VariableSizeArray.java
gnunet-java/src/org/gnunet/construct/ZeroTerminatedString.java
gnunet-java/src/org/gnunet/construct/parsers/
gnunet-java/src/org/gnunet/construct/parsers/ByteFillParser.java
gnunet-java/src/org/gnunet/construct/parsers/FieldParser.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/VariableSizeArrayParser.java
gnunet-java/src/org/gnunet/messages/StringMessage.java
Removed:
gnunet-java/src/org/gnunet/construct/FieldLocation.java
gnunet-java/src/org/gnunet/construct/FillParser.java
gnunet-java/src/org/gnunet/construct/FixedSizeArrayParser.java
gnunet-java/src/org/gnunet/construct/Location.java
gnunet-java/src/org/gnunet/construct/ObjectParser.java
gnunet-java/src/org/gnunet/construct/Parser.java
gnunet-java/src/org/gnunet/construct/RefLocation.java
gnunet-java/src/org/gnunet/construct/SignedIntegerParser.java
gnunet-java/src/org/gnunet/construct/StringParser.java
gnunet-java/src/org/gnunet/construct/TotalSizeParser.java
gnunet-java/src/org/gnunet/construct/UnsignedIntegerParser.java
gnunet-java/src/org/gnunet/construct/VariableSizeArrayParser.java
gnunet-java/src/org/gnunet/messages/ComplexTestMessage.java
gnunet-java/src/org/gnunet/messages/StringTestMessage.java
gnunet-java/src/org/gnunet/messages/TestMessage3.java
gnunet-java/src/org/gnunet/messages/TestMessage4.java
Modified:
gnunet-java/.settings/org.eclipse.jdt.ui.prefs
gnunet-java/ISSUES
gnunet-java/src/org/gnunet/construct/Construct.java
gnunet-java/src/org/gnunet/messages/Message.java
gnunet-java/src/org/gnunet/messages/MessageHeader.java
gnunet-java/src/org/gnunet/messages/QueryMessage.java
gnunet-java/src/org/gnunet/messages/RelativeTimeNBO.java
gnunet-java/src/org/gnunet/messages/SimpleTestMessage.java
gnunet-java/src/org/gnunet/messages/SimpleTestMessage2.java
gnunet-java/src/org/gnunet/messages/SizeTestMessage.java
gnunet-java/src/org/gnunet/service/StatisticsService.java
gnunet-java/src/org/gnunet/util/AbsoluteTime.java
gnunet-java/src/org/gnunet/util/Client.java
gnunet-java/src/org/gnunet/util/Configuration.java
gnunet-java/src/org/gnunet/util/MessageHandler.java
gnunet-java/src/org/gnunet/util/Program.java
gnunet-java/src/org/gnunet/util/Receiver.java
gnunet-java/src/org/gnunet/util/RelativeTime.java
gnunet-java/src/org/gnunet/util/Scheduler.java
gnunet-java/src/org/gnunet/util/TransmitReadyNotify.java
gnunet-java/src/org/gnunet/util/datastructures/BloomFilter.java
gnunet-java/test/org/gnunet/construct/ConstructTest.java
Log:
Modified: gnunet-java/.settings/org.eclipse.jdt.ui.prefs
===================================================================
--- gnunet-java/.settings/org.eclipse.jdt.ui.prefs 2011-11-30 15:21:36 UTC
(rev 18410)
+++ gnunet-java/.settings/org.eclipse.jdt.ui.prefs 2011-12-01 01:00:29 UTC
(rev 18411)
@@ -1,4 +1,4 @@
-#Sun Nov 06 13:14:08 CET 2011
+#Mon Nov 28 16:34:22 CET 2011
cleanup.add_default_serial_version_id=true
cleanup.add_generated_serial_version_id=false
cleanup.add_missing_annotations=true
@@ -12,9 +12,9 @@
cleanup.always_use_parentheses_in_expressions=false
cleanup.always_use_this_for_non_static_field_access=false
cleanup.always_use_this_for_non_static_method_access=false
-cleanup.convert_to_enhanced_for_loop=false
-cleanup.correct_indentation=false
-cleanup.format_source_code=false
+cleanup.convert_to_enhanced_for_loop=true
+cleanup.correct_indentation=true
+cleanup.format_source_code=true
cleanup.format_source_code_changes_only=false
cleanup.make_local_variable_final=true
cleanup.make_parameters_final=true
@@ -30,7 +30,7 @@
cleanup.qualify_static_member_accesses_with_declaring_class=true
cleanup.qualify_static_method_accesses_with_declaring_class=false
cleanup.remove_private_constructors=true
-cleanup.remove_trailing_whitespaces=false
+cleanup.remove_trailing_whitespaces=true
cleanup.remove_trailing_whitespaces_all=true
cleanup.remove_trailing_whitespaces_ignore_empty=false
cleanup.remove_unnecessary_casts=true
@@ -41,11 +41,11 @@
cleanup.remove_unused_private_members=false
cleanup.remove_unused_private_methods=true
cleanup.remove_unused_private_types=true
-cleanup.sort_members=false
+cleanup.sort_members=true
cleanup.sort_members_all=false
cleanup.use_blocks=true
cleanup.use_blocks_only_for_return_and_throw=false
-cleanup.use_parentheses_in_expressions=false
+cleanup.use_parentheses_in_expressions=true
cleanup.use_this_for_non_static_field_access=false
cleanup.use_this_for_non_static_field_access_only_if_necessary=true
cleanup.use_this_for_non_static_method_access=false
Modified: gnunet-java/ISSUES
===================================================================
--- gnunet-java/ISSUES 2011-11-30 15:21:36 UTC (rev 18410)
+++ gnunet-java/ISSUES 2011-12-01 01:00:29 UTC (rev 18411)
@@ -22,17 +22,6 @@
* what about spaces in filenames? quotes in config values?
* formal spec of syntax?
-* binary message parsing:
- * use DSL (eg. Xtext)
- * use hand-written parsers
- * use dynamically construct parsers at runtume from composable matchers (cf.
pythons construct library)
- * flexible
- * slow
- * generate parsers from java files using annotations
- * is java flexible enough for this?
- * cannot generate interfaces / add new members
-
-
* error handling: what to do with io errors in some cases?
* process priority
@@ -43,17 +32,6 @@
-* exception handling in statically used classes (scheduler)
- * solution: singleton? => static {} - blocks?
-
-
-
-
- * advantages of the "new" parsing/unparsing package
- * parsers are decoupled from annotations
- * => parsers could be pre-compiled
- * parsers are only constructed once per class
-
-
-* what about TotalSize?
-
\ No newline at end of file
+* exception hierarchy in Construct
+
+
Added: gnunet-java/src/org/gnunet/construct/ByteFill.java
===================================================================
--- gnunet-java/src/org/gnunet/construct/ByteFill.java
(rev 0)
+++ gnunet-java/src/org/gnunet/construct/ByteFill.java 2011-12-01 01:00:29 UTC
(rev 18411)
@@ -0,0 +1,18 @@
+package org.gnunet.construct;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Fills a byte array with the rest of the message in the current frame.
+ *
+ * @author Florian Dold
+ *
+ */
address@hidden(RetentionPolicy.RUNTIME)
address@hidden(ElementType.FIELD)
+public @interface ByteFill {
+}
+
Modified: gnunet-java/src/org/gnunet/construct/Construct.java
===================================================================
--- gnunet-java/src/org/gnunet/construct/Construct.java 2011-11-30 15:21:36 UTC
(rev 18410)
+++ gnunet-java/src/org/gnunet/construct/Construct.java 2011-12-01 01:00:29 UTC
(rev 18411)
@@ -1,14 +1,22 @@
package org.gnunet.construct;
import java.lang.annotation.Annotation;
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import org.gnunet.construct.parsers.ByteFillParser;
+import org.gnunet.construct.parsers.FieldParser;
+import org.gnunet.construct.parsers.FixedSizeArrayParser;
+import org.gnunet.construct.parsers.IntegerParser;
+import org.gnunet.construct.parsers.NestedParser;
+import org.gnunet.construct.parsers.Parser;
+import org.gnunet.construct.parsers.SequenceParser;
+import org.gnunet.construct.parsers.StringParser;
+import org.gnunet.messages.Message;
+import org.grothoff.Runabout;
/**
* A version of Python's construct library for Java.
@@ -19,247 +27,196 @@
* annotations (int16, int32, uint64, etc.)
* @TODO error handling (exceptions?), documentation
* @TODO performance evaluation
- * @TODO add an Order(n) annotation if there's a java implementation out there
- * that reorders fields
*/
public class Construct {
- private static final Logger logger = LoggerFactory
- .getLogger(Construct.class);
- /**
- * Thrown if a parser requires more space in the buffer.
- *
- * @author Florian Dold
- *
- */
- static class SizeError extends RuntimeException {
+ private static HashMap<Class<? extends Message>, Parser> parserCache = new
HashMap<Class<? extends Message>, Parser>();
- }
-
/**
- * Embed another constructable message.
+ * Given a byte array with a message, parse it into an object of type c.
The
+ * fields of the class are expected to be annotated with annotations from
+ * the construct package.
*
- * @author Florian Dold
- *
+ * @param data
+ * serialized binary object data
+ * @param offset
+ * where the message starts in data
+ * @param c
+ * desired object type to return
+ * @return instance of the desired object type
+ * @throws RuntimeException
+ * (ugh)
*/
- @Retention(RetentionPolicy.RUNTIME)
- @Target(ElementType.FIELD)
- public @interface Nested {
- boolean header() default false;
+ public static <T extends Message> T parseAs(byte[] data, int offset,
+ Class<T> c) {
+ Parser p = getParser(c);
+ T m;
+ try {
+ m = (T) c.newInstance();
+ } catch (InstantiationException e) {
+ throw new RuntimeException();
+ } catch (IllegalAccessException e) {
+ throw new RuntimeException();
+ }
+ p.parse(data, offset, 0, m);
+ return m;
}
+
/**
- * Acceptable targets: byte, short, int, long, BigInteger.
*
- * @author Florian Dold
*
+ * @param c
+ * @return
*/
- @Retention(RetentionPolicy.RUNTIME)
- @Target(ElementType.FIELD)
- public @interface SignedInteger {
- /**
- * number of bits in this signed integer, only multiples of 8 are
- * permitted.
- */
- int value() default 4;
- }
+ public static Parser getParser(Class<? extends Message> c) {
- /**
- * Stores and retrieves the size of the enclosing message.
- *
- * @author Florian Dold
- *
- */
- @Retention(RetentionPolicy.RUNTIME)
- @Target(ElementType.FIELD)
- public @interface TotalSize {
+ if (parserCache.containsKey(c)) {
+ return parserCache.get(c);
+ }
- }
+ Parser p = getParser(c, new ParserGenerator());
- @Retention(RetentionPolicy.RUNTIME)
- @Target(ElementType.FIELD)
- public @interface FixedSizeArray {
- int length();
+ parserCache.put(c, p);
+
+ return p;
}
- /**
- * Acceptable targets: byte, short, int, long, BigInteger.
- *
- * @author Florian Dold
- *
- */
- @Retention(RetentionPolicy.RUNTIME)
- @Target(ElementType.FIELD)
- public @interface UnsignedInteger {
- int value() default 4;
+ public static Parser getParser(Class<? extends Message> c,
+ ParserGenerator pg) {
- // if useSignBit is true, the sign bit may be used to store a bit
- // of an unsigned number (this makes the number negative), if
useSignBit
- // is false
- // an error is signaled if the sign of the target field is set
- boolean useSignBit() default true;
- }
+ SequenceParser parser = new SequenceParser(null);
- @Retention(RetentionPolicy.RUNTIME)
- @Target(ElementType.FIELD)
- public @interface VariableSizeArray {
- // set to empty string to make the array extend to fill the available
- // space
- String lengthField();
- }
+ Field[] fs = c.getFields();
+ for (Field f : fs) {
+ Annotation[] as = f.getAnnotations();
+ if (as.length == 0) {
+ continue;
+ }
+ pg.field = f;
+ pg.annotations = as;
+ pg.annotationsIdx = 0;
- /**
- * Parse and unparse a zero-terminated string with the specified encoding.
- *
- * @author Florian Dold
- *
- */
- @Retention(RetentionPolicy.RUNTIME)
- public @interface ZeroTerminatedString {
+ pg.visitAppropriate(as[0]);
- String charset() default "UTF-8";
- }
+ parser.add(pg.parser);
- /**
- * Fills a byte array with the rest of the message in the buffer.
- *
- * @author Florian Dold
- *
- */
- @Retention(RetentionPolicy.RUNTIME)
- @Target(ElementType.FIELD)
- public @interface Fill {
- }
+ }
- public static <T> T parseWith(Parser p, byte[] data, int offset) {
- RefLocation rl = new RefLocation();
- Location[] locs = { rl };
- p.parse(data, offset, locs);
- return (T) rl.get();
+ return parser;
}
- public static Parser makeParser(Class cls) {
- // TODO: caching
+ public static class ParserGenerator extends Runabout {
- ObjectParser op = new ObjectParser(cls);
+ Field field;
+ Annotation[] annotations;
+ int annotationsIdx;
- // adds the size of the child parser's object so specific locations
- TotalSizeParser tsp = new TotalSizeParser(op);
+ FieldParser parser;
- for (Field f : cls.getDeclaredFields()) {
- Annotation[] anns = f.getAnnotations();
- if (anns.length == 0) {
- continue;
- }
+ List<Field> total_size_path;
- if (anns[0] instanceof TotalSize) {
- Parser child = getFieldParser(f.getType(), anns, 1);
- tsp.addSizeField(child, f);
- op.add(child, f);
- } else if (anns[0] instanceof VariableSizeArray) {
- VariableSizeArray ann = (VariableSizeArray) anns[0];
- Parser child = getFieldParser(f.getType().getComponentType(),
anns, 1);
- Parser p = new VariableSizeArrayParser(child);
-
- try {
- op.add(p, f, cls.getDeclaredField(ann.lengthField()));
- } catch (SecurityException e) {
- throw new RuntimeException();
- } catch (NoSuchFieldException e) {
- throw new RuntimeException();
- }
-
- } else {
- Parser p = getFieldParser(f.getType(), anns, 0);
- op.add(p, f);
+ List<Field> path = new LinkedList<Field>();
+
+ private ParserGenerator() {
+ }
+
+ public void visitDefault(Object o) {
+ throw new RuntimeException("unexpected annotation");
+ }
+
+ public void visit(FrameSize ts) {
+ // set total_size_path to path
+
+ total_size_path = new LinkedList<Field>(path);
+ total_size_path.add(field);
+
+ annotationsIdx++;
+ if (annotationsIdx >= annotations.length) {
+ throw new RuntimeException();
}
+ visitAppropriate(annotations[annotationsIdx]);
}
- return tsp;
- }
- /**
- * get a "simple" parser that only writes to the field in question and has
- * no other arguments
- *
- * @param f
- * @param anns
- * @param start
- * @return
- */
- public static Parser getFieldParser(Class cls, Annotation[] anns, int
start) {
- for (int i = start; i < anns.length; ++i) {
- Annotation ann = anns[i];
- if (ann instanceof SignedInteger) {
- if (i != anns.length - 1) {
- throw new RuntimeException(
- "Further annotations are forbidden after
@SignedInteger");
- }
- SignedInteger a = (SignedInteger) ann;
- return new SignedIntegerParser(a.value());
- } else if (ann instanceof UnsignedInteger) {
- if (i != anns.length - 1) {
- throw new RuntimeException(
- "Further annotations are forbidden after
@UnignedInteger");
- }
- UnsignedInteger a = (UnsignedInteger) ann;
- return new UnsignedIntegerParser(a.value());
- } else if (ann instanceof ZeroTerminatedString) {
- if (i != anns.length - 1) {
- throw new RuntimeException(
- "Further annotations are forbidden after
@ZeroTerminatedString");
- }
- ZeroTerminatedString a = (ZeroTerminatedString) ann;
- return new StringParser();
- } else if (ann instanceof TotalSize) {
- throw new UnsupportedOperationException(
- "total size not yet implemented");
+ // Integer Types
- } else if (ann instanceof Nested) {
- // this needs to be the last annotation
- if (i != anns.length - 1) {
- throw new RuntimeException(
- "Futher annotations are forbidden after @Nested");
- }
- Parser child = makeParser(cls);
- return child;
+ public void visit(UInt8 i) {
+ parser = new IntegerParser(1, IntegerParser.UNSIGNED, field);
+ }
- } else if (ann instanceof FixedSizeArray) {
- FixedSizeArray a = (FixedSizeArray) ann;
- Parser fp = getFieldParser(cls.getComponentType(), anns,
- start + 1);
- return new FixedSizeArrayParser(a.length(), fp);
- } else if (ann instanceof Fill) {
- Parser fp = getFieldParser(cls.getComponentType(), anns,
- start + 1);
- return new FillParser(fp);
- } else {
- throw new RuntimeException("unknown construct annotation: "
- + ann.getClass());
+ public void visit(UInt16 i) {
+ parser = new IntegerParser(2, IntegerParser.UNSIGNED, field);
+ }
+
+ public void visit(UInt32 i) {
+ parser = new IntegerParser(4, IntegerParser.UNSIGNED, field);
+ }
+
+ public void visit(UInt64 i) {
+ parser = new IntegerParser(8, IntegerParser.UNSIGNED, field);
+ }
+
+ public void visit(Int8 i) {
+ parser = new IntegerParser(1, IntegerParser.SIGNED, field);
+ }
+
+ public void visit(Int16 i) {
+ parser = new IntegerParser(2, IntegerParser.SIGNED, field);
+ }
+
+ public void visit(Int32 i) {
+ parser = new IntegerParser(4, IntegerParser.SIGNED, field);
+ }
+
+ public void visit(Int64 i) {
+ parser = new IntegerParser(8, IntegerParser.SIGNED, field);
+ }
+
+ public void visit(Integer i) {
+ parser = new IntegerParser(i.byteSize(), i.signed(), field);
+ }
+
+ public void visit(ZeroTerminatedString zts) {
+ parser = new StringParser("UTF-8", field);
+ }
+
+ public void visit(Nested n) {
+
+ Class<? extends Message> ct = (Class<? extends Message>) field
+ .getType();
+
+ Field old_f = field;
+
+ List<Field> old_path = new ArrayList<Field>(path);
+
+ path.add(field);
+
+ Parser p = getParser(ct, this);
+
+ path = old_path;
+ parser = new NestedParser(p, old_f);
+ }
+
+ public void visit(ByteFill bf) {
+ if (total_size_path == null) {
+ throw new RuntimeException(
+ "no total size found before variable size element");
}
+
+ parser = new ByteFillParser(total_size_path, field);
}
- throw new RuntimeException("unreachable");
- }
- /**
- * Given a byte array with a message, parse it into an object of type c.
The
- * fields of the class are expected to be annotated with annotations from
- * the construct package.
- *
- * @param data
- * serialized binary object data
- * @param offset
- * where the message starts in data
- * @param c
- * desired object type to return
- * @return instance of the desired object type
- * @throws RuntimeException
- * (ugh)
- */
- public static <T> T parse(byte[] data, int offset, Class<T> cls) {
- Parser p = makeParser(cls);
+ public void visit(FixedSizeArray fsa) {
+ Field f = field;
+ int elemNumber = fsa.length();
- return Construct.parseWith(p, data, offset);
+ getParser((Class<? extends Message>) field.getType()
+ .getComponentType(), this);
+
+ parser = new FixedSizeArrayParser(elemNumber, parser, f);
+ }
+
}
/**
@@ -267,7 +224,7 @@
* the object are expected to be annotated with annotations from the
* construct package.
*
- * @param obj
+ * @param o
* object to serialize
* @param data
* where to write the binary object data
@@ -275,26 +232,32 @@
* where to start writing data
* @return number of bytes written to data, -1 on error
*/
- public static int writeTo(Object obj, byte[] data, int offset) {
- Parser p = makeParser(obj.getClass());
- return p.unparse(data, offset, RefLocation.makeLocationsWith(obj));
+ public static int write(Message o, byte[] data, int offset) {
+ Parser p = getParser(o.getClass());
+ return p.write(data, offset, o);
}
/**
- * Compute the size of a serialized message object.
+ * Compute the size of a serialized message.
*
* @param o
* object to serialize
* @return number of bytes required, -1 on error
*/
- public static int estimateSize(Object obj) {
- Parser p = makeParser(obj.getClass());
- return p.estimateSize(RefLocation.makeLocationsWith(obj));
+ public static int getSize(Message m) {
+ Parser p = getParser(m.getClass());
+ return p.getSize(m);
}
- public static byte[] unparse(Object obj) {
- byte[] data = new byte[estimateSize(obj)];
- writeTo(obj, data, 0);
- return data;
+ public static byte[] toBinary(Message m) {
+ byte[] a = new byte[getSize(m)];
+ write(m, a, 0);
+ return a;
}
+
+ public static void patchSizeFields(Message m) {
+ Parser p = getParser(m.getClass());
+ p.patchSizeFields(m, p.getSize(m));
+ }
+
}
Deleted: gnunet-java/src/org/gnunet/construct/FieldLocation.java
===================================================================
--- gnunet-java/src/org/gnunet/construct/FieldLocation.java 2011-11-30
15:21:36 UTC (rev 18410)
+++ gnunet-java/src/org/gnunet/construct/FieldLocation.java 2011-12-01
01:00:29 UTC (rev 18411)
@@ -1,42 +0,0 @@
-package org.gnunet.construct;
-
-import java.lang.reflect.Field;
-
-public class FieldLocation implements Location {
- private Field f;
- private Object o;
-
- public FieldLocation(Field f, Object o) {
- assert f != null;
- this.f = f;
- this.o = o;
- }
-
- @Override
- public void put(Object v) {
- try {
- f.set(o, v);
- } catch (IllegalArgumentException e) {
- throw new RuntimeException();
- } catch (IllegalAccessException e) {
- throw new RuntimeException();
- }
- }
-
- @Override
- public Class getType() {
- return f.getType();
- }
-
- @Override
- public Object get() {
- try {
- return f.get(o);
- } catch (IllegalArgumentException e) {
- throw new RuntimeException();
- } catch (IllegalAccessException e) {
- throw new RuntimeException();
- }
- }
-
-}
Added: gnunet-java/src/org/gnunet/construct/Fill.java
===================================================================
--- gnunet-java/src/org/gnunet/construct/Fill.java
(rev 0)
+++ gnunet-java/src/org/gnunet/construct/Fill.java 2011-12-01 01:00:29 UTC
(rev 18411)
@@ -0,0 +1,17 @@
+package org.gnunet.construct;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Fills a byte array with the rest of the message in the buffer.
+ *
+ * @author Florian Dold
+ *
+ */
address@hidden(RetentionPolicy.RUNTIME)
address@hidden(ElementType.FIELD)
+public @interface Fill {
+}
Deleted: gnunet-java/src/org/gnunet/construct/FillParser.java
===================================================================
--- gnunet-java/src/org/gnunet/construct/FillParser.java 2011-11-30
15:21:36 UTC (rev 18410)
+++ gnunet-java/src/org/gnunet/construct/FillParser.java 2011-12-01
01:00:29 UTC (rev 18411)
@@ -1,90 +0,0 @@
-package org.gnunet.construct;
-
-import java.lang.reflect.Array;
-import java.util.ArrayList;
-import java.util.LinkedList;
-import java.util.List;
-
-/**
- * Parse an array that takes up all the available space.
- *
- * @author Florian Dold
- *
- */
-public class FillParser implements Parser {
- Parser p;
-
- public FillParser(Parser p) {
- this.p = p;
- }
-
- @Override
- public int parse(byte[] src_data, int offset, Location[] dst) {
- assert dst.length == 1;
- Location loc = dst[0];
-
- assert loc.getType().isArray();
-
- int parsed = 0;
-
-
- List<Object> lst = new ArrayList<Object>();
-
- while (true) {
- RefLocation rl = new RefLocation(loc.getType().getComponentType());
- Location[] locs = {rl};
-
- try {
- parsed += p.parse(src_data, offset+parsed, locs);
- } catch (Construct.SizeError e) {
- break;
- }
-
- lst.add(rl.get());
- }
-
- Object arr = Array.newInstance(loc.getType().getComponentType(),
lst.size());
-
- for (int i = 0; i < lst.size(); ++i) {
- Array.set(arr, i, lst.get(i));
- }
-
- loc.put(arr);
-
- return parsed;
- }
-
- @Override
- public int unparse(byte[] dst_data, int offset, Location[] src) {
- assert src.length == 1;
-
- Object arr = src[0].get();
- int parsed = 0;
-
- for (int i = 0; i < Array.getLength(arr); ++i) {
- RefLocation rl = new
RefLocation(arr.getClass().getComponentType());
- rl.put(Array.get(arr, i));
- Location[] locs = { rl };
- parsed += p.unparse(dst_data, offset, locs);
- offset += p.parse(dst_data, offset, locs);
- }
-
- return parsed;
- }
-
- @Override
- public int estimateSize(Location[] args) {
- assert args.length == 1;
- int accum = 0;
- Object arr = args[0].get();
- for (int i = 0; i < Array.getLength(arr); ++i) {
- RefLocation rl = new RefLocation();
- rl.put(Array.get(arr, i));
- Location[] locs = { rl };
- accum += p.estimateSize(locs);
- }
- return accum;
-
- }
-
-}
Added: gnunet-java/src/org/gnunet/construct/FixedSizeArray.java
===================================================================
--- gnunet-java/src/org/gnunet/construct/FixedSizeArray.java
(rev 0)
+++ gnunet-java/src/org/gnunet/construct/FixedSizeArray.java 2011-12-01
01:00:29 UTC (rev 18411)
@@ -0,0 +1,12 @@
+package org.gnunet.construct;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
address@hidden(RetentionPolicy.RUNTIME)
address@hidden(ElementType.FIELD)
+public @interface FixedSizeArray {
+ int length();
+}
Deleted: gnunet-java/src/org/gnunet/construct/FixedSizeArrayParser.java
===================================================================
--- gnunet-java/src/org/gnunet/construct/FixedSizeArrayParser.java
2011-11-30 15:21:36 UTC (rev 18410)
+++ gnunet-java/src/org/gnunet/construct/FixedSizeArrayParser.java
2011-12-01 01:00:29 UTC (rev 18411)
@@ -1,67 +0,0 @@
-package org.gnunet.construct;
-
-import java.lang.reflect.Array;
-
-public class FixedSizeArrayParser implements Parser {
-
- private Parser p;
- private int size;
-
- public FixedSizeArrayParser(int size, Parser p) {
- this.p = p;
- this.size = size;
- }
-
- @Override
- public int parse(byte[] src_data, int offset, Location[] dst) {
- assert dst.length == 1;
- Location loc = dst[0];
-
- assert loc.getType().isArray();
-
- int parsed = 0;
-
- Object array = Array.newInstance(loc.getType().getComponentType(),
size);
-
- for (int i = 0; i < size; ++i) {
- RefLocation rl = new RefLocation(loc.getType().getComponentType());
- Location[] locs = {rl};
- parsed += p.parse(src_data, offset+parsed, locs);
- Array.set(array, i, rl.get());
- }
-
- return parsed;
- }
-
- @Override
- public int unparse(byte[] dst_data, int offset, Location[] src) {
- assert src.length == 1;
-
- Object arr = src[0].get();
- int parsed = 0;
-
- for (int i = 0; i < size; ++i) {
- RefLocation rl = new
RefLocation(arr.getClass().getComponentType());
- rl.put(Array.get(arr, i));
- Location[] locs = {rl};
- parsed += p.unparse(dst_data, offset, locs);
- offset += p.parse(dst_data, offset, locs);
- }
-
- return parsed;
- }
-
- @Override
- public int estimateSize(Location[] args) {
- assert args.length == 1;
- int accum = 0;
- Object arr = args[0].get();
- for (int i = 0; i < size; ++i) {
- RefLocation rl = new RefLocation();
- rl.put(Array.get(arr, i));
- Location[] locs = {rl};
- accum += p.estimateSize(locs);
- }
- return accum;
- }
-}
Added: gnunet-java/src/org/gnunet/construct/FrameSize.java
===================================================================
--- gnunet-java/src/org/gnunet/construct/FrameSize.java
(rev 0)
+++ gnunet-java/src/org/gnunet/construct/FrameSize.java 2011-12-01 01:00:29 UTC
(rev 18411)
@@ -0,0 +1,18 @@
+package org.gnunet.construct;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ *
+ *
+ * @author Florian Dold
+ *
+ */
address@hidden(RetentionPolicy.RUNTIME)
address@hidden(ElementType.FIELD)
+public @interface FrameSize {
+
+}
Added: gnunet-java/src/org/gnunet/construct/Int16.java
===================================================================
--- gnunet-java/src/org/gnunet/construct/Int16.java
(rev 0)
+++ gnunet-java/src/org/gnunet/construct/Int16.java 2011-12-01 01:00:29 UTC
(rev 18411)
@@ -0,0 +1,12 @@
+package org.gnunet.construct;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
address@hidden(RetentionPolicy.RUNTIME)
address@hidden(ElementType.FIELD)
+public @interface Int16 {
+
+}
Added: gnunet-java/src/org/gnunet/construct/Int32.java
===================================================================
--- gnunet-java/src/org/gnunet/construct/Int32.java
(rev 0)
+++ gnunet-java/src/org/gnunet/construct/Int32.java 2011-12-01 01:00:29 UTC
(rev 18411)
@@ -0,0 +1,12 @@
+package org.gnunet.construct;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
address@hidden(RetentionPolicy.RUNTIME)
address@hidden(ElementType.FIELD)
+public @interface Int32 {
+
+}
Added: gnunet-java/src/org/gnunet/construct/Int64.java
===================================================================
--- gnunet-java/src/org/gnunet/construct/Int64.java
(rev 0)
+++ gnunet-java/src/org/gnunet/construct/Int64.java 2011-12-01 01:00:29 UTC
(rev 18411)
@@ -0,0 +1,12 @@
+package org.gnunet.construct;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
address@hidden(RetentionPolicy.RUNTIME)
address@hidden(ElementType.FIELD)
+public @interface Int64 {
+
+}
Added: gnunet-java/src/org/gnunet/construct/Int8.java
===================================================================
--- gnunet-java/src/org/gnunet/construct/Int8.java
(rev 0)
+++ gnunet-java/src/org/gnunet/construct/Int8.java 2011-12-01 01:00:29 UTC
(rev 18411)
@@ -0,0 +1,12 @@
+package org.gnunet.construct;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
address@hidden(RetentionPolicy.RUNTIME)
address@hidden(ElementType.FIELD)
+public @interface Int8 {
+
+}
Added: gnunet-java/src/org/gnunet/construct/Integer.java
===================================================================
--- gnunet-java/src/org/gnunet/construct/Integer.java
(rev 0)
+++ gnunet-java/src/org/gnunet/construct/Integer.java 2011-12-01 01:00:29 UTC
(rev 18411)
@@ -0,0 +1,14 @@
+package org.gnunet.construct;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
address@hidden(RetentionPolicy.RUNTIME)
address@hidden(ElementType.FIELD)
+public @interface Integer {
+ int byteSize();
+
+ boolean signed();
+}
Deleted: gnunet-java/src/org/gnunet/construct/Location.java
===================================================================
--- gnunet-java/src/org/gnunet/construct/Location.java 2011-11-30 15:21:36 UTC
(rev 18410)
+++ gnunet-java/src/org/gnunet/construct/Location.java 2011-12-01 01:00:29 UTC
(rev 18411)
@@ -1,15 +0,0 @@
-package org.gnunet.construct;
-
-/**
- *
- *
- * @author dold
- *
- */
-public interface Location {
- void put(Object o);
-
- Object get();
-
- Class getType();
-}
Added: gnunet-java/src/org/gnunet/construct/Nested.java
===================================================================
--- gnunet-java/src/org/gnunet/construct/Nested.java
(rev 0)
+++ gnunet-java/src/org/gnunet/construct/Nested.java 2011-12-01 01:00:29 UTC
(rev 18411)
@@ -0,0 +1,18 @@
+package org.gnunet.construct;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Embed another constructable message.
+ *
+ * @author Florian Dold
+ *
+ */
address@hidden(RetentionPolicy.RUNTIME)
address@hidden(ElementType.FIELD)
+public @interface Nested {
+ boolean newFrame() default false;
+}
\ No newline at end of file
Deleted: gnunet-java/src/org/gnunet/construct/ObjectParser.java
===================================================================
--- gnunet-java/src/org/gnunet/construct/ObjectParser.java 2011-11-30
15:21:36 UTC (rev 18410)
+++ gnunet-java/src/org/gnunet/construct/ObjectParser.java 2011-12-01
01:00:29 UTC (rev 18411)
@@ -1,155 +0,0 @@
-package org.gnunet.construct;
-
-import java.lang.annotation.Annotation;
-import java.lang.reflect.Field;
-import java.util.LinkedList;
-import java.util.List;
-
-import org.gnunet.construct.Construct.UnsignedInteger;
-
-public class ObjectParser implements Parser {
-
- static class ParserRecord {
- Parser p;
- Field[] args;
-
- public ParserRecord(Parser p, Field... args) {
- this.p = p;
- this.args = args;
- }
- }
-
- /*
- *
- *
- * class TotalSizeParser implements Parser { }
- *
- *
- * // the object parser stores the total size in the parsers before
- * unparsing. // TotalSize parsers do not affect parsing, except maybe for
- * consistency checks List<TotalSizeParser> total_size_parsers;
- */
-
- // parser with arguments
- List<ParserRecord> parser_records = new LinkedList<ParserRecord>();
-
- List<Field> size_fields = new LinkedList<Field>();
-
- private Class cls;
-
- public ObjectParser(Class cls) {
- this.cls = cls;
- }
-
- public void add(Parser p, Field... fields) {
- parser_records.add(new ParserRecord(p, fields));
- }
-
- /**
- * Create locations from the Object's fields we are interested in
- *
- * @param pr
- * @param obj
- * @return
- */
- private Location[] getLocs(Field[] fs, Object obj) {
- assert obj != null;
- Location[] locs = new Location[fs.length];
- for (int i = 0; i < locs.length; ++i) {
- locs[i] = new FieldLocation(fs[i], obj);
- }
- return locs;
- }
-
- public int parse(byte[] data, int offset, Location[] dest) {
- assert dest.length == 1;
-
- Location loc = dest[0];
-
- int parsed = 0;
- // create new object
- Object obj;
- try {
- obj = cls.newInstance();
- } catch (IllegalAccessException iae) {
- throw new RuntimeException(iae);
- } catch (InstantiationException ie) {
- throw new RuntimeException(ie);
- }
-
- for (ParserRecord pr : this.parser_records) {
- // create locations from record
- Location[] locs = getLocs(pr.args, obj);
- int x = pr.p.parse(data, offset + parsed, locs);
- assert x >= 0;
- parsed += x;
- }
-
- loc.put(obj);
-
- return parsed;
- }
-
- public int unparse(byte[] data, int offset, Location[] dest) {
- assert dest.length == 1;
- Object obj = dest[0].get();
- assert obj != null;
-
- int size = Construct.estimateSize(obj);
-
- int parsed = 0;
-
- for (ParserRecord pr : this.parser_records) {
-
- parsed += pr.p
- .unparse(data, offset + parsed, getLocs(pr.args, obj));
- }
- return parsed;
- }
-
- @Override
- public int estimateSize(Location[] args) {
-
- assert args.length == 1;
- Object obj = args[0].get();
-
- if (obj == null) {
- throw new RuntimeException(
- "cannot deserialize null-reference as object");
- }
-
- int size = 0;
- for (ParserRecord pr : this.parser_records) {
- // create locations from record
- Location[] locs = getLocs(pr.args, obj);
- int x = pr.p.estimateSize(locs);
- assert x >= 0;
- size += x;
- }
- return size;
- }
-
- public int getParserOffset(Location[] args, Parser p) {
- assert args.length == 1;
- Object obj = args[0].get();
-
- if (obj == null) {
- throw new RuntimeException(
- "cannot deserialize null-reference as object");
- }
-
- int size = 0;
- for (ParserRecord pr : this.parser_records) {
- if (pr.p == p) {
- return size;
- }
- // create locations from record
- Location[] locs = getLocs(pr.args, obj);
- int x = pr.p.estimateSize(locs);
- assert x >= 0;
- size += x;
-
- }
- throw new RuntimeException("parser not found");
- }
-}
Deleted: gnunet-java/src/org/gnunet/construct/Parser.java
===================================================================
--- gnunet-java/src/org/gnunet/construct/Parser.java 2011-11-30 15:21:36 UTC
(rev 18410)
+++ gnunet-java/src/org/gnunet/construct/Parser.java 2011-12-01 01:00:29 UTC
(rev 18411)
@@ -1,39 +0,0 @@
-package org.gnunet.construct;
-
-public interface Parser {
-
-
- /**
- *
- *
- * @param src_data
- * @param offset
- * @param dst
- * @return number of bytes parsed
- */
- public int parse(byte[] src_data, int offset, Location[] dst);
- // public int parse(byte[] src_data, int offset, Object dst); // Field 'f'
is part of parser instance
-
-
-
- /**
- *
- * @param dst_data
- * @param offset
- * @param src
- * @return number of bytes unparsed
- */
- // 'write'? 'serialize'?
- public int unparse(byte[] dst_data, int offset, Location[] src);
- // public int write(byte[] src_data, int offset, Object src); // Field 'f'
is part of parser instance
-
-
- /**
- *
- * @param args
- * @return
- */
- public int estimateSize(Location[] args); // not estimate! calculate!
- // public int sizeof(Object src); // Field 'f' is part of parser instance
-
-}
Deleted: gnunet-java/src/org/gnunet/construct/RefLocation.java
===================================================================
--- gnunet-java/src/org/gnunet/construct/RefLocation.java 2011-11-30
15:21:36 UTC (rev 18410)
+++ gnunet-java/src/org/gnunet/construct/RefLocation.java 2011-12-01
01:00:29 UTC (rev 18411)
@@ -1,37 +0,0 @@
-package org.gnunet.construct;
-
-public class RefLocation implements Location {
- private Object obj;
- private Class cls;
-
- public RefLocation() {
- this.cls = Object.class;
- }
-
- public RefLocation(Class cls) {
- this.cls = cls;
- }
-
- @Override
- public void put(Object o) {
- this.obj = o;
- }
-
- @Override
- public Object get() {
- return obj;
- }
-
- @Override
- public Class getType() {
- return cls;
- }
-
- public static Location[] makeLocationsWith(Object obj) {
- RefLocation rl = new RefLocation(obj.getClass());
- rl.put(obj);
- return new Location[]{rl};
- }
-
-
-}
Deleted: gnunet-java/src/org/gnunet/construct/SignedIntegerParser.java
===================================================================
--- gnunet-java/src/org/gnunet/construct/SignedIntegerParser.java
2011-11-30 15:21:36 UTC (rev 18410)
+++ gnunet-java/src/org/gnunet/construct/SignedIntegerParser.java
2011-12-01 01:00:29 UTC (rev 18411)
@@ -1,98 +0,0 @@
-package org.gnunet.construct;
-
-import java.math.BigInteger;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class SignedIntegerParser implements Parser {
- private static final Logger logger = LoggerFactory
- .getLogger(SignedIntegerParser.class);
-
- private final int byte_size;
-
- public SignedIntegerParser(int byte_size) {
- this.byte_size = byte_size;
- }
-
-
- public int parse(byte[] data, int offset, Location[] dest) {
- assert dest.length == 1;
-
-
-
- if (offset + byte_size > data.length) {
- throw new Construct.SizeError();
- }
-
-
-
- Location loc = dest[0];
-
- byte[] num_data = new byte[byte_size];
-
- System.arraycopy(data, offset, num_data, 0, byte_size);
- offset += byte_size;
-
- BigInteger num = new BigInteger(num_data);
-
- if (loc.getType().equals(BigInteger.class)) {
- loc.put(num);
- } else {
-
- int bit_size;
- if (loc.getType().equals(Integer.TYPE)) {
- loc.put(num.intValue());
- bit_size = 32;
- } else if (loc.getType().equals(Long.TYPE)) {
- loc.put(num.longValue());
- bit_size = 64;
- } else if (loc.getType().equals(Short.TYPE)) {
- loc.put(num.shortValue());
- bit_size = 16;
- } else if (loc.getType().equals(Byte.TYPE)) {
- loc.put(num.byteValue());
- bit_size = 8;
- } else {
- throw new RuntimeException(
- "construct: target type not supported");
- }
-
- if (num.bitLength() > bit_size) {
- logger.warn("construct: number truncated");
- }
- }
- return byte_size;
- }
-
- @Override
- public int unparse(byte[] dst_data, int offset, Location[] src) {
- assert src.length == 1;
- Object obj = src[0].get();
- BigInteger num;
-
- if (obj instanceof BigInteger) {
- num = (BigInteger) obj;
- } else if (obj instanceof Number) {
- num = BigInteger.valueOf(((Number) obj).longValue());
- } else {
- throw new RuntimeException("invalid number type");
- }
-
- // +1 for the sign
- if ((num.bitLength() + 1) > byte_size * 8) {
- throw new RuntimeException("value to large for serialization");
- }
-
- byte[] buf = num.toByteArray();
-
- System.arraycopy(buf, 0, dst_data, offset, byte_size);
-
- return byte_size;
- }
-
- @Override
- public int estimateSize(Location[] args) {
- return byte_size;
- }
-}
Deleted: gnunet-java/src/org/gnunet/construct/StringParser.java
===================================================================
--- gnunet-java/src/org/gnunet/construct/StringParser.java 2011-11-30
15:21:36 UTC (rev 18410)
+++ gnunet-java/src/org/gnunet/construct/StringParser.java 2011-12-01
01:00:29 UTC (rev 18411)
@@ -1,72 +0,0 @@
-package org.gnunet.construct;
-
-import java.io.UnsupportedEncodingException;
-
-public class StringParser implements Parser {
-
- String cset;
-
- public StringParser() {
- this.cset = "UTF-8";
- }
-
- public StringParser(String charset) {
- this.cset = charset;
- }
-
- @Override
- public int parse(byte[] src_data, int offset, Location[] dst) {
- assert dst.length == 1;
- Location loc = dst[0];
- int length = 0;
- while (src_data[offset+length] != 0) {
- length++;
- }
-
- byte[] str_data = new byte[length];
-
- System.arraycopy(src_data, offset, str_data, 0, length);
-
- String str;
- try {
- str = new String(str_data, cset);
- } catch (UnsupportedEncodingException e) {
- throw new RuntimeException();
- }
- loc.put(str);
-
- return length;
- }
-
- @Override
- public int unparse(byte[] dst_data, int offset, Location[] src) {
- String s = (String) src[0].get();
- byte[] b;
- try {
- b = s.getBytes(cset);
- } catch (UnsupportedEncodingException e) {
- throw new RuntimeException();
- }
-
- System.arraycopy(b, 0, dst_data, offset, b.length);
-
- dst_data[b.length] = (byte) 0;
-
-
- // +1 for the 0-byte
- return b.length + 1;
- }
-
- @Override
- public int estimateSize(Location[] args) {
- String s = (String) args[0].get();
- try {
- byte[] b = s.getBytes(cset);
- return b.length + 1;
- } catch (UnsupportedEncodingException e) {
- throw new RuntimeException();
- }
- }
-
-
-}
Deleted: gnunet-java/src/org/gnunet/construct/TotalSizeParser.java
===================================================================
--- gnunet-java/src/org/gnunet/construct/TotalSizeParser.java 2011-11-30
15:21:36 UTC (rev 18410)
+++ gnunet-java/src/org/gnunet/construct/TotalSizeParser.java 2011-12-01
01:00:29 UTC (rev 18411)
@@ -1,69 +0,0 @@
-package org.gnunet.construct;
-
-import java.lang.reflect.Field;
-import java.util.LinkedList;
-import java.util.List;
-
-class ParserWithField {
- Parser p;
- Field f;
-}
-
-
-public class TotalSizeParser implements Parser {
-
- ObjectParser op;
-
- List<ParserWithField> size_fields = new LinkedList<ParserWithField>();
-
- public TotalSizeParser(ObjectParser op) {
- this.op = op;
- }
-
- @Override
- public int parse(byte[] src_data, int offset, Location[] dst) {
- // the easy case, just set all size_fields to size
- int size = op.parse(src_data, offset, dst);
-
- Object o = dst[0].get();
-
- for (ParserWithField pwf : size_fields) {
- try {
- pwf.f.set(o, size);
- } catch (IllegalArgumentException e) {
- throw new RuntimeException();
- } catch (IllegalAccessException e) {
- throw new RuntimeException();
- }
- }
-
- // TODO: do sanity check on size / consistency
- return size;
- }
-
- @Override
- public int unparse(byte[] dst_data, int offset, Location[] src) {
- int size = estimateSize(src);
-
- int ret = op.unparse(dst_data, offset, src);
-
- for (ParserWithField pwf : size_fields) {
- int os = op.getParserOffset(src, pwf.p);
- pwf.p.unparse(dst_data, offset+os,
RefLocation.makeLocationsWith(size));
- }
- return ret;
- }
-
- @Override
- public int estimateSize(Location[] args) {
- return op.estimateSize(args);
- }
-
- public void addSizeField(Parser p, Field f) {
- ParserWithField pwf = new ParserWithField();
- pwf.p = p;
- pwf.f = f;
- size_fields.add(pwf);
- }
-
-}
Added: gnunet-java/src/org/gnunet/construct/UInt16.java
===================================================================
--- gnunet-java/src/org/gnunet/construct/UInt16.java
(rev 0)
+++ gnunet-java/src/org/gnunet/construct/UInt16.java 2011-12-01 01:00:29 UTC
(rev 18411)
@@ -0,0 +1,12 @@
+package org.gnunet.construct;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
address@hidden(RetentionPolicy.RUNTIME)
address@hidden(ElementType.FIELD)
+public @interface UInt16 {
+
+}
Added: gnunet-java/src/org/gnunet/construct/UInt32.java
===================================================================
--- gnunet-java/src/org/gnunet/construct/UInt32.java
(rev 0)
+++ gnunet-java/src/org/gnunet/construct/UInt32.java 2011-12-01 01:00:29 UTC
(rev 18411)
@@ -0,0 +1,12 @@
+package org.gnunet.construct;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
address@hidden(RetentionPolicy.RUNTIME)
address@hidden(ElementType.FIELD)
+public @interface UInt32 {
+
+}
Added: gnunet-java/src/org/gnunet/construct/UInt64.java
===================================================================
--- gnunet-java/src/org/gnunet/construct/UInt64.java
(rev 0)
+++ gnunet-java/src/org/gnunet/construct/UInt64.java 2011-12-01 01:00:29 UTC
(rev 18411)
@@ -0,0 +1,12 @@
+package org.gnunet.construct;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
address@hidden(RetentionPolicy.RUNTIME)
address@hidden(ElementType.FIELD)
+public @interface UInt64 {
+
+}
Added: gnunet-java/src/org/gnunet/construct/UInt8.java
===================================================================
--- gnunet-java/src/org/gnunet/construct/UInt8.java
(rev 0)
+++ gnunet-java/src/org/gnunet/construct/UInt8.java 2011-12-01 01:00:29 UTC
(rev 18411)
@@ -0,0 +1,12 @@
+package org.gnunet.construct;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
address@hidden(RetentionPolicy.RUNTIME)
address@hidden(ElementType.FIELD)
+public @interface UInt8 {
+
+}
Deleted: gnunet-java/src/org/gnunet/construct/UnsignedIntegerParser.java
===================================================================
--- gnunet-java/src/org/gnunet/construct/UnsignedIntegerParser.java
2011-11-30 15:21:36 UTC (rev 18410)
+++ gnunet-java/src/org/gnunet/construct/UnsignedIntegerParser.java
2011-12-01 01:00:29 UTC (rev 18411)
@@ -1,125 +0,0 @@
-package org.gnunet.construct;
-
-import java.math.BigInteger;
-import java.util.Arrays;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class UnsignedIntegerParser implements Parser {
- private static final Logger logger = LoggerFactory
- .getLogger(SignedIntegerParser.class);
-
- private final int byte_size;
-
- private boolean allow_sign = true;
-
- public UnsignedIntegerParser(int byte_size) {
- this.byte_size = byte_size;
- }
-
- public UnsignedIntegerParser(int byte_size, boolean allow_sign) {
- this.byte_size = byte_size;
- this.allow_sign = allow_sign;
- }
-
- public int parse(byte[] data, int offset, Location[] dest) {
- assert dest.length == 1;
-
- if (offset + byte_size > data.length) {
- throw new Construct.SizeError();
- }
-
- Location loc = dest[0];
-
- // prepend zero, if data has the sign bit set
- byte[] num_data = new byte[byte_size + 1];
-
- System.arraycopy(data, offset, num_data, 1, byte_size);
- offset += byte_size;
-
- BigInteger num = new BigInteger(num_data);
-
- if (loc.getType().equals(BigInteger.class)) {
- loc.put(num);
- } else {
-
- int bit_size;
-
- if (loc.getType().equals(Integer.TYPE)) {
- loc.put(num.intValue());
- bit_size = 32;
- } else if (loc.getType().equals(Long.TYPE)) {
- loc.put(num.longValue());
- bit_size = 64;
- } else if (loc.getType().equals(Short.TYPE)) {
- loc.put(num.shortValue());
- bit_size = 16;
- } else if (loc.getType().equals(Character.TYPE)) {
- loc.put((char) num.intValue());
- bit_size = 16;
- allow_sign = true; // data type is signed...
- } else if (loc.getType().equals(Byte.TYPE)) {
- loc.put(num.byteValue());
- bit_size = 8;
- } else {
- throw new RuntimeException(
- "construct: target type not supported: "
- + loc.getType());
- }
-
- if (allow_sign) {
- if (num.bitLength() > bit_size) {
- logger.warn("construct: number truncated");
- }
- } else {
- // +1 is because java has only signed numbers
- if (num.bitLength() + 1 > bit_size) {
- logger.warn("construct: number truncated");
- }
- }
- }
- return byte_size;
- }
-
- @Override
- public int unparse(byte[] dst_data, int offset, Location[] src) {
- assert src.length == 1;
- Object obj = src[0].get();
- assert obj != null;
-
- BigInteger num;
-
- if (obj instanceof BigInteger) {
- num = (BigInteger) obj;
- } else if (obj instanceof Number) {
- num = BigInteger.valueOf(((Number) obj).longValue());
- } else {
- throw new RuntimeException("invalid number type");
- }
-
- if (num.signum() == -1) {
- throw new RuntimeException(
- "negative value not allowed for unsigned integer");
- }
-
- if (num.bitLength() > byte_size * 8) {
- throw new RuntimeException("value to large for serialization");
- }
-
- byte[] buf = num.toByteArray();
-
- int dst_pos = offset + (byte_size - buf.length);
-
- System.arraycopy(buf, 0, dst_data, dst_pos, buf.length);
-
- Arrays.fill(dst_data, offset, dst_pos, (byte) 0);
-
- return byte_size;
- }
-
- @Override
- public int estimateSize(Location[] args) {
- return byte_size;
- }
-}
Added: gnunet-java/src/org/gnunet/construct/VariableSizeArray.java
===================================================================
--- gnunet-java/src/org/gnunet/construct/VariableSizeArray.java
(rev 0)
+++ gnunet-java/src/org/gnunet/construct/VariableSizeArray.java 2011-12-01
01:00:29 UTC (rev 18411)
@@ -0,0 +1,14 @@
+package org.gnunet.construct;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
address@hidden(RetentionPolicy.RUNTIME)
address@hidden(ElementType.FIELD)
+public @interface VariableSizeArray {
+ // set to empty string to make the array extend to fill the available
+ // space
+ String lengthField();
+}
Deleted: gnunet-java/src/org/gnunet/construct/VariableSizeArrayParser.java
===================================================================
--- gnunet-java/src/org/gnunet/construct/VariableSizeArrayParser.java
2011-11-30 15:21:36 UTC (rev 18410)
+++ gnunet-java/src/org/gnunet/construct/VariableSizeArrayParser.java
2011-12-01 01:00:29 UTC (rev 18411)
@@ -1,34 +0,0 @@
-package org.gnunet.construct;
-
-public class VariableSizeArrayParser implements Parser {
- private Parser p;
-
- public VariableSizeArrayParser(Parser p) {
- this.p = p;
- }
-
- @Override
- public int parse(byte[] src_data, int offset, Location[] dst) {
- assert dst.length == 2;
- Location loc = dst[0];
- int size = ((Integer) dst[1].get()).intValue();
-
-
-
- return 0;
- }
-
- @Override
- public int unparse(byte[] dst_data, int offset, Location[] src) {
- // TODO Auto-generated method stub
- return 0;
- }
-
- @Override
- public int estimateSize(Location[] args) {
- // TODO Auto-generated method stub
- return 0;
- }
-
-
-}
Added: gnunet-java/src/org/gnunet/construct/ZeroTerminatedString.java
===================================================================
--- gnunet-java/src/org/gnunet/construct/ZeroTerminatedString.java
(rev 0)
+++ gnunet-java/src/org/gnunet/construct/ZeroTerminatedString.java
2011-12-01 01:00:29 UTC (rev 18411)
@@ -0,0 +1,16 @@
+package org.gnunet.construct;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * Parse and unparse a zero-terminated string with the specified encoding.
+ *
+ * @author Florian Dold
+ *
+ */
address@hidden(RetentionPolicy.RUNTIME)
+public @interface ZeroTerminatedString {
+
+ String charset() default "UTF-8";
+}
Added: gnunet-java/src/org/gnunet/construct/parsers/ByteFillParser.java
===================================================================
--- gnunet-java/src/org/gnunet/construct/parsers/ByteFillParser.java
(rev 0)
+++ gnunet-java/src/org/gnunet/construct/parsers/ByteFillParser.java
2011-12-01 01:00:29 UTC (rev 18411)
@@ -0,0 +1,111 @@
+package org.gnunet.construct.parsers;
+
+import java.lang.reflect.Array;
+import java.lang.reflect.Field;
+import java.util.List;
+
+import org.gnunet.messages.Message;
+
+/**
+ * Parse an array that takes up all the available space.
+ *
+ * @author Florian Dold
+ *
+ */
+public class ByteFillParser extends FieldParser {
+ FieldParser p;
+
+ List<Field> totalSizePath;
+
+ public ByteFillParser(List<Field> totalSizePath, Field field) {
+ super(field);
+ this.totalSizePath = totalSizePath;
+ }
+
+ @Override
+ public int getSize(final Message src) {
+ return Array.getLength(getFieldValue(src));
+ }
+
+ public int getSizeFieldValue(Message m) {
+ Object obj = m;
+ for (Field f : totalSizePath) {
+
+ try {
+ obj = f.get(obj);
+ } catch (IllegalArgumentException e) {
+ throw new RuntimeException();
+ } catch (IllegalAccessException e) {
+ throw new RuntimeException();
+ }
+ }
+ return ((Number) obj).intValue();
+ }
+
+ @Override
+ public int parse(final byte[] srcData, final int offset, int frameOffset,
+ final Message dst) {
+ if (frameOffset < 0) {
+ throw new RuntimeException(
+ "cannot determine remaining message size");
+ }
+
+ int remaining = getSizeFieldValue(dst) - frameOffset;
+
+ byte[] a = new byte[remaining];
+
+ System.arraycopy(srcData, offset, a, 0, remaining);
+
+ setFieldValue(dst, a);
+
+ return frameOffset;
+ }
+
+ @Override
+ public int write(final byte[] dst_data, final int offset, final Message
src) {
+ byte[] a = (byte[]) getFieldValue(src);
+ System.arraycopy(a, 0, dst_data, offset, a.length);
+ return a.length;
+ }
+
+ @Override
+ public void patchSizeFields(Message m, int frameSize) {
+ Object obj = m;
+
+ for (int i = 0; i < totalSizePath.size() - 1; ++i) {
+
+ try {
+ obj = totalSizePath.get(i).get(obj);
+ } catch (IllegalArgumentException e) {
+ throw new RuntimeException();
+ } catch (IllegalAccessException e) {
+ throw new RuntimeException();
+ }
+
+ }
+
+ Field f = totalSizePath.get(totalSizePath.size() - 1);
+
+ try {
+ if (f.getType().equals(Long.TYPE)){
+ f.setLong(obj, frameSize);
+ } else if (f.getType().equals(Integer.TYPE)){
+ f.setInt(obj, frameSize);
+ } else if (f.getType().equals(Short.TYPE)){
+ f.setShort(obj, (short) frameSize);
+ } else if (f.getType().equals(Long.TYPE)){
+ f.setLong(obj, frameSize);
+ } else {
+ throw new RuntimeException("unexpected target type");
+ }
+
+
+ } catch (IllegalArgumentException e) {
+ throw new RuntimeException(e);
+ } catch (IllegalAccessException e) {
+ throw new RuntimeException();
+ }
+
+ }
+
+}
Copied: gnunet-java/src/org/gnunet/construct/parsers/FieldParser.java (from rev
18233, gnunet-java/src/org/gnunet/construct/Parser.java)
===================================================================
--- gnunet-java/src/org/gnunet/construct/parsers/FieldParser.java
(rev 0)
+++ gnunet-java/src/org/gnunet/construct/parsers/FieldParser.java
2011-12-01 01:00:29 UTC (rev 18411)
@@ -0,0 +1,55 @@
+package org.gnunet.construct.parsers;
+
+import java.lang.reflect.Field;
+
+import org.gnunet.messages.Message;
+
+/**
+ * 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 Object getFieldValueLong(final Object obj) {
+ try {
+ return field.getLong(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();
+ }
+ }
+}
Copied: gnunet-java/src/org/gnunet/construct/parsers/FillParser.java (from rev
18230, gnunet-java/src/org/gnunet/construct/FillParser.java)
===================================================================
--- gnunet-java/src/org/gnunet/construct/parsers/FillParser.java
(rev 0)
+++ gnunet-java/src/org/gnunet/construct/parsers/FillParser.java
2011-12-01 01:00:29 UTC (rev 18411)
@@ -0,0 +1,48 @@
+package org.gnunet.construct.parsers;
+
+import java.lang.reflect.Field;
+import java.util.List;
+
+import org.gnunet.messages.Message;
+
+/**
+ * Parse an array that takes up all the available space.
+ *
+ * @author Florian Dold
+ *
+ */
+public class FillParser extends FieldParser {
+ Parser p;
+
+ public FillParser(final Parser p, final Field f) {
+ super(f);
+ this.p = p;
+
+ }
+
+ @Override
+ public int getSize(final Message src) {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+ @Override
+ public int parse(final byte[] src_data, final int offset,
+ int frameOffset, final Message dst) {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+ @Override
+ public int write(final byte[] dst_data, final int offset, final Message
src) {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+ @Override
+ public void patchSizeFields(Message m, int frameSize) {
+ // TODO Auto-generated method stub
+
+ }
+
+}
Copied: gnunet-java/src/org/gnunet/construct/parsers/FixedSizeArrayParser.java
(from rev 18228, gnunet-java/src/org/gnunet/construct/FixedSizeArrayParser.java)
===================================================================
--- gnunet-java/src/org/gnunet/construct/parsers/FixedSizeArrayParser.java
(rev 0)
+++ gnunet-java/src/org/gnunet/construct/parsers/FixedSizeArrayParser.java
2011-12-01 01:00:29 UTC (rev 18411)
@@ -0,0 +1,85 @@
+package org.gnunet.construct.parsers;
+
+import java.lang.reflect.Array;
+import java.lang.reflect.Field;
+
+import org.gnunet.messages.Message;
+
+public class FixedSizeArrayParser extends FieldParser {
+
+ private final FieldParser elemParser;
+
+ private final int elemNumber;
+
+ public FixedSizeArrayParser(final int elemNumber,
+ final FieldParser elemParser, final Field f) {
+ super(f);
+ this.elemNumber = elemNumber;
+ this.elemParser = elemParser;
+ }
+
+ @Override
+ public int getSize(final Message srcObj) {
+ int size = 0;
+ final Object arr = getFieldValue(srcObj);
+
+ 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;
+ }
+
+ @Override
+ public int parse(final byte[] srcData, final int offset, int frameOffset,
+ final Message dstObj) {
+ int size = 0;
+
+ final Object arr = Array.newInstance(getFieldType().getComponentType(),
+ elemNumber);
+ setFieldValue(dstObj, 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();
+ }
+
+ Array.set(arr, i, elemObj);
+
+ size += elemParser.parse(srcData, offset + size,
+ frameOffset - size, elemObj);
+ }
+
+ return size;
+ }
+
+ @Override
+ public int write(final byte[] dstData, final int offset,
+ final Message srcObj) {
+ int size = 0;
+ final Object arr = getFieldValue(srcObj);
+ for (int i = 0; i < Array.getLength(arr); ++i) {
+ size += elemParser.write(dstData, offset + size,
+ (Message) Array.get(arr, i));
+ }
+ return size;
+ }
+
+ @Override
+ public void patchSizeFields(Message m, int frameSize) {
+ final Object arr = getFieldValue(m);
+ for (int i = 0; i < Array.getLength(arr); ++i) {
+ elemParser.patchSizeFields((Message) Array.get(arr, i), frameSize);
+ }
+
+ }
+}
Added: gnunet-java/src/org/gnunet/construct/parsers/IntegerParser.java
===================================================================
--- gnunet-java/src/org/gnunet/construct/parsers/IntegerParser.java
(rev 0)
+++ gnunet-java/src/org/gnunet/construct/parsers/IntegerParser.java
2011-12-01 01:00:29 UTC (rev 18411)
@@ -0,0 +1,123 @@
+package org.gnunet.construct.parsers;
+
+import java.lang.reflect.Field;
+import java.math.BigInteger;
+
+import org.gnunet.messages.Message;
+
+public class IntegerParser extends FieldParser {
+ private final int byteSize;
+
+ public static final boolean UNSIGNED = false;
+ public static final boolean SIGNED = true;
+
+ private final boolean isSigned;
+
+ static enum FieldType {
+ BIGNUM, BYTE_PRIM, SHORT_PRIM, INT_PRIM, LONG_PRIM
+ }
+
+ private FieldType ft;
+
+ public IntegerParser(final int byteSize, final boolean isSigned,
+ final Field f) {
+ super(f);
+ this.byteSize = byteSize;
+ this.isSigned = isSigned;
+
+ if (f.getType().equals(BigInteger.class)) {
+ ft = FieldType.BIGNUM;
+ } else if (f.getType().equals(Long.TYPE)) {
+ ft = FieldType.LONG_PRIM;
+ } else if (f.getType().equals(Short.TYPE)) {
+ ft = FieldType.SHORT_PRIM;
+ } else if (f.getType().equals(Integer.TYPE)) {
+ ft = FieldType.INT_PRIM;
+ } else {
+ throw new RuntimeException("target type not supported");
+ }
+ }
+
+ @Override
+ public int getSize(final Message srcObj) {
+ return byteSize;
+ }
+
+ @Override
+ public int parse(final byte[] srcData, int offset, int frameOffset, final
Message dstObj) {
+ byte[] numData;
+
+ if (isSigned) {
+ numData = new byte[byteSize];
+ System.arraycopy(srcData, offset, numData, 0, byteSize);
+ } else {
+ numData = new byte[byteSize + 1];
+ System.arraycopy(srcData, offset, numData, 1, byteSize);
+ }
+ offset += byteSize;
+
+ final BigInteger num = new BigInteger(numData);
+
+ try {
+
+ switch (ft) {
+ case SHORT_PRIM:
+ field.setShort(dstObj, num.shortValue());
+ break;
+ case INT_PRIM:
+ field.setInt(dstObj, num.intValue());
+ break;
+ case LONG_PRIM:
+ field.setLong(dstObj, num.longValue());
+ break;
+ default:
+ throw new RuntimeException("invalid member type");
+ }
+
+ } catch (IllegalArgumentException e) {
+ throw new RuntimeException();
+ } catch (IllegalAccessException e) {
+ throw new RuntimeException();
+ }
+
+ return byteSize;
+ }
+
+ @Override
+ public int write(final byte[] dstData, final int offset,
+ final Message srcObj) {
+ BigInteger num;
+
+ try {
+ switch (ft) {
+ case INT_PRIM:
+ num = BigInteger.valueOf(field.getInt(srcObj));
+ break;
+ case SHORT_PRIM:
+ num = BigInteger.valueOf(field.getShort(srcObj));
+ break;
+ case LONG_PRIM:
+ num = BigInteger.valueOf(field.getLong(srcObj));
+ break;
+ default:
+ throw new RuntimeException("invalid member type: ");
+ }
+ } catch (IllegalArgumentException e) {
+ throw new RuntimeException();
+ } catch (IllegalAccessException e) {
+ throw new RuntimeException();
+ }
+
+ final byte[] numData = num.toByteArray();
+
+ System.arraycopy(numData, 0, dstData, offset
+ + (byteSize - numData.length), numData.length);
+
+ return byteSize;
+ }
+
+ @Override
+ public void patchSizeFields(Message m, int frameSize) {
+ return;
+ }
+}
Added: gnunet-java/src/org/gnunet/construct/parsers/NestedParser.java
===================================================================
--- gnunet-java/src/org/gnunet/construct/parsers/NestedParser.java
(rev 0)
+++ gnunet-java/src/org/gnunet/construct/parsers/NestedParser.java
2011-12-01 01:00:29 UTC (rev 18411)
@@ -0,0 +1,48 @@
+package org.gnunet.construct.parsers;
+
+import java.lang.reflect.Field;
+
+import org.gnunet.messages.Message;
+
+public class NestedParser extends FieldParser {
+ private final Parser nestedParser;
+
+ public NestedParser(final Parser p, final Field f) {
+ super(f);
+ this.nestedParser = p;
+ }
+
+ @Override
+ public int getSize(final Message src) {
+ return nestedParser.getSize((Message) getFieldValue(src));
+ }
+
+ @Override
+ public int parse(final byte[] src_data, final int offset,
+ int frameOffset, final Message dstObj) {
+ try {
+ setFieldValue(dstObj, getFieldType().newInstance());
+ } catch (InstantiationException e) {
+ throw new RuntimeException();
+ } catch (IllegalAccessException e) {
+ throw new RuntimeException();
+ }
+
+ return nestedParser.parse(src_data, offset, frameOffset,
+ (Message) getFieldValue(dstObj));
+ }
+
+ @Override
+ public int write(final byte[] dst_data, final int offset, final Message
src) {
+ return nestedParser.write(dst_data, offset,
+ (Message) getFieldValue(src));
+ }
+
+ @Override
+ public void patchSizeFields(Message m, int frameSize) {
+ // todo: nested/opaque frames
+ nestedParser.patchSizeFields(m, frameSize);
+
+ }
+
+}
Added: gnunet-java/src/org/gnunet/construct/parsers/Parser.java
===================================================================
--- gnunet-java/src/org/gnunet/construct/parsers/Parser.java
(rev 0)
+++ gnunet-java/src/org/gnunet/construct/parsers/Parser.java 2011-12-01
01:00:29 UTC (rev 18411)
@@ -0,0 +1,37 @@
+package org.gnunet.construct.parsers;
+
+import org.gnunet.messages.Message;
+
+
+public interface Parser {
+ /**
+ * Compute the exact size of the object's binary representation in bytes.
+ *
+ * @param srcObj
+ * @return
+ */
+ public int getSize(Message srcObj);
+
+ /**
+ *
+ * @param srcData
+ * @param offset
+ * @param frameOffset
+ * @param dstObj
+ * @return
+ */
+ public int parse(byte[] srcData, int offset, int frameOffset, Message
dstObj);
+
+
+ /**
+ *
+ * @param dstData
+ * @param offset
+ * @param srcObj
+ * @return
+ */
+ public int write(byte[] dstData, int offset, Message srcObj);
+
+ public void patchSizeFields(Message m, int frameSize);
+
+}
Copied: gnunet-java/src/org/gnunet/construct/parsers/SequenceParser.java (from
rev 18228, gnunet-java/src/org/gnunet/construct/ObjectParser.java)
===================================================================
--- gnunet-java/src/org/gnunet/construct/parsers/SequenceParser.java
(rev 0)
+++ gnunet-java/src/org/gnunet/construct/parsers/SequenceParser.java
2011-12-01 01:00:29 UTC (rev 18411)
@@ -0,0 +1,56 @@
+package org.gnunet.construct.parsers;
+
+import java.lang.reflect.Field;
+import java.util.LinkedList;
+import java.util.List;
+
+import org.gnunet.messages.Message;
+
+public class SequenceParser extends FieldParser {
+
+ private final List<FieldParser> childParsers = new
LinkedList<FieldParser>();
+
+ public SequenceParser(final Field f) {
+ super(f);
+ }
+
+ public void add(final FieldParser p) {
+ childParsers.add(p);
+ }
+
+ @Override
+ public int getSize(final Message src) {
+ int size = 0;
+ for (final FieldParser p : childParsers) {
+ size += p.getSize(src);
+ }
+ return size;
+ }
+
+ @Override
+ public int parse(final byte[] src_data, final int offset, int frameOffset,
+ final Message dst) {
+ int size = 0;
+ for (final FieldParser p : childParsers) {
+ size += p.parse(src_data, offset + size, frameOffset + size, dst);
+ }
+ return size;
+ }
+
+ @Override
+ public int write(final byte[] dst_data, final int offset, final Message
src) {
+ int size = 0;
+ for (final FieldParser p : childParsers) {
+ size += p.write(dst_data, offset + size, src);
+ }
+ return size;
+ }
+
+ @Override
+ public void patchSizeFields(Message m, int frameSize) {
+ for (final FieldParser p : childParsers) {
+ p.patchSizeFields(m, frameSize);
+ }
+
+ }
+}
Copied: gnunet-java/src/org/gnunet/construct/parsers/StringParser.java (from
rev 18228, gnunet-java/src/org/gnunet/construct/StringParser.java)
===================================================================
--- gnunet-java/src/org/gnunet/construct/parsers/StringParser.java
(rev 0)
+++ gnunet-java/src/org/gnunet/construct/parsers/StringParser.java
2011-12-01 01:00:29 UTC (rev 18411)
@@ -0,0 +1,77 @@
+package org.gnunet.construct.parsers;
+
+import java.io.UnsupportedEncodingException;
+import java.lang.reflect.Field;
+
+import org.gnunet.messages.Message;
+
+public class StringParser extends FieldParser {
+
+ String cset;
+
+ public StringParser(final String charset, final Field f) {
+ super(f);
+ this.cset = charset;
+ }
+
+ @Override
+ public int getSize(final Message srcObj) {
+ final String s = (String) getFieldValue(srcObj);
+ try {
+ final byte[] b = s.getBytes(cset);
+ return b.length + 1;
+ } catch (final UnsupportedEncodingException e) {
+ throw new RuntimeException();
+ }
+ }
+
+ @Override
+ public int parse(final byte[] srcData, final int offset, int frameOffset,
final Message dstObj) {
+ int length = 0;
+ while (srcData[offset + length] != 0) {
+ length++;
+ }
+
+
+ final byte[] stringData = new byte[length];
+
+ System.arraycopy(srcData, offset, stringData, 0, length);
+
+ String str;
+ try {
+ str = new String(stringData, cset);
+ } catch (final UnsupportedEncodingException e) {
+ throw new RuntimeException();
+ }
+
+ setFieldValue(dstObj, str);
+
+ return length + 1;
+ }
+
+ @Override
+ public int write(final byte[] dstData, final int offset, final Message
srcObj) {
+ final String s = (String) getFieldValue(srcObj);
+ byte[] b;
+ try {
+ b = s.getBytes(cset);
+ } catch (final UnsupportedEncodingException e) {
+ throw new RuntimeException();
+ }
+
+ System.arraycopy(b, 0, dstData, offset, b.length);
+
+ System.out.println(b.length);
+
+ dstData[offset + b.length] = (byte) 0;
+
+ // +1 for the 0-byte
+ return b.length + 1;
+ }
+
+ @Override
+ public void patchSizeFields(Message m, int frameSize) {
+ return;
+ }
+
+}
Copied:
gnunet-java/src/org/gnunet/construct/parsers/VariableSizeArrayParser.java (from
rev 18223, gnunet-java/src/org/gnunet/construct/VariableSizeArrayParser.java)
===================================================================
--- gnunet-java/src/org/gnunet/construct/parsers/VariableSizeArrayParser.java
(rev 0)
+++ gnunet-java/src/org/gnunet/construct/parsers/VariableSizeArrayParser.java
2011-12-01 01:00:29 UTC (rev 18411)
@@ -0,0 +1,89 @@
+package org.gnunet.construct.parsers;
+
+import java.lang.reflect.Array;
+import java.lang.reflect.Field;
+
+import org.gnunet.messages.Message;
+
+public class VariableSizeArrayParser extends FieldParser {
+ private final FieldParser elemParser;
+ private Field sizeField;
+
+
+ public VariableSizeArrayParser(final FieldParser elemParser, Field
sizeField, Field arrayField) {
+ super(arrayField);
+ this.elemParser = elemParser;
+ this.sizeField = sizeField;
+ }
+
+ @Override
+ public int getSize(final Message src) {
+ int size = 0;
+ final Object arr = getFieldValue(src);
+
+ 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;
+ }
+
+ @Override
+ public int parse(final byte[] srcData, final int offset, int frameOffset,
final Message dstObj) {
+ int elemNumber;
+ try {
+ elemNumber = ((Number) sizeField.get(dstObj)).intValue();
+ } catch (IllegalArgumentException e1) {
+ throw new RuntimeException();
+ } catch (IllegalAccessException e1) {
+ throw new RuntimeException();
+ }
+
+ int size = 0;
+
+ final Object arr = Array.newInstance(getFieldType().getComponentType(),
+ elemNumber);
+ setFieldValue(dstObj, 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();
+ }
+
+ Array.set(arr, i, elemObj);
+
+ size += elemParser.parse(srcData, offset + size,
+ frameOffset - size, elemObj);
+ }
+
+ return size;
+ }
+
+ @Override
+ public int write(final byte[] dstData, final int offset, final Message
src) {
+ int size = 0;
+ final Object arr = getFieldValue(src);
+ for (int i = 0; i < Array.getLength(arr); ++i) {
+ size += elemParser.write(dstData, offset + size,
+ (Message) Array.get(arr, i));
+ }
+ return size;
+ }
+
+ @Override
+ public void patchSizeFields(Message m, int frameSize) {
+ //XXX: should this patch the length field, too?
+ return;
+ }
+
+}
Deleted: gnunet-java/src/org/gnunet/messages/ComplexTestMessage.java
===================================================================
--- gnunet-java/src/org/gnunet/messages/ComplexTestMessage.java 2011-11-30
15:21:36 UTC (rev 18410)
+++ gnunet-java/src/org/gnunet/messages/ComplexTestMessage.java 2011-12-01
01:00:29 UTC (rev 18411)
@@ -1,92 +0,0 @@
-package org.gnunet.messages;
-
-import org.gnunet.construct.Construct.FixedSizeArray;
-import org.gnunet.construct.Construct.Nested;
-import org.gnunet.construct.Construct.TotalSize;
-import org.gnunet.construct.Construct.UnsignedInteger;
-import org.gnunet.construct.Construct.VariableSizeArray;
-import org.gnunet.construct.Construct.ZeroTerminatedString;
-import org.gnunet.construct.FixedSizeArrayParser;
-import org.gnunet.construct.ObjectParser;
-import org.gnunet.construct.StringParser;
-import org.gnunet.construct.UnsignedIntegerParser;
-import org.gnunet.construct.VariableSizeArrayParser;
-
-public class ComplexTestMessage implements Message {
-
- @UnsignedInteger(2)
- int someNumber;
-
- @FixedSizeArray(length = 5)
- @UnsignedInteger(2) // BAD!
- int[] someArray;
-
- // @FixedSizeArrayUint32_t(length = 5)
- int[] someArray3;
-
-
- @FixedSizeArray(length = 5)
- UnsignedIntegerBox[] someArray2;
-
- static class UnsignedIntegerBox implements Message {
- @UnsignedInteger(2)
- int my_value;
- }
-
- @FixedSizeArray(length = 5)
- SimpleTestMessage[] someArray5;
-
-
- @Nested
- SimpleTestMessage msg;
-
-
- @UnsignedInteger(2)
- int stringTableSize;
-
- @VariableSizeArray(lengthField = "stringTableSize")
- @ZeroTerminatedString(charset = "UTF-8")
- String[] stringTable;
-
-
- @TotalSize
- int mySize;
-
- @TotalSize
- @UnsignedInteger(2)
- int storedMySize;
-
-
-
- // this should work fully automatic
- public static ObjectParser makeParser() throws SecurityException,
- NoSuchFieldException {
-
- ObjectParser p = new ObjectParser(ComplexTestMessage.class);
-
- p.add(new UnsignedIntegerParser(2),
- ComplexTestMessage.class.getField("someNumber"));
-
- FixedSizeArrayParser ap = new FixedSizeArrayParser(5,
- new UnsignedIntegerParser(2));
-
- p.add(ap, ComplexTestMessage.class.getField("someArray"));
-
- VariableSizeArrayParser lp = new VariableSizeArrayParser(
- new StringParser());
-
- // arguments: resulting array, array length
- p.add(lp, ComplexTestMessage.class.getField("stringTable"),
- ComplexTestMessage.class.getField("stringTableSize"));
-
- //p.addSizeField(ComplexTestMessage.class.getField("mySize"));
-
- p.add(new UnsignedIntegerParser(2),
- ComplexTestMessage.class.getField("storedMySize"));
-
- //p.addSizeField(ComplexTestMessage.class.getField("storedMySize"));
-
- return p;
- }
-
-}
Modified: gnunet-java/src/org/gnunet/messages/Message.java
===================================================================
--- gnunet-java/src/org/gnunet/messages/Message.java 2011-11-30 15:21:36 UTC
(rev 18410)
+++ gnunet-java/src/org/gnunet/messages/Message.java 2011-12-01 01:00:29 UTC
(rev 18411)
@@ -1,8 +1,9 @@
package org.gnunet.messages;
/**
- * Base interface for all messages (anything that 'Construct' can serialize or
deserialize).
- * Really just an annotation, but also for sanity checking by the compiler.
+ * Base interface for all messages (anything that 'Construct' can serialize or
+ * deserialize). Really just an annotation, but also for sanity checking by the
+ * compiler.
*/
public interface Message {
}
Modified: gnunet-java/src/org/gnunet/messages/MessageHeader.java
===================================================================
--- gnunet-java/src/org/gnunet/messages/MessageHeader.java 2011-11-30
15:21:36 UTC (rev 18410)
+++ gnunet-java/src/org/gnunet/messages/MessageHeader.java 2011-12-01
01:00:29 UTC (rev 18411)
@@ -1,20 +1,15 @@
package org.gnunet.messages;
-import org.gnunet.construct.Construct.TotalSize;
-import org.gnunet.construct.Construct.UnsignedInteger;
+import org.gnunet.construct.FrameSize;
+import org.gnunet.construct.UInt16;
public class MessageHeader implements Message {
- @TotalSize
- // @UnsignedInteger(2)
- public int size;
-
- @UnsignedInteger(2)
+ @FrameSize
+ @UInt16
+ public int size;
+
+ @UInt16
public int type;
-
-
- // @Fill
- // @UnsignedInteger(1)
- // public byte[] body;
-
+
}
Modified: gnunet-java/src/org/gnunet/messages/QueryMessage.java
===================================================================
--- gnunet-java/src/org/gnunet/messages/QueryMessage.java 2011-11-30
15:21:36 UTC (rev 18410)
+++ gnunet-java/src/org/gnunet/messages/QueryMessage.java 2011-12-01
01:00:29 UTC (rev 18411)
@@ -1,35 +1,17 @@
package org.gnunet.messages;
-import org.gnunet.construct.Construct.Fill;
-import org.gnunet.construct.Construct.Nested;
-import org.gnunet.construct.Construct.UnsignedInteger;
+import org.gnunet.construct.ByteFill;
+import org.gnunet.construct.Nested;
+import org.gnunet.construct.UInt8;
public class QueryMessage implements Message {
-
- @Nested(header = true)
- MessageHeader header;
-
- @UnsignedInteger(2)
- int query;
@Nested
- MessageBar embedded;
+ public MessageHeader header;
- @Fill
- public char[] varsize;
-
-
- static class MessageBar implements Message
- {
+ @UInt8
+ public int query;
- @Nested(header = true)
- MessageHeader header;
-
- @UnsignedInteger(2)
- int query;
-
- @Fill
- public char[] varsize;
-
- }
+ @ByteFill
+ public byte[] varsize;
}
Modified: gnunet-java/src/org/gnunet/messages/RelativeTimeNBO.java
===================================================================
--- gnunet-java/src/org/gnunet/messages/RelativeTimeNBO.java 2011-11-30
15:21:36 UTC (rev 18410)
+++ gnunet-java/src/org/gnunet/messages/RelativeTimeNBO.java 2011-12-01
01:00:29 UTC (rev 18411)
@@ -1,22 +1,22 @@
package org.gnunet.messages;
-import org.gnunet.construct.Construct.UnsignedInteger;
+import org.gnunet.construct.UInt8;
import org.gnunet.util.RelativeTime;
-public class RelativeTimeNBO implements Message {
+public class RelativeTimeNBO implements Message {
/**
* Value__ still in Java-byte order, needs to be converted to Network byte
* order by the Construct class.
*/
- @UnsignedInteger(8)
+ @UInt8
public long value__;
- public RelativeTimeNBO(long value) {
+ public RelativeTimeNBO(final long value) {
this.value__ = value;
}
-
- public RelativeTimeNBO(RelativeTime t) {
+
+ public RelativeTimeNBO(final RelativeTime t) {
if (t.equals(RelativeTime.FOREVER)) {
this.value__ = -1;
} else {
Modified: gnunet-java/src/org/gnunet/messages/SimpleTestMessage.java
===================================================================
--- gnunet-java/src/org/gnunet/messages/SimpleTestMessage.java 2011-11-30
15:21:36 UTC (rev 18410)
+++ gnunet-java/src/org/gnunet/messages/SimpleTestMessage.java 2011-12-01
01:00:29 UTC (rev 18411)
@@ -1,29 +1,20 @@
package org.gnunet.messages;
-import org.gnunet.construct.Construct.Nested;
-import org.gnunet.construct.Construct.SignedInteger;
-import org.gnunet.construct.Construct.UnsignedInteger;
+import org.gnunet.construct.FixedSizeArray;
+import org.gnunet.construct.Nested;
+import org.gnunet.construct.UInt8;
-public class SimpleTestMessage {
-
- @UnsignedInteger(2)
+public class SimpleTestMessage implements Message {
+
+ @UInt8
public short v1;
-
- @SignedInteger(2)
+
+ @UInt8
public short v2;
-
+
@Nested
public SimpleTestMessage2 mn;
-
-
- @Override
- public boolean equals(Object obj) {
- if (!(obj instanceof SimpleTestMessage)) {
- return false;
- }
- SimpleTestMessage other = (SimpleTestMessage) obj;
-
- return v1 == other.v1 && v2 == other.v2 && mn.equals(other.mn);
- }
+ @FixedSizeArray(length=5)
+ public SimpleTestMessage2[] mns;
}
Modified: gnunet-java/src/org/gnunet/messages/SimpleTestMessage2.java
===================================================================
--- gnunet-java/src/org/gnunet/messages/SimpleTestMessage2.java 2011-11-30
15:21:36 UTC (rev 18410)
+++ gnunet-java/src/org/gnunet/messages/SimpleTestMessage2.java 2011-12-01
01:00:29 UTC (rev 18411)
@@ -1,23 +1,11 @@
package org.gnunet.messages;
-import org.gnunet.construct.Construct.UnsignedInteger;
+import org.gnunet.construct.UInt32;
+import org.gnunet.construct.ZeroTerminatedString;
-public class SimpleTestMessage2 {
-
- @UnsignedInteger(4)
+public class SimpleTestMessage2 implements Message {
+
+ @UInt32
public long value;
-
- //@VariableSizeArray("v1")
- //int[] arr;
-
-
- @Override
- public boolean equals(Object obj) {
- if (!(obj instanceof SimpleTestMessage2)) {
- return false;
- }
- SimpleTestMessage2 stm2 = (SimpleTestMessage2) obj;
- return value == stm2.value;
- }
}
Modified: gnunet-java/src/org/gnunet/messages/SizeTestMessage.java
===================================================================
--- gnunet-java/src/org/gnunet/messages/SizeTestMessage.java 2011-11-30
15:21:36 UTC (rev 18410)
+++ gnunet-java/src/org/gnunet/messages/SizeTestMessage.java 2011-12-01
01:00:29 UTC (rev 18411)
@@ -1,15 +1,18 @@
package org.gnunet.messages;
-import org.gnunet.construct.Construct.TotalSize;
-import org.gnunet.construct.Construct.UnsignedInteger;
+import org.gnunet.construct.ByteFill;
+import org.gnunet.construct.FrameSize;
+import org.gnunet.construct.UInt16;
-public class SizeTestMessage {
+public class SizeTestMessage implements Message {
+
+ @FrameSize
+ @UInt16
+ public long totalSize;
+
+ @UInt16
+ public long someValue;
- @TotalSize
- @UnsignedInteger(2)
- public long total_size;
-
- @UnsignedInteger
- public long someValue;
-
+ @ByteFill
+ public byte[] rest;
}
Added: gnunet-java/src/org/gnunet/messages/StringMessage.java
===================================================================
--- gnunet-java/src/org/gnunet/messages/StringMessage.java
(rev 0)
+++ gnunet-java/src/org/gnunet/messages/StringMessage.java 2011-12-01
01:00:29 UTC (rev 18411)
@@ -0,0 +1,15 @@
+package org.gnunet.messages;
+
+import org.gnunet.construct.UInt8;
+import org.gnunet.construct.ZeroTerminatedString;
+
+public class StringMessage implements Message {
+ @UInt8
+ public int num;
+
+ @ZeroTerminatedString
+ public String str;
+
+ @UInt8
+ public int num2;
+}
Deleted: gnunet-java/src/org/gnunet/messages/StringTestMessage.java
===================================================================
--- gnunet-java/src/org/gnunet/messages/StringTestMessage.java 2011-11-30
15:21:36 UTC (rev 18410)
+++ gnunet-java/src/org/gnunet/messages/StringTestMessage.java 2011-12-01
01:00:29 UTC (rev 18411)
@@ -1,9 +0,0 @@
-package org.gnunet.messages;
-
-import org.gnunet.construct.Construct.ZeroTerminatedString;
-
-
-public class StringTestMessage {
- @ZeroTerminatedString
- public String s;
-}
Deleted: gnunet-java/src/org/gnunet/messages/TestMessage3.java
===================================================================
--- gnunet-java/src/org/gnunet/messages/TestMessage3.java 2011-11-30
15:21:36 UTC (rev 18410)
+++ gnunet-java/src/org/gnunet/messages/TestMessage3.java 2011-12-01
01:00:29 UTC (rev 18411)
@@ -1,11 +0,0 @@
-package org.gnunet.messages;
-
-import org.gnunet.construct.Construct.FixedSizeArray;
-import org.gnunet.construct.Construct.UnsignedInteger;
-
-public class TestMessage3 {
-
- @FixedSizeArray(length=10)
- @UnsignedInteger(2)
- public int[] arr;
-}
Deleted: gnunet-java/src/org/gnunet/messages/TestMessage4.java
===================================================================
--- gnunet-java/src/org/gnunet/messages/TestMessage4.java 2011-11-30
15:21:36 UTC (rev 18410)
+++ gnunet-java/src/org/gnunet/messages/TestMessage4.java 2011-12-01
01:00:29 UTC (rev 18411)
@@ -1,16 +0,0 @@
-package org.gnunet.messages;
-
-import org.gnunet.construct.Construct.FixedSizeArray;
-import org.gnunet.construct.Construct.Nested;
-import org.gnunet.construct.Construct.UnsignedInteger;
-
-public class TestMessage4 {
-
- @UnsignedInteger(2)
- public int value;
-
- @FixedSizeArray(length=3)
- @Nested
- public TestMessage3[] tm3s;
-
-}
Modified: gnunet-java/src/org/gnunet/service/StatisticsService.java
===================================================================
--- gnunet-java/src/org/gnunet/service/StatisticsService.java 2011-11-30
15:21:36 UTC (rev 18410)
+++ gnunet-java/src/org/gnunet/service/StatisticsService.java 2011-12-01
01:00:29 UTC (rev 18411)
@@ -1,4 +1,3 @@
-
/*
* The stuff below does nothing whatsoever, first milestone of
* this project is to implement the StatisticsService api
@@ -16,117 +15,119 @@
public class StatisticsService {
- interface Iterator {
- public int call(String subsystem, String name, int value,
boolean is_persistent);
- }
+ enum ActionType {
+ GET, SET, WATCH, UPDATE
+ }
- interface Callback {
-
- }
-
- enum ActionType {GET,SET,WATCH,UPDATE};
+ interface Callback {
- class GetHandle {
- private StatisticsService sh;
- private String subsystem;
- private String name;
- private Callback cont;
- private Iterator proc;
- private AbsoluteTime timeout;
- private ActionType type;
- private int msize;
- void cancel() {
- throw new UnsupportedOperationException();
- }
- }
-
- private class WatchEntry {
- String subssytem;
- String name;
- Iterator proc;
- public WatchEntry(String subssytem, String name, Iterator proc)
{
- this.subssytem = subssytem;
- this.name = name;
- this.proc = proc;
- }
- }
-
-
-
- private Client client;
- private RelativeTime backoff;
-
- private String subsystem;
- private Configuration cfg;
-
- LinkedList<WatchEntry> watches;
-
- LinkedList<GetHandle> actions;
-
- GetHandle currentAction;
-
- Client.TransmitHandle th;
-
+ }
- public StatisticsService(String subsystem, Configuration cfg) {
- this.backoff = new RelativeTime(1);
- this.subsystem = subsystem;
- this.cfg = cfg;
- this.client = new Client("statistics", cfg);
- this.watches = new LinkedList<StatisticsService.WatchEntry>();
- this.actions = new LinkedList<StatisticsService.GetHandle>();
- }
-
+ class GetHandle {
+ private StatisticsService sh;
+ private String subsystem;
+ private String name;
+ private Callback cont;
+ private Iterator proc;
+ private AbsoluteTime timeout;
+ private ActionType type;
+ private int msize;
- public void watch(String subsystem, String name, Iterator cb) {
- throw new UnsupportedOperationException();
- /*
- WatchEntry w = new WatchEntry(subsystem, name, cb);
- this.watches.add(w);
- scheduleWatchRequest(w);
- */
- }
+ void cancel() {
+ throw new UnsupportedOperationException();
+ }
+ };
-
-
+ interface Iterator {
+ public int call(String subsystem, String name, int value,
+ boolean is_persistent);
+ }
- public GetHandle get(String subsystem, String name, RelativeTime
timeout,
- Callback cb, Iterator it) {
- GetHandle h = new GetHandle();
- h.sh = this;
- h.subsystem = subsystem;
- h.name = name;
- h.cont = cb;
- h.proc = it;
- h.type = ActionType.GET;
- insertGetHandle(h);
- return h;
- }
-
- private void insertGetHandle(GetHandle h) {
- actions.add(h);
- if (h == actions.getFirst()) {
- scheduleAction();
- }
- }
-
- private void scheduleAction() {
- if (currentAction != null) {
- return;
- }
- // XXX: What about reconnect stuff?
- currentAction = actions.removeFirst();
- // XXX: what about destruction?
- this.th = client.notifyTransmitReady(currentAction.msize,
/*XXX:dummy*/ null, true, /*XXX:dummy*/ null);
-
- // XXX totally incomplete
- }
+ private class WatchEntry {
+ String subssytem;
+ String name;
+ Iterator proc;
- public void set(String name, int value, boolean make_persistent) {
- throw new UnsupportedOperationException();
- }
+ public WatchEntry(final String subssytem, final String name,
+ final Iterator proc) {
+ this.subssytem = subssytem;
+ this.name = name;
+ this.proc = proc;
+ }
+ }
- public void update(String name, int delta, boolean make_persistent) {
- throw new UnsupportedOperationException();
- }
+ private final Client client;
+ private final RelativeTime backoff;
+
+ private final String subsystem;
+ private final Configuration cfg;
+
+ LinkedList<WatchEntry> watches;
+
+ LinkedList<GetHandle> actions;
+
+ GetHandle currentAction;
+
+ Client.TransmitHandle th;
+
+ public StatisticsService(final String subsystem, final Configuration cfg) {
+ this.backoff = new RelativeTime(1);
+ this.subsystem = subsystem;
+ this.cfg = cfg;
+ this.client = new Client("statistics", cfg);
+ this.watches = new LinkedList<StatisticsService.WatchEntry>();
+ this.actions = new LinkedList<StatisticsService.GetHandle>();
+ }
+
+ public GetHandle get(final String subsystem, final String name,
+ final RelativeTime timeout, final Callback cb, final Iterator it) {
+ final GetHandle h = new GetHandle();
+ h.sh = this;
+ h.subsystem = subsystem;
+ h.name = name;
+ h.cont = cb;
+ h.proc = it;
+ h.type = ActionType.GET;
+ insertGetHandle(h);
+ return h;
+ }
+
+ private void insertGetHandle(final GetHandle h) {
+ actions.add(h);
+ if (h == actions.getFirst()) {
+ scheduleAction();
+ }
+ }
+
+ private void scheduleAction() {
+ if (currentAction != null) {
+ return;
+ }
+ // XXX: What about reconnect stuff?
+ currentAction = actions.removeFirst();
+ // XXX: what about destruction?
+ this.th = client.notifyTransmitReady(currentAction.msize, /* XXX:dummy
*/
+ null, true, /* XXX:dummy */null);
+
+ // XXX totally incomplete
+ }
+
+ public void set(final String name, final int value,
+ final boolean make_persistent) {
+ throw new UnsupportedOperationException();
+ }
+
+ public void update(final String name, final int delta,
+ final boolean make_persistent) {
+ throw new UnsupportedOperationException();
+ }
+
+ public void watch(final String subsystem, final String name,
+ final Iterator cb) {
+ throw new UnsupportedOperationException();
+ /*
+ * WatchEntry w = new WatchEntry(subsystem, name, cb);
+ * this.watches.add(w); scheduleWatchRequest(w);
+ */
+ }
}
Modified: gnunet-java/src/org/gnunet/util/AbsoluteTime.java
===================================================================
--- gnunet-java/src/org/gnunet/util/AbsoluteTime.java 2011-11-30 15:21:36 UTC
(rev 18410)
+++ gnunet-java/src/org/gnunet/util/AbsoluteTime.java 2011-12-01 01:00:29 UTC
(rev 18411)
@@ -16,14 +16,13 @@
along with GNUnet; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.
-*/
+ */
package org.gnunet.util;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-
/**
* A specific point in time.
*
@@ -38,7 +37,14 @@
private static long offset = 0;
- private final long abs_value;
+ /**
+ * Gets the current time.
+ *
+ * @return the current time
+ */
+ public static AbsoluteTime now() {
+ return new AbsoluteTime(System.currentTimeMillis() + offset);
+ }
/**
* Sets the timestamp offset for this instance.
@@ -50,51 +56,31 @@
AbsoluteTime.offset = offset;
}
- /**
- * Gets the current time.
- *
- * @return the current time
- */
- public static AbsoluteTime now() {
- return new AbsoluteTime(System.currentTimeMillis() + offset);
- }
+ private final long abs_value;
public AbsoluteTime(final long abs_value) {
this.abs_value = abs_value;
}
-
/**
- * Returns the milliseconds since some fixed point of reference.
+ * Adds a relative time value to an absolute time.
*
- * @return the absolute time in milliseconds
+ * @param duration
+ * @return this + duration
*/
- public long getMilliseconds() {
- return abs_value;
+ public AbsoluteTime add(final RelativeTime duration) {
+ if (abs_value == Long.MAX_VALUE
+ || duration.getMilliseconds() == Long.MAX_VALUE) {
+ return this;
+ }
+ if (abs_value + duration.getMilliseconds() < abs_value) {
+ logger.warn("time overflow");
+ return AbsoluteTime.FOREVER;
+ }
+ return new AbsoluteTime(abs_value + duration.getMilliseconds());
}
/**
- * Returns the minimum of two time values.
- *
- * @param other
- * @return min(this,other)
- */
- public AbsoluteTime min(final AbsoluteTime other) {
- return (abs_value <= other.abs_value) ? this : other;
- }
-
- /**
- * Returns the maximum of two time values.
- *
- * @param other
- * @return max(this,other)
- */
- public AbsoluteTime max(final AbsoluteTime other) {
- return (abs_value >= other.abs_value) ? this : other;
-
- }
-
- /**
* Calculates the estimate time of arrival/completion for an operation.
*
* @param start
@@ -115,11 +101,17 @@
return RelativeTime.FOREVER;
}
final RelativeTime dur = start.getDuration();
- final double exp = ((double) dur.getMilliseconds()) * ((double) total)
+ final double exp = (double) dur.getMilliseconds() * (double) total
/ finished;
return new RelativeTime((long) exp);
}
+ @Override
+ public int compareTo(final Object o) {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
/**
* Calculates the difference between two absolute times.
*
@@ -148,6 +140,15 @@
}
/**
+ * Returns the milliseconds since some fixed point of reference.
+ *
+ * @return the absolute time in milliseconds
+ */
+ public long getMilliseconds() {
+ return abs_value;
+ }
+
+ /**
* Calculates the remaining time relative to now.
*
* @return future - now
@@ -157,24 +158,27 @@
}
/**
- * Adds a relative time value to an absolute time.
+ * Returns the maximum of two time values.
*
- * @param duration
- * @return this + duration
+ * @param other
+ * @return max(this,other)
*/
- public AbsoluteTime add(final RelativeTime duration) {
- if (abs_value == Long.MAX_VALUE
- || duration.getMilliseconds() == Long.MAX_VALUE) {
- return this;
- }
- if (abs_value + duration.getMilliseconds() < abs_value) {
- logger.warn("time overflow");
- return AbsoluteTime.FOREVER;
- }
- return new AbsoluteTime(abs_value + duration.getMilliseconds());
+ public AbsoluteTime max(final AbsoluteTime other) {
+ return abs_value >= other.abs_value ? this : other;
+
}
/**
+ * Returns the minimum of two time values.
+ *
+ * @param other
+ * @return min(this,other)
+ */
+ public AbsoluteTime min(final AbsoluteTime other) {
+ return abs_value <= other.abs_value ? this : other;
+ }
+
+ /**
* Subtracts a relative time value to an absolute time
*
* @param duration
@@ -189,10 +193,4 @@
}
return new AbsoluteTime(abs_value - duration.getMilliseconds());
}
-
- @Override
- public int compareTo(Object o) {
- // TODO Auto-generated method stub
- return 0;
- }
}
Modified: gnunet-java/src/org/gnunet/util/Client.java
===================================================================
--- gnunet-java/src/org/gnunet/util/Client.java 2011-11-30 15:21:36 UTC (rev
18410)
+++ gnunet-java/src/org/gnunet/util/Client.java 2011-12-01 01:00:29 UTC (rev
18411)
@@ -16,130 +16,138 @@
along with GNUnet; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.
-*/
+ */
-
package org.gnunet.util;
import org.gnunet.messages.MessageHeader;
import org.gnunet.util.Scheduler.Task;
-
/**
* Represents a connection to a service.
*/
public class Client {
- interface MessageHandler {
+ interface MessageHandler {
- }
+ }
- public static class TransmitHandle {
- /**
- * Cancel a request for notification.
- */
- void cancel() {
- throw new UnsupportedOperationException();
- }
+ public static class TransmitHandle {
+ /**
+ * Cancel a request for notification.
+ */
+ void cancel() {
+ throw new UnsupportedOperationException();
+ }
- }
+ }
- /**
- * Get a connection with a service.
- *
- * @param service_name
- * name of the service
- * @param cfg
- * configuration to use
- */
- public Client(String service_name, Configuration c) {
- throw new UnsupportedOperationException();
- }
+ /**
+ * Wait until the service is running.
+ *
+ * @param service
+ * name of the service to wait for
+ * @param cfg
+ * configuration to use
+ * @param timeout
+ * how long to wait at most in ms
+ * @param task
+ * task to run if service is running (reason will be
+ * "PREREQ_DONE" (service running) or "TIMEOUT" (service not
+ * known to be running))
+ */
- /**
- * Read from the service.
- *
- * @param handler
- * function to call with the message
- * @param timeout
- * how long to wait until timing out
- */
+ public static void serviceTest(final String service_name,
+ final Configuration cfg, final RelativeTime timeout, final Task t)
{
+ throw new UnsupportedOperationException();
+ }
- public void receive(MessageHandler handler, RelativeTime timeout) {
- throw new UnsupportedOperationException();
- }
+ /**
+ * Get a connection with a service.
+ *
+ * @param service_name
+ * name of the service
+ * @param cfg
+ * configuration to use
+ */
+ public Client(final String service_name, final Configuration c) {
+ throw new UnsupportedOperationException();
+ }
- /**
- * Ask the client to call us once the specified number of bytes are
free in
- * the transmission buffer. May call the notify method immediately if
enough
- * space is available.
- *
- * @param sock
- * connection to the service
- * @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 auto_retry
- * if the connection to the service dies, should we
automatically
- * re-connect and retry (within the timeout period) or
should we
- * immediately fail in this case? Pass GNUNET_YES if the
caller
- * does not care about temporary connection errors, for
example
- * because the protocol is stateless
- * @param notify
- * function to call
- * @param notify_cls
- * closure for notify
- * @return NULL if someone else is already waiting to be notified
non-NULL
- * if the notify callback was queued (can be used to cancel
using
- * GNUNET_CONNECTION_notify_transmit_ready_cancel)
- */
- public TransmitHandle notifyTransmitReady(int size, RelativeTime
timeout,
- boolean auto_retry, TransmitReadyNotify cb) {
- throw new UnsupportedOperationException();
- }
+ /**
+ * Ask the client to call us once the specified number of bytes are free in
+ * the transmission buffer. May call the notify method immediately if
enough
+ * space is available.
+ *
+ * @param sock
+ * connection to the service
+ * @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 auto_retry
+ * if the connection to the service dies, should we
automatically
+ * re-connect and retry (within the timeout period) or should we
+ * immediately fail in this case? Pass GNUNET_YES if the caller
+ * does not care about temporary connection errors, for example
+ * because the protocol is stateless
+ * @param notify
+ * function to call
+ * @param notify_cls
+ * closure for notify
+ * @return NULL if someone else is already waiting to be notified non-NULL
+ * if the notify callback was queued (can be used to cancel using
+ * GNUNET_CONNECTION_notify_transmit_ready_cancel)
+ */
+ public TransmitHandle notifyTransmitReady(final int size,
+ final RelativeTime timeout, final boolean auto_retry,
+ final TransmitReadyNotify cb) {
+ throw new UnsupportedOperationException();
+ }
-
- /**
- * Convenience API that combines sending a request
- * to the service and waiting for a response.
- * If either operation times out, the callback
- * will be called with a "NULL" response (in which
- * case the connection should probably be destroyed).
- *
- * @param sock connection to use
- * @param hdr message to transmit
- * @param timeout when to give up (for both transmission
- * and for waiting for a response)
- * @param auto_retry if the connection to the service dies, should we
- * automatically re-connect and retry (within the timeout period)
- * or should we immediately fail in this case? Pass GNUNET_YES
- * if the caller does not care about temporary connection errors,
- * for example because the protocol is stateless
- * @param rn function to call with the response
- * @param rn_cls closure for rn
- * @return GNUNET_OK on success, GNUNET_SYSERR if a request
- * is already pending
- */
- //XXX return type bool vs. exceptions
- public boolean transmitAndGetResponse(MessageHeader m, RelativeTime
timeout,
- boolean autoRetry, MessageHandler handler) {
- throw new UnsupportedOperationException();
- }
-
-
- /**
- * Wait until the service is running.
- *
- * @param service name of the service to wait for
- * @param cfg configuration to use
- * @param timeout how long to wait at most in ms
- * @param task task to run if service is running
- * (reason will be "PREREQ_DONE" (service running)
- * or "TIMEOUT" (service not known to be running))
- */
+ /**
+ * Read from the service.
+ *
+ * @param handler
+ * function to call with the message
+ * @param timeout
+ * how long to wait until timing out
+ */
- public static void serviceTest(String service_name, Configuration cfg,
RelativeTime timeout, Task t) {
- throw new UnsupportedOperationException();
- }
+ public void receive(final MessageHandler handler, final RelativeTime
timeout) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Convenience API that combines sending a request to the service and
+ * waiting for a response. If either operation times out, the callback will
+ * be called with a "NULL" response (in which case the connection should
+ * probably be destroyed).
+ *
+ * @param sock
+ * connection to use
+ * @param hdr
+ * message to transmit
+ * @param timeout
+ * when to give up (for both transmission and for waiting for a
+ * response)
+ * @param auto_retry
+ * if the connection to the service dies, should we
automatically
+ * re-connect and retry (within the timeout period) or should we
+ * immediately fail in this case? Pass GNUNET_YES if the caller
+ * does not care about temporary connection errors, for example
+ * because the protocol is stateless
+ * @param rn
+ * function to call with the response
+ * @param rn_cls
+ * closure for rn
+ * @return GNUNET_OK on success, GNUNET_SYSERR if a request is already
+ * pending
+ */
+ // XXX return type bool vs. exceptions
+ public boolean transmitAndGetResponse(final MessageHeader m,
+ final RelativeTime timeout, final boolean autoRetry,
+ final MessageHandler handler) {
+ throw new UnsupportedOperationException();
+ }
}
Modified: gnunet-java/src/org/gnunet/util/Configuration.java
===================================================================
--- gnunet-java/src/org/gnunet/util/Configuration.java 2011-11-30 15:21:36 UTC
(rev 18410)
+++ gnunet-java/src/org/gnunet/util/Configuration.java 2011-12-01 01:00:29 UTC
(rev 18411)
@@ -43,12 +43,23 @@
* @author Florian Dold
*/
public class Configuration {
+ @SuppressWarnings("serial")
+ public static class ParsingError extends Error {
+ ParsingError(final String msg) {
+ super(msg);
+ }
+
+ ParsingError(final String msg, final Throwable t) {
+ super(msg, t);
+ }
+ }
+
private static final Logger logger = LoggerFactory
.getLogger(Configuration.class);
-
private static Pattern section = Pattern.compile("\\[(.*?)\\]");
private static Pattern tag = Pattern.compile("(\\S+?) =( ?.*?)");
private static Pattern comment = Pattern.compile("\\s*[%#].*\n?");
+
private static Pattern delim = Pattern.compile("\\s*\\n\\s*");
private final Map<String, Map<String, String>> sections = new
LinkedHashMap<String, Map<String, String>>();
@@ -59,138 +70,97 @@
public Configuration() {
}
+ public boolean appendValueFilename(final String section,
+ final String option, final String value) {
+ throw new UnsupportedOperationException();
+ }
+
/**
- * Parse a configuration file, add all of the options in the file to the
- * configuration environment.
+ * Expand an expression of the form "$FOO/BAR" to "DIRECTORY/BAR" where
+ * either in the "PATHS" section or the environment "FOO" is set to
+ * "DIRECTORY".
*
- * @param filename
- * name of the configuration file
- * @throws ParsingError
+ * @param orig
+ * string to $-expand
+ * @return $-expanded string
*/
- public void parse(String filename) {
- Scanner sc;
- try {
- sc = new Scanner(new File(filename)).useDelimiter(delim);
- } catch (FileNotFoundException e) {
- throw new ParsingError("Configuration file \"" + filename
- + "\" not found");
+ public String expandDollar(String orig) {
+ final Map<String, String> env = System.getenv();
+ for (final Map.Entry<String, String> e : env.entrySet()) {
+ orig = orig.replace("$" + e.getKey(), e.getValue());
}
- String current_section = "";
-
- while (true) {
- if (sc.hasNext(comment)) {
- sc.next(comment);
- } else if (sc.hasNext(section)) {
- sc.next(section);
- current_section = sc.match().group(1).trim();
- } else if (sc.hasNext(tag)) {
- sc.next(tag);
- String option = sc.match().group(1).trim();
- String value = sc.match().group(2).trim();
-
- if (value.length() != 0 && value.charAt(0) == '"') {
- int pos = value.indexOf('"', 1);
- if (pos == -1) {
- logger.warn("incorrecly quoted config value");
- continue;
- }
- value = value.substring(1, pos);
- }
- setValueString(current_section, option, value);
- } else if (!sc.hasNext()) {
- break;
- } else {
- logger.warn("skipped unreadable configuration line");
- sc.next();
+ if (sections.containsKey("PATHS")) {
+ for (final Map.Entry<String, String> e : sections.get("PATHS")
+ .entrySet()) {
+ orig = orig.replace("$" + e.getKey(), e.getValue());
}
}
+ return orig;
}
/**
- * Start with defaults, the parse configuration file.
- */
- public boolean load(String filename) {
- throw new UnsupportedOperationException();
- }
-
- /**
- * Test if there are configuration options that were changed since the last
- * save.
- */
- public boolean isDirty() {
- throw new UnsupportedOperationException();
- }
-
- /**
- * Write configuration file.
+ * Returns all configuration options in a section.
*
- * @param filename
- * where to write the configuration
- * @throws IOException
+ * @param s
+ * the section of interest
+ * @return an unmodifiable view of the section.
*/
- public void write(String filename) throws IOException {
- BufferedWriter w = new BufferedWriter(
- new FileWriter(new File(filename)));
- for (Map.Entry<String, Map<String, String>> s : sections.entrySet()) {
- w.write(s.getKey());
- w.newLine();
- for (Map.Entry<String, String> e : s.getValue().entrySet()) {
- w.write(e.getKey() + " = " + e.getValue());
- w.newLine();
- }
+ public Map<String, String> getSection(final String s) {
+ final Map<String, String> m = sections.get(s);
+ if (m == null) {
+ throw new ParsingError("configuration section not found");
}
- w.close();
+ return Collections.unmodifiableMap(m);
}
/**
- * Remove the given section and all options in it.
- */
- public void removeSection(String section) {
- sections.remove(section);
- }
-
- /**
- * Write only configuration entries that have been changed to configuration
- * file.
+ * Returns the names of all non-empty sections
*
- * @param cfgNew
- * new configuration
- *
- * @param filename
- * where to write the configuration diff between default and new
+ * @return set of non-empty section names
*/
- public void writeDiffs(Configuration cfgNew, String filename) {
- throw new UnsupportedOperationException();
+ public Set<String> getSections() {
+ return sections.keySet();
}
/**
- * Set an option to a string value in a section.
+ * Get a configuration value that should be in a set of predefined strings
*
* @param section
+ * section of interest
* @param option
- * @param value
+ * option of interest
+ * @param choices
+ * list of legal values
+ * @return matching value from choices
+ * @throws ParsingError
*/
- public void setValueString(String section, String option, String value) {
- Map<String, String> table = sections.get(section);
- if (table == null) {
- table = new LinkedHashMap<String, String>();
- sections.put(section, table);
+ public String getValueChoice(final String section, final String option,
+ final Iterable<String> choices) {
+ final String value = getValueString(section, option);
+ if (value == null) {
+ throw new ParsingError(String.format(
+ "Failure in configuration section %s: value not found",
+ section));
}
- table.put(option, value);
+ for (final String c : choices) {
+ if (c.equals(value)) {
+ return value;
+ }
+ }
+ throw new ParsingError(String.format(
+ "Failure in configuration section %s: invalid value",
section));
}
- /**
- * Set an option to a string value in a section.
- *
- * @param section
- * @param option
- * @param value
- */
- public void setValueNumber(String section, String option, long value) {
- setValueString(section, option, "" + value);
+ public String getValueFileName(final String section, final String option) {
+ throw new UnsupportedOperationException();
}
+ public List<String> getValueFilenames(final String section,
+ final String option) {
+ throw new UnsupportedOperationException();
+ }
+
/**
* Get a configuration value that should be a number
*
@@ -198,15 +168,15 @@
* @param option
* @return null if value not in configuration, the option's value otherwise
*/
- public long getValueNumer(String section, String option) {
- String num_str = getValueString(section, option);
+ public long getValueNumer(final String section, final String option) {
+ final String num_str = getValueString(section, option);
if (num_str == null) {
throw new ParsingError("Failure in configuration section "
+ section + " option " + option + ": value empty");
}
try {
return Long.parseLong(num_str);
- } catch (NumberFormatException e) {
+ } catch (final NumberFormatException e) {
throw new ParsingError("Failure in configuration section "
+ section + " option " + option + ": " + e.getMessage(),
e);
}
@@ -219,7 +189,7 @@
* @param option
* @throws ParsingError
*/
- public String getValueString(String section, String option) {
+ public String getValueString(final String section, final String option) {
if (!sections.containsKey(section)) {
throw new ParsingError(String.format(
"Failure in configuration section %s: option %s not found",
@@ -235,38 +205,35 @@
* @param option
* @return null if option not found
*/
- public RelativeTime getValueTime(String section, String option) {
+ public RelativeTime getValueTime(final String section, final String
option) {
throw new UnsupportedOperationException();
}
/**
- * Get a configuration value that should be in a set of predefined strings
+ * Gets a configuration value that should be in a set of {"YES","NO"}.
*
* @param section
* section of interest
* @param option
* option of interest
- * @param choices
- * list of legal values
- * @return matching value from choices
- * @throws ParsingError
+ * @return true, false, null
*/
- public String getValueChoice(String section, String option,
- Iterable<String> choices) {
- String value = getValueString(section, option);
- if (value == null) {
+ public boolean getValueYesNo(final String section, final String option) {
+ final String v = getValueChoice(section, option,
+ Arrays.asList("YES", "NO"));
+ if (v == null) {
throw new ParsingError(String.format(
- "Failure in configuration section %s: value not found",
- section));
+ "Failure in configuration section %s: option %s not found",
+ section, option));
}
- for (String c : choices) {
- if (c.equals(value)) {
- return value;
- }
+ if (v.equals("YES")) {
+ return true;
}
- throw new ParsingError(String.format(
- "Failure in configuration section %s: invalid value",
- section));
+ if (v.equals("NO")) {
+ return false;
+ }
+ throw new ParsingError(
+ "Configuration error: value not recognized as YES or NO");
}
/**
@@ -279,110 +246,149 @@
* @return true if so, false of not
*
*/
- public boolean haveValue(String section, String option) {
+ public boolean haveValue(final String section, final String option) {
return sections.containsKey(section)
&& sections.get(section).containsKey(option);
}
/**
- * Gets a configuration value that should be in a set of {"YES","NO"}.
- *
- * @param section
- * section of interest
- * @param option
- * option of interest
- * @return true, false, null
+ * Test if there are configuration options that were changed since the last
+ * save.
*/
- public boolean getValueYesNo(String section, String option) {
- String v = getValueChoice(section, option, Arrays.asList("YES", "NO"));
- if (v == null) {
- throw new ParsingError(String.format(
- "Failure in configuration section %s: option %s not found",
- section, option));
- }
- if (v.equals("YES")) {
- return true;
- }
- if (v.equals("NO")) {
- return false;
- }
- throw new ParsingError("Configuration error: value not recognized as
YES or NO");
+ public boolean isDirty() {
+ throw new UnsupportedOperationException();
}
/**
- * Returns all configuration options in a section.
- *
- * @param s
- * the section of interest
- * @return an unmodifiable view of the section.
+ * Start with defaults, the parse configuration file.
*/
- public Map<String, String> getSection(String s) {
- Map<String, String> m = sections.get(s);
- if (m == null) {
- throw new ParsingError("configuration section not found");
- }
- return Collections.unmodifiableMap(m);
+ public boolean load(final String filename) {
+ throw new UnsupportedOperationException();
}
/**
- * Returns the names of all non-empty sections
+ * Parse a configuration file, add all of the options in the file to the
+ * configuration environment.
*
- * @return set of non-empty section names
+ * @param filename
+ * name of the configuration file
+ * @throws ParsingError
*/
- public Set<String> getSections() {
- return sections.keySet();
- }
-
- /**
- * Expand an expression of the form "$FOO/BAR" to "DIRECTORY/BAR" where
- * either in the "PATHS" section or the environment "FOO" is set to
- * "DIRECTORY".
- *
- * @param orig
- * string to $-expand
- * @return $-expanded string
- */
- public String expandDollar(String orig) {
- Map<String, String> env = System.getenv();
- for (Map.Entry<String, String> e : env.entrySet()) {
- orig = orig.replace("$" + e.getKey(), e.getValue());
+ public void parse(final String filename) {
+ Scanner sc;
+ try {
+ sc = new Scanner(new File(filename)).useDelimiter(delim);
+ } catch (final FileNotFoundException e) {
+ throw new ParsingError("Configuration file \"" + filename
+ + "\" not found");
}
- if (sections.containsKey("PATHS")) {
- for (Map.Entry<String, String> e :
sections.get("PATHS").entrySet()) {
- orig = orig.replace("$" + e.getKey(), e.getValue());
+ String current_section = "";
+
+ while (true) {
+ if (sc.hasNext(comment)) {
+ sc.next(comment);
+ } else if (sc.hasNext(section)) {
+ sc.next(section);
+ current_section = sc.match().group(1).trim();
+ } else if (sc.hasNext(tag)) {
+ sc.next(tag);
+ final String option = sc.match().group(1).trim();
+ String value = sc.match().group(2).trim();
+
+ if (value.length() != 0 && value.charAt(0) == '"') {
+ final int pos = value.indexOf('"', 1);
+ if (pos == -1) {
+ logger.warn("incorrecly quoted config value");
+ continue;
+ }
+ value = value.substring(1, pos);
+ }
+ setValueString(current_section, option, value);
+ } else if (!sc.hasNext()) {
+ break;
+ } else {
+ logger.warn("skipped unreadable configuration line");
+ sc.next();
}
}
- return orig;
}
- public String getValueFileName(String section, String option) {
- throw new UnsupportedOperationException();
+ /**
+ * Remove the given section and all options in it.
+ */
+ public void removeSection(final String section) {
+ sections.remove(section);
}
- public List<String> getValueFilenames(String section, String option) {
+ public boolean removeValueFilename(final String section,
+ final String option, final String value) {
throw new UnsupportedOperationException();
}
- public boolean appendValueFilename(String section, String option,
- String value) {
- throw new UnsupportedOperationException();
+ /**
+ * Set an option to a string value in a section.
+ *
+ * @param section
+ * @param option
+ * @param value
+ */
+ public void setValueNumber(final String section, final String option,
+ final long value) {
+ setValueString(section, option, "" + value);
}
- public boolean removeValueFilename(String section, String option,
- String value) {
- throw new UnsupportedOperationException();
+ /**
+ * Set an option to a string value in a section.
+ *
+ * @param section
+ * @param option
+ * @param value
+ */
+ public void setValueString(final String section, final String option,
+ final String value) {
+ Map<String, String> table = sections.get(section);
+ if (table == null) {
+ table = new LinkedHashMap<String, String>();
+ sections.put(section, table);
+ }
+ table.put(option, value);
}
- @SuppressWarnings("serial")
- public static class ParsingError extends Error {
- ParsingError(String msg, Throwable t) {
- super(msg, t);
+ /**
+ * Write configuration file.
+ *
+ * @param filename
+ * where to write the configuration
+ * @throws IOException
+ */
+ public void write(final String filename) throws IOException {
+ final BufferedWriter w = new BufferedWriter(new FileWriter(new File(
+ filename)));
+ for (final Map.Entry<String, Map<String, String>> s : sections
+ .entrySet()) {
+ w.write(s.getKey());
+ w.newLine();
+ for (final Map.Entry<String, String> e : s.getValue().entrySet()) {
+ w.write(e.getKey() + " = " + e.getValue());
+ w.newLine();
+ }
}
+ w.close();
+ }
- ParsingError(String msg) {
- super(msg);
- }
+ /**
+ * Write only configuration entries that have been changed to configuration
+ * file.
+ *
+ * @param cfgNew
+ * new configuration
+ *
+ * @param filename
+ * where to write the configuration diff between default and new
+ */
+ public void writeDiffs(final Configuration cfgNew, final String filename) {
+ throw new UnsupportedOperationException();
}
}
Modified: gnunet-java/src/org/gnunet/util/MessageHandler.java
===================================================================
--- gnunet-java/src/org/gnunet/util/MessageHandler.java 2011-11-30 15:21:36 UTC
(rev 18410)
+++ gnunet-java/src/org/gnunet/util/MessageHandler.java 2011-12-01 01:00:29 UTC
(rev 18411)
@@ -16,25 +16,23 @@
along with GNUnet; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.
-*/
+ */
-
package org.gnunet.util;
import org.gnunet.messages.MessageHeader;
-
/**
*
* @author Florian Dold
- *
+ *
*/
public interface MessageHandler {
/**
- * Method to call when we receive a message
- * from the service.
- *
- * @param msg message received, NULL on timeout or fatal error
+ * Method to call when we receive a message from the service.
+ *
+ * @param msg
+ * message received, NULL on timeout or fatal error
*/
public void handle(MessageHeader msg);
}
Modified: gnunet-java/src/org/gnunet/util/Program.java
===================================================================
--- gnunet-java/src/org/gnunet/util/Program.java 2011-11-30 15:21:36 UTC
(rev 18410)
+++ gnunet-java/src/org/gnunet/util/Program.java 2011-12-01 01:00:29 UTC
(rev 18411)
@@ -1,7 +1,5 @@
package org.gnunet.util;
public class Program {
-
-
}
Modified: gnunet-java/src/org/gnunet/util/Receiver.java
===================================================================
--- gnunet-java/src/org/gnunet/util/Receiver.java 2011-11-30 15:21:36 UTC
(rev 18410)
+++ gnunet-java/src/org/gnunet/util/Receiver.java 2011-12-01 01:00:29 UTC
(rev 18411)
@@ -16,23 +16,23 @@
along with GNUnet; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.
-*/
+ */
-
-
package org.gnunet.util;
import java.net.SocketAddress;
-
public interface Receiver {
/**
* Callback function for data received from the network.
*
- * @param buf received data
- * @param sockaddr address of the sender
- * @param errCode XXX errno? really?! should this be an IO exception?
+ * @param buf
+ * received data
+ * @param sockaddr
+ * address of the sender
+ * @param errCode
+ * XXX errno? really?! should this be an IO exception?
*/
- public void receive(byte[] buf, SocketAddress sockaddr, int errCode);
-
-}
\ No newline at end of file
+ public void receive(byte[] buf, SocketAddress sockaddr, int errCode);
+
+}
Modified: gnunet-java/src/org/gnunet/util/RelativeTime.java
===================================================================
--- gnunet-java/src/org/gnunet/util/RelativeTime.java 2011-11-30 15:21:36 UTC
(rev 18410)
+++ gnunet-java/src/org/gnunet/util/RelativeTime.java 2011-12-01 01:00:29 UTC
(rev 18411)
@@ -16,9 +16,8 @@
along with GNUnet; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.
-*/
+ */
-
package org.gnunet.util;
import org.gnunet.messages.RelativeTimeNBO;
@@ -53,31 +52,50 @@
}
/**
- * Returns the amount of time in milliseconds.
+ * Add relative times together.
*
- * @return the amount of time in milliseconds
+ * @param other
+ * the other timestamp
+ *
+ * @return this + other
*/
- public long getMilliseconds() {
- return rel_value;
+ public RelativeTime add(final RelativeTime other) {
+ if (this.rel_value == Long.MAX_VALUE
+ || other.rel_value == Long.MAX_VALUE) {
+ return RelativeTime.FOREVER;
+ }
+ final long new_rel_value = this.rel_value + other.rel_value;
+ // check for numeric overflow
+ if (new_rel_value < this.rel_value) {
+ logger.warn("time overflow");
+ return RelativeTime.FOREVER;
+ }
+ return new RelativeTime(new_rel_value);
}
/**
- * Converts relative time to an absolute time in the future.
+ * Divide relative time by a given factor.
*
- * @return timestamp that is in the future, or FOREVER if this=FOREVER (or
- * if we would overflow)
+ * @param rel
+ * some duration
+ * @param factor
+ * integer to divide by
+ * @return FOREVER if this=FOREVER or factor=0; otherwise this/factor
*/
- public AbsoluteTime toAbsolute() {
- return AbsoluteTime.now().add(this);
+ public RelativeTime divide(final int factor) {
+ if (factor == 0 || this.rel_value == Long.MAX_VALUE) {
+ return RelativeTime.FOREVER;
+ }
+ return new RelativeTime(this.rel_value / factor);
}
/**
- * Return the minimum of two relative time values.
+ * Returns the amount of time in milliseconds.
*
- * @return min(this, other)
+ * @return the amount of time in milliseconds
*/
- public RelativeTime min(final RelativeTime other) {
- return (rel_value <= other.rel_value) ? this : other;
+ public long getMilliseconds() {
+ return rel_value;
}
/**
@@ -86,10 +104,19 @@
* @return max(this, other)
*/
public RelativeTime max(final RelativeTime other) {
- return (rel_value >= other.rel_value) ? this : other;
+ return rel_value >= other.rel_value ? this : other;
}
/**
+ * Return the minimum of two relative time values.
+ *
+ * @return min(this, other)
+ */
+ public RelativeTime min(final RelativeTime other) {
+ return rel_value <= other.rel_value ? this : other;
+ }
+
+ /**
* Multiply relative time by a given factor.
*
* @return FOREVER if this=FOREVER or on overflow; otherwise this*factor
@@ -108,53 +135,6 @@
}
/**
- * Divide relative time by a given factor.
- *
- * @param rel
- * some duration
- * @param factor
- * integer to divide by
- * @return FOREVER if this=FOREVER or factor=0; otherwise this/factor
- */
- public RelativeTime divide(final int factor) {
- if (factor == 0 || this.rel_value == Long.MAX_VALUE) {
- return RelativeTime.FOREVER;
- }
- return new RelativeTime(this.rel_value / factor);
- }
-
- /**
- * Add relative times together.
- *
- * @param other
- * the other timestamp
- *
- * @return this + other
- */
- public RelativeTime add(final RelativeTime other) {
- if (this.rel_value == Long.MAX_VALUE
- || other.rel_value == Long.MAX_VALUE) {
- return RelativeTime.FOREVER;
- }
- final long new_rel_value = this.rel_value + other.rel_value;
- // check for numeric overflow
- if (new_rel_value < this.rel_value) {
- logger.warn("time overflow");
- return RelativeTime.FOREVER;
- }
- return new RelativeTime(new_rel_value);
- }
-
- public RelativeTimeNBO toNBO()
- {
- long rval = this.rel_value;
- assert (rval >= 0);
- if (rval == FOREVER.rel_value)
- rval = -1L; /* 0xFFFFFFFFFFFFFFFF for network format! */
- return new RelativeTimeNBO(rval);
- }
-
- /**
* Subtract relative timestamp from the other.
*
* @param other
@@ -171,4 +151,23 @@
return new RelativeTime(this.rel_value - other.rel_value);
}
}
+
+ /**
+ * Converts relative time to an absolute time in the future.
+ *
+ * @return timestamp that is in the future, or FOREVER if this=FOREVER (or
+ * if we would overflow)
+ */
+ public AbsoluteTime toAbsolute() {
+ return AbsoluteTime.now().add(this);
+ }
+
+ public RelativeTimeNBO toNBO() {
+ long rval = this.rel_value;
+ assert rval >= 0;
+ if (rval == FOREVER.rel_value) {
+ rval = -1L; /* 0xFFFFFFFFFFFFFFFF for network format! */
+ }
+ return new RelativeTimeNBO(rval);
+ }
}
Modified: gnunet-java/src/org/gnunet/util/Scheduler.java
===================================================================
--- gnunet-java/src/org/gnunet/util/Scheduler.java 2011-11-30 15:21:36 UTC
(rev 18410)
+++ gnunet-java/src/org/gnunet/util/Scheduler.java 2011-12-01 01:00:29 UTC
(rev 18411)
@@ -44,9 +44,6 @@
* @author Florian Dold
*/
public class Scheduler {
- private static final Logger logger = LoggerFactory
- .getLogger(Scheduler.class);
-
public enum Priority {
IDLE, BACKGROUND, DEFAULT, HIGH, UI, URGENT, SHUTDOWN, _COUNT;
static public final Priority KEEP = null;
@@ -56,48 +53,7 @@
STARTUP, SHUTDOWN, TIMEOUT, READ_READY, WRITE_READY, PREREQ_DONE
}
- // tasks that are waiting for a delay to pass, will be moved to 'pending'
- // eventually
- private static Queue<TimeoutTask> pending_timeout = new
PriorityQueue<TimeoutTask>();
-
- // tasks that may be waiting for an event
- private static List<TaskIdentifier> pending = new
LinkedList<TaskIdentifier>();
-
- // only valid while a task is executing
- private static TaskIdentifier active_task;
-
-
- static Priority current_priority;
- static boolean current_liveness;
-
-
- // number of tasks in the ready queue
- private static int ready_count = 0;
-
- // for every priority, there is a list of tasks that is definitely ready to
- // run
- private static ArrayList<LinkedList<TaskIdentifier>> ready = new
ArrayList<LinkedList<TaskIdentifier>>(
- Priority._COUNT.ordinal());
- static {
- for (int i = 0; i < ready.size(); ++i) {
- ready.set(i, new LinkedList<TaskIdentifier>());
- }
- }
-
- private static Selector selector;
- static {
- try {
- selector = SelectorProvider.provider().openSelector();
- } catch (IOException e) {
- // what to do here?
- logger.error("fatal: cannot create selector");
- System.exit(-1);
- }
- }
-
public static interface Task {
- public void run(Context ctx);
-
// the context of a task is set in the task identifier once a task is
// moved into the ready queue
public static class Context {
@@ -105,37 +61,33 @@
Set<Channel> readableSet = null;
Set<Channel> writeableSet = null;
}
+
+ public void run(Context ctx);
}
- final public static Task NO_TASK = new Task() {
- @Override
- public void run(Context ctx) {
- }
- };
-
public static class TaskIdentifier {
private final Task task;
private final TaskIdentifier prereq;
- private Task.Context ctx = new Task.Context();
+ private final Task.Context ctx = new Task.Context();
boolean liveness;
Priority priority;
- TaskIdentifier(Task t, Priority priority, boolean liveness,
- TaskIdentifier prereq) {
+ TaskIdentifier(final Task t, final Priority priority,
+ final boolean liveness, final TaskIdentifier prereq) {
this.task = t;
- this.priority = (priority == null) ? active_task.priority :
priority;
+ this.priority = priority == null ? active_task.priority : priority;
this.liveness = liveness;
this.prereq = prereq;
}
+ public void cancel() {
+ pending.remove(this);
+ }
+
void run() {
active_task = this;
task.run(ctx);
}
-
- public void cancel() {
- pending.remove(this);
- }
}
static class TimeoutTask extends TaskIdentifier implements
@@ -143,8 +95,8 @@
final AbsoluteTime timeout;
boolean selected = false;
- TimeoutTask(Task t, Priority p, boolean liveness,
- TaskIdentifier prereq, RelativeTime delay) {
+ TimeoutTask(final Task t, final Priority p, final boolean liveness,
+ final TaskIdentifier prereq, final RelativeTime delay) {
super(t, p, liveness, prereq);
timeout = delay.toAbsolute();
}
@@ -156,61 +108,107 @@
}
@Override
- public int compareTo(TimeoutTask o) {
- return (new Long(this.timeout.getMilliseconds())
- .compareTo(o.timeout.getMilliseconds()));
+ public int compareTo(final TimeoutTask o) {
+ return new Long(this.timeout.getMilliseconds()).compareTo(o.timeout
+ .getMilliseconds());
}
}
- /**
- * Schedule a new task to be run as soon as possible. The task will be run
- * with the priority of the calling task.
- *
- * @param task
- * main function of the task
- * @param task_cls
- * closure of task
- * @return unique task identifier for the job only valid until "task" is
- * started!
- */
- public static TaskIdentifier addNow(Task task) {
- return addSelect(Priority.KEEP, null, RelativeTime.ZERO, null, null,
- task);
+ private static final Logger logger = LoggerFactory
+ .getLogger(Scheduler.class);
+
+ // tasks that are waiting for a delay to pass, will be moved to 'pending'
+ // eventually
+ private static Queue<TimeoutTask> pending_timeout = new
PriorityQueue<TimeoutTask>();
+ // tasks that may be waiting for an event
+ private static List<TaskIdentifier> pending = new
LinkedList<TaskIdentifier>();
+
+ // only valid while a task is executing
+ private static TaskIdentifier active_task;
+
+ static Priority current_priority;
+ static boolean current_liveness;
+
+ // number of tasks in the ready queue
+ private static int ready_count = 0;
+ // for every priority, there is a list of tasks that is definitely ready to
+ // run
+ private static ArrayList<LinkedList<TaskIdentifier>> ready = new
ArrayList<LinkedList<TaskIdentifier>>(
+ Priority._COUNT.ordinal());
+
+ static {
+ for (int i = 0; i < ready.size(); ++i) {
+ ready.set(i, new LinkedList<TaskIdentifier>());
+ }
}
- public static TaskIdentifier addDelayed(RelativeTime delay, Task task) {
- return addSelect(Priority.KEEP, null, delay, null, null, task);
+ private static Selector selector;
+
+ static {
+ try {
+ selector = SelectorProvider.provider().openSelector();
+ } catch (final IOException e) {
+ // what to do here?
+ logger.error("fatal: cannot create selector");
+ System.exit(-1);
+ }
}
+ final public static Task NO_TASK = new Task() {
+ @Override
+ public void run(final Context ctx) {
+ }
+ };
+
+ public static TaskIdentifier addAfter(final TaskIdentifier prereq,
+ final Task t) {
+ return addSelect(Priority.KEEP, prereq, RelativeTime.ZERO, null, null,
+ t);
+ }
+
/**
* Run the task regardless of any prerequisites, before any other task of
* the same priority.
*/
- public static void addContinuation(Task task, EnumSet<Reason> reason) {
+ public static void addContinuation(final Task task,
+ final EnumSet<Reason> reason) {
assert active_task == null || active_task.priority != null;
- TaskIdentifier tid = new TaskIdentifier(task, Priority.KEEP,
+ final TaskIdentifier tid = new TaskIdentifier(task, Priority.KEEP,
current_liveness, null);
queueReady(tid);
}
- public static TaskIdentifier addAfter(TaskIdentifier prereq, Task t) {
- return addSelect(Priority.KEEP, prereq, RelativeTime.ZERO, null, null,
- t);
+ public static TaskIdentifier addDelayed(final RelativeTime delay,
+ final Task task) {
+ return addSelect(Priority.KEEP, null, delay, null, null, task);
}
- public static TaskIdentifier addWithPriority(Priority prio, Task t) {
- return addSelect(prio, null, RelativeTime.ZERO, null, null, t);
+ /**
+ * Schedule a new task to be run as soon as possible. The task will be run
+ * with the priority of the calling task.
+ *
+ * @param task
+ * main function of the task
+ * @param task_cls
+ * closure of task
+ * @return unique task identifier for the job only valid until "task" is
+ * started!
+ */
+ public static TaskIdentifier addNow(final Task task) {
+ return addSelect(Priority.KEEP, null, RelativeTime.ZERO, null, null,
+ task);
}
// should register the channels with the selector
- public static TaskIdentifier addSelect(Priority p, TaskIdentifier prereq,
- RelativeTime delay, Set<SelectableChannel> rs,
- Set<SelectableChannel> ws, Task t) {
+ public static TaskIdentifier addSelect(final Priority p,
+ final TaskIdentifier prereq, final RelativeTime delay,
+ final Set<SelectableChannel> rs, final Set<SelectableChannel> ws,
+ final Task t) {
if (rs != null) {
- for (SelectableChannel s : rs) {
+ for (final SelectableChannel s : rs) {
try {
s.register(selector, SelectionKey.OP_READ, null);
- } catch (ClosedChannelException e) {
+ } catch (final ClosedChannelException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
@@ -218,10 +216,10 @@
}
if (ws != null) {
- for (SelectableChannel s : ws) {
+ for (final SelectableChannel s : ws) {
try {
s.register(selector, SelectionKey.OP_WRITE, null);
- } catch (ClosedChannelException e) {
+ } catch (final ClosedChannelException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
@@ -229,47 +227,61 @@
}
- TimeoutTask tid = new TimeoutTask(t, p, active_task.liveness, prereq,
delay);
+ final TimeoutTask tid = new TimeoutTask(t, p, active_task.liveness,
+ prereq, delay);
return tid;
}
- /**
- * Request the shutdown of a scheduler. Marks all currently pending tasks
as
- * ready because of shutdown. This will cause all tasks to run (as soon as
- * possible, respecting priorities and prerequisite tasks). Note that tasks
- * scheduled AFTER this call may still be delayed arbitrarily.
- */
- public static void shutdown() {
- throw new UnsupportedOperationException();
+ public static TaskIdentifier addWithPriority(final Priority prio,
+ final Task t) {
+ return addSelect(prio, null, RelativeTime.ZERO, null, null, t);
}
/**
- * Get information about the current load of this scheduler. Use this
- * function to determine if an elective task should be added or simply
- * dropped (if the decision should be made based on the number of tasks
- * ready to run).
+ * Check if the system is still life. Trigger shutdown if we have tasks,
but
+ * none of them give us lifeness.
*
- * * @param p priority-level to query, use KEEP to query the level of the
- * current task, use COUNT to get the sum over all priority levels
- *
- * @return number of tasks pending right now
+ * @return true to continue the main loop, false to exit
*/
- public int getLoad(Priority p) {
- throw new UnsupportedOperationException();
+ private static boolean checkLiveness() {
+ if (ready_count > 0) {
+ return true;
+ }
+
+ for (final TaskIdentifier t : pending) {
+ if (t.liveness) {
+ return true;
+ }
+ }
+
+ for (final TaskIdentifier t : pending_timeout) {
+ if (t.liveness) {
+ return true;
+ }
+ }
+
+ if (!pending.isEmpty() || pending_timeout.isEmpty()) {
+ shutdown();
+ return true;
+ }
+
+ return false;
}
- /**
- * Obtain the reason code for why the current task was started. Will return
- * the same value as the GNUNET_SCHEDULER_TaskContext's reason field.
- *
- * * @return reason(s) why the current task is run
- */
- public EnumSet<Reason> getReason() {
- return active_task.ctx.reasons;
+ private static void queueReady(final TaskIdentifier tid) {
+ assert tid.priority != null;
+ ready.get(tid.priority.ordinal()).add(tid);
+ ready_count++;
}
+ private static void register(final TimeoutTask t) {
+ // register with selector
+ throw new UnsupportedOperationException();
+
+ }
+
/**
* Initialize and run scheduler. This function will return when all tasks
* have completed. On systems with signals, receiving a SIGTERM (and other
@@ -284,7 +296,7 @@
* task to run immediately
* @throws IOException
*/
- public static void run(Task task) throws IOException {
+ public static void run(final Task task) throws IOException {
current_priority = Priority.DEFAULT;
current_liveness = true;
@@ -300,10 +312,10 @@
timeout = RelativeTime.FOREVER;
}
- AbsoluteTime now = AbsoluteTime.now();
+ final AbsoluteTime now = AbsoluteTime.now();
while (true) {
- TimeoutTask t = pending_timeout.peek();
+ final TimeoutTask t = pending_timeout.peek();
if (t == null || t.timeout.compareTo(now) < 0) {
break;
@@ -316,9 +328,9 @@
selector.select(timeout.getMilliseconds());
- for (SelectionKey sk : selector.selectedKeys()) {
+ for (final SelectionKey sk : selector.selectedKeys()) {
sk.cancel();
- TimeoutTask tid = (TimeoutTask) sk.attachment();
+ final TimeoutTask tid = (TimeoutTask) sk.attachment();
if (!tid.selected) {
queueReady(tid);
} else {
@@ -330,18 +342,6 @@
}
}
- private static void register(TimeoutTask t) {
- // register with selector
- throw new UnsupportedOperationException();
-
- }
-
- private static void queueReady(TaskIdentifier tid) {
- assert tid.priority != null;
- ready.get(tid.priority.ordinal()).add(tid);
- ready_count++;
- }
-
/*-
* Execute tasks until there either
* - there are no ready tasks
@@ -355,7 +355,7 @@
// in contrast to the c implementation, p<=0 right here
for (int p = Priority._COUNT.ordinal(); p <= 0; p--) {
- TaskIdentifier tid = ready.get(p).pollFirst();
+ final TaskIdentifier tid = ready.get(p).pollFirst();
if (tid == null) {
break;
} else {
@@ -368,34 +368,38 @@
}
/**
- * Check if the system is still life. Trigger shutdown if we have tasks,
but
- * none of them give us lifeness.
+ * Request the shutdown of a scheduler. Marks all currently pending tasks
as
+ * ready because of shutdown. This will cause all tasks to run (as soon as
+ * possible, respecting priorities and prerequisite tasks). Note that tasks
+ * scheduled AFTER this call may still be delayed arbitrarily.
+ */
+ public static void shutdown() {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Get information about the current load of this scheduler. Use this
+ * function to determine if an elective task should be added or simply
+ * dropped (if the decision should be made based on the number of tasks
+ * ready to run).
*
- * @return true to continue the main loop, false to exit
+ * * @param p priority-level to query, use KEEP to query the level of the
+ * current task, use COUNT to get the sum over all priority levels
+ *
+ * @return number of tasks pending right now
*/
- private static boolean checkLiveness() {
- if (ready_count > 0) {
- return true;
- }
+ public int getLoad(final Priority p) {
+ throw new UnsupportedOperationException();
+ }
- for (TaskIdentifier t : pending) {
- if (t.liveness) {
- return true;
- }
- }
-
- for (TaskIdentifier t : pending_timeout) {
- if (t.liveness) {
- return true;
- }
- }
-
- if (!pending.isEmpty() || pending_timeout.isEmpty()) {
- shutdown();
- return true;
- }
-
- return false;
+ /**
+ * Obtain the reason code for why the current task was started. Will return
+ * the same value as the GNUNET_SCHEDULER_TaskContext's reason field.
+ *
+ * * @return reason(s) why the current task is run
+ */
+ public EnumSet<Reason> getReason() {
+ return active_task.ctx.reasons;
}
}
Modified: gnunet-java/src/org/gnunet/util/TransmitReadyNotify.java
===================================================================
--- gnunet-java/src/org/gnunet/util/TransmitReadyNotify.java 2011-11-30
15:21:36 UTC (rev 18410)
+++ gnunet-java/src/org/gnunet/util/TransmitReadyNotify.java 2011-12-01
01:00:29 UTC (rev 18411)
@@ -16,9 +16,8 @@
along with GNUnet; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.
-*/
+ */
-
package org.gnunet.util;
import java.nio.ByteBuffer;
@@ -34,5 +33,5 @@
// (buffer is initially at mark, data up to limit can be send at once,
// capacity may not be exceeded
public void transmit(ByteBuffer buf);
-
+
}
Modified: gnunet-java/src/org/gnunet/util/datastructures/BloomFilter.java
===================================================================
--- gnunet-java/src/org/gnunet/util/datastructures/BloomFilter.java
2011-11-30 15:21:36 UTC (rev 18410)
+++ gnunet-java/src/org/gnunet/util/datastructures/BloomFilter.java
2011-12-01 01:00:29 UTC (rev 18411)
@@ -25,140 +25,101 @@
/**
* Implementation of a Bloom-filter, as described here:
* http://en.wikipedia.org/wiki/Bloom_filter
- *
+ *
* For updates and bugfixes, see http://github.com/magnuss/java-bloomfilter
- *
+ *
* Inspired by the SimpleBloomFilter-class written by Ian Clarke. This
- * implementation provides a more evenly distributed Hash-function by
- * using a proper digest instead of the Java RNG. Many of the changes
- * were proposed in comments in his blog:
- *
http://blog.locut.us/2008/01/12/a-decent-stand-alone-java-bloom-filter-implementation/
- *
- * @param <E> Object type that is to be inserted into the Bloom filter, e.g.
String or Integer.
+ * implementation provides a more evenly distributed Hash-function by using a
+ * proper digest instead of the Java RNG. Many of the changes were proposed in
+ * comments in his blog:
+ * http://blog.locut.us/2008/01/12/a-decent-stand-alone-java
+ * -bloom-filter-implementation/
+ *
+ * @param <E>
+ * Object type that is to be inserted into the Bloom filter, e.g.
+ * String or Integer.
* @author Magnus Skjegstad <address@hidden>
*/
public class BloomFilter<E> implements Serializable {
private BitSet bitset;
private int bitSetSize;
private double bitsPerElement;
- private int expectedNumberOfFilterElements; // expected (maximum) number
of elements to be added
- private int numberOfAddedElements; // number of elements actually added to
the Bloom filter
+ private int expectedNumberOfFilterElements; // expected (maximum) number of
+ // elements to be added
+ private int numberOfAddedElements; // number of elements actually added to
+ // the Bloom filter
private int k; // number of hash functions
- static final Charset charset = Charset.forName("UTF-8"); // encoding used
for storing hash values as strings
+ static final Charset charset = Charset.forName("UTF-8"); // encoding used
+ // for storing
hash
+ // values as
+ // strings
- static final String hashName = "MD5"; // MD5 gives good enough accuracy in
most circumstances. Change to SHA1 if it's needed
+ static final String hashName = "MD5"; // MD5 gives good enough accuracy in
+ // most circumstances. Change to SHA1
+ // if it's needed
static final MessageDigest digestFunction;
static { // The digest method is reused between instances
MessageDigest tmp;
try {
tmp = java.security.MessageDigest.getInstance(hashName);
- } catch (NoSuchAlgorithmException e) {
+ } catch (final NoSuchAlgorithmException e) {
tmp = null;
}
digestFunction = tmp;
}
/**
- * Constructs an empty Bloom filter. The total length of the Bloom filter
will be
- * c*n.
- *
- * @param c is the number of bits used per element.
- * @param n is the expected number of elements the filter will contain.
- * @param k is the number of hash functions used.
- */
- public BloomFilter(double c, int n, int k) {
- this.expectedNumberOfFilterElements = n;
- this.k = k;
- this.bitsPerElement = c;
- this.bitSetSize = (int)Math.ceil(c * n);
- numberOfAddedElements = 0;
- this.bitset = new BitSet(bitSetSize);
- }
-
- /**
- * Constructs an empty Bloom filter. The optimal number of hash functions
(k) is estimated from the total size of the Bloom
- * and the number of expected elements.
- *
- * @param bitSetSize defines how many bits should be used in total for the
filter.
- * @param expectedNumberOElements defines the maximum number of elements
the filter is expected to contain.
- */
- public BloomFilter(int bitSetSize, int expectedNumberOElements) {
- this(bitSetSize / (double)expectedNumberOElements,
- expectedNumberOElements,
- (int) Math.round((bitSetSize / (double)expectedNumberOElements) *
Math.log(2.0)));
- }
-
- /**
- * Constructs an empty Bloom filter with a given false positive
probability. The number of bits per
- * element and the number of hash functions is estimated
- * to match the false positive probability.
- *
- * @param falsePositiveProbability is the desired false positive
probability.
- * @param expectedNumberOfElements is the expected number of elements in
the Bloom filter.
- */
- public BloomFilter(double falsePositiveProbability, int
expectedNumberOfElements) {
- this(Math.ceil(-(Math.log(falsePositiveProbability) / Math.log(2))) /
Math.log(2), // c = k / ln(2)
- expectedNumberOfElements,
- (int)Math.ceil(-(Math.log(falsePositiveProbability) /
Math.log(2)))); // k = ceil(-log_2(false prob.))
- }
-
- /**
- * Construct a new Bloom filter based on existing Bloom filter data.
- *
- * @param bitSetSize defines how many bits should be used for the filter.
- * @param expectedNumberOfFilterElements defines the maximum number of
elements the filter is expected to contain.
- * @param actualNumberOfFilterElements specifies how many elements have
been inserted into the <code>filterData</code> BitSet.
- * @param filterData a BitSet representing an existing Bloom filter.
- */
- public BloomFilter(int bitSetSize, int expectedNumberOfFilterElements, int
actualNumberOfFilterElements, BitSet filterData) {
- this(bitSetSize, expectedNumberOfFilterElements);
- this.bitset = filterData;
- this.numberOfAddedElements = actualNumberOfFilterElements;
- }
-
- /**
- * Generates a digest based on the contents of a String.
- *
- * @param val specifies the input data.
- * @param charset specifies the encoding of the input data.
+ * Generates a digest based on the contents of an array of bytes.
+ *
+ * @param data
+ * specifies input data.
* @return digest as long.
*/
- public static int createHash(String val, Charset charset) {
- return createHash(val.getBytes(charset));
+ public static int createHash(final byte[] data) {
+ return createHashes(data, 1)[0];
}
/**
* Generates a digest based on the contents of a String.
- *
- * @param val specifies the input data. The encoding is expected to be
UTF-8.
+ *
+ * @param val
+ * specifies the input data. The encoding is expected to be
+ * UTF-8.
* @return digest as long.
*/
- public static int createHash(String val) {
+ public static int createHash(final String val) {
return createHash(val, charset);
}
/**
- * Generates a digest based on the contents of an array of bytes.
- *
- * @param data specifies input data.
+ * Generates a digest based on the contents of a String.
+ *
+ * @param val
+ * specifies the input data.
+ * @param charset
+ * specifies the encoding of the input data.
* @return digest as long.
*/
- public static int createHash(byte[] data) {
- return createHashes(data, 1)[0];
+ public static int createHash(final String val, final Charset charset) {
+ return createHash(val.getBytes(charset));
}
/**
- * Generates digests based on the contents of an array of bytes and splits
the result into 4-byte int's and store them in an array. The
- * digest function is called until the required number of int's are
produced. For each call to digest a salt
- * is prepended to the data. The salt is increased by 1 for each call.
- *
- * @param data specifies input data.
- * @param hashes number of hashes/int's to produce.
+ * Generates digests based on the contents of an array of bytes and splits
+ * the result into 4-byte int's and store them in an array. The digest
+ * function is called until the required number of int's are produced. For
+ * each call to digest a salt is prepended to the data. The salt is
+ * increased by 1 for each call.
+ *
+ * @param data
+ * specifies input data.
+ * @param hashes
+ * number of hashes/int's to produce.
* @return array of int-sized hashes
*/
- public static int[] createHashes(byte[] data, int hashes) {
- int[] result = new int[hashes];
+ public static int[] createHashes(final byte[] data, final int hashes) {
+ final int[] result = new int[hashes];
int k = 0;
byte salt = 0;
@@ -167,14 +128,14 @@
synchronized (digestFunction) {
digestFunction.update(salt);
salt++;
- digest = digestFunction.digest(data);
+ digest = digestFunction.digest(data);
}
-
- for (int i = 0; i < digest.length/4 && k < hashes; i++) {
+
+ for (int i = 0; i < digest.length / 4 && k < hashes; i++) {
int h = 0;
- for (int j = (i*4); j < (i*4)+4; j++) {
+ for (int j = i * 4; j < i * 4 + 4; j++) {
h <<= 8;
- h |= ((int) digest[j]) & 0xFF;
+ h |= digest[j] & 0xFF;
}
result[k] = h;
k++;
@@ -184,100 +145,119 @@
}
/**
- * Compares the contents of two instances to see if they are equal.
- *
- * @param obj is the object to compare to.
- * @return True if the contents of the objects are equal.
+ * Constructs an empty Bloom filter with a given false positive
probability.
+ * The number of bits per element and the number of hash functions is
+ * estimated to match the false positive probability.
+ *
+ * @param falsePositiveProbability
+ * is the desired false positive probability.
+ * @param expectedNumberOfElements
+ * is the expected number of elements in the Bloom filter.
*/
- @Override
- public boolean equals(Object obj) {
- if (obj == null) {
- return false;
- }
- if (getClass() != obj.getClass()) {
- return false;
- }
- final BloomFilter<E> other = (BloomFilter<E>) obj;
- if (this.expectedNumberOfFilterElements !=
other.expectedNumberOfFilterElements) {
- return false;
- }
- if (this.k != other.k) {
- return false;
- }
- if (this.bitSetSize != other.bitSetSize) {
- return false;
- }
- if (this.bitset != other.bitset && (this.bitset == null ||
!this.bitset.equals(other.bitset))) {
- return false;
- }
- return true;
+ public BloomFilter(final double falsePositiveProbability,
+ final int expectedNumberOfElements) {
+ this(Math.ceil(-(Math.log(falsePositiveProbability) / Math.log(2)))
+ / Math.log(2), // c = k / ln(2)
+ expectedNumberOfElements, (int) Math.ceil(-(Math
+ .log(falsePositiveProbability) / Math.log(2)))); // k =
+ //
ceil(-log_2(false
+ //
prob.))
}
/**
- * Calculates a hash code for this class.
- * @return hash code representing the contents of an instance of this
class.
+ * Constructs an empty Bloom filter. The total length of the Bloom filter
+ * will be c*n.
+ *
+ * @param c
+ * is the number of bits used per element.
+ * @param n
+ * is the expected number of elements the filter will contain.
+ * @param k
+ * is the number of hash functions used.
*/
- @Override
- public int hashCode() {
- int hash = 7;
- hash = 61 * hash + (this.bitset != null ? this.bitset.hashCode() : 0);
- hash = 61 * hash + this.expectedNumberOfFilterElements;
- hash = 61 * hash + this.bitSetSize;
- hash = 61 * hash + this.k;
- return hash;
+ public BloomFilter(final double c, final int n, final int k) {
+ this.expectedNumberOfFilterElements = n;
+ this.k = k;
+ this.bitsPerElement = c;
+ this.bitSetSize = (int) Math.ceil(c * n);
+ numberOfAddedElements = 0;
+ this.bitset = new BitSet(bitSetSize);
}
+ /**
+ * Constructs an empty Bloom filter. The optimal number of hash functions
+ * (k) is estimated from the total size of the Bloom and the number of
+ * expected elements.
+ *
+ * @param bitSetSize
+ * defines how many bits should be used in total for the filter.
+ * @param expectedNumberOElements
+ * defines the maximum number of elements the filter is expected
+ * to contain.
+ */
+ public BloomFilter(final int bitSetSize, final int
expectedNumberOElements) {
+ this(bitSetSize / (double) expectedNumberOElements,
+ expectedNumberOElements, (int) Math.round(bitSetSize
+ / (double) expectedNumberOElements * Math.log(2.0)));
+ }
/**
- * Calculates the expected probability of false positives based on
- * the number of expected filter elements and the size of the Bloom filter.
- * <br /><br />
- * The value returned by this method is the <i>expected</i> rate of false
- * positives, assuming the number of inserted elements equals the number of
- * expected elements. If the number of elements in the Bloom filter is less
- * than the expected value, the true probability of false positives will
be lower.
- *
- * @return expected probability of false positives.
+ * Construct a new Bloom filter based on existing Bloom filter data.
+ *
+ * @param bitSetSize
+ * defines how many bits should be used for the filter.
+ * @param expectedNumberOfFilterElements
+ * defines the maximum number of elements the filter is expected
+ * to contain.
+ * @param actualNumberOfFilterElements
+ * specifies how many elements have been inserted into the
+ * <code>filterData</code> BitSet.
+ * @param filterData
+ * a BitSet representing an existing Bloom filter.
*/
- public double expectedFalsePositiveProbability() {
- return getFalsePositiveProbability(expectedNumberOfFilterElements);
+ public BloomFilter(final int bitSetSize,
+ final int expectedNumberOfFilterElements,
+ final int actualNumberOfFilterElements, final BitSet filterData) {
+ this(bitSetSize, expectedNumberOfFilterElements);
+ this.bitset = filterData;
+ this.numberOfAddedElements = actualNumberOfFilterElements;
}
/**
- * Calculate the probability of a false positive given the specified
- * number of inserted elements.
- *
- * @param numberOfElements number of inserted elements.
- * @return probability of a false positive.
+ * Adds an array of bytes to the Bloom filter.
+ *
+ * @param bytes
+ * array of bytes to add to the Bloom filter.
*/
- public double getFalsePositiveProbability(double numberOfElements) {
- // (1 - e^(-k * n / m)) ^ k
- return Math.pow((1 - Math.exp(-k * (double) numberOfElements
- / (double) bitSetSize)), k);
-
+ public void add(final byte[] bytes) {
+ final int[] hashes = createHashes(bytes, k);
+ for (final int hash : hashes) {
+ bitset.set(Math.abs(hash % bitSetSize), true);
+ }
+ numberOfAddedElements++;
}
/**
- * Get the current probability of a false positive. The probability is
calculated from
- * the size of the Bloom filter and the current number of elements added
to it.
- *
- * @return probability of false positives.
+ * Adds an object to the Bloom filter. The output from the object's
+ * toString() method is used as input to the hash functions.
+ *
+ * @param element
+ * is an element to register in the Bloom filter.
*/
- public double getFalsePositiveProbability() {
- return getFalsePositiveProbability(numberOfAddedElements);
+ public void add(final E element) {
+ add(element.toString().getBytes(charset));
}
-
/**
- * Returns the value chosen for K.<br />
- * <br />
- * K is the optimal number of hash functions based on the size
- * of the Bloom filter and the expected number of inserted elements.
- *
- * @return optimal k.
+ * Adds all elements from a Collection to the Bloom filter.
+ *
+ * @param c
+ * Collection of elements.
*/
- public int getK() {
- return k;
+ public void addAll(final Collection<? extends E> c) {
+ for (final E element : c) {
+ add(element);
+ }
}
/**
@@ -289,100 +269,129 @@
}
/**
- * Adds an object to the Bloom filter. The output from the object's
- * toString() method is used as input to the hash functions.
- *
- * @param element is an element to register in the Bloom filter.
+ * Returns true if the array of bytes could have been inserted into the
+ * Bloom filter. Use getFalsePositiveProbability() to calculate the
+ * probability of this being correct.
+ *
+ * @param bytes
+ * array of bytes to check.
+ * @return true if the array could have been inserted into the Bloom
filter.
*/
- public void add(E element) {
- add(element.toString().getBytes(charset));
+ public boolean contains(final byte[] bytes) {
+ final int[] hashes = createHashes(bytes, k);
+ for (final int hash : hashes) {
+ if (!bitset.get(Math.abs(hash % bitSetSize))) {
+ return false;
+ }
+ }
+ return true;
}
/**
- * Adds an array of bytes to the Bloom filter.
- *
- * @param bytes array of bytes to add to the Bloom filter.
+ * Returns true if the element could have been inserted into the Bloom
+ * filter. Use getFalsePositiveProbability() to calculate the probability
of
+ * this being correct.
+ *
+ * @param element
+ * element to check.
+ * @return true if the element could have been inserted into the Bloom
+ * filter.
*/
- public void add(byte[] bytes) {
- int[] hashes = createHashes(bytes, k);
- for (int hash : hashes)
- bitset.set(Math.abs(hash % bitSetSize), true);
- numberOfAddedElements ++;
+ public boolean contains(final E element) {
+ return contains(element.toString().getBytes(charset));
}
/**
- * Adds all elements from a Collection to the Bloom filter.
- * @param c Collection of elements.
+ * Returns true if all the elements of a Collection could have been
inserted
+ * into the Bloom filter. Use getFalsePositiveProbability() to calculate
the
+ * probability of this being correct.
+ *
+ * @param c
+ * elements to check.
+ * @return true if all the elements in c could have been inserted into the
+ * Bloom filter.
*/
- public void addAll(Collection<? extends E> c) {
- for (E element : c)
- add(element);
+ public boolean containsAll(final Collection<? extends E> c) {
+ for (final E element : c) {
+ if (!contains(element)) {
+ return false;
+ }
+ }
+ return true;
}
-
+
/**
- * Returns true if the element could have been inserted into the Bloom
filter.
- * Use getFalsePositiveProbability() to calculate the probability of this
- * being correct.
- *
- * @param element element to check.
- * @return true if the element could have been inserted into the Bloom
filter.
+ * Returns the number of elements added to the Bloom filter after it was
+ * constructed or after clear() was called.
+ *
+ * @return number of elements added to the Bloom filter.
*/
- public boolean contains(E element) {
- return contains(element.toString().getBytes(charset));
+ public int count() {
+ return this.numberOfAddedElements;
}
/**
- * Returns true if the array of bytes could have been inserted into the
Bloom filter.
- * Use getFalsePositiveProbability() to calculate the probability of this
- * being correct.
- *
- * @param bytes array of bytes to check.
- * @return true if the array could have been inserted into the Bloom
filter.
+ * Compares the contents of two instances to see if they are equal.
+ *
+ * @param obj
+ * is the object to compare to.
+ * @return True if the contents of the objects are equal.
*/
- public boolean contains(byte[] bytes) {
- int[] hashes = createHashes(bytes, k);
- for (int hash : hashes) {
- if (!bitset.get(Math.abs(hash % bitSetSize))) {
- return false;
- }
+ @Override
+ public boolean equals(final Object obj) {
+ if (obj == null) {
+ return false;
}
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+ final BloomFilter<E> other = (BloomFilter<E>) obj;
+ if (this.expectedNumberOfFilterElements !=
other.expectedNumberOfFilterElements) {
+ return false;
+ }
+ if (this.k != other.k) {
+ return false;
+ }
+ if (this.bitSetSize != other.bitSetSize) {
+ return false;
+ }
+ if (this.bitset != other.bitset
+ && (this.bitset == null || !this.bitset.equals(other.bitset)))
{
+ return false;
+ }
return true;
}
/**
- * Returns true if all the elements of a Collection could have been
inserted
- * into the Bloom filter. Use getFalsePositiveProbability() to calculate
the
- * probability of this being correct.
- * @param c elements to check.
- * @return true if all the elements in c could have been inserted into the
Bloom filter.
+ * Calculates the expected probability of false positives based on the
+ * number of expected filter elements and the size of the Bloom filter.
<br />
+ * <br />
+ * The value returned by this method is the <i>expected</i> rate of false
+ * positives, assuming the number of inserted elements equals the number of
+ * expected elements. If the number of elements in the Bloom filter is less
+ * than the expected value, the true probability of false positives will be
+ * lower.
+ *
+ * @return expected probability of false positives.
*/
- public boolean containsAll(Collection<? extends E> c) {
- for (E element : c)
- if (!contains(element))
- return false;
- return true;
+ public double expectedFalsePositiveProbability() {
+ return getFalsePositiveProbability(expectedNumberOfFilterElements);
}
/**
* Read a single bit from the Bloom filter.
- * @param bit the bit to read.
+ *
+ * @param bit
+ * the bit to read.
* @return true if the bit is set, false if it is not.
*/
- public boolean getBit(int bit) {
+ public boolean getBit(final int bit) {
return bitset.get(bit);
}
/**
- * Set a single bit in the Bloom filter.
- * @param bit is the bit to set.
- * @param value If true, the bit is set. If false, the bit is cleared.
- */
- public void setBit(int bit, boolean value) {
- bitset.set(bit, value);
- }
-
- /**
* Return the bit set used to store the Bloom filter.
+ *
* @return bit set representing the Bloom filter.
*/
public BitSet getBitSet() {
@@ -390,29 +399,31 @@
}
/**
- * Returns the number of bits in the Bloom filter. Use count() to retrieve
- * the number of inserted elements.
- *
- * @return the size of the bitset used by the Bloom filter.
+ * Get actual number of bits per element based on the number of elements
+ * that have currently been inserted and the length of the Bloom filter.
See
+ * also getExpectedBitsPerElement().
+ *
+ * @return number of bits per element.
*/
- public int size() {
- return this.bitSetSize;
+ public double getBitsPerElement() {
+ return this.bitSetSize / (double) numberOfAddedElements;
}
/**
- * Returns the number of elements added to the Bloom filter after it
- * was constructed or after clear() was called.
- *
- * @return number of elements added to the Bloom filter.
+ * Get expected number of bits per element when the Bloom filter is full.
+ * This value is set by the constructor when the Bloom filter is created.
+ * See also getBitsPerElement().
+ *
+ * @return expected number of bits per element.
*/
- public int count() {
- return this.numberOfAddedElements;
+ public double getExpectedBitsPerElement() {
+ return this.bitsPerElement;
}
/**
* Returns the expected number of elements to be inserted into the filter.
* This value is the same value as the one passed to the constructor.
- *
+ *
* @return expected number of elements.
*/
public int getExpectedNumberOfElements() {
@@ -420,22 +431,76 @@
}
/**
- * Get expected number of bits per element when the Bloom filter is full.
This value is set by the constructor
- * when the Bloom filter is created. See also getBitsPerElement().
- *
- * @return expected number of bits per element.
+ * Get the current probability of a false positive. The probability is
+ * calculated from the size of the Bloom filter and the current number of
+ * elements added to it.
+ *
+ * @return probability of false positives.
*/
- public double getExpectedBitsPerElement() {
- return this.bitsPerElement;
+ public double getFalsePositiveProbability() {
+ return getFalsePositiveProbability(numberOfAddedElements);
}
/**
- * Get actual number of bits per element based on the number of elements
that have currently been inserted and the length
- * of the Bloom filter. See also getExpectedBitsPerElement().
- *
- * @return number of bits per element.
+ * Calculate the probability of a false positive given the specified number
+ * of inserted elements.
+ *
+ * @param numberOfElements
+ * number of inserted elements.
+ * @return probability of a false positive.
*/
- public double getBitsPerElement() {
- return this.bitSetSize / (double)numberOfAddedElements;
+ public double getFalsePositiveProbability(final double numberOfElements) {
+ // (1 - e^(-k * n / m)) ^ k
+ return Math.pow(1 - Math.exp(-k * numberOfElements / bitSetSize), k);
+
}
-}
\ No newline at end of file
+
+ /**
+ * Returns the value chosen for K.<br />
+ * <br />
+ * K is the optimal number of hash functions based on the size of the Bloom
+ * filter and the expected number of inserted elements.
+ *
+ * @return optimal k.
+ */
+ public int getK() {
+ return k;
+ }
+
+ /**
+ * Calculates a hash code for this class.
+ *
+ * @return hash code representing the contents of an instance of this
class.
+ */
+ @Override
+ public int hashCode() {
+ int hash = 7;
+ hash = 61 * hash + (this.bitset != null ? this.bitset.hashCode() : 0);
+ hash = 61 * hash + this.expectedNumberOfFilterElements;
+ hash = 61 * hash + this.bitSetSize;
+ hash = 61 * hash + this.k;
+ return hash;
+ }
+
+ /**
+ * Set a single bit in the Bloom filter.
+ *
+ * @param bit
+ * is the bit to set.
+ * @param value
+ * If true, the bit is set. If false, the bit is cleared.
+ */
+ public void setBit(final int bit, final boolean value) {
+ bitset.set(bit, value);
+ }
+
+ /**
+ * Returns the number of bits in the Bloom filter. Use count() to retrieve
+ * the number of inserted elements.
+ *
+ * @return the size of the bitset used by the Bloom filter.
+ */
+ public int size() {
+ return this.bitSetSize;
+ }
+}
Modified: gnunet-java/test/org/gnunet/construct/ConstructTest.java
===================================================================
--- gnunet-java/test/org/gnunet/construct/ConstructTest.java 2011-11-30
15:21:36 UTC (rev 18410)
+++ gnunet-java/test/org/gnunet/construct/ConstructTest.java 2011-12-01
01:00:29 UTC (rev 18411)
@@ -1,86 +1,96 @@
package org.gnunet.construct;
+import java.math.BigInteger;
+
import org.gnunet.messages.MessageHeader;
+import org.gnunet.messages.QueryMessage;
import org.gnunet.messages.SimpleTestMessage;
import org.gnunet.messages.SimpleTestMessage2;
import org.gnunet.messages.SizeTestMessage;
-import org.gnunet.messages.StringTestMessage;
-import org.gnunet.messages.TestMessage3;
-import org.gnunet.messages.TestMessage4;
+import org.gnunet.messages.StringMessage;
import org.junit.Assert;
import org.junit.Test;
public class ConstructTest {
-
+
@Test
- public void test_SimpleTestMessage_1() {
- Parser op = Construct.makeParser(SimpleTestMessage.class);
- byte[] a = { 0x02, 0x01, // v1
- 0x00, 0x1c, // v2
- 0x00, 0x00, 0x00, 0x05 // nested
- };
- SimpleTestMessage m = Construct.parseWith(op, a, 0);
-
- Assert.assertTrue(m.v1 == ((0x02 << 8) | 0x01));
- Assert.assertTrue(m.v2 == 0x1c);
-
- Assert.assertEquals(8, Construct.estimateSize(m));
+ public void test_SimpleTestMessage() {
+ SimpleTestMessage stm = new SimpleTestMessage();
+ stm.v1 = 20;
+ stm.v2 = 21;
+ stm.mn = new SimpleTestMessage2();
+ stm.mn.value = 42;
+ stm.mns = new SimpleTestMessage2[5];
+ for (int i = 0; i < stm.mns.length; i++) {
+ stm.mns[i] = new SimpleTestMessage2();
+ stm.mns[i].value = i;
+ }
+
+ byte[] a = Construct.toBinary(stm);
+ SimpleTestMessage stm2 = Construct.parseAs(a, 0,
SimpleTestMessage.class);
+
+ Assert.assertEquals(stm.v1, stm2.v1);
+ Assert.assertEquals(stm.v2, stm2.v2);
+ Assert.assertEquals(stm.mn.value, stm2.mn.value);
+ Assert.assertEquals(stm.mns.length, stm2.mns.length);
+
+ for (int i = 0; i < stm.mns.length; i++) {
+ Assert.assertEquals(stm.mns[i].value, stm2.mns[i].value);
+
+ }
+
+
}
-
- @Test
- public void test_SimpleTestMessage_2() {
- SimpleTestMessage m1 = new SimpleTestMessage();
-
- m1.v1 = 42;
- m1.v2 = 420;
-
- m1.mn = new SimpleTestMessage2();
- m1.mn.value = 300;
-
- byte[] data = Construct.unparse(m1);
-
- SimpleTestMessage m2 = Construct
- .parse(data, 0, SimpleTestMessage.class);
-
- Assert.assertEquals(m1, m2);
-
+
+ public static String toHex(byte[] bytes) {
+ BigInteger bi = new BigInteger(1, bytes);
+ return String.format("%0" + (bytes.length << 1) + "X", bi);
}
-
+
@Test
- public void test_TestMessage3() {
- TestMessage3 tm3 = new TestMessage3();
- tm3.arr = new int[10];
+ public void test_StringMessage() {
+ StringMessage strm = new StringMessage();
+ strm.num = 58;
+ strm.str = "ab";
+ strm.num2 = 80;
+
+ byte[] a = Construct.toBinary(strm);
+ StringMessage strm2 = Construct.parseAs(a, 0, StringMessage.class);
+
+ for (byte b : a) {
+ System.out.print((char) b);
+ }
- int size = Construct.estimateSize(tm3);
-
- Assert.assertEquals(2 * 10, size);
-
- byte[] data = Construct.unparse(tm3);
-
- TestMessage3 tm3_2 = Construct.parse(data, 0, TestMessage3.class);
+ Assert.assertEquals(strm.num, strm2.num);
+ Assert.assertEquals(strm.num2, strm2.num2);
+ Assert.assertEquals(strm.str, strm2.str);
+
}
+
@Test
- public void test_TestMessage4() {
- TestMessage4 tm4 = new TestMessage4();
- tm4.tm3s = new TestMessage3[3];
-
- for (int i = 0; i < 3; ++i) {
- TestMessage3 tm3 = new TestMessage3();
- tm3.arr = new int[10];
- tm4.tm3s[i] = tm3;
- }
-
- tm4.value = 54;
-
- Assert.assertEquals(10*2*3 + 2, Construct.estimateSize(tm4));
+ public void test_QueryMessage() {
+ QueryMessage qm = new QueryMessage();
+ qm.header = new MessageHeader();
+ qm.header.type = 0x42;
+ qm.query = 0x43;
+ qm.varsize = new byte[]{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
- byte[] data = Construct.unparse(tm4);
- TestMessage4 tm4_2 = Construct.parse(data, 0, TestMessage4.class);
+ Construct.patchSizeFields(qm);
- // do equality check
- // [...]
+
+ byte[] a = Construct.toBinary(qm);
+
+
+ QueryMessage qm2 = Construct.parseAs(a, 0, QueryMessage.class);
+
+
+ Assert.assertEquals(qm.header.size, qm2.header.size);
+ Assert.assertEquals(qm.header.type, qm2.header.type);
+ Assert.assertEquals(qm.query, qm2.query);
+
+ Assert.assertArrayEquals(qm.varsize, qm2.varsize);
}
@@ -88,40 +98,39 @@
@Test
public void test_SizeTestMessage() {
SizeTestMessage stm = new SizeTestMessage();
+ stm.someValue = 42;
+ stm.rest = new byte[]{1,2,3,4,5};
- byte[] data = Construct.unparse(stm);
+ Construct.patchSizeFields(stm);
- int size = data[0] << 8 | data[1];
- Assert.assertEquals(size, Construct.estimateSize(stm));
+ byte[] a = Construct.toBinary(stm);
- SizeTestMessage stm_2 = Construct.parse(data, 0,
SizeTestMessage.class);
+ SizeTestMessage stm2 = Construct.parseAs(a, 0, SizeTestMessage.class);
- Assert.assertEquals(stm_2.total_size, Construct.estimateSize(stm_2));
+ Assert.assertEquals(stm.someValue, stm2.someValue);
+ Assert.assertEquals(stm.totalSize, stm2.totalSize);
+
+
+ Assert.assertArrayEquals(stm.rest, stm2.rest);
}
@Test
- public void test_StringTestMessage() {
- StringTestMessage stm = new StringTestMessage();
- stm.s = "Hallo, Welt!";
+ public void test_MessageHeader() {
+ MessageHeader h1 = new MessageHeader();
- byte[] data = Construct.unparse(stm);
+ h1.size = 42;
+ h1.type = 52;
- StringTestMessage stm_2 = Construct.parse(data, 0,
StringTestMessage.class);
+ byte[] a = Construct.toBinary(h1);
- Assert.assertEquals(stm.s, stm_2.s);
+ MessageHeader h2 = Construct.parseAs(a, 0, MessageHeader.class);
- }
-
- @Test
- public void test_MessageHeader() {
- MessageHeader h = new MessageHeader();
- h.type = 42;
- h.body = new byte[20];
+ byte[] b = Construct.toBinary(h2);
- byte[] data = Construct.unparse(h);
+ Assert.assertArrayEquals(a, b);
- MessageHeader h2 = Construct.parse(data, 0, MessageHeader.class);
+ Assert.assertEquals(h1.size, h2.size);
+ Assert.assertEquals(h1.type, h2.type);
}
-
}
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [GNUnet-SVN] r18411 - in gnunet-java: . .settings src/org/gnunet/construct src/org/gnunet/construct/parsers src/org/gnunet/messages src/org/gnunet/service src/org/gnunet/util src/org/gnunet/util/datastructures test/org/gnunet/construct,
gnunet <=