Skip to content

Commit

Permalink
improved encode/decode performance in Mojo::Util with a cache
Browse files Browse the repository at this point in the history
  • Loading branch information
kraih committed Nov 25, 2012
1 parent cf0855f commit ad9c717
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 10 deletions.
1 change: 1 addition & 0 deletions Changes
@@ -1,6 +1,7 @@

3.62 2012-11-26
- Improved compatibility with IO::Socket::SSL 1.79.
- Improved encode/decode performance in Mojo::Util by using a cache.
- Improved tests.
- Fixed clone bugs in Mojo::URL.

Expand Down
13 changes: 10 additions & 3 deletions lib/Mojo/Util.pm
Expand Up @@ -4,7 +4,7 @@ use Mojo::Base 'Exporter';
use Carp 'croak';
use Digest::MD5 qw(md5 md5_hex);
use Digest::SHA qw(sha1 sha1_hex);
use Encode ();
use Encode 'find_encoding';
use File::Basename 'dirname';
use File::Spec::Functions 'catfile';
use MIME::Base64 qw(decode_base64 encode_base64);
Expand Down Expand Up @@ -37,6 +37,9 @@ $REVERSE{$ENTITIES{$_}} //= $_
for sort { @{[$a =~ /[A-Z]/g]} <=> @{[$b =~ /[A-Z]/g]} }
sort grep {/;/} keys %ENTITIES;

# Encoding cache
my %CACHE;

our @EXPORT_OK = (
qw(b64_decode b64_encode camelize class_to_file class_to_path decamelize),
qw(decode encode get_line hmac_md5_sum hmac_sha1_sum html_escape),
Expand Down Expand Up @@ -88,11 +91,11 @@ sub decamelize {
sub decode {
my ($encoding, $bytes) = @_;
return undef
unless eval { $bytes = Encode::decode($encoding, $bytes, 1); 1 };
unless eval { $bytes = _encoding($encoding)->decode("$bytes", 1); 1 };
return $bytes;
}
sub encode { Encode::encode(shift, shift) }
sub encode { _encoding($_[0])->encode("$_[1]") }
sub get_line {
Expand Down Expand Up @@ -370,6 +373,10 @@ sub _encode {
return exists $REVERSE{$_[0]} ? "&$REVERSE{$_[0]}" : "&#@{[ord($_[0])]};";
}

sub _encoding {
$CACHE{$_[0]} //= find_encoding($_[0]) // croak "Unknown encoding '$_[0]'";
}

sub _hmac {
my ($hash, $string, $secret) = @_;

Expand Down
22 changes: 15 additions & 7 deletions t/mojo/util.t
Expand Up @@ -65,21 +65,29 @@ is b64_encode('foobar$%^&3217'), "Zm9vYmFyJCVeJjMyMTc=\n",
is b64_decode("Zm9vYmFyJCVeJjMyMTc=\n"), 'foobar$%^&3217',
'right base64 decoded result';

# UTF-8 b64_encode
# b64_encode (UTF-8)
is b64_encode(encode 'UTF-8', "foo\x{df}\x{0100}bar%23\x{263a}"),
"Zm9vw5/EgGJhciUyM+KYug==\n", 'right base64 encoded result';

# UTF-8 b64_decode
# b64_decode (UTF-8)
is decode('UTF-8', b64_decode "Zm9vw5/EgGJhciUyM+KYug==\n"),
"foo\x{df}\x{0100}bar%23\x{263a}", 'right base64 decoded result';

# b64_encode (custom line ending)
is b64_encode('foobar$%^&3217', ''), 'Zm9vYmFyJCVeJjMyMTc=',
'right base64 encoded result';

# Decode invalid UTF-8
# decode (invalid UTF-8)
is decode('UTF-8', "\x{1000}"), undef, 'decoding invalid UTF-8 worked';

# decode (invalid encoding)
is decode('does_not_exist', ''), undef,
'decoding with invalid encoding worked';

# encode (invalid encoding)
eval { encode('does_not_exist', '') };
like $@, qr/Unknown encoding 'does_not_exist'/, 'right error';

# url_escape
is url_escape('business;23'), 'business%3B23', 'right url escaped result';

Expand Down Expand Up @@ -128,11 +136,11 @@ is html_unescape('foobar'), 'foobar', 'right html unescaped result';
is html_unescape('&Ltf&amp&0oo&nbspba;&ltr'), "&Ltf&&0oo\x{00a0}ba;<r",
'right html unescaped result';

# UTF-8 html_escape
# html_escape (UTF-8)
is html_escape("fo\nobar<baz>&\"\x{152}\x{02ae4}"),
"fo\nobar&lt;baz&gt;&amp;&quot;&OElig;&Dashv;", 'right html escaped result';

# UTF-8 html_unescape
# html_unescape (UTF-8)
is html_unescape(decode 'UTF-8', 'foo&lt;baz&gt;&#x26;&#34;&OElig;&Foo;'),
"foo<baz>&\"\x{152}&Foo;", 'right html unescaped result';

Expand All @@ -149,10 +157,10 @@ is xml_escape(qq{la<f>\nbar"baz"'yada\n'&lt;la}),
"la&lt;f&gt;\nbar&quot;baz&quot;&#39;yada\n&#39;&amp;lt;la",
'right xml escaped result';

# UTF-8 xml_escape with nothing to escape
# xml_escape (UTF-8 with nothing to escape)
is xml_escape('привет'), 'привет', 'right xml escaped result';

# UTF-8 xml_escape
# xml_escape (UTF-8)
is xml_escape('привет<foo>'), 'привет&lt;foo&gt;',
'right xml escaped result';

Expand Down

0 comments on commit ad9c717

Please sign in to comment.