faster string_from
Karel Miko
10 years ago
45 | 45 | my ($self, $chars, $len) = @_; |
46 | 46 | |
47 | 47 | $len = 20 unless defined $len; |
48 | return unless $len>0; | |
48 | return unless $len > 0; | |
49 | return unless length($chars) > 0; | |
49 | 50 | |
50 | 51 | my @ch = split(//, $chars); |
51 | my $max_index = scalar(@ch)-1; | |
52 | ||
52 | my $max_index = $#ch; | |
53 | return if $max_index > 65535; | |
54 | ||
53 | 55 | my $mask; |
54 | 56 | for my $n (1..31) { |
55 | 57 | $mask = (1<<$n) - 1; |
56 | 58 | last if $mask >= $max_index; |
57 | 59 | } |
58 | 60 | |
61 | my $upck = ($max_index > 255) ? "n*" : "C*"; | |
62 | my $l = $len * 2; | |
63 | ||
59 | 64 | my $rv = ''; |
65 | my @r; | |
60 | 66 | while (length $rv < $len) { |
61 | my $i = $self->int32 & $mask; | |
67 | @r = unpack($upck, $self->bytes($l)) if scalar @r == 0; | |
68 | my $i = (shift @r) & $mask; | |
62 | 69 | next if $i > $max_index; |
63 | 70 | $rv .= $ch[$i]; |
64 | 71 | } |