-
-
Notifications
You must be signed in to change notification settings - Fork 372
/
Registry.pm6
71 lines (66 loc) · 2.72 KB
/
Registry.pm6
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
my class X::Encoding::Unknown { ... }
my class X::Encoding::AlreadyRegistered { ... }
my class Encoding::Registry {
my $lock := Lock.new;
my %lookup; # access for registering builtins at compile time
my $lookup := nqp::getattr(%lookup,Map,'$!storage'); # access for runtime
BEGIN {
my $lookup := nqp::bindattr(%lookup,Map,'$!storage',nqp::hash);
### If updating encodings here, also update src/core.c/Rakudo/Internals.pm6
my $encodings := nqp::list(
nqp::list('utf8', 'utf-8'),
nqp::list('utf8-c8', 'utf8c8', 'utf-8-c8'),
nqp::list('utf16', 'utf-16'),
nqp::list('utf16le', 'utf-16le', 'utf16-le', 'utf-16-le'),
nqp::list('utf16be', 'utf-16be', 'utf16-be', 'utf-16-be'),
nqp::list('utf32', 'utf-32'),
nqp::list('ascii'),
nqp::list('iso-8859-1','iso_8859-1:1987','iso_8859-1','iso-ir-100',
'latin1','latin-1','csisolatin1','l1','ibm819','cp819'),
nqp::list('windows-1251', 'windows1251'),
nqp::list('windows-1252', 'windows1252'),
nqp::list('windows-932', 'windows932'),
nqp::list('gb2312', 'gb2312'),
nqp::list('gb18030', 'gb18030'),
);
my int $i = -1;
my int $elems = nqp::elems($encodings);
while nqp::islt_i(($i = nqp::add_i($i,1)),$elems) {
my $names := nqp::atpos($encodings,$i);
my $builtin := nqp::create(Encoding::Builtin).SET-SELF(
nqp::shift($names),nqp::clone($names));
nqp::bindkey($lookup,$builtin.name,$builtin);
while nqp::elems($names) {
nqp::bindkey($lookup,nqp::shift($names),$builtin);
}
}
}
method register(Encoding $enc --> Nil) {
$lock.protect: {
nqp::existskey($lookup,(my str $key = $enc.name.fc))
?? X::Encoding::AlreadyRegistered.new(name => $enc.name).throw
!! nqp::bindkey($lookup,$key,$enc);
my $names := nqp::getattr($enc.alternative-names,List,'$!reified');
my int $elems = nqp::elems($names);
my int $i = -1;
nqp::while(
nqp::islt_i(($i = nqp::add_i($i,1)),$elems),
nqp::if(
nqp::existskey($lookup,($key = nqp::atpos($names,$i).fc)),
X::Encoding::AlreadyRegistered.new(
name => nqp::atpos($names,$i)).throw,
nqp::bindkey($lookup,$key,$enc)
)
);
}
}
method find(Str() $name) {
$lock.protect: {
nqp::ifnull(
nqp::atkey($lookup,$name.fc),
X::Encoding::Unknown.new(:$name).throw
)
}
}
}
# vim: expandtab shiftwidth=4