GDPR-IAB-TCFv2

 view release on metacpan or  search on metacpan

lib/GDPR/IAB/TCFv2/RangeSection.pm  view on Meta::CPAN

  push @{$self->{ranges}}, [$vendor_id, $vendor_id];

  if (exists $prefetch->{$vendor_id}) {
    $prefetch->{$vendor_id} = 2;
  }

  return $next_offset;
}

sub max_id {
  my $self = shift;

  return $self->{max_id};
}

sub contains {
  my ($self, $id) = @_;

  croak "invalid vendor id $id: must be positive integer bigger than 0" if $id < 1;

  if ($self->{cache}) {
    return if $id > $self->{max_id};
    my $vec_offset = (($id - 1) >> 3 << 3) | (7 - (($id - 1) & 7));
    return vec($self->{cache}, $vec_offset, 1);
  }

  if ($self->{hcache} && exists $self->{hcache}->{$id}) {
    return $self->{hcache}->{$id};
  }

  return if $id > $self->{max_id};

  foreach my $range (@{$self->{ranges}}) {
    return 1 if $range->[0] <= $id && $id <= $range->[1];
  }

  return 0;
}

sub all {
  my $self = shift;

  my @vendors;
  foreach my $range (@{$self->{ranges}}) {
    push @vendors, $range->[0] .. $range->[1];
  }

  return \@vendors;
}

sub TO_JSON {
  my ($self, $filter_id) = @_;

  if (defined $filter_id) {
    my $val = $self->contains($filter_id);

    if (!!$self->{options}->{json}->{compact}) {
      return $val ? [$filter_id] : [];
    }

    my ($false, $true) = @{$self->{options}->{json}->{boolean_values}};
    my $bool_val = $val ? $true : $false;

    if (!!$self->{options}->{json}->{verbose}) {
      return {$filter_id => $bool_val};
    }

    return $val ? {$filter_id => $true} : {};
  }

  return $self->all if !!$self->{options}->{json}->{compact};

  my ($false, $true) = @{$self->{options}->{json}->{boolean_values}};

  my %map;
  if (!!$self->{options}->{json}->{verbose}) {
    %map = map { $_ => $false } 1 .. $self->{max_id};
  }

  # Direct hash-element assignment per range; the previous form
  # `%map = ( %map, map { $_ => $true } ... )` re-copied the running
  # hash into a list every iteration, accidentally O(n^2) over the
  # number of vendor IDs already accumulated.
  foreach my $range (@{$self->{ranges}}) {
    for my $id ($range->[0] .. $range->[1]) {
      $map{$id} = $true;
    }
  }

  return \%map;
}

1;
__END__

=head1 NAME

GDPR::IAB::TCFv2::RangeSection - TCF v2.3 range section parser

=head1 SYNOPSIS

    use GDPR::IAB::TCFv2::RangeSection;
    my $data = '...'; # raw binary data
    
    my $max_id_consent = 100;

    my ($range_section, $next_offset) = GDPR::IAB::TCFv2::RangeSection->Parse(
        data      => $data,
        data_size => length($data),
        offset    => 230,             # offset for vendor ranges
        max_id    => $max_id_consent,
        options   => { json => {} },
    );

    if ($range_section->contains(284)) {
        # ...
    }

=head1 CONSTRUCTOR

Constructor C<Parse> receives a hash of 6 parameters: 

=over

=item *

Key C<data> is the binary data

=item *

Key C<data_size> is the original binary data size (in bits)

=item *



( run in 0.794 second using v1.01-cache-2.11-cpan-acf6aa7dc9e )