iterator() { return _map.keySet().iterator(); }
+
+ public LongIterator longIterator() {
+ return (LongIterator) _map.keySet().iterator();
+ }
+
+ // ---
+
+ /**
+ * Atomically make the set immutable. Future calls to mutate will throw an
+ * IllegalStateException. Existing mutator calls in other threads racing
+ * with this thread and will either throw IllegalStateException or their
+ * update will be visible to this thread. This implies that a simple flag
+ * cannot make the Set immutable, because a late-arriving update in another
+ * thread might see immutable flag not set yet, then mutate the Set after
+ * the {@link #readOnly} call returns. This call can be called concurrently
+ * (and indeed until the operation completes, all calls on the Set from any
+ * thread either complete normally or end up calling {@link #readOnly}
+ * internally).
+ *
+ * This call is useful in debugging multi-threaded programs where the
+ * Set is constructed in parallel, but construction completes after some
+ * time; and after construction the Set is only read. Making the Set
+ * read-only will cause updates arriving after construction is supposedly
+ * complete to throw an {@link IllegalStateException}.
+ */
+
+ // (1) call _map's immutable() call
+ // (2) get snapshot
+ // (3) CAS down a local map, power-of-2 larger than _map.size()+1/8th
+ // (4) start @ random, visit all snapshot, insert live keys
+ // (5) CAS _map to null, needs happens-after (4)
+ // (6) if Set call sees _map is null, needs happens-after (4) for readers
+ public void readOnly() {
+ throw new RuntimeException("Unimplemented");
+ }
+}
diff --git a/src/main/java/it/tdlight/commonutil/NonBlockingSetInt.java b/src/main/java/it/tdlight/commonutil/NonBlockingSetInt.java
new file mode 100644
index 0000000..9207cfb
--- /dev/null
+++ b/src/main/java/it/tdlight/commonutil/NonBlockingSetInt.java
@@ -0,0 +1,725 @@
+/*
+ * Written by Cliff Click and released to the public domain, as explained at
+ * http://creativecommons.org/licenses/publicdomain
+ */
+
+package it.tdlight.commonutil;
+
+import java.io.IOException;
+import java.io.Serializable;
+import java.lang.reflect.Field;
+import java.util.AbstractSet;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+import java.util.concurrent.atomic.AtomicInteger;
+import org.jctools.maps.ConcurrentAutoTable;
+import org.jctools.util.UnsafeAccess;
+import sun.misc.Unsafe;
+
+/**
+ * A multi-threaded bit-vector set, implemented as an array of primitive
+ * {@code longs}. All operations are non-blocking and multi-threaded safe.
+ * {@link #contains(int)} calls are roughly the same speed as a {load, mask}
+ * sequence. {@link #add(int)} and {@link #remove(int)} calls are a tad more
+ * expensive than a {load, mask, store} sequence because they must use a CAS.
+ * The bit-vector is auto-sizing.
+ *
+ *
General note of caution: The Set API allows the use of {@link Integer}
+ * with silent autoboxing - which can be very expensive if many calls are
+ * being made. Since autoboxing is silent you may not be aware that this is
+ * going on. The built-in API takes lower-case {@code ints} and is much more
+ * efficient.
+ *
+ *
Space: space is used in proportion to the largest element, as opposed to
+ * the number of elements (as is the case with hash-table based Set
+ * implementations). Space is approximately (largest_element/8 + 64) bytes.
+ *
+ * The implementation is a simple bit-vector using CAS for update.
+ *
+ * @since 1.5
+ * @author Cliff Click
+ */
+
+public class NonBlockingSetInt extends AbstractSet implements Serializable {
+ private static final long serialVersionUID = 1234123412341234123L;
+ private static final Unsafe _unsafe = UnsafeAccess.UNSAFE;
+
+ // --- Bits to allow atomic update of the NBSI
+ private static final long _nbsi_offset;
+ static { //
+ Field f = null;
+ try {
+ f = NonBlockingSetInt.class.getDeclaredField("_nbsi");
+ } catch( NoSuchFieldException e ) {
+ }
+ _nbsi_offset = _unsafe.objectFieldOffset(f);
+ }
+ private final boolean CAS_nbsi( NBSI old, NBSI nnn ) {
+ return _unsafe.compareAndSwapObject(this, _nbsi_offset, old, nnn );
+ }
+
+ // The actual Set of Joy, which changes during a resize event. The
+ // Only Field for this class, so I can atomically change the entire
+ // set implementation with a single CAS.
+ private transient NBSI _nbsi;
+
+ /** Create a new empty bit-vector */
+ public NonBlockingSetInt( ) {
+ _nbsi = new NBSI(63, new ConcurrentAutoTable(), this); // The initial 1-word set
+ }
+
+ private NonBlockingSetInt(NonBlockingSetInt a, NonBlockingSetInt b) {
+ _nbsi = new NBSI(a._nbsi,b._nbsi,new ConcurrentAutoTable(),this);
+ }
+
+ /**
+ * Overridden to avoid auto-boxing for NonBlockingSetInt.
+ *
+ * @param c The collection to add to this set.
+ * @return True if the set was modified.
+ */
+ @Override
+ public boolean addAll(Collection extends Integer> c) {
+ if (!NonBlockingSetInt.class.equals(c.getClass())) {
+ return super.addAll(c);
+ }
+ boolean modified = false;
+ for (final IntIterator it = ((NonBlockingSetInt)c).intIterator(); it.hasNext(); ) {
+ modified |= add(it.next());
+ }
+ return modified;
+ }
+
+ /**
+ * Overridden to avoid auto-boxing for NonBlockingSetInt.
+ *
+ * @param c The collection to remove from this set.
+ * @return True if the set was modified.
+ */
+ @Override
+ public boolean removeAll(Collection> c) {
+ if (!NonBlockingSetInt.class.equals(c.getClass())) {
+ return super.removeAll(c);
+ }
+ boolean modified = false;
+ for (final IntIterator it = ((NonBlockingSetInt)c).intIterator(); it.hasNext(); ) {
+ modified |= remove(it.next());
+ }
+ return modified;
+ }
+
+ @Override
+ public boolean containsAll(Collection> c) {
+ if (!NonBlockingSetInt.class.equals(c.getClass())) {
+ return super.containsAll(c);
+ }
+ for (final IntIterator it = ((NonBlockingSetInt)c).intIterator(); it.hasNext(); ) {
+ if (!contains(it.next())) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ @Override
+ public boolean retainAll(Collection> c) {
+ if (!NonBlockingSetInt.class.equals(c.getClass())) {
+ return super.retainAll(c);
+ }
+ boolean modified = false;
+ final NonBlockingSetInt nonBlockingSetInt = (NonBlockingSetInt) c;
+ for (final IntIterator it = intIterator(); it.hasNext(); ) {
+ if (!nonBlockingSetInt.contains(it.next())) {
+ it.remove();
+ modified = true;
+ }
+ }
+ return modified;
+ }
+
+ @Override
+ public int hashCode() {
+ int hashCode = 0;
+ for (final IntIterator it = intIterator(); it.hasNext(); ) {
+ hashCode += it.next();
+ }
+ return hashCode;
+ }
+
+ /**
+ * Add {@code i} to the set. Uppercase {@link Integer} version of add,
+ * requires auto-unboxing. When possible use the {@code int} version of
+ * {@link #add(int)} for efficiency.
+ * @throws IllegalArgumentException if i is negative.
+ * @return true if i was added to the set.
+ */
+ @Override
+ public boolean add ( final Integer i ) {
+ return add(i.intValue());
+ }
+ /**
+ * Test if {@code o} is in the set. This is the uppercase {@link Integer}
+ * version of contains, requires a type-check and auto-unboxing. When
+ * possible use the {@code int} version of {@link #contains(int)} for
+ * efficiency.
+ * @return true if i was in the set.
+ */
+ @Override
+ public boolean contains( final Object o ) {
+ return o instanceof Integer && contains(((Integer) o).intValue());
+ }
+ /**
+ * Remove {@code o} from the set. This is the uppercase {@link Integer}
+ * version of remove, requires a type-check and auto-unboxing. When
+ * possible use the {@code int} version of {@link #remove(int)} for
+ * efficiency.
+ * @return true if i was removed to the set.
+ */
+ @Override
+ public boolean remove( final Object o ) {
+ return o instanceof Integer && remove(((Integer) o).intValue());
+ }
+
+ /**
+ * Add {@code i} to the set. This is the lower-case '{@code int}' version
+ * of {@link #add} - no autoboxing. Negative values throw
+ * IllegalArgumentException.
+ * @throws IllegalArgumentException if i is negative.
+ * @return true if i was added to the set.
+ */
+ public boolean add( final int i ) {
+ if( i < 0 ) throw new IllegalArgumentException(""+i);
+ return _nbsi.add(i);
+ }
+ /**
+ * Test if {@code i} is in the set. This is the lower-case '{@code int}'
+ * version of {@link #contains} - no autoboxing.
+ * @return true if i was int the set.
+ */
+ public boolean contains( final int i ) { return i >= 0 && _nbsi.contains(i); }
+ /**
+ * Remove {@code i} from the set. This is the fast lower-case '{@code int}'
+ * version of {@link #remove} - no autoboxing.
+ * @return true if i was added to the set.
+ */
+ public boolean remove ( final int i ) { return i >= 0 && _nbsi.remove(i); }
+
+ /**
+ * Current count of elements in the set. Due to concurrent racing updates,
+ * the size is only ever approximate. Updates due to the calling thread are
+ * immediately visible to calling thread.
+ * @return count of elements.
+ */
+ @Override
+ public int size ( ) { return _nbsi.size( ); }
+ /** Empty the bitvector. */
+ @Override
+ public void clear ( ) {
+ NBSI cleared = new NBSI(63, new ConcurrentAutoTable(), this); // An empty initial NBSI
+ while( !CAS_nbsi( _nbsi, cleared ) ) // Spin until clear works
+ ;
+ }
+
+ @Override
+ public String toString() {
+ // Overloaded to avoid auto-boxing
+ final IntIterator it = intIterator();
+ if (!it.hasNext()) {
+ return "[]";
+ }
+ final StringBuilder sb = new StringBuilder().append('[');
+ for (;;) {
+ sb.append(it.next());
+ if (!it.hasNext()) {
+ return sb.append(']').toString();
+ }
+ sb.append(", ");
+ }
+ }
+
+ public int sizeInBytes() { return _nbsi.sizeInBytes(); }
+
+ /*****************************************************************
+ *
+ * bitwise comparisons optimised for NBSI
+ *
+ *****************************************************************/
+
+ public NonBlockingSetInt intersect(final NonBlockingSetInt op) {
+ NonBlockingSetInt res = new NonBlockingSetInt(this,op);
+ res._nbsi.intersect(res._nbsi, this._nbsi, op._nbsi);
+ return res;
+ }
+
+ public NonBlockingSetInt union(final NonBlockingSetInt op) {
+ NonBlockingSetInt res = new NonBlockingSetInt(this,op);
+ res._nbsi.union(res._nbsi, this._nbsi, op._nbsi);
+ return res;
+ }
+
+// public NonBlockingSetInt not(final NonBlockingSetInt op) {
+//
+// }
+
+ /** Verbose printout of internal structure for debugging. */
+ public void print() { _nbsi.print(0); }
+
+ /**
+ * Standard Java {@link Iterator}. Not very efficient because it
+ * auto-boxes the returned values.
+ */
+ @Override
+ public Iterator iterator( ) { return new iter(); }
+
+ public IntIterator intIterator() { return new NBSIIntIterator(); }
+
+ private class NBSIIntIterator implements IntIterator {
+
+ NBSI nbsi;
+ int index = -1;
+ int prev = -1;
+
+ NBSIIntIterator() {
+ nbsi = _nbsi;
+ advance();
+ }
+
+ private void advance() {
+ while( true ) {
+ index++; // Next index
+ while( (index>>6) >= nbsi._bits.length ) { // Index out of range?
+ if( nbsi._new == null ) { // New table?
+ index = -2; // No, so must be all done
+ return; //
+ }
+ nbsi = nbsi._new; // Carry on, in the new table
+ }
+ if( nbsi.contains(index) ) return;
+ }
+ }
+ @Override
+ public int next() {
+ if( index == -1 ) throw new NoSuchElementException();
+ prev = index;
+ advance();
+ return prev;
+ }
+
+ @Override
+ public boolean hasNext() {
+ return index != -2;
+ }
+
+ @Override
+ public void remove() {
+ if( prev == -1 ) throw new IllegalStateException();
+ nbsi.remove(prev);
+ prev = -1;
+ }
+ }
+
+ private class iter implements Iterator {
+ NBSIIntIterator intIterator;
+ iter() { intIterator = new NBSIIntIterator(); }
+ @Override
+ public boolean hasNext() { return intIterator.hasNext(); }
+ @Override
+ public Integer next() { return intIterator.next(); }
+ @Override
+ public void remove() { intIterator.remove(); }
+ }
+
+ // --- writeObject -------------------------------------------------------
+ // Write a NBSI to a stream
+ private void writeObject(java.io.ObjectOutputStream s) throws IOException {
+ s.defaultWriteObject(); // Nothing to write
+ final NBSI nbsi = _nbsi; // The One Field is transient
+ final int len = _nbsi._bits.length<<6;
+ s.writeInt(len); // Write max element
+ for( int i=0; i= 0 && idx < ary.length;
+ return _Lbase + idx * _Lscale;
+ }
+ private final boolean CAS( int idx, long old, long nnn ) {
+ return _unsafe.compareAndSwapLong( _bits, rawIndex(_bits, idx), old, nnn );
+ }
+
+ // --- Resize
+ // The New Table, only set once to non-zero during a resize.
+ // Must be atomically set.
+ private NBSI _new;
+ private static final long _new_offset;
+ static { //
+ Field f = null;
+ try {
+ f = NBSI.class.getDeclaredField("_new");
+ } catch( NoSuchFieldException e ) {
+ }
+ _new_offset = _unsafe.objectFieldOffset(f);
+ }
+ private final boolean CAS_new( NBSI nnn ) {
+ return _unsafe.compareAndSwapObject(this, _new_offset, null, nnn );
+ }
+
+ private transient final AtomicInteger _copyIdx; // Used to count bits started copying
+ private transient final AtomicInteger _copyDone; // Used to count words copied in a resize operation
+ private transient final int _sum_bits_length; // Sum of all nested _bits.lengths
+
+ private static final long mask( int i ) { return 1L<<(i&63); }
+
+ // I need 1 free bit out of 64 to allow for resize. I do this by stealing
+ // the high order bit - but then I need to do something with adding element
+ // number 63 (and friends). I could use a mod63 function but it's more
+ // efficient to handle the mod-64 case as an exception.
+ //
+ // Every 64th bit is put in it's own recursive bitvector. If the low 6 bits
+ // are all set, we shift them off and recursively operate on the _nbsi64 set.
+ private final NBSI _nbsi64;
+
+ private NBSI(int max_elem, ConcurrentAutoTable ctr, NonBlockingSetInt nonb ) {
+ super();
+ _non_blocking_set_int = nonb;
+ _size = ctr;
+ _copyIdx = ctr == null ? null : new AtomicInteger();
+ _copyDone = ctr == null ? null : new AtomicInteger();
+ // The main array of bits
+ _bits = new long[(int)(((long)max_elem+63)>>>6)];
+ // Every 64th bit is moved off to it's own subarray, so that the
+ // sign-bit is free for other purposes
+ _nbsi64 = ((max_elem+1)>>>6) == 0 ? null : new NBSI((max_elem+1)>>>6, null, null);
+ _sum_bits_length = _bits.length + (_nbsi64==null ? 0 : _nbsi64._sum_bits_length);
+ }
+
+ /** built a new NBSI with buffers large enough to hold bitwise operations on the operands **/
+ private NBSI(NBSI a, NBSI b, ConcurrentAutoTable ctr, NonBlockingSetInt nonb) {
+ super();
+ _non_blocking_set_int = nonb;
+ _size = ctr;
+ _copyIdx = ctr == null ? null : new AtomicInteger();
+ _copyDone = ctr == null ? null : new AtomicInteger();
+
+ if(!has_bits(a) && !has_bits(b)) {
+ _bits = null;
+ _nbsi64 = null;
+ _sum_bits_length = 0;
+ return;
+ }
+
+ // todo - clean this nastiness up
+ // essentially just safely creates new empty buffers for each of the recursive bitsets
+ if(!has_bits(a)) {
+ _bits = new long[b._bits.length];
+ _nbsi64 = new NBSI(null,b._nbsi64,null,null);
+ } else if(!has_bits(b)) {
+ _bits = new long[a._bits.length];
+ _nbsi64 = new NBSI(null,a._nbsi64,null,null);
+ } else {
+ int bit_length = a._bits.length > b._bits.length ? a._bits.length : b._bits.length;
+ _bits = new long[bit_length];
+ _nbsi64 = new NBSI(a._nbsi64,b._nbsi64,null,null);
+ }
+ _sum_bits_length = _bits.length + _nbsi64._sum_bits_length;
+ }
+
+ private static boolean has_bits(NBSI n) {
+ return n != null && n._bits != null;
+ }
+
+ // Lower-case 'int' versions - no autoboxing, very fast.
+ // 'i' is known positive.
+ public boolean add( final int i ) {
+ // Check for out-of-range for the current size bit vector.
+ // If so we need to grow the bit vector.
+ if( (i>>6) >= _bits.length )
+ return install_larger_new_bits(i). // Install larger pile-o-bits (duh)
+ help_copy().add(i); // Finally, add to the new table
+
+ // Handle every 64th bit via using a nested array
+ NBSI nbsi = this; // The bit array being added into
+ int j = i; // The bit index being added
+ while( (j&63) == 63 ) { // Bit 64? (low 6 bits are all set)
+ nbsi = nbsi._nbsi64; // Recurse
+ j = j>>6; // Strip off low 6 bits (all set)
+ }
+
+ final long mask = mask(j);
+ long old;
+ do {
+ old = nbsi._bits[j>>6]; // Read old bits
+ if( old < 0 ) // Not mutable?
+ // Not mutable: finish copy of word, and retry on copied word
+ return help_copy_impl(i).help_copy().add(i);
+ if( (old & mask) != 0 ) return false; // Bit is already set?
+ } while( !nbsi.CAS( j>>6, old, old | mask ) );
+ _size.add(1);
+ return true;
+ }
+
+ public boolean remove( final int i ) {
+ if( (i>>6) >= _bits.length ) // Out of bounds? Not in this array!
+ return _new==null ? false : help_copy().remove(i);
+
+ // Handle every 64th bit via using a nested array
+ NBSI nbsi = this; // The bit array being added into
+ int j = i; // The bit index being added
+ while( (j&63) == 63 ) { // Bit 64? (low 6 bits are all set)
+ nbsi = nbsi._nbsi64; // Recurse
+ j = j>>6; // Strip off low 6 bits (all set)
+ }
+
+ final long mask = mask(j);
+ long old;
+ do {
+ old = nbsi._bits[j>>6]; // Read old bits
+ if( old < 0 ) // Not mutable?
+ // Not mutable: finish copy of word, and retry on copied word
+ return help_copy_impl(i).help_copy().remove(i);
+ if( (old & mask) == 0 ) return false; // Bit is already clear?
+ } while( !nbsi.CAS( j>>6, old, old & ~mask ) );
+ _size.add(-1);
+ return true;
+ }
+
+ public boolean contains( final int i ) {
+ if( (i>>6) >= _bits.length ) // Out of bounds? Not in this array!
+ return _new==null ? false : help_copy().contains(i);
+
+ // Handle every 64th bit via using a nested array
+ NBSI nbsi = this; // The bit array being added into
+ int j = i; // The bit index being added
+ while( (j&63) == 63 ) { // Bit 64? (low 6 bits are all set)
+ nbsi = nbsi._nbsi64; // Recurse
+ j = j>>6; // Strip off low 6 bits (all set)
+ }
+
+ final long mask = mask(j);
+ long old = nbsi._bits[j>>6]; // Read old bits
+ if( old < 0 ) // Not mutable?
+ // Not mutable: finish copy of word, and retry on copied word
+ return help_copy_impl(i).help_copy().contains(i);
+ // Yes mutable: test & return bit
+ return (old & mask) != 0;
+ }
+
+ /**
+ * Bitwise operations which store the result in this instance.
+ * Assumes that this instance contains ample buffer space to store the largest
+ * buffer from each NBSI in the recursive bitmap.
+ *
+ * Also assumes that this method is called during the construction process of
+ * the bitset before the instance could be leaked to multiple threads.
+ ***/
+ public boolean intersect(NBSI dest, NBSI a, NBSI b) {
+ // terminate recursion if one bitset is missing data
+ // since that word should be left as 0L anyway
+ if(!has_bits(a) || !has_bits(b))
+ return true;
+ for(int i = 0; i < dest._bits.length; i++) {
+ long left = a.safe_read_word(i,0L);
+ long right = b.safe_read_word(i,0L);
+ dest._bits[i] = (left & right) & Long.MAX_VALUE; // mask sign bit
+ }
+ // todo - recompute size
+ return intersect(dest._nbsi64, a._nbsi64, b._nbsi64);
+ }
+
+ public boolean union(NBSI dest, NBSI a, NBSI b) {
+ // terminate recursion if neiter bitset has data
+ if(!has_bits(a) && !has_bits(b))
+ return true;
+ if(has_bits(a) || has_bits(b)) {
+ for(int i = 0; i < dest._bits.length; i++) {
+ long left = a == null ? 0L : a.safe_read_word(i,0);
+ long right = b == null ? 0L : b.safe_read_word(i,0);
+ dest._bits[i] = (left | right) & Long.MAX_VALUE;
+ }
+ }
+ return union(dest._nbsi64, a == null ? null : a._nbsi64, b == null ? null : b._nbsi64);
+ }
+
+ /**************************************************************************/
+
+ private long safe_read_word(int i, long default_word) {
+ if(i >= _bits.length) {
+ // allow reading past the end of the buffer filling in a default word
+ return default_word;
+ }
+ long word = _bits[i];
+ if(word < 0) {
+ NBSI nb = help_copy_impl(i);
+ if(nb._non_blocking_set_int == null) {
+ return default_word;
+ }
+ word = nb.help_copy()._bits[i];
+ }
+ return word;
+ }
+
+ public int sizeInBytes() { return (int)_bits.length; }
+
+ public int size() { return (int)_size.get(); }
+
+ // Must grow the current array to hold an element of size i
+ private NBSI install_larger_new_bits( final int i ) {
+ if( _new == null ) {
+ // Grow by powers of 2, to avoid minor grow-by-1's.
+ // Note: must grow by exact powers-of-2 or the by-64-bit trick doesn't work right
+ int sz = (_bits.length<<6)<<1;
+ // CAS to install a new larger size. Did it work? Did it fail? We
+ // don't know and don't care. Only One can be installed, so if
+ // another thread installed a too-small size, we can't help it - we
+ // must simply install our new larger size as a nested-resize table.
+ CAS_new(new NBSI(sz, _size, _non_blocking_set_int));
+ }
+ // Return self for 'fluid' programming style
+ return this;
+ }
+
+ // Help any top-level NBSI to copy until completed.
+ // Always return the _new version of *this* NBSI, in case we're nested.
+ private NBSI help_copy() {
+ // Pick some words to help with - but only help copy the top-level NBSI.
+ // Nested NBSI waits until the top is done before we start helping.
+ NBSI top_nbsi = _non_blocking_set_int._nbsi;
+ final int HELP = 8; // Tuning number: how much copy pain are we willing to inflict?
+ // We "help" by forcing individual bit indices to copy. However, bits
+ // come in lumps of 64 per word, so we just advance the bit counter by 64's.
+ int idx = top_nbsi._copyIdx.getAndAdd(64*HELP);
+ for( int i=0; i>6; // Strip off low 6 bits (all set)
+ }
+
+ // Transit from state 1: word is not immutable yet
+ // Immutable is in bit 63, the sign bit.
+ long bits = old._bits[j>>6];
+ while( bits >= 0 ) { // Still in state (1)?
+ long oldbits = bits;
+ bits |= mask(63); // Target state of bits: sign-bit means immutable
+ if( old.CAS( j>>6, oldbits, bits ) ) {
+ if( oldbits == 0 ) _copyDone.addAndGet(1);
+ break; // Success - old array word is now immutable
+ }
+ bits = old._bits[j>>6]; // Retry if CAS failed
+ }
+
+ // Transit from state 2: non-zero in old and zero in new
+ if( bits != mask(63) ) { // Non-zero in old?
+ long new_bits = nnn._bits[j>>6];
+ if( new_bits == 0 ) { // New array is still zero
+ new_bits = bits & ~mask(63); // Desired new value: a mutable copy of bits
+ // One-shot CAS attempt, no loop, from 0 to non-zero.
+ // If it fails, somebody else did the copy for us
+ if( !nnn.CAS( j>>6, 0, new_bits ) )
+ new_bits = nnn._bits[j>>6]; // Since it failed, get the new value
+ assert new_bits != 0;
+ }
+
+ // Transit from state 3: non-zero in old and non-zero in new
+ // One-shot CAS attempt, no loop, from non-zero to 0 (but immutable)
+ if( old.CAS( j>>6, bits, mask(63) ) )
+ _copyDone.addAndGet(1); // One more word finished copying
+ }
+
+ // Now in state 4: zero (and immutable) in old
+
+ // Return the self bitvector for 'fluid' programming style
+ return this;
+ }
+
+ private void print( int d, String msg ) {
+ for( int i=0; i {
-
- void consume(T t, U u) throws IOException;
-}
diff --git a/src/main/java/org/warp/commonutils/functional/IOBooleanSupplier.java b/src/main/java/org/warp/commonutils/functional/IOBooleanSupplier.java
deleted file mode 100644
index c2912cc..0000000
--- a/src/main/java/org/warp/commonutils/functional/IOBooleanSupplier.java
+++ /dev/null
@@ -1,8 +0,0 @@
-package org.warp.commonutils.functional;
-
-import java.io.IOException;
-
-public interface IOBooleanSupplier {
-
- boolean get() throws IOException;
-}
diff --git a/src/main/java/org/warp/commonutils/functional/IOCompletableFunction.java b/src/main/java/org/warp/commonutils/functional/IOCompletableFunction.java
deleted file mode 100644
index e040a3a..0000000
--- a/src/main/java/org/warp/commonutils/functional/IOCompletableFunction.java
+++ /dev/null
@@ -1,8 +0,0 @@
-package org.warp.commonutils.functional;
-
-import java.io.IOException;
-import java.util.concurrent.CompletableFuture;
-
-public interface IOCompletableFunction {
- CompletableFuture apply(T value) throws IOException;
-}
diff --git a/src/main/java/org/warp/commonutils/functional/IOConsumer.java b/src/main/java/org/warp/commonutils/functional/IOConsumer.java
deleted file mode 100644
index 09b779a..0000000
--- a/src/main/java/org/warp/commonutils/functional/IOConsumer.java
+++ /dev/null
@@ -1,8 +0,0 @@
-package org.warp.commonutils.functional;
-
-import java.io.IOException;
-
-public interface IOConsumer {
-
- void consume(T value) throws IOException;
-}
diff --git a/src/main/java/org/warp/commonutils/functional/IOFunction.java b/src/main/java/org/warp/commonutils/functional/IOFunction.java
deleted file mode 100644
index e5704c3..0000000
--- a/src/main/java/org/warp/commonutils/functional/IOFunction.java
+++ /dev/null
@@ -1,8 +0,0 @@
-package org.warp.commonutils.functional;
-
-import java.io.IOException;
-
-public interface IOFunction {
-
- U apply(T data) throws IOException;
-}
diff --git a/src/main/java/org/warp/commonutils/functional/IOIntegerSupplier.java b/src/main/java/org/warp/commonutils/functional/IOIntegerSupplier.java
deleted file mode 100644
index b311899..0000000
--- a/src/main/java/org/warp/commonutils/functional/IOIntegerSupplier.java
+++ /dev/null
@@ -1,8 +0,0 @@
-package org.warp.commonutils.functional;
-
-import java.io.IOException;
-
-public interface IOIntegerSupplier {
-
- int get() throws IOException;
-}
diff --git a/src/main/java/org/warp/commonutils/functional/IOLongSupplier.java b/src/main/java/org/warp/commonutils/functional/IOLongSupplier.java
deleted file mode 100644
index 78bed27..0000000
--- a/src/main/java/org/warp/commonutils/functional/IOLongSupplier.java
+++ /dev/null
@@ -1,8 +0,0 @@
-package org.warp.commonutils.functional;
-
-import java.io.IOException;
-
-public interface IOLongSupplier {
-
- long get() throws IOException;
-}
diff --git a/src/main/java/org/warp/commonutils/functional/IORunnable.java b/src/main/java/org/warp/commonutils/functional/IORunnable.java
deleted file mode 100644
index 20431e6..0000000
--- a/src/main/java/org/warp/commonutils/functional/IORunnable.java
+++ /dev/null
@@ -1,8 +0,0 @@
-package org.warp.commonutils.functional;
-
-import java.io.IOException;
-
-public interface IORunnable {
-
- void run() throws IOException;
-}
diff --git a/src/main/java/org/warp/commonutils/functional/IOSupplier.java b/src/main/java/org/warp/commonutils/functional/IOSupplier.java
deleted file mode 100644
index 1c26436..0000000
--- a/src/main/java/org/warp/commonutils/functional/IOSupplier.java
+++ /dev/null
@@ -1,8 +0,0 @@
-package org.warp.commonutils.functional;
-
-import java.io.IOException;
-
-public interface IOSupplier {
-
- T get() throws IOException;
-}
diff --git a/src/main/java/org/warp/commonutils/functional/IOTriConsumer.java b/src/main/java/org/warp/commonutils/functional/IOTriConsumer.java
deleted file mode 100644
index 6b496a3..0000000
--- a/src/main/java/org/warp/commonutils/functional/IOTriConsumer.java
+++ /dev/null
@@ -1,55 +0,0 @@
-package org.warp.commonutils.functional;
-
-import java.io.IOException;
-import java.util.Objects;
-import java.util.function.Consumer;
-
-/**
- * Represents an operation that accepts three input arguments and returns no
- * result. This is the three-arity specialization of {@link Consumer}.
- * Unlike most other functional interfaces, {@code TriConsumer} is expected
- * to operate via side-effects.
- *
- * This is a functional interface
- * whose functional method is {@link #accept(Object, Object, Object)}.
- *
- * @param the type of the first argument to the operation
- * @param the type of the second argument to the operation
- * @param the type of the thord argument to the operation
- *
- * @see Consumer
- * @since 1.8
- */
-@FunctionalInterface
-public interface IOTriConsumer {
-
- /**
- * Performs this operation on the given arguments.
- *
- * @param t the first input argument
- * @param u the second input argument
- * @param v the third input argument
- */
- void accept(T t, U u, V v) throws IOException;
-
- /**
- * Returns a composed {@code TriConsumer} that performs, in sequence, this
- * operation followed by the {@code after} operation. If performing either
- * operation throws an exception, it is relayed to the caller of the
- * composed operation. If performing this operation throws an exception,
- * the {@code after} operation will not be performed.
- *
- * @param after the operation to perform after this operation
- * @return a composed {@code TriConsumer} that performs in sequence this
- * operation followed by the {@code after} operation
- * @throws NullPointerException if {@code after} is null
- */
- default IOTriConsumer andThen(IOTriConsumer super T, ? super U, ? super V> after) {
- Objects.requireNonNull(after);
-
- return (l, r, u) -> {
- accept(l, r, u);
- after.accept(l, r, u);
- };
- }
-}
diff --git a/src/main/java/org/warp/commonutils/functional/TriConsumer.java b/src/main/java/org/warp/commonutils/functional/TriConsumer.java
deleted file mode 100644
index e7c19bb..0000000
--- a/src/main/java/org/warp/commonutils/functional/TriConsumer.java
+++ /dev/null
@@ -1,54 +0,0 @@
-package org.warp.commonutils.functional;
-
-import java.util.Objects;
-import java.util.function.Consumer;
-
-/**
- * Represents an operation that accepts three input arguments and returns no
- * result. This is the three-arity specialization of {@link Consumer}.
- * Unlike most other functional interfaces, {@code TriConsumer} is expected
- * to operate via side-effects.
- *
- * This is a functional interface
- * whose functional method is {@link #accept(Object, Object, Object)}.
- *
- * @param the type of the first argument to the operation
- * @param the type of the second argument to the operation
- * @param the type of the thord argument to the operation
- *
- * @see Consumer
- * @since 1.8
- */
-@FunctionalInterface
-public interface TriConsumer {
-
- /**
- * Performs this operation on the given arguments.
- *
- * @param t the first input argument
- * @param u the second input argument
- * @param v the third input argument
- */
- void accept(T t, U u, V v);
-
- /**
- * Returns a composed {@code TriConsumer} that performs, in sequence, this
- * operation followed by the {@code after} operation. If performing either
- * operation throws an exception, it is relayed to the caller of the
- * composed operation. If performing this operation throws an exception,
- * the {@code after} operation will not be performed.
- *
- * @param after the operation to perform after this operation
- * @return a composed {@code TriConsumer} that performs in sequence this
- * operation followed by the {@code after} operation
- * @throws NullPointerException if {@code after} is null
- */
- default org.warp.commonutils.functional.TriConsumer andThen(org.warp.commonutils.functional.TriConsumer super T, ? super U, ? super V> after) {
- Objects.requireNonNull(after);
-
- return (l, r, u) -> {
- accept(l, r, u);
- after.accept(l, r, u);
- };
- }
-}
diff --git a/src/main/java/org/warp/commonutils/functional/TriFunction.java b/src/main/java/org/warp/commonutils/functional/TriFunction.java
deleted file mode 100644
index 3e5abf9..0000000
--- a/src/main/java/org/warp/commonutils/functional/TriFunction.java
+++ /dev/null
@@ -1,51 +0,0 @@
-package org.warp.commonutils.functional;
-
-import java.util.Objects;
-import java.util.function.Function;
-
-/**
- * Represents a function that accepts three arguments and produces a result.
- * This is the three-arity specialization of {@link Function}.
- *
- * This is a functional interface
- * whose functional method is {@link #apply(Object, Object, Object)}.
- *
- * @param the type of the first argument to the function
- * @param the type of the second argument to the function
- * @param the type of the third argument to the function
- * @param the type of the result of the function
- *
- * @see Function
- * @since 1.8
- */
-@FunctionalInterface
-public interface TriFunction {
-
- /**
- * Applies this function to the given arguments.
- *
- * @param t the first function argument
- * @param u the second function argument
- * @param x the third function argument
- * @return the function result
- */
- R apply(T t, U u, X x);
-
- /**
- * Returns a composed function that first applies this function to
- * its input, and then applies the {@code after} function to the result.
- * If evaluation of either function throws an exception, it is relayed to
- * the caller of the composed function.
- *
- * @param the type of output of the {@code after} function, and of the
- * composed function
- * @param after the function to apply after this function is applied
- * @return a composed function that first applies this function and then
- * applies the {@code after} function
- * @throws NullPointerException if after is null
- */
- default org.warp.commonutils.functional.TriFunction andThen(Function super R, ? extends V> after) {
- Objects.requireNonNull(after);
- return (T t, U u, X x) -> after.apply(apply(t, u, x));
- }
-}
diff --git a/src/main/java/org/warp/commonutils/locks/LockUtils.java b/src/main/java/org/warp/commonutils/locks/LockUtils.java
deleted file mode 100644
index 137149c..0000000
--- a/src/main/java/org/warp/commonutils/locks/LockUtils.java
+++ /dev/null
@@ -1,193 +0,0 @@
-package org.warp.commonutils.locks;
-
-import java.io.IOException;
-import java.util.concurrent.locks.Lock;
-import java.util.concurrent.locks.StampedLock;
-import java.util.function.Supplier;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-import org.warp.commonutils.functional.IORunnable;
-import org.warp.commonutils.functional.IOSupplier;
-
-public class LockUtils {
-
- public static void lock(@Nullable Lock lock, @NotNull Runnable r) {
- if (lock != null) {
- lock.lock();
- }
- try {
- r.run();
- } finally {
- if (lock != null) {
- lock.unlock();
- }
- }
- }
-
- public static void readLock(@Nullable StampedLock lock, @NotNull Runnable r) {
- long lockValue;
- if (lock != null) {
- lockValue = lock.readLock();
- } else {
- lockValue = 0;
- }
- try {
- r.run();
- } finally {
- if (lock != null) {
- lock.unlockRead(lockValue);
- }
- }
- }
-
- public static void writeLock(@Nullable StampedLock lock, @NotNull Runnable r) {
- long lockValue;
- if (lock != null) {
- lockValue = lock.writeLock();
- } else {
- lockValue = 0;
- }
- try {
- r.run();
- } finally {
- if (lock != null) {
- lock.unlockWrite(lockValue);
- }
- }
- }
-
- public static void lockIO(@Nullable Lock lock, @NotNull IORunnable r) throws IOException {
- if (lock != null) {
- lock.lock();
- }
- try {
- r.run();
- } finally {
- if (lock != null) {
- lock.unlock();
- }
- }
- }
-
- public static void readLockIO(@Nullable StampedLock lock, @NotNull IORunnable r) throws IOException {
- long lockValue;
- if (lock != null) {
- lockValue = lock.readLock();
- } else {
- lockValue = 0;
- }
- try {
- r.run();
- } finally {
- if (lock != null) {
- lock.unlockRead(lockValue);
- }
- }
- }
-
- public static void writeLockIO(@Nullable StampedLock lock, @NotNull IORunnable r) throws IOException {
- long lockValue;
- if (lock != null) {
- lockValue = lock.writeLock();
- } else {
- lockValue = 0;
- }
- try {
- r.run();
- } finally {
- if (lock != null) {
- lock.unlockWrite(lockValue);
- }
- }
- }
-
- public static T lock(@Nullable Lock lock, @NotNull Supplier r) {
- if (lock != null) {
- lock.lock();
- }
- try {
- return r.get();
- } finally {
- if (lock != null) {
- lock.unlock();
- }
- }
- }
-
- public static T readLock(@Nullable StampedLock lock, @NotNull Supplier r) {
- long lockValue;
- if (lock != null) {
- lockValue = lock.readLock();
- } else {
- lockValue = 0;
- }
- try {
- return r.get();
- } finally {
- if (lock != null) {
- lock.unlockRead(lockValue);
- }
- }
- }
-
- public static T writeLock(@Nullable StampedLock lock, @NotNull Supplier r) {
- long lockValue;
- if (lock != null) {
- lockValue = lock.writeLock();
- } else {
- lockValue = 0;
- }
- try {
- return r.get();
- } finally {
- if (lock != null) {
- lock.unlockWrite(lockValue);
- }
- }
- }
-
- public static T lockIO(@Nullable Lock lock, @NotNull IOSupplier r) throws IOException {
- if (lock != null) {
- lock.lock();
- }
- try {
- return r.get();
- } finally {
- if (lock != null) {
- lock.unlock();
- }
- }
- }
-
- public static T readLockIO(@Nullable StampedLock lock, @NotNull IOSupplier r) throws IOException {
- long lockValue;
- if (lock != null) {
- lockValue = lock.readLock();
- } else {
- lockValue = 0;
- }
- try {
- return r.get();
- } finally {
- if (lock != null) {
- lock.unlockRead(lockValue);
- }
- }
- }
-
- public static T writeLockIO(@Nullable StampedLock lock, @NotNull IOSupplier r) throws IOException {
- long lockValue;
- if (lock != null) {
- lockValue = lock.writeLock();
- } else {
- lockValue = 0;
- }
- try {
- return r.get();
- } finally {
- if (lock != null) {
- lock.unlockWrite(lockValue);
- }
- }
- }
-}
diff --git a/src/main/java/org/warp/commonutils/moshi/BooleanListJsonAdapter.java b/src/main/java/org/warp/commonutils/moshi/BooleanListJsonAdapter.java
deleted file mode 100644
index 2f5a2b1..0000000
--- a/src/main/java/org/warp/commonutils/moshi/BooleanListJsonAdapter.java
+++ /dev/null
@@ -1,40 +0,0 @@
-package org.warp.commonutils.moshi;
-
-import com.squareup.moshi.JsonAdapter;
-import com.squareup.moshi.JsonReader;
-import com.squareup.moshi.JsonWriter;
-import it.unimi.dsi.fastutil.booleans.BooleanArrayList;
-import it.unimi.dsi.fastutil.booleans.BooleanList;
-import it.unimi.dsi.fastutil.booleans.BooleanLists;
-import it.unimi.dsi.fastutil.bytes.ByteArrayList;
-import java.io.IOException;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-public class BooleanListJsonAdapter extends JsonAdapter {
-
- @Override
- public @NotNull BooleanList fromJson(@NotNull JsonReader reader) throws IOException {
- reader.beginArray();
- BooleanArrayList modifiableOutput = new BooleanArrayList();
- while (reader.hasNext()) {
- modifiableOutput.add(reader.nextBoolean());
- }
- reader.endArray();
- return BooleanLists.unmodifiable(modifiableOutput);
- }
-
- @Override
- public void toJson(@NotNull JsonWriter writer, @Nullable BooleanList value) throws IOException {
- if (value == null) {
- writer.nullValue();
- return;
- }
-
- writer.beginArray();
- for (int i = 0; i < value.size(); i++) {
- writer.value(value.getBoolean(i));
- }
- writer.endArray();
- }
-}
diff --git a/src/main/java/org/warp/commonutils/moshi/ByteListJsonAdapter.java b/src/main/java/org/warp/commonutils/moshi/ByteListJsonAdapter.java
deleted file mode 100644
index b5b7d46..0000000
--- a/src/main/java/org/warp/commonutils/moshi/ByteListJsonAdapter.java
+++ /dev/null
@@ -1,39 +0,0 @@
-package org.warp.commonutils.moshi;
-
-import com.squareup.moshi.JsonAdapter;
-import com.squareup.moshi.JsonReader;
-import com.squareup.moshi.JsonWriter;
-import it.unimi.dsi.fastutil.bytes.ByteArrayList;
-import it.unimi.dsi.fastutil.bytes.ByteList;
-import it.unimi.dsi.fastutil.bytes.ByteLists;
-import java.io.IOException;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-public class ByteListJsonAdapter extends JsonAdapter {
-
- @Override
- public @NotNull ByteList fromJson(@NotNull JsonReader reader) throws IOException {
- reader.beginArray();
- ByteArrayList modifiableOutput = new ByteArrayList();
- while (reader.hasNext()) {
- modifiableOutput.add((byte) reader.nextInt());
- }
- reader.endArray();
- return ByteLists.unmodifiable(modifiableOutput);
- }
-
- @Override
- public void toJson(@NotNull JsonWriter writer, @Nullable ByteList value) throws IOException {
- if (value == null) {
- writer.nullValue();
- return;
- }
-
- writer.beginArray();
- for (int i = 0; i < value.size(); i++) {
- writer.value((long) value.getByte(i));
- }
- writer.endArray();
- }
-}
diff --git a/src/main/java/org/warp/commonutils/moshi/CharListJsonAdapter.java b/src/main/java/org/warp/commonutils/moshi/CharListJsonAdapter.java
deleted file mode 100644
index fd971b2..0000000
--- a/src/main/java/org/warp/commonutils/moshi/CharListJsonAdapter.java
+++ /dev/null
@@ -1,39 +0,0 @@
-package org.warp.commonutils.moshi;
-
-import com.squareup.moshi.JsonAdapter;
-import com.squareup.moshi.JsonReader;
-import com.squareup.moshi.JsonWriter;
-import it.unimi.dsi.fastutil.chars.CharArrayList;
-import it.unimi.dsi.fastutil.chars.CharList;
-import it.unimi.dsi.fastutil.chars.CharLists;
-import java.io.IOException;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-public class CharListJsonAdapter extends JsonAdapter {
-
- @Override
- public @NotNull CharList fromJson(@NotNull JsonReader reader) throws IOException {
- reader.beginArray();
- CharArrayList modifiableOutput = new CharArrayList();
- while (reader.hasNext()) {
- modifiableOutput.add((char) reader.nextInt());
- }
- reader.endArray();
- return CharLists.unmodifiable(modifiableOutput);
- }
-
- @Override
- public void toJson(@NotNull JsonWriter writer, @Nullable CharList value) throws IOException {
- if (value == null) {
- writer.nullValue();
- return;
- }
-
- writer.beginArray();
- for (int i = 0; i < value.size(); i++) {
- writer.value((long) value.getChar(i));
- }
- writer.endArray();
- }
-}
diff --git a/src/main/java/org/warp/commonutils/moshi/IntListJsonAdapter.java b/src/main/java/org/warp/commonutils/moshi/IntListJsonAdapter.java
deleted file mode 100644
index d531335..0000000
--- a/src/main/java/org/warp/commonutils/moshi/IntListJsonAdapter.java
+++ /dev/null
@@ -1,39 +0,0 @@
-package org.warp.commonutils.moshi;
-
-import com.squareup.moshi.JsonAdapter;
-import com.squareup.moshi.JsonReader;
-import com.squareup.moshi.JsonWriter;
-import it.unimi.dsi.fastutil.ints.IntArrayList;
-import it.unimi.dsi.fastutil.ints.IntList;
-import it.unimi.dsi.fastutil.ints.IntLists;
-import java.io.IOException;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-public class IntListJsonAdapter extends JsonAdapter {
-
- @Override
- public @NotNull IntList fromJson(@NotNull JsonReader reader) throws IOException {
- reader.beginArray();
- IntArrayList modifiableOutput = new IntArrayList();
- while (reader.hasNext()) {
- modifiableOutput.add(reader.nextInt());
- }
- reader.endArray();
- return IntLists.unmodifiable(modifiableOutput);
- }
-
- @Override
- public void toJson(@NotNull JsonWriter writer, @Nullable IntList value) throws IOException {
- if (value == null) {
- writer.nullValue();
- return;
- }
-
- writer.beginArray();
- for (int i = 0; i < value.size(); i++) {
- writer.value((long) value.getInt(i));
- }
- writer.endArray();
- }
-}
diff --git a/src/main/java/org/warp/commonutils/moshi/LongListJsonAdapter.java b/src/main/java/org/warp/commonutils/moshi/LongListJsonAdapter.java
deleted file mode 100644
index c5dd5ad..0000000
--- a/src/main/java/org/warp/commonutils/moshi/LongListJsonAdapter.java
+++ /dev/null
@@ -1,39 +0,0 @@
-package org.warp.commonutils.moshi;
-
-import com.squareup.moshi.JsonAdapter;
-import com.squareup.moshi.JsonReader;
-import com.squareup.moshi.JsonWriter;
-import it.unimi.dsi.fastutil.longs.LongArrayList;
-import it.unimi.dsi.fastutil.longs.LongList;
-import it.unimi.dsi.fastutil.longs.LongLists;
-import java.io.IOException;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-public class LongListJsonAdapter extends JsonAdapter {
-
- @Override
- public @NotNull LongList fromJson(@NotNull JsonReader reader) throws IOException {
- reader.beginArray();
- LongArrayList modifiableOutput = new LongArrayList();
- while (reader.hasNext()) {
- modifiableOutput.add(reader.nextLong());
- }
- reader.endArray();
- return LongLists.unmodifiable(modifiableOutput);
- }
-
- @Override
- public void toJson(@NotNull JsonWriter writer, @Nullable LongList value) throws IOException {
- if (value == null) {
- writer.nullValue();
- return;
- }
-
- writer.beginArray();
- for (int i = 0; i < value.size(); i++) {
- writer.value(value.getLong(i));
- }
- writer.endArray();
- }
-}
diff --git a/src/main/java/org/warp/commonutils/moshi/MoshiPolymorphic.java b/src/main/java/org/warp/commonutils/moshi/MoshiPolymorphic.java
deleted file mode 100644
index e340b3f..0000000
--- a/src/main/java/org/warp/commonutils/moshi/MoshiPolymorphic.java
+++ /dev/null
@@ -1,373 +0,0 @@
-package org.warp.commonutils.moshi;
-
-import com.squareup.moshi.JsonAdapter;
-import com.squareup.moshi.JsonDataException;
-import com.squareup.moshi.JsonReader;
-import com.squareup.moshi.JsonReader.Options;
-import com.squareup.moshi.JsonWriter;
-import com.squareup.moshi.Moshi;
-import com.squareup.moshi.Types;
-import dev.zacsweers.moshix.records.RecordsJsonAdapterFactory;
-import java.io.IOException;
-import java.lang.reflect.Field;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Modifier;
-import java.lang.reflect.Type;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.function.Function;
-import java.util.stream.Collectors;
-import org.apache.commons.lang3.StringUtils;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-import org.warp.commonutils.serialization.UTFUtils;
-
-public abstract class MoshiPolymorphic {
-
- public enum GetterStyle {
- FIELDS,
- RECORDS_GETTERS,
- STANDARD_GETTERS
- }
-
- private final boolean instantiateUsingStaticOf;
- private final GetterStyle getterStyle;
- private boolean initialized = false;
- private Moshi abstractMoshi;
- private final Map> abstractClassesSerializers = new ConcurrentHashMap<>();
- private final Map>> abstractListClassesSerializers = new ConcurrentHashMap<>();
- private final Map> concreteClassesSerializers = new ConcurrentHashMap<>();
- private final Map>> concreteListClassesSerializers = new ConcurrentHashMap<>();
- private final Map> extraClassesSerializers = new ConcurrentHashMap<>();
- private final Map> customAdapters = new ConcurrentHashMap<>();
-
- public MoshiPolymorphic() {
- this(false, GetterStyle.FIELDS);
- }
-
- public MoshiPolymorphic(boolean instantiateUsingStaticOf, GetterStyle getterStyle) {
- this.instantiateUsingStaticOf = instantiateUsingStaticOf;
- this.getterStyle = getterStyle;
- }
-
- private synchronized void initialize() {
- if (!this.initialized) {
- this.initialized = true;
- var abstractMoshiBuilder = new Moshi.Builder();
- var abstractClasses = getAbstractClasses();
- var concreteClasses = getConcreteClasses();
- var extraAdapters = getExtraAdapters();
-
- extraAdapters.forEach((extraClass, jsonAdapter) -> {
- extraClassesSerializers.put(extraClass, jsonAdapter);
- abstractMoshiBuilder.add(extraClass, jsonAdapter);
- });
-
- for (Class> declaredClass : abstractClasses) {
- var name = fixType(declaredClass.getSimpleName());
- JsonAdapter adapter = new PolymorphicAdapter<>(name);
- if (!extraClassesSerializers.containsKey(declaredClass)) {
- abstractMoshiBuilder.add(declaredClass, adapter);
- abstractClassesSerializers.put(declaredClass, adapter);
- abstractListClassesSerializers.put(Types.newParameterizedType(List.class, declaredClass),
- new ListValueAdapter<>(adapter)
- );
- }
- customAdapters.put(name, adapter);
- }
-
- for (Class> declaredClass : concreteClasses) {
- var name = fixType(declaredClass.getSimpleName());
- JsonAdapter adapter = new NormalValueAdapter<>(name, declaredClass);
- if (!extraClassesSerializers.containsKey(declaredClass)
- && !abstractClassesSerializers.containsKey(declaredClass)) {
- concreteClassesSerializers.put(declaredClass, adapter);
- concreteListClassesSerializers.put(Types.newParameterizedType(List.class, declaredClass),
- new ListValueAdapter<>(adapter)
- );
- abstractMoshiBuilder.add(declaredClass, adapter);
- }
- customAdapters.put(name, adapter);
- }
-
- abstractMoshiBuilder.addLast(new RecordsJsonAdapterFactory());
-
- abstractMoshi = abstractMoshiBuilder.build();
- }
- }
-
- protected abstract Set> getAbstractClasses();
-
- protected abstract Set> getConcreteClasses();
-
- protected Map, JsonAdapter>> getExtraAdapters() {
- return Map.of();
- }
-
- protected abstract boolean shouldIgnoreField(String fieldName);
-
- public Moshi.Builder registerAdapters(Moshi.Builder moshiBuilder) {
- initialize();
- extraClassesSerializers.forEach(moshiBuilder::add);
- abstractClassesSerializers.forEach(moshiBuilder::add);
- abstractListClassesSerializers.forEach(moshiBuilder::add);
- concreteClassesSerializers.forEach(moshiBuilder::add);
- concreteListClassesSerializers.forEach(moshiBuilder::add);
- return moshiBuilder;
- }
-
- private class PolymorphicAdapter extends JsonAdapter {
-
- private final String adapterName;
-
- private PolymorphicAdapter(String adapterName) {
- this.adapterName = adapterName;
- }
-
- private final Options NAMES = Options.of("type", "properties");
-
- @Nullable
- @Override
- public T fromJson(@NotNull JsonReader jsonReader) throws IOException {
- String type = null;
-
- jsonReader.beginObject();
- iterate: while (jsonReader.hasNext()) {
- switch (jsonReader.selectName(NAMES)) {
- case 0:
- type = fixType(jsonReader.nextString());
- break;
- case 1:
- if (type == null) {
- throw new JsonDataException("Type must be defined before properties");
- }
- break iterate;
- default:
- String name = jsonReader.nextName();
- throw new JsonDataException("Key \"" + name + "\" is invalid");
- }
- }
-
- JsonAdapter extends OBJ> propertiesAdapter = customAdapters.get(type);
- if (propertiesAdapter == null) {
- throw new JsonDataException("Type \"" + type + "\" is unknown");
- }
- //noinspection unchecked
- var result = (T) propertiesAdapter.fromJson(jsonReader);
-
- jsonReader.endObject();
-
- return result;
- }
-
- @Override
- public void toJson(@NotNull JsonWriter jsonWriter, @Nullable T t) throws IOException {
- if (t == null) {
- jsonWriter.nullValue();
- } else {
- String type = fixType(t.getClass().getSimpleName());
-
- JsonAdapter propertiesAdapter = customAdapters.get(type);
- if (propertiesAdapter == null) {
- abstractMoshi.adapter(java.lang.Object.class).toJson(jsonWriter, t);
- } else {
- jsonWriter.beginObject();
- jsonWriter.name("type").value(type);
- jsonWriter.name("properties");
- //noinspection unchecked
- propertiesAdapter.toJson(jsonWriter, (OBJ) t);
- jsonWriter.endObject();
- }
- }
- }
- }
-
- private class NormalValueAdapter extends JsonAdapter {
-
- private final String adapterName;
- private final Options names;
- private final Class> declaredClass;
- private final List declaredFields;
- private final Function[] fieldGetters;
-
- private NormalValueAdapter(String adapterName, Class> declaredClass) {
- try {
- this.adapterName = adapterName;
- this.declaredClass = declaredClass;
- this.declaredFields = Arrays
- .stream(declaredClass.getDeclaredFields())
- .filter(field -> {
- var modifiers = field.getModifiers();
- return !Modifier.isStatic(modifiers)
- && !Modifier.isTransient(modifiers)
- && !shouldIgnoreField(field.getName());
- })
- .collect(Collectors.toList());
- String[] fieldNames = new String[this.declaredFields.size()];
- //noinspection unchecked
- this.fieldGetters = new Function[this.declaredFields.size()];
- int i = 0;
- for (Field declaredField : this.declaredFields) {
- fieldNames[i] = declaredField.getName();
-
- switch (getterStyle) {
- case STANDARD_GETTERS:
- var getterMethod = declaredField
- .getDeclaringClass()
- .getMethod("get" + StringUtils.capitalize(declaredField.getName()));
- fieldGetters[i] = obj -> {
- try {
- return getterMethod.invoke(obj);
- } catch (InvocationTargetException | IllegalAccessException e) {
- throw new RuntimeException(e);
- }
- };
- break;
- case RECORDS_GETTERS:
- var getterMethod2 = declaredField
- .getDeclaringClass()
- .getMethod(declaredField.getName());
- fieldGetters[i] = obj -> {
- try {
- return getterMethod2.invoke(obj);
- } catch (InvocationTargetException | IllegalAccessException e) {
- throw new RuntimeException(e);
- }
- };
- break;
- case FIELDS:
- fieldGetters[i] = t -> {
- try {
- return declaredField.get(t);
- } catch (IllegalAccessException e) {
- throw new RuntimeException(e);
- }
- };
- break;
- }
-
- i++;
- } this.names = Options.of(fieldNames);
- } catch (NoSuchMethodException e) {
- throw new RuntimeException(e);
- }
- }
-
- @Nullable
- @Override
- public T fromJson(@NotNull JsonReader jsonReader) throws IOException {
- try {
- Object instance;
- Object[] fields;
- if (instantiateUsingStaticOf) {
- fields = new Object[declaredFields.size()];
- instance = null;
- } else {
- fields = null;
- instance = declaredClass.getConstructor().newInstance();
- }
-
- jsonReader.beginObject();
- while (jsonReader.hasNext()) {
- var nameId = jsonReader.selectName(names);
- if (nameId >= 0 && nameId < this.declaredFields.size()) {
- var fieldValue = abstractMoshi.adapter(declaredFields.get(nameId).getGenericType()).fromJson(jsonReader);
- if (instantiateUsingStaticOf) {
- fields[nameId] = fieldValue;
- } else {
- declaredFields.get(nameId).set(instance, fieldValue);
- }
- } else {
- String keyName = jsonReader.nextName();
- throw new JsonDataException("Key \"" + keyName + "\" is invalid");
- }
- }
- jsonReader.endObject();
-
- if (instantiateUsingStaticOf) {
- Class[] params = new Class[declaredFields.size()];
- for (int i = 0; i < declaredFields.size(); i++) {
- params[i] = declaredFields.get(i).getType();
- }
- instance = declaredClass.getMethod("of", params).invoke(null, fields);
- }
-
- //noinspection unchecked
- return (T) instance;
- } catch (InstantiationException | IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
- throw new JsonDataException(e);
- }
- }
-
- @Override
- public void toJson(@NotNull JsonWriter jsonWriter, @Nullable T t) throws IOException {
- if (t == null) {
- jsonWriter.nullValue();
- } else {
- jsonWriter.beginObject();
- int i = 0;
- for (Field declaredField : declaredFields) {
- jsonWriter.name(declaredField.getName());
- Class> fieldType = declaredField.getType();
- if (abstractClassesSerializers.containsKey(fieldType)) {
- //noinspection unchecked
- abstractClassesSerializers.get(fieldType).toJson(jsonWriter, (OBJ) fieldGetters[i].apply(t));
- } else if (concreteClassesSerializers.containsKey(fieldType)) {
- //noinspection unchecked
- concreteClassesSerializers.get(fieldType).toJson(jsonWriter, (OBJ) fieldGetters[i].apply(t));
- } else {
- abstractMoshi.adapter(fieldType).toJson(jsonWriter, fieldGetters[i].apply(t));
- }
- i++;
- }
- jsonWriter.endObject();
- }
- }
- }
-
- private static class ListValueAdapter extends JsonAdapter> {
-
- private final JsonAdapter valueAdapter;
-
- public ListValueAdapter(JsonAdapter valueAdapter) {
- this.valueAdapter = valueAdapter;
- }
-
- @Nullable
- @Override
- public List fromJson(@NotNull JsonReader jsonReader) throws IOException {
- jsonReader.beginArray();
- var result = new ArrayList();
- while (jsonReader.hasNext()) {
- result.add(valueAdapter.fromJson(jsonReader));
- }
- jsonReader.endArray();
- return Collections.unmodifiableList(result);
- }
-
- @Override
- public void toJson(@NotNull JsonWriter jsonWriter, @Nullable List ts) throws IOException {
- if (ts == null) {
- jsonWriter.nullValue();
- } else {
- jsonWriter.beginArray();
- for (T value : ts) {
- valueAdapter.toJson(jsonWriter.valueSink(), value);
- }
- jsonWriter.endArray();
- }
- }
- }
-
- private static String fixType(String nextString) {
- if (nextString.length() > 512) {
- throw new IllegalArgumentException("Input too long: " + nextString.length());
- }
- return UTFUtils.keepOnlyASCII(nextString);
- }
-}
\ No newline at end of file
diff --git a/src/main/java/org/warp/commonutils/moshi/ShortListJsonAdapter.java b/src/main/java/org/warp/commonutils/moshi/ShortListJsonAdapter.java
deleted file mode 100644
index 761939e..0000000
--- a/src/main/java/org/warp/commonutils/moshi/ShortListJsonAdapter.java
+++ /dev/null
@@ -1,39 +0,0 @@
-package org.warp.commonutils.moshi;
-
-import com.squareup.moshi.JsonAdapter;
-import com.squareup.moshi.JsonReader;
-import com.squareup.moshi.JsonWriter;
-import it.unimi.dsi.fastutil.shorts.ShortArrayList;
-import it.unimi.dsi.fastutil.shorts.ShortList;
-import it.unimi.dsi.fastutil.shorts.ShortLists;
-import java.io.IOException;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-public class ShortListJsonAdapter extends JsonAdapter {
-
- @Override
- public @NotNull ShortList fromJson(@NotNull JsonReader reader) throws IOException {
- reader.beginArray();
- ShortArrayList modifiableOutput = new ShortArrayList();
- while (reader.hasNext()) {
- modifiableOutput.add((short) reader.nextInt());
- }
- reader.endArray();
- return ShortLists.unmodifiable(modifiableOutput);
- }
-
- @Override
- public void toJson(@NotNull JsonWriter writer, @Nullable ShortList value) throws IOException {
- if (value == null) {
- writer.nullValue();
- return;
- }
-
- writer.beginArray();
- for (int i = 0; i < value.size(); i++) {
- writer.value((long) value.getShort(i));
- }
- writer.endArray();
- }
-}
diff --git a/src/main/java/org/warp/commonutils/random/LFSR.java b/src/main/java/org/warp/commonutils/random/LFSR.java
deleted file mode 100644
index a3fba5b..0000000
--- a/src/main/java/org/warp/commonutils/random/LFSR.java
+++ /dev/null
@@ -1,137 +0,0 @@
-package org.warp.commonutils.random;
-
-import java.math.BigInteger;
-import java.util.Iterator;
-import java.util.Random;
-import org.jetbrains.annotations.NotNull;
-
-/**
- * Linear feedback shift register
- *
- * Taps can be found at: See http://www.xilinx.com/support/documentation/application_notes/xapp052.pdf See
- * http://mathoverflow.net/questions/46961/how-are-taps-proven-to-work-for-lfsrs/46983#46983 See
- * http://www.newwaveinstruments.com/resources/articles/m_sequence_linear_feedback_shift_register_lfsr.htm See
- * http://www.yikes.com/~ptolemy/lfsr_web/index.htm See http://seanerikoconnor.freeservers.com/Mathematics/AbstractAlgebra/PrimitivePolynomials/overview.html
- *
- * @author OldCurmudgeon
- */
-public class LFSR implements Iterable {
-
- private static final Random random = new Random();
-
- // Bit pattern for taps.
- private final BigInteger taps;
- // Where to start (and end).
- private final BigInteger start;
-
- public static LFSR randomInt() {
- return random(32, random.nextInt());
- }
-
- public static LFSR randomLong() {
- return random(64, random.nextLong());
- }
-
- public static LFSR randomPositiveLong() {
- return random(50, Math.abs(random.nextInt()));
- }
-
- public static BigInteger randomPrimitive(int bitsSize) {
- // Build the BigInteger.
- BigInteger primitive = BigInteger.ZERO;
- for (int bitNumber = 0; bitNumber <= bitsSize; bitNumber++) {
- if (random.nextBoolean() || bitNumber == 0 || bitNumber == bitsSize) {
- primitive = primitive.or(BigInteger.ONE.shiftLeft(bitNumber));
- }
- }
- return primitive;
- }
-
- public static LFSR random(int bitsSize, long startNumber) {
- return new LFSR(randomPrimitive(bitsSize), BigInteger.valueOf(startNumber));
- }
-
- // The poly must be primitive to span the full sequence.
- public LFSR(BigInteger primitivePoly, BigInteger start) {
- // Where to start from (and stop).
- this.start = start.equals(BigInteger.ZERO) ? BigInteger.ONE : start;
- // Knock off the 2^0 coefficient of the polynomial for the TAP.
- this.taps = primitivePoly.shiftRight(1);
- }
-
- @NotNull
- @Override
- public LFSRIterator iterator() {
- return new LFSRIterator(start);
- }
-
- public class LFSRIterator implements Iterator {
- // The last one we returned.
-
- private BigInteger last = null;
- // The next one to return.
- private BigInteger next = null;
-
- public LFSRIterator(BigInteger start) {
- // Do not return the seed.
- last = start;
- }
-
- @Override
- public boolean hasNext() {
- if (next == null) {
- /*
- * Uses the Galois form.
- *
- * Shift last right one.
- *
- * If the bit shifted out was a 1 - xor with the tap mask.
- */
- boolean shiftedOutA1 = last.testBit(0);
- // Shift right.
- next = last.shiftRight(1);
- if (shiftedOutA1) {
- // Tap!
- next = next.xor(taps);
- }
- // Never give them `start` again.
- if (next.equals(start)) {
- // Could set a finished flag here too.
- next = null;
- }
- }
- return next != null;
- }
-
- @Override
- public BigInteger next() {
- // Remember this one.
- last = hasNext() ? next : null;
- // Don't deliver it again.
- next = null;
- return last;
- }
-
- public BigInteger next(BigInteger last) {
- this.last = last;
- next = null;
- return next();
- }
-
- @Override
- public void remove() {
- throw new UnsupportedOperationException("Not supported.");
- }
-
- @Override
- public String toString() {
- return LFSR.this.toString() + "[" + (last != null ? last.toString(16) : "") + "-" + (next != null ? next
- .toString(16) : "") + "]";
- }
- }
-
- @Override
- public String toString() {
- return "(" + taps.toString(32) + ")-" + start.toString(32);
- }
-}
\ No newline at end of file
diff --git a/src/main/java/org/warp/commonutils/range/MappedRanges.java b/src/main/java/org/warp/commonutils/range/MappedRanges.java
deleted file mode 100644
index 8ca2464..0000000
--- a/src/main/java/org/warp/commonutils/range/MappedRanges.java
+++ /dev/null
@@ -1,121 +0,0 @@
-package org.warp.commonutils.range;
-
-import it.unimi.dsi.fastutil.objects.Object2ObjectMap;
-import it.unimi.dsi.fastutil.objects.Object2ObjectMaps;
-import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
-import it.unimi.dsi.fastutil.objects.Object2ObjectRBTreeMap;
-import it.unimi.dsi.fastutil.objects.Object2ObjectSortedMap;
-import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet;
-import java.util.Comparator;
-import java.util.function.Function;
-
-public class MappedRanges {
-
- private final Object2ObjectMap ranges;
-
- public MappedRanges(int start, int end, T value) {
- if (start > end) {
- throw new IndexOutOfBoundsException();
- }
- this.ranges = new Object2ObjectOpenHashMap<>();
- ranges.put(new Range(start, end), value);
- }
-
- public void deleteRange(final int start, final int end, Function replaceWhenSplitting, Function cloneWhenSplitting) {
- if (start > end) {
- throw new IndexOutOfBoundsException();
- }
- Object2ObjectOpenHashMap rangesToAdd = new Object2ObjectOpenHashMap<>();
- ObjectOpenHashSet rangesToDelete = new ObjectOpenHashSet<>();
- ranges.forEach((range, value) -> {
- if (range.start <= end && range.end >= start) {
- if (range.start >= start && range.end <= end) {
- // delete the range
- rangesToDelete.add(range);
- } else if (range.start <= start && range.end >= end) {
- // cut the hole
- rangesToDelete.add(range);
- rangesToAdd.put(new Range(range.start, start), value);
- rangesToAdd.put(new Range(end, range.end), cloneWhenSplitting.apply(value));
- } else if (range.start <= start && range.end <= end && range.end > start) {
- // shrink the right border
- rangesToDelete.add(range);
- rangesToAdd.put(new Range(range.start, start), value);
- } else if (range.start >= start && range.end >= end && range.start < end) {
- // shrink the left border
- rangesToDelete.add(range);
- rangesToAdd.put(new Range(end, range.end), value);
- }
- }
- });
- for (Range range : rangesToDelete) {
- ranges.remove(range);
- }
- rangesToAdd.forEach((range, value) -> {
- if (canAddRange(range)) {
- ranges.put(range, replaceWhenSplitting.apply(value));
- }
- });
- }
-
- public void transformRange(int start, int end, Function replaceWhenOverlapping, Function cloneWhenSplitting) {
- if (start > end) {
- throw new IndexOutOfBoundsException();
- }
- Object2ObjectOpenHashMap rangesToTransform = new Object2ObjectOpenHashMap<>();
- Object2ObjectOpenHashMap rangesToAdd = new Object2ObjectOpenHashMap<>();
- ObjectOpenHashSet rangesToRemove = new ObjectOpenHashSet<>();
- ranges.forEach((range, value) -> {
- if (range.start <= end && range.end >= start) {
- if (range.start >= start && range.end <= end) {
- // transform the range
- rangesToTransform.put(range, replaceWhenOverlapping.apply(value));
- } else if (range.start <= start && range.end >= end) {
- // transform the middle
- rangesToRemove.add(range);
- rangesToAdd.put(new Range(range.start, start), value);
- rangesToTransform.put(new Range(start, end), replaceWhenOverlapping.apply(cloneWhenSplitting.apply(value)));
- rangesToAdd.put(new Range(end, range.end), cloneWhenSplitting.apply(value));
- } else if (range.start <= start && range.end <= end && range.end > start) {
- // transform the right
- rangesToRemove.add(range);
- rangesToAdd.put(new Range(range.start, start), value);
- rangesToTransform.put(new Range(start, range.end), replaceWhenOverlapping.apply(cloneWhenSplitting.apply(value)));
- } else if (range.start >= start && range.end >= end && range.start < end) {
- // transform the left
- rangesToRemove.add(range);
- rangesToTransform.put(new Range(range.start, end), replaceWhenOverlapping.apply(cloneWhenSplitting.apply(value)));
- rangesToAdd.put(new Range(end, range.end), value);
- } else {
- // do not transform
- }
- }
- });
-
- rangesToRemove.forEach((range) -> {
- ranges.remove(range);
- });
- rangesToAdd.forEach((range, value) -> {
- if (canAddRange(range)) {
- ranges.put(range, value);
- }
- });
- rangesToTransform.forEach((range, value) -> {
- ranges.put(range, value);
- });
- }
-
- private boolean canAddRange(UnmodifiableRange range) {
- return range.getStart() != range.getEnd();
- }
-
- private boolean canAddRange(Range range) {
- return range.getStart() != range.getEnd();
- }
-
- public Object2ObjectMap getRanges() {
- Object2ObjectSortedMap a = new Object2ObjectRBTreeMap<>(Comparator.comparingLong(UnmodifiableRange::getStart));
- ranges.forEach((range, value) -> a.put(range.unmodifiableClone(), value));
- return Object2ObjectMaps.unmodifiable(a);
- }
-}
diff --git a/src/main/java/org/warp/commonutils/range/Range.java b/src/main/java/org/warp/commonutils/range/Range.java
deleted file mode 100644
index 26093a5..0000000
--- a/src/main/java/org/warp/commonutils/range/Range.java
+++ /dev/null
@@ -1,60 +0,0 @@
-package org.warp.commonutils.range;
-
-import java.util.Objects;
-import java.util.StringJoiner;
-import org.warp.commonutils.error.IndexOutOfBoundsException;
-
-public class Range {
-
- public long start;
- public long end;
-
- public Range(long start, long end) {
- if (start > end) {
- throw new IndexOutOfBoundsException(start, 0, end);
- }
- this.start = start;
- this.end = end;
- }
-
- public long getStart() {
- return start;
- }
-
- public long getEnd() {
- return end;
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) {
- return true;
- }
- if (o == null || getClass() != o.getClass()) {
- return false;
- }
- Range range = (Range) o;
- return start == range.start && end == range.end;
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(start, end);
- }
-
- @Override
- public String toString() {
- return new StringJoiner(", ", Range.class.getSimpleName() + "[", "]").add("start=" + start).add("end=" + end)
- .toString();
- }
-
- @SuppressWarnings("MethodDoesntCallSuperMethod")
- @Override
- public Range clone() {
- return new Range(start, end);
- }
-
- public UnmodifiableRange unmodifiableClone() {
- return new UnmodifiableRange(start, end);
- }
-}
diff --git a/src/main/java/org/warp/commonutils/range/Ranges.java b/src/main/java/org/warp/commonutils/range/Ranges.java
deleted file mode 100644
index 3f140cd..0000000
--- a/src/main/java/org/warp/commonutils/range/Ranges.java
+++ /dev/null
@@ -1,104 +0,0 @@
-package org.warp.commonutils.range;
-
-import it.unimi.dsi.fastutil.objects.ObjectArrayList;
-import it.unimi.dsi.fastutil.objects.ObjectRBTreeSet;
-import it.unimi.dsi.fastutil.objects.ObjectSortedSet;
-import it.unimi.dsi.fastutil.objects.ObjectSortedSets;
-import java.util.ArrayList;
-import java.util.Comparator;
-import java.util.List;
-import org.warp.commonutils.error.IndexOutOfBoundsException;
-
-public class Ranges {
-
- private final ObjectArrayList ranges;
-
- public Ranges(long start, long end) {
- if (start > end) {
- throw new IndexOutOfBoundsException(start, 0, end);
- }
- this.ranges = new ObjectArrayList<>();
- ranges.add(new Range(start, end));
- }
-
- public void addRange(Range range) {
- addRange(range.start, range.end);
- }
-
- public void addRange(long start, long end) {
- if (start > end) {
- throw new IndexOutOfBoundsException(start, 0, end);
- }
- long rangeStart = start;
- long rangeEnd = end;
- var it = ranges.iterator();
- while (it.hasNext()) {
- Range range = it.next();
- if (range.start <= end && range.end >= start) {
- boolean remove = false;
- if (range.start < rangeStart && range.end >= rangeStart) {
- rangeStart = range.start;
- remove = true;
- }
- if (range.end > rangeEnd && range.start <= rangeEnd) {
- rangeEnd = range.end;
- remove = true;
- }
- if (remove) {
- it.remove();
- }
- }
- }
- addRangeIfNotZero(new Range(rangeStart, rangeEnd));
- }
-
- public void deleteRange(final long start, final long end) {
- if (start > end) {
- throw new IndexOutOfBoundsException(start);
- }
- List rangesToAdd = new ArrayList<>(ranges.size());
- var it = ranges.iterator();
- while (it.hasNext()) {
- Range range = it.next();
- if (range.start <= end && range.end >= start) {
- if (range.start >= start && range.end <= end) {
- // delete the range
- it.remove();
- } else if (range.start <= start && range.end >= end) {
- // cut the hole
- it.remove();
- rangesToAdd.add(new Range(range.start, start));
- rangesToAdd.add(new Range(end, range.end));
- } else if (range.start <= start && range.end <= end && range.end > start) {
- // shrink the right border
- it.remove();
- rangesToAdd.add(new Range(range.start, start));
- } else if (range.start >= start && range.end >= end && range.start < end) {
- // shrink the left border
- it.remove();
- rangesToAdd.add(new Range(end, range.end));
- }
- }
- }
- for (Range rangeToAdd : rangesToAdd) {
- addRangeIfNotZero(rangeToAdd);
- }
- }
-
- /**
- * This methods does not check overlapping ranges! It's used only internally to skip empty ranges
- *
- * @param range
- */
- private void addRangeIfNotZero(Range range) {
- if (range.start != range.end) {
- ranges.add(range);
- }
- }
-
- public ObjectSortedSet getRanges() {
- ObjectSortedSet a = new ObjectRBTreeSet<>(Comparator.comparingLong(UnmodifiableRange::getStart));
- ranges.forEach((range) -> a.add(range.unmodifiableClone()));
- return ObjectSortedSets.unmodifiable(a);
- }
-}
diff --git a/src/main/java/org/warp/commonutils/range/UnmodifiableRange.java b/src/main/java/org/warp/commonutils/range/UnmodifiableRange.java
deleted file mode 100644
index bce0655..0000000
--- a/src/main/java/org/warp/commonutils/range/UnmodifiableRange.java
+++ /dev/null
@@ -1,54 +0,0 @@
-package org.warp.commonutils.range;
-
-import java.util.Objects;
-import java.util.StringJoiner;
-import org.warp.commonutils.error.IndexOutOfBoundsException;
-
-public class UnmodifiableRange {
-
- private final long start;
- private final long end;
-
- public UnmodifiableRange(long start, long end) {
- if (start > end) {
- throw new IndexOutOfBoundsException(start, 0, end);
- }
- this.start = start;
- this.end = end;
- }
-
- public long getStart() {
- return start;
- }
-
- public long getEnd() {
- return end;
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) {
- return true;
- }
- if (o == null || getClass() != o.getClass()) {
- return false;
- }
- UnmodifiableRange that = (UnmodifiableRange) o;
- return start == that.start && end == that.end;
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(start, end);
- }
-
- @Override
- public String toString() {
- return new StringJoiner(", ", UnmodifiableRange.class.getSimpleName() + "[", "]").add("start=" + start)
- .add("end=" + end).toString();
- }
-
- public Range toRange() {
- return new Range(start, end);
- }
-}
diff --git a/src/main/java/org/warp/commonutils/serialization/UTFUtils.java b/src/main/java/org/warp/commonutils/serialization/UTFUtils.java
deleted file mode 100644
index 67b278b..0000000
--- a/src/main/java/org/warp/commonutils/serialization/UTFUtils.java
+++ /dev/null
@@ -1,42 +0,0 @@
-package org.warp.commonutils.serialization;
-
-import java.io.DataInput;
-import java.io.DataOutput;
-import java.io.IOException;
-import java.nio.charset.StandardCharsets;
-
-public class UTFUtils {
- public static void writeUTF(DataOutput out, String utf) throws IOException {
- byte[] bytes = utf.getBytes(StandardCharsets.UTF_8);
- out.writeInt(bytes.length);
- out.write(bytes);
- }
-
- public static String readUTF(DataInput in) throws IOException {
- int len = in.readInt();
- byte[] data = new byte[len];
- in.readFully(data, 0, len);
- return new String(data, StandardCharsets.UTF_8);
- }
-
- /**
- * Keep only ascii alphanumeric letters
- */
- public static String keepOnlyASCII(String nextString) {
- char[] chars = nextString.toCharArray();
- //noinspection UnusedAssignment
- nextString = null;
- int writeIndex = 0;
- char c;
- for (int checkIndex = 0; checkIndex < chars.length; checkIndex++) {
- c = chars[checkIndex];
- if ((c >= '0' && c <= '9') || (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z')) {
- if (writeIndex != checkIndex) {
- chars[writeIndex] = c;
- }
- writeIndex++;
- }
- }
- return new String(chars, 0, writeIndex);
- }
-}
diff --git a/src/main/java/org/warp/commonutils/stream/ByteBufferBackedInputStream.java b/src/main/java/org/warp/commonutils/stream/ByteBufferBackedInputStream.java
deleted file mode 100644
index 3f4bc37..0000000
--- a/src/main/java/org/warp/commonutils/stream/ByteBufferBackedInputStream.java
+++ /dev/null
@@ -1,29 +0,0 @@
-package org.warp.commonutils.stream;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.nio.ByteBuffer;
-import org.jetbrains.annotations.NotNull;
-
-/**
- * Simple {@link InputStream} implementation that exposes currently
- * available content of a {@link ByteBuffer}.
- */
-public class ByteBufferBackedInputStream extends InputStream {
- protected final ByteBuffer _b;
-
- public ByteBufferBackedInputStream(ByteBuffer buf) { _b = buf; }
-
- @Override public int available() { return _b.remaining(); }
-
- @Override
- public int read() throws IOException { return _b.hasRemaining() ? (_b.get() & 0xFF) : -1; }
-
- @Override
- public int read(byte @NotNull [] bytes, int off, int len) throws IOException {
- if (!_b.hasRemaining()) return -1;
- len = Math.min(len, _b.remaining());
- _b.get(bytes, off, len);
- return len;
- }
-}
\ No newline at end of file
diff --git a/src/main/java/org/warp/commonutils/stream/DataInputOutput.java b/src/main/java/org/warp/commonutils/stream/DataInputOutput.java
deleted file mode 100644
index 7435511..0000000
--- a/src/main/java/org/warp/commonutils/stream/DataInputOutput.java
+++ /dev/null
@@ -1,11 +0,0 @@
-package org.warp.commonutils.stream;
-
-import java.io.DataInput;
-import java.io.DataOutput;
-
-public interface DataInputOutput extends DataInput, DataOutput {
-
- DataInput getIn();
-
- DataOutput getOut();
-}
diff --git a/src/main/java/org/warp/commonutils/stream/DataInputOutputImpl.java b/src/main/java/org/warp/commonutils/stream/DataInputOutputImpl.java
deleted file mode 100644
index 9acf2fe..0000000
--- a/src/main/java/org/warp/commonutils/stream/DataInputOutputImpl.java
+++ /dev/null
@@ -1,173 +0,0 @@
-package org.warp.commonutils.stream;
-
-import java.io.DataInput;
-import java.io.DataOutput;
-import java.io.IOException;
-import org.jetbrains.annotations.NotNull;
-
-public class DataInputOutputImpl implements DataInputOutput {
-
- private final DataInput in;
- private final DataOutput out;
-
- public DataInputOutputImpl(DataInput in, DataOutput out) {
- this.in = in;
- this.out = out;
- }
-
- @Override
- public DataInput getIn() {
- return this;
- }
-
- @Override
- public DataOutput getOut() {
- return this;
- }
-
- @Override
- public void readFully(byte @NotNull [] bytes) throws IOException {
- in.readFully(bytes);
- }
-
- @Override
- public void readFully(byte @NotNull [] bytes, int i, int i1) throws IOException {
- in.readFully(bytes, i, i1);
- }
-
- @Override
- public int skipBytes(int i) throws IOException {
- return in.skipBytes(i);
- }
-
- @Override
- public boolean readBoolean() throws IOException {
- return in.readBoolean();
- }
-
- @Override
- public byte readByte() throws IOException {
- return in.readByte();
- }
-
- @Override
- public int readUnsignedByte() throws IOException {
- return in.readUnsignedByte();
- }
-
- @Override
- public short readShort() throws IOException {
- return in.readShort();
- }
-
- @Override
- public int readUnsignedShort() throws IOException {
- return in.readUnsignedShort();
- }
-
- @Override
- public char readChar() throws IOException {
- return in.readChar();
- }
-
- @Override
- public int readInt() throws IOException {
- return in.readInt();
- }
-
- @Override
- public long readLong() throws IOException {
- return in.readLong();
- }
-
- @Override
- public float readFloat() throws IOException {
- return in.readFloat();
- }
-
- @Override
- public double readDouble() throws IOException {
- return in.readDouble();
- }
-
- @Override
- public String readLine() throws IOException {
- return in.readLine();
- }
-
- @NotNull
- @Override
- public String readUTF() throws IOException {
- return in.readUTF();
- }
-
- @Override
- public void write(int i) throws IOException {
- out.write(i);
- }
-
- @Override
- public void write(byte @NotNull [] bytes) throws IOException {
- out.write(bytes);
- }
-
- @Override
- public void write(byte @NotNull [] bytes, int i, int i1) throws IOException {
- out.write(bytes, i, i1);
- }
-
- @Override
- public void writeBoolean(boolean b) throws IOException {
- out.writeBoolean(b);
- }
-
- @Override
- public void writeByte(int i) throws IOException {
- out.writeByte(i);
- }
-
- @Override
- public void writeShort(int i) throws IOException {
- out.writeShort(i);
- }
-
- @Override
- public void writeChar(int i) throws IOException {
- out.writeChar(i);
- }
-
- @Override
- public void writeInt(int i) throws IOException {
- out.writeInt(i);
- }
-
- @Override
- public void writeLong(long l) throws IOException {
- out.writeLong(l);
- }
-
- @Override
- public void writeFloat(float v) throws IOException {
- out.writeFloat(v);
- }
-
- @Override
- public void writeDouble(double v) throws IOException {
- out.writeDouble(v);
- }
-
- @Override
- public void writeBytes(@NotNull String s) throws IOException {
- out.writeBytes(s);
- }
-
- @Override
- public void writeChars(@NotNull String s) throws IOException {
- out.writeChars(s);
- }
-
- @Override
- public void writeUTF(@NotNull String s) throws IOException {
- out.writeUTF(s);
- }
-}
diff --git a/src/main/java/org/warp/commonutils/stream/DataInputOutputStream.java b/src/main/java/org/warp/commonutils/stream/DataInputOutputStream.java
deleted file mode 100644
index 16a1a3a..0000000
--- a/src/main/java/org/warp/commonutils/stream/DataInputOutputStream.java
+++ /dev/null
@@ -1,103 +0,0 @@
-package org.warp.commonutils.stream;
-
-import java.io.DataInputStream;
-import java.io.DataOutputStream;
-import java.io.IOException;
-import org.jetbrains.annotations.NotNull;
-
-public class DataInputOutputStream extends DataOutputStream implements DataInputOutput {
-
- private final DataInputStream in;
-
- public DataInputOutputStream(DataInputStream in, DataOutputStream out) {
- super(out);
- this.in = in;
- }
-
- @Override
- public DataInputStream getIn() {
- return in;
- }
-
- @Override
- public DataOutputStream getOut() {
- return this;
- }
-
- @Override
- public void readFully(byte @NotNull [] bytes) throws IOException {
- in.readFully(bytes);
- }
-
- @Override
- public void readFully(byte @NotNull [] bytes, int i, int i1) throws IOException {
- in.readFully(bytes, i, i1);
- }
-
- @Override
- public int skipBytes(int i) throws IOException {
- return in.skipBytes(i);
- }
-
- @Override
- public boolean readBoolean() throws IOException {
- return in.readBoolean();
- }
-
- @Override
- public byte readByte() throws IOException {
- return in.readByte();
- }
-
- @Override
- public int readUnsignedByte() throws IOException {
- return in.readUnsignedByte();
- }
-
- @Override
- public short readShort() throws IOException {
- return in.readShort();
- }
-
- @Override
- public int readUnsignedShort() throws IOException {
- return in.readUnsignedShort();
- }
-
- @Override
- public char readChar() throws IOException {
- return in.readChar();
- }
-
- @Override
- public int readInt() throws IOException {
- return in.readInt();
- }
-
- @Override
- public long readLong() throws IOException {
- return in.readLong();
- }
-
- @Override
- public float readFloat() throws IOException {
- return in.readFloat();
- }
-
- @Override
- public double readDouble() throws IOException {
- return in.readDouble();
- }
-
- @Deprecated
- @Override
- public String readLine() throws IOException {
- return in.readLine();
- }
-
- @NotNull
- @Override
- public String readUTF() throws IOException {
- return in.readUTF();
- }
-}
diff --git a/src/main/java/org/warp/commonutils/stream/SafeDataInputStream.java b/src/main/java/org/warp/commonutils/stream/SafeDataInputStream.java
deleted file mode 100644
index e5a3936..0000000
--- a/src/main/java/org/warp/commonutils/stream/SafeDataInputStream.java
+++ /dev/null
@@ -1,580 +0,0 @@
-/*
- * Copyright (c) 1994, 2019, Oracle and/or its affiliates. All rights reserved.
- * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
- *
- *
- *
- *
- *
- *
- *
- *
- *
- *
- *
- *
- *
- *
- *
- *
- *
- *
- *
- *
- */
-
-package org.warp.commonutils.stream;
-
-import java.io.DataInput;
-import org.jetbrains.annotations.NotNull;
-
-/**
- * A data input stream lets an application read primitive Java data
- * types from an underlying input stream in a machine-independent
- * way. An application uses a data output stream to write data that
- * can later be read by a data input stream.
- *
- * DataInputStream is not necessarily safe for multithreaded access.
- * Thread safety is optional and is the responsibility of users of
- * methods in this class.
- *
- * @author Arthur van Hoff
- * @see java.io.DataOutputStream
- * @since 1.0
- */
-public class SafeDataInputStream extends SafeFilterInputStream implements DataInput {
-
- /**
- * Creates a DataInputStream that uses the specified
- * underlying InputStream.
- *
- * @param in the specified input stream
- */
- public SafeDataInputStream(SafeInputStream in) {
- super(in);
- }
-
- /**
- * working arrays initialized on demand by readUTF
- */
- private byte[] bytearr = new byte[80];
- private char[] chararr = new char[80];
-
- /**
- * Reads some number of bytes from the contained input stream and
- * stores them into the buffer array {@code b}. The number of
- * bytes actually read is returned as an integer. This method blocks
- * until input data is available, end of file is detected, or an
- * exception is thrown.
- *
- *
If {@code b} is null, a {@code NullPointerException} is
- * thrown. If the length of {@code b} is zero, then no bytes are
- * read and {@code 0} is returned; otherwise, there is an attempt
- * to read at least one byte. If no byte is available because the
- * stream is at end of file, the value {@code -1} is returned;
- * otherwise, at least one byte is read and stored into {@code b}.
- *
- *
The first byte read is stored into element {@code b[0]}, the
- * next one into {@code b[1]}, and so on. The number of bytes read
- * is, at most, equal to the length of {@code b}. Let {@code k}
- * be the number of bytes actually read; these bytes will be stored in
- * elements {@code b[0]} through {@code b[k-1]}, leaving
- * elements {@code b[k]} through {@code b[b.length-1]}
- * unaffected.
- *
- *
The {@code read(b)} method has the same effect as:
- *
- * read(b, 0, b.length)
- *
- *
- * @param b the buffer into which the data is read.
- * @return the total number of bytes read into the buffer, or
- * {@code -1} if there is no more data because the end
- * of the stream has been reached.
- * @see SafeFilterInputStream#in
- * @see java.io.InputStream#read(byte[], int, int)
- */
- public final int read(byte[] b) {
- return in.read(b, 0, b.length);
- }
-
- /**
- * Reads up to {@code len} bytes of data from the contained
- * input stream into an array of bytes. An attempt is made to read
- * as many as {@code len} bytes, but a smaller number may be read,
- * possibly zero. The number of bytes actually read is returned as an
- * integer.
- *
- * This method blocks until input data is available, end of file is
- * detected, or an exception is thrown.
- *
- *
If {@code len} is zero, then no bytes are read and
- * {@code 0} is returned; otherwise, there is an attempt to read at
- * least one byte. If no byte is available because the stream is at end of
- * file, the value {@code -1} is returned; otherwise, at least one
- * byte is read and stored into {@code b}.
- *
- *
The first byte read is stored into element {@code b[off]}, the
- * next one into {@code b[off+1]}, and so on. The number of bytes read
- * is, at most, equal to {@code len}. Let k be the number of
- * bytes actually read; these bytes will be stored in elements
- * {@code b[off]} through {@code b[off+}k {@code -1]},
- * leaving elements {@code b[off+}k {@code ]} through
- * {@code b[off+len-1]} unaffected.
- *
- *
In every case, elements {@code b[0]} through
- * {@code b[off]} and elements {@code b[off+len]} through
- * {@code b[b.length-1]} are unaffected.
- *
- * @param b the buffer into which the data is read.
- * @param off the start offset in the destination array {@code b}
- * @param len the maximum number of bytes read.
- * @return the total number of bytes read into the buffer, or
- * {@code -1} if there is no more data because the end
- * of the stream has been reached.
- * @throws NullPointerException If {@code b} is {@code null}.
- * @throws IndexOutOfBoundsException If {@code off} is negative,
- * {@code len} is negative, or {@code len} is greater than
- * {@code b.length - off}
- * @see SafeFilterInputStream#in
- * @see java.io.InputStream#read(byte[], int, int)
- */
- public final int read(byte[] b, int off, int len) {
- return in.read(b, off, len);
- }
-
- /**
- * See the general contract of the {@code readFully}
- * method of {@code DataInput}.
- *
- * Bytes
- * for this operation are read from the contained
- * input stream.
- *
- * @param b the buffer into which the data is read.
- * @throws NullPointerException if {@code b} is {@code null}.
- * @see SafeFilterInputStream#in
- */
- public final void readFully(byte @NotNull [] b) {
- readFully(b, 0, b.length);
- }
-
- /**
- * See the general contract of the {@code readFully}
- * method of {@code DataInput}.
- *
- * Bytes
- * for this operation are read from the contained
- * input stream.
- *
- * @param b the buffer into which the data is read.
- * @param off the start offset in the data array {@code b}.
- * @param len the number of bytes to read.
- * @throws NullPointerException if {@code b} is {@code null}.
- * @throws IndexOutOfBoundsException if {@code off} is negative,
- * {@code len} is negative, or {@code len} is greater than
- * {@code b.length - off}.
- * @see SafeFilterInputStream#in
- */
- public final void readFully(byte @NotNull [] b, int off, int len) {
- if (len < 0)
- throw new IndexOutOfBoundsException();
- int n = 0;
- while (n < len) {
- int count = in.read(b, off + n, len - n);
- if (count < 0)
- throw new IndexOutOfBoundsException();
- n += count;
- }
- }
-
- /**
- * See the general contract of the {@code skipBytes}
- * method of {@code DataInput}.
- *
- * Bytes for this operation are read from the contained
- * input stream.
- *
- * @param n the number of bytes to be skipped.
- * @return the actual number of bytes skipped.
- */
- public final int skipBytes(int n) {
- int total = 0;
- int cur;
-
- while ((total 0)) {
- total += cur;
- }
-
- return total;
- }
-
- /**
- * See the general contract of the {@code readBoolean}
- * method of {@code DataInput}.
- *
- * Bytes for this operation are read from the contained
- * input stream.
- *
- * @return the {@code boolean} value read.
- * @see SafeFilterInputStream#in
- */
- public final boolean readBoolean() {
- int ch = in.read();
- if (ch < 0)
- throw new IndexOutOfBoundsException();
- return (ch != 0);
- }
-
- /**
- * See the general contract of the {@code readByte}
- * method of {@code DataInput}.
- *
- * Bytes
- * for this operation are read from the contained
- * input stream.
- *
- * @return the next byte of this input stream as a signed 8-bit
- * {@code byte}.
- * @see SafeFilterInputStream#in
- */
- public final byte readByte() {
- int ch = in.read();
- if (ch < 0)
- throw new IndexOutOfBoundsException();
- return (byte)(ch);
- }
-
- /**
- * See the general contract of the {@code readUnsignedByte}
- * method of {@code DataInput}.
- *
- * Bytes
- * for this operation are read from the contained
- * input stream.
- *
- * @return the next byte of this input stream, interpreted as an
- * unsigned 8-bit number.
- * @see SafeFilterInputStream#in
- */
- public final int readUnsignedByte() {
- int ch = in.read();
- if (ch < 0)
- throw new IndexOutOfBoundsException();
- return ch;
- }
-
- /**
- * See the general contract of the {@code readShort}
- * method of {@code DataInput}.
- *
- * Bytes
- * for this operation are read from the contained
- * input stream.
- *
- * @return the next two bytes of this input stream, interpreted as a
- * signed 16-bit number.
- * @see SafeFilterInputStream#in
- */
- public final short readShort() {
- int ch1 = in.read();
- int ch2 = in.read();
- if ((ch1 | ch2) < 0)
- throw new IndexOutOfBoundsException();
- return (short)((ch1 << 8) + (ch2 << 0));
- }
-
- /**
- * See the general contract of the {@code readUnsignedShort}
- * method of {@code DataInput}.
- *
- * Bytes
- * for this operation are read from the contained
- * input stream.
- *
- * @return the next two bytes of this input stream, interpreted as an
- * unsigned 16-bit integer.
- * @see SafeFilterInputStream#in
- */
- public final int readUnsignedShort() {
- int ch1 = in.read();
- int ch2 = in.read();
- if ((ch1 | ch2) < 0)
- throw new IndexOutOfBoundsException();
- return (ch1 << 8) + (ch2 << 0);
- }
-
- /**
- * See the general contract of the {@code readChar}
- * method of {@code DataInput}.
- *
- * Bytes
- * for this operation are read from the contained
- * input stream.
- *
- * @return the next two bytes of this input stream, interpreted as a
- * {@code char}.
- * @see SafeFilterInputStream#in
- */
- public final char readChar() {
- int ch1 = in.read();
- int ch2 = in.read();
- if ((ch1 | ch2) < 0)
- throw new IndexOutOfBoundsException();
- return (char)((ch1 << 8) + (ch2 << 0));
- }
-
- /**
- * See the general contract of the {@code readInt}
- * method of {@code DataInput}.
- *
- * Bytes
- * for this operation are read from the contained
- * input stream.
- *
- * @return the next four bytes of this input stream, interpreted as an
- * {@code int}.
- * @see SafeFilterInputStream#in
- */
- public final int readInt() {
- int ch1 = in.read();
- int ch2 = in.read();
- int ch3 = in.read();
- int ch4 = in.read();
- if ((ch1 | ch2 | ch3 | ch4) < 0)
- throw new IndexOutOfBoundsException();
- return ((ch1 << 24) + (ch2 << 16) + (ch3 << 8) + (ch4 << 0));
- }
-
- private final byte[] readBuffer = new byte[8];
-
- /**
- * See the general contract of the {@code readLong}
- * method of {@code DataInput}.
- *
- * Bytes
- * for this operation are read from the contained
- * input stream.
- *
- * @return the next eight bytes of this input stream, interpreted as a
- * {@code long}.
- * @see SafeFilterInputStream#in
- */
- public final long readLong() {
- readFully(readBuffer, 0, 8);
- return (((long)readBuffer[0] << 56) +
- ((long)(readBuffer[1] & 255) << 48) +
- ((long)(readBuffer[2] & 255) << 40) +
- ((long)(readBuffer[3] & 255) << 32) +
- ((long)(readBuffer[4] & 255) << 24) +
- ((readBuffer[5] & 255) << 16) +
- ((readBuffer[6] & 255) << 8) +
- ((readBuffer[7] & 255) << 0));
- }
-
- /**
- * See the general contract of the {@code readFloat}
- * method of {@code DataInput}.
- *
- * Bytes
- * for this operation are read from the contained
- * input stream.
- *
- * @return the next four bytes of this input stream, interpreted as a
- * {@code float}.
- * @see SafeDataInputStream#readInt()
- * @see java.lang.Float#intBitsToFloat(int)
- */
- public final float readFloat() {
- return Float.intBitsToFloat(readInt());
- }
-
- /**
- * See the general contract of the {@code readDouble}
- * method of {@code DataInput}.
- *
- * Bytes
- * for this operation are read from the contained
- * input stream.
- *
- * @return the next eight bytes of this input stream, interpreted as a
- * {@code double}.
- * @see SafeDataInputStream#readLong()
- * @see java.lang.Double#longBitsToDouble(long)
- */
- public final double readDouble() {
- return Double.longBitsToDouble(readLong());
- }
-
- private char[] lineBuffer;
-
- /**
- * See the general contract of the {@code readLine}
- * method of {@code DataInput}.
- *
- * Bytes
- * for this operation are read from the contained
- * input stream.
- *
- * @deprecated This method does not properly convert bytes to characters.
- * As of JDK 1.1, the preferred way to read lines of text is via the
- * {@code BufferedReader.readLine()} method. Programs that use the
- * {@code DataInputStream} class to read lines can be converted to use
- * the {@code BufferedReader} class by replacing code of the form:
- *
- * DataInputStream d = new DataInputStream(in);
- *
- * with:
- *
- * BufferedReader d
- * = new BufferedReader(new InputStreamReader(in));
- *
- *
- * @return the next line of text from this input stream.
- * @see java.io.BufferedReader#readLine()
- * @see SafeFilterInputStream#in
- */
- @Deprecated
- public final String readLine() {
- char[] buf = lineBuffer;
-
- if (buf == null) {
- buf = lineBuffer = new char[128];
- }
-
- int room = buf.length;
- int offset = 0;
- int c;
-
- loop: while (true) {
- switch (c = in.read()) {
- case -1:
- case '\n':
- break loop;
-
- case '\r':
- int c2 = in.read();
- if ((c2 != '\n') && (c2 != -1)) {
- if (!(in instanceof SafePushbackInputStream)) {
- this.in = new SafePushbackInputStream(in);
- }
- ((SafePushbackInputStream)in).unread(c2);
- }
- break loop;
-
- default:
- if (--room < 0) {
- buf = new char[offset + 128];
- room = buf.length - offset - 1;
- System.arraycopy(lineBuffer, 0, buf, 0, offset);
- lineBuffer = buf;
- }
- buf[offset++] = (char) c;
- break;
- }
- }
- if ((c == -1) && (offset == 0)) {
- return null;
- }
- return String.copyValueOf(buf, 0, offset);
- }
-
- /**
- * See the general contract of the {@code readUTF}
- * method of {@code DataInput}.
- *
- * Bytes
- * for this operation are read from the contained
- * input stream.
- *
- * @return a Unicode string.
- * @see SafeDataInputStream#readUTF(SafeDataInputStream)
- */
- public final @NotNull String readUTF() {
- return readUTF(this);
- }
-
- /**
- * Reads from the
- * stream {@code in} a representation
- * of a Unicode character string encoded in
- * modified UTF-8 format;
- * this string of characters is then returned as a {@code String}.
- * The details of the modified UTF-8 representation
- * are exactly the same as for the {@code readUTF}
- * method of {@code DataInput}.
- *
- * @param in a data input stream.
- * @return a Unicode string.
- * @see SafeDataInputStream#readUnsignedShort()
- */
- public static String readUTF(SafeDataInputStream in) {
- int utflen = in.readUnsignedShort();
- byte[] bytearr;
- char[] chararr;
- if (in.bytearr.length < utflen){
- in.bytearr = new byte[utflen*2];
- in.chararr = new char[utflen*2];
- }
- chararr = in.chararr;
- bytearr = in.bytearr;
-
- int c, char2, char3;
- int count = 0;
- int chararr_count=0;
-
- in.readFully(bytearr, 0, utflen);
-
- while (count < utflen) {
- c = (int) bytearr[count] & 0xff;
- if (c > 127) break;
- count++;
- chararr[chararr_count++]=(char)c;
- }
-
- while (count < utflen) {
- c = (int) bytearr[count] & 0xff;
- switch (c >> 4) {
- case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:
- /* 0xxxxxxx*/
- count++;
- chararr[chararr_count++]=(char)c;
- break;
- case 12: case 13:
- /* 110x xxxx 10xx xxxx*/
- count += 2;
- if (count > utflen)
- throw new IllegalArgumentException(
- "malformed input: partial character at end");
- char2 = bytearr[count-1];
- if ((char2 & 0xC0) != 0x80)
- throw new IllegalArgumentException(
- "malformed input around byte " + count);
- chararr[chararr_count++]=(char)(((c & 0x1F) << 6) |
- (char2 & 0x3F));
- break;
- case 14:
- /* 1110 xxxx 10xx xxxx 10xx xxxx */
- count += 3;
- if (count > utflen)
- throw new IllegalArgumentException(
- "malformed input: partial character at end");
- char2 = bytearr[count-2];
- char3 = bytearr[count-1];
- if (((char2 & 0xC0) != 0x80) || ((char3 & 0xC0) != 0x80))
- throw new IllegalArgumentException(
- "malformed input around byte " + (count-1));
- chararr[chararr_count++]=(char)(((c & 0x0F) << 12) |
- ((char2 & 0x3F) << 6) |
- ((char3 & 0x3F) << 0));
- break;
- default:
- /* 10xx xxxx, 1111 xxxx */
- throw new IllegalArgumentException(
- "malformed input around byte " + count);
- }
- }
- // The number of chars produced may be less than utflen
- return new String(chararr, 0, chararr_count);
- }
-}
diff --git a/src/main/java/org/warp/commonutils/stream/SafeDataOutput.java b/src/main/java/org/warp/commonutils/stream/SafeDataOutput.java
deleted file mode 100644
index a48aa34..0000000
--- a/src/main/java/org/warp/commonutils/stream/SafeDataOutput.java
+++ /dev/null
@@ -1,339 +0,0 @@
-/*
- * Copyright (c) 1995, 2020, Oracle and/or its affiliates. All rights reserved.
- * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
- *
- *
- *
- *
- *
- *
- *
- *
- *
- *
- *
- *
- *
- *
- *
- *
- *
- *
- *
- *
- */
-
-package org.warp.commonutils.stream;
-
-/**
- * The {@code SafeDataOutput} interface provides
- * for converting data from any of the Java
- * primitive types to a series of bytes and
- * writing these bytes to a binary stream.
- * There is also a facility for converting
- * a {@code String} into
- * modified UTF-8
- * format and writing the resulting series
- * of bytes.
- *
- * For all the methods in this interface that
- * write bytes, it is generally true that if
- * a byte cannot be written for any reason,
- * an {@code IOException} is thrown.
- *
- * @author Frank Yellin
- * @see java.io.DataInput
- * @see java.io.DataOutputStream
- * @since 1.0
- */
-public interface SafeDataOutput {
- /**
- * Writes to the output stream the eight
- * low-order bits of the argument {@code b}.
- * The 24 high-order bits of {@code b}
- * are ignored.
- *
- * @param b the byte to be written.
- */
- void write(int b);
-
- /**
- * Writes to the output stream all the bytes in array {@code b}.
- * If {@code b} is {@code null},
- * a {@code NullPointerException} is thrown.
- * If {@code b.length} is zero, then
- * no bytes are written. Otherwise, the byte
- * {@code b[0]} is written first, then
- * {@code b[1]}, and so on; the last byte
- * written is {@code b[b.length-1]}.
- *
- * @param b the data.
- */
- void write(byte b[]);
-
- /**
- * Writes {@code len} bytes from array
- * {@code b}, in order, to
- * the output stream. If {@code b}
- * is {@code null}, a {@code NullPointerException}
- * is thrown. If {@code off} is negative,
- * or {@code len} is negative, or {@code off+len}
- * is greater than the length of the array
- * {@code b}, then an {@code IndexOutOfBoundsException}
- * is thrown. If {@code len} is zero,
- * then no bytes are written. Otherwise, the
- * byte {@code b[off]} is written first,
- * then {@code b[off+1]}, and so on; the
- * last byte written is {@code b[off+len-1]}.
- *
- * @param b the data.
- * @param off the start offset in the data.
- * @param len the number of bytes to write.
- */
- void write(byte b[], int off, int len);
-
- /**
- * Writes a {@code boolean} value to this output stream.
- * If the argument {@code v}
- * is {@code true}, the value {@code (byte)1}
- * is written; if {@code v} is {@code false},
- * the value {@code (byte)0} is written.
- * The byte written by this method may
- * be read by the {@code readBoolean}
- * method of interface {@code DataInput},
- * which will then return a {@code boolean}
- * equal to {@code v}.
- *
- * @param v the boolean to be written.
- */
- void writeBoolean(boolean v);
-
- /**
- * Writes to the output stream the eight low-order
- * bits of the argument {@code v}.
- * The 24 high-order bits of {@code v}
- * are ignored. (This means that {@code writeByte}
- * does exactly the same thing as {@code write}
- * for an integer argument.) The byte written
- * by this method may be read by the {@code readByte}
- * method of interface {@code DataInput},
- * which will then return a {@code byte}
- * equal to {@code (byte)v}.
- *
- * @param v the byte value to be written.
- */
- void writeByte(int v);
-
- /**
- * Writes two bytes to the output
- * stream to represent the value of the argument.
- * The byte values to be written, in the order
- * shown, are:
- *
{@code
- * (byte)(0xff & (v >> 8))
- * (byte)(0xff & v)
- * }
- * The bytes written by this method may be
- * read by the {@code readShort} method
- * of interface {@code DataInput}, which
- * will then return a {@code short} equal
- * to {@code (short)v}.
- *
- * @param v the {@code short} value to be written.
- */
- void writeShort(int v);
-
- /**
- * Writes a {@code char} value, which
- * is comprised of two bytes, to the
- * output stream.
- * The byte values to be written, in the order
- * shown, are:
- *
{@code
- * (byte)(0xff & (v >> 8))
- * (byte)(0xff & v)
- * }
- * The bytes written by this method may be
- * read by the {@code readChar} method
- * of interface {@code DataInput}, which
- * will then return a {@code char} equal
- * to {@code (char)v}.
- *
- * @param v the {@code char} value to be written.
- */
- void writeChar(int v);
-
- /**
- * Writes an {@code int} value, which is
- * comprised of four bytes, to the output stream.
- * The byte values to be written, in the order
- * shown, are:
- *
{@code
- * (byte)(0xff & (v >> 24))
- * (byte)(0xff & (v >> 16))
- * (byte)(0xff & (v >> 8))
- * (byte)(0xff & v)
- * }
- * The bytes written by this method may be read
- * by the {@code readInt} method of interface
- * {@code DataInput}, which will then
- * return an {@code int} equal to {@code v}.
- *
- * @param v the {@code int} value to be written.
- */
- void writeInt(int v);
-
- /**
- * Writes a {@code long} value, which is
- * comprised of eight bytes, to the output stream.
- * The byte values to be written, in the order
- * shown, are:
- *
{@code
- * (byte)(0xff & (v >> 56))
- * (byte)(0xff & (v >> 48))
- * (byte)(0xff & (v >> 40))
- * (byte)(0xff & (v >> 32))
- * (byte)(0xff & (v >> 24))
- * (byte)(0xff & (v >> 16))
- * (byte)(0xff & (v >> 8))
- * (byte)(0xff & v)
- * }
- * The bytes written by this method may be
- * read by the {@code readLong} method
- * of interface {@code DataInput}, which
- * will then return a {@code long} equal
- * to {@code v}.
- *
- * @param v the {@code long} value to be written.
- */
- void writeLong(long v);
-
- /**
- * Writes a {@code float} value,
- * which is comprised of four bytes, to the output stream.
- * It does this as if it first converts this
- * {@code float} value to an {@code int}
- * in exactly the manner of the {@code Float.floatToIntBits}
- * method and then writes the {@code int}
- * value in exactly the manner of the {@code writeInt}
- * method. The bytes written by this method
- * may be read by the {@code readFloat}
- * method of interface {@code DataInput},
- * which will then return a {@code float}
- * equal to {@code v}.
- *
- * @param v the {@code float} value to be written.
- */
- void writeFloat(float v);
-
- /**
- * Writes a {@code double} value,
- * which is comprised of eight bytes, to the output stream.
- * It does this as if it first converts this
- * {@code double} value to a {@code long}
- * in exactly the manner of the {@code Double.doubleToLongBits}
- * method and then writes the {@code long}
- * value in exactly the manner of the {@code writeLong}
- * method. The bytes written by this method
- * may be read by the {@code readDouble}
- * method of interface {@code DataInput},
- * which will then return a {@code double}
- * equal to {@code v}.
- *
- * @param v the {@code double} value to be written.
- */
- void writeDouble(double v);
-
- /**
- * Writes a string to the output stream.
- * For every character in the string
- * {@code s}, taken in order, one byte
- * is written to the output stream. If
- * {@code s} is {@code null}, a {@code NullPointerException}
- * is thrown.
If {@code s.length}
- * is zero, then no bytes are written. Otherwise,
- * the character {@code s[0]} is written
- * first, then {@code s[1]}, and so on;
- * the last character written is {@code s[s.length-1]}.
- * For each character, one byte is written,
- * the low-order byte, in exactly the manner
- * of the {@code writeByte} method . The
- * high-order eight bits of each character
- * in the string are ignored.
- *
- * @param s the string of bytes to be written.
- */
- void writeBytes(String s);
-
- /**
- * Writes every character in the string {@code s},
- * to the output stream, in order,
- * two bytes per character. If {@code s}
- * is {@code null}, a {@code NullPointerException}
- * is thrown. If {@code s.length}
- * is zero, then no characters are written.
- * Otherwise, the character {@code s[0]}
- * is written first, then {@code s[1]},
- * and so on; the last character written is
- * {@code s[s.length-1]}. For each character,
- * two bytes are actually written, high-order
- * byte first, in exactly the manner of the
- * {@code writeChar} method.
- *
- * @param s the string value to be written.
- */
- void writeChars(String s);
-
- /**
- * Writes two bytes of length information
- * to the output stream, followed
- * by the
- * modified UTF-8
- * representation
- * of every character in the string {@code s}.
- * If {@code s} is {@code null},
- * a {@code NullPointerException} is thrown.
- * Each character in the string {@code s}
- * is converted to a group of one, two, or
- * three bytes, depending on the value of the
- * character.
- * If a character {@code c}
- * is in the range \u0001
through
- * \u007f
, it is represented
- * by one byte:
- *
(byte)c
- * If a character {@code c} is \u0000
- * or is in the range \u0080
- * through \u07ff
, then it is
- * represented by two bytes, to be written
- * in the order shown:
{@code
- * (byte)(0xc0 | (0x1f & (c >> 6)))
- * (byte)(0x80 | (0x3f & c))
- * } If a character
- * {@code c} is in the range \u0800
- * through {@code uffff}, then it is
- * represented by three bytes, to be written
- * in the order shown:
{@code
- * (byte)(0xe0 | (0x0f & (c >> 12)))
- * (byte)(0x80 | (0x3f & (c >> 6)))
- * (byte)(0x80 | (0x3f & c))
- * } First,
- * the total number of bytes needed to represent
- * all the characters of {@code s} is
- * calculated. If this number is larger than
- * {@code 65535}, then a {@code UTFDataFormatException}
- * is thrown. Otherwise, this length is written
- * to the output stream in exactly the manner
- * of the {@code writeShort} method;
- * after this, the one-, two-, or three-byte
- * representation of each character in the
- * string {@code s} is written.
The
- * bytes written by this method may be read
- * by the {@code readUTF} method of interface
- * {@code DataInput}, which will then
- * return a {@code String} equal to {@code s}.
- *
- * @param s the string value to be written.
- */
- void writeUTF(String s);
-}
diff --git a/src/main/java/org/warp/commonutils/stream/SafeDataOutputStream.java b/src/main/java/org/warp/commonutils/stream/SafeDataOutputStream.java
deleted file mode 100644
index 32cc8d5..0000000
--- a/src/main/java/org/warp/commonutils/stream/SafeDataOutputStream.java
+++ /dev/null
@@ -1,408 +0,0 @@
-/*
- * Copyright (c) 1994, 2019, Oracle and/or its affiliates. All rights reserved.
- * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
- *
- *
- *
- *
- *
- *
- *
- *
- *
- *
- *
- *
- *
- *
- *
- *
- *
- *
- *
- *
- */
-
-package org.warp.commonutils.stream;
-
-import java.io.DataOutputStream;
-
-/**
- * A data output stream lets an application write primitive Java data
- * types to an output stream in a portable way. An application can
- * then use a data input stream to read the data back in.
- *
- * @author unascribed
- * @see java.io.DataInputStream
- * @since 1.0
- */
-public class SafeDataOutputStream extends SafeFilterOutputStream implements SafeDataOutput {
- /**
- * The number of bytes written to the data output stream so far.
- * If this counter overflows, it will be wrapped to Integer.MAX_VALUE.
- */
- protected int written;
-
- /**
- * bytearr is initialized on demand by writeUTF
- */
- private byte[] bytearr = null;
-
- /**
- * Creates a new data output stream to write data to the specified
- * underlying output stream. The counter {@code written} is
- * set to zero.
- *
- * @param out the underlying output stream, to be saved for later
- * use.
- * @see SafeFilterOutputStream#out
- */
- public SafeDataOutputStream(SafeOutputStream out) {
- super(out);
- }
-
- /**
- * Increases the written counter by the specified value
- * until it reaches Integer.MAX_VALUE.
- */
- private void incCount(int value) {
- int temp = written + value;
- if (temp < 0) {
- temp = Integer.MAX_VALUE;
- }
- written = temp;
- }
-
- /**
- * Writes the specified byte (the low eight bits of the argument
- * {@code b}) to the underlying output stream. If no exception
- * is thrown, the counter {@code written} is incremented by
- * {@code 1}.
- *
- * Implements the {@code write} method of {@code OutputStream}.
- *
- * @param b the {@code byte} to be written.
- * @see SafeFilterOutputStream#out
- */
- public synchronized void write(int b) {
- out.write(b);
- incCount(1);
- }
-
- /**
- * Writes {@code len} bytes from the specified byte array
- * starting at offset {@code off} to the underlying output stream.
- * If no exception is thrown, the counter {@code written} is
- * incremented by {@code len}.
- *
- * @param b the data.
- * @param off the start offset in the data.
- * @param len the number of bytes to write.
- * @see SafeFilterOutputStream#out
- */
- public synchronized void write(byte b[], int off, int len)
- {
- out.write(b, off, len);
- incCount(len);
- }
-
- /**
- * Flushes this data output stream. This forces any buffered output
- * bytes to be written out to the stream.
- *
- * The {@code flush} method of {@code SafeDataOutputStream}
- * calls the {@code flush} method of its underlying output stream.
- *
- * @see SafeFilterOutputStream#out
- * @see java.io.OutputStream#flush()
- */
- public void flush() {
- out.flush();
- }
-
- /**
- * Writes a {@code boolean} to the underlying output stream as
- * a 1-byte value. The value {@code true} is written out as the
- * value {@code (byte)1}; the value {@code false} is
- * written out as the value {@code (byte)0}. If no exception is
- * thrown, the counter {@code written} is incremented by
- * {@code 1}.
- *
- * @param v a {@code boolean} value to be written.
- * @see SafeFilterOutputStream#out
- */
- public final void writeBoolean(boolean v) {
- out.write(v ? 1 : 0);
- incCount(1);
- }
-
- /**
- * Writes out a {@code byte} to the underlying output stream as
- * a 1-byte value. If no exception is thrown, the counter
- * {@code written} is incremented by {@code 1}.
- *
- * @param v a {@code byte} value to be written.
- * @see SafeFilterOutputStream#out
- */
- public final void writeByte(int v) {
- out.write(v);
- incCount(1);
- }
-
- /**
- * Writes a {@code short} to the underlying output stream as two
- * bytes, high byte first. If no exception is thrown, the counter
- * {@code written} is incremented by {@code 2}.
- *
- * @param v a {@code short} to be written.
- * @see SafeFilterOutputStream#out
- */
- public final void writeShort(int v) {
- out.write((v >>> 8) & 0xFF);
- out.write((v >>> 0) & 0xFF);
- incCount(2);
- }
-
- /**
- * Writes a {@code char} to the underlying output stream as a
- * 2-byte value, high byte first. If no exception is thrown, the
- * counter {@code written} is incremented by {@code 2}.
- *
- * @param v a {@code char} value to be written.
- * @see SafeFilterOutputStream#out
- */
- public final void writeChar(int v) {
- out.write((v >>> 8) & 0xFF);
- out.write((v >>> 0) & 0xFF);
- incCount(2);
- }
-
- /**
- * Writes an {@code int} to the underlying output stream as four
- * bytes, high byte first. If no exception is thrown, the counter
- * {@code written} is incremented by {@code 4}.
- *
- * @param v an {@code int} to be written.
- * @see SafeFilterOutputStream#out
- */
- public final void writeInt(int v) {
- out.write((v >>> 24) & 0xFF);
- out.write((v >>> 16) & 0xFF);
- out.write((v >>> 8) & 0xFF);
- out.write((v >>> 0) & 0xFF);
- incCount(4);
- }
-
- private byte writeBuffer[] = new byte[8];
-
- /**
- * Writes a {@code long} to the underlying output stream as eight
- * bytes, high byte first. In no exception is thrown, the counter
- * {@code written} is incremented by {@code 8}.
- *
- * @param v a {@code long} to be written.
- * @see SafeFilterOutputStream#out
- */
- public final void writeLong(long v) {
- writeBuffer[0] = (byte)(v >>> 56);
- writeBuffer[1] = (byte)(v >>> 48);
- writeBuffer[2] = (byte)(v >>> 40);
- writeBuffer[3] = (byte)(v >>> 32);
- writeBuffer[4] = (byte)(v >>> 24);
- writeBuffer[5] = (byte)(v >>> 16);
- writeBuffer[6] = (byte)(v >>> 8);
- writeBuffer[7] = (byte)(v >>> 0);
- out.write(writeBuffer, 0, 8);
- incCount(8);
- }
-
- /**
- * Converts the float argument to an {@code int} using the
- * {@code floatToIntBits} method in class {@code Float},
- * and then writes that {@code int} value to the underlying
- * output stream as a 4-byte quantity, high byte first. If no
- * exception is thrown, the counter {@code written} is
- * incremented by {@code 4}.
- *
- * @param v a {@code float} value to be written.
- * @see SafeFilterOutputStream#out
- * @see java.lang.Float#floatToIntBits(float)
- */
- public final void writeFloat(float v) {
- writeInt(Float.floatToIntBits(v));
- }
-
- /**
- * Converts the double argument to a {@code long} using the
- * {@code doubleToLongBits} method in class {@code Double},
- * and then writes that {@code long} value to the underlying
- * output stream as an 8-byte quantity, high byte first. If no
- * exception is thrown, the counter {@code written} is
- * incremented by {@code 8}.
- *
- * @param v a {@code double} value to be written.
- * @see SafeFilterOutputStream#out
- * @see java.lang.Double#doubleToLongBits(double)
- */
- public final void writeDouble(double v) {
- writeLong(Double.doubleToLongBits(v));
- }
-
- /**
- * Writes out the string to the underlying output stream as a
- * sequence of bytes. Each character in the string is written out, in
- * sequence, by discarding its high eight bits. If no exception is
- * thrown, the counter {@code written} is incremented by the
- * length of {@code s}.
- *
- * @param s a string of bytes to be written.
- * @see SafeFilterOutputStream#out
- */
- public final void writeBytes(String s) {
- int len = s.length();
- for (int i = 0 ; i < len ; i++) {
- out.write((byte)s.charAt(i));
- }
- incCount(len);
- }
-
- /**
- * Writes a string to the underlying output stream as a sequence of
- * characters. Each character is written to the data output stream as
- * if by the {@code writeChar} method. If no exception is
- * thrown, the counter {@code written} is incremented by twice
- * the length of {@code s}.
- *
- * @param s a {@code String} value to be written.
- * @see SafeDataOutputStream#writeChar(int)
- * @see SafeFilterOutputStream#out
- */
- public final void writeChars(String s) {
- int len = s.length();
- for (int i = 0 ; i < len ; i++) {
- int v = s.charAt(i);
- out.write((v >>> 8) & 0xFF);
- out.write((v >>> 0) & 0xFF);
- }
- incCount(len * 2);
- }
-
- /**
- * Writes a string to the underlying output stream using
- * modified UTF-8
- * encoding in a machine-independent manner.
- *
- * First, two bytes are written to the output stream as if by the
- * {@code writeShort} method giving the number of bytes to
- * follow. This value is the number of bytes actually written out,
- * not the length of the string. Following the length, each character
- * of the string is output, in sequence, using the modified UTF-8 encoding
- * for the character. If no exception is thrown, the counter
- * {@code written} is incremented by the total number of
- * bytes written to the output stream. This will be at least two
- * plus the length of {@code str}, and at most two plus
- * thrice the length of {@code str}.
- *
- * @param str a string to be written.
- * @see #writeChars(String)
- */
- public final void writeUTF(String str) {
- writeUTF(str, this);
- }
-
- /**
- * Writes a string to the specified DataOutput using
- * modified UTF-8
- * encoding in a machine-independent manner.
- *
- * First, two bytes are written to out as if by the {@code writeShort}
- * method giving the number of bytes to follow. This value is the number of
- * bytes actually written out, not the length of the string. Following the
- * length, each character of the string is output, in sequence, using the
- * modified UTF-8 encoding for the character. If no exception is thrown, the
- * counter {@code written} is incremented by the total number of
- * bytes written to the output stream. This will be at least two
- * plus the length of {@code str}, and at most two plus
- * thrice the length of {@code str}.
- *
- * @param str a string to be written.
- * @param out destination to write to
- * @return The number of bytes written out.
- */
- static int writeUTF(String str, SafeDataOutput out) {
- final int strlen = str.length();
- int utflen = strlen; // optimized for ASCII
-
- for (int i = 0; i < strlen; i++) {
- int c = str.charAt(i);
- if (c >= 0x80 || c == 0)
- utflen += (c >= 0x800) ? 2 : 1;
- }
-
- if (utflen > 65535 || /* overflow */ utflen < strlen)
- throw new IllegalArgumentException(tooLongMsg(str, utflen));
-
- final byte[] bytearr;
- if (out instanceof SafeDataOutputStream) {
- SafeDataOutputStream dos = (SafeDataOutputStream)out;
- if (dos.bytearr == null || (dos.bytearr.length < (utflen + 2)))
- dos.bytearr = new byte[(utflen*2) + 2];
- bytearr = dos.bytearr;
- } else {
- bytearr = new byte[utflen + 2];
- }
-
- int count = 0;
- bytearr[count++] = (byte) ((utflen >>> 8) & 0xFF);
- bytearr[count++] = (byte) ((utflen >>> 0) & 0xFF);
-
- int i = 0;
- for (i = 0; i < strlen; i++) { // optimized for initial run of ASCII
- int c = str.charAt(i);
- if (c >= 0x80 || c == 0) break;
- bytearr[count++] = (byte) c;
- }
-
- for (; i < strlen; i++) {
- int c = str.charAt(i);
- if (c < 0x80 && c != 0) {
- bytearr[count++] = (byte) c;
- } else if (c >= 0x800) {
- bytearr[count++] = (byte) (0xE0 | ((c >> 12) & 0x0F));
- bytearr[count++] = (byte) (0x80 | ((c >> 6) & 0x3F));
- bytearr[count++] = (byte) (0x80 | ((c >> 0) & 0x3F));
- } else {
- bytearr[count++] = (byte) (0xC0 | ((c >> 6) & 0x1F));
- bytearr[count++] = (byte) (0x80 | ((c >> 0) & 0x3F));
- }
- }
- out.write(bytearr, 0, utflen + 2);
- return utflen + 2;
- }
-
- private static String tooLongMsg(String s, int bits32) {
- int slen = s.length();
- String head = s.substring(0, 8);
- String tail = s.substring(slen - 8, slen);
- // handle int overflow with max 3x expansion
- long actualLength = (long)slen + Integer.toUnsignedLong(bits32 - slen);
- return "encoded string (" + head + "..." + tail + ") too long: "
- + actualLength + " bytes";
- }
-
- /**
- * Returns the current value of the counter {@code written},
- * the number of bytes written to this data output stream so far.
- * If the counter overflows, it will be wrapped to Integer.MAX_VALUE.
- *
- * @return the value of the {@code written} field.
- * @see SafeDataOutputStream#written
- */
- public final int size() {
- return written;
- }
-
- public DataOutputStream asDataOutputStream() {
- return new DataOutputStream(this.out);
- }
-}
diff --git a/src/main/java/org/warp/commonutils/stream/SafeFilterInputStream.java b/src/main/java/org/warp/commonutils/stream/SafeFilterInputStream.java
deleted file mode 100644
index 28be7e9..0000000
--- a/src/main/java/org/warp/commonutils/stream/SafeFilterInputStream.java
+++ /dev/null
@@ -1,210 +0,0 @@
-package org.warp.commonutils.stream;
-
-/**
- * A {@code FilterInputStream} contains
- * some other input stream, which it uses as
- * its basic source of data, possibly transforming
- * the data along the way or providing additional
- * functionality. The class {@code FilterInputStream}
- * itself simply overrides all methods of
- * {@code InputStream} with versions that
- * pass all requests to the contained input
- * stream. Subclasses of {@code FilterInputStream}
- * may further override some of these methods
- * and may also provide additional methods
- * and fields.
- *
- * @author Jonathan Payne
- * @since 1.0
- */
-public class SafeFilterInputStream extends SafeInputStream {
- /**
- * The input stream to be filtered.
- */
- protected volatile SafeInputStream in;
-
- /**
- * Creates a {@code FilterInputStream}
- * by assigning the argument {@code in}
- * to the field {@code this.in} so as
- * to remember it for later use.
- *
- * @param in the underlying input stream, or {@code null} if
- * this instance is to be created without an underlying stream.
- */
- protected SafeFilterInputStream(SafeInputStream in) {
- this.in = in;
- }
-
- /**
- * Reads the next byte of data from this input stream. The value
- * byte is returned as an {@code int} in the range
- * {@code 0} to {@code 255}. If no byte is available
- * because the end of the stream has been reached, the value
- * {@code -1} is returned. This method blocks until input data
- * is available, the end of the stream is detected, or an exception
- * is thrown.
- *
- * This method
- * simply performs {@code in.read()} and returns the result.
- *
- * @return the next byte of data, or {@code -1} if the end of the
- * stream is reached.
- * @see SafeFilterInputStream#in
- */
- public int read() {
- return in.read();
- }
-
- /**
- * Reads up to {@code b.length} bytes of data from this
- * input stream into an array of bytes. This method blocks until some
- * input is available.
- *
- * This method simply performs the call
- * {@code read(b, 0, b.length)} and returns
- * the result. It is important that it does
- * not do {@code in.read(b)} instead;
- * certain subclasses of {@code FilterInputStream}
- * depend on the implementation strategy actually
- * used.
- *
- * @param b the buffer into which the data is read.
- * @return the total number of bytes read into the buffer, or
- * {@code -1} if there is no more data because the end of
- * the stream has been reached.
- * @see SafeFilterInputStream#read(byte[], int, int)
- */
- public int read(byte b[]) {
- return read(b, 0, b.length);
- }
-
- /**
- * Reads up to {@code len} bytes of data from this input stream
- * into an array of bytes. If {@code len} is not zero, the method
- * blocks until some input is available; otherwise, no
- * bytes are read and {@code 0} is returned.
- *
- * This method simply performs {@code in.read(b, off, len)}
- * and returns the result.
- *
- * @param b the buffer into which the data is read.
- * @param off the start offset in the destination array {@code b}
- * @param len the maximum number of bytes read.
- * @return the total number of bytes read into the buffer, or
- * {@code -1} if there is no more data because the end of
- * the stream has been reached.
- * @throws NullPointerException If {@code b} is {@code null}.
- * @throws IndexOutOfBoundsException If {@code off} is negative,
- * {@code len} is negative, or {@code len} is greater than
- * {@code b.length - off}
- * @see SafeFilterInputStream#in
- */
- public int read(byte b[], int off, int len) {
- return in.read(b, off, len);
- }
-
- /**
- * Skips over and discards {@code n} bytes of data from the
- * input stream. The {@code skip} method may, for a variety of
- * reasons, end up skipping over some smaller number of bytes,
- * possibly {@code 0}. The actual number of bytes skipped is
- * returned.
- *
- * This method simply performs {@code in.skip(n)}.
- *
- * @param n the number of bytes to be skipped.
- * @return the actual number of bytes skipped.
- */
- public long skip(long n) {
- return in.skip(n);
- }
-
- /**
- * Returns an estimate of the number of bytes that can be read (or
- * skipped over) from this input stream without blocking by the next
- * caller of a method for this input stream. The next caller might be
- * the same thread or another thread. A single read or skip of this
- * many bytes will not block, but may read or skip fewer bytes.
- *
- * This method returns the result of {@link #in in}.available().
- *
- * @return an estimate of the number of bytes that can be read (or skipped
- * over) from this input stream without blocking.
- */
- public int available() {
- return in.available();
- }
-
- /**
- * Closes this input stream and releases any system resources
- * associated with the stream.
- * This
- * method simply performs {@code in.close()}.
- *
- * @see SafeFilterInputStream#in
- */
- public void close() {
- in.close();
- }
-
- /**
- * Marks the current position in this input stream. A subsequent
- * call to the {@code reset} method repositions this stream at
- * the last marked position so that subsequent reads re-read the same bytes.
- *
- * The {@code readlimit} argument tells this input stream to
- * allow that many bytes to be read before the mark position gets
- * invalidated.
- *
- * This method simply performs {@code in.mark(readlimit)}.
- *
- * @param readlimit the maximum limit of bytes that can be read before
- * the mark position becomes invalid.
- * @see SafeFilterInputStream#in
- * @see SafeFilterInputStream#reset()
- */
- public synchronized void mark(int readlimit) {
- in.mark(readlimit);
- }
-
- /**
- * Repositions this stream to the position at the time the
- * {@code mark} method was last called on this input stream.
- *
- * This method
- * simply performs {@code in.reset()}.
- *
- * Stream marks are intended to be used in
- * situations where you need to read ahead a little to see what's in
- * the stream. Often this is most easily done by invoking some
- * general parser. If the stream is of the type handled by the
- * parse, it just chugs along happily. If the stream is not of
- * that type, the parser should toss an exception when it fails.
- * If this happens within readlimit bytes, it allows the outer
- * code to reset the stream and try another parser.
- *
- * @see SafeFilterInputStream#in
- * @see SafeFilterInputStream#mark(int)
- */
- public synchronized void reset() {
- in.reset();
- }
-
- /**
- * Tests if this input stream supports the {@code mark}
- * and {@code reset} methods.
- * This method
- * simply performs {@code in.markSupported()}.
- *
- * @return {@code true} if this stream type supports the
- * {@code mark} and {@code reset} method;
- * {@code false} otherwise.
- * @see SafeFilterInputStream#in
- * @see java.io.InputStream#mark(int)
- * @see java.io.InputStream#reset()
- */
- public boolean markSupported() {
- return in.markSupported();
- }
-}
diff --git a/src/main/java/org/warp/commonutils/stream/SafeFilterOutputStream.java b/src/main/java/org/warp/commonutils/stream/SafeFilterOutputStream.java
deleted file mode 100644
index f4fd0e5..0000000
--- a/src/main/java/org/warp/commonutils/stream/SafeFilterOutputStream.java
+++ /dev/null
@@ -1,180 +0,0 @@
-package org.warp.commonutils.stream;
-
-
-/**
- * This class is the superclass of all classes that filter output
- * streams. These streams sit on top of an already existing output
- * stream (the underlying output stream) which it uses as its
- * basic sink of data, but possibly transforming the data along the
- * way or providing additional functionality.
- *
- * The class {@code FilterOutputStream} itself simply overrides
- * all methods of {@code SafeOutputStream} with versions that pass
- * all requests to the underlying output stream. Subclasses of
- * {@code FilterOutputStream} may further override some of these
- * methods as well as provide additional methods and fields.
- *
- * @author Jonathan Payne
- * @since 1.0
- */
-public class SafeFilterOutputStream extends SafeOutputStream {
- /**
- * The underlying output stream to be filtered.
- */
- protected SafeOutputStream out;
-
- /**
- * Whether the stream is closed; implicitly initialized to false.
- */
- private volatile boolean closed;
-
- /**
- * Object used to prevent a race on the 'closed' instance variable.
- */
- private final Object closeLock = new Object();
-
- /**
- * Creates an output stream filter built on top of the specified
- * underlying output stream.
- *
- * @param out the underlying output stream to be assigned to
- * the field {@code this.out} for later use, or
- * {@code null} if this instance is to be
- * created without an underlying stream.
- */
- public SafeFilterOutputStream(SafeOutputStream out) {
- this.out = out;
- }
-
- /**
- * Writes the specified {@code byte} to this output stream.
- *
- * The {@code write} method of {@code FilterOutputStream}
- * calls the {@code write} method of its underlying output stream,
- * that is, it performs {@code out.write(b)}.
- *
- * Implements the abstract {@code write} method of {@code SafeOutputStream}.
- *
- * @param b the {@code byte}.
- */
- @Override
- public void write(int b) {
- out.write(b);
- }
-
- /**
- * Writes {@code b.length} bytes to this output stream.
- *
- * The {@code write} method of {@code FilterOutputStream}
- * calls its {@code write} method of three arguments with the
- * arguments {@code b}, {@code 0}, and
- * {@code b.length}.
- *
- * Note that this method does not call the one-argument
- * {@code write} method of its underlying output stream with
- * the single argument {@code b}.
- *
- * @param b the data to be written.
- * @see SafeFilterOutputStream#write(byte[], int, int)
- */
- @Override
- public void write(byte b[]) {
- write(b, 0, b.length);
- }
-
- /**
- * Writes {@code len} bytes from the specified
- * {@code byte} array starting at offset {@code off} to
- * this output stream.
- *
- * The {@code write} method of {@code FilterOutputStream}
- * calls the {@code write} method of one argument on each
- * {@code byte} to output.
- *
- * Note that this method does not call the {@code write} method
- * of its underlying output stream with the same arguments. Subclasses
- * of {@code FilterOutputStream} should provide a more efficient
- * implementation of this method.
- *
- * @param b the data.
- * @param off the start offset in the data.
- * @param len the number of bytes to write.
- * @see SafeFilterOutputStream#write(int)
- */
- @Override
- public void write(byte b[], int off, int len) {
- if ((off | len | (b.length - (len + off)) | (off + len)) < 0)
- throw new IndexOutOfBoundsException();
-
- for (int i = 0 ; i < len ; i++) {
- write(b[off + i]);
- }
- }
-
- /**
- * Flushes this output stream and forces any buffered output bytes
- * to be written out to the stream.
- *
- * The {@code flush} method of {@code FilterOutputStream}
- * calls the {@code flush} method of its underlying output stream.
- *
- * @see SafeFilterOutputStream#out
- */
- @Override
- public void flush() {
- out.flush();
- }
-
- /**
- * Closes this output stream and releases any system resources
- * associated with the stream.
- *
- * When not already closed, the {@code close} method of {@code
- * FilterOutputStream} calls its {@code flush} method, and then
- * calls the {@code close} method of its underlying output stream.
- *
- * @see SafeFilterOutputStream#flush()
- * @see SafeFilterOutputStream#out
- */
- @Override
- public void close() {
- if (closed) {
- return;
- }
- synchronized (closeLock) {
- if (closed) {
- return;
- }
- closed = true;
- }
-
- Throwable flushException = null;
- try {
- flush();
- } catch (Throwable e) {
- flushException = e;
- throw e;
- } finally {
- if (flushException == null) {
- out.close();
- } else {
- try {
- out.close();
- } catch (Throwable closeException) {
- // evaluate possible precedence of flushException over closeException
- if ((flushException instanceof ThreadDeath) &&
- !(closeException instanceof ThreadDeath)) {
- flushException.addSuppressed(closeException);
- throw (ThreadDeath) flushException;
- }
-
- if (flushException != closeException) {
- closeException.addSuppressed(flushException);
- }
-
- throw closeException;
- }
- }
- }
- }
-}
diff --git a/src/main/java/org/warp/commonutils/stream/SafeInputStream.java b/src/main/java/org/warp/commonutils/stream/SafeInputStream.java
deleted file mode 100644
index db60727..0000000
--- a/src/main/java/org/warp/commonutils/stream/SafeInputStream.java
+++ /dev/null
@@ -1,201 +0,0 @@
-package org.warp.commonutils.stream;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Objects;
-
-public abstract class SafeInputStream extends InputStream {
-
- // MAX_SKIP_BUFFER_SIZE is used to determine the maximum buffer size to
- // use when skipping.
- private static final int MAX_SKIP_BUFFER_SIZE = 2048;
-
- private static final int DEFAULT_BUFFER_SIZE = 8192;
-
- @Override
- public abstract int read();
-
- public int read(byte b[]) {
- return read(b, 0, b.length);
- }
-
- public int read(byte b[], int off, int len) {
- Objects.checkFromIndexSize(off, len, b.length);
- if (len == 0) {
- return 0;
- }
-
- int c = read();
- if (c == -1) {
- return -1;
- }
- b[off] = (byte)c;
-
- int i = 1;
- for (; i < len ; i++) {
- c = read();
- if (c == -1) {
- break;
- }
- b[off + i] = (byte)c;
- }
- return i;
- }
-
- public byte[] readAllBytes() {
- return readNBytes(Integer.MAX_VALUE);
- }
-
- private static final int MAX_BUFFER_SIZE = Integer.MAX_VALUE - 8;
-
- public byte[] readNBytes(int len) {
- if (len < 0) {
- throw new IllegalArgumentException("len < 0");
- }
-
- List bufs = null;
- byte[] result = null;
- int total = 0;
- int remaining = len;
- int n;
- do {
- byte[] buf = new byte[Math.min(remaining, DEFAULT_BUFFER_SIZE)];
- int nread = 0;
-
- // read to EOF which may read more or less than buffer size
- while ((n = read(buf, nread,
- Math.min(buf.length - nread, remaining))) > 0) {
- nread += n;
- remaining -= n;
- }
-
- if (nread > 0) {
- if (MAX_BUFFER_SIZE - total < nread) {
- throw new OutOfMemoryError("Required array size too large");
- }
- total += nread;
- if (result == null) {
- result = buf;
- } else {
- if (bufs == null) {
- bufs = new ArrayList<>();
- bufs.add(result);
- }
- bufs.add(buf);
- }
- }
- // if the last call to read returned -1 or the number of bytes
- // requested have been read then break
- } while (n >= 0 && remaining > 0);
-
- if (bufs == null) {
- if (result == null) {
- return new byte[0];
- }
- return result.length == total ?
- result : Arrays.copyOf(result, total);
- }
-
- result = new byte[total];
- int offset = 0;
- remaining = total;
- for (byte[] b : bufs) {
- int count = Math.min(b.length, remaining);
- System.arraycopy(b, 0, result, offset, count);
- offset += count;
- remaining -= count;
- }
-
- return result;
- }
-
- public int readNBytes(byte[] b, int off, int len) {
- Objects.checkFromIndexSize(off, len, b.length);
-
- int n = 0;
- while (n < len) {
- int count = read(b, off + n, len - n);
- if (count < 0)
- break;
- n += count;
- }
- return n;
- }
-
- public long skip(long n) {
- long remaining = n;
- int nr;
-
- if (n <= 0) {
- return 0;
- }
-
- int size = (int)Math.min(MAX_SKIP_BUFFER_SIZE, remaining);
- byte[] skipBuffer = new byte[size];
- while (remaining > 0) {
- nr = read(skipBuffer, 0, (int)Math.min(size, remaining));
- if (nr < 0) {
- break;
- }
- remaining -= nr;
- }
-
- return n - remaining;
- }
-
- public void skipNBytes(long n) {
- if (n > 0) {
- long ns = skip(n);
- if (ns >= 0 && ns < n) { // skipped too few bytes
- // adjust number to skip
- n -= ns;
- // read until requested number skipped or EOS reached
- while (n > 0 && read() != -1) {
- n--;
- }
- // if not enough skipped, then EOFE
- if (n != 0) {
- throw new IndexOutOfBoundsException();
- }
- } else if (ns != n) { // skipped negative or too many bytes
- throw new IllegalArgumentException("Unable to skip exactly");
- }
- }
- }
-
- public int available() {
- return 0;
- }
-
- public void close() {}
-
- public synchronized void mark(int readlimit) {}
-
- public synchronized void reset() {
- throw new UnsupportedOperationException("mark/reset not supported");
- }
-
- public boolean markSupported() {
- return false;
- }
-
- public long transferTo(OutputStream out) {
- Objects.requireNonNull(out, "out");
- long transferred = 0;
- byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
- int read;
- while ((read = this.read(buffer, 0, DEFAULT_BUFFER_SIZE)) >= 0) {
- try {
- out.write(buffer, 0, read);
- } catch (IOException e) {
- throw new IllegalStateException(e);
- }
- transferred += read;
- }
- return transferred;
- }
-}
diff --git a/src/main/java/org/warp/commonutils/stream/SafeMeasurableInputStream.java b/src/main/java/org/warp/commonutils/stream/SafeMeasurableInputStream.java
deleted file mode 100644
index 547f847..0000000
--- a/src/main/java/org/warp/commonutils/stream/SafeMeasurableInputStream.java
+++ /dev/null
@@ -1,28 +0,0 @@
-package org.warp.commonutils.stream;
-
-/*
- * Copyright (C) 2005-2020 Sebastiano Vigna
- *
- * Licensed 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.
- */
-
-
-import java.io.InputStream;
-
-/** An {@link InputStream} that implements also the {@link SafeMeasurableStream} interface.
- *
- * @since 5.0.4
- */
-
-public abstract class SafeMeasurableInputStream extends SafeInputStream implements SafeMeasurableStream {
-}
diff --git a/src/main/java/org/warp/commonutils/stream/SafeMeasurableOutputStream.java b/src/main/java/org/warp/commonutils/stream/SafeMeasurableOutputStream.java
deleted file mode 100644
index fb67530..0000000
--- a/src/main/java/org/warp/commonutils/stream/SafeMeasurableOutputStream.java
+++ /dev/null
@@ -1,27 +0,0 @@
-package org.warp.commonutils.stream;
-
-/*
- * Copyright (C) 2005-2020 Sebastiano Vigna
- *
- * Licensed 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.
- */
-
-import java.io.OutputStream;
-
-/** An {@link OutputStream} that implements also the {@link SafeMeasurableStream} interface.
- *
- * @since 6.0.0
- */
-
-public abstract class SafeMeasurableOutputStream extends SafeOutputStream implements SafeMeasurableStream {
-}
diff --git a/src/main/java/org/warp/commonutils/stream/SafeMeasurableStream.java b/src/main/java/org/warp/commonutils/stream/SafeMeasurableStream.java
deleted file mode 100644
index 3e8ecc5..0000000
--- a/src/main/java/org/warp/commonutils/stream/SafeMeasurableStream.java
+++ /dev/null
@@ -1,49 +0,0 @@
-package org.warp.commonutils.stream;
-
-/*
- * Copyright (C) 2005-2020 Sebastiano Vigna
- *
- * Licensed 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.
- */
-
-
-/** An stream that provides eager access to its length,
- * and keeps track of the current position (e.g., the number of bytes read so far, or the current
- * position of the file pointer).
- *
- * This class has two methods, both specified as optional. This apparently bizarre
- * behaviour is necessary because of wrapper classes which use reflection
- * to support those methods (see, e.g., {@link MeasurableInputStream}, {@link FastBufferedInputStream} and {@link FastBufferedOutputStream}).
- *
- * @since 6.0.0
- */
-
-public interface SafeMeasurableStream {
-
- /** Returns the overall length of this stream (optional operation). In most cases, this will require the
- * stream to perform some extra action, possibly changing the state of the input stream itself (typically, reading
- * all the bytes up to the end, or flushing on output stream).
- * Implementing classes should always document what state will the input stream be in
- * after calling this method, and which kind of exception could be thrown.
- */
- long length();
-
- /** Returns the current position in this stream (optional operation).
- *
- *
Usually, the position is just the number of bytes read or written
- * since the stream was opened, but in the case of a
- * {@link it.unimi.dsi.fastutil.io.RepositionableStream} it
- * represent the current position.
- */
- long position();
-}
diff --git a/src/main/java/org/warp/commonutils/stream/SafeOutputStream.java b/src/main/java/org/warp/commonutils/stream/SafeOutputStream.java
deleted file mode 100644
index 0fa9867..0000000
--- a/src/main/java/org/warp/commonutils/stream/SafeOutputStream.java
+++ /dev/null
@@ -1,169 +0,0 @@
-package org.warp.commonutils.stream;
-
-import java.io.Closeable;
-import java.io.Flushable;
-import java.io.OutputStream;
-import java.util.Objects;
-import org.jetbrains.annotations.NotNull;
-
-/**
- * This abstract class is the superclass of all classes representing
- * an output stream of bytes. An output stream accepts output bytes
- * and sends them to some sink.
- *
- * Applications that need to define a subclass of
- * {@code OutputStream} must always provide at least a method
- * that writes one byte of output.
- *
- * @author Arthur van Hoff
- * @see java.io.BufferedOutputStream
- * @see java.io.ByteArrayOutputStream
- * @see java.io.DataOutputStream
- * @see java.io.FilterOutputStream
- * @see java.io.InputStream
- * @see java.io.OutputStream#write(int)
- * @since 1.0
- */
-public abstract class SafeOutputStream extends OutputStream implements Closeable, Flushable {
- /**
- * Constructor for subclasses to call.
- */
- public SafeOutputStream() {}
-
- /**
- * Returns a new {@code OutputStream} which discards all bytes. The
- * returned stream is initially open. The stream is closed by calling
- * the {@code close()} method. Subsequent calls to {@code close()} have
- * no effect.
- *
- *
While the stream is open, the {@code write(int)}, {@code
- * write(byte[])}, and {@code write(byte[], int, int)} methods do nothing.
- * After the stream has been closed, these methods all throw {@code
- * IOException}.
- *
- *
The {@code flush()} method does nothing.
- *
- * @return an {@code OutputStream} which discards all bytes
- *
- * @since 11
- */
- public static java.io.OutputStream nullOutputStream() {
- return new java.io.OutputStream() {
- private volatile boolean closed;
-
- private void ensureOpen() {
- if (closed) {
- throw new IllegalStateException("Stream closed");
- }
- }
-
- @Override
- public void write(int b) {
- ensureOpen();
- }
-
- @Override
- public void write(byte @NotNull [] b, int off, int len) {
- Objects.checkFromIndexSize(off, len, b.length);
- ensureOpen();
- }
-
- @Override
- public void close() {
- closed = true;
- }
- };
- }
-
- /**
- * Writes the specified byte to this output stream. The general
- * contract for {@code write} is that one byte is written
- * to the output stream. The byte to be written is the eight
- * low-order bits of the argument {@code b}. The 24
- * high-order bits of {@code b} are ignored.
- *
- * Subclasses of {@code OutputStream} must provide an
- * implementation for this method.
- *
- * @param b the {@code byte}.
- */
- public abstract void write(int b);
-
- /**
- * Writes {@code b.length} bytes from the specified byte array
- * to this output stream. The general contract for {@code write(b)}
- * is that it should have exactly the same effect as the call
- * {@code write(b, 0, b.length)}.
- *
- * @param b the data.
- * @see java.io.OutputStream#write(byte[], int, int)
- */
- public void write(byte @NotNull [] b) {
- write(b, 0, b.length);
- }
-
- /**
- * Writes {@code len} bytes from the specified byte array
- * starting at offset {@code off} to this output stream.
- * The general contract for {@code write(b, off, len)} is that
- * some of the bytes in the array {@code b} are written to the
- * output stream in order; element {@code b[off]} is the first
- * byte written and {@code b[off+len-1]} is the last byte written
- * by this operation.
- *
- * The {@code write} method of {@code OutputStream} calls
- * the write method of one argument on each of the bytes to be
- * written out. Subclasses are encouraged to override this method and
- * provide a more efficient implementation.
- *
- * If {@code b} is {@code null}, a
- * {@code NullPointerException} is thrown.
- *
- * If {@code off} is negative, or {@code len} is negative, or
- * {@code off+len} is greater than the length of the array
- * {@code b}, then an {@code IndexOutOfBoundsException} is thrown.
- *
- * @param b the data.
- * @param off the start offset in the data.
- * @param len the number of bytes to write.
- */
- public void write(byte[] b, int off, int len) {
- Objects.checkFromIndexSize(off, len, b.length);
- // len == 0 condition implicitly handled by loop bounds
- for (int i = 0 ; i < len ; i++) {
- write(b[off + i]);
- }
- }
-
- /**
- * Flushes this output stream and forces any buffered output bytes
- * to be written out. The general contract of {@code flush} is
- * that calling it is an indication that, if any bytes previously
- * written have been buffered by the implementation of the output
- * stream, such bytes should immediately be written to their
- * intended destination.
- *
- * If the intended destination of this stream is an abstraction provided by
- * the underlying operating system, for example a file, then flushing the
- * stream guarantees only that bytes previously written to the stream are
- * passed to the operating system for writing; it does not guarantee that
- * they are actually written to a physical device such as a disk drive.
- *
- * The {@code flush} method of {@code OutputStream} does nothing.
- *
- */
- public void flush() {
- }
-
- /**
- * Closes this output stream and releases any system resources
- * associated with this stream. The general contract of {@code close}
- * is that it closes the output stream. A closed stream cannot perform
- * output operations and cannot be reopened.
- *
- * The {@code close} method of {@code OutputStream} does nothing.
- *
- */
- public void close() {
- }
-}
diff --git a/src/main/java/org/warp/commonutils/stream/SafePushbackInputStream.java b/src/main/java/org/warp/commonutils/stream/SafePushbackInputStream.java
deleted file mode 100644
index 04420d9..0000000
--- a/src/main/java/org/warp/commonutils/stream/SafePushbackInputStream.java
+++ /dev/null
@@ -1,332 +0,0 @@
-package org.warp.commonutils.stream;
-
-/**
- * A {@code PushbackInputStream} adds
- * functionality to another input stream, namely
- * the ability to "push back" or "unread" bytes,
- * by storing pushed-back bytes in an internal buffer.
- * This is useful in situations where
- * it is convenient for a fragment of code
- * to read an indefinite number of data bytes
- * that are delimited by a particular byte
- * value; after reading the terminating byte,
- * the code fragment can "unread" it, so that
- * the next read operation on the input stream
- * will reread the byte that was pushed back.
- * For example, bytes representing the characters
- * constituting an identifier might be terminated
- * by a byte representing an operator character;
- * a method whose job is to read just an identifier
- * can read until it sees the operator and
- * then push the operator back to be re-read.
- *
- * @author David Connelly
- * @author Jonathan Payne
- * @since 1.0
- */
-public class SafePushbackInputStream extends SafeFilterInputStream {
- /**
- * The pushback buffer.
- * @since 1.1
- */
- protected byte[] buf;
-
- /**
- * The position within the pushback buffer from which the next byte will
- * be read. When the buffer is empty, {@code pos} is equal to
- * {@code buf.length}; when the buffer is full, {@code pos} is
- * equal to zero.
- *
- * @since 1.1
- */
- protected int pos;
-
- /**
- * Check to make sure that this stream has not been closed
- */
- private void ensureOpen() {
- if (in == null)
- throw new IllegalStateException("Stream closed");
- }
-
- /**
- * Creates a {@code PushbackInputStream}
- * with a pushback buffer of the specified {@code size},
- * and saves its argument, the input stream
- * {@code in}, for later use. Initially,
- * the pushback buffer is empty.
- *
- * @param in the input stream from which bytes will be read.
- * @param size the size of the pushback buffer.
- * @throws IllegalArgumentException if {@code size <= 0}
- * @since 1.1
- */
- public SafePushbackInputStream(SafeInputStream in, int size) {
- super(in);
- if (size <= 0) {
- throw new IllegalArgumentException("size <= 0");
- }
- this.buf = new byte[size];
- this.pos = size;
- }
-
- /**
- * Creates a {@code PushbackInputStream}
- * with a 1-byte pushback buffer, and saves its argument, the input stream
- * {@code in}, for later use. Initially,
- * the pushback buffer is empty.
- *
- * @param in the input stream from which bytes will be read.
- */
- public SafePushbackInputStream(SafeInputStream in) {
- this(in, 1);
- }
-
- /**
- * Reads the next byte of data from this input stream. The value
- * byte is returned as an {@code int} in the range
- * {@code 0} to {@code 255}. If no byte is available
- * because the end of the stream has been reached, the value
- * {@code -1} is returned. This method blocks until input data
- * is available, the end of the stream is detected, or an exception
- * is thrown.
- *
- *
This method returns the most recently pushed-back byte, if there is
- * one, and otherwise calls the {@code read} method of its underlying
- * input stream and returns whatever value that method returns.
- *
- * @return the next byte of data, or {@code -1} if the end of the
- * stream has been reached.
- * or an I/O error occurs.
- * @see java.io.InputStream#read()
- */
- public int read() {
- ensureOpen();
- if (pos < buf.length) {
- return buf[pos++] & 0xff;
- }
- return super.read();
- }
-
- /**
- * Reads up to {@code len} bytes of data from this input stream into
- * an array of bytes. This method first reads any pushed-back bytes; after
- * that, if fewer than {@code len} bytes have been read then it
- * reads from the underlying input stream. If {@code len} is not zero, the method
- * blocks until at least 1 byte of input is available; otherwise, no
- * bytes are read and {@code 0} is returned.
- *
- * @param b the buffer into which the data is read.
- * @param off the start offset in the destination array {@code b}
- * @param len the maximum number of bytes read.
- * @return the total number of bytes read into the buffer, or
- * {@code -1} if there is no more data because the end of
- * the stream has been reached.
- * @throws NullPointerException If {@code b} is {@code null}.
- * @throws IndexOutOfBoundsException If {@code off} is negative,
- * {@code len} is negative, or {@code len} is greater than
- * {@code b.length - off}
- * or an I/O error occurs.
- * @see java.io.InputStream#read(byte[], int, int)
- */
- public int read(byte[] b, int off, int len) {
- ensureOpen();
- if (b == null) {
- throw new NullPointerException();
- } else if (off < 0 || len < 0 || len > b.length - off) {
- throw new IndexOutOfBoundsException();
- } else if (len == 0) {
- return 0;
- }
-
- int avail = buf.length - pos;
- if (avail > 0) {
- if (len < avail) {
- avail = len;
- }
- System.arraycopy(buf, pos, b, off, avail);
- pos += avail;
- off += avail;
- len -= avail;
- }
- if (len > 0) {
- len = super.read(b, off, len);
- if (len == -1) {
- return avail == 0 ? -1 : avail;
- }
- return avail + len;
- }
- return avail;
- }
-
- /**
- * Pushes back a byte by copying it to the front of the pushback buffer.
- * After this method returns, the next byte to be read will have the value
- * {@code (byte)b}.
- *
- * @param b the {@code int} value whose low-order
- * byte is to be pushed back.
- */
- public void unread(int b) {
- ensureOpen();
- if (pos == 0) {
- throw new IllegalStateException("Push back buffer is full");
- }
- buf[--pos] = (byte)b;
- }
-
- /**
- * Pushes back a portion of an array of bytes by copying it to the front
- * of the pushback buffer. After this method returns, the next byte to be
- * read will have the value {@code b[off]}, the byte after that will
- * have the value {@code b[off+1]}, and so forth.
- *
- * @param b the byte array to push back.
- * @param off the start offset of the data.
- * @param len the number of bytes to push back.
- * @throws NullPointerException If {@code b} is {@code null}.
- * @since 1.1
- */
- public void unread(byte[] b, int off, int len) {
- ensureOpen();
- if (len > pos) {
- throw new IllegalStateException("Push back buffer is full");
- }
- pos -= len;
- System.arraycopy(b, off, buf, pos, len);
- }
-
- /**
- * Pushes back an array of bytes by copying it to the front of the
- * pushback buffer. After this method returns, the next byte to be read
- * will have the value {@code b[0]}, the byte after that will have the
- * value {@code b[1]}, and so forth.
- *
- * @param b the byte array to push back
- * @throws NullPointerException If {@code b} is {@code null}.
- * @since 1.1
- */
- public void unread(byte[] b) {
- unread(b, 0, b.length);
- }
-
- /**
- * Returns an estimate of the number of bytes that can be read (or
- * skipped over) from this input stream without blocking by the next
- * invocation of a method for this input stream. The next invocation might be
- * the same thread or another thread. A single read or skip of this
- * many bytes will not block, but may read or skip fewer bytes.
- *
- *
The method returns the sum of the number of bytes that have been
- * pushed back and the value returned by {@link
- * SafeFilterInputStream#available available}.
- *
- * @return the number of bytes that can be read (or skipped over) from
- * the input stream without blocking.
- * @see SafeFilterInputStream#in
- * @see java.io.InputStream#available()
- */
- public int available() {
- ensureOpen();
- int n = buf.length - pos;
- int avail = super.available();
- return n > (Integer.MAX_VALUE - avail)
- ? Integer.MAX_VALUE
- : n + avail;
- }
-
- /**
- * Skips over and discards {@code n} bytes of data from this
- * input stream. The {@code skip} method may, for a variety of
- * reasons, end up skipping over some smaller number of bytes,
- * possibly zero. If {@code n} is negative, no bytes are skipped.
- *
- *
The {@code skip} method of {@code PushbackInputStream}
- * first skips over the bytes in the pushback buffer, if any. It then
- * calls the {@code skip} method of the underlying input stream if
- * more bytes need to be skipped. The actual number of bytes skipped
- * is returned.
- *
- * @param n {@inheritDoc}
- * @return {@inheritDoc}
- * @see SafeFilterInputStream#in
- * @see java.io.InputStream#skip(long n)
- * @since 1.2
- */
- public long skip(long n) {
- ensureOpen();
- if (n <= 0) {
- return 0;
- }
-
- long pskip = buf.length - pos;
- if (pskip > 0) {
- if (n < pskip) {
- pskip = n;
- }
- pos += pskip;
- n -= pskip;
- }
- if (n > 0) {
- pskip += super.skip(n);
- }
- return pskip;
- }
-
- /**
- * Tests if this input stream supports the {@code mark} and
- * {@code reset} methods, which it does not.
- *
- * @return {@code false}, since this class does not support the
- * {@code mark} and {@code reset} methods.
- * @see java.io.InputStream#mark(int)
- * @see java.io.InputStream#reset()
- */
- public boolean markSupported() {
- return false;
- }
-
- /**
- * Marks the current position in this input stream.
- *
- *
The {@code mark} method of {@code PushbackInputStream}
- * does nothing.
- *
- * @param readlimit the maximum limit of bytes that can be read before
- * the mark position becomes invalid.
- * @see java.io.InputStream#reset()
- */
- public synchronized void mark(int readlimit) {
- }
-
- /**
- * Repositions this stream to the position at the time the
- * {@code mark} method was last called on this input stream.
- *
- *
The method {@code reset} for class
- * {@code PushbackInputStream} does nothing except throw an
- * {@code IOException}.
- *
- * @see java.io.InputStream#mark(int)
- * @see java.io.IOException
- */
- public synchronized void reset() {
- throw new UnsupportedOperationException("mark/reset not supported");
- }
-
- /**
- * Closes this input stream and releases any system resources
- * associated with the stream.
- * Once the stream has been closed, further read(), unread(),
- * available(), reset(), or skip() invocations will throw an IOException.
- * Closing a previously closed stream has no effect.
- *
- */
- public synchronized void close() {
- if (in == null)
- return;
- in.close();
- in = null;
- buf = null;
- }
-}
diff --git a/src/main/java/org/warp/commonutils/stream/SafeRepositionableStream.java b/src/main/java/org/warp/commonutils/stream/SafeRepositionableStream.java
deleted file mode 100644
index e79f2df..0000000
--- a/src/main/java/org/warp/commonutils/stream/SafeRepositionableStream.java
+++ /dev/null
@@ -1,40 +0,0 @@
-package org.warp.commonutils.stream;
-
-/*
- * Copyright (C) 2005-2020 Sebastiano Vigna
- *
- * Licensed 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.
- */
-
-
-/** A basic interface specifying positioning methods for a byte stream.
- *
- * @author Sebastiano Vigna
- * @since 4.4
- */
-
-public interface SafeRepositionableStream {
-
- /** Sets the current stream position.
- *
- * @param newPosition the new stream position.
- */
- void position(long newPosition);
-
- /** Returns the current stream position.
- *
- * @return the current stream position.
- */
- long position();
-
-}
diff --git a/src/main/java/org/warp/commonutils/type/AddStrategy.java b/src/main/java/org/warp/commonutils/type/AddStrategy.java
deleted file mode 100644
index 4506a53..0000000
--- a/src/main/java/org/warp/commonutils/type/AddStrategy.java
+++ /dev/null
@@ -1,10 +0,0 @@
-package org.warp.commonutils.type;
-
-public enum AddStrategy {
- OVERWRITE_POSITION,
- KEEP_POSITION;
-
- public static AddStrategy getDefault() {
- return KEEP_POSITION;
- }
-}
diff --git a/src/main/java/org/warp/commonutils/type/ArrayStack.java b/src/main/java/org/warp/commonutils/type/ArrayStack.java
deleted file mode 100644
index 86cfe37..0000000
--- a/src/main/java/org/warp/commonutils/type/ArrayStack.java
+++ /dev/null
@@ -1,15 +0,0 @@
-package org.warp.commonutils.type;
-
-import it.unimi.dsi.fastutil.objects.ObjectArrayList;
-import java.util.Collection;
-
-public class ArrayStack extends FastUtilStackWrapper {
-
- public ArrayStack() {
- super(new ObjectArrayList<>());
- }
-
- public ArrayStack(Collection stack) {
- super(new ObjectArrayList<>(stack));
- }
-}
diff --git a/src/main/java/org/warp/commonutils/type/Bytes.java b/src/main/java/org/warp/commonutils/type/Bytes.java
deleted file mode 100644
index 65cf933..0000000
--- a/src/main/java/org/warp/commonutils/type/Bytes.java
+++ /dev/null
@@ -1,68 +0,0 @@
-package org.warp.commonutils.type;
-
-import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import org.jetbrains.annotations.NotNull;
-
-public class Bytes {
- public final byte[] data;
-
- public Bytes(byte @NotNull[] data) {
- this.data = data;
- }
-
- public static Map extends Bytes,? extends Bytes> ofMap(Map oldMap) {
- var newMap = new HashMap(oldMap.size());
- oldMap.forEach((key, value) -> newMap.put(new Bytes(key), new Bytes(value)));
- return newMap;
- }
-
- public static List extends Bytes> ofList(List oldList) {
- var newList = new ArrayList(oldList.size());
- oldList.forEach((item) -> newList.add(new Bytes(item)));
- return newList;
- }
-
- public static Set extends Bytes> ofSet(Set oldSet) {
- var newSet = new ObjectOpenHashSet(oldSet.size());
- oldSet.forEach((item) -> newSet.add(new Bytes(item)));
- return newSet;
- }
-
- public static byte[][] toByteArray(Collection value) {
- Bytes[] valueBytesArray = value.toArray(Bytes[]::new);
- byte[][] convertedResult = new byte[valueBytesArray.length][];
- for (int i = 0; i < valueBytesArray.length; i++) {
- convertedResult[i] = valueBytesArray[i].data;
- }
- return convertedResult;
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) {
- return true;
- }
- if (o == null || getClass() != o.getClass()) {
- return false;
- }
- Bytes that = (Bytes) o;
- return Arrays.equals(data, that.data);
- }
-
- @Override
- public int hashCode() {
- return Arrays.hashCode(data);
- }
-
- @Override
- public String toString() {
- return Arrays.toString(data);
- }
-}
diff --git a/src/main/java/org/warp/commonutils/type/EqualsWrapper.java b/src/main/java/org/warp/commonutils/type/EqualsWrapper.java
deleted file mode 100644
index d74b12f..0000000
--- a/src/main/java/org/warp/commonutils/type/EqualsWrapper.java
+++ /dev/null
@@ -1,35 +0,0 @@
-package org.warp.commonutils.type;
-
-import java.util.Objects;
-
-public class EqualsWrapper {
-
- private final T value;
- private final Object equal;
-
- public EqualsWrapper(T value, Object equal) {
- this.value = value;
- this.equal = equal;
- }
-
- public T get() {
- return value;
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) {
- return true;
- }
- if (o == null || getClass() != o.getClass()) {
- return false;
- }
- EqualsWrapper> that = (EqualsWrapper>) o;
- return Objects.equals(equal, that.equal);
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(equal);
- }
-}
diff --git a/src/main/java/org/warp/commonutils/type/FastUtilStackWrapper.java b/src/main/java/org/warp/commonutils/type/FastUtilStackWrapper.java
deleted file mode 100644
index e08e4e4..0000000
--- a/src/main/java/org/warp/commonutils/type/FastUtilStackWrapper.java
+++ /dev/null
@@ -1,128 +0,0 @@
-package org.warp.commonutils.type;
-
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.Objects;
-import java.util.StringJoiner;
-import org.jetbrains.annotations.NotNull;
-
-public class FastUtilStackWrapper implements Stack, Collection {
-
- private final it.unimi.dsi.fastutil.Stack stack;
- private final Collection collection;
-
- public & Collection> FastUtilStackWrapper(U stack) {
- this.stack = stack;
- this.collection = stack;
- }
-
- @Override
- public void push(T o) {
- this.stack.push(o);
- }
-
- @Override
- public T pop() {
- return this.stack.pop();
- }
-
- @Override
- public T peek(int n) {
- return this.stack.peek(n);
- }
-
- @Override
- public int size() {
- return collection.size();
- }
-
- @Override
- public boolean isEmpty() {
- return this.stack.isEmpty();
- }
-
- @Override
- public boolean contains(Object o) {
- return collection.contains(o);
- }
-
- @NotNull
- @Override
- public Iterator iterator() {
- return collection.iterator();
- }
-
- @NotNull
- @Override
- public Object @NotNull [] toArray() {
- return collection.toArray();
- }
-
- @NotNull
- @Override
- public T1 @NotNull [] toArray(@NotNull T1 @NotNull [] a) {
- //noinspection SuspiciousToArrayCall
- return collection.toArray(a);
- }
-
- @Override
- public boolean add(T t) {
- return collection.add(t);
- }
-
- @Override
- public boolean remove(Object o) {
- return collection.remove(o);
- }
-
- @Override
- public boolean containsAll(@NotNull Collection> c) {
- return collection.containsAll(c);
- }
-
- @Override
- public boolean addAll(@NotNull Collection extends T> c) {
- return collection.addAll(c);
- }
-
- @Override
- public boolean removeAll(@NotNull Collection> c) {
- return collection.removeAll(c);
- }
-
- @Override
- public boolean retainAll(@NotNull Collection> c) {
- return collection.retainAll(c);
- }
-
- @Override
- public void clear() {
- collection.clear();
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) {
- return true;
- }
- if (o == null || getClass() != o.getClass()) {
- return false;
- }
-
- FastUtilStackWrapper> that = (FastUtilStackWrapper>) o;
-
- return Objects.equals(stack, that.stack);
- }
-
- @Override
- public int hashCode() {
- return stack != null ? stack.hashCode() : 0;
- }
-
- @Override
- public String toString() {
- return new StringJoiner(", ", FastUtilStackWrapper.class.getSimpleName() + "[", "]")
- .add("stack=" + stack)
- .toString();
- }
-}
diff --git a/src/main/java/org/warp/commonutils/type/ImmutableLinkedSet.java b/src/main/java/org/warp/commonutils/type/ImmutableLinkedSet.java
deleted file mode 100644
index 1501c00..0000000
--- a/src/main/java/org/warp/commonutils/type/ImmutableLinkedSet.java
+++ /dev/null
@@ -1,157 +0,0 @@
-package org.warp.commonutils.type;
-
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.LinkedHashSet;
-import java.util.Set;
-import java.util.Spliterator;
-import java.util.function.Consumer;
-import java.util.function.IntFunction;
-import java.util.function.Predicate;
-import java.util.stream.Stream;
-import org.jetbrains.annotations.NotNull;
-
-public class ImmutableLinkedSet implements Set {
-
- private final LinkedHashSet set;
-
- public ImmutableLinkedSet(LinkedHashSet set) {
- this.set = set;
- }
-
- @Override
- public int size() {
- return set.size();
- }
-
- @Override
- public boolean isEmpty() {
- return set.isEmpty();
- }
-
- @Override
- public boolean contains(Object o) {
- return set.contains(o);
- }
-
- @NotNull
- @Override
- public Iterator iterator() {
- var it = set.iterator();
- return new Iterator<>() {
- @Override
- public boolean hasNext() {
- return it.hasNext();
- }
-
- @Override
- public E next() {
- return it.next();
- }
- };
- }
-
- @Override
- public void forEach(Consumer super E> action) {
- set.forEach(action);
- }
-
- @NotNull
- @Override
- public Object @NotNull [] toArray() {
- return set.toArray();
- }
-
- @NotNull
- @Override
- public T @NotNull [] toArray(@NotNull T @NotNull [] a) {
- //noinspection SuspiciousToArrayCall
- return set.toArray(a);
- }
-
- @Override
- public T[] toArray(IntFunction generator) {
- //noinspection SuspiciousToArrayCall
- return set.toArray(generator);
- }
-
- @Override
- public boolean add(E e) {
- throw new UnsupportedOperationException("Read only");
- }
-
- @Override
- public boolean remove(Object o) {
- throw new UnsupportedOperationException("Read only");
- }
-
- @Override
- public boolean containsAll(@NotNull Collection> c) {
- return set.containsAll(c);
- }
-
- @Override
- public boolean addAll(@NotNull Collection extends E> c) {
- throw new UnsupportedOperationException("Read only");
- }
-
- @Override
- public boolean retainAll(@NotNull Collection> c) {
- throw new UnsupportedOperationException("Read only");
- }
-
- @Override
- public boolean removeAll(@NotNull Collection> c) {
- throw new UnsupportedOperationException("Read only");
- }
-
- @Override
- public boolean removeIf(Predicate super E> filter) {
- throw new UnsupportedOperationException("Read only");
- }
-
- @Override
- public void clear() {
- throw new UnsupportedOperationException("Read only");
- }
-
- @Override
- public Spliterator spliterator() {
- var spl = set.spliterator();
- return new Spliterator<>() {
- @Override
- public boolean tryAdvance(Consumer super E> action) {
- return spl.tryAdvance(action);
- }
-
- @Override
- public Spliterator trySplit() {
- return spl.trySplit();
- }
-
- @Override
- public long estimateSize() {
- return spl.estimateSize();
- }
-
- @Override
- public int characteristics() {
- return spl.characteristics();
- }
- };
- }
-
- @Override
- public Stream stream() {
- return set.stream();
- }
-
- @Override
- public Stream parallelStream() {
- return set.parallelStream();
- }
-
- public LinkedHashSet copyMutable() {
- return new LinkedHashSet<>(set);
- }
-}
diff --git a/src/main/java/org/warp/commonutils/type/MultiAssociation.java b/src/main/java/org/warp/commonutils/type/MultiAssociation.java
deleted file mode 100644
index d529795..0000000
--- a/src/main/java/org/warp/commonutils/type/MultiAssociation.java
+++ /dev/null
@@ -1,116 +0,0 @@
-package org.warp.commonutils.type;
-
-import it.unimi.dsi.fastutil.objects.ObjectSet;
-import java.util.Set;
-
-/**
- * One to many relationship
- *
- * o ------- o
- * +--- o
- * o ---+--- o
- * +-|- o
- * o -----|- o
- * o ------- o
- * o ---+--- o
- * +--- o
- *
- * @param Source type
- * @param Destination type
- */
-public interface MultiAssociation {
-
- /**
- * Link source to dest
- * @param src Source
- * @param dest Destination
- * @return true if linked, false if it was already linked with that destination
- */
- boolean link(T src, U dest);
-
- /**
- * Unlink only if src is linked with dest
- * @param src Source
- * @param dest Destination
- * @return true if unlinked, false if not present
- */
- boolean unlink(T src, U dest);
-
- /**
- * Unlink
- * @param src Source
- * @return previous linked destinations
- */
- Set unlink(T src);
-
- /**
- * Unlink
- * @param dest Destination
- * @return previous linked source
- */
- Set unlinkFromSource(U dest);
-
- /**
- * Check if link exists
- * @param src Source
- * @return true if source is linked with at least 1 destination
- */
- default boolean hasAnyLink(T src) {
- return !getLinks(src).isEmpty();
- }
-
- /**
- * Check if link exists
- * @param dest Destination
- * @return true if destination is linked with at least 1 destination
- */
- default boolean hasAnyLinkSource(U dest) {
- return !getLinkSources(dest).isEmpty();
- }
-
- /**
- * Check if link exists
- * @param src Source
- * @param dest Destination
- * @return true if source and destination are linked together
- */
- boolean hasLink(T src, U dest);
-
- /**
- * Get a link destination
- * @param src Source
- * @return Existing linked destinations
- */
- Set getLinks(T src);
-
- /**
- * Get a link source
- * @param dest Source
- * @return Existing linked sources
- */
- Set getLinkSources(U dest);
-
- /**
- * Delete all links
- */
- void clear();
-
- /**
- * Get the count of existing links
- * @return size
- */
- int size();
-
- /**
- * Get all the sources
- * @return Set of sources
- */
- ObjectSet getSources();
-
- /**
- * Get all the destinations
- * @return Set of destinations
- */
- ObjectSet getDestinations();
-
-}
diff --git a/src/main/java/org/warp/commonutils/type/ShortNamedThreadFactory.java b/src/main/java/org/warp/commonutils/type/ShortNamedThreadFactory.java
deleted file mode 100644
index 0bb4eee..0000000
--- a/src/main/java/org/warp/commonutils/type/ShortNamedThreadFactory.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.warp.commonutils.type;
-
-
-import java.util.Locale;
-import java.util.concurrent.Executors;
-import java.util.concurrent.ThreadFactory;
-import java.util.concurrent.atomic.AtomicInteger;
-import org.jetbrains.annotations.NotNull;
-
-/**
- * A default {@link ThreadFactory} implementation that accepts the name prefix
- * of the created threads as a constructor argument. Otherwise, this factory
- * yields the same semantics as the thread factory returned by
- * {@link Executors#defaultThreadFactory()}.
- */
-public class ShortNamedThreadFactory implements ThreadFactory {
-
- private static int POOL_NUMBERS_COUNT = 50;
- private static final AtomicInteger[] threadPoolNumber = new AtomicInteger[POOL_NUMBERS_COUNT];
- static {
- for (int i = 0; i < threadPoolNumber.length; i++) {
- threadPoolNumber[i] = new AtomicInteger(1);
- }
- }
- private ThreadGroup group;
- private boolean daemon;
- private final AtomicInteger threadNumber = new AtomicInteger(1);
- private static final String NAME_PATTERN = "%s-%d";
- private final String threadNamePrefix;
-
- /**
- * Creates a new {@link ShortNamedThreadFactory} instance
- *
- * @param threadNamePrefix the name prefix assigned to each thread created.
- */
- public ShortNamedThreadFactory(String threadNamePrefix) {
- group = Thread.currentThread().getThreadGroup();
- this.threadNamePrefix = String.format(Locale.ROOT, NAME_PATTERN,
- checkPrefix(threadNamePrefix), threadPoolNumber[(threadNamePrefix.hashCode() % POOL_NUMBERS_COUNT / 2) + POOL_NUMBERS_COUNT / 2].getAndIncrement());
- }
-
- public ShortNamedThreadFactory withGroup(ThreadGroup threadGroup) {
- this.group = threadGroup;
- return this;
- }
-
- public ShortNamedThreadFactory setDaemon(boolean daemon) {
- this.daemon = daemon;
- return this;
- }
-
- private static String checkPrefix(String prefix) {
- return prefix == null || prefix.length() == 0 ? "Unnamed" : prefix;
- }
-
- /**
- * Creates a new {@link Thread}
- *
- * @see java.util.concurrent.ThreadFactory#newThread(java.lang.Runnable)
- */
- @Override
- public Thread newThread(@NotNull Runnable r) {
- final Thread t = new Thread(group, r, String.format(Locale.ROOT, "%s-%d",
- this.threadNamePrefix, threadNumber.getAndIncrement()), 0);
- t.setDaemon(daemon);
- t.setPriority(Thread.NORM_PRIORITY);
- return t;
- }
-
-}
diff --git a/src/main/java/org/warp/commonutils/type/Stack.java b/src/main/java/org/warp/commonutils/type/Stack.java
deleted file mode 100644
index 9dc3dac..0000000
--- a/src/main/java/org/warp/commonutils/type/Stack.java
+++ /dev/null
@@ -1,43 +0,0 @@
-package org.warp.commonutils.type;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-import org.warp.commonutils.error.IndexOutOfBoundsException;
-
-/**
- * A stack
- *
- * A stack must provide the classical {@link #push(Object)} and
- * {@link #pop()} operations, but may be also peekable to some extent: it may provide just the {@link #top()}
- * function, or even a more powerful {@link #peek(int)} method that provides access to all elements on the stack
- * (indexed from the top, which has index 0).
- */
-
-public interface Stack extends it.unimi.dsi.fastutil.Stack {
-
- /**
- * Pop multiple times
- * @param count the number of times to pop
- * @return list of popped elements
- */
- default List pop(int count) {
- if (count < 0) {
- throw new IndexOutOfBoundsException(count);
- }
- var items = new ArrayList(count);
- for (int i = 0; i < count; i++) {
- items.add(this.pop());
- }
- return items;
- }
-
- static Stack create() {
- return new ArrayStack<>();
- }
-
- static & Collection> Stack wrap(U stack) {
- return new FastUtilStackWrapper<>(stack);
- }
-
-}
diff --git a/src/main/java/org/warp/commonutils/type/VariableWrapper.java b/src/main/java/org/warp/commonutils/type/VariableWrapper.java
deleted file mode 100644
index b0b5857..0000000
--- a/src/main/java/org/warp/commonutils/type/VariableWrapper.java
+++ /dev/null
@@ -1,10 +0,0 @@
-package org.warp.commonutils.type;
-
-public class VariableWrapper {
-
- public volatile T var;
-
- public VariableWrapper(T value) {
- this.var = value;
- }
-}