| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
package Class::Accessor::PackedString::Set; |
|
2
|
|
|
|
|
|
|
|
|
3
|
|
|
|
|
|
|
our $DATE = '2017-10-15'; # DATE |
|
4
|
|
|
|
|
|
|
our $VERSION = '0.001'; # VERSION |
|
5
|
|
|
|
|
|
|
|
|
6
|
|
|
|
|
|
|
#IFUNBUILT |
|
7
|
|
|
|
|
|
|
# use strict 'subs', 'vars'; |
|
8
|
|
|
|
|
|
|
# use warnings; |
|
9
|
|
|
|
|
|
|
#END IFUNBUILT |
|
10
|
|
|
|
|
|
|
|
|
11
|
|
|
|
|
|
|
sub import { |
|
12
|
3
|
|
|
3
|
|
536
|
my ($class0, $spec) = @_; |
|
13
|
3
|
|
|
|
|
7
|
my $caller = caller(); |
|
14
|
|
|
|
|
|
|
|
|
15
|
3
|
|
|
|
|
42
|
my $class = $caller; |
|
16
|
|
|
|
|
|
|
|
|
17
|
|
|
|
|
|
|
#IFUNBUILT |
|
18
|
|
|
|
|
|
|
# no warnings 'redefine'; |
|
19
|
|
|
|
|
|
|
#END IFUNBUILT |
|
20
|
|
|
|
|
|
|
|
|
21
|
3
|
|
|
|
|
6
|
my $attrs = $spec->{accessors}; |
|
22
|
|
|
|
|
|
|
|
|
23
|
|
|
|
|
|
|
# store list of accessors in the package |
|
24
|
|
|
|
|
|
|
{ |
|
25
|
|
|
|
|
|
|
#IFUNBUILT |
|
26
|
|
|
|
|
|
|
# no warnings 'once'; |
|
27
|
|
|
|
|
|
|
#END IFUNBUILT |
|
28
|
3
|
|
|
|
|
3
|
@{"$class\::HAS_PACKED"} = @$attrs; |
|
|
3
|
|
|
|
|
6
|
|
|
|
3
|
|
|
|
|
13
|
|
|
29
|
|
|
|
|
|
|
} |
|
30
|
|
|
|
|
|
|
|
|
31
|
|
|
|
|
|
|
# generate accessors |
|
32
|
3
|
|
|
|
|
7
|
my %idx ; # key = attribute name, value = index |
|
33
|
|
|
|
|
|
|
my %tmpl ; # key = attribute name, value = pack() template |
|
34
|
3
|
|
|
|
|
0
|
my %tmplsize; # key = attribute name, value = pack() data size |
|
35
|
3
|
|
|
|
|
6
|
my @attrs = @$attrs; |
|
36
|
3
|
|
|
|
|
10
|
while (my ($name, $template) = splice @attrs, 0, 2) { |
|
37
|
7
|
|
|
|
|
14
|
$idx{$name} = keys %idx; |
|
38
|
7
|
|
|
|
|
9
|
$tmpl{$name} = $template; |
|
39
|
7
|
|
|
|
|
27
|
$tmplsize{$name} = length(pack $template); |
|
40
|
|
|
|
|
|
|
} |
|
41
|
|
|
|
|
|
|
|
|
42
|
3
|
|
|
|
|
7
|
@attrs = @$attrs; |
|
43
|
3
|
|
|
|
|
8
|
while (my ($name, $template) = splice @attrs, 0, 2) { |
|
44
|
7
|
|
|
|
|
12
|
my $idx = $idx{$name}; |
|
45
|
7
|
|
|
|
|
11
|
my $code_str = 'sub (;$) {' . "\n"; |
|
46
|
7
|
|
|
|
|
10
|
$code_str .= qq( my \$self = shift;\n); |
|
47
|
|
|
|
|
|
|
|
|
48
|
7
|
|
|
|
|
9
|
$code_str .= qq( my \$val;\n my \$pos = 0;\n while (1) {\n last if \$pos >= length(\$\$self);\n my \$idx = ord(substr(\$\$self, \$pos++, 1));\n); |
|
49
|
7
|
|
|
|
|
23
|
for my $attr (sort {$idx{$a} <=> $idx{$b}} keys %idx) { |
|
|
13
|
|
|
|
|
32
|
|
|
50
|
17
|
|
|
|
|
21
|
my $idx = $idx{$attr}; |
|
51
|
17
|
100
|
|
|
|
48
|
$code_str .= qq| |.($idx == 0 ? "if " : "elsif").qq| (\$idx == $idx) { my \$v = unpack("| . $tmpl{$attr} . qq|", substr(\$\$self, \$pos, | . $tmplsize{$attr} . qq|));|; |
|
52
|
17
|
100
|
|
|
|
28
|
if ($attr eq $name) { |
|
53
|
7
|
|
|
|
|
14
|
$code_str .= qq| \$val = \$v; if (\@_ && defined \$_[0]) { substr(\$\$self, \$pos, | . $tmplsize{$attr} . qq|) = pack("| . $tmpl{$attr} . qq|", \$_[0]); return \$val } last|; |
|
54
|
|
|
|
|
|
|
} else { |
|
55
|
10
|
|
|
|
|
16
|
$code_str .= qq| \$pos += | . $tmplsize{$attr} . qq|; next|; |
|
56
|
|
|
|
|
|
|
} |
|
57
|
17
|
|
|
|
|
26
|
$code_str .= qq| }\n|; |
|
58
|
|
|
|
|
|
|
} |
|
59
|
7
|
|
|
|
|
12
|
$code_str .= qq( else { die "Invalid data in object \$self: invalid index \$idx" }\n); |
|
60
|
7
|
|
|
|
|
8
|
$code_str .= qq( }\n); |
|
61
|
|
|
|
|
|
|
|
|
62
|
7
|
|
|
|
|
9
|
$code_str .= qq( return \$val unless \@_;\n); |
|
63
|
7
|
|
|
|
|
11
|
$code_str .= qq( if (defined \$_[0]) {\n); # set a newly set attribute, append |
|
64
|
7
|
|
|
|
|
11
|
$code_str .= qq| \$\$self .= chr($idx) . pack("|. $tmpl{$name} . qq|", \$_[0]);\n|; |
|
65
|
7
|
|
|
|
|
11
|
$code_str .= qq( } elsif (defined \$val) {\n); # delete unset attribute |
|
66
|
7
|
|
|
|
|
10
|
$code_str .= qq| substr(\$\$self, \$pos-1, | . $tmplsize{$name} . qq|+1) = "";\n|; |
|
67
|
7
|
|
|
|
|
8
|
$code_str .= qq( }\n); |
|
68
|
7
|
|
|
|
|
10
|
$code_str .= qq( return \$val;\n); |
|
69
|
7
|
|
|
|
|
10
|
$code_str .= "}\n"; |
|
70
|
|
|
|
|
|
|
#print "D:accessor code for $name: ", $code_str, "\n"; |
|
71
|
7
|
50
|
0
|
1
|
|
1478
|
*{"$class\::$name"} = eval $code_str; |
|
|
7
|
0
|
0
|
|
|
34
|
|
|
|
1
|
0
|
100
|
|
|
23
|
|
|
|
1
|
0
|
0
|
|
|
2
|
|
|
|
1
|
0
|
0
|
|
|
2
|
|
|
|
1
|
50
|
0
|
|
|
2
|
|
|
|
1
|
50
|
100
|
|
|
8
|
|
|
|
0
|
0
|
|
|
|
0
|
|
|
|
0
|
0
|
|
|
|
0
|
|
|
|
0
|
0
|
|
|
|
0
|
|
|
|
0
|
0
|
|
|
|
0
|
|
|
|
0
|
0
|
|
|
|
0
|
|
|
|
0
|
0
|
|
|
|
0
|
|
|
|
0
|
0
|
|
|
|
0
|
|
|
|
0
|
0
|
|
|
|
0
|
|
|
|
0
|
100
|
|
|
|
0
|
|
|
|
0
|
100
|
|
|
|
0
|
|
|
|
0
|
100
|
|
|
|
0
|
|
|
|
0
|
50
|
|
|
|
0
|
|
|
|
0
|
100
|
|
|
|
0
|
|
|
|
0
|
100
|
|
|
|
0
|
|
|
|
0
|
50
|
|
|
|
0
|
|
|
|
1
|
0
|
|
|
|
3
|
|
|
|
1
|
0
|
|
|
|
4
|
|
|
|
1
|
0
|
|
|
|
5
|
|
|
|
0
|
0
|
|
|
|
0
|
|
|
|
1
|
0
|
|
|
|
2
|
|
|
|
0
|
0
|
|
|
|
0
|
|
|
|
0
|
0
|
|
|
|
0
|
|
|
|
0
|
100
|
|
|
|
0
|
|
|
|
0
|
0
|
|
|
|
0
|
|
|
|
0
|
100
|
|
|
|
0
|
|
|
|
0
|
50
|
|
|
|
0
|
|
|
|
0
|
0
|
|
|
|
0
|
|
|
|
0
|
50
|
|
|
|
0
|
|
|
|
0
|
50
|
|
|
|
0
|
|
|
|
0
|
0
|
|
|
|
0
|
|
|
|
0
|
100
|
|
|
|
0
|
|
|
|
0
|
0
|
|
|
|
0
|
|
|
|
0
|
50
|
|
|
|
0
|
|
|
|
0
|
50
|
|
|
|
0
|
|
|
|
0
|
0
|
|
|
|
0
|
|
|
|
0
|
50
|
|
|
|
0
|
|
|
|
0
|
50
|
|
|
|
0
|
|
|
|
0
|
0
|
|
|
|
0
|
|
|
|
0
|
100
|
|
|
|
0
|
|
|
|
0
|
100
|
|
|
|
0
|
|
|
|
0
|
100
|
|
|
|
0
|
|
|
|
0
|
50
|
|
|
|
0
|
|
|
|
6
|
100
|
|
|
|
13
|
|
|
|
6
|
100
|
|
|
|
9
|
|
|
|
6
|
50
|
|
|
|
8
|
|
|
|
6
|
|
|
|
|
11
|
|
|
|
10
|
|
|
|
|
20
|
|
|
|
8
|
|
|
|
|
15
|
|
|
|
8
|
|
|
|
|
19
|
|
|
|
4
|
|
|
|
|
11
|
|
|
|
4
|
|
|
|
|
6
|
|
|
|
4
|
|
|
|
|
7
|
|
|
|
4
|
|
|
|
|
10
|
|
|
|
4
|
|
|
|
|
8
|
|
|
|
4
|
|
|
|
|
14
|
|
|
|
1
|
|
|
|
|
5
|
|
|
|
1
|
|
|
|
|
2
|
|
|
|
3
|
|
|
|
|
5
|
|
|
|
0
|
|
|
|
|
0
|
|
|
|
5
|
|
|
|
|
18
|
|
|
|
2
|
|
|
|
|
6
|
|
|
|
1
|
|
|
|
|
4
|
|
|
|
1
|
|
|
|
|
3
|
|
|
|
2
|
|
|
|
|
4
|
|
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
|
1
|
|
|
|
|
26
|
|
|
|
1
|
|
|
|
|
2
|
|
|
|
1
|
|
|
|
|
2
|
|
|
|
1
|
|
|
|
|
2
|
|
|
|
3
|
|
|
|
|
9
|
|
|
|
2
|
|
|
|
|
4
|
|
|
|
2
|
|
|
|
|
6
|
|
|
|
1
|
|
|
|
|
3
|
|
|
|
1
|
|
|
|
|
2
|
|
|
|
1
|
|
|
|
|
23
|
|
|
|
1
|
|
|
|
|
3
|
|
|
|
1
|
|
|
|
|
2
|
|
|
|
1
|
|
|
|
|
2
|
|
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
|
1
|
|
|
|
|
3
|
|
|
|
1
|
|
|
|
|
13
|
|
|
|
1
|
|
|
|
|
6
|
|
|
|
0
|
|
|
|
|
0
|
|
|
|
1
|
|
|
|
|
2
|
|
|
|
1
|
|
|
|
|
22
|
|
|
|
1
|
|
|
|
|
2
|
|
|
|
1
|
|
|
|
|
2
|
|
|
|
1
|
|
|
|
|
2
|
|
|
|
2
|
|
|
|
|
5
|
|
|
|
1
|
|
|
|
|
3
|
|
|
|
1
|
|
|
|
|
5
|
|
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
|
1
|
|
|
|
|
3
|
|
|
|
1
|
|
|
|
|
2
|
|
|
|
1
|
|
|
|
|
2
|
|
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
|
1
|
|
|
|
|
3
|
|
|
|
1
|
|
|
|
|
3
|
|
|
|
1
|
|
|
|
|
3
|
|
|
|
0
|
|
|
|
|
0
|
|
|
|
1
|
|
|
|
|
3
|
|
|
|
6
|
|
|
|
|
1294
|
|
|
|
6
|
|
|
|
|
10
|
|
|
|
6
|
|
|
|
|
8
|
|
|
|
6
|
|
|
|
|
11
|
|
|
|
7
|
|
|
|
|
20
|
|
|
|
5
|
|
|
|
|
12
|
|
|
|
5
|
|
|
|
|
17
|
|
|
|
4
|
|
|
|
|
12
|
|
|
|
4
|
|
|
|
|
7
|
|
|
|
4
|
|
|
|
|
16
|
|
|
|
1
|
|
|
|
|
4
|
|
|
|
1
|
|
|
|
|
3
|
|
|
|
3
|
|
|
|
|
5
|
|
|
|
1
|
|
|
|
|
5
|
|
|
|
1
|
|
|
|
|
5
|
|
|
|
1
|
|
|
|
|
3
|
|
|
|
0
|
|
|
|
|
0
|
|
|
|
5
|
|
|
|
|
23
|
|
|
|
2
|
|
|
|
|
7
|
|
|
|
1
|
|
|
|
|
6
|
|
|
|
1
|
|
|
|
|
3
|
|
|
|
2
|
|
|
|
|
5
|
|
|
72
|
7
|
50
|
|
|
|
34
|
die if $@; |
|
73
|
|
|
|
|
|
|
} |
|
74
|
|
|
|
|
|
|
|
|
75
|
|
|
|
|
|
|
# generate constructor |
|
76
|
|
|
|
|
|
|
{ |
|
77
|
3
|
|
|
|
|
5
|
my $code_str; |
|
|
3
|
|
|
|
|
3
|
|
|
78
|
|
|
|
|
|
|
|
|
79
|
3
|
|
|
|
|
5
|
$code_str = 'sub { my $o = ""; bless \$o, shift }'; |
|
80
|
|
|
|
|
|
|
|
|
81
|
|
|
|
|
|
|
# TODO |
|
82
|
|
|
|
|
|
|
|
|
83
|
|
|
|
|
|
|
#$code_str = 'sub { my ($class, %args) = @_;'; |
|
84
|
|
|
|
|
|
|
#$code_str .= qq( no warnings 'uninitialized';); |
|
85
|
|
|
|
|
|
|
#$code_str .= qq( my \@attrs = map { undef } 1..$num_attrs;); |
|
86
|
|
|
|
|
|
|
#for my $attr (sort keys %$attrs) { |
|
87
|
|
|
|
|
|
|
# my $idx = $idx{$attr}; |
|
88
|
|
|
|
|
|
|
# $code_str .= qq( if (exists \$args{'$attr'}) { \$attrs[$idx] = delete \$args{'$attr'} }); |
|
89
|
|
|
|
|
|
|
#} |
|
90
|
|
|
|
|
|
|
#$code_str .= ' die "Unknown $class attributes in constructor: ".join(", ", sort keys %args) if keys %args;'; |
|
91
|
|
|
|
|
|
|
#$code_str .= qq( my \$self = pack('$pack_template', \@attrs); bless \\\$self, '$class';); |
|
92
|
|
|
|
|
|
|
#$code_str .= ' }'; |
|
93
|
|
|
|
|
|
|
|
|
94
|
|
|
|
|
|
|
#print "D:constructor code for class $class: ", $code_str, "\n"; |
|
95
|
3
|
|
100
|
|
|
12
|
my $constructor = $spec->{constructor} || "new"; |
|
96
|
3
|
50
|
|
|
|
5
|
unless (*{"$class\::$constructor"}{CODE}) { |
|
|
3
|
|
|
|
|
13
|
|
|
97
|
3
|
|
|
1
|
|
196
|
*{"$class\::$constructor"} = eval $code_str; |
|
|
3
|
|
|
|
|
10
|
|
|
|
1
|
|
|
|
|
974
|
|
|
|
1
|
|
|
|
|
4
|
|
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
|
1
|
|
|
|
|
2324
|
|
|
|
1
|
|
|
|
|
3
|
|
|
98
|
3
|
50
|
|
|
|
72
|
die if $@; |
|
99
|
|
|
|
|
|
|
}; |
|
100
|
|
|
|
|
|
|
} |
|
101
|
|
|
|
|
|
|
} |
|
102
|
|
|
|
|
|
|
|
|
103
|
|
|
|
|
|
|
1; |
|
104
|
|
|
|
|
|
|
# ABSTRACT: Like Class::Accessor::PackedString, but store attributes as they are set |
|
105
|
|
|
|
|
|
|
|
|
106
|
|
|
|
|
|
|
__END__ |