File Coverage

blib/lib/MARC/Charset/Table.pm
Criterion Covered Total %
statement 48 53 90.5
branch 4 6 66.6
condition 1 6 16.6
subroutine 16 17 94.1
pod 8 8 100.0
total 77 90 85.5


line stmt bran cond sub pod time code
1             package MARC::Charset::Table;
2              
3             =head1 NAME
4              
5             MARC::Charset::Table - character mapping db
6              
7             =head1 SYNOPSIS
8              
9             use MARC::Charset::Table;
10             use MARC::Charset::Constants qw(:all);
11              
12             # create the table object
13             my $table = MARC::Charset::Table->new();
14            
15             # get a code using the marc8 character set code and the character
16             my $code = $table->lookup_by_marc8(CYRILLIC_BASIC, 'K');
17              
18             # get a code using the utf8 value
19             $code = $table->lookup_by_utf8(chr(0x043A));
20              
21             =head1 DESCRIPTION
22              
23             MARC::Charset::Table is a wrapper around the character mapping database,
24             which is implemented as a tied hash on disk. This database gets generated
25             by Makefile.PL on installation of MARC::Charset using
26             MARC::Charset::Compiler.
27              
28             The database is essentially a key/value mapping where a key is a
29             MARC-8 character set code + a MARC-8 character, or an integer representing the
30             UCS code point. These keys map to a serialized MARC::Charset::Code object.
31              
32             =cut
33              
34 17     17   1088 use strict;
  17         38  
  17         769  
35 17     17   97 use warnings;
  17         38  
  17         562  
36 17     17   20911 use POSIX;
  17         577007  
  17         406  
37             BEGIN {
38 17     17   67671 @AnyDBM_File::ISA = qw(GDBM_File DB_File NDBM_File ODBM_File SDBM_File);
39             # SDBM_File is last on the list because it produces the largest database
40             # on disk.
41             }
42 17     17   17679 use AnyDBM_File;
  17         109256  
  17         1089  
43 17     17   23700 use MARC::Charset::Code;
  17         63  
  17         153  
44 17     17   734 use MARC::Charset::Constants qw(:all);
  17         31  
  17         3675  
45 17     17   39382 use Storable qw(nfreeze thaw);
  17         93614  
  17         11983  
46              
47             =head2 new()
48              
49             The consturctor.
50              
51             =cut
52              
53             sub new
54             {
55 17     17 1 525 my $class = shift;
56 17   33     358 my $self = bless {}, ref($class) || $class;
57 17         89 $self->_init(O_RDONLY);
58 17         69 return $self;
59             }
60              
61              
62             =head2 add_code()
63              
64             Add a MARC::Charset::Code to the table.
65              
66             =cut
67              
68              
69             sub add_code
70             {
71 1     1 1 72 my ($self, $code) = @_;
72              
73             # the Code object is serialized
74 1         6 my $frozen = nfreeze($code);
75              
76             # to support lookup by marc8 and utf8 values we
77             # stash away the rule in the db using two keys
78 1         162 my $marc8_key = $code->marc8_hash_code();
79 1         6 my $utf8_key = $code->utf8_hash_code();
80              
81             # stash away the marc8 lookup key
82 1         14 $self->{db}->{$marc8_key} = $frozen;
83              
84             # stash away the utf8 lookup key (only if it's not already there!)
85             # this means that the sets that appear in the xml file will have
86             # precedence ascii/ansel. Note that we're using 'defined' instead of
87             # 'exists' because NDBM_File and ODBM_File don't support 'exists'.
88 1 50       46 $self->{db}->{$utf8_key} = $frozen unless defined $self->{db}->{$utf8_key};
89             }
90              
91              
92             =head2 get_code()
93              
94             Retrieve a code using a hash key.
95              
96             =cut
97              
98             sub get_code
99             {
100 480     480 1 670 my ($self, $key) = @_;
101 480         1475 my $db = $self->db();
102 480         701778 my $frozen = $db->{$key};
103 480 50       3247 return thaw($frozen) if $frozen;
104 0         0 return;
105             }
106              
107              
108             =head2 lookup_by_marc8()
109              
110             Looks up MARC::Charset::Code entry using a character set code and a MARC-8
111             value.
112              
113             use MARC::Charset::Constants qw(HEBREW);
114             $code = $table->lookup_by_marc8(HEBREW, chr(0x60));
115              
116             =cut
117              
118             sub lookup_by_marc8
119             {
120 367     367 1 584 my ($self, $charset, $marc8) = @_;
121 367 100       751 $charset = BASIC_LATIN if $charset eq ASCII_DEFAULT;
122 367         1320 return $self->get_code(sprintf('%s:%s', $charset, $marc8));
123             }
124              
125              
126             =head2 lookup_by_utf8()
127              
128             Looks up a MARC::Charset::Code object using a utf8 value.
129              
130             =cut
131              
132             sub lookup_by_utf8
133             {
134 111     111 1 286 my ($self, $value) = @_;
135 111         426 return $self->get_code(ord($value));
136             }
137              
138              
139              
140              
141             =head2 db()
142              
143             Returns a reference to a tied character database. MARC::Charset::Table
144             wraps access to the db, but you can get at it if you want.
145              
146             =cut
147              
148             sub db
149             {
150 481     481 1 1347 return shift->{db};
151             }
152              
153              
154             =head2 db_path()
155              
156             Returns the path to the character encoding database. Can be called
157             statically too:
158              
159             print MARC::Charset::Table->db_path();
160              
161             =cut
162              
163             sub db_path
164             {
165 18     18 1 64 my $path = $INC{'MARC/Charset/Table.pm'};
166 18         161 $path =~ s/\.pm$//;
167 18         2351 return $path;
168             }
169              
170              
171             =head2 brand_new()
172              
173             An alternate constructor which removes the existing database and starts
174             afresh. Be careful with this one, it's really only used on MARC::Charset
175             installation.
176              
177             =cut
178              
179             sub brand_new
180             {
181 0     0 1 0 my $class = shift;
182 0   0     0 my $self = bless {}, ref($class) || $class;
183 0         0 $self->_init(O_CREAT|O_RDWR);
184              
185 0         0 return $self;
186             }
187              
188              
189             # helper function for initializing table internals
190              
191             sub _init
192             {
193 17     17   41 my ($self, $dbm_opts) = @_;
194 17         75 tie my %db, 'AnyDBM_File', db_path(), $dbm_opts, 0644; ## no critic (ValuesAndExpressions::ProhibitLeadingZeros)
195 17         171 $self->{db} = \%db;
196             }
197              
198              
199              
200              
201              
202             1;