You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tuweni.apache.org by to...@apache.org on 2023/01/29 08:55:40 UTC

[incubator-tuweni] branch main updated: add README for bytes and uints

This is an automated email from the ASF dual-hosted git repository.

toulmean pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/incubator-tuweni.git


The following commit(s) were added to refs/heads/main by this push:
     new 65856804f add README for bytes and uints
     new c956581a5 Merge pull request #503 from atoulme/add_readmes
65856804f is described below

commit 65856804f46034e4a4233b27532ab0f0a7d0c34a
Author: Antoine Toulme <an...@lunar-ocean.com>
AuthorDate: Sun Jan 29 00:19:32 2023 -0800

    add README for bytes and uints
---
 bytes/README.md | 319 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 units/README.md | 141 +++++++++++++++++++++++++
 2 files changed, 460 insertions(+)

diff --git a/bytes/README.md b/bytes/README.md
new file mode 100644
index 000000000..14ef32eb6
--- /dev/null
+++ b/bytes/README.md
@@ -0,0 +1,319 @@
+<!---
+Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE
+file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file
+to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the
+License. You may obtain a copy of the License at
+ *
+http://www.apache.org/licenses/LICENSE-2.0
+ *
+Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
+an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
+specific language governing permissions and limitations under the License.
+ --->
+# Bytes
+
+# Getting started
+
+Apache Tuweni provides support for manipulating bytes.
+
+To get started, install the `bytes` library.
+
+With Maven:
+
+```xml
+<dependency>
+  <groupId>org.apache.tuweni</groupId>
+  <artifactId>bytes</artifactId>
+  <version>2.3.1</version> <!-- replace with latest release -->
+</dependency>
+```
+
+Or using Gradle:
+
+```groovy
+implementation("org.apache.tuweni:bytes:2.3.1") // replace with latest release
+```
+
+The [bytes library](https://tuweni.apache.org/docs/org.apache.tuweni.bytes/index.html) revolves mainly around the [`Bytes`](https://tuweni.apache.org/docs/org.apache.tuweni.bytes/-bytes/index.html) interface.
+
+This tutorial goes over the main uses of `Bytes`, from creating them to manipulating them.
+
+# Creating Bytes
+
+## From a bytes array:
+
+You can create `Bytes` objects by wrapping a native byte array:
+
+```java
+Bytes bytes = Bytes.wrap(new byte[] {1, 2, 3, 4});
+```
+
+Note the underlying array is not copied - any change to the byte array will change the Bytes object's behavior.
+
+You can also wrap with an offset and a size to select a portion of the array:
+
+```java
+// wrapping with an offset of 2 and a size of one byte
+Bytes bytes = Bytes.wrap(new byte[] {1, 2, 3, 4}, 2, 1);
+```
+
+## From a hex string:
+
+You can create `Bytes` objects from a hexadecimal-encoded string with the [`fromHexString`](https://tuweni.apache.org/docs/org.apache.tuweni.bytes/-bytes/from-hex-string.html) method:
+
+```java
+Bytes bytes = Bytes.fromHexString("0xdeadbeef");
+```
+
+The `"0x"` prefix is optional.
+
+However, this requires an even-sized string. For example, this succeeds:
+
+```java
+Bytes bytes = Bytes.fromHexString("01FF2A");
+```
+
+This fails:
+
+```java
+Bytes bytes = Bytes.fromHexString("1FF2A");
+```
+
+You can circumvent this with the [`fromHexStringLenient` method](https://tuweni.apache.org/docs/org.apache.tuweni.bytes/-bytes/from-hex-string-lenient.html):
+
+```java
+Bytes bytes = Bytes.fromHexStringLenient("1FF2A");
+```
+
+## From a base64-encoded string:
+
+You can create `Bytes` objects from a base64-encoded string with the [`fromBase64String`](https://tuweni.apache.org/docs/org.apache.tuweni.bytes/-bytes/from-base64-string.html) method:
+
+```java
+Bytes value = Bytes.fromBase64String("deadbeefISDAbest");
+```
+
+# From primitive types
+
+We also have convenience methods to create `Bytes` objects from primitive types.
+
+* [Bytes.of()](https://tuweni.apache.org/docs/org.apache.tuweni.bytes/-bytes/of.html)
+
+[Bytes.of()](https://tuweni.apache.org/docs/org.apache.tuweni.bytes/-bytes/of.html) takes a variadic argument of bytes:
+
+```java
+Bytes value = Bytes.of(0x00, 0x01, 0xff, 0x2a);
+```
+
+* [Bytes.ofUnsignedInt()](https://tuweni.apache.org/docs/org.apache.tuweni.bytes/-bytes/of-unsigned-int.html)
+* [Bytes.ofUnsignedLong()](https://tuweni.apache.org/docs/org.apache.tuweni.bytes/-bytes/of-unsigned-long.html)
+* [Bytes.ofUnsignedShort()](https://tuweni.apache.org/docs/org.apache.tuweni.bytes/-bytes/of-unsigned-short.html)
+
+```java
+Bytes value = Bytes.ofUnsignedInt(42);
+```
+
+## More wrapping
+### Use [`Bytes.wrapByteBuf(buffer)`](https://tuweni.apache.org/docs/org.apache.tuweni.bytes/-bytes/wrap-byte-buf.html) to wrap a Netty `ByteBuf` object as a `Bytes` object.
+
+```java
+ByteBuf buffer = Unpooled.buffer(42);
+Bytes.wrapByteBuf(buffer);
+```
+
+You can apply an offset and size parameter:
+
+```java
+Bytes value = Bytes.wrapByteBuf(buffer, 1, 1);
+```
+
+### Use [`Bytes.wrapByteBuffer(buffer)`](https://tuweni.apache.org/docs/org.apache.tuweni.bytes/-bytes/wrap-byte-buffer.html) to wrap a `ByteBuffer` object as a `Bytes` object.
+
+```java
+Bytes.wrapByteBuffer(buffer);
+```
+
+You can apply an offset and size parameter:
+
+```java
+Bytes value = Bytes.wrapByteBuffer(buffer, 1, 1);
+```
+
+### Use [`Bytes.wrapBuffer(buffer)`](https://tuweni.apache.org/docs/org.apache.tuweni.bytes/-bytes/wrap-byte-buffer.html) to wrap a Vert.x `Buffer` object as a `Bytes` object.
+
+```java
+Bytes.wrapBuffer(buffer);
+```
+
+You can apply an offset and size parameter:
+
+```java
+Bytes value = Bytes.wrapBuffer(buffer, 1, 1);
+```
+
+## Random
+
+You can create random bytes objects of a given length with the [Bytes.random() method](https://tuweni.apache.org/docs/org.apache.tuweni.bytes/-bytes/random.html):
+
+```java
+// create a Bytes object of 20 bytes:
+Bytes.random(20);
+```
+
+Create a Bytes object with our own Random implementation:
+
+```java
+Random random = new SecureRandom();
+...
+Bytes.random(20, random);
+```
+
+# Manipulating bytes
+
+## Concatenating and wrapping
+
+You can [concatenate](https://tuweni.apache.org/docs/org.apache.tuweni.bytes/-bytes/concatenate.html) or [wrap](https://tuweni.apache.org/docs/org.apache.tuweni.bytes/-bytes/wrap.html) bytes objects.
+
+When concatenating, the underlying objects are copied into a new bytes object.
+
+When wrapping, you are creating a *view* made of the underlying bytes objects. If their values change, the wrapped view changes as well.
+
+Of course, wrapping is preferrable to avoid copying bytes in memory.
+
+## Copying and slicing
+
+In the same spirit as above, you can [copy](https://tuweni.apache.org/docs/org.apache.tuweni.bytes/-bytes/copy.html) or [slice](https://tuweni.apache.org/docs/org.apache.tuweni.bytes/-bytes/slice.html) bytes objects. When you slice a bytes object, you create a view of the original bytes object, and the slice will change if the underlying bytes object changes. If you copy instead, you create a new copy of the bytes.
+
+```java
+// slice from the second byte:
+bytes.slice(2);
+// slice from the second byte to the fifth byte:
+bytes.slice(2, 5);
+```
+
+## Shifting bytes
+
+You can shift [right](https://tuweni.apache.org/docs/org.apache.tuweni.bytes/-bytes/shift-right.html) and [left](https://tuweni.apache.org/docs/org.apache.tuweni.bytes/-bytes/shift-left.html) the bits of a bytes object by a given distance.
+
+This is equivalent to the `<<<` or `>>>` operators in Java.
+
+## xor, or, and
+
+You can apply boolean operations to Bytes objects.
+
+* [xor](https://tuweni.apache.org/docs/org.apache.tuweni.bytes/-bytes/xor.html)
+* [or](https://tuweni.apache.org/docs/org.apache.tuweni.bytes/-bytes/or.html)
+* [and](https://tuweni.apache.org/docs/org.apache.tuweni.bytes/-bytes/and.html)
+
+Those methods take as argument the value to compare this value with, and return a new Bytes object that is the result of the boolean operation.
+
+If the argument and the value are different lengths, then the shorter will be zero-padded to the left.
+
+```java
+Bytes value = Bytes.fromHexString("0x01000001").xor(Bytes.fromHexString("0x01000000"));
+assertEquals(Bytes.fromHexString("0x00000001"), value);
+```
+
+## not
+
+The [`not` method](https://tuweni.apache.org/docs/org.apache.tuweni.bytes/-bytes/not.html) returns a bit-wise NOT of the bytes.
+
+```java
+Bytes value = Bytes.fromHexString("0x01000001").not();
+assertEquals(Bytes.fromHexString("0xfefffffe"), value);
+```
+
+## commonPrefix
+
+The [`commonPrefix` method](https://tuweni.apache.org/docs/org.apache.tuweni.bytes/-bytes/common-prefix.html) returns the common bytes both the value and the argument start with.
+
+# Extracting values
+You can extract values from a bytes object into native Java objects such as ints and longs, bytes, byte arrays and so on.
+
+Note all the methods here take an optional `ByteOrder` argument, defaulting to big endian by default.
+
+## toInt() and toLong()
+
+The [method `toInt()`](https://tuweni.apache.org/docs/org.apache.tuweni.bytes/-bytes/to-int.html) and the [method `toLong()`](https://tuweni.apache.org/docs/org.apache.tuweni.bytes/-bytes/to-long.html) respectively translate the bytes values into an int or a long, requiring respectively the value to be at most 4 or 8 bytes long.
+
+## get(i)
+
+The [`get(i)` method](/docs/org.apache.tuweni.bytes/-bytes/get.html) provides the byte at index `i`.
+
+## getInt(i) and getLong(i)
+
+The [method `getInt()`](https://tuweni.apache.org/docs/org.apache.tuweni.bytes/-bytes/get-int.html) and the [method `getLong()`](https://tuweni.apache.org/docs/org.apache.tuweni.bytes/-bytes/get-long.html) respectively return the next 4 or 8 bytes into an int or a long.
+
+## toArray() and toArrayUnsafe()
+
+The [method `toArray`](https://tuweni.apache.org/docs/org.apache.tuweni.bytes/-bytes/to-array.html) copies the bytes of the object into a new bytes array.
+
+The [method `toArrayUnsafe`](https://tuweni.apache.org/docs/org.apache.tuweni.bytes/-bytes/to-array-unsafe.html) makes available the underlying byte array of the object - modifying it changes the Bytes object. Note this is more performant as it doesn't allocate new memory.
+
+## To BigIntegers
+
+The [method `toUnsignedBigInteger`](https://tuweni.apache.org/docs/org.apache.tuweni.bytes/-bytes/to-unsigned-big-integer.html) creates a new unsigned BigInteger object with the contents of the Bytes object.
+You can also use the method [`toBigInteger`](https://tuweni.apache.org/docs/org.apache.tuweni.bytes/-bytes/to-big-integer.html) to represent Bytes as a signed integer, using the two's-complement representation.
+
+## Transforming Bytes into strings
+
+There is a sleuth of options to turn bytes into strings, and they all have different use cases.
+
+* The [method `toHexString`](https://tuweni.apache.org/docs/org.apache.tuweni.bytes/-bytes/to-hex-string.html) provides the value represented as hexadecimal, starting with "0x".
+* The [method `toUnprefixedHexString`](https://tuweni.apache.org/docs/org.apache.tuweni.bytes/-bytes/to-unprefixed-hex-string.html) provides the value represented as hexadecimal, no "0x" prefix though.
+* The [method `toShortHexString`](https://tuweni.apache.org/docs/org.apache.tuweni.bytes/-bytes/to-short-hex-string.html) provides the value represented as a minimal hexadecimal string (without any leading zero).
+* The [method `toQuantityHexString`](https://tuweni.apache.org/docs/org.apache.tuweni.bytes/-bytes/to-quantity-hex-string.html) provides the value represented as a minimal hexadecimal string (without any leading zero, except if it's valued zero or empty, in which case it returns 0x0).
+* The [method `toEllipsisHexString`](https://tuweni.apache.org/docs/org.apache.tuweni.bytes/-bytes/to-ellipsis-hex-string.html) provides the first 3 bytes and last 3 bytes represented as hexadecimal strings, joined with an ellipsis (`...`).
+
+By default, `toString()` calls `toHexString()`.
+
+# Mutable Bytes
+
+By default, bytes objects are not mutable. You can use [`MutableBytes` objects](https://tuweni.apache.org/docs/org.apache.tuweni.bytes/-mutable-bytes/index.html) instead.
+
+## Creating MutableBytes objects
+
+The methods described in the [tutorial "Creating Bytes"](https://tuweni.apache.org/tutorials/creating-bytes) all work in the same way for `MutableBytes`.
+
+You can call the [method `mutableCopy()`](https://tuweni.apache.org/docs/org.apache.tuweni.bytes/-mutable-bytes/mutable-copy.html) on any Bytes object to get a copy of the Bytes object as mutable.
+
+Finally, you can create fresh objects with the [`create()` method](https://tuweni.apache.org/docs/org.apache.tuweni.bytes/-mutable-bytes/create.html).
+
+## Fill, Clear
+
+Fill a MutableBytes with the same byte the [fill method](https://tuweni.apache.org/docs/org.apache.tuweni.bytes/-mutable-bytes/fill.html):
+
+```java
+MutableBytes bytes = MutableBytes.create(2);
+bytes.fill((byte) 34);
+assertEquals(Bytes.fromHexString("0x2222"), bytes);
+```
+
+You can clear the contents with the [`clear` method](/docs/org.apache.tuweni.bytes/-mutable-bytes/clear.html):
+
+```java
+MutableBytes bytes = MutableBytes.fromHexString("0xdeadbeef");
+bytes.clear();
+```
+
+## Setting values
+
+You can set values with different arguments:
+
+* The [`set(int i, byte b)` method](https://tuweni.apache.org/docs/org.apache.tuweni.bytes/-mutable-bytes/set.html) sets the value of a byte at index `i`.
+* The [`setInt(int i, int value)` method](https://tuweni.apache.org/docs/org.apache.tuweni.bytes/-mutable-bytes/set-int.html) sets the value of the next four bytes at index `i`.
+* The [`setLong(int i, long value)` method](https://tuweni.apache.org/docs/org.apache.tuweni.bytes/-mutable-bytes/set-long.html) sets the value of the next eight bytes at index `i`.
+* The [`set(int offset, Bytes bytes)` method](https://tuweni.apache.org/docs/org.apache.tuweni.bytes/-mutable-bytes/set.html) sets the value of the next bytes at index `i`.
+
+# Your own Bytes class
+
+You can create your very own implementation of `Bytes` by extending the [`AbstractBytes` class](https://tuweni.apache.org/docs/org.apache.tuweni.bytes/-abstract-bytes/index.html).
+
+You will need to implement the following functions:
+* [`get(i)`](https://tuweni.apache.org/docs/org.apache.tuweni.bytes/-bytes/get.html)
+* [`size()`](https://tuweni.apache.org/docs/org.apache.tuweni.bytes/-bytes/size.html)
+* [`slice(offset, size)`](https://tuweni.apache.org/docs/org.apache.tuweni.bytes/-bytes/slice.html)
+* [`copy(offset, size)`](https://tuweni.apache.org/docs/org.apache.tuweni.bytes/-bytes/copy.html)
+* [`mutableCopy(offset, size)`](https://tuweni.apache.org/docs/org.apache.tuweni.bytes/-bytes/mutable-copy.html)
+
+You can choose to simplify greatly by extending the [`DelegatingBytes` class](https://tuweni.apache.org/docs/org.apache.tuweni.bytes/-delegating-bytes/index.html) instead.
diff --git a/units/README.md b/units/README.md
new file mode 100644
index 000000000..0be400832
--- /dev/null
+++ b/units/README.md
@@ -0,0 +1,141 @@
+<!---
+Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE
+file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file
+to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the
+License. You may obtain a copy of the License at
+ *
+http://www.apache.org/licenses/LICENSE-2.0
+ *
+Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
+an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
+specific language governing permissions and limitations under the License.
+ --->
+# Units
+
+# Getting started
+
+Apache Tuweni provides support for manipulating unsigned integers and base Ethereum currencies.
+
+To get started, install the `units` library.
+
+With Maven:
+
+```xml
+<dependency>
+  <groupId>org.apache.tuweni</groupId>
+  <artifactId>units</artifactId>
+  <version>2.3.1</version> <!-- replace with latest release -->
+</dependency>
+```
+
+Or using Gradle:
+
+```groovy
+implementation("org.apache.tuweni:units:2.3.1") // replace with latest release
+```
+
+The [units library](https://tuweni.apache.org/docs/org.apache.tuweni.units.bigints/index.html) revolves mainly around the [`Uint256`](https://tuweni.apache.org/docs/org.apache.tuweni.units.bigints/-u-int256/index.html), [`Uint384`](https://tuweni.apache.org/docs/org.apache.tuweni.units.bigints/-u-int384/index.html)  and [`Uint64`](https://tuweni.apache.org/docs/org.apache.tuweni.units.bigints/-u-int64/index.html)  interfaces.
+
+This tutorial goes over the main uses of `Uint256` - you can apply the same behaviors over to `Uint384`, `Uint64` or `Uint32`.
+
+It will also touch on `Wei` and `Gas`.
+
+# Java API 
+
+NOTE: We are going to use the [`UInt256` class](https://tuweni.apache.org/docs/org.apache.tuweni.units.bigints/-u-int256/index.html) for all examples, but the same behaviors are possible with the [`UInt384`](https://tuweni.apache.org/docs/org.apache.tuweni.units.bigints/-u-int384/index.html), [`UInt64`](https://tuweni.apache.org/docs/org.apache.tuweni.units.bigints/-u-int64/index.html), [`UInt32`](https://tuweni.apache.org/docs/org.apache.tuweni.units.bigints/-u-int32/index.html) classes.
+
+We refer to those classes as `UInt`.
+
+# Creating Uints
+
+## `valueOf`
+
+You can initialize a `UInt` with the [static method `valueOf`](https://tuweni.apache.org/docs/org.apache.tuweni.units.bigints/-u-int256/value-of.html), with an integer, a long, or a BigInteger object. This only accepts positive values.
+
+```java
+// from an int
+UInt256 value = UInt256.valueOf(42);
+// from a long
+UInt256 value = UInt256.valueOf(42L);
+// from a BigInteger
+UInt256 value = UInt256.valueOf(BigInteger.ONE);
+```
+
+## `fromBytes`
+
+You can initialize a `UInt` from a `Bytes` object, using the [`fromBytes` method](https://tuweni.apache.org/docs/org.apache.tuweni.units.bigints/-u-int256/from-bytes.html).
+
+```java
+UInt256 value = UInt256.fromBytes(Bytes.wrap(new byte[] {0x01, 0x02, 0x03}));
+```
+
+## `fromHexString`
+
+You can initialize a `UInt` from a string representing a hexadecimal encoding of bytes, with an optional prefix of `0x`.
+
+```java
+UInt256 value = UInt256.fromHexString("0xdeadbeef");
+```
+
+# UInt operations
+
+`Uints` are immutable, so all operations create a new object as the result of the operation.
+
+## Arithmetic operations
+
+### Adding and subtracting
+
+* [`add(other)`](https://tuweni.apache.org/docs/org.apache.tuweni.units.bigints/-u-int256-value/add.html)
+* [`substract(other)`](https://tuweni.apache.org/docs/org.apache.tuweni.units.bigints/-u-int256-value/subtract.html)
+
+Since these are bound integers, they will overflow and underflow if the operation returns a value outside the boundaries - for a `Uint256`, 0 to 2^256.
+
+For this reason, the API also contains `exact` methods that throw exceptions if the operations overflows or underflows.
+
+* [`addExact(other)`](https://tuweni.apache.org/docs/org.apache.tuweni.units.bigints/-u-int256-value/add-exact.html)
+* [`subtractExact(other)`](https://tuweni.apache.org/docs/org.apache.tuweni.units.bigints/-u-int256-value/subtract-exact.html)
+
+### Multiplying and dividing
+
+* [`multiply(other)`](https://tuweni.apache.org/docs/org.apache.tuweni.units.bigints/-u-int256-value/multiply.html)
+* [`divide(other)`](https://tuweni.apache.org/docs/org.apache.tuweni.units.bigints/-u-int256-value/divide.html)
+
+Additionally, the [method `divideCeil(other)`](https://tuweni.apache.org/docs/org.apache.tuweni.units.bigints/-u-int256-value/divide-ceil.html) divides integers but returns the ceiling of the rounding.
+
+```java
+UInt256 result = UInt256.valueOf(12L).divide(UInt256.valueOf(5L)); // returns 2
+UInt256 resultCeiling = UInt256.valueOf(12L).divideCeil(UInt256.valueOf(5L)); // returns 3
+```
+
+### Modulus
+
+You can use the [method `mod(divisor)`](https://tuweni.apache.org/docs/org.apache.tuweni.units.bigints/-u-int256-value/mod.html) to get the modulus of the value by the divisor.
+
+The [method `mod0`](https://tuweni.apache.org/docs/org.apache.tuweni.units.bigints/-u-int256-value/mod0.html) is more forgiving - if you divide by zero, it will return zero instead of throwing an exception.
+
+### Power
+
+The [method `pow(exponent)`](https://tuweni.apache.org/docs/org.apache.tuweni.units.bigints/-u-int256-value/pow.html) returns a value that is `value^exponent mod 2^256.
+# Boolean operations
+You can use the following methods to perform boolean operations:
+* [`not()`: bit-wise NOT of this value.](https://tuweni.apache.org/docs/org.apache.tuweni.units.bigints/-u-int256/not.html)
+* [`and(other)`: bit-wise AND of this value and the supplied value.](https://tuweni.apache.org/docs/org.apache.tuweni.units.bigints/-u-int256/and.html)
+* [`or(other)`: bit-wise OR of this value and the supplied value.](https://tuweni.apache.org/docs/org.apache.tuweni.units.bigints/-u-int256/or.html)
+* [`xor(other)`: bit-wise XOR of this value and the supplied value.](https://tuweni.apache.org/docs/org.apache.tuweni.units.bigints/-u-int256/xor.html)
+# Shifting bytes
+You can shift [right](https://tuweni.apache.org/docs/org.apache.tuweni.units.bigints/-u-int256/shift-right.html) and [left](https://tuweni.apache.org/docs/org.apache.tuweni.units.bigints/-u-int256/shift-left.html) the bits of the underlying bytes object by a given distance.
+This is equivalent to the `<<<` or `>>>` operators in Java.
+
+# Your own UInt class
+
+You can create your own domain class based off the `Uints`. A good example is the [`Wei class`](https://tuweni.apache.org/docs/org.apache.tuweni.units.ethereum/-wei/index.html).
+
+You will need to provide the super constructor the constructor of your class.
+
+```java
+public final class Wei extends BaseUInt256Value<Wei> { 
+  private Wei(UInt256 bytes) {
+    super(bytes, Wei::new);
+  }
+}
+```
\ No newline at end of file


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@tuweni.apache.org
For additional commands, e-mail: commits-help@tuweni.apache.org