| Filename | /usr/share/perl5/Business/ISBN.pm |
| Statements | Executed 33 statements in 3.46ms |
| Calls | P | F | Exclusive Time |
Inclusive Time |
Subroutine |
|---|---|---|---|---|---|
| 1 | 1 | 1 | 3.37ms | 3.60ms | Business::ISBN::BEGIN@75 |
| 1 | 1 | 1 | 818µs | 1.59ms | Business::ISBN::BEGIN@132 |
| 1 | 1 | 1 | 773µs | 1.35ms | Business::ISBN::BEGIN@133 |
| 1 | 1 | 1 | 271µs | 316µs | Business::ISBN::BEGIN@61 |
| 1 | 1 | 1 | 81µs | 81µs | Business::ISBN::CORE:sort (opcode) |
| 1 | 1 | 1 | 20µs | 25µs | Business::ISBN::BEGIN@4 |
| 1 | 1 | 1 | 15µs | 92µs | Business::ISBN::BEGIN@73 |
| 1 | 1 | 1 | 13µs | 67µs | Business::ISBN::BEGIN@72 |
| 1 | 1 | 1 | 13µs | 133µs | Business::ISBN::BEGIN@69 |
| 1 | 1 | 1 | 11µs | 11µs | Business::ISBN::BEGIN@99 |
| 0 | 0 | 0 | 0s | 0s | Business::ISBN::_check_validity |
| 0 | 0 | 0 | 0s | 0s | Business::ISBN::_checksum_pos |
| 0 | 0 | 0 | 0s | 0s | Business::ISBN::_common_format |
| 0 | 0 | 0 | 0s | 0s | Business::ISBN::_get_xisbn |
| 0 | 0 | 0 | 0s | 0s | Business::ISBN::_group_code_length |
| 0 | 0 | 0 | 0s | 0s | Business::ISBN::_group_data |
| 0 | 0 | 0 | 0s | 0s | Business::ISBN::_hyphen_positions |
| 0 | 0 | 0 | 0s | 0s | Business::ISBN::_init |
| 0 | 0 | 0 | 0s | 0s | Business::ISBN::_max_group_code_length |
| 0 | 0 | 0 | 0s | 0s | Business::ISBN::_max_publisher_code_length |
| 0 | 0 | 0 | 0s | 0s | Business::ISBN::_parse_article_code |
| 0 | 0 | 0 | 0s | 0s | Business::ISBN::_parse_checksum |
| 0 | 0 | 0 | 0s | 0s | Business::ISBN::_parse_group_code |
| 0 | 0 | 0 | 0s | 0s | Business::ISBN::_parse_isbn |
| 0 | 0 | 0 | 0s | 0s | Business::ISBN::_parse_publisher_code |
| 0 | 0 | 0 | 0s | 0s | Business::ISBN::_prefix_length |
| 0 | 0 | 0 | 0s | 0s | Business::ISBN::_publisher_code_length |
| 0 | 0 | 0 | 0s | 0s | Business::ISBN::_publisher_ranges |
| 0 | 0 | 0 | 0s | 0s | Business::ISBN::_set_article_code |
| 0 | 0 | 0 | 0s | 0s | Business::ISBN::_set_checksum |
| 0 | 0 | 0 | 0s | 0s | Business::ISBN::_set_group_code |
| 0 | 0 | 0 | 0s | 0s | Business::ISBN::_set_group_code_string |
| 0 | 0 | 0 | 0s | 0s | Business::ISBN::_set_is_valid |
| 0 | 0 | 0 | 0s | 0s | Business::ISBN::_set_isbn |
| 0 | 0 | 0 | 0s | 0s | Business::ISBN::_set_prefix |
| 0 | 0 | 0 | 0s | 0s | Business::ISBN::_set_publisher_code |
| 0 | 0 | 0 | 0s | 0s | Business::ISBN::_set_publisher_code_string |
| 0 | 0 | 0 | 0s | 0s | Business::ISBN::_set_type |
| 0 | 0 | 0 | 0s | 0s | Business::ISBN::_xisbn_url |
| 0 | 0 | 0 | 0s | 0s | Business::ISBN::article_code |
| 0 | 0 | 0 | 0s | 0s | Business::ISBN::as_isbn10 |
| 0 | 0 | 0 | 0s | 0s | Business::ISBN::as_isbn13 |
| 0 | 0 | 0 | 0s | 0s | Business::ISBN::as_string |
| 0 | 0 | 0 | 0s | 0s | Business::ISBN::checksum |
| 0 | 0 | 0 | 0s | 0s | Business::ISBN::common_data |
| 0 | 0 | 0 | 0s | 0s | Business::ISBN::error |
| 0 | 0 | 0 | 0s | 0s | Business::ISBN::fix_checksum |
| 0 | 0 | 0 | 0s | 0s | Business::ISBN::group |
| 0 | 0 | 0 | 0s | 0s | Business::ISBN::group_code |
| 0 | 0 | 0 | 0s | 0s | Business::ISBN::input_isbn |
| 0 | 0 | 0 | 0s | 0s | Business::ISBN::is_valid |
| 0 | 0 | 0 | 0s | 0s | Business::ISBN::is_valid_checksum |
| 0 | 0 | 0 | 0s | 0s | Business::ISBN::isbn |
| 0 | 0 | 0 | 0s | 0s | Business::ISBN::new |
| 0 | 0 | 0 | 0s | 0s | Business::ISBN::png_barcode |
| 0 | 0 | 0 | 0s | 0s | Business::ISBN::prefix |
| 0 | 0 | 0 | 0s | 0s | Business::ISBN::publisher_code |
| 0 | 0 | 0 | 0s | 0s | Business::ISBN::type |
| 0 | 0 | 0 | 0s | 0s | Business::ISBN::valid_isbn_checksum |
| 0 | 0 | 0 | 0s | 0s | Business::ISBN::xisbn |
| Line | State ments |
Time on line |
Calls | Time in subs |
Code |
|---|---|---|---|---|---|
| 1 | # $Revision: 2.16 $ | ||||
| 2 | # $Id: ISBN.pm,v 2.16 2008/08/09 04:29:55 comdog Exp $ | ||||
| 3 | package Business::ISBN; | ||||
| 4 | 3 | 52µs | 2 | 30µs | # spent 25µs (20+5) within Business::ISBN::BEGIN@4 which was called:
# once (20µs+5µs) by C4::Search::BEGIN@36 at line 4 # spent 25µs making 1 call to Business::ISBN::BEGIN@4
# spent 5µs making 1 call to strict::import |
| 5 | |||||
| 6 | =head1 NAME | ||||
| 7 | |||||
| - - | |||||
| 58 | # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # | ||||
| 59 | # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # | ||||
| 60 | # # Boring set up stuff | ||||
| 61 | 1 | 45µs | # spent 316µs (271+45) within Business::ISBN::BEGIN@61 which was called:
# once (271µs+45µs) by C4::Search::BEGIN@36 at line 68 # spent 45µs making 1 call to subs::import | ||
| 62 | _common_format | ||||
| 63 | INVALID_GROUP_CODE | ||||
| 64 | INVALID_PUBLISHER_CODE | ||||
| 65 | BAD_CHECKSUM | ||||
| 66 | GOOD_ISBN | ||||
| 67 | BAD_ISBN | ||||
| 68 | 3 | 244µs | 1 | 316µs | ); # spent 316µs making 1 call to Business::ISBN::BEGIN@61 |
| 69 | 1 | 120µs | # spent 133µs (13+120) within Business::ISBN::BEGIN@69 which was called:
# once (13µs+120µs) by C4::Search::BEGIN@36 at line 70 # spent 120µs making 1 call to vars::import | ||
| 70 | 3 | 39µs | 1 | 133µs | $MAX_GROUP_CODE_LENGTH %ERROR_TEXT ); # spent 133µs making 1 call to Business::ISBN::BEGIN@69 |
| 71 | |||||
| 72 | 3 | 40µs | 2 | 121µs | # spent 67µs (13+54) within Business::ISBN::BEGIN@72 which was called:
# once (13µs+54µs) by C4::Search::BEGIN@36 at line 72 # spent 67µs making 1 call to Business::ISBN::BEGIN@72
# spent 54µs making 1 call to Exporter::import |
| 73 | 3 | 40µs | 2 | 170µs | # spent 92µs (15+77) within Business::ISBN::BEGIN@73 which was called:
# once (15µs+77µs) by C4::Search::BEGIN@36 at line 73 # spent 92µs making 1 call to Business::ISBN::BEGIN@73
# spent 77µs making 1 call to base::import |
| 74 | |||||
| 75 | 3 | 428µs | 3 | 3.62ms | # spent 3.60ms (3.37+228µs) within Business::ISBN::BEGIN@75 which was called:
# once (3.37ms+228µs) by C4::Search::BEGIN@36 at line 75 # spent 3.60ms making 1 call to Business::ISBN::BEGIN@75
# spent 13µs making 1 call to UNIVERSAL::VERSION
# spent 4µs making 1 call to UNIVERSAL::import |
| 76 | # ugh, hack | ||||
| 77 | 1 | 2µs | *group_data = *Business::ISBN::country_data; | ||
| 78 | sub _group_data { $group_data{ $_[1] } } | ||||
| 79 | |||||
| 80 | sub _max_group_code_length { $Business::ISBN::MAX_COUNTRY_CODE_LENGTH }; | ||||
| 81 | sub _max_publisher_code_length { | ||||
| 82 | $_[0]->_max_length | ||||
| 83 | |||||
| 84 | - $_[0]->_prefix_length # prefix | ||||
| 85 | |||||
| 86 | - $_[0]->_group_code_length # group | ||||
| 87 | - 1 # article | ||||
| 88 | - 1; # checksum | ||||
| 89 | }; | ||||
| 90 | |||||
| 91 | sub _publisher_ranges | ||||
| 92 | { | ||||
| 93 | my $self = shift; | ||||
| 94 | [ @{ $self->_group_data( $self->group_code )->[1] } ]; | ||||
| 95 | } | ||||
| 96 | |||||
| 97 | 1 | 400ns | my $debug = 0; | ||
| 98 | |||||
| 99 | # spent 11µs within Business::ISBN::BEGIN@99 which was called:
# once (11µs+0s) by C4::Search::BEGIN@36 at line 111 | ||||
| 100 | 2 | 11µs | @EXPORT_OK = qw( | ||
| 101 | INVALID_GROUP_CODE INVALID_PUBLISHER_CODE | ||||
| 102 | BAD_CHECKSUM GOOD_ISBN BAD_ISBN | ||||
| 103 | INVALID_PREFIX | ||||
| 104 | %ERROR_TEXT | ||||
| 105 | valid_isbn_checksum | ||||
| 106 | ); | ||||
| 107 | |||||
| 108 | %EXPORT_TAGS = ( | ||||
| 109 | 'all' => \@EXPORT_OK, | ||||
| 110 | ); | ||||
| 111 | 1 | 168µs | 1 | 11µs | }; # spent 11µs making 1 call to Business::ISBN::BEGIN@99 |
| 112 | |||||
| 113 | 1 | 600ns | $VERSION = "2.05"; | ||
| 114 | |||||
| 115 | sub INVALID_PREFIX () { -4 }; | ||||
| 116 | sub INVALID_GROUP_CODE () { -2 }; | ||||
| 117 | sub INVALID_PUBLISHER_CODE () { -3 }; | ||||
| 118 | sub BAD_CHECKSUM () { -1 }; | ||||
| 119 | sub GOOD_ISBN () { 1 }; | ||||
| 120 | sub BAD_ISBN () { 0 }; | ||||
| 121 | |||||
| 122 | |||||
| 123 | 1 | 7µs | %ERROR_TEXT = ( | ||
| 124 | 0 => "Bad ISBN", | ||||
| 125 | 1 => "Good ISBN", | ||||
| 126 | -1 => "Bad ISBN checksum", | ||||
| 127 | -2 => "Invalid group code", | ||||
| 128 | -3 => "Invalid publisher code", | ||||
| 129 | -4 => "Invalid prefix (must be 978 or 979)", | ||||
| 130 | ); | ||||
| 131 | |||||
| 132 | 3 | 187µs | 2 | 1.62ms | # spent 1.59ms (818µs+774µs) within Business::ISBN::BEGIN@132 which was called:
# once (818µs+774µs) by C4::Search::BEGIN@36 at line 132 # spent 1.59ms making 1 call to Business::ISBN::BEGIN@132
# spent 27µs making 1 call to Exporter::import |
| 133 | 3 | 2.23ms | 2 | 1.37ms | # spent 1.35ms (773µs+573µs) within Business::ISBN::BEGIN@133 which was called:
# once (773µs+573µs) by C4::Search::BEGIN@36 at line 133 # spent 1.35ms making 1 call to Business::ISBN::BEGIN@133
# spent 26µs making 1 call to Exporter::import |
| 134 | |||||
| 135 | =head2 Function interface | ||||
| 136 | |||||
| - - | |||||
| 157 | sub valid_isbn_checksum | ||||
| 158 | { | ||||
| 159 | my $isbn = shift; | ||||
| 160 | |||||
| 161 | my $obj = Business::ISBN->new( $isbn ); | ||||
| 162 | |||||
| 163 | return 1 if $obj->is_valid_checksum == GOOD_ISBN; | ||||
| 164 | return 0 if $obj->is_valid_checksum == BAD_CHECKSUM; | ||||
| 165 | return; | ||||
| 166 | } | ||||
| 167 | |||||
| 168 | =head2 Object interface | ||||
| 169 | |||||
| - - | |||||
| 224 | # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # | ||||
| 225 | # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # | ||||
| 226 | sub new | ||||
| 227 | { | ||||
| 228 | my $class = shift; | ||||
| 229 | my $input_data = shift; | ||||
| 230 | my $common_data = _common_format $input_data; | ||||
| 231 | |||||
| 232 | return unless $common_data; | ||||
| 233 | |||||
| 234 | my $self = { | ||||
| 235 | input_isbn => $input_data, | ||||
| 236 | common_data => $common_data | ||||
| 237 | }; | ||||
| 238 | |||||
| 239 | my $isbn = do { | ||||
| 240 | if( length( $common_data ) == 10 ) | ||||
| 241 | { | ||||
| 242 | bless $self, 'Business::ISBN10'; | ||||
| 243 | } | ||||
| 244 | elsif( length( $common_data ) == 13 ) | ||||
| 245 | { | ||||
| 246 | bless $self, 'Business::ISBN13'; | ||||
| 247 | } | ||||
| 248 | else | ||||
| 249 | { | ||||
| 250 | return BAD_ISBN; | ||||
| 251 | } | ||||
| 252 | }; | ||||
| 253 | |||||
| 254 | $self->_init( $common_data ); | ||||
| 255 | $self->_parse_isbn( $common_data ); | ||||
| 256 | |||||
| 257 | return $isbn; | ||||
| 258 | } | ||||
| 259 | |||||
| 260 | =back | ||||
| 261 | |||||
| - - | |||||
| 273 | sub input_isbn { $_[0]->{'input_isbn'} } | ||||
| 274 | |||||
| 275 | =item common_data | ||||
| 276 | |||||
| - - | |||||
| 282 | sub common_data { $_[0]->{'common_data'} } | ||||
| 283 | |||||
| 284 | |||||
| 285 | =item isbn | ||||
| 286 | |||||
| - - | |||||
| 295 | sub isbn { $_[0]->{'isbn'} } | ||||
| 296 | |||||
| 297 | =item error | ||||
| 298 | |||||
| - - | |||||
| 304 | sub error { $_[0]->{'valid'} } | ||||
| 305 | |||||
| 306 | =item is_valid | ||||
| 307 | |||||
| - - | |||||
| 314 | sub is_valid { $_[0]->{'valid'} eq GOOD_ISBN } | ||||
| 315 | |||||
| 316 | =item type | ||||
| 317 | |||||
| - - | |||||
| 322 | sub type { $_[0]->{'type'} } | ||||
| 323 | |||||
| 324 | |||||
| 325 | =item prefix | ||||
| 326 | |||||
| - - | |||||
| 333 | sub prefix { $_[0]->{'prefix'} } | ||||
| 334 | sub _prefix_length { length $_[0]->{'prefix'} } | ||||
| 335 | |||||
| 336 | =item group_code | ||||
| 337 | |||||
| - - | |||||
| 344 | sub group_code { $_[0]->{'group_code'} } | ||||
| 345 | |||||
| 346 | =item group | ||||
| 347 | |||||
| - - | |||||
| 354 | sub group { $_[0]->_group_data( $_[0]->group_code )->[0] } | ||||
| 355 | |||||
| 356 | sub _group_code_length { | ||||
| 357 | length( | ||||
| 358 | defined $_[0]->{'group_code'} ? $_[0]->{'group_code'} : '' | ||||
| 359 | ); | ||||
| 360 | } | ||||
| 361 | |||||
| 362 | =item publisher_code | ||||
| 363 | |||||
| - - | |||||
| 369 | sub publisher_code { $_[0]->{'publisher_code'} } | ||||
| 370 | sub _publisher_code_length { | ||||
| 371 | length( | ||||
| 372 | defined $_[0]->{'publisher_code'} ? $_[0]->{'publisher_code'} : '' | ||||
| 373 | ); | ||||
| 374 | } | ||||
| 375 | |||||
| 376 | =item article_code | ||||
| 377 | |||||
| - - | |||||
| 383 | sub article_code { $_[0]->{'article_code'} } | ||||
| 384 | |||||
| 385 | =item checksum | ||||
| 386 | |||||
| - - | |||||
| 392 | sub checksum { $_[0]->{'checksum'} } | ||||
| 393 | sub _checksum_pos { length( $_[0]->isbn ) - 1 } | ||||
| 394 | |||||
| 395 | |||||
| 396 | =item is_valid_checksum | ||||
| 397 | |||||
| - - | |||||
| 404 | sub is_valid_checksum | ||||
| 405 | { | ||||
| 406 | my $self = shift; | ||||
| 407 | |||||
| 408 | cluck "is_valid_checksum: Didn't get object!" unless ref $self; | ||||
| 409 | |||||
| 410 | return GOOD_ISBN if $self->checksum eq $self->_checksum; | ||||
| 411 | |||||
| 412 | return BAD_CHECKSUM; | ||||
| 413 | } | ||||
| 414 | |||||
| 415 | =item fix_checksum | ||||
| 416 | |||||
| - - | |||||
| 421 | sub fix_checksum | ||||
| 422 | { | ||||
| 423 | my $self = shift; | ||||
| 424 | |||||
| 425 | my $last_char = substr($self->isbn, $self->_checksum_pos, 1); | ||||
| 426 | my $checksum = $self->_checksum; | ||||
| 427 | |||||
| 428 | my $isbn = $self->isbn; | ||||
| 429 | substr($isbn, $self->_checksum_pos, 1) = $checksum; | ||||
| 430 | |||||
| 431 | $self->_set_isbn( $isbn ); | ||||
| 432 | $self->_set_checksum( $checksum ); | ||||
| 433 | |||||
| 434 | $self->_check_validity; | ||||
| 435 | |||||
| 436 | return 0 if $last_char eq $checksum; | ||||
| 437 | return 1; | ||||
| 438 | } | ||||
| 439 | |||||
| 440 | |||||
| 441 | =item as_string(), as_string([]) | ||||
| 442 | |||||
| - - | |||||
| 465 | sub as_string | ||||
| 466 | { | ||||
| 467 | my $self = shift; | ||||
| 468 | my $array_ref = shift; | ||||
| 469 | |||||
| 470 | #this allows one to override the positions settings from the | ||||
| 471 | #constructor | ||||
| 472 | $array_ref = $self->_hyphen_positions unless ref $array_ref eq ref []; | ||||
| 473 | |||||
| 474 | # print STDERR Data::Dumper->Dump( [$array_ref], [qw(array_ref)] ); | ||||
| 475 | # print STDERR Data::Dumper->Dump( [$self], [qw(self)] ); | ||||
| 476 | |||||
| 477 | return unless $self->is_valid eq GOOD_ISBN; | ||||
| 478 | my $isbn = $self->isbn; | ||||
| 479 | |||||
| 480 | foreach my $position ( sort { $b <=> $a } @$array_ref ) | ||||
| 481 | { | ||||
| 482 | next if $position > 12 or $position < 1; | ||||
| 483 | substr($isbn, $position, 0) = '-'; | ||||
| 484 | } | ||||
| 485 | |||||
| 486 | return $isbn; | ||||
| 487 | } | ||||
| 488 | |||||
| 489 | =item as_isbn10 | ||||
| 490 | |||||
| - - | |||||
| 497 | sub as_isbn10 | ||||
| 498 | { | ||||
| 499 | croak "as_isbn10() must be implemented in Business::ISBN subclass" | ||||
| 500 | } | ||||
| 501 | |||||
| 502 | =item as_isbn13 | ||||
| 503 | |||||
| - - | |||||
| 510 | sub as_isbn13 | ||||
| 511 | { | ||||
| 512 | croak "as_isbn13() must be implemented in Business::ISBN subclass" | ||||
| 513 | } | ||||
| 514 | |||||
| 515 | =item xisbn | ||||
| 516 | |||||
| - - | |||||
| 524 | sub xisbn | ||||
| 525 | { | ||||
| 526 | my $self = shift; | ||||
| 527 | |||||
| 528 | my $data = $self->_get_xisbn; | ||||
| 529 | $data =~ tr/x/X/; | ||||
| 530 | |||||
| 531 | my @isbns = $data =~ m|<isbn>(.*?)</isbn>|ig; | ||||
| 532 | shift @isbns; | ||||
| 533 | wantarray ? @isbns : \@isbns; | ||||
| 534 | } | ||||
| 535 | |||||
| 536 | sub _get_xisbn | ||||
| 537 | { | ||||
| 538 | my $self = shift; | ||||
| 539 | |||||
| 540 | eval "use LWP::Simple"; | ||||
| 541 | if( $@ ) { carp "You need LWP::Simple to use xisbn()"; return; } | ||||
| 542 | |||||
| 543 | my $data = LWP::Simple::get( $self->_xisbn_url ); | ||||
| 544 | |||||
| 545 | carp "Could not fetch xISBN data" unless defined $data; | ||||
| 546 | |||||
| 547 | return $data; | ||||
| 548 | } | ||||
| 549 | |||||
| 550 | sub _xisbn_url | ||||
| 551 | { | ||||
| 552 | my $self = shift; | ||||
| 553 | my $isbn = $self->as_string([]); | ||||
| 554 | |||||
| 555 | return "http://labs.oclc.org/xisbn/$isbn"; | ||||
| 556 | } | ||||
| 557 | |||||
| 558 | =item png_barcode | ||||
| 559 | |||||
| - - | |||||
| 568 | sub png_barcode | ||||
| 569 | { | ||||
| 570 | my $self = shift; | ||||
| 571 | |||||
| 572 | my $ean = $self->as_isbn13->as_string([]); | ||||
| 573 | |||||
| 574 | eval "use GD::Barcode::EAN13"; | ||||
| 575 | if( $@ ) | ||||
| 576 | { | ||||
| 577 | carp "Need GD::Barcode::EAN13 to use png_barcode!"; | ||||
| 578 | return; | ||||
| 579 | } | ||||
| 580 | |||||
| 581 | my $image = GD::Barcode::EAN13->new($ean)->plot->png; | ||||
| 582 | |||||
| 583 | return $image; | ||||
| 584 | } | ||||
| 585 | |||||
| 586 | =back | ||||
| 587 | |||||
| - - | |||||
| 590 | sub _set_isbn { $_[0]->{'isbn'} = $_[1]; } | ||||
| 591 | |||||
| 592 | sub _set_is_valid { $_[0]->{'valid'} = $_[1]; } | ||||
| 593 | |||||
| 594 | sub _set_prefix | ||||
| 595 | { | ||||
| 596 | croak "_set_prefix() must be implemented in Business::ISBN subclass" | ||||
| 597 | } | ||||
| 598 | |||||
| 599 | sub _set_group_code { $_[0]->{'group_code'} = $_[1]; } | ||||
| 600 | |||||
| 601 | sub _set_group_code_string { $_[0]->{'group_code_string'} = $_[1]; } | ||||
| 602 | |||||
| 603 | sub _set_publisher_code { $_[0]->{'publisher_code'} = $_[1]; } | ||||
| 604 | |||||
| 605 | sub _set_publisher_code_string { $_[0]->{'publisher_code_string'} = $_[1]; } | ||||
| 606 | |||||
| 607 | sub _set_article_code { $_[0]->{'article_code'} = $_[1]; } | ||||
| 608 | |||||
| 609 | sub _set_checksum { $_[0]->{'checksum'} = $_[1]; } | ||||
| 610 | |||||
| 611 | sub _set_type | ||||
| 612 | { | ||||
| 613 | croak "_set_type() must be implemented in Business::ISBN subclass" | ||||
| 614 | } | ||||
| 615 | |||||
| 616 | |||||
| 617 | # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # | ||||
| 618 | # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # | ||||
| 619 | # # internal methods. you don't get to use this one. | ||||
| 620 | sub _common_format | ||||
| 621 | { | ||||
| 622 | #we want uppercase X's | ||||
| 623 | my $data = uc shift; | ||||
| 624 | |||||
| 625 | #get rid of everything except decimal digits and X | ||||
| 626 | $data =~ s/[^0-9X]//g; | ||||
| 627 | |||||
| 628 | return $1 if $data =~ m/ | ||||
| 629 | \A #anchor at start | ||||
| 630 | ( | ||||
| 631 | (?:\d\d\d)? | ||||
| 632 | \d{9}[0-9X] | ||||
| 633 | ) | ||||
| 634 | \z #anchor at end | ||||
| 635 | /x; | ||||
| 636 | |||||
| 637 | return; | ||||
| 638 | } | ||||
| 639 | |||||
| 640 | sub _init | ||||
| 641 | { | ||||
| 642 | my $self = shift; | ||||
| 643 | my $common_data = shift; | ||||
| 644 | |||||
| 645 | my $class = ref $self =~ m/.*::(.*)/g; | ||||
| 646 | |||||
| 647 | $self->_set_type; | ||||
| 648 | $self->_set_isbn( $common_data ); | ||||
| 649 | |||||
| 650 | # we don't know if we have a valid group code yet | ||||
| 651 | # so let's assume that we don't | ||||
| 652 | $self->_set_is_valid( INVALID_GROUP_CODE ); | ||||
| 653 | } | ||||
| 654 | |||||
| 655 | { | ||||
| 656 | 2 | 4µs | my @methods = ( | ||
| 657 | [ qw( prefix ), INVALID_PREFIX ], | ||||
| 658 | [ qw( group_code ), INVALID_GROUP_CODE ], | ||||
| 659 | [ qw( publisher_code ), INVALID_PUBLISHER_CODE ], | ||||
| 660 | [ qw( article_code ), BAD_ISBN ], | ||||
| 661 | [ qw( checksum ), BAD_CHECKSUM ], | ||||
| 662 | ); | ||||
| 663 | |||||
| 664 | sub _parse_isbn | ||||
| 665 | { | ||||
| 666 | my $self = shift; | ||||
| 667 | |||||
| 668 | foreach my $pair ( @methods ) | ||||
| 669 | { | ||||
| 670 | my( $method, $error_code ) = @$pair; | ||||
| 671 | |||||
| 672 | my $parser = "_parse_$method"; | ||||
| 673 | my $result = $self->$parser; | ||||
| 674 | |||||
| 675 | unless( defined $result ) | ||||
| 676 | { | ||||
| 677 | $self->_set_is_valid( $error_code ); | ||||
| 678 | #print STDERR "Got bad result for $method [$$self{isbn}]\n"; | ||||
| 679 | return; | ||||
| 680 | } | ||||
| 681 | |||||
| 682 | $method = "_set_$method"; | ||||
| 683 | $self->$method( $result ); | ||||
| 684 | } | ||||
| 685 | |||||
| 686 | $self->_set_is_valid( $self->is_valid_checksum ); | ||||
| 687 | |||||
| 688 | return $self; | ||||
| 689 | } | ||||
| 690 | } | ||||
| 691 | |||||
| 692 | sub _parse_group_code | ||||
| 693 | { | ||||
| 694 | my $self = shift; | ||||
| 695 | |||||
| 696 | my $trial; # try this to see what we get | ||||
| 697 | my $group_code_length = 0; | ||||
| 698 | |||||
| 699 | my $count = 1; | ||||
| 700 | |||||
| 701 | GROUP_CODE: | ||||
| 702 | while( defined( $trial= substr($self->isbn, $self->_prefix_length, $count++) ) ) | ||||
| 703 | { | ||||
| 704 | if( defined $self->_group_data( $trial ) ) | ||||
| 705 | { | ||||
| 706 | return $trial; | ||||
| 707 | last GROUP_CODE; | ||||
| 708 | } | ||||
| 709 | |||||
| 710 | # if we've past the point of finding a group | ||||
| 711 | # code we're pretty much stuffed. | ||||
| 712 | return if $count > $self->_max_group_code_length; | ||||
| 713 | } | ||||
| 714 | |||||
| 715 | return; #failed if I got this far | ||||
| 716 | } | ||||
| 717 | |||||
| 718 | sub _parse_publisher_code | ||||
| 719 | { | ||||
| 720 | my $self = shift; | ||||
| 721 | |||||
| 722 | my $pairs = $self->_publisher_ranges; | ||||
| 723 | |||||
| 724 | # get the longest possible publisher code | ||||
| 725 | # I'll try substrs of this to get the real one | ||||
| 726 | my $longest = substr( | ||||
| 727 | $self->isbn, | ||||
| 728 | $self->_prefix_length + $self->_group_code_length, | ||||
| 729 | $self->_max_publisher_code_length, | ||||
| 730 | ); | ||||
| 731 | |||||
| 732 | #print STDERR "Trying to parse publisher: longest [$longest]\n"; | ||||
| 733 | while( @$pairs ) | ||||
| 734 | { | ||||
| 735 | my $lower = shift @$pairs; | ||||
| 736 | my $upper = shift @$pairs; | ||||
| 737 | |||||
| 738 | my $trial = substr( $longest, 0, length $lower ); | ||||
| 739 | #print STDERR "Trying [$trial] with $lower <-> $upper [$$self{isbn}]\n"; | ||||
| 740 | |||||
| 741 | # this has to be a sring comparison because there are | ||||
| 742 | # possibly leading 0s | ||||
| 743 | if( $trial ge $lower and $trial le $upper ) | ||||
| 744 | { | ||||
| 745 | #print STDERR "Returning $trial\n"; | ||||
| 746 | return $trial; | ||||
| 747 | } | ||||
| 748 | |||||
| 749 | } | ||||
| 750 | |||||
| 751 | return; #failed if I got this far | ||||
| 752 | } | ||||
| 753 | |||||
| 754 | sub _parse_article_code | ||||
| 755 | { | ||||
| 756 | my $self = shift; | ||||
| 757 | |||||
| 758 | my $head = $self->_prefix_length + | ||||
| 759 | $self->_group_code_length + | ||||
| 760 | $self->_publisher_code_length; | ||||
| 761 | my $length = length( $self->isbn ) - $head - 1; | ||||
| 762 | |||||
| 763 | substr( $self->isbn, $head, $length ); | ||||
| 764 | } | ||||
| 765 | |||||
| 766 | sub _parse_checksum | ||||
| 767 | { | ||||
| 768 | my $self = shift; | ||||
| 769 | |||||
| 770 | substr( $self->isbn, -1, 1 ); | ||||
| 771 | } | ||||
| 772 | |||||
| 773 | sub _check_validity | ||||
| 774 | { | ||||
| 775 | my $self = shift; | ||||
| 776 | |||||
| 777 | if( $self->is_valid_checksum eq GOOD_ISBN and | ||||
| 778 | defined $self->group_code and | ||||
| 779 | defined $self->publisher_code and | ||||
| 780 | defined $self->prefix | ||||
| 781 | ) | ||||
| 782 | { | ||||
| 783 | $self->_set_is_valid( GOOD_ISBN ); | ||||
| 784 | } | ||||
| 785 | else | ||||
| 786 | { | ||||
| 787 | $self->_set_is_valid( INVALID_PUBLISHER_CODE ) | ||||
| 788 | unless defined $self->publisher_code; | ||||
| 789 | $self->_set_is_valid( INVALID_GROUP_CODE ) | ||||
| 790 | unless defined $self->group_code; | ||||
| 791 | $self->_set_is_valid( INVALID_PREFIX ) | ||||
| 792 | unless defined $self->prefix; | ||||
| 793 | $self->_set_is_valid( GOOD_ISBN ) | ||||
| 794 | unless $self->is_valid_checksum ne GOOD_ISBN; | ||||
| 795 | } | ||||
| 796 | } | ||||
| 797 | |||||
| 798 | sub _hyphen_positions | ||||
| 799 | { | ||||
| 800 | croak "hyphen_positions() must be implemented in Business::ISBN subclass" | ||||
| 801 | } | ||||
| 802 | |||||
| 803 | |||||
| 804 | 1 | 8µs | 1; | ||
| 805 | |||||
| 806 | __END__ | ||||
# spent 81µs within Business::ISBN::CORE:sort which was called:
# once (81µs+0s) by Business::ISBN::BEGIN@75 at line 272 of Business/ISBN/Data.pm |