From 9812b662a44fe50bb2f8700002c78a7d59904b28 Mon Sep 17 00:00:00 2001 From: James Yuzawa Date: Mon, 12 Jan 2026 13:20:46 -0500 Subject: [PATCH 01/11] optimize hot loops --- .../section/AbstractLazilyEncodableSection.java | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/AbstractLazilyEncodableSection.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/AbstractLazilyEncodableSection.java index 167e7188..8b94a586 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/AbstractLazilyEncodableSection.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/AbstractLazilyEncodableSection.java @@ -30,7 +30,9 @@ public boolean hasField(String fieldName) { this.decoded = true; } - for(EncodableSegment segment : segments) { + int numSegments = segments.size(); + for (int i = 0; i < numSegments; i++) { + EncodableSegment segment = segments.get(i); if (segment.hasField(fieldName)) { return true; } @@ -46,7 +48,9 @@ public Object getFieldValue(String fieldName) { this.decoded = true; } - for(EncodableSegment segment : segments) { + int numSegments = segments.size(); + for (int i = 0; i < numSegments; i++) { + EncodableSegment segment = segments.get(i); if(segment.hasField(fieldName)) { return segment.getFieldValue(fieldName); } @@ -62,7 +66,9 @@ public void setFieldValue(String fieldName, Object value) { this.decoded = true; } - for(EncodableSegment segment : segments) { + int numSegments = segments.size(); + for (int i = 0; i < numSegments; i++) { + EncodableSegment segment = segments.get(i); if(segment.hasField(fieldName)) { segment.setFieldValue(fieldName, value); this.dirty = true; From 674d03f8ff00ab0fd186ad78232254e08a47b727 Mon Sep 17 00:00:00 2001 From: James Yuzawa Date: Mon, 12 Jan 2026 14:10:30 -0500 Subject: [PATCH 02/11] clean up mutability collection flow --- .../AbstractDirtyableBitStringDataType.java | 24 ++++++ .../AbstractEncodableBitStringDataType.java | 6 +- .../iab/gpp/encoder/datatype/DataType.java | 6 +- .../EncodableArrayOfFixedIntegerRanges.java | 20 +++-- .../EncodableFibonacciIntegerRange.java | 7 +- .../datatype/EncodableFixedBitfield.java | 7 +- .../datatype/EncodableFixedIntegerList.java | 11 +-- .../datatype/EncodableFixedIntegerRange.java | 7 +- .../datatype/EncodableFlexibleBitfield.java | 7 +- .../EncodableOptimizedFibonacciRange.java | 7 +- .../EncodableOptimizedFixedRange.java | 7 +- .../{ManagedFixedList.java => FixedList.java} | 20 +++-- .../encoder/datatype/ManagedIntegerSet.java | 77 ------------------- .../iab/gpp/encoder/datatype/RangeEntry.java | 18 ++++- .../datatype/encoder/BaseIntegerSet.java | 56 -------------- .../encoder/datatype/encoder/Dirtyable.java | 6 ++ .../encoder/FibonacciIntegerRangeEncoder.java | 4 +- .../encoder/FixedIntegerRangeEncoder.java | 4 +- .../datatype/encoder/IntegerBitSet.java | 73 +++++++++++++++++- .../encoder/datatype/encoder/IntegerSet.java | 2 +- .../OptimizedFibonacciRangeEncoder.java | 3 +- .../encoder/OptimizedFixedRangeEncoder.java | 3 +- .../AbstractLazilyEncodableSegment.java | 4 +- 23 files changed, 171 insertions(+), 208 deletions(-) create mode 100644 iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/AbstractDirtyableBitStringDataType.java rename iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/{ManagedFixedList.java => FixedList.java} (59%) delete mode 100644 iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/ManagedIntegerSet.java delete mode 100644 iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/encoder/BaseIntegerSet.java create mode 100644 iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/encoder/Dirtyable.java diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/AbstractDirtyableBitStringDataType.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/AbstractDirtyableBitStringDataType.java new file mode 100644 index 00000000..cf2abaa6 --- /dev/null +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/AbstractDirtyableBitStringDataType.java @@ -0,0 +1,24 @@ +package com.iab.gpp.encoder.datatype; + +import com.iab.gpp.encoder.datatype.encoder.Dirtyable; + +// This class is used to handle collection types. +// It is important that we monitor the collections we return for changes. +public abstract class AbstractDirtyableBitStringDataType + extends AbstractEncodableBitStringDataType { + + protected AbstractDirtyableBitStringDataType(boolean hardFailIfMissing) { + super(hardFailIfMissing); + } + + @Override + public boolean isDirty() { + return super.isDirty() || value.isDirty(); + } + + @Override + public void setDirty(boolean dirty) { + super.setDirty(dirty); + value.setDirty(dirty); + } +} diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/AbstractEncodableBitStringDataType.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/AbstractEncodableBitStringDataType.java index 8cb8cdb6..48cf6922 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/AbstractEncodableBitStringDataType.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/AbstractEncodableBitStringDataType.java @@ -23,11 +23,11 @@ public AbstractEncodableBitStringDataType withValidator(Predicate validato return this; } - public boolean hasValue() { + public final boolean hasValue() { return this.value != null; } - public T getValue() { + public final T getValue() { return this.value; } @@ -48,7 +48,7 @@ public void setValue(Object value) { } - public boolean getHardFailIfMissing() { + public final boolean getHardFailIfMissing() { return this.hardFailIfMissing; } diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/DataType.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/DataType.java index 58d70730..be85c17b 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/DataType.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/DataType.java @@ -1,9 +1,9 @@ package com.iab.gpp.encoder.datatype; -public interface DataType { +import com.iab.gpp.encoder.datatype.encoder.Dirtyable; + +public interface DataType extends Dirtyable { boolean hasValue(); T getValue(); void setValue(Object value); - boolean isDirty(); - void setDirty(boolean dirty); } diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableArrayOfFixedIntegerRanges.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableArrayOfFixedIntegerRanges.java index bcc9ff98..ad805233 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableArrayOfFixedIntegerRanges.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableArrayOfFixedIntegerRanges.java @@ -1,7 +1,6 @@ package com.iab.gpp.encoder.datatype; import java.util.ArrayList; -import java.util.Collections; import java.util.List; import com.iab.gpp.encoder.bitstring.BitString; @@ -12,16 +11,18 @@ import com.iab.gpp.encoder.error.DecodingException; import com.iab.gpp.encoder.error.EncodingException; -public final class EncodableArrayOfFixedIntegerRanges extends AbstractEncodableBitStringDataType> { +public final class EncodableArrayOfFixedIntegerRanges extends AbstractDirtyableBitStringDataType> { private int keyBitStringLength; private int typeBitStringLength; + private static final FixedList EMPTY = new FixedList<>(List.of()); + public EncodableArrayOfFixedIntegerRanges(int keyBitStringLength, int typeBitStringLength, boolean hardFailIfMissing) { super(hardFailIfMissing); this.keyBitStringLength = keyBitStringLength; this.typeBitStringLength = typeBitStringLength; - this.value = Collections.emptyList(); + this.value = EMPTY; } @Override @@ -58,11 +59,13 @@ public void decode(BitString bitString) { IntegerSet ids = FixedIntegerRangeEncoder.decode(substring); index += substring.length(); - entries.add(new RangeEntry(key, type, ids)); + RangeEntry entry = new RangeEntry(key, type, ids); + entry.setDirty(false); + entries.add(entry); } - // NOTE: this requires that updates to structure be done using the setter - this.value = Collections.unmodifiableList(entries); + // NOTE: this requires that adding/removing ranges uses the setter + this.value = new FixedList<>(entries); } catch (Exception e) { throw new DecodingException(e); } @@ -98,4 +101,9 @@ public BitString substring(BitString bitString, int fromIndex) throws SubstringE } } + @SuppressWarnings("unchecked") + @Override + public void setValue(Object value) { + super.setValue(new FixedList<>((List) value)); + } } diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableFibonacciIntegerRange.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableFibonacciIntegerRange.java index 19963a55..2c8df3c7 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableFibonacciIntegerRange.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableFibonacciIntegerRange.java @@ -11,7 +11,7 @@ import com.iab.gpp.encoder.error.DecodingException; import com.iab.gpp.encoder.error.EncodingException; -public final class EncodableFibonacciIntegerRange extends AbstractEncodableBitStringDataType { +public final class EncodableFibonacciIntegerRange extends AbstractDirtyableBitStringDataType { public EncodableFibonacciIntegerRange() { super(true); @@ -57,9 +57,4 @@ public void setValue(Object value) { this.value.clear(); this.value.addAll((Collection) value); } - - @Override - public IntegerSet getValue() { - return new ManagedIntegerSet(this, super.getValue()); - } } diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableFixedBitfield.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableFixedBitfield.java index e7404069..48615032 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableFixedBitfield.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableFixedBitfield.java @@ -9,7 +9,7 @@ import com.iab.gpp.encoder.error.DecodingException; import com.iab.gpp.encoder.error.EncodingException; -public final class EncodableFixedBitfield extends AbstractEncodableBitStringDataType { +public final class EncodableFixedBitfield extends AbstractDirtyableBitStringDataType { private final int numElements; @@ -49,9 +49,4 @@ public void setValue(Object value) { this.value.clear(); this.value.addAll((Collection) value); } - - @Override - public IntegerSet getValue() { - return new ManagedIntegerSet(this, super.getValue()); - } } diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableFixedIntegerList.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableFixedIntegerList.java index 3a4db509..e38cd8b9 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableFixedIntegerList.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableFixedIntegerList.java @@ -9,7 +9,7 @@ import com.iab.gpp.encoder.error.DecodingException; import com.iab.gpp.encoder.error.EncodingException; -public final class EncodableFixedIntegerList extends AbstractEncodableBitStringDataType> { +public final class EncodableFixedIntegerList extends AbstractDirtyableBitStringDataType> { private int elementBitStringLength; private int numElements; @@ -37,7 +37,7 @@ public void encode(BitStringBuilder builder) { public void decode(BitString bitString) { try { - this.value = FixedIntegerListEncoder.decode(bitString, this.elementBitStringLength, this.numElements); + this.value = new FixedList<>(FixedIntegerListEncoder.decode(bitString, this.elementBitStringLength, this.numElements)); } catch (Exception e) { throw new DecodingException(e); } @@ -61,11 +61,6 @@ public void setValue(Object value) { if (v.size() > numElements) { v = v.subList(0, numElements); } - super.setValue(v); - } - - @Override - public List getValue() { - return new ManagedFixedList<>(this, super.getValue()); + super.setValue(new FixedList<>(v)); } } diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableFixedIntegerRange.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableFixedIntegerRange.java index 7bbbc4a6..56b94487 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableFixedIntegerRange.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableFixedIntegerRange.java @@ -10,7 +10,7 @@ import com.iab.gpp.encoder.error.DecodingException; import com.iab.gpp.encoder.error.EncodingException; -public final class EncodableFixedIntegerRange extends AbstractEncodableBitStringDataType { +public final class EncodableFixedIntegerRange extends AbstractDirtyableBitStringDataType { protected EncodableFixedIntegerRange() { super(true); @@ -56,9 +56,4 @@ public void setValue(Object value) { this.value.clear(); this.value.addAll((Collection) value); } - - @Override - public IntegerSet getValue() { - return new ManagedIntegerSet(this, super.getValue()); - } } diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableFlexibleBitfield.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableFlexibleBitfield.java index 46337183..04e8d8a5 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableFlexibleBitfield.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableFlexibleBitfield.java @@ -11,7 +11,7 @@ import com.iab.gpp.encoder.error.DecodingException; import com.iab.gpp.encoder.error.EncodingException; -public final class EncodableFlexibleBitfield extends AbstractEncodableBitStringDataType { +public final class EncodableFlexibleBitfield extends AbstractDirtyableBitStringDataType { private IntSupplier getLengthSupplier; @@ -51,9 +51,4 @@ public void setValue(Object value) { this.value.clear(); this.value.addAll((Collection) value); } - - @Override - public IntegerSet getValue() { - return new ManagedIntegerSet(this, super.getValue()); - } } diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableOptimizedFibonacciRange.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableOptimizedFibonacciRange.java index 1aba7d88..d966ad66 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableOptimizedFibonacciRange.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableOptimizedFibonacciRange.java @@ -10,7 +10,7 @@ import com.iab.gpp.encoder.error.DecodingException; import com.iab.gpp.encoder.error.EncodingException; -public final class EncodableOptimizedFibonacciRange extends AbstractEncodableBitStringDataType { +public final class EncodableOptimizedFibonacciRange extends AbstractDirtyableBitStringDataType { protected EncodableOptimizedFibonacciRange() { super(true); @@ -64,9 +64,4 @@ public void setValue(Object value) { this.value.clear(); this.value.addAll((Collection) value); } - - @Override - public IntegerSet getValue() { - return new ManagedIntegerSet(this, super.getValue()); - } } diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableOptimizedFixedRange.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableOptimizedFixedRange.java index a0669607..14b00485 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableOptimizedFixedRange.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableOptimizedFixedRange.java @@ -11,7 +11,7 @@ import com.iab.gpp.encoder.error.EncodingException; -public final class EncodableOptimizedFixedRange extends AbstractEncodableBitStringDataType { +public final class EncodableOptimizedFixedRange extends AbstractDirtyableBitStringDataType { public EncodableOptimizedFixedRange() { super(true); @@ -56,9 +56,4 @@ public void setValue(Object value) { this.value.clear(); this.value.addAll((Collection) value); } - - @Override - public IntegerSet getValue() { - return new ManagedIntegerSet(this, super.getValue()); - } } diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/ManagedFixedList.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/FixedList.java similarity index 59% rename from iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/ManagedFixedList.java rename to iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/FixedList.java index df38f67f..4a3955e6 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/ManagedFixedList.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/FixedList.java @@ -2,14 +2,14 @@ import java.util.AbstractList; import java.util.List; +import com.iab.gpp.encoder.datatype.encoder.Dirtyable; -final class ManagedFixedList extends AbstractList { +public final class FixedList extends AbstractList implements Dirtyable { - private final DataType parent; + private boolean dirty; private final List delegate; - ManagedFixedList(DataType parent, List delegate) { - this.parent = parent; + FixedList(List delegate) { this.delegate = delegate; } @@ -27,7 +27,7 @@ public T get(int index) { public T set(int index, T value) { T prior = delegate.set(index, value); if (prior != null) { - parent.setDirty(true); + dirty = true; } return prior; } @@ -36,4 +36,14 @@ public T set(int index, T value) { public String toString() { return delegate.toString(); } + + @Override + public boolean isDirty() { + return dirty; + } + + @Override + public void setDirty(boolean dirty) { + this.dirty = dirty; + } } diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/ManagedIntegerSet.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/ManagedIntegerSet.java deleted file mode 100644 index daccfdb9..00000000 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/ManagedIntegerSet.java +++ /dev/null @@ -1,77 +0,0 @@ -package com.iab.gpp.encoder.datatype; - -import java.util.PrimitiveIterator; -import java.util.stream.IntStream; -import java.util.stream.Stream; -import com.iab.gpp.encoder.datatype.encoder.BaseIntegerSet; -import com.iab.gpp.encoder.datatype.encoder.IntegerSet; - -final class ManagedIntegerSet extends BaseIntegerSet { - - private final DataType parent; - private final IntegerSet delegate; - - ManagedIntegerSet(DataType parent, IntegerSet delegate) { - this.parent = parent; - this.delegate = delegate; - } - - @Override - public void clear() { - delegate.clear(); - parent.setDirty(true); - } - - @Override - public boolean isEmpty() { - return delegate.isEmpty(); - } - - @Override - public int size() { - return delegate.size(); - } - - @Override - public PrimitiveIterator.OfInt iterator() { - return delegate.iterator(); - } - - @Override - public Stream stream(){ - return delegate.stream(); - } - - @Override - public IntStream intStream() { - return delegate.intStream(); - } - - @Override - public boolean containsInt(int value) { - return delegate.containsInt(value); - } - - @Override - public boolean addInt(int value) { - boolean modified = delegate.addInt(value); - if (modified) { - parent.setDirty(true); - } - return modified; - } - - @Override - public boolean removeInt(int value) { - boolean modified = delegate.removeInt(value); - if (modified) { - parent.setDirty(true); - } - return modified; - } - - @Override - public String toString() { - return delegate.toString(); - } -} diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/RangeEntry.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/RangeEntry.java index 5ea4bd7f..ed997b16 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/RangeEntry.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/RangeEntry.java @@ -2,11 +2,13 @@ import java.util.Collection; import java.util.Set; +import com.iab.gpp.encoder.datatype.encoder.Dirtyable; import com.iab.gpp.encoder.datatype.encoder.IntegerBitSet; import com.iab.gpp.encoder.datatype.encoder.IntegerSet; -public class RangeEntry { +public class RangeEntry implements Dirtyable { + private boolean dirty; private int key; private int type; private final IntegerSet ids; @@ -24,6 +26,7 @@ public int getKey() { } public void setKey(int key) { + this.dirty = true; this.key = key; } @@ -32,6 +35,7 @@ public int getType() { } public void setType(int type) { + this.dirty = true; this.type = type; } @@ -40,8 +44,20 @@ public IntegerSet getIds() { } public void setIds(Collection ids) { + this.dirty = true; this.ids.clear(); this.ids.addAll(ids); } + @Override + public boolean isDirty() { + return dirty || ids.isDirty(); + } + + @Override + public void setDirty(boolean dirty) { + this.dirty = dirty; + ids.setDirty(dirty); + } + } diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/encoder/BaseIntegerSet.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/encoder/BaseIntegerSet.java deleted file mode 100644 index bb872855..00000000 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/encoder/BaseIntegerSet.java +++ /dev/null @@ -1,56 +0,0 @@ -package com.iab.gpp.encoder.datatype.encoder; - -import java.util.AbstractSet; -import java.util.Collection; - -public abstract class BaseIntegerSet extends AbstractSet implements IntegerSet { - - @Override - public final boolean contains(Object value) { - if (value instanceof Integer) { - return containsInt((Integer) value); - } - return false; - } - - @Override - public final boolean add(Integer value) { - if (value == null) { - return false; - } - return addInt(value); - } - - @Override - public final boolean remove(Object value) { - if (value instanceof Integer) { - return removeInt((Integer) value); - } - return false; - } - - @Override - public boolean removeAll(Collection c) { - boolean modified = false; - for (Integer i : this) { - if (c.contains(i)) { - remove(i); - modified = true; - } - } - return modified; - } - - @Override - public boolean retainAll(Collection c) { - boolean modified = false; - for (Integer i : this) { - if (!c.contains(i)) { - remove(i); - modified = true; - } - } - return modified; - } - -} diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/encoder/Dirtyable.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/encoder/Dirtyable.java new file mode 100644 index 00000000..2353de1d --- /dev/null +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/encoder/Dirtyable.java @@ -0,0 +1,6 @@ +package com.iab.gpp.encoder.datatype.encoder; + +public interface Dirtyable { + boolean isDirty(); + void setDirty(boolean dirty); +} diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/encoder/FibonacciIntegerRangeEncoder.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/encoder/FibonacciIntegerRangeEncoder.java index 67958875..baac388a 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/encoder/FibonacciIntegerRangeEncoder.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/encoder/FibonacciIntegerRangeEncoder.java @@ -47,7 +47,7 @@ private static void writeGroup(BitStringBuilder builder, int groupStart, int las } } - public static IntegerSet decode(BitString bitString) throws DecodingException { + public static IntegerBitSet decode(BitString bitString) throws DecodingException { if (bitString.length() < 12) { throw new DecodingException("Undecodable FibonacciIntegerRange '" + bitString + "'"); } @@ -81,7 +81,7 @@ public static IntegerSet decode(BitString bitString) throws DecodingException { startIndex = index + 2; } } - + value.setDirty(false); return value; } } diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/encoder/FixedIntegerRangeEncoder.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/encoder/FixedIntegerRangeEncoder.java index a92e2b09..48ef1429 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/encoder/FixedIntegerRangeEncoder.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/encoder/FixedIntegerRangeEncoder.java @@ -43,7 +43,7 @@ private static void writeGroup(BitStringBuilder builder, int groupStart, int las } } - public static IntegerSet decode(BitString bitString) throws DecodingException { + public static IntegerBitSet decode(BitString bitString) throws DecodingException { if (bitString.length() < 12) { throw new DecodingException("Undecodable FixedIntegerRange '" + bitString + "'"); } @@ -69,7 +69,7 @@ public static IntegerSet decode(BitString bitString) throws DecodingException { startIndex += 16; } } - + value.setDirty(false); return value; } } diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/encoder/IntegerBitSet.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/encoder/IntegerBitSet.java index 7ff3483d..663b28f8 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/encoder/IntegerBitSet.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/encoder/IntegerBitSet.java @@ -1,6 +1,8 @@ package com.iab.gpp.encoder.datatype.encoder; +import java.util.AbstractSet; import java.util.BitSet; +import java.util.Collection; import java.util.NoSuchElementException; import java.util.Spliterator; import java.util.Spliterators; @@ -9,14 +11,15 @@ import java.util.stream.IntStream; import java.util.stream.StreamSupport; -public final class IntegerBitSet extends BaseIntegerSet { +public final class IntegerBitSet extends AbstractSet implements IntegerSet { private static final Logger LOGGER = Logger.getLogger(IntegerBitSet.class.getName()); static final int MAX_COLLECTION_SIZE = 8192; - protected final BitSet bitSet; - protected final int from; - protected final int to; + private boolean dirty; + private final BitSet bitSet; + private final int from; + private final int to; private final int adjustment; public IntegerBitSet(BitSet bitSet, int from, int to, int adjustment) { @@ -55,6 +58,7 @@ private int getOffset(int value) { @Override public void clear() { + dirty = true; bitSet.clear(from, to); } @@ -126,6 +130,7 @@ public void addRange(int start, int end) { logOutOfRange(end); realEnd = to; } + dirty = true; bitSet.set(realStart, realEnd); } @@ -140,6 +145,7 @@ public boolean addInt(int value) { return false; } bitSet.set(offset, true); + dirty = true; return true; } @@ -154,6 +160,65 @@ public boolean removeInt(int value) { return false; } bitSet.set(offset, false); + dirty = true; return true; } + + @Override + public final boolean contains(Object value) { + if (value instanceof Integer) { + return containsInt((Integer) value); + } + return false; + } + + @Override + public final boolean add(Integer value) { + if (value == null) { + return false; + } + return addInt(value); + } + + @Override + public final boolean remove(Object value) { + if (value instanceof Integer) { + return removeInt((Integer) value); + } + return false; + } + + @Override + public boolean removeAll(Collection c) { + boolean modified = false; + for (Integer i : this) { + if (c.contains(i)) { + remove(i); + modified = true; + } + } + return modified; + } + + @Override + public boolean retainAll(Collection c) { + boolean modified = false; + for (Integer i : this) { + if (!c.contains(i)) { + remove(i); + modified = true; + } + } + return modified; + } + + @Override + public boolean isDirty() { + return dirty; + } + + @Override + public void setDirty(boolean dirty) { + this.dirty = dirty; + } } diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/encoder/IntegerSet.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/encoder/IntegerSet.java index bc9aa3f7..5f27795e 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/encoder/IntegerSet.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/encoder/IntegerSet.java @@ -5,7 +5,7 @@ import java.util.Set; import java.util.stream.IntStream; -public interface IntegerSet extends Set { +public interface IntegerSet extends Set, Dirtyable { boolean containsInt(int value); default boolean containsAny(Collection c) { diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/encoder/OptimizedFibonacciRangeEncoder.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/encoder/OptimizedFibonacciRangeEncoder.java index 66160efd..195bb0dc 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/encoder/OptimizedFibonacciRangeEncoder.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/encoder/OptimizedFibonacciRangeEncoder.java @@ -28,7 +28,7 @@ public static void encode(BitStringBuilder builder, IntegerSet value) throws Enc } } - public static IntegerSet decode(BitString bitString) throws DecodingException { + public static IntegerBitSet decode(BitString bitString) throws DecodingException { if (bitString.length() < 12) { throw new DecodingException("Undecodable FibonacciIntegerRange '" + bitString + "'"); } @@ -44,6 +44,7 @@ public static IntegerSet decode(BitString bitString) throws DecodingException { value.addInt(i + 1); } } + value.setDirty(false); return value; } } diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/encoder/OptimizedFixedRangeEncoder.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/encoder/OptimizedFixedRangeEncoder.java index 5a5660f8..2721e94a 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/encoder/OptimizedFixedRangeEncoder.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/encoder/OptimizedFixedRangeEncoder.java @@ -27,7 +27,7 @@ public static void encode(BitStringBuilder builder, IntegerSet value) throws Enc } } - public static IntegerSet decode(BitString bitString) throws DecodingException { + public static IntegerBitSet decode(BitString bitString) throws DecodingException { if (bitString.length() < 12) { throw new DecodingException("Undecodable FixedIntegerRange '" + bitString + "'"); } @@ -43,6 +43,7 @@ public static IntegerSet decode(BitString bitString) throws DecodingException { value.addInt(i + 1); } } + value.setDirty(false); return value; } } diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/AbstractLazilyEncodableSegment.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/AbstractLazilyEncodableSegment.java index 9e07c18e..b054ba04 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/AbstractLazilyEncodableSegment.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/AbstractLazilyEncodableSegment.java @@ -1,8 +1,8 @@ package com.iab.gpp.encoder.segment; -import java.util.List; import java.util.function.Predicate; import com.iab.gpp.encoder.datatype.DataType; +import com.iab.gpp.encoder.datatype.FixedList; import com.iab.gpp.encoder.error.InvalidFieldException; import com.iab.gpp.encoder.field.Fields; @@ -10,7 +10,7 @@ public abstract class AbstractLazilyEncodableSegment> implem protected static final Predicate nullableBooleanAsTwoBitIntegerValidator = (n -> n >= 0 && n <= 2); protected static final Predicate nonNullableBooleanAsTwoBitIntegerValidator = (n -> n >= 1 && n <= 2); - protected static final Predicate> nullableBooleanAsTwoBitIntegerListValidator = (l -> { + protected static final Predicate> nullableBooleanAsTwoBitIntegerListValidator = (l -> { for (int n : l) { if (n < 0 || n > 2) { return false; From cd9a8761c961ce1397daf4dc6b8e4034959c5dbd Mon Sep 17 00:00:00 2001 From: James Yuzawa Date: Mon, 12 Jan 2026 15:33:46 -0500 Subject: [PATCH 03/11] use arrays --- .../EncodableArrayOfFixedIntegerRanges.java | 8 ++++---- .../datatype/EncodableFixedIntegerList.java | 18 ++++++++++-------- .../encoder/FixedIntegerListEncoder.java | 13 +++++++------ 3 files changed, 21 insertions(+), 18 deletions(-) diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableArrayOfFixedIntegerRanges.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableArrayOfFixedIntegerRanges.java index ad805233..78069946 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableArrayOfFixedIntegerRanges.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableArrayOfFixedIntegerRanges.java @@ -1,6 +1,6 @@ package com.iab.gpp.encoder.datatype; -import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import com.iab.gpp.encoder.bitstring.BitString; @@ -46,7 +46,7 @@ public void encode(BitStringBuilder sb) { public void decode(BitString bitString) { try { int size = FixedIntegerEncoder.decode(bitString, 0, 12); - List entries = new ArrayList<>(size); + RangeEntry[] entries = new RangeEntry[size]; int index = 12; for (int i = 0; i < size; i++) { int key = FixedIntegerEncoder.decode(bitString, index, keyBitStringLength); @@ -61,11 +61,11 @@ public void decode(BitString bitString) { RangeEntry entry = new RangeEntry(key, type, ids); entry.setDirty(false); - entries.add(entry); + entries[i] = entry; } // NOTE: this requires that adding/removing ranges uses the setter - this.value = new FixedList<>(entries); + this.value = new FixedList<>(Arrays.asList(entries)); } catch (Exception e) { throw new DecodingException(e); } diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableFixedIntegerList.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableFixedIntegerList.java index e38cd8b9..d9f10208 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableFixedIntegerList.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableFixedIntegerList.java @@ -1,6 +1,6 @@ package com.iab.gpp.encoder.datatype; -import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import com.iab.gpp.encoder.bitstring.BitString; @@ -54,13 +54,15 @@ public BitString substring(BitString bitString, int fromIndex) throws SubstringE @SuppressWarnings("unchecked") @Override public void setValue(Object value) { - List v = new ArrayList<>((List) value); - for (int i = v.size(); i < numElements; i++) { - v.add(0); + List list = (List) value; + int size = list.size(); + if (size != numElements) { + Integer[] newList = new Integer[numElements]; + for (int i = 0; i < numElements; i++) { + newList[i] = i < size ? list.get(i) : 0; + } + list = Arrays.asList(newList); } - if (v.size() > numElements) { - v = v.subList(0, numElements); - } - super.setValue(new FixedList<>(v)); + super.setValue(new FixedList<>(list)); } } diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/encoder/FixedIntegerListEncoder.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/encoder/FixedIntegerListEncoder.java index 7140af9c..b7b7acdd 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/encoder/FixedIntegerListEncoder.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/encoder/FixedIntegerListEncoder.java @@ -1,6 +1,6 @@ package com.iab.gpp.encoder.datatype.encoder; -import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import com.iab.gpp.encoder.bitstring.BitString; @@ -41,16 +41,17 @@ public static List decode(BitString bitString, int elementBitStringLeng bitString = bitString.expandTo(elementBitStringLength * numElements); - List value = new ArrayList<>(numElements); + Integer[] value = new Integer[numElements]; length = bitString.length(); + int idx = 0; for (int i = 0; i < length; i += elementBitStringLength) { - value.add(IntegerCache.valueOf(FixedIntegerEncoder.decode(bitString, i, elementBitStringLength))); + value[idx++] = IntegerCache.valueOf(FixedIntegerEncoder.decode(bitString, i, elementBitStringLength)); } - while (value.size() < numElements) { - value.add(0); + while (idx < numElements) { + value[idx++] = 0; } - return value; + return Arrays.asList(value); } } From bf62f5fb21e1164ad2bb1604ebea52f1daffa7a4 Mon Sep 17 00:00:00 2001 From: James Yuzawa Date: Mon, 12 Jan 2026 15:42:24 -0500 Subject: [PATCH 04/11] clean up dirty flow again --- .../EncodableArrayOfFixedIntegerRanges.java | 1 - .../com/iab/gpp/encoder/datatype/FixedList.java | 14 ++++++++++++++ .../encoder/FibonacciIntegerRangeEncoder.java | 1 - .../datatype/encoder/FixedIntegerRangeEncoder.java | 1 - .../encoder/OptimizedFibonacciRangeEncoder.java | 1 - .../encoder/OptimizedFixedRangeEncoder.java | 1 - 6 files changed, 14 insertions(+), 5 deletions(-) diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableArrayOfFixedIntegerRanges.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableArrayOfFixedIntegerRanges.java index 78069946..b1035592 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableArrayOfFixedIntegerRanges.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableArrayOfFixedIntegerRanges.java @@ -60,7 +60,6 @@ public void decode(BitString bitString) { index += substring.length(); RangeEntry entry = new RangeEntry(key, type, ids); - entry.setDirty(false); entries[i] = entry; } diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/FixedList.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/FixedList.java index 4a3955e6..4e2d8b04 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/FixedList.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/FixedList.java @@ -39,11 +39,25 @@ public String toString() { @Override public boolean isDirty() { + int size = delegate.size(); + for (int i = 0; i < size; i++) { + T value = delegate.get(i); + if (value instanceof Dirtyable && ((Dirtyable) value).isDirty()) { + return true; + } + } return dirty; } @Override public void setDirty(boolean dirty) { + int size = delegate.size(); + for (int i = 0; i < size; i++) { + T value = delegate.get(i); + if (value instanceof Dirtyable) { + ((Dirtyable) value).setDirty(dirty); + } + } this.dirty = dirty; } } diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/encoder/FibonacciIntegerRangeEncoder.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/encoder/FibonacciIntegerRangeEncoder.java index baac388a..46b409bc 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/encoder/FibonacciIntegerRangeEncoder.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/encoder/FibonacciIntegerRangeEncoder.java @@ -81,7 +81,6 @@ public static IntegerBitSet decode(BitString bitString) throws DecodingException startIndex = index + 2; } } - value.setDirty(false); return value; } } diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/encoder/FixedIntegerRangeEncoder.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/encoder/FixedIntegerRangeEncoder.java index 48ef1429..6160fa12 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/encoder/FixedIntegerRangeEncoder.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/encoder/FixedIntegerRangeEncoder.java @@ -69,7 +69,6 @@ public static IntegerBitSet decode(BitString bitString) throws DecodingException startIndex += 16; } } - value.setDirty(false); return value; } } diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/encoder/OptimizedFibonacciRangeEncoder.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/encoder/OptimizedFibonacciRangeEncoder.java index 195bb0dc..9240bee7 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/encoder/OptimizedFibonacciRangeEncoder.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/encoder/OptimizedFibonacciRangeEncoder.java @@ -44,7 +44,6 @@ public static IntegerBitSet decode(BitString bitString) throws DecodingException value.addInt(i + 1); } } - value.setDirty(false); return value; } } diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/encoder/OptimizedFixedRangeEncoder.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/encoder/OptimizedFixedRangeEncoder.java index 2721e94a..3126c60d 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/encoder/OptimizedFixedRangeEncoder.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/encoder/OptimizedFixedRangeEncoder.java @@ -43,7 +43,6 @@ public static IntegerBitSet decode(BitString bitString) throws DecodingException value.addInt(i + 1); } } - value.setDirty(false); return value; } } From 56b930e4fd3f2c9b70588b8beb6dd6daf50ca341 Mon Sep 17 00:00:00 2001 From: James Yuzawa Date: Mon, 12 Jan 2026 16:55:25 -0500 Subject: [PATCH 05/11] FixedIntegerList --- .../datatype/EncodableFixedIntegerList.java | 26 +++----- .../encoder/datatype/FixedIntegerList.java | 59 +++++++++++++++++++ .../iab/gpp/encoder/datatype/FixedList.java | 4 +- .../encoder/FixedIntegerListEncoder.java | 17 +++--- .../com/iab/gpp/encoder/section/UsCa.java | 11 ++-- .../com/iab/gpp/encoder/section/UsCo.java | 6 +- .../com/iab/gpp/encoder/section/UsCt.java | 11 ++-- .../com/iab/gpp/encoder/section/UsDe.java | 11 ++-- .../com/iab/gpp/encoder/section/UsFl.java | 11 ++-- .../com/iab/gpp/encoder/section/UsIa.java | 6 +- .../com/iab/gpp/encoder/section/UsMt.java | 11 ++-- .../com/iab/gpp/encoder/section/UsNat.java | 11 ++-- .../com/iab/gpp/encoder/section/UsNe.java | 6 +- .../com/iab/gpp/encoder/section/UsNh.java | 11 ++-- .../com/iab/gpp/encoder/section/UsNj.java | 11 ++-- .../com/iab/gpp/encoder/section/UsOr.java | 11 ++-- .../com/iab/gpp/encoder/section/UsTn.java | 6 +- .../com/iab/gpp/encoder/section/UsTx.java | 6 +- .../com/iab/gpp/encoder/section/UsUt.java | 6 +- .../com/iab/gpp/encoder/section/UsVa.java | 6 +- .../AbstractLazilyEncodableSegment.java | 4 +- .../gpp/encoder/segment/UsCaCoreSegment.java | 5 +- .../gpp/encoder/segment/UsCoCoreSegment.java | 3 +- .../gpp/encoder/segment/UsCtCoreSegment.java | 5 +- .../gpp/encoder/segment/UsDeCoreSegment.java | 5 +- .../gpp/encoder/segment/UsFlCoreSegment.java | 5 +- .../gpp/encoder/segment/UsIaCoreSegment.java | 3 +- .../gpp/encoder/segment/UsMtCoreSegment.java | 5 +- .../gpp/encoder/segment/UsNatCoreSegment.java | 5 +- .../gpp/encoder/segment/UsNeCoreSegment.java | 3 +- .../gpp/encoder/segment/UsNhCoreSegment.java | 5 +- .../gpp/encoder/segment/UsNjCoreSegment.java | 5 +- .../gpp/encoder/segment/UsOrCoreSegment.java | 5 +- .../gpp/encoder/segment/UsTnCoreSegment.java | 3 +- .../gpp/encoder/segment/UsTxCoreSegment.java | 3 +- .../gpp/encoder/segment/UsUtCoreSegment.java | 3 +- .../gpp/encoder/segment/UsVaCoreSegment.java | 3 +- 37 files changed, 171 insertions(+), 146 deletions(-) create mode 100644 iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/FixedIntegerList.java diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableFixedIntegerList.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableFixedIntegerList.java index d9f10208..c15ad1d6 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableFixedIntegerList.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableFixedIntegerList.java @@ -1,6 +1,5 @@ package com.iab.gpp.encoder.datatype; -import java.util.Arrays; import java.util.List; import com.iab.gpp.encoder.bitstring.BitString; @@ -9,22 +8,16 @@ import com.iab.gpp.encoder.error.DecodingException; import com.iab.gpp.encoder.error.EncodingException; -public final class EncodableFixedIntegerList extends AbstractDirtyableBitStringDataType> { +public final class EncodableFixedIntegerList extends AbstractDirtyableBitStringDataType { private int elementBitStringLength; private int numElements; - protected EncodableFixedIntegerList(int elementBitStringLength, int numElements) { + public EncodableFixedIntegerList(int elementBitStringLength, int numElements) { super(true); this.elementBitStringLength = elementBitStringLength; this.numElements = numElements; - } - - public EncodableFixedIntegerList(int elementBitStringLength, List value) { - super(true); - this.elementBitStringLength = elementBitStringLength; - this.numElements = value.size(); - setValue(value); + super.setValue(new FixedIntegerList(numElements)); } public void encode(BitStringBuilder builder) { @@ -37,7 +30,7 @@ public void encode(BitStringBuilder builder) { public void decode(BitString bitString) { try { - this.value = new FixedList<>(FixedIntegerListEncoder.decode(bitString, this.elementBitStringLength, this.numElements)); + FixedIntegerListEncoder.decode(this.value, bitString, this.elementBitStringLength, this.numElements); } catch (Exception e) { throw new DecodingException(e); } @@ -56,13 +49,10 @@ public BitString substring(BitString bitString, int fromIndex) throws SubstringE public void setValue(Object value) { List list = (List) value; int size = list.size(); - if (size != numElements) { - Integer[] newList = new Integer[numElements]; - for (int i = 0; i < numElements; i++) { - newList[i] = i < size ? list.get(i) : 0; - } - list = Arrays.asList(newList); + for (int i = 0; i < numElements; i++) { + this.value.set(i, i < size ? list.get(i) : 0); } - super.setValue(new FixedList<>(list)); + // call validator + super.setValue(this.value); } } diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/FixedIntegerList.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/FixedIntegerList.java new file mode 100644 index 00000000..3d04802b --- /dev/null +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/FixedIntegerList.java @@ -0,0 +1,59 @@ +package com.iab.gpp.encoder.datatype; + +import java.util.AbstractList; +import java.util.Arrays; +import com.iab.gpp.encoder.datatype.encoder.Dirtyable; + +public final class FixedIntegerList extends AbstractList implements Dirtyable { + + private boolean dirty; + private final byte[] array; + + public FixedIntegerList(int size) { + this.array = new byte[size]; + } + + @Override + public int size() { + return array.length; + } + + @Override + public Integer get(int index) { + return getInt(index); + } + + public int getInt(int index) { + return array[index]; + } + + @Override + public Integer set(int index, Integer value) { + return setInt(index, value); + } + + public int setInt(int index, int value) { + if(value < 0 || value > 0xff) { + throw new IllegalArgumentException("FixedIntegerList only supports positive integers less than 256."); + } + int prior = array[index]; + array[index] = (byte) value; + dirty = true; + return prior; + } + + @Override + public String toString() { + return Arrays.toString(array); + } + + @Override + public boolean isDirty() { + return dirty; + } + + @Override + public void setDirty(boolean dirty) { + this.dirty = dirty; + } +} diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/FixedList.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/FixedList.java index 4e2d8b04..962feb0e 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/FixedList.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/FixedList.java @@ -26,9 +26,7 @@ public T get(int index) { @Override public T set(int index, T value) { T prior = delegate.set(index, value); - if (prior != null) { - dirty = true; - } + dirty = true; return prior; } diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/encoder/FixedIntegerListEncoder.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/encoder/FixedIntegerListEncoder.java index b7b7acdd..e4ed367f 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/encoder/FixedIntegerListEncoder.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/encoder/FixedIntegerListEncoder.java @@ -1,10 +1,10 @@ package com.iab.gpp.encoder.datatype.encoder; -import java.util.Arrays; import java.util.List; import com.iab.gpp.encoder.bitstring.BitString; import com.iab.gpp.encoder.bitstring.BitStringBuilder; +import com.iab.gpp.encoder.datatype.FixedIntegerList; import com.iab.gpp.encoder.error.DecodingException; import com.iab.gpp.encoder.error.EncodingException; @@ -28,7 +28,13 @@ public static void encode(BitStringBuilder builder, List value, int ele } } - public static List decode(BitString bitString, int elementBitStringLength, int numElements) + public static FixedIntegerList decode(BitString bitString, int elementBitStringLength, int numElements) { + FixedIntegerList out = new FixedIntegerList(numElements); + decode(out, bitString, elementBitStringLength, numElements); + return out; + } + + public static void decode(FixedIntegerList out, BitString bitString, int elementBitStringLength, int numElements) throws DecodingException { int length = bitString.length(); if (length > elementBitStringLength * numElements) { @@ -41,17 +47,14 @@ public static List decode(BitString bitString, int elementBitStringLeng bitString = bitString.expandTo(elementBitStringLength * numElements); - Integer[] value = new Integer[numElements]; length = bitString.length(); int idx = 0; for (int i = 0; i < length; i += elementBitStringLength) { - value[idx++] = IntegerCache.valueOf(FixedIntegerEncoder.decode(bitString, i, elementBitStringLength)); + out.set(idx++, IntegerCache.valueOf(FixedIntegerEncoder.decode(bitString, i, elementBitStringLength))); } while (idx < numElements) { - value[idx++] = 0; + out.set(idx++, 0); } - - return Arrays.asList(value); } } diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsCa.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsCa.java index 3ab9bbd2..d737de1d 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsCa.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsCa.java @@ -3,6 +3,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import com.iab.gpp.encoder.datatype.FixedIntegerList; import com.iab.gpp.encoder.field.UsCaField; import com.iab.gpp.encoder.segment.EncodableSegment; import com.iab.gpp.encoder.segment.UsCaCoreSegment; @@ -98,14 +99,12 @@ public Integer getSharingOptOut() { return (Integer) this.getFieldValue(UsCaField.SHARING_OPT_OUT); } - @SuppressWarnings("unchecked") - public List getSensitiveDataProcessing() { - return (List) this.getFieldValue(UsCaField.SENSITIVE_DATA_PROCESSING); + public FixedIntegerList getSensitiveDataProcessing() { + return (FixedIntegerList) this.getFieldValue(UsCaField.SENSITIVE_DATA_PROCESSING); } - @SuppressWarnings("unchecked") - public List getKnownChildSensitiveDataConsents() { - return (List) this.getFieldValue(UsCaField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS); + public FixedIntegerList getKnownChildSensitiveDataConsents() { + return (FixedIntegerList) this.getFieldValue(UsCaField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS); } public Integer getPersonalDataConsents() { diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsCo.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsCo.java index 083031a8..31a40d9d 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsCo.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsCo.java @@ -3,6 +3,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import com.iab.gpp.encoder.datatype.FixedIntegerList; import com.iab.gpp.encoder.field.UsCoField; import com.iab.gpp.encoder.segment.EncodableSegment; import com.iab.gpp.encoder.segment.UsCoCoreSegment; @@ -98,9 +99,8 @@ public Integer getTargetedAdvertisingOptOut() { return (Integer) this.getFieldValue(UsCoField.TARGETED_ADVERTISING_OPT_OUT); } - @SuppressWarnings("unchecked") - public List getSensitiveDataProcessing() { - return (List) this.getFieldValue(UsCoField.SENSITIVE_DATA_PROCESSING); + public FixedIntegerList getSensitiveDataProcessing() { + return (FixedIntegerList) this.getFieldValue(UsCoField.SENSITIVE_DATA_PROCESSING); } public Integer getKnownChildSensitiveDataConsents() { diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsCt.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsCt.java index 9d49656f..3bc3c5b6 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsCt.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsCt.java @@ -3,6 +3,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import com.iab.gpp.encoder.datatype.FixedIntegerList; import com.iab.gpp.encoder.field.UsCtField; import com.iab.gpp.encoder.segment.EncodableSegment; import com.iab.gpp.encoder.segment.UsCtCoreSegment; @@ -98,14 +99,12 @@ public Integer getTargetedAdvertisingOptOut() { return (Integer) this.getFieldValue(UsCtField.TARGETED_ADVERTISING_OPT_OUT); } - @SuppressWarnings("unchecked") - public List getSensitiveDataProcessing() { - return (List) this.getFieldValue(UsCtField.SENSITIVE_DATA_PROCESSING); + public FixedIntegerList getSensitiveDataProcessing() { + return (FixedIntegerList) this.getFieldValue(UsCtField.SENSITIVE_DATA_PROCESSING); } - @SuppressWarnings("unchecked") - public List getKnownChildSensitiveDataConsents() { - return (List) this.getFieldValue(UsCtField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS); + public FixedIntegerList getKnownChildSensitiveDataConsents() { + return (FixedIntegerList) this.getFieldValue(UsCtField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS); } public Integer getMspaCoveredTransaction() { diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsDe.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsDe.java index 52664417..cd3b11c5 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsDe.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsDe.java @@ -3,6 +3,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import com.iab.gpp.encoder.datatype.FixedIntegerList; import com.iab.gpp.encoder.field.UsDeField; import com.iab.gpp.encoder.segment.EncodableSegment; import com.iab.gpp.encoder.segment.UsDeCoreSegment; @@ -98,14 +99,12 @@ public Integer getTargetedAdvertisingOptOut() { return (Integer) this.getFieldValue(UsDeField.TARGETED_ADVERTISING_OPT_OUT); } - @SuppressWarnings("unchecked") - public List getSensitiveDataProcessing() { - return (List) this.getFieldValue(UsDeField.SENSITIVE_DATA_PROCESSING); + public FixedIntegerList getSensitiveDataProcessing() { + return (FixedIntegerList) this.getFieldValue(UsDeField.SENSITIVE_DATA_PROCESSING); } - @SuppressWarnings("unchecked") - public List getKnownChildSensitiveDataConsents() { - return (List) this.getFieldValue(UsDeField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS); + public FixedIntegerList getKnownChildSensitiveDataConsents() { + return (FixedIntegerList) this.getFieldValue(UsDeField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS); } public Integer getAdditionalDataProcessingConsent() { diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsFl.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsFl.java index 6e6fd6b5..3c8888e1 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsFl.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsFl.java @@ -3,6 +3,7 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; +import com.iab.gpp.encoder.datatype.FixedIntegerList; import com.iab.gpp.encoder.field.UsFlField; import com.iab.gpp.encoder.segment.EncodableSegment; import com.iab.gpp.encoder.segment.UsFlCoreSegment; @@ -87,14 +88,12 @@ public Integer getTargetedAdvertisingOptOut() { return (Integer) this.getFieldValue(UsFlField.TARGETED_ADVERTISING_OPT_OUT); } - @SuppressWarnings("unchecked") - public List getSensitiveDataProcessing() { - return (List) this.getFieldValue(UsFlField.SENSITIVE_DATA_PROCESSING); + public FixedIntegerList getSensitiveDataProcessing() { + return (FixedIntegerList) this.getFieldValue(UsFlField.SENSITIVE_DATA_PROCESSING); } - @SuppressWarnings("unchecked") - public List getKnownChildSensitiveDataConsents() { - return (List) this.getFieldValue(UsFlField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS); + public FixedIntegerList getKnownChildSensitiveDataConsents() { + return (FixedIntegerList) this.getFieldValue(UsFlField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS); } public Integer getAdditionalDataProcessingConsent() { diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsIa.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsIa.java index 37e5cb53..b7ffc38e 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsIa.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsIa.java @@ -3,6 +3,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import com.iab.gpp.encoder.datatype.FixedIntegerList; import com.iab.gpp.encoder.field.UsIaField; import com.iab.gpp.encoder.segment.EncodableSegment; import com.iab.gpp.encoder.segment.UsIaCoreSegment; @@ -102,9 +103,8 @@ public Integer getTargetedAdvertisingOptOut() { return (Integer) this.getFieldValue(UsIaField.TARGETED_ADVERTISING_OPT_OUT); } - @SuppressWarnings("unchecked") - public List getSensitiveDataProcessing() { - return (List) this.getFieldValue(UsIaField.SENSITIVE_DATA_PROCESSING); + public FixedIntegerList getSensitiveDataProcessing() { + return (FixedIntegerList) this.getFieldValue(UsIaField.SENSITIVE_DATA_PROCESSING); } public Integer getKnownChildSensitiveDataConsents() { diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsMt.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsMt.java index 03dea7c1..a4e57d2f 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsMt.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsMt.java @@ -3,6 +3,7 @@ import java.util.Arrays; import java.util.ArrayList; import java.util.List; +import com.iab.gpp.encoder.datatype.FixedIntegerList; import com.iab.gpp.encoder.field.UsMtField; import com.iab.gpp.encoder.segment.EncodableSegment; import com.iab.gpp.encoder.segment.UsMtCoreSegment; @@ -98,14 +99,12 @@ public Integer getTargetedAdvertisingOptOut() { return (Integer) this.getFieldValue(UsMtField.TARGETED_ADVERTISING_OPT_OUT); } - @SuppressWarnings("unchecked") - public List getSensitiveDataProcessing() { - return (List) this.getFieldValue(UsMtField.SENSITIVE_DATA_PROCESSING); + public FixedIntegerList getSensitiveDataProcessing() { + return (FixedIntegerList) this.getFieldValue(UsMtField.SENSITIVE_DATA_PROCESSING); } - @SuppressWarnings("unchecked") - public List getKnownChildSensitiveDataConsents() { - return (List) this.getFieldValue(UsMtField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS); + public FixedIntegerList getKnownChildSensitiveDataConsents() { + return (FixedIntegerList) this.getFieldValue(UsMtField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS); } public Integer getAdditionalDataProcessingConsent() { diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsNat.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsNat.java index 809f2569..64b6c8f0 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsNat.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsNat.java @@ -3,6 +3,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import com.iab.gpp.encoder.datatype.FixedIntegerList; import com.iab.gpp.encoder.field.UsNatField; import com.iab.gpp.encoder.segment.EncodableSegment; import com.iab.gpp.encoder.segment.UsNatCoreSegment; @@ -114,14 +115,12 @@ public Integer getTargetedAdvertisingOptOut() { return (Integer) this.getFieldValue(UsNatField.TARGETED_ADVERTISING_OPT_OUT); } - @SuppressWarnings("unchecked") - public List getSensitiveDataProcessing() { - return (List) this.getFieldValue(UsNatField.SENSITIVE_DATA_PROCESSING); + public FixedIntegerList getSensitiveDataProcessing() { + return (FixedIntegerList) this.getFieldValue(UsNatField.SENSITIVE_DATA_PROCESSING); } - @SuppressWarnings("unchecked") - public List getKnownChildSensitiveDataConsents() { - return (List) this.getFieldValue(UsNatField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS); + public FixedIntegerList getKnownChildSensitiveDataConsents() { + return (FixedIntegerList) this.getFieldValue(UsNatField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS); } public Integer getPersonalDataConsents() { diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsNe.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsNe.java index 36e9ff8b..a009def8 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsNe.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsNe.java @@ -3,6 +3,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import com.iab.gpp.encoder.datatype.FixedIntegerList; import com.iab.gpp.encoder.field.UsNeField; import com.iab.gpp.encoder.segment.EncodableSegment; import com.iab.gpp.encoder.segment.UsNeCoreSegment; @@ -98,9 +99,8 @@ public Integer getTargetedAdvertisingOptOut() { return (Integer) this.getFieldValue(UsNeField.TARGETED_ADVERTISING_OPT_OUT); } - @SuppressWarnings("unchecked") - public List getSensitiveDataProcessing() { - return (List) this.getFieldValue(UsNeField.SENSITIVE_DATA_PROCESSING); + public FixedIntegerList getSensitiveDataProcessing() { + return (FixedIntegerList) this.getFieldValue(UsNeField.SENSITIVE_DATA_PROCESSING); } public Integer getKnownChildSensitiveDataConsents() { diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsNh.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsNh.java index b2f22d81..a907d2ed 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsNh.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsNh.java @@ -3,6 +3,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import com.iab.gpp.encoder.datatype.FixedIntegerList; import com.iab.gpp.encoder.field.UsNhField; import com.iab.gpp.encoder.segment.EncodableSegment; import com.iab.gpp.encoder.segment.UsNhCoreSegment; @@ -98,14 +99,12 @@ public Integer getTargetedAdvertisingOptOut() { return (Integer) this.getFieldValue(UsNhField.TARGETED_ADVERTISING_OPT_OUT); } - @SuppressWarnings("unchecked") - public List getSensitiveDataProcessing() { - return (List) this.getFieldValue(UsNhField.SENSITIVE_DATA_PROCESSING); + public FixedIntegerList getSensitiveDataProcessing() { + return (FixedIntegerList) this.getFieldValue(UsNhField.SENSITIVE_DATA_PROCESSING); } - @SuppressWarnings("unchecked") - public List getKnownChildSensitiveDataConsents() { - return (List) this.getFieldValue(UsNhField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS); + public FixedIntegerList getKnownChildSensitiveDataConsents() { + return (FixedIntegerList) this.getFieldValue(UsNhField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS); } public Integer getAdditionalDataProcessingConsent() { diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsNj.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsNj.java index b694d403..c5c648ea 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsNj.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsNj.java @@ -3,6 +3,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import com.iab.gpp.encoder.datatype.FixedIntegerList; import com.iab.gpp.encoder.field.UsNjField; import com.iab.gpp.encoder.segment.EncodableSegment; import com.iab.gpp.encoder.segment.UsNjCoreSegment; @@ -98,14 +99,12 @@ public Integer getTargetedAdvertisingOptOut() { return (Integer) this.getFieldValue(UsNjField.TARGETED_ADVERTISING_OPT_OUT); } - @SuppressWarnings("unchecked") - public List getSensitiveDataProcessing() { - return (List) this.getFieldValue(UsNjField.SENSITIVE_DATA_PROCESSING); + public FixedIntegerList getSensitiveDataProcessing() { + return (FixedIntegerList) this.getFieldValue(UsNjField.SENSITIVE_DATA_PROCESSING); } - @SuppressWarnings("unchecked") - public List getKnownChildSensitiveDataConsents() { - return (List) this.getFieldValue(UsNjField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS); + public FixedIntegerList getKnownChildSensitiveDataConsents() { + return (FixedIntegerList) this.getFieldValue(UsNjField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS); } public Integer getAdditionalDataProcessingConsent() { diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsOr.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsOr.java index 3e14ca1a..41d0d3ce 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsOr.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsOr.java @@ -3,6 +3,7 @@ import java.util.Arrays; import java.util.ArrayList; import java.util.List; +import com.iab.gpp.encoder.datatype.FixedIntegerList; import com.iab.gpp.encoder.field.UsOrField; import com.iab.gpp.encoder.segment.EncodableSegment; import com.iab.gpp.encoder.segment.UsOrCoreSegment; @@ -98,14 +99,12 @@ public Integer getTargetedAdvertisingOptOut() { return (Integer) this.getFieldValue(UsOrField.TARGETED_ADVERTISING_OPT_OUT); } - @SuppressWarnings("unchecked") - public List getSensitiveDataProcessing() { - return (List) this.getFieldValue(UsOrField.SENSITIVE_DATA_PROCESSING); + public FixedIntegerList getSensitiveDataProcessing() { + return (FixedIntegerList) this.getFieldValue(UsOrField.SENSITIVE_DATA_PROCESSING); } - @SuppressWarnings("unchecked") - public List getKnownChildSensitiveDataConsents() { - return (List) this.getFieldValue(UsOrField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS); + public FixedIntegerList getKnownChildSensitiveDataConsents() { + return (FixedIntegerList) this.getFieldValue(UsOrField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS); } public Integer getAdditionalDataProcessingConsent() { diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsTn.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsTn.java index 894f9ed9..23b17edf 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsTn.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsTn.java @@ -3,6 +3,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import com.iab.gpp.encoder.datatype.FixedIntegerList; import com.iab.gpp.encoder.field.UsTnField; import com.iab.gpp.encoder.segment.EncodableSegment; import com.iab.gpp.encoder.segment.UsTnCoreSegment; @@ -98,9 +99,8 @@ public Integer getTargetedAdvertisingOptOut() { return (Integer) this.getFieldValue(UsTnField.TARGETED_ADVERTISING_OPT_OUT); } - @SuppressWarnings("unchecked") - public List getSensitiveDataProcessing() { - return (List) this.getFieldValue(UsTnField.SENSITIVE_DATA_PROCESSING); + public FixedIntegerList getSensitiveDataProcessing() { + return (FixedIntegerList) this.getFieldValue(UsTnField.SENSITIVE_DATA_PROCESSING); } public Integer getKnownChildSensitiveDataConsents() { diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsTx.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsTx.java index 0feec120..521ff729 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsTx.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsTx.java @@ -3,6 +3,7 @@ import java.util.Arrays; import java.util.ArrayList; import java.util.List; +import com.iab.gpp.encoder.datatype.FixedIntegerList; import com.iab.gpp.encoder.field.UsTxField; import com.iab.gpp.encoder.segment.EncodableSegment; import com.iab.gpp.encoder.segment.UsTxCoreSegment; @@ -98,9 +99,8 @@ public Integer getTargetedAdvertisingOptOut() { return (Integer) this.getFieldValue(UsTxField.TARGETED_ADVERTISING_OPT_OUT); } - @SuppressWarnings("unchecked") - public List getSensitiveDataProcessing() { - return (List) this.getFieldValue(UsTxField.SENSITIVE_DATA_PROCESSING); + public FixedIntegerList getSensitiveDataProcessing() { + return (FixedIntegerList) this.getFieldValue(UsTxField.SENSITIVE_DATA_PROCESSING); } public Integer getKnownChildSensitiveDataConsents() { diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsUt.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsUt.java index 96d2217b..05cc7836 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsUt.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsUt.java @@ -3,6 +3,7 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; +import com.iab.gpp.encoder.datatype.FixedIntegerList; import com.iab.gpp.encoder.field.UsUtField; import com.iab.gpp.encoder.segment.EncodableSegment; import com.iab.gpp.encoder.segment.UsUtCoreSegment; @@ -91,9 +92,8 @@ public Integer getTargetedAdvertisingOptOut() { return (Integer) this.getFieldValue(UsUtField.TARGETED_ADVERTISING_OPT_OUT); } - @SuppressWarnings("unchecked") - public List getSensitiveDataProcessing() { - return (List) this.getFieldValue(UsUtField.SENSITIVE_DATA_PROCESSING); + public FixedIntegerList getSensitiveDataProcessing() { + return (FixedIntegerList) this.getFieldValue(UsUtField.SENSITIVE_DATA_PROCESSING); } public Integer getKnownChildSensitiveDataConsents() { diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsVa.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsVa.java index c144a2d3..95a0abd0 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsVa.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsVa.java @@ -3,6 +3,7 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; +import com.iab.gpp.encoder.datatype.FixedIntegerList; import com.iab.gpp.encoder.field.UsVaField; import com.iab.gpp.encoder.segment.EncodableSegment; import com.iab.gpp.encoder.segment.UsVaCoreSegment; @@ -87,9 +88,8 @@ public Integer getTargetedAdvertisingOptOut() { return (Integer) this.getFieldValue(UsVaField.TARGETED_ADVERTISING_OPT_OUT); } - @SuppressWarnings("unchecked") - public List getSensitiveDataProcessing() { - return (List) this.getFieldValue(UsVaField.SENSITIVE_DATA_PROCESSING); + public FixedIntegerList getSensitiveDataProcessing() { + return (FixedIntegerList) this.getFieldValue(UsVaField.SENSITIVE_DATA_PROCESSING); } public Integer getKnownChildSensitiveDataConsents() { diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/AbstractLazilyEncodableSegment.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/AbstractLazilyEncodableSegment.java index b054ba04..d4f5f3c5 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/AbstractLazilyEncodableSegment.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/AbstractLazilyEncodableSegment.java @@ -2,7 +2,7 @@ import java.util.function.Predicate; import com.iab.gpp.encoder.datatype.DataType; -import com.iab.gpp.encoder.datatype.FixedList; +import com.iab.gpp.encoder.datatype.FixedIntegerList; import com.iab.gpp.encoder.error.InvalidFieldException; import com.iab.gpp.encoder.field.Fields; @@ -10,7 +10,7 @@ public abstract class AbstractLazilyEncodableSegment> implem protected static final Predicate nullableBooleanAsTwoBitIntegerValidator = (n -> n >= 0 && n <= 2); protected static final Predicate nonNullableBooleanAsTwoBitIntegerValidator = (n -> n >= 1 && n <= 2); - protected static final Predicate> nullableBooleanAsTwoBitIntegerListValidator = (l -> { + protected static final Predicate nullableBooleanAsTwoBitIntegerListValidator = (l -> { for (int n : l) { if (n < 0 || n > 2) { return false; diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsCaCoreSegment.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsCaCoreSegment.java index eafc1f12..0072a91f 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsCaCoreSegment.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsCaCoreSegment.java @@ -1,6 +1,5 @@ package com.iab.gpp.encoder.segment; -import java.util.Arrays; import com.iab.gpp.encoder.base64.AbstractBase64UrlEncoder; import com.iab.gpp.encoder.base64.CompressedBase64UrlEncoder; import com.iab.gpp.encoder.bitstring.BitString; @@ -42,9 +41,9 @@ protected EncodableBitStringFields initializeFields() { fields.put(UsCaField.SHARING_OPT_OUT, new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); fields.put(UsCaField.SENSITIVE_DATA_PROCESSING, - new EncodableFixedIntegerList(2, Arrays.asList(0, 0, 0, 0, 0, 0, 0, 0, 0)) + new EncodableFixedIntegerList(2, 9) .withValidator(nullableBooleanAsTwoBitIntegerListValidator)); - fields.put(UsCaField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS, new EncodableFixedIntegerList(2, Arrays.asList(0, 0)) + fields.put(UsCaField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS, new EncodableFixedIntegerList(2, 2) .withValidator(nullableBooleanAsTwoBitIntegerListValidator)); fields.put(UsCaField.PERSONAL_DATA_CONSENTS, new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsCoCoreSegment.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsCoCoreSegment.java index 98e96fc9..deafdc52 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsCoCoreSegment.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsCoCoreSegment.java @@ -1,6 +1,5 @@ package com.iab.gpp.encoder.segment; -import java.util.Arrays; import com.iab.gpp.encoder.base64.AbstractBase64UrlEncoder; import com.iab.gpp.encoder.base64.CompressedBase64UrlEncoder; import com.iab.gpp.encoder.bitstring.BitString; @@ -41,7 +40,7 @@ protected EncodableBitStringFields initializeFields() { new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); fields.put(UsCoField.TARGETED_ADVERTISING_OPT_OUT, new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); - fields.put(UsCoField.SENSITIVE_DATA_PROCESSING, new EncodableFixedIntegerList(2, Arrays.asList(0, 0, 0, 0, 0, 0, 0)) + fields.put(UsCoField.SENSITIVE_DATA_PROCESSING, new EncodableFixedIntegerList(2, 7) .withValidator(nullableBooleanAsTwoBitIntegerListValidator)); fields.put(UsCoField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS, new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsCtCoreSegment.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsCtCoreSegment.java index d6e27686..46535363 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsCtCoreSegment.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsCtCoreSegment.java @@ -1,6 +1,5 @@ package com.iab.gpp.encoder.segment; -import java.util.Arrays; import com.iab.gpp.encoder.base64.AbstractBase64UrlEncoder; import com.iab.gpp.encoder.base64.CompressedBase64UrlEncoder; import com.iab.gpp.encoder.bitstring.BitString; @@ -42,9 +41,9 @@ protected EncodableBitStringFields initializeFields() { fields.put(UsCtField.TARGETED_ADVERTISING_OPT_OUT, new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); fields.put(UsCtField.SENSITIVE_DATA_PROCESSING, - new EncodableFixedIntegerList(2, Arrays.asList(0, 0, 0, 0, 0, 0, 0, 0)) + new EncodableFixedIntegerList(2, 8) .withValidator(nullableBooleanAsTwoBitIntegerListValidator)); - fields.put(UsCtField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS, new EncodableFixedIntegerList(2, Arrays.asList(0, 0, 0)) + fields.put(UsCtField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS, new EncodableFixedIntegerList(2, 3) .withValidator(nullableBooleanAsTwoBitIntegerListValidator)); fields.put(UsCtField.MSPA_COVERED_TRANSACTION, new EncodableFixedInteger(2, 1).withValidator(nonNullableBooleanAsTwoBitIntegerValidator)); diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsDeCoreSegment.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsDeCoreSegment.java index 534fbf28..6b935cf8 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsDeCoreSegment.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsDeCoreSegment.java @@ -1,6 +1,5 @@ package com.iab.gpp.encoder.segment; -import java.util.Arrays; import com.iab.gpp.encoder.base64.AbstractBase64UrlEncoder; import com.iab.gpp.encoder.base64.CompressedBase64UrlEncoder; import com.iab.gpp.encoder.bitstring.BitString; @@ -42,10 +41,10 @@ protected EncodableBitStringFields initializeFields() { fields.put(UsDeField.TARGETED_ADVERTISING_OPT_OUT, new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); fields.put(UsDeField.SENSITIVE_DATA_PROCESSING, - new EncodableFixedIntegerList(2, Arrays.asList(0, 0, 0, 0, 0, 0, 0, 0, 0)) + new EncodableFixedIntegerList(2, 9) .withValidator(nullableBooleanAsTwoBitIntegerListValidator)); fields.put(UsDeField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS, - new EncodableFixedIntegerList(2, Arrays.asList(0, 0, 0, 0, 0)) + new EncodableFixedIntegerList(2, 5) .withValidator(nullableBooleanAsTwoBitIntegerListValidator)); fields.put(UsDeField.ADDITIONAL_DATA_PROCESSING_CONSENT, new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsFlCoreSegment.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsFlCoreSegment.java index 384d34ac..9e6e49b7 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsFlCoreSegment.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsFlCoreSegment.java @@ -1,6 +1,5 @@ package com.iab.gpp.encoder.segment; -import java.util.Arrays; import com.iab.gpp.encoder.base64.AbstractBase64UrlEncoder; import com.iab.gpp.encoder.base64.CompressedBase64UrlEncoder; import com.iab.gpp.encoder.bitstring.BitString; @@ -42,9 +41,9 @@ protected EncodableBitStringFields initializeFields() { fields.put(UsFlField.TARGETED_ADVERTISING_OPT_OUT, new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); fields.put(UsFlField.SENSITIVE_DATA_PROCESSING, - new EncodableFixedIntegerList(2, Arrays.asList(0, 0, 0, 0, 0, 0, 0, 0)) + new EncodableFixedIntegerList(2, 8) .withValidator(nullableBooleanAsTwoBitIntegerListValidator)); - fields.put(UsFlField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS, new EncodableFixedIntegerList(2, Arrays.asList(0, 0, 0)) + fields.put(UsFlField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS, new EncodableFixedIntegerList(2, 3) .withValidator(nullableBooleanAsTwoBitIntegerListValidator)); fields.put(UsFlField.ADDITIONAL_DATA_PROCESSING_CONSENT, new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsIaCoreSegment.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsIaCoreSegment.java index 530ccd13..087f0445 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsIaCoreSegment.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsIaCoreSegment.java @@ -1,6 +1,5 @@ package com.iab.gpp.encoder.segment; -import java.util.Arrays; import com.iab.gpp.encoder.base64.AbstractBase64UrlEncoder; import com.iab.gpp.encoder.base64.CompressedBase64UrlEncoder; import com.iab.gpp.encoder.bitstring.BitString; @@ -44,7 +43,7 @@ protected EncodableBitStringFields initializeFields() { fields.put(UsIaField.TARGETED_ADVERTISING_OPT_OUT, new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); fields.put(UsIaField.SENSITIVE_DATA_PROCESSING, - new EncodableFixedIntegerList(2, Arrays.asList(0, 0, 0, 0, 0, 0, 0, 0)) + new EncodableFixedIntegerList(2, 8) .withValidator(nullableBooleanAsTwoBitIntegerListValidator)); fields.put(UsIaField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS, new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsMtCoreSegment.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsMtCoreSegment.java index 49d8813b..89cad156 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsMtCoreSegment.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsMtCoreSegment.java @@ -1,6 +1,5 @@ package com.iab.gpp.encoder.segment; -import java.util.Arrays; import com.iab.gpp.encoder.base64.AbstractBase64UrlEncoder; import com.iab.gpp.encoder.base64.CompressedBase64UrlEncoder; import com.iab.gpp.encoder.bitstring.BitString; @@ -42,9 +41,9 @@ protected EncodableBitStringFields initializeFields() { fields.put(UsMtField.TARGETED_ADVERTISING_OPT_OUT, new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); fields.put(UsMtField.SENSITIVE_DATA_PROCESSING, - new EncodableFixedIntegerList(2, Arrays.asList(0, 0, 0, 0, 0, 0, 0, 0)) + new EncodableFixedIntegerList(2, 8) .withValidator(nullableBooleanAsTwoBitIntegerListValidator)); - fields.put(UsMtField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS, new EncodableFixedIntegerList(2, Arrays.asList(0, 0, 0)) + fields.put(UsMtField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS, new EncodableFixedIntegerList(2, 3) .withValidator(nullableBooleanAsTwoBitIntegerListValidator)); fields.put(UsMtField.ADDITIONAL_DATA_PROCESSING_CONSENT, new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsNatCoreSegment.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsNatCoreSegment.java index 5257d91e..3212b317 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsNatCoreSegment.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsNatCoreSegment.java @@ -1,6 +1,5 @@ package com.iab.gpp.encoder.segment; -import java.util.Arrays; import com.iab.gpp.encoder.base64.AbstractBase64UrlEncoder; import com.iab.gpp.encoder.base64.CompressedBase64UrlEncoder; import com.iab.gpp.encoder.bitstring.BitString; @@ -50,9 +49,9 @@ protected EncodableBitStringFields initializeFields() { fields.put(UsNatField.TARGETED_ADVERTISING_OPT_OUT, new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); fields.put(UsNatField.SENSITIVE_DATA_PROCESSING, - new EncodableFixedIntegerList(2, Arrays.asList(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)) + new EncodableFixedIntegerList(2, 16) .withValidator(nullableBooleanAsTwoBitIntegerListValidator)); - fields.put(UsNatField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS, new EncodableFixedIntegerList(2, Arrays.asList(0, 0, 0)) + fields.put(UsNatField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS, new EncodableFixedIntegerList(2, 3) .withValidator(nullableBooleanAsTwoBitIntegerListValidator)); fields.put(UsNatField.PERSONAL_DATA_CONSENTS, new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsNeCoreSegment.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsNeCoreSegment.java index fb7b77a1..52d06230 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsNeCoreSegment.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsNeCoreSegment.java @@ -1,6 +1,5 @@ package com.iab.gpp.encoder.segment; -import java.util.Arrays; import com.iab.gpp.encoder.base64.AbstractBase64UrlEncoder; import com.iab.gpp.encoder.base64.CompressedBase64UrlEncoder; import com.iab.gpp.encoder.bitstring.BitString; @@ -42,7 +41,7 @@ protected EncodableBitStringFields initializeFields() { fields.put(UsNeField.TARGETED_ADVERTISING_OPT_OUT, new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); fields.put(UsNeField.SENSITIVE_DATA_PROCESSING, - new EncodableFixedIntegerList(2, Arrays.asList(0, 0, 0, 0, 0, 0, 0, 0)) + new EncodableFixedIntegerList(2, 8) .withValidator(nullableBooleanAsTwoBitIntegerListValidator)); fields.put(UsNeField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS, new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsNhCoreSegment.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsNhCoreSegment.java index 789f86b5..44ce9219 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsNhCoreSegment.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsNhCoreSegment.java @@ -1,6 +1,5 @@ package com.iab.gpp.encoder.segment; -import java.util.Arrays; import com.iab.gpp.encoder.base64.AbstractBase64UrlEncoder; import com.iab.gpp.encoder.base64.CompressedBase64UrlEncoder; import com.iab.gpp.encoder.bitstring.BitString; @@ -42,9 +41,9 @@ protected EncodableBitStringFields initializeFields() { fields.put(UsNhField.TARGETED_ADVERTISING_OPT_OUT, new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); fields.put(UsNhField.SENSITIVE_DATA_PROCESSING, - new EncodableFixedIntegerList(2, Arrays.asList(0, 0, 0, 0, 0, 0, 0, 0)) + new EncodableFixedIntegerList(2, 8) .withValidator(nullableBooleanAsTwoBitIntegerListValidator)); - fields.put(UsNhField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS, new EncodableFixedIntegerList(2, Arrays.asList(0, 0, 0)) + fields.put(UsNhField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS, new EncodableFixedIntegerList(2, 3) .withValidator(nullableBooleanAsTwoBitIntegerListValidator)); fields.put(UsNhField.ADDITIONAL_DATA_PROCESSING_CONSENT, new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsNjCoreSegment.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsNjCoreSegment.java index 99f94205..3de4bb2f 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsNjCoreSegment.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsNjCoreSegment.java @@ -1,6 +1,5 @@ package com.iab.gpp.encoder.segment; -import java.util.Arrays; import com.iab.gpp.encoder.base64.AbstractBase64UrlEncoder; import com.iab.gpp.encoder.base64.CompressedBase64UrlEncoder; import com.iab.gpp.encoder.bitstring.BitString; @@ -42,9 +41,9 @@ protected EncodableBitStringFields initializeFields() { fields.put(UsNjField.TARGETED_ADVERTISING_OPT_OUT, new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); fields.put(UsNjField.SENSITIVE_DATA_PROCESSING, - new EncodableFixedIntegerList(2, Arrays.asList(0, 0, 0, 0, 0, 0, 0, 0, 0, 0)) + new EncodableFixedIntegerList(2, 10) .withValidator(nullableBooleanAsTwoBitIntegerListValidator)); - fields.put(UsNjField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS, new EncodableFixedIntegerList(2, Arrays.asList(0, 0, 0, 0, 0)) + fields.put(UsNjField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS, new EncodableFixedIntegerList(2, 5) .withValidator(nullableBooleanAsTwoBitIntegerListValidator)); fields.put(UsNjField.ADDITIONAL_DATA_PROCESSING_CONSENT, new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsOrCoreSegment.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsOrCoreSegment.java index f9ef489d..a1278600 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsOrCoreSegment.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsOrCoreSegment.java @@ -1,6 +1,5 @@ package com.iab.gpp.encoder.segment; -import java.util.Arrays; import com.iab.gpp.encoder.base64.AbstractBase64UrlEncoder; import com.iab.gpp.encoder.base64.CompressedBase64UrlEncoder; import com.iab.gpp.encoder.bitstring.BitString; @@ -42,9 +41,9 @@ protected EncodableBitStringFields initializeFields() { fields.put(UsOrField.TARGETED_ADVERTISING_OPT_OUT, new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); fields.put(UsOrField.SENSITIVE_DATA_PROCESSING, - new EncodableFixedIntegerList(2, Arrays.asList(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)) + new EncodableFixedIntegerList(2, 11) .withValidator(nullableBooleanAsTwoBitIntegerListValidator)); - fields.put(UsOrField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS, new EncodableFixedIntegerList(2, Arrays.asList(0, 0, 0)) + fields.put(UsOrField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS, new EncodableFixedIntegerList(2, 3) .withValidator(nullableBooleanAsTwoBitIntegerListValidator)); fields.put(UsOrField.ADDITIONAL_DATA_PROCESSING_CONSENT, new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsTnCoreSegment.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsTnCoreSegment.java index b6bd3409..c22afdf6 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsTnCoreSegment.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsTnCoreSegment.java @@ -1,6 +1,5 @@ package com.iab.gpp.encoder.segment; -import java.util.Arrays; import com.iab.gpp.encoder.base64.AbstractBase64UrlEncoder; import com.iab.gpp.encoder.base64.CompressedBase64UrlEncoder; import com.iab.gpp.encoder.bitstring.BitString; @@ -42,7 +41,7 @@ protected EncodableBitStringFields initializeFields() { fields.put(UsTnField.TARGETED_ADVERTISING_OPT_OUT, new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); fields.put(UsTnField.SENSITIVE_DATA_PROCESSING, - new EncodableFixedIntegerList(2, Arrays.asList(0, 0, 0, 0, 0, 0, 0, 0)) + new EncodableFixedIntegerList(2, 8) .withValidator(nullableBooleanAsTwoBitIntegerListValidator)); fields.put(UsTnField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS, new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsTxCoreSegment.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsTxCoreSegment.java index 2b809263..8c67106a 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsTxCoreSegment.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsTxCoreSegment.java @@ -1,6 +1,5 @@ package com.iab.gpp.encoder.segment; -import java.util.Arrays; import com.iab.gpp.encoder.base64.AbstractBase64UrlEncoder; import com.iab.gpp.encoder.base64.CompressedBase64UrlEncoder; import com.iab.gpp.encoder.bitstring.BitString; @@ -42,7 +41,7 @@ protected EncodableBitStringFields initializeFields() { fields.put(UsTxField.TARGETED_ADVERTISING_OPT_OUT, new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); fields.put(UsTxField.SENSITIVE_DATA_PROCESSING, - new EncodableFixedIntegerList(2, Arrays.asList(0, 0, 0, 0, 0, 0, 0, 0)) + new EncodableFixedIntegerList(2, 8) .withValidator(nullableBooleanAsTwoBitIntegerListValidator)); fields.put(UsTxField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS, new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsUtCoreSegment.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsUtCoreSegment.java index 368cfca5..27e42ca4 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsUtCoreSegment.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsUtCoreSegment.java @@ -1,6 +1,5 @@ package com.iab.gpp.encoder.segment; -import java.util.Arrays; import com.iab.gpp.encoder.base64.AbstractBase64UrlEncoder; import com.iab.gpp.encoder.base64.CompressedBase64UrlEncoder; import com.iab.gpp.encoder.bitstring.BitString; @@ -44,7 +43,7 @@ protected EncodableBitStringFields initializeFields() { fields.put(UsUtField.TARGETED_ADVERTISING_OPT_OUT, new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); fields.put(UsUtField.SENSITIVE_DATA_PROCESSING, - new EncodableFixedIntegerList(2, Arrays.asList(0, 0, 0, 0, 0, 0, 0, 0)) + new EncodableFixedIntegerList(2, 8) .withValidator(nullableBooleanAsTwoBitIntegerListValidator)); fields.put(UsUtField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS, new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsVaCoreSegment.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsVaCoreSegment.java index b374520b..d0028cb6 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsVaCoreSegment.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsVaCoreSegment.java @@ -1,6 +1,5 @@ package com.iab.gpp.encoder.segment; -import java.util.Arrays; import com.iab.gpp.encoder.base64.AbstractBase64UrlEncoder; import com.iab.gpp.encoder.base64.CompressedBase64UrlEncoder; import com.iab.gpp.encoder.bitstring.BitString; @@ -42,7 +41,7 @@ protected EncodableBitStringFields initializeFields() { fields.put(UsVaField.TARGETED_ADVERTISING_OPT_OUT, new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); fields.put(UsVaField.SENSITIVE_DATA_PROCESSING, - new EncodableFixedIntegerList(2, Arrays.asList(0, 0, 0, 0, 0, 0, 0, 0)) + new EncodableFixedIntegerList(2, 8) .withValidator(nullableBooleanAsTwoBitIntegerListValidator)); fields.put(UsVaField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS, new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); From 8f8000184ff16447ecceddfc58330c6df759d513 Mon Sep 17 00:00:00 2001 From: James Yuzawa Date: Mon, 12 Jan 2026 17:01:04 -0500 Subject: [PATCH 06/11] avoid itable calls to IntegerSet --- .../iab/gpp/encoder/bitstring/BitString.java | 3 +- .../EncodableFibonacciIntegerRange.java | 3 +- .../datatype/EncodableFixedBitfield.java | 3 +- .../datatype/EncodableFixedIntegerRange.java | 3 +- .../datatype/EncodableFlexibleBitfield.java | 3 +- .../EncodableOptimizedFixedRange.java | 3 +- .../iab/gpp/encoder/datatype/RangeEntry.java | 3 +- .../encoder/FibonacciIntegerRangeEncoder.java | 4 +- .../encoder/FixedIntegerRangeEncoder.java | 4 +- .../datatype/encoder/IntegerBitSet.java | 210 ----------------- .../datatype/encoder/IntegerCache.java | 2 +- .../encoder/datatype/encoder/IntegerSet.java | 220 ++++++++++++++++-- .../OptimizedFibonacciRangeEncoder.java | 4 +- .../encoder/OptimizedFixedRangeEncoder.java | 4 +- .../FibonacciIntegerRangeEncoderTest.java | 2 +- .../encoder/FixedBitfieldEncoderTest.java | 18 +- .../encoder/FixedIntegerRangeEncoderTest.java | 2 +- 17 files changed, 234 insertions(+), 257 deletions(-) diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/bitstring/BitString.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/bitstring/BitString.java index 8026d69c..77601d40 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/bitstring/BitString.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/bitstring/BitString.java @@ -1,7 +1,6 @@ package com.iab.gpp.encoder.bitstring; import java.util.BitSet; -import com.iab.gpp.encoder.datatype.encoder.IntegerBitSet; import com.iab.gpp.encoder.datatype.encoder.IntegerSet; import com.iab.gpp.encoder.error.DecodingException; @@ -46,7 +45,7 @@ public static final BitString of(String str) { } public IntegerSet toIntegerSet() { - return new IntegerBitSet(bitSet, from, to, 1); + return new IntegerSet(bitSet, from, to, 1); } @Override diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableFibonacciIntegerRange.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableFibonacciIntegerRange.java index 2c8df3c7..3bf4a54c 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableFibonacciIntegerRange.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableFibonacciIntegerRange.java @@ -3,7 +3,6 @@ import java.util.Collection; import com.iab.gpp.encoder.bitstring.BitString; import com.iab.gpp.encoder.bitstring.BitStringBuilder; -import com.iab.gpp.encoder.datatype.encoder.IntegerBitSet; import com.iab.gpp.encoder.datatype.encoder.FibonacciIntegerEncoder; import com.iab.gpp.encoder.datatype.encoder.FibonacciIntegerRangeEncoder; import com.iab.gpp.encoder.datatype.encoder.FixedIntegerEncoder; @@ -15,7 +14,7 @@ public final class EncodableFibonacciIntegerRange extends AbstractDirtyableBitSt public EncodableFibonacciIntegerRange() { super(true); - this.value = new IntegerBitSet(); + this.value = new IntegerSet(); } public void encode(BitStringBuilder builder) { diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableFixedBitfield.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableFixedBitfield.java index 48615032..993d8551 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableFixedBitfield.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableFixedBitfield.java @@ -3,7 +3,6 @@ import java.util.Collection; import com.iab.gpp.encoder.bitstring.BitString; import com.iab.gpp.encoder.bitstring.BitStringBuilder; -import com.iab.gpp.encoder.datatype.encoder.IntegerBitSet; import com.iab.gpp.encoder.datatype.encoder.FixedBitfieldEncoder; import com.iab.gpp.encoder.datatype.encoder.IntegerSet; import com.iab.gpp.encoder.error.DecodingException; @@ -16,7 +15,7 @@ public final class EncodableFixedBitfield extends AbstractDirtyableBitStringData public EncodableFixedBitfield(int numElements) { super(true); this.numElements = numElements; - this.value = new IntegerBitSet(numElements); + this.value = new IntegerSet(numElements); } public void encode(BitStringBuilder builder) { diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableFixedIntegerRange.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableFixedIntegerRange.java index 56b94487..66b9232f 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableFixedIntegerRange.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableFixedIntegerRange.java @@ -3,7 +3,6 @@ import java.util.Collection; import com.iab.gpp.encoder.bitstring.BitString; import com.iab.gpp.encoder.bitstring.BitStringBuilder; -import com.iab.gpp.encoder.datatype.encoder.IntegerBitSet; import com.iab.gpp.encoder.datatype.encoder.FixedIntegerEncoder; import com.iab.gpp.encoder.datatype.encoder.FixedIntegerRangeEncoder; import com.iab.gpp.encoder.datatype.encoder.IntegerSet; @@ -14,7 +13,7 @@ public final class EncodableFixedIntegerRange extends AbstractDirtyableBitString protected EncodableFixedIntegerRange() { super(true); - this.value = new IntegerBitSet(); + this.value = new IntegerSet(); } public void encode(BitStringBuilder builder) { diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableFlexibleBitfield.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableFlexibleBitfield.java index 04e8d8a5..9287d62d 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableFlexibleBitfield.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableFlexibleBitfield.java @@ -5,7 +5,6 @@ import com.iab.gpp.encoder.bitstring.BitString; import com.iab.gpp.encoder.bitstring.BitStringBuilder; -import com.iab.gpp.encoder.datatype.encoder.IntegerBitSet; import com.iab.gpp.encoder.datatype.encoder.FixedBitfieldEncoder; import com.iab.gpp.encoder.datatype.encoder.IntegerSet; import com.iab.gpp.encoder.error.DecodingException; @@ -18,7 +17,7 @@ public final class EncodableFlexibleBitfield extends AbstractDirtyableBitStringD public EncodableFlexibleBitfield(IntSupplier getLengthSupplier) { super(true); this.getLengthSupplier = getLengthSupplier; - this.value = new IntegerBitSet(); + this.value = new IntegerSet(); } public void encode(BitStringBuilder builder) { diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableOptimizedFixedRange.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableOptimizedFixedRange.java index 14b00485..aa716c37 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableOptimizedFixedRange.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableOptimizedFixedRange.java @@ -3,7 +3,6 @@ import java.util.Collection; import com.iab.gpp.encoder.bitstring.BitString; import com.iab.gpp.encoder.bitstring.BitStringBuilder; -import com.iab.gpp.encoder.datatype.encoder.IntegerBitSet; import com.iab.gpp.encoder.datatype.encoder.FixedIntegerEncoder; import com.iab.gpp.encoder.datatype.encoder.IntegerSet; import com.iab.gpp.encoder.datatype.encoder.OptimizedFixedRangeEncoder; @@ -15,7 +14,7 @@ public final class EncodableOptimizedFixedRange extends AbstractDirtyableBitStri public EncodableOptimizedFixedRange() { super(true); - this.value = new IntegerBitSet(); + this.value = new IntegerSet(); } public void encode(BitStringBuilder builder) { diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/RangeEntry.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/RangeEntry.java index ed997b16..29e33eed 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/RangeEntry.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/RangeEntry.java @@ -3,7 +3,6 @@ import java.util.Collection; import java.util.Set; import com.iab.gpp.encoder.datatype.encoder.Dirtyable; -import com.iab.gpp.encoder.datatype.encoder.IntegerBitSet; import com.iab.gpp.encoder.datatype.encoder.IntegerSet; public class RangeEntry implements Dirtyable { @@ -17,7 +16,7 @@ public RangeEntry(int key, int type, Set ids) { super(); this.key = key; this.type = type; - this.ids = new IntegerBitSet(); + this.ids = new IntegerSet(); this.ids.addAll(ids); } diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/encoder/FibonacciIntegerRangeEncoder.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/encoder/FibonacciIntegerRangeEncoder.java index 46b409bc..95dbf869 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/encoder/FibonacciIntegerRangeEncoder.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/encoder/FibonacciIntegerRangeEncoder.java @@ -47,13 +47,13 @@ private static void writeGroup(BitStringBuilder builder, int groupStart, int las } } - public static IntegerBitSet decode(BitString bitString) throws DecodingException { + public static IntegerSet decode(BitString bitString) throws DecodingException { if (bitString.length() < 12) { throw new DecodingException("Undecodable FibonacciIntegerRange '" + bitString + "'"); } int count = FixedIntegerEncoder.decode(bitString, 0, 12); - IntegerBitSet value = new IntegerBitSet(); + IntegerSet value = new IntegerSet(); int offset = 0; int startIndex = 12; diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/encoder/FixedIntegerRangeEncoder.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/encoder/FixedIntegerRangeEncoder.java index 6160fa12..a399ba49 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/encoder/FixedIntegerRangeEncoder.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/encoder/FixedIntegerRangeEncoder.java @@ -43,13 +43,13 @@ private static void writeGroup(BitStringBuilder builder, int groupStart, int las } } - public static IntegerBitSet decode(BitString bitString) throws DecodingException { + public static IntegerSet decode(BitString bitString) throws DecodingException { if (bitString.length() < 12) { throw new DecodingException("Undecodable FixedIntegerRange '" + bitString + "'"); } int count = FixedIntegerEncoder.decode(bitString, 0, 12); - IntegerBitSet value = new IntegerBitSet(); + IntegerSet value = new IntegerSet(); int startIndex = 12; for (int i = 0; i < count; i++) { boolean group = BooleanEncoder.decode(bitString, startIndex, 1); diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/encoder/IntegerBitSet.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/encoder/IntegerBitSet.java index 663b28f8..6ae65a06 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/encoder/IntegerBitSet.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/encoder/IntegerBitSet.java @@ -11,214 +11,4 @@ import java.util.stream.IntStream; import java.util.stream.StreamSupport; -public final class IntegerBitSet extends AbstractSet implements IntegerSet { - private static final Logger LOGGER = Logger.getLogger(IntegerBitSet.class.getName()); - static final int MAX_COLLECTION_SIZE = 8192; - - private boolean dirty; - private final BitSet bitSet; - private final int from; - private final int to; - private final int adjustment; - - public IntegerBitSet(BitSet bitSet, int from, int to, int adjustment) { - this.bitSet = bitSet; - this.from = from; - this.to = to; - this.adjustment = adjustment; - } - - public IntegerBitSet(int limit) { - this(new BitSet(0), 0, limit, 0); - } - - public IntegerBitSet() { - this(MAX_COLLECTION_SIZE); - } - - @Override - public int size() { - OfInt it = iterator(); - int count = 0; - while (it.hasNext()) { - it.next(); - count++; - } - return count; - } - - private int getOffset(int value) { - int offset = from - adjustment + value; - if (offset < from) { - throw new IndexOutOfBoundsException("Negative index provided"); - } - return offset; - } - - @Override - public void clear() { - dirty = true; - bitSet.clear(from, to); - } - - @Override - public boolean isEmpty() { - return bitSet.nextSetBit(from) == -1; - } - - @Override - public boolean containsInt(int value) { - int offset = getOffset(value); - return offset < to && bitSet.get(offset); - } - - @Override - public OfInt iterator() { - return new OfInt() { - int cursor = bitSet.nextSetBit(from); - - @Override - public boolean hasNext() { - return cursor < to && cursor != -1; - } - - @Override - public Integer next() { - return IntegerCache.valueOf(nextInt()); - } - - @Override - public int nextInt() { - if (!this.hasNext()) { - throw new NoSuchElementException(); - } - int next = cursor; - cursor = bitSet.nextSetBit(cursor + 1); - return next - from + adjustment; - } - }; - } - - @Override - public Spliterator.OfInt spliterator(){ - return Spliterators.spliteratorUnknownSize( - iterator(), - Spliterator.ORDERED | Spliterator.DISTINCT | Spliterator.IMMUTABLE | Spliterator.NONNULL); - } - - @Override - public IntStream intStream() { - return StreamSupport.intStream(spliterator(), false); - } - - private static final void logOutOfRange(int value) { - LOGGER.warning("Exceeding IntegerBitSet.MAX_COLLECTION_SIZE: "+ value); - } - - public void addRange(int start, int end) { - if (end < start) { - throw new IllegalArgumentException("Negative length range"); - } - int realStart = getOffset(start); - int realEnd = getOffset(end); - if (realStart >= to) { - logOutOfRange(start); - return; - } - if (realEnd > to) { - logOutOfRange(end); - realEnd = to; - } - dirty = true; - bitSet.set(realStart, realEnd); - } - - public boolean addInt(int value) { - int offset = getOffset(value); - if (offset >= to) { - logOutOfRange(value); - return false; - } - boolean present = bitSet.get(offset); - if (present) { - return false; - } - bitSet.set(offset, true); - dirty = true; - return true; - } - - public boolean removeInt(int value) { - int offset = getOffset(value); - if (offset >= to) { - logOutOfRange(value); - return false; - } - boolean present = bitSet.get(offset); - if (!present) { - return false; - } - bitSet.set(offset, false); - dirty = true; - return true; - } - - @Override - public final boolean contains(Object value) { - if (value instanceof Integer) { - return containsInt((Integer) value); - } - return false; - } - - @Override - public final boolean add(Integer value) { - if (value == null) { - return false; - } - return addInt(value); - } - - @Override - public final boolean remove(Object value) { - if (value instanceof Integer) { - return removeInt((Integer) value); - } - return false; - } - - @Override - public boolean removeAll(Collection c) { - boolean modified = false; - for (Integer i : this) { - if (c.contains(i)) { - remove(i); - modified = true; - } - } - return modified; - } - - @Override - public boolean retainAll(Collection c) { - boolean modified = false; - for (Integer i : this) { - if (!c.contains(i)) { - remove(i); - modified = true; - } - } - return modified; - } - - @Override - public boolean isDirty() { - return dirty; - } - - @Override - public void setDirty(boolean dirty) { - this.dirty = dirty; - } -} diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/encoder/IntegerCache.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/encoder/IntegerCache.java index d92823e5..07471ea2 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/encoder/IntegerCache.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/encoder/IntegerCache.java @@ -1,6 +1,6 @@ package com.iab.gpp.encoder.datatype.encoder; -import static com.iab.gpp.encoder.datatype.encoder.IntegerBitSet.MAX_COLLECTION_SIZE; +import static com.iab.gpp.encoder.datatype.encoder.IntegerSet.MAX_COLLECTION_SIZE; final class IntegerCache { private IntegerCache() {} diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/encoder/IntegerSet.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/encoder/IntegerSet.java index 5f27795e..387f35fe 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/encoder/IntegerSet.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/encoder/IntegerSet.java @@ -1,28 +1,222 @@ package com.iab.gpp.encoder.datatype.encoder; +import java.util.AbstractSet; +import java.util.BitSet; import java.util.Collection; -import java.util.PrimitiveIterator; -import java.util.Set; +import java.util.NoSuchElementException; +import java.util.Spliterator; +import java.util.Spliterators; +import java.util.PrimitiveIterator.OfInt; +import java.util.logging.Logger; import java.util.stream.IntStream; +import java.util.stream.StreamSupport; -public interface IntegerSet extends Set, Dirtyable { - boolean containsInt(int value); +public final class IntegerSet extends AbstractSet implements Dirtyable { + private static final Logger LOGGER = Logger.getLogger(IntegerSet.class.getName()); - default boolean containsAny(Collection c) { - for (Object e : c) { - if (!contains(e)) { - return false; + static final int MAX_COLLECTION_SIZE = 8192; + + private boolean dirty; + private final BitSet bitSet; + private final int from; + private final int to; + private final int adjustment; + + public IntegerSet(BitSet bitSet, int from, int to, int adjustment) { + this.bitSet = bitSet; + this.from = from; + this.to = to; + this.adjustment = adjustment; + } + + public IntegerSet(int limit) { + this(new BitSet(0), 0, limit, 0); + } + + public IntegerSet() { + this(MAX_COLLECTION_SIZE); + } + + @Override + public int size() { + OfInt it = iterator(); + int count = 0; + while (it.hasNext()) { + it.next(); + count++; + } + return count; + } + + private int getOffset(int value) { + int offset = from - adjustment + value; + if (offset < from) { + throw new IndexOutOfBoundsException("Negative index provided"); + } + return offset; + } + + @Override + public void clear() { + dirty = true; + bitSet.clear(from, to); + } + + @Override + public boolean isEmpty() { + return bitSet.nextSetBit(from) == -1; + } + + public boolean containsInt(int value) { + int offset = getOffset(value); + return offset < to && bitSet.get(offset); + } + + @Override + public OfInt iterator() { + return new OfInt() { + int cursor = bitSet.nextSetBit(from); + + @Override + public boolean hasNext() { + return cursor < to && cursor != -1; + } + + @Override + public Integer next() { + return IntegerCache.valueOf(nextInt()); } + + @Override + public int nextInt() { + if (!this.hasNext()) { + throw new NoSuchElementException(); + } + int next = cursor; + cursor = bitSet.nextSetBit(cursor + 1); + return next - from + adjustment; + } + }; + } + + @Override + public Spliterator.OfInt spliterator(){ + return Spliterators.spliteratorUnknownSize( + iterator(), + Spliterator.ORDERED | Spliterator.DISTINCT | Spliterator.IMMUTABLE | Spliterator.NONNULL); + } + + public IntStream intStream() { + return StreamSupport.intStream(spliterator(), false); + } + + private static final void logOutOfRange(int value) { + LOGGER.warning("Exceeding IntegerBitSet.MAX_COLLECTION_SIZE: "+ value); + } + + public void addRange(int start, int end) { + if (end < start) { + throw new IllegalArgumentException("Negative length range"); + } + int realStart = getOffset(start); + int realEnd = getOffset(end); + if (realStart >= to) { + logOutOfRange(start); + return; + } + if (realEnd > to) { + logOutOfRange(end); + realEnd = to; + } + dirty = true; + bitSet.set(realStart, realEnd); + } + + public boolean addInt(int value) { + int offset = getOffset(value); + if (offset >= to) { + logOutOfRange(value); + return false; + } + boolean present = bitSet.get(offset); + if (present) { + return false; + } + bitSet.set(offset, true); + dirty = true; + return true; + } + + public boolean removeInt(int value) { + int offset = getOffset(value); + if (offset >= to) { + logOutOfRange(value); + return false; } + boolean present = bitSet.get(offset); + if (!present) { + return false; + } + bitSet.set(offset, false); + dirty = true; return true; } - boolean addInt(int value); + @Override + public final boolean contains(Object value) { + if (value instanceof Integer) { + return containsInt((Integer) value); + } + return false; + } + + @Override + public final boolean add(Integer value) { + if (value == null) { + return false; + } + return addInt(value); + } + + @Override + public final boolean remove(Object value) { + if (value instanceof Integer) { + return removeInt((Integer) value); + } + return false; + } + + @Override + public boolean removeAll(Collection c) { + boolean modified = false; + for (Integer i : this) { + if (c.contains(i)) { + remove(i); + modified = true; + } + } + return modified; + } - boolean removeInt(int value); + @Override + public boolean retainAll(Collection c) { + boolean modified = false; + for (Integer i : this) { + if (!c.contains(i)) { + remove(i); + modified = true; + } + } + return modified; + } - IntStream intStream(); + @Override + public boolean isDirty() { + return dirty; + } @Override - PrimitiveIterator.OfInt iterator(); -} + public void setDirty(boolean dirty) { + this.dirty = dirty; + } +} \ No newline at end of file diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/encoder/OptimizedFibonacciRangeEncoder.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/encoder/OptimizedFibonacciRangeEncoder.java index 9240bee7..a0b8494e 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/encoder/OptimizedFibonacciRangeEncoder.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/encoder/OptimizedFibonacciRangeEncoder.java @@ -28,7 +28,7 @@ public static void encode(BitStringBuilder builder, IntegerSet value) throws Enc } } - public static IntegerBitSet decode(BitString bitString) throws DecodingException { + public static IntegerSet decode(BitString bitString) throws DecodingException { if (bitString.length() < 12) { throw new DecodingException("Undecodable FibonacciIntegerRange '" + bitString + "'"); } @@ -38,7 +38,7 @@ public static IntegerBitSet decode(BitString bitString) throws DecodingException } else { BitString bits = bitString.substring(17); int length = bits.length(); - IntegerBitSet value = new IntegerBitSet(); + IntegerSet value = new IntegerSet(); for (int i = 0; i < length; i++) { if (bits.getValue(i)) { value.addInt(i + 1); diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/encoder/OptimizedFixedRangeEncoder.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/encoder/OptimizedFixedRangeEncoder.java index 3126c60d..607ace29 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/encoder/OptimizedFixedRangeEncoder.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/encoder/OptimizedFixedRangeEncoder.java @@ -27,7 +27,7 @@ public static void encode(BitStringBuilder builder, IntegerSet value) throws Enc } } - public static IntegerBitSet decode(BitString bitString) throws DecodingException { + public static IntegerSet decode(BitString bitString) throws DecodingException { if (bitString.length() < 12) { throw new DecodingException("Undecodable FixedIntegerRange '" + bitString + "'"); } @@ -37,7 +37,7 @@ public static IntegerBitSet decode(BitString bitString) throws DecodingException } else { BitString bits = bitString.substring(17); int length = bits.length(); - IntegerBitSet value = new IntegerBitSet(); + IntegerSet value = new IntegerSet(); for (int i = 0; i < length; i++) { if (bits.getValue(i)) { value.addInt(i + 1); diff --git a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/datatype/encoder/FibonacciIntegerRangeEncoderTest.java b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/datatype/encoder/FibonacciIntegerRangeEncoderTest.java index b8ad0b2f..0579095b 100644 --- a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/datatype/encoder/FibonacciIntegerRangeEncoderTest.java +++ b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/datatype/encoder/FibonacciIntegerRangeEncoderTest.java @@ -43,7 +43,7 @@ public void testEncode4() { @Test public void testEncode5() { BitStringBuilder builder = new BitStringBuilder(); - IntegerSet set = new IntegerBitSet(); + IntegerSet set = new IntegerSet(); set.addAll(Arrays.asList(6, 7, 2, 5)); FibonacciIntegerRangeEncoder.encode(builder, set); Assertions.assertEquals("000000000010001110011011", builder.build().toString()); diff --git a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/datatype/encoder/FixedBitfieldEncoderTest.java b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/datatype/encoder/FixedBitfieldEncoderTest.java index a0549270..1a18454f 100644 --- a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/datatype/encoder/FixedBitfieldEncoderTest.java +++ b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/datatype/encoder/FixedBitfieldEncoderTest.java @@ -13,7 +13,7 @@ public class FixedBitfieldEncoderTest { @Test public void testEncode1() { BitStringBuilder builder = new BitStringBuilder(); - IntegerSet set = new IntegerBitSet(); + IntegerSet set = new IntegerSet(); FixedBitfieldEncoder.encode(builder, set, 2); Assertions.assertEquals("00", builder.build().toString()); } @@ -21,7 +21,7 @@ public void testEncode1() { @Test public void testEncode2() { BitStringBuilder builder = new BitStringBuilder(); - IntegerSet set = new IntegerBitSet(); + IntegerSet set = new IntegerSet(); FixedBitfieldEncoder.encode(builder, set, 1); Assertions.assertEquals("0", builder.build().toString()); } @@ -29,7 +29,7 @@ public void testEncode2() { @Test public void testEncode3() { BitStringBuilder builder = new BitStringBuilder(); - IntegerSet set = new IntegerBitSet(); + IntegerSet set = new IntegerSet(); set.add(0); FixedBitfieldEncoder.encode(builder, set, 1); Assertions.assertEquals("1", builder.build().toString()); @@ -38,7 +38,7 @@ public void testEncode3() { @Test public void testEncode4() { BitStringBuilder builder = new BitStringBuilder(); - IntegerSet set = new IntegerBitSet(); + IntegerSet set = new IntegerSet(); FixedBitfieldEncoder.encode(builder, set, 2); Assertions.assertEquals("00", builder.build().toString()); } @@ -46,7 +46,7 @@ public void testEncode4() { @Test public void testEncode5() { BitStringBuilder builder = new BitStringBuilder(); - IntegerSet set = new IntegerBitSet(); + IntegerSet set = new IntegerSet(); set.addInt(1); FixedBitfieldEncoder.encode(builder, set, 2); Assertions.assertEquals("01", builder.build().toString()); @@ -55,7 +55,7 @@ public void testEncode5() { @Test public void testEncode6() { BitStringBuilder builder = new BitStringBuilder(); - IntegerSet set = new IntegerBitSet(); + IntegerSet set = new IntegerSet(); set.addInt(0); FixedBitfieldEncoder.encode(builder, set, 2); Assertions.assertEquals("10", builder.build().toString()); @@ -64,7 +64,7 @@ public void testEncode6() { @Test public void testEncode7() { BitStringBuilder builder = new BitStringBuilder(); - IntegerSet set = new IntegerBitSet(); + IntegerSet set = new IntegerSet(); set.addInt(0); set.addInt(1); FixedBitfieldEncoder.encode(builder, set, 2); @@ -73,7 +73,7 @@ public void testEncode7() { @Test public void testEncode8() { - IntegerSet set = new IntegerBitSet(5); + IntegerSet set = new IntegerSet(5); for(int i = 0; i <= 10; i++) { set.addInt(i); } @@ -82,7 +82,7 @@ public void testEncode8() { @Test public void testEncode9() { - IntegerBitSet set = new IntegerBitSet(5); + IntegerSet set = new IntegerSet(5); set.addRange(0,10); Assertions.assertEquals(Set.of(0,1,2,3,4), set); } diff --git a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/datatype/encoder/FixedIntegerRangeEncoderTest.java b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/datatype/encoder/FixedIntegerRangeEncoderTest.java index 7fe4db47..7f187b7a 100644 --- a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/datatype/encoder/FixedIntegerRangeEncoderTest.java +++ b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/datatype/encoder/FixedIntegerRangeEncoderTest.java @@ -45,7 +45,7 @@ public void testEncode4() { @Test public void testEncode5() { BitStringBuilder builder = new BitStringBuilder(); - IntegerSet set = new IntegerBitSet(); + IntegerSet set = new IntegerSet(); set.addAll(Arrays.asList(6, 7, 2, 5)); FixedIntegerRangeEncoder.encode(builder, set); Assertions.assertEquals("00000000001000000000000000010100000000000001010000000000000111", From 15153777c4ff1ab7bc4fd13c0c2b3394b83e4a43 Mon Sep 17 00:00:00 2001 From: James Yuzawa Date: Tue, 13 Jan 2026 13:28:08 -0500 Subject: [PATCH 07/11] update tests --- .../iab/gpp/encoder/datatype/FixedList.java | 9 ++-- .../datatype/encoder/IntegerBitSet.java | 14 ------ .../datatype/FixedIntegerListTest.java | 32 ++++++++++++ .../gpp/encoder/datatype/FixedListTest.java | 33 ++++++++++++ .../datatype/encoder/IntegerSetTest.java | 50 +++++++++++++++++++ 5 files changed, 118 insertions(+), 20 deletions(-) delete mode 100644 iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/encoder/IntegerBitSet.java create mode 100644 iabgpp-encoder/src/test/java/com/iab/gpp/encoder/datatype/FixedIntegerListTest.java create mode 100644 iabgpp-encoder/src/test/java/com/iab/gpp/encoder/datatype/FixedListTest.java create mode 100644 iabgpp-encoder/src/test/java/com/iab/gpp/encoder/datatype/encoder/IntegerSetTest.java diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/FixedList.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/FixedList.java index 962feb0e..c5ea40c9 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/FixedList.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/FixedList.java @@ -4,7 +4,7 @@ import java.util.List; import com.iab.gpp.encoder.datatype.encoder.Dirtyable; -public final class FixedList extends AbstractList implements Dirtyable { +public final class FixedList extends AbstractList implements Dirtyable { private boolean dirty; private final List delegate; @@ -40,7 +40,7 @@ public boolean isDirty() { int size = delegate.size(); for (int i = 0; i < size; i++) { T value = delegate.get(i); - if (value instanceof Dirtyable && ((Dirtyable) value).isDirty()) { + if (value.isDirty()) { return true; } } @@ -51,10 +51,7 @@ public boolean isDirty() { public void setDirty(boolean dirty) { int size = delegate.size(); for (int i = 0; i < size; i++) { - T value = delegate.get(i); - if (value instanceof Dirtyable) { - ((Dirtyable) value).setDirty(dirty); - } + delegate.get(i).setDirty(dirty); } this.dirty = dirty; } diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/encoder/IntegerBitSet.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/encoder/IntegerBitSet.java deleted file mode 100644 index 6ae65a06..00000000 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/encoder/IntegerBitSet.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.iab.gpp.encoder.datatype.encoder; - -import java.util.AbstractSet; -import java.util.BitSet; -import java.util.Collection; -import java.util.NoSuchElementException; -import java.util.Spliterator; -import java.util.Spliterators; -import java.util.logging.Logger; -import java.util.PrimitiveIterator.OfInt; -import java.util.stream.IntStream; -import java.util.stream.StreamSupport; - - diff --git a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/datatype/FixedIntegerListTest.java b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/datatype/FixedIntegerListTest.java new file mode 100644 index 00000000..166c48e4 --- /dev/null +++ b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/datatype/FixedIntegerListTest.java @@ -0,0 +1,32 @@ +package com.iab.gpp.encoder.datatype; + +import static org.junit.jupiter.api.Assertions.*; +import java.util.List; +import org.junit.jupiter.api.Test; + +class FixedIntegerListTest { + + @Test + void test() { + FixedIntegerList list = new FixedIntegerList(5); + assertFalse(list.isDirty()); + list.set(0, 2); + list.set(1, 1); + list.set(2, 5); + list.set(3, 8); + list.set(4, 3); + assertThrows(IllegalArgumentException.class, () -> list.set(4, Integer.MAX_VALUE)); + assertThrows(IllegalArgumentException.class, () -> list.set(4, -1)); + assertEquals(5, list.size()); + assertEquals(List.of(2,1,5,8,3), list); + assertEquals(2, list.get(0)); + assertEquals(1, list.get(1)); + assertEquals(5, list.get(2)); + assertEquals(8, list.get(3)); + assertEquals(3, list.get(4)); + assertTrue(list.isDirty()); + list.setDirty(false); + assertFalse(list.isDirty()); + } + +} diff --git a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/datatype/FixedListTest.java b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/datatype/FixedListTest.java new file mode 100644 index 00000000..ad1c14b7 --- /dev/null +++ b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/datatype/FixedListTest.java @@ -0,0 +1,33 @@ +package com.iab.gpp.encoder.datatype; + +import static org.junit.jupiter.api.Assertions.*; +import java.util.Arrays; +import java.util.List; +import java.util.Set; +import org.junit.jupiter.api.Test; + +class FixedListTest { + + @Test + void test() { + RangeEntry item1 = new RangeEntry(1, 2, Set.of(3,4,5)); + RangeEntry item2 = new RangeEntry(6, 7, Set.of(8,9,10)); + RangeEntry item3 = new RangeEntry(11, 12, Set.of(13,14,15)); + FixedList list = new FixedList<>(Arrays.asList(new RangeEntry[] {item1, item2, item3})); + assertEquals(List.of(item1, item2, item3), list); + assertEquals(item1, list.get(0)); + assertEquals(item2, list.get(1)); + assertEquals(item3, list.get(2)); + assertEquals(3, list.size()); + assertFalse(list.isEmpty()); + assertTrue(list.isDirty()); + list.setDirty(false); + assertFalse(list.isDirty()); + item2.getIds().remove(9); + assertTrue(list.isDirty()); + RangeEntry item2a = new RangeEntry(100, 200, Set.of(300,400,500)); + assertEquals(item2, list.set(1, item2a)); + assertEquals(item2a, list.get(1)); + } + +} diff --git a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/datatype/encoder/IntegerSetTest.java b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/datatype/encoder/IntegerSetTest.java new file mode 100644 index 00000000..7d4cdb3c --- /dev/null +++ b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/datatype/encoder/IntegerSetTest.java @@ -0,0 +1,50 @@ +package com.iab.gpp.encoder.datatype.encoder; + +import static org.junit.jupiter.api.Assertions.*; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Set; +import org.junit.jupiter.api.Test; + +class IntegerSetTest { + + @Test + void test() { + IntegerSet set = new IntegerSet(5); + assertFalse(set.isDirty()); + assertTrue(set.isEmpty()); + set.add(0); + set.add(2); + set.add(3); + assertEquals(Set.of(0,2,3), set); + assertTrue(set.isDirty()); + assertFalse(set.isEmpty()); + assertEquals(3, set.size()); + assertFalse(set.remove(1)); + assertTrue(set.remove(2)); + assertEquals(2, set.size()); + set.addAll(List.of(3,4)); + assertEquals(Set.of(0,3,4), set); + List out = new ArrayList<>(); + Iterator it = set.iterator(); + it.forEachRemaining(out::add); + assertEquals(List.of(0,3,4), out); + assertFalse(set.contains(2)); + assertTrue(set.contains(3)); + assertTrue(set.isDirty()); + set.setDirty(false); + assertFalse(set.isDirty()); + set.retainAll(Set.of(1,2,3)); + assertEquals(Set.of(3), set); + assertTrue(set.addAll(List.of(1,3,4))); + assertFalse(set.addAll(List.of(1,3,4))); + assertTrue(set.removeAll(List.of(3,4))); + assertEquals(Set.of(1), set); + set.clear(); + assertTrue(set.isEmpty()); + set.addRange(1, 3); + assertEquals(Set.of(1,2), set); + } + +} From 74870a8c995bcfe76cf9aca0c845ff4c4ce14946 Mon Sep 17 00:00:00 2001 From: James Yuzawa Date: Tue, 13 Jan 2026 14:26:53 -0500 Subject: [PATCH 08/11] fixed signed byte int limit --- .../java/com/iab/gpp/encoder/datatype/FixedIntegerList.java | 5 +++-- .../com/iab/gpp/encoder/datatype/FixedIntegerListTest.java | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/FixedIntegerList.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/FixedIntegerList.java index 3d04802b..4ad15042 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/FixedIntegerList.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/FixedIntegerList.java @@ -33,8 +33,9 @@ public Integer set(int index, Integer value) { } public int setInt(int index, int value) { - if(value < 0 || value > 0xff) { - throw new IllegalArgumentException("FixedIntegerList only supports positive integers less than 256."); + // NOTE: int 128 is prevented since it would get turned into byte -128 + if(value < 0 || value > 128) { + throw new IllegalArgumentException("FixedIntegerList only supports positive integers less than 128."); } int prior = array[index]; array[index] = (byte) value; diff --git a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/datatype/FixedIntegerListTest.java b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/datatype/FixedIntegerListTest.java index 166c48e4..6aee9b3e 100644 --- a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/datatype/FixedIntegerListTest.java +++ b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/datatype/FixedIntegerListTest.java @@ -15,7 +15,7 @@ void test() { list.set(2, 5); list.set(3, 8); list.set(4, 3); - assertThrows(IllegalArgumentException.class, () -> list.set(4, Integer.MAX_VALUE)); + assertThrows(IllegalArgumentException.class, () -> list.set(4, 128)); assertThrows(IllegalArgumentException.class, () -> list.set(4, -1)); assertEquals(5, list.size()); assertEquals(List.of(2,1,5,8,3), list); From 92cbd01d0c8b2d4e8cc9f4504e0bdee874ff1021 Mon Sep 17 00:00:00 2001 From: James Yuzawa Date: Tue, 13 Jan 2026 14:42:57 -0500 Subject: [PATCH 09/11] javadoc --- .../java/com/iab/gpp/encoder/datatype/FixedIntegerList.java | 4 ++++ .../java/com/iab/gpp/encoder/datatype/encoder/IntegerSet.java | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/FixedIntegerList.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/FixedIntegerList.java index 4ad15042..c463f0c7 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/FixedIntegerList.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/FixedIntegerList.java @@ -4,6 +4,10 @@ import java.util.Arrays; import com.iab.gpp.encoder.datatype.encoder.Dirtyable; +/** + * An optimized implementation of {@literal List} of fixed size. + * Use {@link #getInt(int)} and {@link #setInt(int, int)} for efficient access. + */ public final class FixedIntegerList extends AbstractList implements Dirtyable { private boolean dirty; diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/encoder/IntegerSet.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/encoder/IntegerSet.java index 387f35fe..340252e8 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/encoder/IntegerSet.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/encoder/IntegerSet.java @@ -11,6 +11,10 @@ import java.util.stream.IntStream; import java.util.stream.StreamSupport; +/** + * An optimized implementation of {@literal Set} backed by a {@link java.util.BitSet}. + * Use {@link #containsInt(int)}, {@link #addInt(int)}, and {@link #removeInt(int)} for efficient access. + */ public final class IntegerSet extends AbstractSet implements Dirtyable { private static final Logger LOGGER = Logger.getLogger(IntegerSet.class.getName()); From 5070310e556a7643c9617fc9a166125b02b5a763 Mon Sep 17 00:00:00 2001 From: James Yuzawa Date: Tue, 13 Jan 2026 15:23:35 -0500 Subject: [PATCH 10/11] DirtyableList --- .../gpp/encoder/datatype/DirtyableList.java | 103 ++++++++++++++++++ .../EncodableArrayOfFixedIntegerRanges.java | 17 +-- .../iab/gpp/encoder/datatype/FixedList.java | 58 ---------- .../iab/gpp/encoder/datatype/RangeEntry.java | 12 +- ...edListTest.java => DirtyableListTest.java} | 11 +- 5 files changed, 126 insertions(+), 75 deletions(-) create mode 100644 iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/DirtyableList.java delete mode 100644 iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/FixedList.java rename iabgpp-encoder/src/test/java/com/iab/gpp/encoder/datatype/{FixedListTest.java => DirtyableListTest.java} (75%) diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/DirtyableList.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/DirtyableList.java new file mode 100644 index 00000000..dffbb74d --- /dev/null +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/DirtyableList.java @@ -0,0 +1,103 @@ +package com.iab.gpp.encoder.datatype; + +import java.util.AbstractList; +import java.util.ArrayList; +import java.util.Collection; +import com.iab.gpp.encoder.datatype.encoder.Dirtyable; + +// This class tracks whether a list has been modified. +final class DirtyableList extends AbstractList implements Dirtyable { + + private boolean dirty; + private final ArrayList delegate; + + DirtyableList() { + this.delegate = new ArrayList<>(); + } + + @Override + public int size() { + return delegate.size(); + } + + @Override + public boolean add(T value) { + boolean result = delegate.add(value); + dirty = true; + return result; + } + + @Override + public T get(int index) { + return delegate.get(index); + } + + @Override + public T set(int index, T value) { + T prior = delegate.set(index, value); + dirty = true; + return prior; + } + + @Override + public void add(int index, T element) { + delegate.add(index, element); + dirty = true; + } + + @Override + public T remove(int index) { + T old = delegate.remove(index); + dirty = true; + return old; + } + + @Override + public int indexOf(Object o) { + return delegate.indexOf(o); + } + + @Override + public int lastIndexOf(Object o) { + return delegate.lastIndexOf(o); + } + + @Override + public void clear() { + delegate.clear(); + dirty = true; + } + + @Override + public boolean addAll(Collection c) { + boolean result = delegate.addAll(c); + dirty = true; + return result; + } + + @Override + public String toString() { + return delegate.toString(); + } + + @Override + public boolean isDirty() { + int size = delegate.size(); + for (int i = 0; i < size; i++) { + T value = delegate.get(i); + if (value.isDirty()) { + return true; + } + } + return dirty; + } + + @Override + public void setDirty(boolean dirty) { + int size = delegate.size(); + for (int i = 0; i < size; i++) { + delegate.get(i).setDirty(dirty); + } + this.dirty = dirty; + } +} diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableArrayOfFixedIntegerRanges.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableArrayOfFixedIntegerRanges.java index b1035592..b76026d1 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableArrayOfFixedIntegerRanges.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableArrayOfFixedIntegerRanges.java @@ -1,6 +1,5 @@ package com.iab.gpp.encoder.datatype; -import java.util.Arrays; import java.util.List; import com.iab.gpp.encoder.bitstring.BitString; @@ -11,18 +10,16 @@ import com.iab.gpp.encoder.error.DecodingException; import com.iab.gpp.encoder.error.EncodingException; -public final class EncodableArrayOfFixedIntegerRanges extends AbstractDirtyableBitStringDataType> { +public final class EncodableArrayOfFixedIntegerRanges extends AbstractDirtyableBitStringDataType> { private int keyBitStringLength; private int typeBitStringLength; - private static final FixedList EMPTY = new FixedList<>(List.of()); - public EncodableArrayOfFixedIntegerRanges(int keyBitStringLength, int typeBitStringLength, boolean hardFailIfMissing) { super(hardFailIfMissing); this.keyBitStringLength = keyBitStringLength; this.typeBitStringLength = typeBitStringLength; - this.value = EMPTY; + this.value = new DirtyableList<>(); } @Override @@ -46,7 +43,7 @@ public void encode(BitStringBuilder sb) { public void decode(BitString bitString) { try { int size = FixedIntegerEncoder.decode(bitString, 0, 12); - RangeEntry[] entries = new RangeEntry[size]; + value.clear(); int index = 12; for (int i = 0; i < size; i++) { int key = FixedIntegerEncoder.decode(bitString, index, keyBitStringLength); @@ -60,11 +57,8 @@ public void decode(BitString bitString) { index += substring.length(); RangeEntry entry = new RangeEntry(key, type, ids); - entries[i] = entry; + value.add(entry); } - - // NOTE: this requires that adding/removing ranges uses the setter - this.value = new FixedList<>(Arrays.asList(entries)); } catch (Exception e) { throw new DecodingException(e); } @@ -103,6 +97,7 @@ public BitString substring(BitString bitString, int fromIndex) throws SubstringE @SuppressWarnings("unchecked") @Override public void setValue(Object value) { - super.setValue(new FixedList<>((List) value)); + this.value.clear(); + this.value.addAll((List) value); } } diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/FixedList.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/FixedList.java deleted file mode 100644 index c5ea40c9..00000000 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/FixedList.java +++ /dev/null @@ -1,58 +0,0 @@ -package com.iab.gpp.encoder.datatype; - -import java.util.AbstractList; -import java.util.List; -import com.iab.gpp.encoder.datatype.encoder.Dirtyable; - -public final class FixedList extends AbstractList implements Dirtyable { - - private boolean dirty; - private final List delegate; - - FixedList(List delegate) { - this.delegate = delegate; - } - - @Override - public int size() { - return delegate.size(); - } - - @Override - public T get(int index) { - return delegate.get(index); - } - - @Override - public T set(int index, T value) { - T prior = delegate.set(index, value); - dirty = true; - return prior; - } - - @Override - public String toString() { - return delegate.toString(); - } - - @Override - public boolean isDirty() { - int size = delegate.size(); - for (int i = 0; i < size; i++) { - T value = delegate.get(i); - if (value.isDirty()) { - return true; - } - } - return dirty; - } - - @Override - public void setDirty(boolean dirty) { - int size = delegate.size(); - for (int i = 0; i < size; i++) { - delegate.get(i).setDirty(dirty); - } - this.dirty = dirty; - } -} diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/RangeEntry.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/RangeEntry.java index 29e33eed..027934f8 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/RangeEntry.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/RangeEntry.java @@ -1,18 +1,17 @@ package com.iab.gpp.encoder.datatype; import java.util.Collection; -import java.util.Set; import com.iab.gpp.encoder.datatype.encoder.Dirtyable; import com.iab.gpp.encoder.datatype.encoder.IntegerSet; -public class RangeEntry implements Dirtyable { +public final class RangeEntry implements Dirtyable { private boolean dirty; private int key; private int type; private final IntegerSet ids; - public RangeEntry(int key, int type, Set ids) { + public RangeEntry(int key, int type, Collection ids) { super(); this.key = key; this.type = type; @@ -20,6 +19,13 @@ public RangeEntry(int key, int type, Set ids) { this.ids.addAll(ids); } + RangeEntry(int key, int type, IntegerSet ids) { + super(); + this.key = key; + this.type = type; + this.ids = ids; + } + public int getKey() { return key; } diff --git a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/datatype/FixedListTest.java b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/datatype/DirtyableListTest.java similarity index 75% rename from iabgpp-encoder/src/test/java/com/iab/gpp/encoder/datatype/FixedListTest.java rename to iabgpp-encoder/src/test/java/com/iab/gpp/encoder/datatype/DirtyableListTest.java index ad1c14b7..dbbc28b0 100644 --- a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/datatype/FixedListTest.java +++ b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/datatype/DirtyableListTest.java @@ -1,19 +1,20 @@ package com.iab.gpp.encoder.datatype; import static org.junit.jupiter.api.Assertions.*; -import java.util.Arrays; import java.util.List; import java.util.Set; import org.junit.jupiter.api.Test; -class FixedListTest { +class DirtyableListTest { @Test void test() { RangeEntry item1 = new RangeEntry(1, 2, Set.of(3,4,5)); RangeEntry item2 = new RangeEntry(6, 7, Set.of(8,9,10)); RangeEntry item3 = new RangeEntry(11, 12, Set.of(13,14,15)); - FixedList list = new FixedList<>(Arrays.asList(new RangeEntry[] {item1, item2, item3})); + DirtyableList list = new DirtyableList<>(); + list.add(item1); + list.addAll(List.of(item2, item3)); assertEquals(List.of(item1, item2, item3), list); assertEquals(item1, list.get(0)); assertEquals(item2, list.get(1)); @@ -28,6 +29,10 @@ void test() { RangeEntry item2a = new RangeEntry(100, 200, Set.of(300,400,500)); assertEquals(item2, list.set(1, item2a)); assertEquals(item2a, list.get(1)); + assertEquals(item3, list.remove(2)); + assertEquals(2, list.size()); + list.add(item3); + assertEquals(List.of(item1, item2a, item3), list); } } From 06f6c2843abe35ecc0c026b3850f2addfc3cb92b Mon Sep 17 00:00:00 2001 From: James Yuzawa Date: Tue, 13 Jan 2026 15:25:04 -0500 Subject: [PATCH 11/11] fix test --- .../java/com/iab/gpp/encoder/datatype/FixedIntegerList.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/FixedIntegerList.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/FixedIntegerList.java index c463f0c7..9e6176e4 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/FixedIntegerList.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/FixedIntegerList.java @@ -38,7 +38,7 @@ public Integer set(int index, Integer value) { public int setInt(int index, int value) { // NOTE: int 128 is prevented since it would get turned into byte -128 - if(value < 0 || value > 128) { + if(value < 0 || value >= 128) { throw new IllegalArgumentException("FixedIntegerList only supports positive integers less than 128."); } int prior = array[index];