line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package JE::String; |
2
|
|
|
|
|
|
|
|
3
|
|
|
|
|
|
|
our $VERSION = '0.064'; |
4
|
|
|
|
|
|
|
|
5
|
|
|
|
|
|
|
|
6
|
101
|
|
|
101
|
|
31337
|
use strict; |
|
101
|
|
|
|
|
138
|
|
|
101
|
|
|
|
|
3219
|
|
7
|
101
|
|
|
101
|
|
401
|
use warnings; no warnings 'utf8'; |
|
101
|
|
|
101
|
|
113
|
|
|
101
|
|
|
|
|
2082
|
|
|
101
|
|
|
|
|
346
|
|
|
101
|
|
|
|
|
134
|
|
|
101
|
|
|
|
|
3379
|
|
8
|
|
|
|
|
|
|
|
9
|
101
|
|
|
|
|
469
|
use overload fallback => 1, |
10
|
|
|
|
|
|
|
'""' => 'value', |
11
|
|
|
|
|
|
|
# cmp => sub { "$_[0]" cmp $_[1] } |
12
|
101
|
|
|
101
|
|
1399
|
; |
|
101
|
|
|
|
|
857
|
|
13
|
|
|
|
|
|
|
|
14
|
101
|
|
|
101
|
|
5794
|
use Carp; |
|
101
|
|
|
|
|
143
|
|
|
101
|
|
|
|
|
5924
|
|
15
|
101
|
|
|
101
|
|
456
|
use Scalar::Util qw 'blessed tainted'; |
|
101
|
|
|
|
|
142
|
|
|
101
|
|
|
|
|
5205
|
|
16
|
|
|
|
|
|
|
|
17
|
101
|
|
|
101
|
|
433
|
use Exporter 5.57 'import'; |
|
101
|
|
|
|
|
2234
|
|
|
101
|
|
|
|
|
54725
|
|
18
|
|
|
|
|
|
|
our @EXPORT_OK = qw'surrogify desurrogify'; |
19
|
|
|
|
|
|
|
|
20
|
|
|
|
|
|
|
require JE::Object::String; |
21
|
|
|
|
|
|
|
require JE::Boolean; |
22
|
|
|
|
|
|
|
require JE::Number; |
23
|
|
|
|
|
|
|
|
24
|
|
|
|
|
|
|
|
25
|
|
|
|
|
|
|
# Internals: |
26
|
|
|
|
|
|
|
# bless [ $utf16_string, $unicode_string, $global_object], 'JE::String'; |
27
|
|
|
|
|
|
|
# Either of the first two slots may be empty. It will be filled in |
28
|
|
|
|
|
|
|
# on demand. |
29
|
|
|
|
|
|
|
|
30
|
|
|
|
|
|
|
|
31
|
|
|
|
|
|
|
sub new { |
32
|
19010
|
|
|
19010
|
0
|
27954
|
my($class, $global, $val) = @_; |
33
|
19010
|
50
|
|
|
|
53155
|
defined blessed $global |
34
|
|
|
|
|
|
|
or croak "First argument to JE::String->new is not an object"; |
35
|
|
|
|
|
|
|
|
36
|
19010
|
|
|
|
|
20244
|
my $self; |
37
|
19010
|
50
|
33
|
|
|
48912
|
if(defined blessed $val and $val->can('to_string')) { |
38
|
0
|
|
|
|
|
0
|
$self = bless [$val->to_string->[0],undef,$global], $class; |
39
|
|
|
|
|
|
|
} |
40
|
|
|
|
|
|
|
else { |
41
|
19010
|
|
|
|
|
54197
|
$self = bless [undef,$val, $global], $class; |
42
|
|
|
|
|
|
|
} |
43
|
19010
|
|
|
|
|
58269
|
$self; |
44
|
|
|
|
|
|
|
} |
45
|
|
|
|
|
|
|
|
46
|
|
|
|
|
|
|
sub _new { # ~~~ Should we document this and make it public? The problem |
47
|
|
|
|
|
|
|
# with it is that it has no error-checking whatsoever, and |
48
|
|
|
|
|
|
|
# can consequently make JS do weird things. (Maybe it’s OK, |
49
|
|
|
|
|
|
|
# since I doubt any code would choke on a charCodeAt result |
50
|
|
|
|
|
|
|
# > 0xffff.) |
51
|
47682
|
100
|
|
47682
|
|
227245
|
bless [defined $_[2] ? $_[2] : '',undef,$_[1]], $_[0]; |
52
|
|
|
|
|
|
|
} |
53
|
|
|
|
|
|
|
|
54
|
|
|
|
|
|
|
sub prop { |
55
|
|
|
|
|
|
|
# ~~~ Make prop simply return the value if the prototype has that |
56
|
|
|
|
|
|
|
# property. |
57
|
390
|
|
|
390
|
0
|
456
|
my $self = shift; |
58
|
|
|
|
|
|
|
|
59
|
390
|
100
|
|
|
|
823
|
if ($_[0] eq 'length') { |
60
|
13
|
100
|
|
|
|
100
|
return JE::Number->new($$self[2], length ( |
61
|
|
|
|
|
|
|
defined $$self[0] ? $$self[0] : |
62
|
|
|
|
|
|
|
($$self[0]=surrogify($$self[1])) |
63
|
|
|
|
|
|
|
)); |
64
|
|
|
|
|
|
|
} |
65
|
|
|
|
|
|
|
|
66
|
377
|
|
|
|
|
1073
|
$$self[2]->prototype_for('String')->prop(@_); |
67
|
|
|
|
|
|
|
} |
68
|
|
|
|
|
|
|
|
69
|
|
|
|
|
|
|
sub keys { |
70
|
0
|
|
|
0
|
0
|
0
|
my $self = shift; |
71
|
0
|
|
|
|
|
0
|
$$self[2]->prototype_for('String')->keys;} |
72
|
|
|
|
|
|
|
|
73
|
|
|
|
|
|
|
sub delete { |
74
|
0
|
|
|
0
|
0
|
0
|
return $_[1] ne 'length' |
75
|
|
|
|
|
|
|
} |
76
|
|
|
|
|
|
|
|
77
|
|
|
|
|
|
|
sub method { |
78
|
1
|
|
|
1
|
0
|
1
|
my $self = shift; |
79
|
1
|
|
|
|
|
28
|
$$self[2]->prototype_for('String')->prop(shift)->apply( |
80
|
|
|
|
|
|
|
$self,$$self[2]->upgrade(@_) |
81
|
|
|
|
|
|
|
); |
82
|
|
|
|
|
|
|
} |
83
|
|
|
|
|
|
|
|
84
|
|
|
|
|
|
|
|
85
|
|
|
|
|
|
|
sub value { |
86
|
29774
|
100
|
|
29774
|
0
|
1714523
|
defined $_[0][1] ? $_[0][1] : ($_[0][1] = desurrogify($_[0][0])); |
87
|
|
|
|
|
|
|
} |
88
|
|
|
|
|
|
|
*TO_JSON=*value; |
89
|
|
|
|
|
|
|
|
90
|
|
|
|
|
|
|
sub value16 { |
91
|
41101
|
100
|
|
41101
|
0
|
223469
|
defined $_[0][0] ? $_[0][0] : ($_[0][0] = surrogify($_[0][1])); |
92
|
|
|
|
|
|
|
} |
93
|
|
|
|
|
|
|
|
94
|
|
|
|
|
|
|
|
95
|
19975
|
|
|
19975
|
0
|
58775
|
sub typeof { 'string' } |
96
|
1195
|
|
|
1195
|
0
|
2176
|
sub id { 'str:' . $_[0]->value16 } |
97
|
80
|
|
|
80
|
0
|
831
|
sub class { 'String' } |
98
|
673
|
|
|
673
|
0
|
1867
|
sub primitive { 1 } |
99
|
|
|
|
|
|
|
|
100
|
26019
|
|
|
26019
|
0
|
38042
|
sub to_primitive { $_[0] } |
101
|
29454
|
|
|
29454
|
0
|
101793
|
sub to_string { $_[0] } |
102
|
|
|
|
|
|
|
# $_[0][2] is the global obj |
103
|
130
|
100
|
|
130
|
0
|
1587
|
sub to_boolean { JE::Boolean->new( $_[0][2], |
104
|
|
|
|
|
|
|
length defined $_[0][0] |
105
|
|
|
|
|
|
|
? $_[0][0] : $_[0][1] |
106
|
|
|
|
|
|
|
) } |
107
|
7
|
|
|
7
|
0
|
178
|
sub to_object { JE::Object::String->new($_[0][2], shift) } |
108
|
|
|
|
|
|
|
|
109
|
99
|
|
|
99
|
|
10274
|
our $s = qr.[\p{Zs}\s\ck\x{2028}\x{2029}]*.; |
|
99
|
|
|
|
|
12062
|
|
|
99
|
|
|
|
|
1677
|
|
110
|
|
|
|
|
|
|
|
111
|
|
|
|
|
|
|
sub to_number { |
112
|
844
|
|
|
844
|
0
|
19220
|
my $value = (my $self = shift)->[0]; |
113
|
844
|
100
|
|
|
|
2006
|
defined $value or $value = $$self[1]; |
114
|
844
|
100
|
|
|
|
9219
|
JE::Number->new($self->[2], |
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
115
|
|
|
|
|
|
|
$value =~ /^$s |
116
|
|
|
|
|
|
|
( |
117
|
|
|
|
|
|
|
[+-]? |
118
|
|
|
|
|
|
|
(?: |
119
|
|
|
|
|
|
|
(?=[0-9]|\.[0-9]) [0-9]* (?:\.[0-9]*)? |
120
|
|
|
|
|
|
|
(?:[Ee][+-]?[0-9]+)? |
121
|
|
|
|
|
|
|
| |
122
|
|
|
|
|
|
|
Infinity |
123
|
|
|
|
|
|
|
) |
124
|
|
|
|
|
|
|
$s |
125
|
|
|
|
|
|
|
)? |
126
|
|
|
|
|
|
|
\z |
127
|
|
|
|
|
|
|
/ox ? defined $1 ? $value : 0 : |
128
|
|
|
|
|
|
|
$value =~ /^$s 0[Xx] ([A-Fa-f0-9]+) $s\z/ox ? hex $1 : |
129
|
|
|
|
|
|
|
'NaN' |
130
|
|
|
|
|
|
|
); |
131
|
|
|
|
|
|
|
} |
132
|
|
|
|
|
|
|
|
133
|
2
|
|
|
2
|
0
|
7
|
sub global { $_[0][2] } |
134
|
|
|
|
|
|
|
|
135
|
|
|
|
|
|
|
sub taint { |
136
|
1
|
|
|
1
|
0
|
3
|
my $self = shift; |
137
|
1
|
50
|
33
|
|
|
8
|
tainted $self->[0] || tainted $self->[1] and return $self; |
138
|
0
|
|
|
|
|
0
|
my $alter_ego = [@$self]; |
139
|
0
|
0
|
|
|
|
0
|
$alter_ego->[defined $alter_ego->[0] ? 0 : 1] .= shift(); |
140
|
0
|
|
|
|
|
0
|
return bless $alter_ego, ref $self; |
141
|
|
|
|
|
|
|
} |
142
|
|
|
|
|
|
|
|
143
|
|
|
|
|
|
|
|
144
|
|
|
|
|
|
|
sub desurrogify($) { |
145
|
45876
|
|
|
45876
|
0
|
58826
|
my $ret = shift; |
146
|
45876
|
|
|
|
|
40422
|
my($ord1, $ord2); |
147
|
45876
|
|
|
|
|
121354
|
for(my $n = 0; $n < length $ret; ++$n) { # really slow |
148
|
1866414
|
100
|
100
|
|
|
4459609
|
($ord1 = ord substr $ret,$n,1) >= 0xd800 and |
|
|
|
100
|
|
|
|
|
|
|
|
66
|
|
|
|
|
149
|
|
|
|
|
|
|
$ord1 <= 0xdbff and |
150
|
|
|
|
|
|
|
($ord2 = ord substr $ret,$n+1,1) >= 0xdc00 and |
151
|
|
|
|
|
|
|
$ord2 <= 0xdfff and |
152
|
|
|
|
|
|
|
substr($ret,$n,2) = |
153
|
|
|
|
|
|
|
chr 0x10000 + ($ord1 - 0xD800) * 0x400 + ($ord2 - 0xDC00); |
154
|
|
|
|
|
|
|
} |
155
|
|
|
|
|
|
|
|
156
|
|
|
|
|
|
|
# In perl 5.8.8, if there is a sub on the call stack that was |
157
|
|
|
|
|
|
|
# triggered by the overloading mechanism when the object with the |
158
|
|
|
|
|
|
|
# overloaded operator was passed as the only argument to 'die', |
159
|
|
|
|
|
|
|
# then the following substitution magically calls that subroutine |
160
|
|
|
|
|
|
|
# again with the same arguments, thereby causing infinite |
161
|
|
|
|
|
|
|
# recursion: |
162
|
|
|
|
|
|
|
# |
163
|
|
|
|
|
|
|
# $ret =~ s/([\x{d800}-\x{dbff}])([\x{dc00}-\x{dfff}])/ |
164
|
|
|
|
|
|
|
# chr 0x10000 + (ord($1) - 0xD800) * 0x400 + |
165
|
|
|
|
|
|
|
# (ord($2) - 0xDC00) |
166
|
|
|
|
|
|
|
# /ge; |
167
|
|
|
|
|
|
|
# |
168
|
|
|
|
|
|
|
# 5.9.4 still has this bug. |
169
|
|
|
|
|
|
|
|
170
|
45876
|
|
|
|
|
220005
|
$ret; |
171
|
|
|
|
|
|
|
} |
172
|
|
|
|
|
|
|
|
173
|
|
|
|
|
|
|
sub surrogify($) { |
174
|
511
|
|
|
511
|
0
|
899
|
my $ret = shift; |
175
|
|
|
|
|
|
|
|
176
|
101
|
|
|
101
|
|
1504758
|
no warnings 'utf8'; |
|
101
|
|
|
|
|
161
|
|
|
101
|
|
|
|
|
10309
|
|
177
|
|
|
|
|
|
|
|
178
|
511
|
|
|
|
|
59335
|
$ret =~ s<([^\0-\x{ffff}])>< |
179
|
8
|
|
|
|
|
227
|
chr((ord($1) - 0x10000) / 0x400 + 0xD800) |
180
|
|
|
|
|
|
|
. chr((ord($1) - 0x10000) % 0x400 + 0xDC00) |
181
|
|
|
|
|
|
|
>eg; |
182
|
511
|
|
|
|
|
1827
|
$ret; |
183
|
|
|
|
|
|
|
} |
184
|
|
|
|
|
|
|
|
185
|
|
|
|
|
|
|
|
186
|
|
|
|
|
|
|
1; |
187
|
|
|
|
|
|
|
__END__ |