From a6b7d994de12e3384c85427bef190402386a4334 Mon Sep 17 00:00:00 2001 From: James Yuzawa Date: Thu, 26 Feb 2026 16:27:00 -0500 Subject: [PATCH 01/15] support subsection headers --- .../com/iab/gpp/encoder/field/UsInField.java | 63 +++++++++++++ .../section/AbstractUsSectionWithHeader.java | 55 ++++++++++++ .../com/iab/gpp/encoder/section/UsIn.java | 88 +++++++++++++++++++ .../segment/AbstractBase64Segment.java | 4 +- .../AbstractLazilyEncodableSegment.java | 9 +- .../gpp/encoder/segment/Base64Segment.java | 6 +- .../gpp/encoder/segment/EncodableSegment.java | 2 + .../segment/TraditionalBase64Segment.java | 6 +- .../gpp/encoder/segment/UsNatCoreSegment.java | 2 +- .../gpp/encoder/segment/UspV1CoreSegment.java | 2 +- 10 files changed, 230 insertions(+), 7 deletions(-) create mode 100644 iabgpp-encoder/src/main/java/com/iab/gpp/encoder/field/UsInField.java create mode 100644 iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/AbstractUsSectionWithHeader.java create mode 100644 iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsIn.java diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/field/UsInField.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/field/UsInField.java new file mode 100644 index 0000000..c756b17 --- /dev/null +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/field/UsInField.java @@ -0,0 +1,63 @@ +package com.iab.gpp.encoder.field; + +import com.iab.gpp.encoder.datatype.DataType; +import com.iab.gpp.encoder.datatype.EncodableFibonacciIntegerRange; +import com.iab.gpp.encoder.datatype.EncodableFixedInteger; +import com.iab.gpp.encoder.datatype.EncodableFixedIntegerList; +import com.iab.gpp.encoder.section.UsIn; + +public enum UsInField implements FieldKey { + SECTION_ID(new EncodableFixedInteger<>("SectionID", 6, UsIn.ID)), + VERSION(new EncodableFixedInteger<>("Version", 6, UsIn.VERSION)), + SUB_SECTIONS(new EncodableFibonacciIntegerRange<>("SubSections")), + + MSPA_VERSION(new EncodableFixedInteger<>("MspaVersion", 6, 0)), + MSPA_COVERED_TRANSACTION( + new EncodableFixedInteger<>("MspaCoveredTransaction", 2, 1, VALIDATOR_12)), + MSPA_MODE(new EncodableFixedInteger<>("MspaMode", 2, 0, VALIDATOR_012)), + PROCESSING_NOTICE(new EncodableFixedInteger<>("ProcessingNotice", 2, 0, VALIDATOR_012)), + SALE_OPT_OUT_NOTICE(new EncodableFixedInteger<>("SaleOptOutNotice", 2, 0, VALIDATOR_012)), + TARGETED_ADVERTISING_OPT_OUT_NOTICE( + new EncodableFixedInteger<>("TargetedAdvertisingOptOutNotice", 2, 0, VALIDATOR_012)), + SALE_OPT_OUT(new EncodableFixedInteger<>("SaleOptOut", 2, 0, VALIDATOR_012)), + TARGETED_ADVERTISING_OPT_OUT( + new EncodableFixedInteger<>("TargetedAdvertisingOptOut", 2, 0, VALIDATOR_012)), + KNOWN_CHILD_SENSITIVE_DATA_CONSENTS( + new EncodableFixedInteger<>("KnownChildSensitiveDataConsents", 2, 0, VALIDATOR_012)), + ADDITIONAL_DATA_PROCESSING_CONSENT( + new EncodableFixedInteger<>("AdditionalDataProcessingConsent", 2, 0, VALIDATOR_012)), + + SENSITIVE_DATA_PROCESSING( + new EncodableFixedIntegerList<>("SensitiveDataProcessing", 2, 8, VALIDATOR_LIST_012)); + + private final DataType type; + + UsInField(DataType type) { + this.type = type; + } + + @Override + public DataType getType() { + return type; + } + + public static final FieldNames USIN_HEADER_SEGMENT_FIELD_NAMES = + new FieldNames<>(UsInField.SECTION_ID, UsInField.VERSION, UsInField.SUB_SECTIONS); + + public static final FieldNames USIN_CORE_SEGMENT_FIELD_NAMES = + new FieldNames<>( + UsInField.MSPA_VERSION, + UsInField.MSPA_COVERED_TRANSACTION, + UsInField.MSPA_MODE, + UsInField.PROCESSING_NOTICE, + UsInField.SALE_OPT_OUT_NOTICE, + UsInField.TARGETED_ADVERTISING_OPT_OUT_NOTICE, + UsInField.SALE_OPT_OUT, + UsInField.TARGETED_ADVERTISING_OPT_OUT, + UsInField.SENSITIVE_DATA_PROCESSING, + UsInField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS, + UsInField.ADDITIONAL_DATA_PROCESSING_CONSENT); + + public static final FieldNames USIN_SENSITIVE_DATA_CONSENTS_SEGMENT_FIELD_NAMES = + new FieldNames<>(UsInField.SENSITIVE_DATA_PROCESSING); +} diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/AbstractUsSectionWithHeader.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/AbstractUsSectionWithHeader.java new file mode 100644 index 0000000..e3b2546 --- /dev/null +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/AbstractUsSectionWithHeader.java @@ -0,0 +1,55 @@ +package com.iab.gpp.encoder.section; + +import com.iab.gpp.encoder.datatype.IntegerSet; +import com.iab.gpp.encoder.field.FieldKey; +import com.iab.gpp.encoder.segment.EncodableSegment; +import java.util.ArrayList; +import java.util.List; +import java.util.PrimitiveIterator; + +public abstract class AbstractUsSectionWithHeader & FieldKey> + extends AbstractUsSection { + + @SafeVarargs + protected AbstractUsSectionWithHeader(EncodableSegment... segments) { + super(segments); + } + + protected abstract E getSubSectionsKey(); + + public IntegerSet getSubSections() { + return (IntegerSet) getSegment(0).getFieldValue(getSubSectionsKey()); + } + + @Override + protected final void doDecode(CharSequence encodedString) { + List encodedSegments = SlicedCharSequence.split(encodedString, '.'); + getSegment(0).decode(encodedSegments.get(0)); + IntegerSet subSections = getSubSections(); + PrimitiveIterator.OfInt it = subSections.iterator(); + while (it.hasNext()) { + int subSectionIndex = 1 + it.nextInt(); + getSegment(subSectionIndex).decode(encodedSegments.get(subSectionIndex)); + } + } + + @Override + protected final CharSequence doEncode() { + int size = size(); + List encodedSegments = new ArrayList<>(size); + IntegerSet subSections = getSubSections(); + for (int i = 1; i < size(); i++) { + EncodableSegment segment = getSegment(i); + if (!segment.isOptional() || segment.isDirty()) { + subSections.add(i - 1); + } + } + encodedSegments.add(getSegment(0).encodeCharSequence()); + PrimitiveIterator.OfInt it = subSections.iterator(); + while (it.hasNext()) { + int subSectionIndex = 1 + it.nextInt(); + encodedSegments.add(getSegment(subSectionIndex).encodeCharSequence()); + } + return SlicedCharSequence.join('.', encodedSegments); + } +} diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsIn.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsIn.java new file mode 100644 index 0000000..e4cfe8f --- /dev/null +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsIn.java @@ -0,0 +1,88 @@ +package com.iab.gpp.encoder.section; + +import com.iab.gpp.encoder.datatype.FixedIntegerList; +import com.iab.gpp.encoder.field.UsInField; +import com.iab.gpp.encoder.segment.Base64Segment; + +public class UsIn extends AbstractUsSectionWithHeader { + + public static final int ID = 25; + public static final int VERSION = 1; + public static final String NAME = "usin"; + + public UsIn() { + super( + new Base64Segment<>(UsInField.USIN_HEADER_SEGMENT_FIELD_NAMES), + new Base64Segment<>(UsInField.USIN_CORE_SEGMENT_FIELD_NAMES), + new Base64Segment<>(UsInField.USIN_SENSITIVE_DATA_CONSENTS_SEGMENT_FIELD_NAMES, true)); + } + + public UsIn(String encodedString) { + this(); + decode(encodedString); + } + + @Override + public int getId() { + return UsIn.ID; + } + + @Override + public String getName() { + return UsIn.NAME; + } + + @Override + public int getVersion() { + return UsIn.VERSION; + } + + @Override + protected final UsInField getSubSectionsKey() { + return UsInField.SUB_SECTIONS; + } + + public Integer getMspaVersion() { + return (Integer) this.getFieldValue(UsInField.MSPA_VERSION); + } + + public Integer getMspaCoveredTransaction() { + return (Integer) this.getFieldValue(UsInField.MSPA_COVERED_TRANSACTION); + } + + public Integer getMspaMode() { + return (Integer) this.getFieldValue(UsInField.MSPA_MODE); + } + + public Integer getProcessingNotice() { + return (Integer) this.getFieldValue(UsInField.PROCESSING_NOTICE); + } + + public Integer getSaleOptOutNotice() { + return (Integer) this.getFieldValue(UsInField.SALE_OPT_OUT_NOTICE); + } + + public Integer getTargetedAdvertisingOptOutNotice() { + return (Integer) this.getFieldValue(UsInField.TARGETED_ADVERTISING_OPT_OUT_NOTICE); + } + + public Integer getSaleOptOut() { + return (Integer) this.getFieldValue(UsInField.SALE_OPT_OUT); + } + + public Integer getTargetedAdvertisingOptOut() { + return (Integer) this.getFieldValue(UsInField.TARGETED_ADVERTISING_OPT_OUT); + } + + public Integer getKnownChildSensitiveDataConsents() { + return (Integer) this.getFieldValue(UsInField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS); + } + + public Integer getAdditionalDataProcessingConsent() { + return (Integer) this.getFieldValue(UsInField.ADDITIONAL_DATA_PROCESSING_CONSENT); + } + + public FixedIntegerList getSensitiveDataProcessing() { + return (FixedIntegerList) this.getFieldValue(UsInField.SENSITIVE_DATA_PROCESSING); + } +} diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/AbstractBase64Segment.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/AbstractBase64Segment.java index 090651a..ce5fc8d 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/AbstractBase64Segment.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/AbstractBase64Segment.java @@ -11,8 +11,8 @@ abstract class AbstractBase64Segment & FieldKey> extends AbstractLazilyEncodableSegment { - protected AbstractBase64Segment(FieldNames fieldNames) { - super(fieldNames); + protected AbstractBase64Segment(FieldNames fieldNames, boolean optional) { + super(fieldNames, optional); } protected abstract AbstractBase64UrlEncoder getBase64UrlEncoder(); 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 e6386ca..aa58541 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 @@ -9,11 +9,18 @@ abstract class AbstractLazilyEncodableSegment & FieldKey> protected final FieldNames fieldNames; protected final Object[] values; + private boolean optional; private boolean dirty; - protected AbstractLazilyEncodableSegment(FieldNames fieldNames) { + protected AbstractLazilyEncodableSegment(FieldNames fieldNames, boolean optional) { this.fieldNames = fieldNames; this.values = new Object[fieldNames.size()]; + this.optional = optional; + } + + @Override + public final boolean isOptional() { + return optional; } @Override diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/Base64Segment.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/Base64Segment.java index 181e187..c5aff71 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/Base64Segment.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/Base64Segment.java @@ -7,8 +7,12 @@ public final class Base64Segment & FieldKey> extends AbstractBase64Segment { + public Base64Segment(FieldNames fieldNames, boolean optional) { + super(fieldNames, optional); + } + public Base64Segment(FieldNames fieldNames) { - super(fieldNames); + this(fieldNames, false); } protected AbstractBase64UrlEncoder getBase64UrlEncoder() { diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/EncodableSegment.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/EncodableSegment.java index 30654a4..e072bbd 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/EncodableSegment.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/EncodableSegment.java @@ -13,4 +13,6 @@ public abstract class EncodableSegment & FieldKey> extends Abs protected abstract Object getFieldValueUnsafe(E key); public abstract void setFieldValue(E fieldName, Object value); + + public abstract boolean isOptional(); } diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/TraditionalBase64Segment.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/TraditionalBase64Segment.java index 5b2610b..66c6d33 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/TraditionalBase64Segment.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/TraditionalBase64Segment.java @@ -8,8 +8,12 @@ public final class TraditionalBase64Segment & FieldKey> extends AbstractBase64Segment { + public TraditionalBase64Segment(FieldNames fieldNames, boolean optional) { + super(fieldNames, optional); + } + public TraditionalBase64Segment(FieldNames fieldNames) { - super(fieldNames); + this(fieldNames, false); } protected AbstractBase64UrlEncoder getBase64UrlEncoder() { 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 c69cb9f..0907035 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 @@ -10,7 +10,7 @@ public final class UsNatCoreSegment extends AbstractBase64Segment { private static final int VERSION_LENGTH = 6; public UsNatCoreSegment() { - super(UsNatField.USNAT_CORE_SEGMENT_FIELD_NAMES); + super(UsNatField.USNAT_CORE_SEGMENT_FIELD_NAMES, false); } protected AbstractBase64UrlEncoder getBase64UrlEncoder() { diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UspV1CoreSegment.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UspV1CoreSegment.java index 9defd65..b845f92 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UspV1CoreSegment.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UspV1CoreSegment.java @@ -6,7 +6,7 @@ public final class UspV1CoreSegment extends AbstractLazilyEncodableSegment { public UspV1CoreSegment() { - super(UspV1Field.USPV1_CORE_SEGMENT_FIELD_NAMES); + super(UspV1Field.USPV1_CORE_SEGMENT_FIELD_NAMES, false); } @Override From 1f7ed2d8d5accfa4dc00af8fe90eae32985c4b6f Mon Sep 17 00:00:00 2001 From: James Yuzawa Date: Fri, 6 Mar 2026 13:59:57 -0500 Subject: [PATCH 02/15] add more states --- .../java/com/iab/gpp/encoder/GppModel.java | 8 ++ .../com/iab/gpp/encoder/field/UsInField.java | 1 - .../com/iab/gpp/encoder/field/UsKyField.java | 62 +++++++++++++ .../com/iab/gpp/encoder/field/UsMdField.java | 59 +++++++++++++ .../com/iab/gpp/encoder/field/UsRiField.java | 62 +++++++++++++ .../com/iab/gpp/encoder/section/UsKy.java | 88 +++++++++++++++++++ .../com/iab/gpp/encoder/section/UsMd.java | 83 +++++++++++++++++ .../com/iab/gpp/encoder/section/UsRi.java | 88 +++++++++++++++++++ 8 files changed, 450 insertions(+), 1 deletion(-) create mode 100644 iabgpp-encoder/src/main/java/com/iab/gpp/encoder/field/UsKyField.java create mode 100644 iabgpp-encoder/src/main/java/com/iab/gpp/encoder/field/UsMdField.java create mode 100644 iabgpp-encoder/src/main/java/com/iab/gpp/encoder/field/UsRiField.java create mode 100644 iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsKy.java create mode 100644 iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsMd.java create mode 100644 iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsRi.java diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/GppModel.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/GppModel.java index 0a2f294..83427bf 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/GppModel.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/GppModel.java @@ -15,6 +15,9 @@ import com.iab.gpp.encoder.section.UsDe; import com.iab.gpp.encoder.section.UsFl; import com.iab.gpp.encoder.section.UsIa; +import com.iab.gpp.encoder.section.UsIn; +import com.iab.gpp.encoder.section.UsKy; +import com.iab.gpp.encoder.section.UsMd; import com.iab.gpp.encoder.section.UsMn; import com.iab.gpp.encoder.section.UsMt; import com.iab.gpp.encoder.section.UsNat; @@ -22,6 +25,7 @@ import com.iab.gpp.encoder.section.UsNh; import com.iab.gpp.encoder.section.UsNj; import com.iab.gpp.encoder.section.UsOr; +import com.iab.gpp.encoder.section.UsRi; import com.iab.gpp.encoder.section.UsTn; import com.iab.gpp.encoder.section.UsTx; import com.iab.gpp.encoder.section.UsUt; @@ -64,6 +68,10 @@ public class GppModel extends AbstractEncodable { constructors.add(UsNj::new); constructors.add(UsTn::new); constructors.add(UsMn::new); + constructors.add(UsIn::new); + constructors.add(UsMd::new); + constructors.add(UsKy::new); + constructors.add(UsRi::new); for (Supplier> constructor : constructors) { EncodableSection prototype = constructor.get(); diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/field/UsInField.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/field/UsInField.java index c756b17..fcf1056 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/field/UsInField.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/field/UsInField.java @@ -54,7 +54,6 @@ public enum UsInField implements FieldKey { UsInField.TARGETED_ADVERTISING_OPT_OUT_NOTICE, UsInField.SALE_OPT_OUT, UsInField.TARGETED_ADVERTISING_OPT_OUT, - UsInField.SENSITIVE_DATA_PROCESSING, UsInField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS, UsInField.ADDITIONAL_DATA_PROCESSING_CONSENT); diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/field/UsKyField.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/field/UsKyField.java new file mode 100644 index 0000000..e320a14 --- /dev/null +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/field/UsKyField.java @@ -0,0 +1,62 @@ +package com.iab.gpp.encoder.field; + +import com.iab.gpp.encoder.datatype.DataType; +import com.iab.gpp.encoder.datatype.EncodableFibonacciIntegerRange; +import com.iab.gpp.encoder.datatype.EncodableFixedInteger; +import com.iab.gpp.encoder.datatype.EncodableFixedIntegerList; +import com.iab.gpp.encoder.section.UsIn; + +public enum UsKyField implements FieldKey { + SECTION_ID(new EncodableFixedInteger<>("SectionID", 6, UsIn.ID)), + VERSION(new EncodableFixedInteger<>("Version", 6, UsIn.VERSION)), + SUB_SECTIONS(new EncodableFibonacciIntegerRange<>("SubSections")), + + MSPA_VERSION(new EncodableFixedInteger<>("MspaVersion", 6, 0)), + MSPA_COVERED_TRANSACTION( + new EncodableFixedInteger<>("MspaCoveredTransaction", 2, 1, VALIDATOR_12)), + MSPA_MODE(new EncodableFixedInteger<>("MspaMode", 2, 0, VALIDATOR_012)), + PROCESSING_NOTICE(new EncodableFixedInteger<>("ProcessingNotice", 2, 0, VALIDATOR_012)), + SALE_OPT_OUT_NOTICE(new EncodableFixedInteger<>("SaleOptOutNotice", 2, 0, VALIDATOR_012)), + TARGETED_ADVERTISING_OPT_OUT_NOTICE( + new EncodableFixedInteger<>("TargetedAdvertisingOptOutNotice", 2, 0, VALIDATOR_012)), + SALE_OPT_OUT(new EncodableFixedInteger<>("SaleOptOut", 2, 0, VALIDATOR_012)), + TARGETED_ADVERTISING_OPT_OUT( + new EncodableFixedInteger<>("TargetedAdvertisingOptOut", 2, 0, VALIDATOR_012)), + KNOWN_CHILD_SENSITIVE_DATA_CONSENTS( + new EncodableFixedInteger<>("KnownChildSensitiveDataConsents", 2, 0, VALIDATOR_012)), + ADDITIONAL_DATA_PROCESSING_CONSENT( + new EncodableFixedInteger<>("AdditionalDataProcessingConsent", 2, 0, VALIDATOR_012)), + + SENSITIVE_DATA_PROCESSING( + new EncodableFixedIntegerList<>("SensitiveDataProcessing", 2, 8, VALIDATOR_LIST_012)); + + private final DataType type; + + UsKyField(DataType type) { + this.type = type; + } + + @Override + public DataType getType() { + return type; + } + + public static final FieldNames USKY_HEADER_SEGMENT_FIELD_NAMES = + new FieldNames<>(UsKyField.SECTION_ID, UsKyField.VERSION, UsKyField.SUB_SECTIONS); + + public static final FieldNames USKY_CORE_SEGMENT_FIELD_NAMES = + new FieldNames<>( + UsKyField.MSPA_VERSION, + UsKyField.MSPA_COVERED_TRANSACTION, + UsKyField.MSPA_MODE, + UsKyField.PROCESSING_NOTICE, + UsKyField.SALE_OPT_OUT_NOTICE, + UsKyField.TARGETED_ADVERTISING_OPT_OUT_NOTICE, + UsKyField.SALE_OPT_OUT, + UsKyField.TARGETED_ADVERTISING_OPT_OUT, + UsKyField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS, + UsKyField.ADDITIONAL_DATA_PROCESSING_CONSENT); + + public static final FieldNames USKY_SENSITIVE_DATA_CONSENTS_SEGMENT_FIELD_NAMES = + new FieldNames<>(UsKyField.SENSITIVE_DATA_PROCESSING); +} diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/field/UsMdField.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/field/UsMdField.java new file mode 100644 index 0000000..48a991e --- /dev/null +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/field/UsMdField.java @@ -0,0 +1,59 @@ +package com.iab.gpp.encoder.field; + +import com.iab.gpp.encoder.datatype.DataType; +import com.iab.gpp.encoder.datatype.EncodableBoolean; +import com.iab.gpp.encoder.datatype.EncodableFibonacciIntegerRange; +import com.iab.gpp.encoder.datatype.EncodableFixedInteger; +import com.iab.gpp.encoder.section.UsIn; + +public enum UsMdField implements FieldKey { + SECTION_ID(new EncodableFixedInteger<>("SectionID", 6, UsIn.ID)), + VERSION(new EncodableFixedInteger<>("Version", 6, UsIn.VERSION)), + SUB_SECTIONS(new EncodableFibonacciIntegerRange<>("SubSections")), + + MSPA_VERSION(new EncodableFixedInteger<>("MspaVersion", 6, 0)), + MSPA_COVERED_TRANSACTION( + new EncodableFixedInteger<>("MspaCoveredTransaction", 2, 1, VALIDATOR_12)), + MSPA_MODE(new EncodableFixedInteger<>("MspaMode", 2, 0, VALIDATOR_012)), + PROCESSING_NOTICE(new EncodableFixedInteger<>("ProcessingNotice", 2, 0, VALIDATOR_012)), + SALE_OPT_OUT_NOTICE(new EncodableFixedInteger<>("SaleOptOutNotice", 2, 0, VALIDATOR_012)), + TARGETED_ADVERTISING_OPT_OUT_NOTICE( + new EncodableFixedInteger<>("TargetedAdvertisingOptOutNotice", 2, 0, VALIDATOR_012)), + SALE_OPT_OUT(new EncodableFixedInteger<>("SaleOptOut", 2, 0, VALIDATOR_012)), + TARGETED_ADVERTISING_OPT_OUT( + new EncodableFixedInteger<>("TargetedAdvertisingOptOut", 2, 0, VALIDATOR_012)), + ADDITIONAL_DATA_PROCESSING_CONSENT( + new EncodableFixedInteger<>("AdditionalDataProcessingConsent", 2, 0, VALIDATOR_012)), + + GPC_SUBSECTION_TYPE(new EncodableFixedInteger<>("GpcSubSectionType", 2, 1)), + GPC(new EncodableBoolean<>("Gpc", false)); + + private final DataType type; + + UsMdField(DataType type) { + this.type = type; + } + + @Override + public DataType getType() { + return type; + } + + public static final FieldNames USMD_HEADER_SEGMENT_FIELD_NAMES = + new FieldNames<>(UsMdField.SECTION_ID, UsMdField.VERSION, UsMdField.SUB_SECTIONS); + + public static final FieldNames USMD_CORE_SEGMENT_FIELD_NAMES = + new FieldNames<>( + UsMdField.MSPA_VERSION, + UsMdField.MSPA_COVERED_TRANSACTION, + UsMdField.MSPA_MODE, + UsMdField.PROCESSING_NOTICE, + UsMdField.SALE_OPT_OUT_NOTICE, + UsMdField.TARGETED_ADVERTISING_OPT_OUT_NOTICE, + UsMdField.SALE_OPT_OUT, + UsMdField.TARGETED_ADVERTISING_OPT_OUT, + UsMdField.ADDITIONAL_DATA_PROCESSING_CONSENT); + + public static final FieldNames USMD_GPC_SEGMENT_FIELD_NAMES = + new FieldNames<>(UsMdField.GPC_SUBSECTION_TYPE, UsMdField.GPC); +} diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/field/UsRiField.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/field/UsRiField.java new file mode 100644 index 0000000..fc5fe33 --- /dev/null +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/field/UsRiField.java @@ -0,0 +1,62 @@ +package com.iab.gpp.encoder.field; + +import com.iab.gpp.encoder.datatype.DataType; +import com.iab.gpp.encoder.datatype.EncodableFibonacciIntegerRange; +import com.iab.gpp.encoder.datatype.EncodableFixedInteger; +import com.iab.gpp.encoder.datatype.EncodableFixedIntegerList; +import com.iab.gpp.encoder.section.UsIn; + +public enum UsRiField implements FieldKey { + SECTION_ID(new EncodableFixedInteger<>("SectionID", 6, UsIn.ID)), + VERSION(new EncodableFixedInteger<>("Version", 6, UsIn.VERSION)), + SUB_SECTIONS(new EncodableFibonacciIntegerRange<>("SubSections")), + + MSPA_VERSION(new EncodableFixedInteger<>("MspaVersion", 6, 0)), + MSPA_COVERED_TRANSACTION( + new EncodableFixedInteger<>("MspaCoveredTransaction", 2, 1, VALIDATOR_12)), + MSPA_MODE(new EncodableFixedInteger<>("MspaMode", 2, 0, VALIDATOR_012)), + PROCESSING_NOTICE(new EncodableFixedInteger<>("ProcessingNotice", 2, 0, VALIDATOR_012)), + SALE_OPT_OUT_NOTICE(new EncodableFixedInteger<>("SaleOptOutNotice", 2, 0, VALIDATOR_012)), + TARGETED_ADVERTISING_OPT_OUT_NOTICE( + new EncodableFixedInteger<>("TargetedAdvertisingOptOutNotice", 2, 0, VALIDATOR_012)), + SALE_OPT_OUT(new EncodableFixedInteger<>("SaleOptOut", 2, 0, VALIDATOR_012)), + TARGETED_ADVERTISING_OPT_OUT( + new EncodableFixedInteger<>("TargetedAdvertisingOptOut", 2, 0, VALIDATOR_012)), + KNOWN_CHILD_SENSITIVE_DATA_CONSENTS( + new EncodableFixedInteger<>("KnownChildSensitiveDataConsents", 2, 0, VALIDATOR_012)), + ADDITIONAL_DATA_PROCESSING_CONSENT( + new EncodableFixedInteger<>("AdditionalDataProcessingConsent", 2, 0, VALIDATOR_012)), + + SENSITIVE_DATA_PROCESSING( + new EncodableFixedIntegerList<>("SensitiveDataProcessing", 2, 8, VALIDATOR_LIST_012)); + + private final DataType type; + + UsRiField(DataType type) { + this.type = type; + } + + @Override + public DataType getType() { + return type; + } + + public static final FieldNames USRI_HEADER_SEGMENT_FIELD_NAMES = + new FieldNames<>(UsRiField.SECTION_ID, UsRiField.VERSION, UsRiField.SUB_SECTIONS); + + public static final FieldNames USRI_CORE_SEGMENT_FIELD_NAMES = + new FieldNames<>( + UsRiField.MSPA_VERSION, + UsRiField.MSPA_COVERED_TRANSACTION, + UsRiField.MSPA_MODE, + UsRiField.PROCESSING_NOTICE, + UsRiField.SALE_OPT_OUT_NOTICE, + UsRiField.TARGETED_ADVERTISING_OPT_OUT_NOTICE, + UsRiField.SALE_OPT_OUT, + UsRiField.TARGETED_ADVERTISING_OPT_OUT, + UsRiField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS, + UsRiField.ADDITIONAL_DATA_PROCESSING_CONSENT); + + public static final FieldNames USRI_SENSITIVE_DATA_CONSENTS_SEGMENT_FIELD_NAMES = + new FieldNames<>(UsRiField.SENSITIVE_DATA_PROCESSING); +} diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsKy.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsKy.java new file mode 100644 index 0000000..a0c01d4 --- /dev/null +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsKy.java @@ -0,0 +1,88 @@ +package com.iab.gpp.encoder.section; + +import com.iab.gpp.encoder.datatype.FixedIntegerList; +import com.iab.gpp.encoder.field.UsKyField; +import com.iab.gpp.encoder.segment.Base64Segment; + +public class UsKy extends AbstractUsSectionWithHeader { + + public static final int ID = 26; + public static final int VERSION = 1; + public static final String NAME = "usky"; + + public UsKy() { + super( + new Base64Segment<>(UsKyField.USKY_HEADER_SEGMENT_FIELD_NAMES), + new Base64Segment<>(UsKyField.USKY_CORE_SEGMENT_FIELD_NAMES), + new Base64Segment<>(UsKyField.USKY_SENSITIVE_DATA_CONSENTS_SEGMENT_FIELD_NAMES, true)); + } + + public UsKy(String encodedString) { + this(); + decode(encodedString); + } + + @Override + public int getId() { + return UsKy.ID; + } + + @Override + public String getName() { + return UsKy.NAME; + } + + @Override + public int getVersion() { + return UsKy.VERSION; + } + + @Override + protected final UsKyField getSubSectionsKey() { + return UsKyField.SUB_SECTIONS; + } + + public Integer getMspaVersion() { + return (Integer) this.getFieldValue(UsKyField.MSPA_VERSION); + } + + public Integer getMspaCoveredTransaction() { + return (Integer) this.getFieldValue(UsKyField.MSPA_COVERED_TRANSACTION); + } + + public Integer getMspaMode() { + return (Integer) this.getFieldValue(UsKyField.MSPA_MODE); + } + + public Integer getProcessingNotice() { + return (Integer) this.getFieldValue(UsKyField.PROCESSING_NOTICE); + } + + public Integer getSaleOptOutNotice() { + return (Integer) this.getFieldValue(UsKyField.SALE_OPT_OUT_NOTICE); + } + + public Integer getTargetedAdvertisingOptOutNotice() { + return (Integer) this.getFieldValue(UsKyField.TARGETED_ADVERTISING_OPT_OUT_NOTICE); + } + + public Integer getSaleOptOut() { + return (Integer) this.getFieldValue(UsKyField.SALE_OPT_OUT); + } + + public Integer getTargetedAdvertisingOptOut() { + return (Integer) this.getFieldValue(UsKyField.TARGETED_ADVERTISING_OPT_OUT); + } + + public Integer getKnownChildSensitiveDataConsents() { + return (Integer) this.getFieldValue(UsKyField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS); + } + + public Integer getAdditionalDataProcessingConsent() { + return (Integer) this.getFieldValue(UsKyField.ADDITIONAL_DATA_PROCESSING_CONSENT); + } + + public FixedIntegerList getSensitiveDataProcessing() { + return (FixedIntegerList) this.getFieldValue(UsKyField.SENSITIVE_DATA_PROCESSING); + } +} diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsMd.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsMd.java new file mode 100644 index 0000000..5b2be88 --- /dev/null +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsMd.java @@ -0,0 +1,83 @@ +package com.iab.gpp.encoder.section; + +import com.iab.gpp.encoder.field.UsMdField; +import com.iab.gpp.encoder.segment.Base64Segment; + +public class UsMd extends AbstractUsSectionWithHeader { + + public static final int ID = 24; + public static final int VERSION = 1; + public static final String NAME = "usmd"; + + public UsMd() { + super( + new Base64Segment<>(UsMdField.USMD_HEADER_SEGMENT_FIELD_NAMES), + new Base64Segment<>(UsMdField.USMD_CORE_SEGMENT_FIELD_NAMES), + new Base64Segment<>(UsMdField.USMD_GPC_SEGMENT_FIELD_NAMES, true)); + } + + public UsMd(String encodedString) { + this(); + decode(encodedString); + } + + @Override + public int getId() { + return UsMd.ID; + } + + @Override + public String getName() { + return UsMd.NAME; + } + + @Override + public int getVersion() { + return UsMd.VERSION; + } + + @Override + protected final UsMdField getSubSectionsKey() { + return UsMdField.SUB_SECTIONS; + } + + public Integer getMspaVersion() { + return (Integer) this.getFieldValue(UsMdField.MSPA_VERSION); + } + + public Integer getMspaCoveredTransaction() { + return (Integer) this.getFieldValue(UsMdField.MSPA_COVERED_TRANSACTION); + } + + public Integer getMspaMode() { + return (Integer) this.getFieldValue(UsMdField.MSPA_MODE); + } + + public Integer getProcessingNotice() { + return (Integer) this.getFieldValue(UsMdField.PROCESSING_NOTICE); + } + + public Integer getSaleOptOutNotice() { + return (Integer) this.getFieldValue(UsMdField.SALE_OPT_OUT_NOTICE); + } + + public Integer getTargetedAdvertisingOptOutNotice() { + return (Integer) this.getFieldValue(UsMdField.TARGETED_ADVERTISING_OPT_OUT_NOTICE); + } + + public Integer getSaleOptOut() { + return (Integer) this.getFieldValue(UsMdField.SALE_OPT_OUT); + } + + public Integer getTargetedAdvertisingOptOut() { + return (Integer) this.getFieldValue(UsMdField.TARGETED_ADVERTISING_OPT_OUT); + } + + public Integer getAdditionalDataProcessingConsent() { + return (Integer) this.getFieldValue(UsMdField.ADDITIONAL_DATA_PROCESSING_CONSENT); + } + + public Boolean getGpc() { + return (Boolean) this.getFieldValue(UsMdField.GPC); + } +} diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsRi.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsRi.java new file mode 100644 index 0000000..eb2196d --- /dev/null +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsRi.java @@ -0,0 +1,88 @@ +package com.iab.gpp.encoder.section; + +import com.iab.gpp.encoder.datatype.FixedIntegerList; +import com.iab.gpp.encoder.field.UsRiField; +import com.iab.gpp.encoder.segment.Base64Segment; + +public class UsRi extends AbstractUsSectionWithHeader { + + public static final int ID = 25; + public static final int VERSION = 1; + public static final String NAME = "usin"; + + public UsRi() { + super( + new Base64Segment<>(UsRiField.USRI_HEADER_SEGMENT_FIELD_NAMES), + new Base64Segment<>(UsRiField.USRI_CORE_SEGMENT_FIELD_NAMES), + new Base64Segment<>(UsRiField.USRI_SENSITIVE_DATA_CONSENTS_SEGMENT_FIELD_NAMES, true)); + } + + public UsRi(String encodedString) { + this(); + decode(encodedString); + } + + @Override + public int getId() { + return UsRi.ID; + } + + @Override + public String getName() { + return UsRi.NAME; + } + + @Override + public int getVersion() { + return UsRi.VERSION; + } + + @Override + protected final UsRiField getSubSectionsKey() { + return UsRiField.SUB_SECTIONS; + } + + public Integer getMspaVersion() { + return (Integer) this.getFieldValue(UsRiField.MSPA_VERSION); + } + + public Integer getMspaCoveredTransaction() { + return (Integer) this.getFieldValue(UsRiField.MSPA_COVERED_TRANSACTION); + } + + public Integer getMspaMode() { + return (Integer) this.getFieldValue(UsRiField.MSPA_MODE); + } + + public Integer getProcessingNotice() { + return (Integer) this.getFieldValue(UsRiField.PROCESSING_NOTICE); + } + + public Integer getSaleOptOutNotice() { + return (Integer) this.getFieldValue(UsRiField.SALE_OPT_OUT_NOTICE); + } + + public Integer getTargetedAdvertisingOptOutNotice() { + return (Integer) this.getFieldValue(UsRiField.TARGETED_ADVERTISING_OPT_OUT_NOTICE); + } + + public Integer getSaleOptOut() { + return (Integer) this.getFieldValue(UsRiField.SALE_OPT_OUT); + } + + public Integer getTargetedAdvertisingOptOut() { + return (Integer) this.getFieldValue(UsRiField.TARGETED_ADVERTISING_OPT_OUT); + } + + public Integer getKnownChildSensitiveDataConsents() { + return (Integer) this.getFieldValue(UsRiField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS); + } + + public Integer getAdditionalDataProcessingConsent() { + return (Integer) this.getFieldValue(UsRiField.ADDITIONAL_DATA_PROCESSING_CONSENT); + } + + public FixedIntegerList getSensitiveDataProcessing() { + return (FixedIntegerList) this.getFieldValue(UsRiField.SENSITIVE_DATA_PROCESSING); + } +} From cab1c6f0fd98570aa4c64a3ea6555856a9ed32d0 Mon Sep 17 00:00:00 2001 From: James Yuzawa Date: Fri, 6 Mar 2026 14:06:14 -0500 Subject: [PATCH 03/15] fix id --- .../src/main/java/com/iab/gpp/encoder/section/UsRi.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsRi.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsRi.java index eb2196d..f9cba25 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsRi.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsRi.java @@ -6,7 +6,7 @@ public class UsRi extends AbstractUsSectionWithHeader { - public static final int ID = 25; + public static final int ID = 27; public static final int VERSION = 1; public static final String NAME = "usin"; From ecb38f3c968b44016f13739f9a95ebdf714ad402 Mon Sep 17 00:00:00 2001 From: James Yuzawa Date: Fri, 6 Mar 2026 16:52:50 -0500 Subject: [PATCH 04/15] clean up conditional encoding --- .../AbstractDirtyableBitStringDataType.java | 3 +++ .../com/iab/gpp/encoder/datatype/DataType.java | 10 ++++++++++ .../EncodableArrayOfFixedIntegerRanges.java | 5 +++++ .../EncodableFibonacciIntegerRange.java | 5 +++++ .../datatype/EncodableFixedBitfield.java | 5 +++++ .../datatype/EncodableFixedIntegerList.java | 5 +++++ .../datatype/EncodableFixedIntegerRange.java | 5 +++++ .../datatype/EncodableFlexibleBitfield.java | 5 +++++ .../datatype/EncodableOptimizedFixedRange.java | 5 +++++ .../gpp/encoder/datatype/FixedIntegerList.java | 9 +++++++++ .../com/iab/gpp/encoder/field/UsMdField.java | 4 ++-- .../com/iab/gpp/encoder/field/UsNatField.java | 5 +++++ .../section/AbstractUsSectionWithHeader.java | 2 +- .../encoder/segment/AbstractBase64Segment.java | 4 ++-- .../AbstractLazilyEncodableSegment.java | 18 +++++++++++++----- .../iab/gpp/encoder/segment/Base64Segment.java | 10 +++++++++- .../gpp/encoder/segment/EncodableSegment.java | 2 +- .../segment/TraditionalBase64Segment.java | 8 ++------ .../gpp/encoder/segment/UsNatCoreSegment.java | 2 +- .../gpp/encoder/segment/UspV1CoreSegment.java | 2 +- 20 files changed, 94 insertions(+), 20 deletions(-) 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 index 3d0c51b..bbfbfea 100644 --- 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 @@ -19,6 +19,9 @@ public boolean isDirty(Object[] values, int index) { return (value != null && value.isDirty()); } + @Override + protected abstract boolean isPresent(T value); + @SuppressWarnings("unchecked") @Override public void setDirty(Object[] values, int index, boolean dirty) { 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 92c6e3d..e93944e 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 @@ -69,6 +69,16 @@ public final T get(Object[] values, int index) { return value; } + @SuppressWarnings("unchecked") + public final boolean isPresent(Object[] values, int index) { + T value = (T) values[index]; + return value != null && isPresent(value); + } + + protected boolean isPresent(T value) { + return true; + } + public final void set(Object[] values, int index, Object newValue) { T oldValue = get(values, index); T effectiveValue = processValue(oldValue, newValue); 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 81bccc5..f01470e 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 @@ -29,6 +29,11 @@ protected DirtyableList initialize() { return new DirtyableList<>(); } + @Override + protected boolean isPresent(DirtyableList value) { + return !value.isEmpty(); + } + @Override protected void encode( BitString sb, DirtyableList entries, EncodableSegment segment) { 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 c1d0ba7..7ac2ffd 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 @@ -18,6 +18,11 @@ public IntegerSet initialize() { return new IntegerSet(); } + @Override + protected boolean isPresent(IntegerSet value) { + return !value.isEmpty(); + } + @Override protected void encode(BitString builder, IntegerSet value, EncodableSegment segment) { FibonacciIntegerRangeEncoder.encode(builder, value); 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 ffb2dda..a22eb31 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 @@ -26,6 +26,11 @@ protected IntegerSet initialize() { return new IntegerSet(numElements); } + @Override + protected boolean isPresent(IntegerSet value) { + return !value.isEmpty(); + } + @Override protected void encode(BitString builder, IntegerSet value, EncodableSegment segment) { FixedBitfieldEncoder.encode(builder, value, this.numElements); 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 57d0598..a0ced76 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 @@ -33,6 +33,11 @@ protected FixedIntegerList initialize() { return new FixedIntegerList(elementBitStringLength, numElements); } + @Override + protected boolean isPresent(FixedIntegerList value) { + return value.isPresent(); + } + @Override protected void encode(BitString builder, FixedIntegerList value, EncodableSegment segment) { FixedIntegerListEncoder.encode(builder, value, this.elementBitStringLength, this.numElements); 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 ec84489..51f37ff 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 @@ -18,6 +18,11 @@ protected IntegerSet initialize() { return new IntegerSet(); } + @Override + protected boolean isPresent(IntegerSet value) { + return !value.isEmpty(); + } + @Override protected void encode(BitString builder, IntegerSet value, EncodableSegment segment) { FixedIntegerRangeEncoder.encode(builder, value); 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 88b7118..a0a0574 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 @@ -22,6 +22,11 @@ protected IntegerSet initialize() { return new IntegerSet(); } + @Override + protected boolean isPresent(IntegerSet value) { + return !value.isEmpty(); + } + @Override protected void encode(BitString builder, IntegerSet value, EncodableSegment segment) { FixedBitfieldEncoder.encode(builder, value, this.getLengthSupplier.extract(segment)); 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 90a3ed9..b333b24 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 @@ -18,6 +18,11 @@ protected IntegerSet initialize() { return new IntegerSet(); } + @Override + protected boolean isPresent(IntegerSet value) { + return !value.isEmpty(); + } + @Override protected void encode(BitString builder, IntegerSet value, EncodableSegment segment) { OptimizedFixedRangeEncoder.encode(builder, 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 index 36486cb..f9e0efb 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 @@ -26,6 +26,15 @@ public FixedIntegerList(int elementBitStringLength, int numElements) { this(new BitSet(elementBitStringLength * numElements), 0, elementBitStringLength, numElements); } + public boolean isPresent() { + for (int i = 0; i < numElements; i++) { + if (getInt(i) > 0) { + return true; + } + } + return false; + } + @Override public int size() { return numElements; diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/field/UsMdField.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/field/UsMdField.java index 48a991e..cb9f0da 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/field/UsMdField.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/field/UsMdField.java @@ -24,10 +24,10 @@ public enum UsMdField implements FieldKey { new EncodableFixedInteger<>("TargetedAdvertisingOptOut", 2, 0, VALIDATOR_012)), ADDITIONAL_DATA_PROCESSING_CONSENT( new EncodableFixedInteger<>("AdditionalDataProcessingConsent", 2, 0, VALIDATOR_012)), - + GPC_SUBSECTION_TYPE(new EncodableFixedInteger<>("GpcSubSectionType", 2, 1)), GPC(new EncodableBoolean<>("Gpc", false)); - + private final DataType type; UsMdField(DataType type) { diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/field/UsNatField.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/field/UsNatField.java index 3826d03..482d662 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/field/UsNatField.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/field/UsNatField.java @@ -107,6 +107,11 @@ protected FixedIntegerList initialize() { return new FixedIntegerList(elementBitStringLength, lengthProvider.v2Length); } + @Override + protected boolean isPresent(FixedIntegerList value) { + return value.isPresent(); + } + @Override protected void encode( BitString builder, FixedIntegerList value, EncodableSegment segment) { diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/AbstractUsSectionWithHeader.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/AbstractUsSectionWithHeader.java index e3b2546..8b7c317 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/AbstractUsSectionWithHeader.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/AbstractUsSectionWithHeader.java @@ -40,7 +40,7 @@ protected final CharSequence doEncode() { IntegerSet subSections = getSubSections(); for (int i = 1; i < size(); i++) { EncodableSegment segment = getSegment(i); - if (!segment.isOptional() || segment.isDirty()) { + if (segment.shouldEncode()) { subSections.add(i - 1); } } diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/AbstractBase64Segment.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/AbstractBase64Segment.java index ce5fc8d..090651a 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/AbstractBase64Segment.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/AbstractBase64Segment.java @@ -11,8 +11,8 @@ abstract class AbstractBase64Segment & FieldKey> extends AbstractLazilyEncodableSegment { - protected AbstractBase64Segment(FieldNames fieldNames, boolean optional) { - super(fieldNames, optional); + protected AbstractBase64Segment(FieldNames fieldNames) { + super(fieldNames); } protected abstract AbstractBase64UrlEncoder getBase64UrlEncoder(); 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 aa58541..e2ab494 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 @@ -9,18 +9,26 @@ abstract class AbstractLazilyEncodableSegment & FieldKey> protected final FieldNames fieldNames; protected final Object[] values; - private boolean optional; private boolean dirty; - protected AbstractLazilyEncodableSegment(FieldNames fieldNames, boolean optional) { + protected AbstractLazilyEncodableSegment(FieldNames fieldNames) { this.fieldNames = fieldNames; this.values = new Object[fieldNames.size()]; - this.optional = optional; } @Override - public final boolean isOptional() { - return optional; + public boolean shouldEncode() { + return true; + } + + protected final boolean isPresent() { + int size = fieldNames.size(); + for (int i = 0; i < size; i++) { + if (fieldNames.get(i).isPresent(values, i)) { + return true; + } + } + return false; } @Override diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/Base64Segment.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/Base64Segment.java index c5aff71..4ce5b32 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/Base64Segment.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/Base64Segment.java @@ -7,8 +7,11 @@ public final class Base64Segment & FieldKey> extends AbstractBase64Segment { + private final boolean optional; + public Base64Segment(FieldNames fieldNames, boolean optional) { - super(fieldNames, optional); + super(fieldNames); + this.optional = optional; } public Base64Segment(FieldNames fieldNames) { @@ -18,4 +21,9 @@ public Base64Segment(FieldNames fieldNames) { protected AbstractBase64UrlEncoder getBase64UrlEncoder() { return CompressedBase64UrlEncoder.getInstance(); } + + @Override + public boolean shouldEncode() { + return !optional || this.isPresent(); + } } diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/EncodableSegment.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/EncodableSegment.java index e072bbd..4cf3463 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/EncodableSegment.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/EncodableSegment.java @@ -14,5 +14,5 @@ public abstract class EncodableSegment & FieldKey> extends Abs public abstract void setFieldValue(E fieldName, Object value); - public abstract boolean isOptional(); + public abstract boolean shouldEncode(); } diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/TraditionalBase64Segment.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/TraditionalBase64Segment.java index 66c6d33..f2eba8c 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/TraditionalBase64Segment.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/TraditionalBase64Segment.java @@ -8,15 +8,11 @@ public final class TraditionalBase64Segment & FieldKey> extends AbstractBase64Segment { - public TraditionalBase64Segment(FieldNames fieldNames, boolean optional) { - super(fieldNames, optional); - } - public TraditionalBase64Segment(FieldNames fieldNames) { - this(fieldNames, false); + super(fieldNames); } - protected AbstractBase64UrlEncoder getBase64UrlEncoder() { + protected final AbstractBase64UrlEncoder getBase64UrlEncoder() { return TraditionalBase64UrlEncoder.getInstance(); } } 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 0907035..c69cb9f 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 @@ -10,7 +10,7 @@ public final class UsNatCoreSegment extends AbstractBase64Segment { private static final int VERSION_LENGTH = 6; public UsNatCoreSegment() { - super(UsNatField.USNAT_CORE_SEGMENT_FIELD_NAMES, false); + super(UsNatField.USNAT_CORE_SEGMENT_FIELD_NAMES); } protected AbstractBase64UrlEncoder getBase64UrlEncoder() { diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UspV1CoreSegment.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UspV1CoreSegment.java index b845f92..9defd65 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UspV1CoreSegment.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UspV1CoreSegment.java @@ -6,7 +6,7 @@ public final class UspV1CoreSegment extends AbstractLazilyEncodableSegment { public UspV1CoreSegment() { - super(UspV1Field.USPV1_CORE_SEGMENT_FIELD_NAMES, false); + super(UspV1Field.USPV1_CORE_SEGMENT_FIELD_NAMES); } @Override From 69f838916e7aac5290a2eb8b95948aff91ff4fa9 Mon Sep 17 00:00:00 2001 From: James Yuzawa Date: Fri, 6 Mar 2026 16:53:28 -0500 Subject: [PATCH 05/15] fix state --- .../src/main/java/com/iab/gpp/encoder/section/UsRi.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsRi.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsRi.java index f9cba25..819038b 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsRi.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsRi.java @@ -8,7 +8,7 @@ public class UsRi extends AbstractUsSectionWithHeader { public static final int ID = 27; public static final int VERSION = 1; - public static final String NAME = "usin"; + public static final String NAME = "usri"; public UsRi() { super( From f9d16dd6c656f38c07bf84f79b697488e2f69851 Mon Sep 17 00:00:00 2001 From: James Yuzawa Date: Fri, 6 Mar 2026 16:58:12 -0500 Subject: [PATCH 06/15] update test --- .../com/iab/gpp/encoder/GppModelTest.java | 24 +++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/GppModelTest.java b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/GppModelTest.java index d444485..4728161 100644 --- a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/GppModelTest.java +++ b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/GppModelTest.java @@ -9,6 +9,9 @@ import com.iab.gpp.encoder.field.UsDeField; import com.iab.gpp.encoder.field.UsFlField; import com.iab.gpp.encoder.field.UsIaField; +import com.iab.gpp.encoder.field.UsInField; +import com.iab.gpp.encoder.field.UsKyField; +import com.iab.gpp.encoder.field.UsMdField; import com.iab.gpp.encoder.field.UsMnField; import com.iab.gpp.encoder.field.UsMtField; import com.iab.gpp.encoder.field.UsNatField; @@ -16,6 +19,7 @@ import com.iab.gpp.encoder.field.UsNhField; import com.iab.gpp.encoder.field.UsNjField; import com.iab.gpp.encoder.field.UsOrField; +import com.iab.gpp.encoder.field.UsRiField; import com.iab.gpp.encoder.field.UsTnField; import com.iab.gpp.encoder.field.UsTxField; import com.iab.gpp.encoder.field.UsUtField; @@ -29,6 +33,9 @@ import com.iab.gpp.encoder.section.UsDe; import com.iab.gpp.encoder.section.UsFl; import com.iab.gpp.encoder.section.UsIa; +import com.iab.gpp.encoder.section.UsIn; +import com.iab.gpp.encoder.section.UsKy; +import com.iab.gpp.encoder.section.UsMd; import com.iab.gpp.encoder.section.UsMn; import com.iab.gpp.encoder.section.UsMt; import com.iab.gpp.encoder.section.UsNat; @@ -36,6 +43,7 @@ import com.iab.gpp.encoder.section.UsNh; import com.iab.gpp.encoder.section.UsNj; import com.iab.gpp.encoder.section.UsOr; +import com.iab.gpp.encoder.section.UsRi; import com.iab.gpp.encoder.section.UsTn; import com.iab.gpp.encoder.section.UsTx; import com.iab.gpp.encoder.section.UsUt; @@ -128,6 +136,10 @@ public void testEncodeDefaultAll() { gppModel.setFieldValue(UsNj.NAME, UsNjField.VERSION, UsNj.VERSION); gppModel.setFieldValue(UsTn.NAME, UsTnField.VERSION, UsTn.VERSION); gppModel.setFieldValue(UsMn.NAME, UsMnField.VERSION, UsMn.VERSION); + gppModel.setFieldValue(UsIn.NAME, UsInField.VERSION, UsIn.VERSION); + gppModel.setFieldValue(UsMd.NAME, UsMdField.VERSION, UsMd.VERSION); + gppModel.setFieldValue(UsKy.NAME, UsKyField.VERSION, UsKy.VERSION); + gppModel.setFieldValue(UsRi.NAME, UsRiField.VERSION, UsRi.VERSION); Assertions.assertEquals(true, gppModel.hasSection(TcfEuV2.NAME)); Assertions.assertEquals(true, gppModel.hasSection(TcfCaV1.NAME)); @@ -149,10 +161,14 @@ public void testEncodeDefaultAll() { Assertions.assertEquals(true, gppModel.hasSection(UsNj.NAME)); Assertions.assertEquals(true, gppModel.hasSection(UsTn.NAME)); Assertions.assertEquals(true, gppModel.hasSection(UsMn.NAME)); + Assertions.assertEquals(true, gppModel.hasSection(UsIn.NAME)); + Assertions.assertEquals(true, gppModel.hasSection(UsMd.NAME)); + Assertions.assertEquals(true, gppModel.hasSection(UsKy.NAME)); + Assertions.assertEquals(true, gppModel.hasSection(UsRi.NAME)); String gppString = gppModel.encode(); Assertions.assertEquals( - "DBACOYs~CPSG_8APSG_8AAAAAAENAACAAAAAAAAAAAAAAAAAAAAA.QAAA.IAAA~BPSG_8APSG_8AAAAAAENAACAAAAAAAAAAAAAAAAAAA.YAAAAAAAAAA~1---~CAAAAAAAAABA.QA~BAAAAABA.QA~BAAAABA~BAAAAEA.QA~BAAAAAQA~BAAAAAEA.QA~BAAAAABA~BAAAAABA.QA~BAAAAAABAA.QA~BAAAAAQA.QA~BAAAAAABAA.QA~BAAAAAQA.QA~BAAAAAQA.QA~BAAAAABA.QA~BAAAAAAAQA.QA~BAAAAAQA.QA~BAAAAAQA.QA", + "DBACOcGA~CPSG_8APSG_8AAAAAAENAACAAAAAAAAAAAAAAAAAAAAA.QAAA.IAAA~BPSG_8APSG_8AAAAAAENAACAAAAAAAAAAAAAAAAAAA.YAAAAAAAAAA~1---~CAAAAAAAAABA.QA~BAAAAABA.QA~BAAAABA~BAAAAEA.QA~BAAAAAQA~BAAAAAEA.QA~BAAAAABA~BAAAAABA.QA~BAAAAAABAA.QA~BAAAAAQA.QA~BAAAAAABAA.QA~BAAAAAQA.QA~BAAAAAQA.QA~BAAAAABA.QA~BAAAAAAAQA.QA~BAAAAAQA.QA~BAAAAAQA.QA~ZBAA.AQAA~ZBAA.AQAA~ZBAA.AQAA~ZBAA.AQAA", gppString); } @@ -428,7 +444,7 @@ public void testDecodeDefaults() { @Test public void testDecodeDefaultsAll() { String gppString = - "DBACOYs~CPSG_8APSG_8AAAAAAENAACAAAAAAAAAAAAAAAAAAAAA.QAAA.IAAA~BPSG_8APSG_8AAAAAAENAACAAAAAAAAAAAAAAAAAAA.YAAAAAAAAAA~1---~BAAAAAAAAABA.QA~BAAAAABA.QA~BAAAABA~BAAAAEA.QA~BAAAAAQA~BAAAAAEA.QA~BAAAAABA~BAAAAABA.QA~BAAAAAABAA.QA~BAAAAAQA.QA~BAAAAAABAA.QA~BAAAAAQA.QA~BAAAAAQA.QA~BAAAAABA.QA~BAAAAAAAQA.QA~BAAAAAQA.QA~BAAAAAABAA.QA"; + "DBACOcGA~CPSG_8APSG_8AAAAAAENAACAAAAAAAAAAAAAAAAAAAAA.QAAA.IAAA~BPSG_8APSG_8AAAAAAENAACAAAAAAAAAAAAAAAAAAA.YAAAAAAAAAA~1---~CAAAAAAAAABA.QA~BAAAAABA.QA~BAAAABA~BAAAAEA.QA~BAAAAAQA~BAAAAAEA.QA~BAAAAABA~BAAAAABA.QA~BAAAAAABAA.QA~BAAAAAQA.QA~BAAAAAABAA.QA~BAAAAAQA.QA~BAAAAAQA.QA~BAAAAABA.QA~BAAAAAAAQA.QA~BAAAAAQA.QA~BAAAAAQA.QA~ZBAA.AQAA~ZBAA.AQAA~ZBAA.AQAA~ZBAA.AQAA"; GppModel gppModel = new GppModel(gppString); Assertions.assertEquals(true, gppModel.hasSection(TcfEuV2.NAME)); @@ -451,6 +467,10 @@ public void testDecodeDefaultsAll() { Assertions.assertEquals(true, gppModel.hasSection(UsNj.NAME)); Assertions.assertEquals(true, gppModel.hasSection(UsTn.NAME)); Assertions.assertEquals(true, gppModel.hasSection(UsMn.NAME)); + Assertions.assertEquals(true, gppModel.hasSection(UsIn.NAME)); + Assertions.assertEquals(true, gppModel.hasSection(UsMd.NAME)); + Assertions.assertEquals(true, gppModel.hasSection(UsKy.NAME)); + Assertions.assertEquals(true, gppModel.hasSection(UsRi.NAME)); } @Test From 448bebd2ab2894a8aec538d4a5842fcbaef38bf9 Mon Sep 17 00:00:00 2001 From: James Yuzawa Date: Fri, 6 Mar 2026 17:14:18 -0500 Subject: [PATCH 07/15] move optional --- .../gpp/encoder/segment/AbstractBase64Segment.java | 4 ++-- .../segment/AbstractLazilyEncodableSegment.java | 11 ++++++----- .../com/iab/gpp/encoder/segment/Base64Segment.java | 10 +--------- .../gpp/encoder/segment/TraditionalBase64Segment.java | 6 +++++- .../com/iab/gpp/encoder/segment/UsNatCoreSegment.java | 2 +- .../com/iab/gpp/encoder/segment/UspV1CoreSegment.java | 2 +- 6 files changed, 16 insertions(+), 19 deletions(-) diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/AbstractBase64Segment.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/AbstractBase64Segment.java index 090651a..ce5fc8d 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/AbstractBase64Segment.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/AbstractBase64Segment.java @@ -11,8 +11,8 @@ abstract class AbstractBase64Segment & FieldKey> extends AbstractLazilyEncodableSegment { - protected AbstractBase64Segment(FieldNames fieldNames) { - super(fieldNames); + protected AbstractBase64Segment(FieldNames fieldNames, boolean optional) { + super(fieldNames, optional); } protected abstract AbstractBase64UrlEncoder getBase64UrlEncoder(); 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 e2ab494..1e15d28 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 @@ -10,18 +10,19 @@ abstract class AbstractLazilyEncodableSegment & FieldKey> protected final FieldNames fieldNames; protected final Object[] values; private boolean dirty; + private final boolean optional; - protected AbstractLazilyEncodableSegment(FieldNames fieldNames) { + protected AbstractLazilyEncodableSegment(FieldNames fieldNames, boolean optional) { this.fieldNames = fieldNames; this.values = new Object[fieldNames.size()]; + this.optional = optional; } @Override public boolean shouldEncode() { - return true; - } - - protected final boolean isPresent() { + if (!optional) { + return true; + } int size = fieldNames.size(); for (int i = 0; i < size; i++) { if (fieldNames.get(i).isPresent(values, i)) { diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/Base64Segment.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/Base64Segment.java index 4ce5b32..c5aff71 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/Base64Segment.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/Base64Segment.java @@ -7,11 +7,8 @@ public final class Base64Segment & FieldKey> extends AbstractBase64Segment { - private final boolean optional; - public Base64Segment(FieldNames fieldNames, boolean optional) { - super(fieldNames); - this.optional = optional; + super(fieldNames, optional); } public Base64Segment(FieldNames fieldNames) { @@ -21,9 +18,4 @@ public Base64Segment(FieldNames fieldNames) { protected AbstractBase64UrlEncoder getBase64UrlEncoder() { return CompressedBase64UrlEncoder.getInstance(); } - - @Override - public boolean shouldEncode() { - return !optional || this.isPresent(); - } } diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/TraditionalBase64Segment.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/TraditionalBase64Segment.java index f2eba8c..4f1432b 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/TraditionalBase64Segment.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/TraditionalBase64Segment.java @@ -8,8 +8,12 @@ public final class TraditionalBase64Segment & FieldKey> extends AbstractBase64Segment { + public TraditionalBase64Segment(FieldNames fieldNames, boolean optional) { + super(fieldNames, optional); + } + public TraditionalBase64Segment(FieldNames fieldNames) { - super(fieldNames); + this(fieldNames, false); } protected final AbstractBase64UrlEncoder getBase64UrlEncoder() { 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 c69cb9f..0907035 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 @@ -10,7 +10,7 @@ public final class UsNatCoreSegment extends AbstractBase64Segment { private static final int VERSION_LENGTH = 6; public UsNatCoreSegment() { - super(UsNatField.USNAT_CORE_SEGMENT_FIELD_NAMES); + super(UsNatField.USNAT_CORE_SEGMENT_FIELD_NAMES, false); } protected AbstractBase64UrlEncoder getBase64UrlEncoder() { diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UspV1CoreSegment.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UspV1CoreSegment.java index 9defd65..b845f92 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UspV1CoreSegment.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UspV1CoreSegment.java @@ -6,7 +6,7 @@ public final class UspV1CoreSegment extends AbstractLazilyEncodableSegment { public UspV1CoreSegment() { - super(UspV1Field.USPV1_CORE_SEGMENT_FIELD_NAMES); + super(UspV1Field.USPV1_CORE_SEGMENT_FIELD_NAMES, false); } @Override From 1b49c7d5369fd210393bdc5be0d51003fa681cbe Mon Sep 17 00:00:00 2001 From: James Yuzawa Date: Fri, 6 Mar 2026 17:14:48 -0500 Subject: [PATCH 08/15] tcf 2.3 support --- .../iab/gpp/encoder/field/TcfEuV2Field.java | 4 +-- .../com/iab/gpp/encoder/section/TcfEuV2.java | 31 +++++++------------ .../com/iab/gpp/encoder/GppModelTest.java | 16 +++++----- .../iab/gpp/encoder/section/TcfEuV2Test.java | 5 ++- 4 files changed, 22 insertions(+), 34 deletions(-) diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/field/TcfEuV2Field.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/field/TcfEuV2Field.java index 45046e7..85abfca 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/field/TcfEuV2Field.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/field/TcfEuV2Field.java @@ -20,8 +20,8 @@ public enum TcfEuV2Field implements FieldKey { CONSENT_SCREEN(new EncodableFixedInteger<>("ConsentScreen", 6, 0)), CONSENT_LANGUAGE(new EncodableFixedString<>("ConsentLanguage", 2, "EN")), VENDOR_LIST_VERSION(new EncodableFixedInteger<>("VendorListVersion", 12, 0)), - POLICY_VERSION(new EncodableFixedInteger<>("PolicyVersion", 6, 2)), - IS_SERVICE_SPECIFIC(new EncodableBoolean<>("IsServiceSpecific", false)), + POLICY_VERSION(new EncodableFixedInteger<>("PolicyVersion", 6, 5)), + IS_SERVICE_SPECIFIC(new EncodableBoolean<>("IsServiceSpecific", true)), USE_NON_STANDARD_STACKS(new EncodableBoolean<>("UseNonStandardStacks", false)), SPECIAL_FEATURE_OPTINS(new EncodableFixedBitfield<>("SpecialFeatureOptins", 12)), PURPOSE_CONSENTS(new EncodableFixedBitfield<>("PurposeConsents", 24)), diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/TcfEuV2.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/TcfEuV2.java index dbcd95d..cee763c 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/TcfEuV2.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/TcfEuV2.java @@ -4,6 +4,7 @@ import com.iab.gpp.encoder.datatype.RangeEntry; import com.iab.gpp.encoder.error.DecodingException; import com.iab.gpp.encoder.field.TcfEuV2Field; +import com.iab.gpp.encoder.segment.EncodableSegment; import com.iab.gpp.encoder.segment.TraditionalBase64Segment; import java.time.Instant; import java.util.ArrayList; @@ -18,8 +19,10 @@ public class TcfEuV2 extends EncodableSection { public TcfEuV2() { super( new TraditionalBase64Segment<>(TcfEuV2Field.TCFEUV2_CORE_SEGMENT_FIELD_NAMES), - new TraditionalBase64Segment<>(TcfEuV2Field.TCFEUV2_PUBLISHER_PURPOSES_SEGMENT_FIELD_NAMES), - new TraditionalBase64Segment<>(TcfEuV2Field.TCFEUV2_VENDORS_ALLOWED_SEGMENT_FIELD_NAMES), + new TraditionalBase64Segment<>( + TcfEuV2Field.TCFEUV2_PUBLISHER_PURPOSES_SEGMENT_FIELD_NAMES, true), + new TraditionalBase64Segment<>( + TcfEuV2Field.TCFEUV2_VENDORS_ALLOWED_SEGMENT_FIELD_NAMES, true), new TraditionalBase64Segment<>(TcfEuV2Field.TCFEUV2_VENDORS_DISCLOSED_SEGMENT_FIELD_NAMES)); } @@ -82,26 +85,14 @@ public void doDecode(CharSequence encodedString) { @Override public CharSequence doEncode() { - List encodedSegments = new ArrayList<>(size()); - if (size() >= 1) { - encodedSegments.add(getSegment(0).encodeCharSequence()); - - Boolean isServiceSpecific = (Boolean) this.getFieldValue(TcfEuV2Field.IS_SERVICE_SPECIFIC); - if (isServiceSpecific) { - if (size() >= 2) { - encodedSegments.add(getSegment(1).encodeCharSequence()); - } - } else { - if (size() >= 2) { - encodedSegments.add(getSegment(2).encodeCharSequence()); - - if (size() >= 3) { - encodedSegments.add(getSegment(3).encodeCharSequence()); - } - } + int size = size(); + List encodedSegments = new ArrayList<>(size); + for (int i = 0; i < size; i++) { + EncodableSegment segment = getSegment(i); + if (segment.shouldEncode()) { + encodedSegments.add(segment.encodeCharSequence()); } } - return SlicedCharSequence.join('.', encodedSegments); } diff --git a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/GppModelTest.java b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/GppModelTest.java index 4728161..a2f6b44 100644 --- a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/GppModelTest.java +++ b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/GppModelTest.java @@ -168,7 +168,7 @@ public void testEncodeDefaultAll() { String gppString = gppModel.encode(); Assertions.assertEquals( - "DBACOcGA~CPSG_8APSG_8AAAAAAENAACAAAAAAAAAAAAAAAAAAAAA.QAAA.IAAA~BPSG_8APSG_8AAAAAAENAACAAAAAAAAAAAAAAAAAAA.YAAAAAAAAAA~1---~CAAAAAAAAABA.QA~BAAAAABA.QA~BAAAABA~BAAAAEA.QA~BAAAAAQA~BAAAAAEA.QA~BAAAAABA~BAAAAABA.QA~BAAAAAABAA.QA~BAAAAAQA.QA~BAAAAAABAA.QA~BAAAAAQA.QA~BAAAAAQA.QA~BAAAAABA.QA~BAAAAAAAQA.QA~BAAAAAQA.QA~BAAAAAQA.QA~ZBAA.AQAA~ZBAA.AQAA~ZBAA.AQAA~ZBAA.AQAA", + "DBACOcGA~CPSG_8APSG_8AAAAAAENAAFgAAAAAAAAAAAAAAAAAAAA.IAAA~BPSG_8APSG_8AAAAAAENAACAAAAAAAAAAAAAAAAAAA.YAAAAAAAAAA~1---~CAAAAAAAAABA.QA~BAAAAABA.QA~BAAAABA~BAAAAEA.QA~BAAAAAQA~BAAAAAEA.QA~BAAAAABA~BAAAAABA.QA~BAAAAAABAA.QA~BAAAAAQA.QA~BAAAAAABAA.QA~BAAAAAQA.QA~BAAAAAQA.QA~BAAAAABA.QA~BAAAAAAAQA.QA~BAAAAAQA.QA~BAAAAAQA.QA~ZBAA.AQAA~ZBAA.AQAA~ZBAA.AQAA~ZBAA.AQAA", gppString); } @@ -261,8 +261,7 @@ public void testEncodeTcfEuV2() { Assertions.assertEquals(false, gppModel.hasSection(TcfCaV1.NAME)); String gppString = gppModel.encode(); - Assertions.assertEquals( - "DBABMA~CPSG_8APSG_8ANwAAAENAwCAAAAAAAAAAAAAAAAAAAAA.QAAA.IAAA", gppString); + Assertions.assertEquals("DBABMA~CPSG_8APSG_8ANwAAAENAwCAAAAAAAAAAAAAAAAAAAAA.IAAA", gppString); Assertions.assertEquals(2, gppString.split("~").length); @@ -311,7 +310,7 @@ public void testEncodeUspV1AndTcfEuV2() { String gppString = gppModel.encode(); Assertions.assertEquals( - "DBACNYA~CPSG_8APSG_8ANwAAAENAwCAAAAAAAAAAAAAAAAAAAAA.QAAA.IAAA~1YNN", gppString); + "DBACNYA~CPSG_8APSG_8ANwAAAENAwCAAAAAAAAAAAAAAAAAAAAA.IAAA~1YNN", gppString); Assertions.assertEquals(3, gppString.split("~").length); @@ -412,7 +411,7 @@ public void testEncodeUspV1AndTcfEuV2AndTcfCaV1() { String gppString = gppModel.encode(); Assertions.assertEquals( - "DBACOeA~CPSG_8APSG_8ANwAAAENAwCAAAAAAAAAAAAAAAAAAAAA.QAAA.IAAA~BPSG_8APSG_8AAyACAENGdCgf_gfgAfgfgBgABABAAABAB4AACACAAA.fHHHA4444ao~1YNN", + "DBACOeA~CPSG_8APSG_8ANwAAAENAwCAAAAAAAAAAAAAAAAAAAAA.IAAA~BPSG_8APSG_8AAyACAENGdCgf_gfgAfgfgBgABABAAABAB4AACACAAA.fHHHA4444ao~1YNN", gppString); Assertions.assertEquals(4, gppString.split("~").length); @@ -727,7 +726,7 @@ public void testEncode1() { gppModel.toString(); Assertions.assertEquals( - "DBABMA~CPSG_8APSG_8AAAAAAENAACAAAAAAAAAAAAAAOAAAABAAAAA.QAAA.IAAA", gppModel.encode()); + "DBABMA~CPSG_8APSG_8AAAAAAENAAFgAAAAAAAAAAAAAOAAAABAAAAA.IAAA", gppModel.encode()); } @Test @@ -739,7 +738,7 @@ public void testEncode2() { gppModel.setFieldValue(TcfEuV2.NAME, TcfEuV2Field.LAST_UPDATED, utcDateTime); Assertions.assertEquals( - "DBABMA~CPSG_8APSG_8AAAAAAENAACAAAAAAAAAAAAAAOwAQAOgAAAA.QAAA.IAAA", gppModel.encode()); + "DBABMA~CPSG_8APSG_8AAAAAAENAAFgAAAAAAAAAAAAAOwAQAOgAAAA.IAAA", gppModel.encode()); } @Test @@ -751,8 +750,7 @@ public void testEncode3() { gppModel.setFieldValue(TcfEuV2.NAME, TcfEuV2Field.LAST_UPDATED, utcDateTime); Assertions.assertEquals( - "DBABMA~CPSG_8APSG_8AAAAAAENAACAAAAAAAAAAAAAFpQAwAAgCtAWkAAAAAAA.QAAA.IAAA", - gppModel.encode()); + "DBABMA~CPSG_8APSG_8AAAAAAENAAFgAAAAAAAAAAAAFpQAwAAgCtAWkAAAAAAA.IAAA", gppModel.encode()); } @Test diff --git a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/TcfEuV2Test.java b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/TcfEuV2Test.java index 1abdfb6..a5a0794 100644 --- a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/TcfEuV2Test.java +++ b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/TcfEuV2Test.java @@ -24,8 +24,7 @@ public void testEncode1() { tcfEuV2.setFieldValue( TcfEuV2Field.LAST_UPDATED, ZonedDateTime.of(2022, 1, 1, 0, 0, 0, 0, ZoneId.of("UTC")).toInstant()); - Assertions.assertEquals( - "CPSG_8APSG_8AAAAAAENAACAAAAAAAAAAAAAAAAAAAAA.QAAA.IAAA", tcfEuV2.encode()); + Assertions.assertEquals("CPSG_8APSG_8AAAAAAENAAFgAAAAAAAAAAAAAAAAAAAA.IAAA", tcfEuV2.encode()); TcfEuV2Field.TCFEUV2_CORE_SEGMENT_FIELD_NAMES.toString(); } @@ -51,7 +50,7 @@ public void testEncode2() { Set.of(), tcfEuV2.getFieldValue(TcfEuV2Field.PUBLISHER_CUSTOM_LEGITIMATE_INTERESTS)); Assertions.assertEquals( - "CPSG_8APSG_8AAAAAAENAACgAAAAAAAAAAAAAAAAAAAA.YAAAAAAAAAAA", tcfEuV2.encode()); + "CPSG_8APSG_8AAAAAAENAAFgAAAAAAAAAAAAAAAAAAAA.YAAAAAAAAAAA.IAAA", tcfEuV2.encode()); } @Test From 9d236d042b5574f20d5616729ef97fc3adc5dc2b Mon Sep 17 00:00:00 2001 From: James Yuzawa Date: Sat, 7 Mar 2026 10:54:49 -0500 Subject: [PATCH 09/15] add tests --- .../com/iab/gpp/encoder/field/UsKyField.java | 6 +- .../com/iab/gpp/encoder/field/UsMdField.java | 6 +- .../com/iab/gpp/encoder/field/UsRiField.java | 6 +- .../section/AbstractUsSectionWithHeader.java | 4 +- .../com/iab/gpp/encoder/GppModelTest.java | 4 +- .../com/iab/gpp/encoder/section/UsInTest.java | 140 ++++++++++++++++++ .../com/iab/gpp/encoder/section/UsKyTest.java | 140 ++++++++++++++++++ .../com/iab/gpp/encoder/section/UsMdTest.java | 121 +++++++++++++++ .../com/iab/gpp/encoder/section/UsRiTest.java | 140 ++++++++++++++++++ 9 files changed, 555 insertions(+), 12 deletions(-) create mode 100644 iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UsInTest.java create mode 100644 iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UsKyTest.java create mode 100644 iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UsMdTest.java create mode 100644 iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UsRiTest.java diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/field/UsKyField.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/field/UsKyField.java index e320a14..c05faf7 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/field/UsKyField.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/field/UsKyField.java @@ -4,11 +4,11 @@ import com.iab.gpp.encoder.datatype.EncodableFibonacciIntegerRange; import com.iab.gpp.encoder.datatype.EncodableFixedInteger; import com.iab.gpp.encoder.datatype.EncodableFixedIntegerList; -import com.iab.gpp.encoder.section.UsIn; +import com.iab.gpp.encoder.section.UsKy; public enum UsKyField implements FieldKey { - SECTION_ID(new EncodableFixedInteger<>("SectionID", 6, UsIn.ID)), - VERSION(new EncodableFixedInteger<>("Version", 6, UsIn.VERSION)), + SECTION_ID(new EncodableFixedInteger<>("SectionID", 6, UsKy.ID)), + VERSION(new EncodableFixedInteger<>("Version", 6, UsKy.VERSION)), SUB_SECTIONS(new EncodableFibonacciIntegerRange<>("SubSections")), MSPA_VERSION(new EncodableFixedInteger<>("MspaVersion", 6, 0)), diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/field/UsMdField.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/field/UsMdField.java index cb9f0da..58bf0a9 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/field/UsMdField.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/field/UsMdField.java @@ -4,11 +4,11 @@ import com.iab.gpp.encoder.datatype.EncodableBoolean; import com.iab.gpp.encoder.datatype.EncodableFibonacciIntegerRange; import com.iab.gpp.encoder.datatype.EncodableFixedInteger; -import com.iab.gpp.encoder.section.UsIn; +import com.iab.gpp.encoder.section.UsMd; public enum UsMdField implements FieldKey { - SECTION_ID(new EncodableFixedInteger<>("SectionID", 6, UsIn.ID)), - VERSION(new EncodableFixedInteger<>("Version", 6, UsIn.VERSION)), + SECTION_ID(new EncodableFixedInteger<>("SectionID", 6, UsMd.ID)), + VERSION(new EncodableFixedInteger<>("Version", 6, UsMd.VERSION)), SUB_SECTIONS(new EncodableFibonacciIntegerRange<>("SubSections")), MSPA_VERSION(new EncodableFixedInteger<>("MspaVersion", 6, 0)), diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/field/UsRiField.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/field/UsRiField.java index fc5fe33..d5e5917 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/field/UsRiField.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/field/UsRiField.java @@ -4,11 +4,11 @@ import com.iab.gpp.encoder.datatype.EncodableFibonacciIntegerRange; import com.iab.gpp.encoder.datatype.EncodableFixedInteger; import com.iab.gpp.encoder.datatype.EncodableFixedIntegerList; -import com.iab.gpp.encoder.section.UsIn; +import com.iab.gpp.encoder.section.UsRi; public enum UsRiField implements FieldKey { - SECTION_ID(new EncodableFixedInteger<>("SectionID", 6, UsIn.ID)), - VERSION(new EncodableFixedInteger<>("Version", 6, UsIn.VERSION)), + SECTION_ID(new EncodableFixedInteger<>("SectionID", 6, UsRi.ID)), + VERSION(new EncodableFixedInteger<>("Version", 6, UsRi.VERSION)), SUB_SECTIONS(new EncodableFibonacciIntegerRange<>("SubSections")), MSPA_VERSION(new EncodableFixedInteger<>("MspaVersion", 6, 0)), diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/AbstractUsSectionWithHeader.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/AbstractUsSectionWithHeader.java index 8b7c317..00b4cb1 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/AbstractUsSectionWithHeader.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/AbstractUsSectionWithHeader.java @@ -26,6 +26,7 @@ protected final void doDecode(CharSequence encodedString) { List encodedSegments = SlicedCharSequence.split(encodedString, '.'); getSegment(0).decode(encodedSegments.get(0)); IntegerSet subSections = getSubSections(); + subSections.addInt(0); PrimitiveIterator.OfInt it = subSections.iterator(); while (it.hasNext()) { int subSectionIndex = 1 + it.nextInt(); @@ -38,13 +39,14 @@ protected final CharSequence doEncode() { int size = size(); List encodedSegments = new ArrayList<>(size); IntegerSet subSections = getSubSections(); - for (int i = 1; i < size(); i++) { + for (int i = 2; i < size(); i++) { EncodableSegment segment = getSegment(i); if (segment.shouldEncode()) { subSections.add(i - 1); } } encodedSegments.add(getSegment(0).encodeCharSequence()); + encodedSegments.add(getSegment(1).encodeCharSequence()); PrimitiveIterator.OfInt it = subSections.iterator(); while (it.hasNext()) { int subSectionIndex = 1 + it.nextInt(); diff --git a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/GppModelTest.java b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/GppModelTest.java index a2f6b44..f6762ff 100644 --- a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/GppModelTest.java +++ b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/GppModelTest.java @@ -168,7 +168,7 @@ public void testEncodeDefaultAll() { String gppString = gppModel.encode(); Assertions.assertEquals( - "DBACOcGA~CPSG_8APSG_8AAAAAAENAAFgAAAAAAAAAAAAAAAAAAAA.IAAA~BPSG_8APSG_8AAAAAAENAACAAAAAAAAAAAAAAAAAAA.YAAAAAAAAAA~1---~CAAAAAAAAABA.QA~BAAAAABA.QA~BAAAABA~BAAAAEA.QA~BAAAAAQA~BAAAAAEA.QA~BAAAAABA~BAAAAABA.QA~BAAAAAABAA.QA~BAAAAAQA.QA~BAAAAAABAA.QA~BAAAAAQA.QA~BAAAAAQA.QA~BAAAAABA.QA~BAAAAAAAQA.QA~BAAAAAQA.QA~BAAAAAQA.QA~ZBAA.AQAA~ZBAA.AQAA~ZBAA.AQAA~ZBAA.AQAA", + "DBACOcGA~CPSG_8APSG_8AAAAAAENAAFgAAAAAAAAAAAAAAAAAAAA.IAAA~BPSG_8APSG_8AAAAAAENAACAAAAAAAAAAAAAAAAAAA.YAAAAAAAAAA~1---~CAAAAAAAAABA.QA~BAAAAABA.QA~BAAAABA~BAAAAEA.QA~BAAAAAQA~BAAAAAEA.QA~BAAAAABA~BAAAAABA.QA~BAAAAAABAA.QA~BAAAAAQA.QA~BAAAAAABAA.QA~BAAAAAQA.QA~BAAAAAQA.QA~BAAAAABA.QA~BAAAAAAAQA.QA~BAAAAAQA.QA~BAAAAAQA.QA~YBAA.AQAA~ZBAA.AQAA~aBAA.AQAA~bBAA.AQAA", gppString); } @@ -443,7 +443,7 @@ public void testDecodeDefaults() { @Test public void testDecodeDefaultsAll() { String gppString = - "DBACOcGA~CPSG_8APSG_8AAAAAAENAACAAAAAAAAAAAAAAAAAAAAA.QAAA.IAAA~BPSG_8APSG_8AAAAAAENAACAAAAAAAAAAAAAAAAAAA.YAAAAAAAAAA~1---~CAAAAAAAAABA.QA~BAAAAABA.QA~BAAAABA~BAAAAEA.QA~BAAAAAQA~BAAAAAEA.QA~BAAAAABA~BAAAAABA.QA~BAAAAAABAA.QA~BAAAAAQA.QA~BAAAAAABAA.QA~BAAAAAQA.QA~BAAAAAQA.QA~BAAAAABA.QA~BAAAAAAAQA.QA~BAAAAAQA.QA~BAAAAAQA.QA~ZBAA.AQAA~ZBAA.AQAA~ZBAA.AQAA~ZBAA.AQAA"; + "DBACOcGA~CPSG_8APSG_8AAAAAAENAAFgAAAAAAAAAAAAAAAAAAAA.IAAA~BPSG_8APSG_8AAAAAAENAACAAAAAAAAAAAAAAAAAAA.YAAAAAAAAAA~1---~CAAAAAAAAABA.QA~BAAAAABA.QA~BAAAABA~BAAAAEA.QA~BAAAAAQA~BAAAAAEA.QA~BAAAAABA~BAAAAABA.QA~BAAAAAABAA.QA~BAAAAAQA.QA~BAAAAAABAA.QA~BAAAAAQA.QA~BAAAAAQA.QA~BAAAAABA.QA~BAAAAAAAQA.QA~BAAAAAQA.QA~BAAAAAQA.QA~YBAA.AQAA~ZBAA.AQAA~aBAA.AQAA~bBAA.AQAA"; GppModel gppModel = new GppModel(gppString); Assertions.assertEquals(true, gppModel.hasSection(TcfEuV2.NAME)); diff --git a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UsInTest.java b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UsInTest.java new file mode 100644 index 0000000..904e1b8 --- /dev/null +++ b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UsInTest.java @@ -0,0 +1,140 @@ +package com.iab.gpp.encoder.section; + +import com.iab.gpp.encoder.error.DecodingException; +import com.iab.gpp.encoder.error.ValidationException; +import com.iab.gpp.encoder.field.UsInField; +import java.util.Arrays; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +public class UsInTest { + + @Test + public void testEncode1() { + UsIn usIn = new UsIn(); + Assertions.assertEquals("ZBAA.AQAA", usIn.encode()); + } + + @Test + public void testEncode2() { + UsIn usIn = new UsIn(); + + usIn.setFieldValue(UsInField.PROCESSING_NOTICE, 1); + usIn.setFieldValue(UsInField.SALE_OPT_OUT_NOTICE, 1); + usIn.setFieldValue(UsInField.TARGETED_ADVERTISING_OPT_OUT_NOTICE, 1); + usIn.setFieldValue(UsInField.SALE_OPT_OUT, 1); + usIn.setFieldValue(UsInField.TARGETED_ADVERTISING_OPT_OUT, 1); + usIn.setFieldValue(UsInField.SENSITIVE_DATA_PROCESSING, Arrays.asList(2, 1, 0, 2, 1, 0, 2, 1)); + usIn.setFieldValue(UsInField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS, 1); + usIn.setFieldValue(UsInField.ADDITIONAL_DATA_PROCESSING_CONSENT, 1); + usIn.setFieldValue(UsInField.MSPA_COVERED_TRANSACTION, 1); + usIn.setFieldValue(UsInField.MSPA_MODE, 1); + usIn.setFieldValue(UsInField.MSPA_VERSION, 1); + + Assertions.assertEquals("ZBABYA.BVVV.kkk", usIn.encode()); + } + + @Test + public void testSetInvalidValues() { + UsIn usIn = new UsIn(); + + try { + usIn.setFieldValue(UsInField.PROCESSING_NOTICE, 3); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usIn.setFieldValue(UsInField.SALE_OPT_OUT_NOTICE, 3); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usIn.setFieldValue(UsInField.TARGETED_ADVERTISING_OPT_OUT_NOTICE, 3); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usIn.setFieldValue(UsInField.SALE_OPT_OUT, 3); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usIn.setFieldValue(UsInField.TARGETED_ADVERTISING_OPT_OUT, -1); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usIn.setFieldValue( + UsInField.SENSITIVE_DATA_PROCESSING, Arrays.asList(0, 1, 2, 3, 1, 2, 0, 1)); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usIn.setFieldValue(UsInField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS, 3); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usIn.setFieldValue(UsInField.ADDITIONAL_DATA_PROCESSING_CONSENT, 3); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usIn.setFieldValue(UsInField.MSPA_COVERED_TRANSACTION, 0); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usIn.setFieldValue(UsInField.MSPA_MODE, 4); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + } + + @Test + public void testDecode1() throws DecodingException { + UsIn usIn = new UsIn("ZBABYA.BVVV.kkk"); + + Assertions.assertEquals(1, usIn.getVersion()); + Assertions.assertEquals(1, usIn.getProcessingNotice()); + Assertions.assertEquals(1, usIn.getSaleOptOutNotice()); + Assertions.assertEquals(1, usIn.getTargetedAdvertisingOptOutNotice()); + Assertions.assertEquals(1, usIn.getSaleOptOut()); + Assertions.assertEquals(1, usIn.getTargetedAdvertisingOptOut()); + Assertions.assertEquals( + Arrays.asList(2, 1, 0, 2, 1, 0, 2, 1), usIn.getSensitiveDataProcessing()); + Assertions.assertEquals(1, usIn.getKnownChildSensitiveDataConsents()); + Assertions.assertEquals(1, usIn.getAdditionalDataProcessingConsent()); + Assertions.assertEquals(1, usIn.getMspaCoveredTransaction()); + Assertions.assertEquals(1, usIn.getMspaMode()); + Assertions.assertEquals(1, usIn.getMspaVersion()); + } + + @Test() + public void testDecodeGarbage() { + Assertions.assertThrows( + DecodingException.class, + () -> { + new UsIn("z").getProcessingNotice(); + }); + } +} diff --git a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UsKyTest.java b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UsKyTest.java new file mode 100644 index 0000000..11d3ad3 --- /dev/null +++ b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UsKyTest.java @@ -0,0 +1,140 @@ +package com.iab.gpp.encoder.section; + +import com.iab.gpp.encoder.error.DecodingException; +import com.iab.gpp.encoder.error.ValidationException; +import com.iab.gpp.encoder.field.UsKyField; +import java.util.Arrays; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +public class UsKyTest { + + @Test + public void testEncode1() { + UsKy usKy = new UsKy(); + Assertions.assertEquals("aBAA.AQAA", usKy.encode()); + } + + @Test + public void testEncode2() { + UsKy usKy = new UsKy(); + + usKy.setFieldValue(UsKyField.PROCESSING_NOTICE, 1); + usKy.setFieldValue(UsKyField.SALE_OPT_OUT_NOTICE, 1); + usKy.setFieldValue(UsKyField.TARGETED_ADVERTISING_OPT_OUT_NOTICE, 1); + usKy.setFieldValue(UsKyField.SALE_OPT_OUT, 1); + usKy.setFieldValue(UsKyField.TARGETED_ADVERTISING_OPT_OUT, 1); + usKy.setFieldValue(UsKyField.SENSITIVE_DATA_PROCESSING, Arrays.asList(2, 1, 0, 2, 1, 0, 2, 1)); + usKy.setFieldValue(UsKyField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS, 1); + usKy.setFieldValue(UsKyField.ADDITIONAL_DATA_PROCESSING_CONSENT, 1); + usKy.setFieldValue(UsKyField.MSPA_COVERED_TRANSACTION, 1); + usKy.setFieldValue(UsKyField.MSPA_MODE, 1); + usKy.setFieldValue(UsKyField.MSPA_VERSION, 1); + + Assertions.assertEquals("aBABYA.BVVV.kkk", usKy.encode()); + } + + @Test + public void testSetInvalidValues() { + UsKy usKy = new UsKy(); + + try { + usKy.setFieldValue(UsKyField.PROCESSING_NOTICE, 3); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usKy.setFieldValue(UsKyField.SALE_OPT_OUT_NOTICE, 3); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usKy.setFieldValue(UsKyField.TARGETED_ADVERTISING_OPT_OUT_NOTICE, 3); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usKy.setFieldValue(UsKyField.SALE_OPT_OUT, 3); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usKy.setFieldValue(UsKyField.TARGETED_ADVERTISING_OPT_OUT, -1); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usKy.setFieldValue( + UsKyField.SENSITIVE_DATA_PROCESSING, Arrays.asList(0, 1, 2, 3, 1, 2, 0, 1)); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usKy.setFieldValue(UsKyField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS, 3); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usKy.setFieldValue(UsKyField.ADDITIONAL_DATA_PROCESSING_CONSENT, 3); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usKy.setFieldValue(UsKyField.MSPA_COVERED_TRANSACTION, 0); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usKy.setFieldValue(UsKyField.MSPA_MODE, 4); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + } + + @Test + public void testDecode1() throws DecodingException { + UsKy usKy = new UsKy("aBABYA.BVVV.kkk"); + + Assertions.assertEquals(1, usKy.getVersion()); + Assertions.assertEquals(1, usKy.getProcessingNotice()); + Assertions.assertEquals(1, usKy.getSaleOptOutNotice()); + Assertions.assertEquals(1, usKy.getTargetedAdvertisingOptOutNotice()); + Assertions.assertEquals(1, usKy.getSaleOptOut()); + Assertions.assertEquals(1, usKy.getTargetedAdvertisingOptOut()); + Assertions.assertEquals( + Arrays.asList(2, 1, 0, 2, 1, 0, 2, 1), usKy.getSensitiveDataProcessing()); + Assertions.assertEquals(1, usKy.getKnownChildSensitiveDataConsents()); + Assertions.assertEquals(1, usKy.getAdditionalDataProcessingConsent()); + Assertions.assertEquals(1, usKy.getMspaCoveredTransaction()); + Assertions.assertEquals(1, usKy.getMspaMode()); + Assertions.assertEquals(1, usKy.getMspaVersion()); + } + + @Test() + public void testDecodeGarbage() { + Assertions.assertThrows( + DecodingException.class, + () -> { + new UsKy("z").getProcessingNotice(); + }); + } +} diff --git a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UsMdTest.java b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UsMdTest.java new file mode 100644 index 0000000..8c2748f --- /dev/null +++ b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UsMdTest.java @@ -0,0 +1,121 @@ +package com.iab.gpp.encoder.section; + +import com.iab.gpp.encoder.error.DecodingException; +import com.iab.gpp.encoder.error.ValidationException; +import com.iab.gpp.encoder.field.UsMdField; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +public class UsMdTest { + + @Test + public void testEncode1() { + UsMd usMd = new UsMd(); + Assertions.assertEquals("YBAA.AQAA", usMd.encode()); + } + + @Test + public void testEncode2() { + UsMd usMd = new UsMd(); + + usMd.setFieldValue(UsMdField.PROCESSING_NOTICE, 1); + usMd.setFieldValue(UsMdField.SALE_OPT_OUT_NOTICE, 1); + usMd.setFieldValue(UsMdField.TARGETED_ADVERTISING_OPT_OUT_NOTICE, 1); + usMd.setFieldValue(UsMdField.SALE_OPT_OUT, 1); + usMd.setFieldValue(UsMdField.TARGETED_ADVERTISING_OPT_OUT, 1); + usMd.setFieldValue(UsMdField.ADDITIONAL_DATA_PROCESSING_CONSENT, 1); + usMd.setFieldValue(UsMdField.MSPA_COVERED_TRANSACTION, 1); + usMd.setFieldValue(UsMdField.MSPA_MODE, 1); + usMd.setFieldValue(UsMdField.MSPA_VERSION, 1); + usMd.setFieldValue(UsMdField.GPC, true); + + Assertions.assertEquals("YBABYA.BVVU.YA", usMd.encode()); + } + + @Test + public void testSetInvalidValues() { + UsMd usMd = new UsMd(); + + try { + usMd.setFieldValue(UsMdField.PROCESSING_NOTICE, 3); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usMd.setFieldValue(UsMdField.SALE_OPT_OUT_NOTICE, 3); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usMd.setFieldValue(UsMdField.TARGETED_ADVERTISING_OPT_OUT_NOTICE, 3); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usMd.setFieldValue(UsMdField.SALE_OPT_OUT, 3); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usMd.setFieldValue(UsMdField.TARGETED_ADVERTISING_OPT_OUT, -1); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usMd.setFieldValue(UsMdField.ADDITIONAL_DATA_PROCESSING_CONSENT, 3); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usMd.setFieldValue(UsMdField.MSPA_COVERED_TRANSACTION, 0); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usMd.setFieldValue(UsMdField.MSPA_MODE, 4); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + } + + @Test + public void testDecode1() throws DecodingException { + UsMd usMd = new UsMd("YBABYA.BVVU.YA"); + + Assertions.assertEquals(1, usMd.getVersion()); + Assertions.assertEquals(1, usMd.getProcessingNotice()); + Assertions.assertEquals(1, usMd.getSaleOptOutNotice()); + Assertions.assertEquals(1, usMd.getTargetedAdvertisingOptOutNotice()); + Assertions.assertEquals(1, usMd.getSaleOptOut()); + Assertions.assertEquals(1, usMd.getTargetedAdvertisingOptOut()); + Assertions.assertEquals(1, usMd.getAdditionalDataProcessingConsent()); + Assertions.assertEquals(1, usMd.getMspaCoveredTransaction()); + Assertions.assertEquals(1, usMd.getMspaMode()); + Assertions.assertEquals(1, usMd.getMspaVersion()); + Assertions.assertEquals(true, usMd.getGpc()); + } + + @Test() + public void testDecodeGarbage() { + Assertions.assertThrows( + DecodingException.class, + () -> { + new UsMd("z").getProcessingNotice(); + }); + } +} diff --git a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UsRiTest.java b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UsRiTest.java new file mode 100644 index 0000000..e5d05c9 --- /dev/null +++ b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UsRiTest.java @@ -0,0 +1,140 @@ +package com.iab.gpp.encoder.section; + +import com.iab.gpp.encoder.error.DecodingException; +import com.iab.gpp.encoder.error.ValidationException; +import com.iab.gpp.encoder.field.UsRiField; +import java.util.Arrays; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +public class UsRiTest { + + @Test + public void testEncode1() { + UsRi usRi = new UsRi(); + Assertions.assertEquals("bBAA.AQAA", usRi.encode()); + } + + @Test + public void testEncode2() { + UsRi usRi = new UsRi(); + + usRi.setFieldValue(UsRiField.PROCESSING_NOTICE, 1); + usRi.setFieldValue(UsRiField.SALE_OPT_OUT_NOTICE, 1); + usRi.setFieldValue(UsRiField.TARGETED_ADVERTISING_OPT_OUT_NOTICE, 1); + usRi.setFieldValue(UsRiField.SALE_OPT_OUT, 1); + usRi.setFieldValue(UsRiField.TARGETED_ADVERTISING_OPT_OUT, 1); + usRi.setFieldValue(UsRiField.SENSITIVE_DATA_PROCESSING, Arrays.asList(2, 1, 0, 2, 1, 0, 2, 1)); + usRi.setFieldValue(UsRiField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS, 1); + usRi.setFieldValue(UsRiField.ADDITIONAL_DATA_PROCESSING_CONSENT, 1); + usRi.setFieldValue(UsRiField.MSPA_COVERED_TRANSACTION, 1); + usRi.setFieldValue(UsRiField.MSPA_MODE, 1); + usRi.setFieldValue(UsRiField.MSPA_VERSION, 1); + + Assertions.assertEquals("bBABYA.BVVV.kkk", usRi.encode()); + } + + @Test + public void testSetInvalidValues() { + UsRi usRi = new UsRi(); + + try { + usRi.setFieldValue(UsRiField.PROCESSING_NOTICE, 3); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usRi.setFieldValue(UsRiField.SALE_OPT_OUT_NOTICE, 3); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usRi.setFieldValue(UsRiField.TARGETED_ADVERTISING_OPT_OUT_NOTICE, 3); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usRi.setFieldValue(UsRiField.SALE_OPT_OUT, 3); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usRi.setFieldValue(UsRiField.TARGETED_ADVERTISING_OPT_OUT, -1); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usRi.setFieldValue( + UsRiField.SENSITIVE_DATA_PROCESSING, Arrays.asList(0, 1, 2, 3, 1, 2, 0, 1)); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usRi.setFieldValue(UsRiField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS, 3); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usRi.setFieldValue(UsRiField.ADDITIONAL_DATA_PROCESSING_CONSENT, 3); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usRi.setFieldValue(UsRiField.MSPA_COVERED_TRANSACTION, 0); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usRi.setFieldValue(UsRiField.MSPA_MODE, 4); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + } + + @Test + public void testDecode1() throws DecodingException { + UsRi usRi = new UsRi("bBABYA.BVVV.kkk"); + + Assertions.assertEquals(1, usRi.getVersion()); + Assertions.assertEquals(1, usRi.getProcessingNotice()); + Assertions.assertEquals(1, usRi.getSaleOptOutNotice()); + Assertions.assertEquals(1, usRi.getTargetedAdvertisingOptOutNotice()); + Assertions.assertEquals(1, usRi.getSaleOptOut()); + Assertions.assertEquals(1, usRi.getTargetedAdvertisingOptOut()); + Assertions.assertEquals( + Arrays.asList(2, 1, 0, 2, 1, 0, 2, 1), usRi.getSensitiveDataProcessing()); + Assertions.assertEquals(1, usRi.getKnownChildSensitiveDataConsents()); + Assertions.assertEquals(1, usRi.getAdditionalDataProcessingConsent()); + Assertions.assertEquals(1, usRi.getMspaCoveredTransaction()); + Assertions.assertEquals(1, usRi.getMspaMode()); + Assertions.assertEquals(1, usRi.getMspaVersion()); + } + + @Test() + public void testDecodeGarbage() { + Assertions.assertThrows( + DecodingException.class, + () -> { + new UsRi("z").getProcessingNotice(); + }); + } +} From c04932814742e22328c28912688a3554d5723484 Mon Sep 17 00:00:00 2001 From: James Yuzawa Date: Sat, 7 Mar 2026 11:03:18 -0500 Subject: [PATCH 10/15] remove gpc segment type --- .../com/iab/gpp/encoder/section/AbstractUsSectionWithGpc.java | 2 -- .../src/main/java/com/iab/gpp/encoder/section/UsCa.java | 4 ---- .../src/main/java/com/iab/gpp/encoder/section/UsCo.java | 4 ---- .../src/main/java/com/iab/gpp/encoder/section/UsCt.java | 4 ---- .../src/main/java/com/iab/gpp/encoder/section/UsDe.java | 4 ---- .../src/main/java/com/iab/gpp/encoder/section/UsIa.java | 4 ---- .../src/main/java/com/iab/gpp/encoder/section/UsMn.java | 4 ---- .../src/main/java/com/iab/gpp/encoder/section/UsMt.java | 4 ---- .../src/main/java/com/iab/gpp/encoder/section/UsNat.java | 4 ---- .../src/main/java/com/iab/gpp/encoder/section/UsNe.java | 4 ---- .../src/main/java/com/iab/gpp/encoder/section/UsNh.java | 4 ---- .../src/main/java/com/iab/gpp/encoder/section/UsNj.java | 4 ---- .../src/main/java/com/iab/gpp/encoder/section/UsOr.java | 4 ---- .../src/main/java/com/iab/gpp/encoder/section/UsTn.java | 4 ---- .../src/main/java/com/iab/gpp/encoder/section/UsTx.java | 4 ---- 15 files changed, 58 deletions(-) diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/AbstractUsSectionWithGpc.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/AbstractUsSectionWithGpc.java index 2fce463..3a0ef10 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/AbstractUsSectionWithGpc.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/AbstractUsSectionWithGpc.java @@ -46,8 +46,6 @@ protected final CharSequence doEncode() { return SlicedCharSequence.join('.', encodedSegments); } - public abstract Integer getGpcSegmentType(); - public Boolean getGpcSegmentIncluded() { return (Boolean) getSegment(1).getFieldValue(getGpcSegmentIncludedKey()); } 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 c51eb0d..6b891c6 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 @@ -85,10 +85,6 @@ public Integer getMspaServiceProviderMode() { return (Integer) this.getFieldValue(UsCaField.MSPA_SERVICE_PROVIDER_MODE); } - public Integer getGpcSegmentType() { - return (Integer) this.getFieldValue(UsCaField.GPC_SEGMENT_TYPE); - } - public Boolean getGpc() { return (Boolean) this.getFieldValue(UsCaField.GPC); } 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 63f6de5..b7a5a5f 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 @@ -81,10 +81,6 @@ public Integer getMspaServiceProviderMode() { return (Integer) this.getFieldValue(UsCoField.MSPA_SERVICE_PROVIDER_MODE); } - public Integer getGpcSegmentType() { - return (Integer) this.getFieldValue(UsCoField.GPC_SEGMENT_TYPE); - } - public Boolean getGpc() { return (Boolean) this.getFieldValue(UsCoField.GPC); } 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 5d1cddd..3b34310 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 @@ -81,10 +81,6 @@ public Integer getMspaServiceProviderMode() { return (Integer) this.getFieldValue(UsCtField.MSPA_SERVICE_PROVIDER_MODE); } - public Integer getGpcSegmentType() { - return (Integer) this.getFieldValue(UsCtField.GPC_SEGMENT_TYPE); - } - public Boolean getGpc() { return (Boolean) this.getFieldValue(UsCtField.GPC); } 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 8fb0888..135df49 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 @@ -85,10 +85,6 @@ public Integer getMspaServiceProviderMode() { return (Integer) this.getFieldValue(UsDeField.MSPA_SERVICE_PROVIDER_MODE); } - public Integer getGpcSegmentType() { - return (Integer) this.getFieldValue(UsDeField.GPC_SEGMENT_TYPE); - } - public Boolean getGpc() { return (Boolean) this.getFieldValue(UsDeField.GPC); } 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 918066b..71ab745 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 @@ -85,10 +85,6 @@ public Integer getMspaServiceProviderMode() { return (Integer) this.getFieldValue(UsIaField.MSPA_SERVICE_PROVIDER_MODE); } - public Integer getGpcSegmentType() { - return (Integer) this.getFieldValue(UsIaField.GPC_SEGMENT_TYPE); - } - public Boolean getGpc() { return (Boolean) this.getFieldValue(UsIaField.GPC); } diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsMn.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsMn.java index eab0847..1b90a08 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsMn.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsMn.java @@ -85,10 +85,6 @@ public Integer getMspaServiceProviderMode() { return (Integer) this.getFieldValue(UsMnField.MSPA_SERVICE_PROVIDER_MODE); } - public Integer getGpcSegmentType() { - return (Integer) this.getFieldValue(UsMnField.GPC_SEGMENT_TYPE); - } - public Boolean getGpc() { return (Boolean) this.getFieldValue(UsMnField.GPC); } 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 972f661..6546b72 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 @@ -85,10 +85,6 @@ public Integer getMspaServiceProviderMode() { return (Integer) this.getFieldValue(UsMtField.MSPA_SERVICE_PROVIDER_MODE); } - public Integer getGpcSegmentType() { - return (Integer) this.getFieldValue(UsMtField.GPC_SEGMENT_TYPE); - } - public Boolean getGpc() { return (Boolean) this.getFieldValue(UsMtField.GPC); } 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 e6f07b1..6f48947 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 @@ -101,10 +101,6 @@ public Integer getMspaServiceProviderMode() { return (Integer) this.getFieldValue(UsNatField.MSPA_SERVICE_PROVIDER_MODE); } - public Integer getGpcSegmentType() { - return (Integer) this.getFieldValue(UsNatField.GPC_SEGMENT_TYPE); - } - public Boolean getGpc() { return (Boolean) this.getFieldValue(UsNatField.GPC); } 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 5b6beb2..f9532cf 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 @@ -85,10 +85,6 @@ public Integer getMspaServiceProviderMode() { return (Integer) this.getFieldValue(UsNeField.MSPA_SERVICE_PROVIDER_MODE); } - public Integer getGpcSegmentType() { - return (Integer) this.getFieldValue(UsNeField.GPC_SEGMENT_TYPE); - } - public Boolean getGpc() { return (Boolean) this.getFieldValue(UsNeField.GPC); } 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 413357a..9aad2ea 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 @@ -85,10 +85,6 @@ public Integer getMspaServiceProviderMode() { return (Integer) this.getFieldValue(UsNhField.MSPA_SERVICE_PROVIDER_MODE); } - public Integer getGpcSegmentType() { - return (Integer) this.getFieldValue(UsNhField.GPC_SEGMENT_TYPE); - } - public Boolean getGpc() { return (Boolean) this.getFieldValue(UsNhField.GPC); } 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 2e99650..687a799 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 @@ -85,10 +85,6 @@ public Integer getMspaServiceProviderMode() { return (Integer) this.getFieldValue(UsNjField.MSPA_SERVICE_PROVIDER_MODE); } - public Integer getGpcSegmentType() { - return (Integer) this.getFieldValue(UsNjField.GPC_SEGMENT_TYPE); - } - public Boolean getGpc() { return (Boolean) this.getFieldValue(UsNjField.GPC); } 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 ddd2be6..5481d0d 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 @@ -85,10 +85,6 @@ public Integer getMspaServiceProviderMode() { return (Integer) this.getFieldValue(UsOrField.MSPA_SERVICE_PROVIDER_MODE); } - public Integer getGpcSegmentType() { - return (Integer) this.getFieldValue(UsOrField.GPC_SEGMENT_TYPE); - } - public Boolean getGpc() { return (Boolean) this.getFieldValue(UsOrField.GPC); } 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 89cf984..487354d 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 @@ -85,10 +85,6 @@ public Integer getMspaServiceProviderMode() { return (Integer) this.getFieldValue(UsTnField.MSPA_SERVICE_PROVIDER_MODE); } - public Integer getGpcSegmentType() { - return (Integer) this.getFieldValue(UsTnField.GPC_SEGMENT_TYPE); - } - public Boolean getGpc() { return (Boolean) this.getFieldValue(UsTnField.GPC); } 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 40bac9d..4eff422 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 @@ -85,10 +85,6 @@ public Integer getMspaServiceProviderMode() { return (Integer) this.getFieldValue(UsTxField.MSPA_SERVICE_PROVIDER_MODE); } - public Integer getGpcSegmentType() { - return (Integer) this.getFieldValue(UsTxField.GPC_SEGMENT_TYPE); - } - public Boolean getGpc() { return (Boolean) this.getFieldValue(UsTxField.GPC); } From 12df6ed9e641b14ecee4305ae4d65dc712a4ef0e Mon Sep 17 00:00:00 2001 From: James Yuzawa Date: Sat, 7 Mar 2026 11:03:24 -0500 Subject: [PATCH 11/15] add more tests --- .../src/test/java/com/iab/gpp/encoder/section/TcfCaV1Test.java | 3 +++ .../src/test/java/com/iab/gpp/encoder/section/UsCaTest.java | 2 ++ .../src/test/java/com/iab/gpp/encoder/section/UsNatTest.java | 3 +++ .../src/test/java/com/iab/gpp/encoder/section/UsUtTest.java | 2 ++ 4 files changed, 10 insertions(+) diff --git a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/TcfCaV1Test.java b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/TcfCaV1Test.java index 6039239..9c184d5 100644 --- a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/TcfCaV1Test.java +++ b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/TcfCaV1Test.java @@ -114,6 +114,9 @@ public void testDecode1() { Assertions.assertEquals(0, tcfCaV1.getCmpId()); Assertions.assertEquals(0, tcfCaV1.getCmpVersion()); Assertions.assertEquals(0, tcfCaV1.getVendorListVersion()); + Assertions.assertEquals(0, tcfCaV1.getConsentScreen()); + Assertions.assertEquals(2, tcfCaV1.getPolicyVersion()); + Assertions.assertEquals(1, tcfCaV1.getVersion()); Assertions.assertEquals(false, tcfCaV1.getUseNonStandardStacks()); Assertions.assertEquals(Set.of(), tcfCaV1.getSpecialFeatureExpressConsent()); Assertions.assertEquals(Set.of(), tcfCaV1.getPurposesExpressConsent()); diff --git a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UsCaTest.java b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UsCaTest.java index 3ef7975..cd9e54c 100644 --- a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UsCaTest.java +++ b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UsCaTest.java @@ -153,8 +153,10 @@ public void testEncodeWithGpcSegmentExcluded() { public void testDecode1() { UsCa usCa = new UsCa("BVWSSSVY.YA"); + Assertions.assertEquals(1, usCa.getVersion()); Assertions.assertEquals(1, usCa.getSaleOptOutNotice()); Assertions.assertEquals(1, usCa.getSharingOptOut()); + Assertions.assertEquals(1, usCa.getSharingOptOutNotice()); Assertions.assertEquals(1, usCa.getSensitiveDataLimitUseNotice()); Assertions.assertEquals(1, usCa.getSaleOptOut()); Assertions.assertEquals(1, usCa.getSharingOptOut()); diff --git a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UsNatTest.java b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UsNatTest.java index d535788..5c5322f 100644 --- a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UsNatTest.java +++ b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UsNatTest.java @@ -191,6 +191,7 @@ public void testEncodeWithGpcSegmentIncluded() { public void testDecode1() throws DecodingException { UsNat usNat = new UsNat("CVVVkkkkkpFY.YA"); + Assertions.assertEquals(2, usNat.getVersion()); Assertions.assertEquals(1, usNat.getSharingNotice()); Assertions.assertEquals(1, usNat.getSaleOptOutNotice()); Assertions.assertEquals(1, usNat.getSharingOptOutNotice()); @@ -215,6 +216,7 @@ public void testDecode1() throws DecodingException { public void testDecodeWithGpcSegmentExcluded() throws DecodingException { UsNat usNat = new UsNat("BVVVkkkkkpFY"); + Assertions.assertEquals(2, usNat.getVersion()); Assertions.assertEquals(1, usNat.getSharingNotice()); Assertions.assertEquals(1, usNat.getSaleOptOutNotice()); Assertions.assertEquals(1, usNat.getSharingOptOutNotice()); @@ -239,6 +241,7 @@ public void testDecodeWithGpcSegmentExcluded() throws DecodingException { public void testDecodeBackwardsCompatibility() throws DecodingException { UsNat usNat = new UsNat("BVQqAAAACg"); + Assertions.assertEquals(1, usNat.getVersion()); Assertions.assertEquals(1, usNat.getSharingNotice()); Assertions.assertEquals(1, usNat.getSaleOptOutNotice()); Assertions.assertEquals(1, usNat.getSharingOptOutNotice()); diff --git a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UsUtTest.java b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UsUtTest.java index 3ad6dc0..20c3e7f 100644 --- a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UsUtTest.java +++ b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UsUtTest.java @@ -121,10 +121,12 @@ public void testSetInvalidValues() { public void testDecode1() throws DecodingException { UsUt usUt = new UsUt("BVVkklWA"); + Assertions.assertEquals(1, usUt.getVersion()); Assertions.assertEquals(1, usUt.getSharingNotice()); Assertions.assertEquals(1, usUt.getSaleOptOutNotice()); Assertions.assertEquals(1, usUt.getTargetedAdvertisingOptOutNotice()); Assertions.assertEquals(1, usUt.getSaleOptOut()); + Assertions.assertEquals(1, usUt.getSensitiveDataProcessingOptOutNotice()); Assertions.assertEquals(1, usUt.getTargetedAdvertisingOptOut()); Assertions.assertEquals( Arrays.asList(2, 1, 0, 2, 1, 0, 2, 1), usUt.getSensitiveDataProcessing()); From 2b3341cd3ff1bb959fece87d3cdd343b1ecd5ba0 Mon Sep 17 00:00:00 2001 From: James Yuzawa Date: Sat, 7 Mar 2026 11:07:09 -0500 Subject: [PATCH 12/15] add new getters --- .../java/com/iab/gpp/encoder/GppModel.java | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/GppModel.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/GppModel.java index 83427bf..a2a7d26 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/GppModel.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/GppModel.java @@ -47,7 +47,8 @@ public class GppModel extends AbstractEncodable { static { List>> constructors = new ArrayList<>(); - // register section constructors here + // ADDING A NEW SECTION: + // register section constructors here and add get*Section() method below constructors.add(TcfEuV2::new); constructors.add(TcfCaV1::new); constructors.add(UspV1::new); @@ -271,6 +272,22 @@ public UsMn getUsMnSection() { return (UsMn) getSection(UsMn.ID); } + public UsIn getUsInSection() { + return (UsIn) getSection(UsIn.ID); + } + + public UsKy getUsKySection() { + return (UsKy) getSection(UsKy.ID); + } + + public UsMd getUsMdSection() { + return (UsMd) getSection(UsMd.ID); + } + + public UsRi getUsRiSection() { + return (UsRi) getSection(UsRi.ID); + } + public List getSectionIds() { ensureDecode(); return new ArrayList<>(header.getSectionsIds()); From 47ae49ad4ce5f788fa4f6cb7127969ce3f61bc44 Mon Sep 17 00:00:00 2001 From: James Yuzawa Date: Sat, 7 Mar 2026 11:16:10 -0500 Subject: [PATCH 13/15] return proper versions --- .../src/main/java/com/iab/gpp/encoder/section/TcfCaV1.java | 2 +- .../src/main/java/com/iab/gpp/encoder/section/TcfEuV2.java | 2 +- .../src/main/java/com/iab/gpp/encoder/section/UsCa.java | 2 +- .../src/main/java/com/iab/gpp/encoder/section/UsCo.java | 2 +- .../src/main/java/com/iab/gpp/encoder/section/UsCt.java | 2 +- .../src/main/java/com/iab/gpp/encoder/section/UsDe.java | 2 +- .../src/main/java/com/iab/gpp/encoder/section/UsFl.java | 2 +- .../src/main/java/com/iab/gpp/encoder/section/UsIa.java | 2 +- .../src/main/java/com/iab/gpp/encoder/section/UsIn.java | 2 +- .../src/main/java/com/iab/gpp/encoder/section/UsKy.java | 2 +- .../src/main/java/com/iab/gpp/encoder/section/UsMd.java | 2 +- .../src/main/java/com/iab/gpp/encoder/section/UsMn.java | 2 +- .../src/main/java/com/iab/gpp/encoder/section/UsMt.java | 2 +- .../src/main/java/com/iab/gpp/encoder/section/UsNe.java | 2 +- .../src/main/java/com/iab/gpp/encoder/section/UsNh.java | 2 +- .../src/main/java/com/iab/gpp/encoder/section/UsNj.java | 2 +- .../src/main/java/com/iab/gpp/encoder/section/UsOr.java | 2 +- .../src/main/java/com/iab/gpp/encoder/section/UsRi.java | 2 +- .../src/main/java/com/iab/gpp/encoder/section/UsTn.java | 2 +- .../src/main/java/com/iab/gpp/encoder/section/UsTx.java | 2 +- .../src/main/java/com/iab/gpp/encoder/section/UsUt.java | 2 +- .../src/main/java/com/iab/gpp/encoder/section/UsVa.java | 2 +- .../src/test/java/com/iab/gpp/encoder/section/UsCoTest.java | 1 + .../src/test/java/com/iab/gpp/encoder/section/UsCtTest.java | 1 + .../src/test/java/com/iab/gpp/encoder/section/UsDeTest.java | 1 + .../src/test/java/com/iab/gpp/encoder/section/UsFlTest.java | 1 + .../src/test/java/com/iab/gpp/encoder/section/UsIaTest.java | 1 + .../src/test/java/com/iab/gpp/encoder/section/UsMnTest.java | 1 + .../src/test/java/com/iab/gpp/encoder/section/UsMtTest.java | 1 + .../src/test/java/com/iab/gpp/encoder/section/UsNeTest.java | 1 + .../src/test/java/com/iab/gpp/encoder/section/UsNhTest.java | 1 + .../src/test/java/com/iab/gpp/encoder/section/UsNjTest.java | 1 + .../src/test/java/com/iab/gpp/encoder/section/UsOrTest.java | 1 + .../src/test/java/com/iab/gpp/encoder/section/UsTnTest.java | 1 + .../src/test/java/com/iab/gpp/encoder/section/UsTxTest.java | 1 + .../src/test/java/com/iab/gpp/encoder/section/UsVaTest.java | 1 + 36 files changed, 36 insertions(+), 22 deletions(-) diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/TcfCaV1.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/TcfCaV1.java index fc14c31..e936db5 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/TcfCaV1.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/TcfCaV1.java @@ -39,7 +39,7 @@ public String getName() { @Override public int getVersion() { - return TcfCaV1.VERSION; + return (Integer) this.getFieldValue(TcfCaV1Field.VERSION); } @Override diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/TcfEuV2.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/TcfEuV2.java index cee763c..6a123dc 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/TcfEuV2.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/TcfEuV2.java @@ -43,7 +43,7 @@ public String getName() { @Override public int getVersion() { - return TcfEuV2.VERSION; + return (Integer) this.getFieldValue(TcfEuV2Field.VERSION); } @Override 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 6b891c6..3be8efd 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 @@ -33,7 +33,7 @@ public String getName() { @Override public int getVersion() { - return UsCa.VERSION; + return (Integer) this.getFieldValue(UsCaField.VERSION); } @Override 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 b7a5a5f..7e11bb8 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 @@ -33,7 +33,7 @@ public String getName() { @Override public int getVersion() { - return UsCo.VERSION; + return (Integer) this.getFieldValue(UsCoField.VERSION); } @Override 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 3b34310..6c037f6 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 @@ -33,7 +33,7 @@ public String getName() { @Override public int getVersion() { - return UsCt.VERSION; + return (Integer) this.getFieldValue(UsCtField.VERSION); } @Override 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 135df49..13402b5 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 @@ -33,7 +33,7 @@ public String getName() { @Override public int getVersion() { - return UsDe.VERSION; + return (Integer) this.getFieldValue(UsDeField.VERSION); } @Override 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 c967faf..e9714b6 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 @@ -31,7 +31,7 @@ public String getName() { @Override public int getVersion() { - return UsFl.VERSION; + return (Integer) this.getFieldValue(UsFlField.VERSION); } public Integer getProcessingNotice() { 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 71ab745..601ff1a 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 @@ -33,7 +33,7 @@ public String getName() { @Override public int getVersion() { - return UsIa.VERSION; + return (Integer) this.getFieldValue(UsIaField.VERSION); } @Override diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsIn.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsIn.java index e4cfe8f..0f17592 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsIn.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsIn.java @@ -34,7 +34,7 @@ public String getName() { @Override public int getVersion() { - return UsIn.VERSION; + return (Integer) this.getFieldValue(UsInField.VERSION); } @Override diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsKy.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsKy.java index a0c01d4..bc59a0e 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsKy.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsKy.java @@ -34,7 +34,7 @@ public String getName() { @Override public int getVersion() { - return UsKy.VERSION; + return (Integer) this.getFieldValue(UsKyField.VERSION); } @Override diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsMd.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsMd.java index 5b2be88..bfc3ab5 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsMd.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsMd.java @@ -33,7 +33,7 @@ public String getName() { @Override public int getVersion() { - return UsMd.VERSION; + return (Integer) this.getFieldValue(UsMdField.VERSION); } @Override diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsMn.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsMn.java index 1b90a08..37626f8 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsMn.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsMn.java @@ -33,7 +33,7 @@ public String getName() { @Override public int getVersion() { - return UsMn.VERSION; + return (Integer) this.getFieldValue(UsMnField.VERSION); } @Override 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 6546b72..0bc1bc2 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 @@ -33,7 +33,7 @@ public String getName() { @Override public int getVersion() { - return UsMt.VERSION; + return (Integer) this.getFieldValue(UsMtField.VERSION); } @Override 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 f9532cf..8902b24 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 @@ -33,7 +33,7 @@ public String getName() { @Override public int getVersion() { - return UsNe.VERSION; + return (Integer) this.getFieldValue(UsNeField.VERSION); } @Override 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 9aad2ea..67f237e 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 @@ -33,7 +33,7 @@ public String getName() { @Override public int getVersion() { - return UsNh.VERSION; + return (Integer) this.getFieldValue(UsNhField.VERSION); } @Override 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 687a799..763d51f 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 @@ -33,7 +33,7 @@ public String getName() { @Override public int getVersion() { - return UsNj.VERSION; + return (Integer) this.getFieldValue(UsNjField.VERSION); } @Override 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 5481d0d..d35624a 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 @@ -33,7 +33,7 @@ public String getName() { @Override public int getVersion() { - return UsOr.VERSION; + return (Integer) this.getFieldValue(UsOrField.VERSION); } @Override diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsRi.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsRi.java index 819038b..e0e3566 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsRi.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsRi.java @@ -34,7 +34,7 @@ public String getName() { @Override public int getVersion() { - return UsRi.VERSION; + return (Integer) this.getFieldValue(UsRiField.VERSION); } @Override 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 487354d..4a48a23 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 @@ -33,7 +33,7 @@ public String getName() { @Override public int getVersion() { - return UsTn.VERSION; + return (Integer) this.getFieldValue(UsTnField.VERSION); } @Override 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 4eff422..cd622eb 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 @@ -33,7 +33,7 @@ public String getName() { @Override public int getVersion() { - return UsTx.VERSION; + return (Integer) this.getFieldValue(UsTxField.VERSION); } @Override 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 4c81876..3d9731d 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 @@ -31,7 +31,7 @@ public String getName() { @Override public int getVersion() { - return UsUt.VERSION; + return (Integer) this.getFieldValue(UsUtField.VERSION); } public Integer getSharingNotice() { 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 8b8eec5..148283b 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 @@ -31,7 +31,7 @@ public String getName() { @Override public int getVersion() { - return UsVa.VERSION; + return (Integer) this.getFieldValue(UsVaField.VERSION); } public Integer getSharingNotice() { diff --git a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UsCoTest.java b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UsCoTest.java index 38d6264..79f337c 100644 --- a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UsCoTest.java +++ b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UsCoTest.java @@ -120,6 +120,7 @@ public void testEncodeWithGpcSegmentExcluded() { public void testDecode1() { UsCo usCo = new UsCo("BVWSSVg.YA"); + Assertions.assertEquals(1, usCo.getVersion()); Assertions.assertEquals(1, usCo.getSharingNotice()); Assertions.assertEquals(1, usCo.getSaleOptOutNotice()); Assertions.assertEquals(1, usCo.getTargetedAdvertisingOptOutNotice()); diff --git a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UsCtTest.java b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UsCtTest.java index 1dd4877..7564769 100644 --- a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UsCtTest.java +++ b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UsCtTest.java @@ -121,6 +121,7 @@ public void testEncodeWithGpcSegmentExcluded() { public void testDecode1() throws DecodingException { UsCt usCt = new UsCt("BVWSSZFg.YA"); + Assertions.assertEquals(1, usCt.getVersion()); Assertions.assertEquals(1, usCt.getSharingNotice()); Assertions.assertEquals(1, usCt.getSaleOptOutNotice()); Assertions.assertEquals(1, usCt.getTargetedAdvertisingOptOutNotice()); diff --git a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UsDeTest.java b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UsDeTest.java index dfc6c08..93f49a4 100644 --- a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UsDeTest.java +++ b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UsDeTest.java @@ -130,6 +130,7 @@ public void testEncodeWithGpcSegmentExcluded() { public void testDecode1() throws DecodingException { UsDe usDe = new UsDe("BVWSSSSVYA.YA"); + Assertions.assertEquals(1, usDe.getVersion()); Assertions.assertEquals(1, usDe.getProcessingNotice()); Assertions.assertEquals(1, usDe.getSaleOptOutNotice()); Assertions.assertEquals(1, usDe.getTargetedAdvertisingOptOutNotice()); diff --git a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UsFlTest.java b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UsFlTest.java index fe4158a..e8cf21f 100644 --- a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UsFlTest.java +++ b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UsFlTest.java @@ -128,6 +128,7 @@ public void testSetInvalidValues() { public void testDecode1() throws DecodingException { UsFl usFl = new UsFl("BVWSSZlY"); + Assertions.assertEquals(1, usFl.getVersion()); Assertions.assertEquals(1, usFl.getProcessingNotice()); Assertions.assertEquals(1, usFl.getSaleOptOutNotice()); Assertions.assertEquals(1, usFl.getTargetedAdvertisingOptOutNotice()); diff --git a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UsIaTest.java b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UsIaTest.java index 6bd6b05..178de70 100644 --- a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UsIaTest.java +++ b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UsIaTest.java @@ -129,6 +129,7 @@ public void testEncodeWithGpcSegmentExcluded() { public void testDecode1() throws DecodingException { UsIa usIa = new UsIa("BVVkklWA.YA"); + Assertions.assertEquals(1, usIa.getVersion()); Assertions.assertEquals(1, usIa.getProcessingNotice()); Assertions.assertEquals(1, usIa.getSaleOptOutNotice()); Assertions.assertEquals(1, usIa.getTargetedAdvertisingOptOutNotice()); diff --git a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UsMnTest.java b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UsMnTest.java index 02506a3..4250137 100644 --- a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UsMnTest.java +++ b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UsMnTest.java @@ -129,6 +129,7 @@ public void testEncodeWithGpcSegmentExcluded() { public void testDecode1() throws DecodingException { UsMn usMn = new UsMn("BVWSSVWA.YA"); + Assertions.assertEquals(1, usMn.getVersion()); Assertions.assertEquals(1, usMn.getProcessingNotice()); Assertions.assertEquals(1, usMn.getSaleOptOutNotice()); Assertions.assertEquals(1, usMn.getTargetedAdvertisingOptOutNotice()); diff --git a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UsMtTest.java b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UsMtTest.java index 8e951bd..8f18c39 100644 --- a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UsMtTest.java +++ b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UsMtTest.java @@ -129,6 +129,7 @@ public void testEncodeWithGpcSegmentExcluded() { public void testDecode1() throws DecodingException { UsMt usMt = new UsMt("BVWSSZFY.YA"); + Assertions.assertEquals(1, usMt.getVersion()); Assertions.assertEquals(1, usMt.getSharingNotice()); Assertions.assertEquals(1, usMt.getSaleOptOutNotice()); Assertions.assertEquals(1, usMt.getTargetedAdvertisingOptOutNotice()); diff --git a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UsNeTest.java b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UsNeTest.java index 10b6e81..a8926c9 100644 --- a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UsNeTest.java +++ b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UsNeTest.java @@ -129,6 +129,7 @@ public void testEncodeWithGpcSegmentExcluded() { public void testDecode1() throws DecodingException { UsNe usNe = new UsNe("BVWSSVWA.YA"); + Assertions.assertEquals(1, usNe.getVersion()); Assertions.assertEquals(1, usNe.getProcessingNotice()); Assertions.assertEquals(1, usNe.getSaleOptOutNotice()); Assertions.assertEquals(1, usNe.getTargetedAdvertisingOptOutNotice()); diff --git a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UsNhTest.java b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UsNhTest.java index 805166c..41e466f 100644 --- a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UsNhTest.java +++ b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UsNhTest.java @@ -129,6 +129,7 @@ public void testEncodeWithGpcSegmentExcluded() { public void testDecode1() throws DecodingException { UsNh usNh = new UsNh("BVWSSZFY.YA"); + Assertions.assertEquals(1, usNh.getVersion()); Assertions.assertEquals(1, usNh.getProcessingNotice()); Assertions.assertEquals(1, usNh.getSaleOptOutNotice()); Assertions.assertEquals(1, usNh.getTargetedAdvertisingOptOutNotice()); diff --git a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UsNjTest.java b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UsNjTest.java index b32b0ce..14deba8 100644 --- a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UsNjTest.java +++ b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UsNjTest.java @@ -130,6 +130,7 @@ public void testEncodeWithGpcSegmentExcluded() { public void testDecode1() throws DecodingException { UsNj usNj = new UsNj("BVWSSRklWA.YA"); + Assertions.assertEquals(1, usNj.getVersion()); Assertions.assertEquals(1, usNj.getProcessingNotice()); Assertions.assertEquals(1, usNj.getSaleOptOutNotice()); Assertions.assertEquals(1, usNj.getTargetedAdvertisingOptOutNotice()); diff --git a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UsOrTest.java b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UsOrTest.java index 3a78e62..20a7820 100644 --- a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UsOrTest.java +++ b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UsOrTest.java @@ -130,6 +130,7 @@ public void testEncodeWithGpcSegmentExcluded() { public void testDecode1() throws DecodingException { UsOr usOr = new UsOr("BVWSSRpFYA.YA"); + Assertions.assertEquals(1, usOr.getVersion()); Assertions.assertEquals(1, usOr.getProcessingNotice()); Assertions.assertEquals(1, usOr.getSaleOptOutNotice()); Assertions.assertEquals(1, usOr.getTargetedAdvertisingOptOutNotice()); diff --git a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UsTnTest.java b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UsTnTest.java index 79aa5ff..c8b477f 100644 --- a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UsTnTest.java +++ b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UsTnTest.java @@ -129,6 +129,7 @@ public void testEncodeWithGpcSegmentExcluded() { public void testDecode1() throws DecodingException { UsTn usTn = new UsTn("BVWSSVWA.YA"); + Assertions.assertEquals(1, usTn.getVersion()); Assertions.assertEquals(1, usTn.getProcessingNotice()); Assertions.assertEquals(1, usTn.getSaleOptOutNotice()); Assertions.assertEquals(1, usTn.getTargetedAdvertisingOptOutNotice()); diff --git a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UsTxTest.java b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UsTxTest.java index 28a4ef4..8c0aa93 100644 --- a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UsTxTest.java +++ b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UsTxTest.java @@ -129,6 +129,7 @@ public void testEncodeWithGpcSegmentExcluded() { public void testDecode1() throws DecodingException { UsTx usTx = new UsTx("BVWSSVWA.YA"); + Assertions.assertEquals(1, usTx.getVersion()); Assertions.assertEquals(1, usTx.getProcessingNotice()); Assertions.assertEquals(1, usTx.getSaleOptOutNotice()); Assertions.assertEquals(1, usTx.getTargetedAdvertisingOptOutNotice()); diff --git a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UsVaTest.java b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UsVaTest.java index 06025a4..afea3f8 100644 --- a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UsVaTest.java +++ b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UsVaTest.java @@ -120,6 +120,7 @@ public void testSetInvalidValues() { public void testDecode1() throws DecodingException { UsVa usVa = new UsVa("BVWSSVY"); + Assertions.assertEquals(1, usVa.getVersion()); Assertions.assertEquals(1, usVa.getSharingNotice()); Assertions.assertEquals(1, usVa.getSaleOptOutNotice()); Assertions.assertEquals(1, usVa.getTargetedAdvertisingOptOutNotice()); From 23cd21e5ff6cec0cecdf40bbe06abff5baee08f2 Mon Sep 17 00:00:00 2001 From: James Yuzawa Date: Sat, 7 Mar 2026 11:27:47 -0500 Subject: [PATCH 14/15] more tests --- .../java/com/iab/gpp/encoder/GppModel.java | 5 ++-- .../com/iab/gpp/encoder/GppModelTest.java | 30 ++++++++++--------- 2 files changed, 19 insertions(+), 16 deletions(-) diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/GppModel.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/GppModel.java index a2a7d26..23ce62f 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/GppModel.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/GppModel.java @@ -1,5 +1,6 @@ package com.iab.gpp.encoder; +import com.iab.gpp.encoder.datatype.IntegerSet; import com.iab.gpp.encoder.error.DecodingException; import com.iab.gpp.encoder.error.InvalidFieldException; import com.iab.gpp.encoder.field.FieldKey; @@ -288,9 +289,9 @@ public UsRi getUsRiSection() { return (UsRi) getSection(UsRi.ID); } - public List getSectionIds() { + public IntegerSet getSectionIds() { ensureDecode(); - return new ArrayList<>(header.getSectionsIds()); + return header.getSectionsIds(); } @Override diff --git a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/GppModelTest.java b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/GppModelTest.java index f6762ff..7fcfb5e 100644 --- a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/GppModelTest.java +++ b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/GppModelTest.java @@ -52,7 +52,6 @@ import java.time.Instant; import java.time.ZoneId; import java.time.ZonedDateTime; -import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Set; @@ -78,7 +77,7 @@ public void testEncodeDefault() { String gppString = gppModel.encode(); Assertions.assertEquals("DBAA", gppString); - Assertions.assertEquals(new ArrayList<>(), gppModel.getSectionIds()); + Assertions.assertEquals(Set.of(), gppModel.getSectionIds()); Assertions.assertEquals(false, gppModel.hasSection(UspV1.ID)); Assertions.assertEquals(false, gppModel.hasSection(TcfEuV2.ID)); Assertions.assertEquals(false, gppModel.hasSection(TcfCaV1.ID)); @@ -205,7 +204,7 @@ public void testEncodeUspv1() { gppModel.setFieldValue(UspV1.NAME, UspV1Field.OPT_OUT_SALE, 'N'); gppModel.setFieldValue(UspV1.NAME, UspV1Field.LSPA_COVERED, 'N'); - Assertions.assertEquals(Arrays.asList(6), gppModel.getSectionIds()); + Assertions.assertEquals(Set.of(6), gppModel.getSectionIds()); Assertions.assertEquals(true, gppModel.hasSection(UspV1.ID)); Assertions.assertEquals(false, gppModel.hasSection(TcfEuV2.ID)); Assertions.assertEquals(false, gppModel.hasSection(TcfCaV1.ID)); @@ -216,8 +215,11 @@ public void testEncodeUspv1() { String gppString = gppModel.encode(); Assertions.assertEquals("DBABTA~1YNN", gppString); + Assertions.assertEquals("1YNN", gppModel.encodeSection(UspV1.ID)); + Assertions.assertEquals("1YNN", gppModel.encodeSection(UspV1.NAME)); - Assertions.assertEquals(Arrays.asList(6), gppModel.getSectionIds()); + Assertions.assertEquals(Set.of(6), gppModel.getSectionIds()); + Assertions.assertEquals(Set.of(6), gppModel.getHeader().getSectionsIds()); Assertions.assertEquals(true, gppModel.hasSection(UspV1.ID)); Assertions.assertEquals(false, gppModel.hasSection(TcfEuV2.ID)); Assertions.assertEquals(false, gppModel.hasSection(TcfCaV1.ID)); @@ -251,7 +253,7 @@ public void testEncodeTcfEuV2() { gppModel.setFieldValue(TcfEuV2.NAME, TcfEuV2Field.CREATED, utcDateTime); gppModel.setFieldValue(TcfEuV2.NAME, TcfEuV2Field.LAST_UPDATED, utcDateTime); - Assertions.assertEquals(Arrays.asList(2), gppModel.getSectionIds()); + Assertions.assertEquals(Set.of(2), gppModel.getSectionIds()); Assertions.assertEquals(false, gppModel.hasSection(UspV1.ID)); Assertions.assertEquals(true, gppModel.hasSection(TcfEuV2.ID)); Assertions.assertEquals(false, gppModel.hasSection(TcfCaV1.ID)); @@ -265,7 +267,7 @@ public void testEncodeTcfEuV2() { Assertions.assertEquals(2, gppString.split("~").length); - Assertions.assertEquals(Arrays.asList(2), gppModel.getSectionIds()); + Assertions.assertEquals(Set.of(2), gppModel.getSectionIds()); Assertions.assertEquals(false, gppModel.hasSection(UspV1.ID)); Assertions.assertEquals(true, gppModel.hasSection(TcfEuV2.ID)); Assertions.assertEquals(false, gppModel.hasSection(TcfCaV1.ID)); @@ -295,7 +297,7 @@ public void testEncodeUspV1AndTcfEuV2() { gppModel.setFieldValue(TcfEuV2.NAME, TcfEuV2Field.CREATED, utcDateTime); gppModel.setFieldValue(TcfEuV2.NAME, TcfEuV2Field.LAST_UPDATED, utcDateTime); - Assertions.assertEquals(Arrays.asList(2), gppModel.getSectionIds()); + Assertions.assertEquals(Set.of(2), gppModel.getSectionIds()); Assertions.assertEquals(false, gppModel.hasSection(UspV1.NAME)); Assertions.assertEquals(true, gppModel.hasSection(TcfEuV2.NAME)); Assertions.assertEquals(false, gppModel.hasSection(TcfCaV1.NAME)); @@ -314,7 +316,7 @@ public void testEncodeUspV1AndTcfEuV2() { Assertions.assertEquals(3, gppString.split("~").length); - Assertions.assertEquals(Arrays.asList(2, 6), gppModel.getSectionIds()); + Assertions.assertEquals(Set.of(2, 6), gppModel.getSectionIds()); Assertions.assertEquals(true, gppModel.hasSection(UspV1.NAME)); Assertions.assertEquals(true, gppModel.hasSection(TcfEuV2.NAME)); Assertions.assertEquals(false, gppModel.hasSection(TcfCaV1.NAME)); @@ -344,7 +346,7 @@ public void testEncodeUspV1AndTcfEuV2AndTcfCaV1() { gppModel.setFieldValue(TcfEuV2.NAME, TcfEuV2Field.CREATED, utcDateTime); gppModel.setFieldValue(TcfEuV2.NAME, TcfEuV2Field.LAST_UPDATED, utcDateTime); - Assertions.assertEquals(Arrays.asList(2), gppModel.getSectionIds()); + Assertions.assertEquals(Set.of(2), gppModel.getSectionIds()); Assertions.assertEquals(false, gppModel.hasSection(UspV1.ID)); Assertions.assertEquals(true, gppModel.hasSection(TcfEuV2.ID)); Assertions.assertEquals(false, gppModel.hasSection(TcfCaV1.ID)); @@ -416,7 +418,7 @@ public void testEncodeUspV1AndTcfEuV2AndTcfCaV1() { Assertions.assertEquals(4, gppString.split("~").length); - Assertions.assertEquals(Arrays.asList(2, 5, 6), gppModel.getSectionIds()); + Assertions.assertEquals(Set.of(2, 5, 6), gppModel.getSectionIds()); Assertions.assertEquals(true, gppModel.hasSection(UspV1.ID)); Assertions.assertEquals(true, gppModel.hasSection(TcfEuV2.ID)); Assertions.assertEquals(true, gppModel.hasSection(TcfCaV1.ID)); @@ -477,7 +479,7 @@ public void testDecodeUspv1() { String gppString = "DBABTA~1YNN"; GppModel gppModel = new GppModel(gppString); - Assertions.assertEquals(Arrays.asList(6), gppModel.getSectionIds()); + Assertions.assertEquals(Set.of(6), gppModel.getSectionIds()); Assertions.assertEquals(true, gppModel.hasSection(UspV1.ID)); Assertions.assertEquals(false, gppModel.hasSection(TcfEuV2.ID)); Assertions.assertEquals(false, gppModel.hasSection(TcfCaV1.ID)); @@ -500,7 +502,7 @@ public void testDecodeTcfEuV2() { String gppString = "DBABMA~CPSG_8APSG_8ANwAAAENAwCAAAAAAAAAAAAAAAAAAAAA.QAAA.IAAA"; GppModel gppModel = new GppModel(gppString); - Assertions.assertEquals(Arrays.asList(2), gppModel.getSectionIds()); + Assertions.assertEquals(Set.of(2), gppModel.getSectionIds()); Assertions.assertEquals(false, gppModel.hasSection(UspV1.ID)); Assertions.assertEquals(true, gppModel.hasSection(TcfEuV2.ID)); Assertions.assertEquals(false, gppModel.hasSection(TcfCaV1.ID)); @@ -558,7 +560,7 @@ public void testDecodeUspv1AndTcfEuV2() { String gppString = "DBACNYA~CPSG_8APSG_8ANwAAAENAwCAAAAAAAAAAAAAAAAAAAAA.QAAA.IAAA~1YNN"; GppModel gppModel = new GppModel(gppString); - Assertions.assertEquals(Arrays.asList(2, 6), gppModel.getSectionIds()); + Assertions.assertEquals(Set.of(2, 6), gppModel.getSectionIds()); Assertions.assertEquals(true, gppModel.hasSection(UspV1.ID)); Assertions.assertEquals(true, gppModel.hasSection(TcfEuV2.ID)); Assertions.assertEquals(false, gppModel.hasSection(TcfCaV1.ID)); @@ -637,7 +639,7 @@ public void testDecodeUspv1AndTcfEuV2AndTcfCaV1() { "DBACOeA~CPSG_8APSG_8ANwAAAENAwCAAAAAAAAAAAAAAAAAAAAA.QAAA.IAAA~BPSG_8APSG_8AAyACAENGdCgf_gfgAfgfgBgABABAAABAB4AACACAAA.fHHHA4444ao~1YNN"; GppModel gppModel = new GppModel(gppString); - Assertions.assertEquals(Arrays.asList(2, 5, 6), gppModel.getSectionIds()); + Assertions.assertEquals(Set.of(2, 5, 6), gppModel.getSectionIds()); Assertions.assertEquals(true, gppModel.hasSection(UspV1.NAME)); Assertions.assertEquals(true, gppModel.hasSection(TcfEuV2.NAME)); Assertions.assertEquals(true, gppModel.hasSection(TcfCaV1.NAME)); From c490328a40f1d359fbd8f957b8db62d1e7848af5 Mon Sep 17 00:00:00 2001 From: James Yuzawa Date: Sat, 7 Mar 2026 13:42:11 -0500 Subject: [PATCH 15/15] clean up isPresent --- .../java/com/iab/gpp/encoder/datatype/FixedIntegerList.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 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 f9e0efb..99778d4 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 @@ -27,8 +27,10 @@ public FixedIntegerList(int elementBitStringLength, int numElements) { } public boolean isPresent() { - for (int i = 0; i < numElements; i++) { - if (getInt(i) > 0) { + int start = offset; + int end = start + elementBitStringLength * numElements; + for (int i = start; i < end; i++) { + if (bitSet.get(i)) { return true; } }