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 )