| File: | Dpkg/Control/HashCore/Tie.pm |
| Coverage: | 91.9% |
| line | stmt | bran | cond | sub | pod | time | code |
|---|---|---|---|---|---|---|---|
| 1 | # Copyright © 2007-2009 Raphaël Hertzog <hertzog@debian.org> | ||||||
| 2 | # Copyright © 2009, 2012-2019, 2021 Guillem Jover <guillem@debian.org> | ||||||
| 3 | # | ||||||
| 4 | # This program is free software; you can redistribute it and/or modify | ||||||
| 5 | # it under the terms of the GNU General Public License as published by | ||||||
| 6 | # the Free Software Foundation; either version 2 of the License, or | ||||||
| 7 | # (at your option) any later version. | ||||||
| 8 | # | ||||||
| 9 | # This program is distributed in the hope that it will be useful, | ||||||
| 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
| 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||||||
| 12 | # GNU General Public License for more details. | ||||||
| 13 | # | ||||||
| 14 | # You should have received a copy of the GNU General Public License | ||||||
| 15 | # along with this program. If not, see <https://www.gnu.org/licenses/>. | ||||||
| 16 | |||||||
| 17 | =encoding utf8 | ||||||
| 18 | |||||||
| 19 - 35 | =head1 NAME Dpkg::Control::HashCore::Tie - ties a Dpkg::Control::Hash object =head1 DESCRIPTION This module provides a class that is used to tie a hash. It implements hash-like functions by normalizing the name of fields received in keys (using Dpkg::Control::Fields::field_capitalize()). It also stores the order in which fields have been added in order to be able to dump them in the same order. But the order information is stored in a parent object of type L<Dpkg::Control>. B<Note>: This is a private module, its API can change at any time. =cut | ||||||
| 36 | |||||||
| 37 | package Dpkg::Control::HashCore::Tie 0.01; | ||||||
| 38 | |||||||
| 39 | 138 138 138 | 495 135 2199 | use strict; | ||||
| 40 | 138 138 138 | 454 151 3265 | use warnings; | ||||
| 41 | |||||||
| 42 | 138 138 138 | 262 105 6302 | use Dpkg::Control::FieldsCore; | ||||
| 43 | |||||||
| 44 | 138 138 138 | 291 94 3298 | use Carp; | ||||
| 45 | 138 138 138 | 272 104 3100 | use Tie::Hash; | ||||
| 46 | 138 138 138 | 313 111 486 | use parent -norequire, qw(Tie::ExtraHash); | ||||
| 47 | |||||||
| 48 | # $self->[0] is the real hash | ||||||
| 49 | # $self->[1] is a reference to the hash contained by the parent object. | ||||||
| 50 | # This reference bypasses the top-level scalar reference of a | ||||||
| 51 | # Dpkg::Control::Hash, hence ensuring that reference gets DESTROYed | ||||||
| 52 | # properly. | ||||||
| 53 | |||||||
| 54 - 63 | =head1 FUNCTIONS =over 4 =item Dpkg::Control::Hash->new($parent) Return a reference to a tied hash implementing storage of simple "field: value" mapping as used in many Debian-specific files. =cut | ||||||
| 64 | |||||||
| 65 | sub new { | ||||||
| 66 | 2676 | 1 | 2664 | my ($class, @args) = @_; | |||
| 67 | 2676 | 2013 | my $hash = {}; | ||||
| 68 | |||||||
| 69 | 2676 2676 | 1728 4365 | tie %{$hash}, $class, @args; ## no critic (Miscellanea::ProhibitTies) | ||||
| 70 | 2676 | 4442 | return $hash; | ||||
| 71 | } | ||||||
| 72 | |||||||
| 73 | sub TIEHASH { | ||||||
| 74 | 2676 | 2486 | my ($class, $parent) = @_; | ||||
| 75 | |||||||
| 76 | 2676 | 5613 | croak 'parent object must be Dpkg::Control::Hash' | ||||
| 77 | if not $parent->isa('Dpkg::Control::HashCore') and | ||||||
| 78 | not $parent->isa('Dpkg::Control::Hash'); | ||||||
| 79 | 2676 | 7610 | return bless [ {}, $$parent ], $class; | ||||
| 80 | } | ||||||
| 81 | |||||||
| 82 | sub FETCH { | ||||||
| 83 | 14169 | 10838 | my ($self, $key) = @_; | ||||
| 84 | |||||||
| 85 | 14169 | 9193 | $key = lc($key); | ||||
| 86 | 14169 | 33432 | return $self->[0]->{$key} if exists $self->[0]->{$key}; | ||||
| 87 | 39 | 78 | return; | ||||
| 88 | } | ||||||
| 89 | |||||||
| 90 | sub STORE { | ||||||
| 91 | 19101 | 19715 | my ($self, $key, $value) = @_; | ||||
| 92 | |||||||
| 93 | 19101 | 12238 | $key = lc($key); | ||||
| 94 | 19101 | 18165 | if (not exists $self->[0]->{$key}) { | ||||
| 95 | 15030 15030 | 8381 15595 | push @{$self->[1]->{in_order}}, field_capitalize($key); | ||||
| 96 | } | ||||||
| 97 | 19101 | 26572 | $self->[0]->{$key} = $value; | ||||
| 98 | } | ||||||
| 99 | |||||||
| 100 | sub EXISTS { | ||||||
| 101 | 7383 | 5801 | my ($self, $key) = @_; | ||||
| 102 | |||||||
| 103 | 7383 | 5074 | $key = lc($key); | ||||
| 104 | 7383 | 12315 | return exists $self->[0]->{$key}; | ||||
| 105 | } | ||||||
| 106 | |||||||
| 107 | sub DELETE { | ||||||
| 108 | 3 | 7 | my ($self, $key) = @_; | ||||
| 109 | 3 | 8 | my $parent = $self->[1]; | ||||
| 110 | 3 | 5 | my $in_order = $parent->{in_order}; | ||||
| 111 | |||||||
| 112 | 3 | 4 | $key = lc($key); | ||||
| 113 | 3 | 6 | if (exists $self->[0]->{$key}) { | ||||
| 114 | 3 | 3 | delete $self->[0]->{$key}; | ||||
| 115 | 3 3 9 3 | 3 3 175 4 | @{$in_order} = grep { lc ne $key } @{$in_order}; | ||||
| 116 | 3 | 266 | return 1; | ||||
| 117 | } else { | ||||||
| 118 | 0 | 0 | return 0; | ||||
| 119 | } | ||||||
| 120 | } | ||||||
| 121 | |||||||
| 122 | sub FIRSTKEY { | ||||||
| 123 | 2292 | 1559 | my $self = shift; | ||||
| 124 | 2292 | 1699 | my $parent = $self->[1]; | ||||
| 125 | |||||||
| 126 | 2292 2292 | 1424 2566 | foreach my $key (@{$parent->{in_order}}) { | ||||
| 127 | 2292 | 5190 | return $key if exists $self->[0]->{lc $key}; | ||||
| 128 | } | ||||||
| 129 | } | ||||||
| 130 | |||||||
| 131 | sub NEXTKEY { | ||||||
| 132 | 4239 | 3283 | my ($self, $prev) = @_; | ||||
| 133 | 4239 | 2595 | my $parent = $self->[1]; | ||||
| 134 | 4239 | 2466 | my $found = 0; | ||||
| 135 | |||||||
| 136 | 4239 4239 | 2451 3334 | foreach my $key (@{$parent->{in_order}}) { | ||||
| 137 | 9210 | 6236 | if ($found) { | ||||
| 138 | 1947 | 3794 | return $key if exists $self->[0]->{lc $key}; | ||||
| 139 | } else { | ||||||
| 140 | 7263 | 6760 | $found = 1 if $key eq $prev; | ||||
| 141 | } | ||||||
| 142 | } | ||||||
| 143 | 2292 | 2956 | return; | ||||
| 144 | } | ||||||
| 145 | |||||||
| 146 | =back | ||||||
| 147 | |||||||
| 148 - 154 | =head1 CHANGES =head2 Version 0.xx This is a private module. =cut | ||||||
| 155 | |||||||
| 156 | 1; | ||||||