DBusArray.java
/*
* SPDX-FileCopyrightText: 2025 Lucimber UG
* SPDX-License-Identifier: Apache-2.0
*/
package com.lucimber.dbus.type;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import java.util.Objects;
import java.util.Spliterator;
import java.util.function.Consumer;
import java.util.function.Predicate;
import java.util.function.UnaryOperator;
import java.util.stream.Stream;
/**
* An ordered collection of elements.
*
* @param <ElementT> The element's data type.
*/
public final class DBusArray<ElementT extends DBusType>
implements List<ElementT>, DBusContainerType {
private final ArrayList<ElementT> delegate;
private final DBusSignature signature;
/**
* Constructs a new instance.
*
* @param signature a {@link DBusSignature}; must describe an array
*/
public DBusArray(final DBusSignature signature) {
this.signature = Objects.requireNonNull(signature);
if (!signature.isArray()) {
throw new IllegalArgumentException("signature must describe an array");
}
this.delegate = new ArrayList<>();
}
/**
* Constructs a new instance from another one.
*
* @param other a {@link DBusArray}
*/
public DBusArray(final DBusArray<ElementT> other) {
Objects.requireNonNull(other);
delegate = new ArrayList<>(other.delegate);
signature = other.signature;
}
// Factory methods for common array types
/**
* Creates an array of strings.
*
* @param strings the strings to add to the array
* @return a new DBusArray containing DBusString elements
*/
public static DBusArray<DBusString> ofStrings(final String... strings) {
final DBusArray<DBusString> array = new DBusArray<>(DBusSignature.valueOf("as"));
for (final String str : strings) {
array.add(DBusString.valueOf(str));
}
return array;
}
/**
* Creates an array of 32-bit integers.
*
* @param integers the integers to add to the array
* @return a new DBusArray containing DBusInt32 elements
*/
public static DBusArray<DBusInt32> ofInt32s(final int... integers) {
final DBusArray<DBusInt32> array = new DBusArray<>(DBusSignature.valueOf("ai"));
for (final int i : integers) {
array.add(DBusInt32.valueOf(i));
}
return array;
}
/**
* Creates an array of 64-bit integers.
*
* @param longs the longs to add to the array
* @return a new DBusArray containing DBusInt64 elements
*/
public static DBusArray<DBusInt64> ofInt64s(final long... longs) {
final DBusArray<DBusInt64> array = new DBusArray<>(DBusSignature.valueOf("ax"));
for (final long l : longs) {
array.add(DBusInt64.valueOf(l));
}
return array;
}
/**
* Creates an array of booleans.
*
* @param booleans the booleans to add to the array
* @return a new DBusArray containing DBusBoolean elements
*/
public static DBusArray<DBusBoolean> ofBooleans(final boolean... booleans) {
final DBusArray<DBusBoolean> array = new DBusArray<>(DBusSignature.valueOf("ab"));
for (final boolean b : booleans) {
array.add(DBusBoolean.valueOf(b));
}
return array;
}
/**
* Creates an array of doubles.
*
* @param doubles the doubles to add to the array
* @return a new DBusArray containing DBusDouble elements
*/
public static DBusArray<DBusDouble> ofDoubles(final double... doubles) {
final DBusArray<DBusDouble> array = new DBusArray<>(DBusSignature.valueOf("ad"));
for (final double d : doubles) {
array.add(DBusDouble.valueOf(d));
}
return array;
}
/**
* Creates an array of object paths.
*
* @param paths the paths to add to the array
* @return a new DBusArray containing DBusObjectPath elements
*/
public static DBusArray<DBusObjectPath> ofObjectPaths(final String... paths) {
final DBusArray<DBusObjectPath> array = new DBusArray<>(DBusSignature.valueOf("ao"));
for (final String path : paths) {
array.add(DBusObjectPath.valueOf(path));
}
return array;
}
/**
* Creates an empty array with the specified element signature.
*
* @param elementSignature the signature of the array elements (e.g., "s" for strings)
* @param <T> the element type
* @return a new empty DBusArray
*/
@SuppressWarnings("unchecked")
public static <T extends DBusType> DBusArray<T> empty(final String elementSignature) {
return new DBusArray<>(DBusSignature.valueOf("a" + elementSignature));
}
@Override
public int size() {
return delegate.size();
}
@Override
public boolean isEmpty() {
return delegate.isEmpty();
}
@Override
public boolean contains(final Object o) {
return delegate.contains(o);
}
@Override
public Iterator<ElementT> iterator() {
return delegate.iterator();
}
@Override
public Object[] toArray() {
return delegate.toArray();
}
@Override
public <T> T[] toArray(final T[] a) {
return delegate.toArray(a);
}
@Override
public void add(final int index, final ElementT element) {
delegate.add(index, element);
}
@Override
public boolean add(final ElementT value) {
return delegate.add(value);
}
@Override
public ElementT remove(final int index) {
return delegate.remove(index);
}
@Override
public boolean remove(final Object o) {
return delegate.remove(o);
}
@Override
public boolean containsAll(final Collection<?> c) {
return delegate.containsAll(c);
}
@Override
public boolean addAll(final Collection<? extends ElementT> c) {
return delegate.addAll(c);
}
@Override
public boolean addAll(final int index, final Collection<? extends ElementT> c) {
return delegate.addAll(index, c);
}
@Override
public boolean removeAll(final Collection<?> c) {
return delegate.removeAll(c);
}
@Override
public boolean retainAll(final Collection<?> c) {
return delegate.retainAll(c);
}
@Override
public void clear() {
delegate.clear();
}
@Override
public ElementT get(final int index) {
return delegate.get(index);
}
@Override
public ElementT set(final int index, final ElementT element) {
return delegate.set(index, element);
}
@Override
public int indexOf(final Object o) {
return delegate.indexOf(o);
}
@Override
public int lastIndexOf(final Object o) {
return delegate.lastIndexOf(o);
}
@Override
public ListIterator<ElementT> listIterator() {
return delegate.listIterator();
}
@Override
public ListIterator<ElementT> listIterator(final int index) {
return delegate.listIterator(index);
}
@Override
public List<ElementT> subList(final int fromIndex, final int toIndex) {
return delegate.subList(fromIndex, toIndex);
}
@Override
public DBusSignature getSignature() {
return signature;
}
@Override
public Type getType() {
return Type.ARRAY;
}
@Override
public List<ElementT> getDelegate() {
return new ArrayList<>(delegate);
}
@Override
public void forEach(final Consumer<? super ElementT> action) {
delegate.forEach(action);
}
@Override
public void replaceAll(final UnaryOperator<ElementT> operator) {
delegate.replaceAll(operator);
}
@Override
public void sort(final Comparator<? super ElementT> c) {
delegate.sort(c);
}
@Override
public Spliterator<ElementT> spliterator() {
return delegate.spliterator();
}
@Override
public boolean removeIf(final Predicate<? super ElementT> filter) {
return delegate.removeIf(filter);
}
@Override
public Stream<ElementT> stream() {
return delegate.stream();
}
@Override
public Stream<ElementT> parallelStream() {
return delegate.parallelStream();
}
@Override
public boolean equals(final Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
final DBusArray<?> dBusArray = (DBusArray<?>) o;
return delegate.equals(dBusArray.delegate) && signature.equals(dBusArray.signature);
}
@Override
public int hashCode() {
return Objects.hash(delegate, signature);
}
}