File Coverage

blib/lib/Encode/UTF8/Slow.pm
Criterion Covered Total %
statement 24 24 100.0
branch 12 12 100.0
condition n/a
subroutine 5 5 100.0
pod 2 2 100.0
total 43 43 100.0


line stmt bran cond sub pod time code
1             package Encode::UTF8::Slow;
2 1     1   13710 use strict;
  1         1  
  1         23  
3 1     1   503 use Encode 'encode';
  1         7250  
  1         59  
4 1     1   5 use Exporter 'import';
  1         3  
  1         217  
5              
6             our $VERSION = 0.01;
7             our @EXPORT_OK = qw/bytes_to_codepoint codepoint_to_bytes/;
8              
9             # utf8 handling per RFC 3629
10             # Char. number range | UTF-8 octet sequence
11             # (hexadecimal) | (binary)
12             # --------------------+------------------------------------
13             # 0000 0000-0000 007F | 0xxxxxxx
14             # 0000 0080-0000 07FF | 110xxxxx 10xxxxxx
15             # 0000 0800-0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx
16             # 0001 0000-0010 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
17              
18             sub codepoint_to_bytes {
19 6     6 1 655 my $codepoint = shift;
20              
21 6 100       20 if ($codepoint < 0x80) {
    100          
    100          
22 1         14 return pack 'C', $codepoint;
23             }
24             elsif ($codepoint < 0x800) {
25 2         19 return pack 'CC',
26             $codepoint >> 6 | 0b11000000,
27             $codepoint & 0b00111111 | 0b10000000;
28             }
29             elsif ($codepoint < 0x10000) {
30 1         9 return pack 'CCC',
31             $codepoint >> 12 | 0b11100000,
32             $codepoint >> 6 & 0b00111111 | 0b10000000,
33             $codepoint & 0b00111111 | 0b10000000;
34             }
35             else {
36 2         18 return pack 'CCCC',
37             $codepoint >> 18 | 0b11110000,
38             $codepoint >> 12 & 0b00111111 | 0b10000000,
39             $codepoint >> 6 & 0b00111111 | 0b10000000,
40             $codepoint & 0b00111111 | 0b10000000;
41             }
42             }
43              
44             sub bytes_to_codepoint {
45             # treat the scalar as bytes/octets
46 6     6 1 899 my $input = encode('UTF-8', shift);
47              
48             # length returns number of bytes
49 6         271 my $len = length $input;
50 6         8 my $template = 'C' x $len;
51 6         16 my @bytes = unpack $template, $input;
52              
53             # reverse encoding
54 6 100       16 if ($len == 1) {
    100          
    100          
55 1         4 return $bytes[0];
56             }
57             elsif ($len == 2) {
58 2         8 return (($bytes[0] & 0b00011111) << 6) +
59             ($bytes[1] & 0b00111111);
60             }
61             elsif ($len == 3) {
62 1         5 return (($bytes[0] & 0b00001111) << 12) +
63             (($bytes[1] & 0b00111111) << 6) +
64             ( $bytes[2] & 0b00111111);
65             }
66             else {
67 2         9 return (($bytes[0] & 0b00000111) << 18) +
68             (($bytes[1] & 0b00111111) << 12) +
69             (($bytes[2] & 0b00111111) << 6) +
70             ($bytes[3] & 0b00111111);
71             }
72             }
73              
74             1;
75             __END__