File Coverage

blib/lib/WWW/betfair/TypeCheck.pm
Criterion Covered Total %
statement 9 211 4.2
branch 0 168 0.0
condition 0 6 0.0
subroutine 3 45 6.6
pod 42 42 100.0
total 54 472 11.4


line stmt bran cond sub pod time code
1             package WWW::betfair::TypeCheck;
2 1     1   7 use strict;
  1         2  
  1         45  
3 1     1   7 use warnings;
  1         2  
  1         36  
4 1     1   1181 use Regexp::Common;
  1         2944  
  1         5  
5              
6             =head1 DESCRIPTION
7              
8             Used by L to provide type checking for parameters passed to the betfair API. Includes betfair's enumerated types.
9              
10             =head2 new
11              
12             Returns a new L object. Requires no parameters.
13              
14             =cut
15              
16             sub new {
17 0     0 1   my $class = shift;
18 0           my $self = {
19             typeChecks => { int => \&checkInt,
20             exchangeId => \&checkExchangeId,
21             decimal => \&checkDecimal,
22             date => \&checkDate,
23             string => \&checkString,
24             string9 => \&checkString9,
25             cardDate => \&checkCardDate,
26             cv2 => \&checkCv2,
27             username => \&checkUsername,
28             currencyCode => \&checkCurrencyCode,
29             password => \&checkPassword,
30             boolean => \&checkBoolean,
31             hash => \&checkHash,
32             arrayInt => \&checkArrayInt,
33             accountStatementEnum => \&checkAccountStatementEnum,
34             accountStatementIncludeEnum => \&checkAccountStatementIncludeEnum,
35             accountStatusEnum => \&checkAccountStatusEnum,
36             accountTypeEnum => \&checkAccountTypeEnum,
37             betCategoryTypeEnum => \&checkBetCategoryTypeEnum,
38             betPersistenceTypeEnum => \&checkBetPersistenceTypeEnum,
39             betsOrderByEnum => \&checkBetsOrderByEnum,
40             betStatusEnum => \&checkBetStatusEnum,
41             betTypeEnum => \&checkBetTypeEnum,
42             billingPeriodEnum => \&checkBillingPeriodEnum,
43             cardTypeEnum => \&checkCardTypeEnum,
44             gamcareLimitFreqEnum => \&checkGamcareLimitFreqEnum,
45             genderEnum => \&checkGenderEnum,
46             marketStatusEnum => \&checkMarketStatusEnum,
47             marketTypeEnum => \&checkMarketTypeEnum,
48             arrayMarketTypeEnum => \&checkArrayMarketTypeEnum,
49             marketTypeVariantEnum => \&checkMarketTypeVariantEnum,
50             paymentCardStatusEnum => \&checkPaymentCardStatusEnum,
51             regionEnum => \&checkRegionEnum,
52             securityQuestion1Enum => \&checkSecurityQuestion1Enum,
53             securityQuestion2Enum => \&checkSecurityQuestion2Enum,
54             serviceEnum => \&checkServiceEnum,
55             sortOrderEnum => \&checkSortOrderEnum,
56             subscriptionStatusEnum => \&checkSubscriptionStatusEnum,
57             titleEnum => \&checkTitleEnum,
58             validationErrorsEnum => \&checkValidationErrorsEnum,
59             },
60             };
61 0           return bless $self, $class;
62             }
63              
64              
65             =head2 checkParameter
66              
67             Receives a parameter and parameter type and executes the appropriate check method for that type.
68              
69             =cut
70              
71             sub checkParameter {
72 0     0 1   my ($self, $type, $parameter) = @_;
73 0 0 0       return 0 unless (defined $type and defined $parameter);
74 0 0         return 0 unless exists $self->{typeChecks}->{$type};
75 0           my $check = $self->{typeChecks}->{$type};
76 0           return $self->$check($parameter);
77             }
78              
79             =head2 checkAccountStatementEnum
80              
81             Checks submitted value is a valid betfair enumerated type, see L for details.
82              
83             =cut
84              
85             sub checkAccountStatementEnum {
86 0     0 1   my ($self, $arg) = @_;
87 0 0         return 0 unless defined $arg;
88 0 0         return 1 if grep {/^$arg$/} qw/OK RESULT_ERR RESULT_FIX RESULT_LOST RESULT_NOT_APPLICABLE RESULT_WON COMMISSION_REVERSAL/;
  0            
89 0           return 0;
90             }
91              
92             =head2 checkAccountStatementIncludeEnum
93              
94             Checks submitted value is a valid betfair enumerated type, see L for details.
95              
96             =cut
97              
98             sub checkAccountStatementIncludeEnum {
99 0     0 1   my ($self, $arg) = @_;
100 0 0         return 0 unless defined $arg;
101 0 0         return 1 if grep {/^$arg$/} qw/ALL DEPOSITS_WITHDRAWALS EXCHANGE POKER_ROOM/;
  0            
102 0           return 0;
103             }
104              
105             =head2 checkAccountStatusEnum
106              
107             Checks submitted value is a valid betfair enumerated type, see L.
108              
109             =cut
110              
111             sub checkAccountStatusEnum {
112 0     0 1   my ($self, $arg) = @_;
113 0 0         return 0 unless defined $arg;
114 0 0         return 1 if grep {/^$arg$/} qw/A C D L P S T X Z/;
  0            
115 0           return 0;
116             }
117              
118             =head2 checkAccountTypeEnum
119              
120             Checks submitted value is a valid betfair enumerated type, see L for details.
121              
122             =cut
123              
124             sub checkAccountTypeEnum {
125 0     0 1   my ($self, $arg) = @_;
126 0 0         return 0 unless defined $arg;
127 0 0         return 1 if grep {/^$arg$/} qw/STANDARD MARGIN TRADING AGENT_CLIENT/;
  0            
128 0           return 0;
129             }
130              
131             =head2 checkBetCategoryTypeEnum
132              
133             Checks submitted value is a valid betfair enumerated type, see L for details.
134              
135             =cut
136              
137             sub checkBetCategoryTypeEnum {
138 0     0 1   my ($self, $arg) = @_;
139 0 0         return 0 unless defined $arg;
140 0 0         return 1 if grep {/^$arg$/} qw/NONE E M L/;
  0            
141 0           return 0;
142             }
143              
144             =head2 checkBetPersistenceTypeEnum
145              
146             Checks submitted value is a valid betfair enumerated type, see L for details.
147              
148             =cut
149              
150             sub checkBetPersistenceTypeEnum {
151 0     0 1   my ($self, $arg) = @_;
152 0 0         return 0 unless defined $arg;
153 0 0         return 1 if grep {/^$arg$/} qw/NONE IP SP/;
  0            
154 0           return 0;
155             }
156              
157             =head2 checkBetsOrderByEnum
158              
159             Checks submitted value is a valid betfair enumerated type, see L for details.
160              
161             =cut
162              
163             sub checkBetsOrderByEnum {
164 0     0 1   my ($self, $arg) = @_;
165 0 0         return 0 unless defined $arg;
166 0 0         return 1 if grep {/^$arg$/} qw/BET_ID CANCELLED_DATE MARKET_NAME MATCHED_DATE NONE PLACED_DATE/;
  0            
167 0           return 0;
168             }
169              
170             =head2 checkBetStatusEnum
171              
172             Checks submitted value is a valid betfair enumerated type, see L for details.
173              
174             =cut
175              
176             sub checkBetStatusEnum {
177 0     0 1   my ($self, $arg) = @_;
178 0 0         return 0 unless defined $arg;
179 0 0         return 1 if grep {/^$arg$/} qw/C L M MU S U V/;
  0            
180 0           return 0;
181             }
182              
183             =head2 checkBetTypeEnum
184              
185             Checks submitted value is a valid betfair enumerated type, see L for details.
186              
187             =cut
188              
189             sub checkBetTypeEnum {
190 0     0 1   my ($self, $arg) = @_;
191 0 0         return 0 unless defined $arg;
192 0 0         return 1 if grep {/^$arg$/} qw/B L/;
  0            
193 0           return 0;
194             }
195              
196             =head2 checkBillingPeriodEnum
197              
198             Checks submitted value is a valid betfair enumerated type, see L for details.
199              
200             =cut
201              
202             sub checkBillingPeriodEnum {
203 0     0 1   my ($self, $arg) = @_;
204 0 0         return 0 unless defined $arg;
205 0 0         return 1 if grep {/^$arg$/} qw/WEEKLY MONTHLY QUARTERLY ANNUALLY/;
  0            
206 0           return 0;
207             }
208              
209             =head2 checkCardTypeEnum
210              
211             Checks submitted value is a valid betfair enumerated type, see L for details.
212              
213             =cut
214              
215             sub checkCardTypeEnum {
216 0     0 1   my ($self, $arg) = @_;
217 0 0         return 0 unless defined $arg;
218 0 0         return 1 if grep {/^$arg$/} qw/VISA MASTERCARD VISADELTA SWITCH SOLO ELECTRON LASER MAESTRO INVALID_CARD_TYPE/;
  0            
219 0           return 0;
220             }
221              
222             =head2 checkGamcareLimitFreqEnum
223              
224             Checks submitted value is a valid betfair enumerated type, see L for details.
225              
226             =cut
227              
228             sub checkGamcareLimitFreqEnum {
229 0     0 1   my ($self, $arg) = @_;
230 0 0         return 0 unless defined $arg;
231 0 0         return 1 if grep {/^$arg$/} qw/DAILY WEEKLY MONTHLY YEARLY/;
  0            
232 0           return 0;
233             }
234              
235             =head2 checkGenderEnum
236              
237             Checks submitted value is a valid betfair enumerated type, see L for details.
238              
239             =cut
240              
241             sub checkGenderEnum {
242 0     0 1   my ($self, $arg) = @_;
243 0 0         return 0 unless defined $arg;
244 0 0         return 1 if grep {/^$arg$/} qw/M F/;
  0            
245 0           return 0;
246             }
247              
248             =head2 checkMarketStatusEnum
249              
250             Checks submitted value is a valid betfair enumerated type, see L for details.
251              
252             =cut
253              
254             sub checkMarketStatusEnum {
255 0     0 1   my ($self, $arg) = @_;
256 0 0         return 0 unless defined $arg;
257 0 0         return 1 if grep {/^$arg$/} qw/ACTIVE CLOSED INACTIVE SUSPENDED/;
  0            
258 0           return 0;
259             }
260              
261              
262             =head2 checkMarketTypeEnum
263              
264             Checks submitted value is a valid betfair enumerated type, see L for details.
265              
266             =cut
267              
268             sub checkMarketTypeEnum {
269 0     0 1   my ($self, $arg) = @_;
270 0 0         return 0 unless defined $arg;
271 0 0         return 1 if grep {/^$arg$/} qw/A L O R NOT_APPLICABLE/;
  0            
272 0           return 0;
273             }
274              
275             =head2 checkArrayMarketTypeEnum
276              
277             Checks the argument is a non-null arrayref containing only valid marketTypeEnum values.
278              
279             =cut
280              
281             sub checkArrayMarketTypeEnum {
282 0     0 1   my ($self, $arg) = @_;
283 0 0         return 0 unless @$arg;
284 0 0         return 0 unless ref $arg eq 'ARRAY';
285 0           foreach (@{$arg}) {
  0            
286 0 0         return 0 unless $self->checkMarketTypeEnum($_);
287             }
288 0           return 1;
289             }
290              
291             =head2 checkMarketTypeVariantEnum
292              
293             Checks submitted value is a valid betfair enumerated type, see L for details.
294              
295             =cut
296              
297             sub checkMarketTypeVariantEnum {
298 0     0 1   my ($self, $arg) = @_;
299 0 0         return 0 unless defined $arg;
300 0 0         return 1 if grep {/^$arg$/} qw/D ASL ADL/;
  0            
301 0           return 0;
302             }
303              
304             =head2 checkPaymentCardStatusEnum
305              
306             Checks submitted value is a valid betfair enumerated type, see L.
307              
308             =cut
309              
310             sub checkPaymentCardStatusEnum {
311 0     0 1   my ($self, $arg) = @_;
312 0 0         return 0 unless defined $arg;
313 0 0         return 1 if grep {/^$arg$/} qw/LOCKED UNLOCKED/;
  0            
314 0           return 0;
315             }
316              
317             =head2 checkRegionEnum
318              
319             Checks submitted value is a valid betfair enumerated type, see L for details.
320              
321             =cut
322              
323             sub checkRegionEnum {
324 0     0 1   my ($self, $arg) = @_;
325 0 0         return 0 unless defined $arg;
326 0 0         return 1 if grep {/^$arg$/} qw/AUZ_NZL GBR IRL NA NORD ZAF/;
  0            
327 0           return 0;
328             }
329              
330             =head2 checkSecurityQuestion1Enum
331              
332             Checks submitted value is a valid betfair enumerated type, see L for details.
333              
334             =cut
335              
336             sub checkSecurityQuestion1Enum {
337 0     0 1   my ($self, $arg) = @_;
338 0 0         return 0 unless defined $arg;
339 0 0         return 1 if grep {/^$arg$/} qw/SQ1A SQ1B SQ1C SQ1D/;
  0            
340 0           return 0;
341             }
342              
343             =head2 checkSecurityQuestion2Enum
344              
345             Checks submitted value is a valid betfair enumerated type, see L for details.
346              
347             =cut
348              
349             sub checkSecurityQuestion2Enum {
350 0     0 1   my ($self, $arg) = @_;
351 0 0         return 0 unless defined $arg;
352 0 0         return 1 if grep {/^$arg$/} qw/SQ2A SQ2B SQ2C SQ2S/;
  0            
353 0           return 0;
354             }
355              
356             =head2 checkServiceEnum
357              
358             Checks submitted value is a valid betfair enumerated type, see L.
359              
360             =cut
361              
362             sub checkServiceEnum {
363 0     0 1   my ($self, $arg) = @_;
364 0 0         return 0 unless defined $arg;
365 0 0         return 1 if grep {/^$arg$/} qw/ADD_PAYMENT_CARD CANCEL_BETS CREATE_ACCOUNT CONVERT_CURRENCY DELETE_PAYMENT_CARD DEPOSIT_FROM_PAYMENT_CARD
  0            
366             DO_KEEP_ALIVE EDIT_BETS FORGOT_PASSWORD GET_ACCOUNT_STATEMENT GET_BET GET_CURRENT_BETS GET_CURRENCIES
367             GET_MARKET_TRADED_VOLUME GET_PAYMENT_CARD LOAD_BET_HISTORY LOAD_DETAILED_AVAIL_MKT_DEPTH LOAD_EVENT_TYPES
368             LOAD_EVENTS LOAD_MARKET LOAD_MARKET_PRICES LOAD_MARKET_PRICES_COMPRESSED LOAD_MARKET_PROFIT_LOSS
369             LOAD_SERVICE_ANNOUNCEMENTS LOAD_SUBSCRIPTION_INFO LOGIN LOGOUT MODIFY_PASSWORD MODIFY_PROFILE PLACE_BETS
370             RETRIEVE_LIMB_MESSAGE SUBMIT_LIMB_MESSAGE UPDATE_PAYMENT_CARD VIEW_PROFILE WITHDRAW_TO_PAYMENT_CARD/;
371 0           return 0;
372             }
373              
374             =head2 checkSortOrderEnum
375              
376             Checks submitted value is a valid betfair enumerated type, see L for details.
377              
378             =cut
379              
380             sub checkSortOrderEnum {
381 0     0 1   my ($self, $arg) = @_;
382 0 0         return 0 unless defined $arg;
383 0 0         return 1 if grep {/^$arg$/} qw/ASC DESC/;
  0            
384 0           return 0;
385             }
386              
387             =head2 checkSubscriptionStatusEnum
388              
389             Checks submitted value is a valid betfair enumerated type, see L for details.
390              
391             =cut
392              
393             sub checkSubscriptionStatusEnum {
394 0     0 1   my ($self, $arg) = @_;
395 0 0         return 0 unless defined $arg;
396 0 0         return 1 if grep {/^$arg$/} qw/ACTIVE INACTIVE SUSPENDED/;
  0            
397 0           return 0;
398             }
399              
400             =head2 checkTitleEnum
401              
402             Checks submitted value is a valid betfair enumerated type, see L for details.
403              
404             =cut
405              
406             sub checkTitleEnum {
407 0     0 1   my ($self, $arg) = @_;
408 0 0         return 0 unless defined $arg;
409 0 0         return 1 if grep {/^$arg$/} qw/Dr Miss Mr Mrs Ms/;
  0            
410 0           return 0;
411             }
412              
413             =head2 checkValidationErrorsEnum
414              
415             Checks submitted value is a valid betfair enumerated type, see L for details.
416              
417             =cut
418              
419             sub checkValidationErrorsEnum {
420 0     0 1   my ($self, $arg) = @_;
421 0 0         return 0 unless defined $arg;
422 0 0         return 1 if grep {/^$arg$/} qw/DUPLICATE_USERNAME FUND_TRANSFER_CANCEL FUND_TRANSFER_CURRENCY_MISMATCH INCOMPLETE_DETAILS
  0            
423             INSUFFICIENT_FUNDS INVALID_ACCOUNT_TYPE INVALID_ADDRESS_LINE1 INVALID_ADDRESS_LINE2 INVALID_ADDRESS_LINE3
424             INVALID_ANSWER1 INVALID_ANSWER2 INVALID_BROWSER INVALID_CITY INVALID_COUNTRY_OF_RESIDENCE INVALID_COUNTY_STATE
425             INVALID_CURRENCY INVALID_DEPOSIT_LIMIT INVALID_DEPOSIT_LIMIT_FREQUENCY INVALID_DETAILS INVALID_DOB
426             INVALID_EMAIL INVALID_FIRSTNAME INVALID_GENDER INVALID_HOME_PHONE INVALID_IP_ADDRESS INVALID_LANGUAGE INVALID_LOCALE
427             INVALID_LOSS_LIMIT INVALID_LOSS_LIMIT_FREQUENCY INVALID_MASTER_ID INVALID_MOBILE_PHONE INVALID_PARTNERID
428             INVALID_PASSWORD INVALID_POSTCODE INVALID_PRIVACY_VERSION INVALID_PRODUCT_ID INVALID_REFERRER_CODE
429             INVALID_REGION INVALID_SECURITY_QUESTION1 INVALID_SECURITY_QUESTION2 INVALID_SUBPARTNER_ID INVALID_SUPERPARTNER_ID
430             INVALID_SURNAME INVALID_TC_VERSION INVALID_TIMEZONE INVALID_TITLE INVALID_USERNAME INVALID_WORK_PHONE
431             RESERVED_PASSWORD/;
432 0           return 0;
433             }
434              
435             =head2 checkDecimal
436              
437             Checks the value submitted is a decimal number. Accepts whole numbers with no decimal point and negative numbers with a leading minus ('-').
438              
439             =cut
440              
441             sub checkDecimal {
442 0     0 1   my ($self, $arg) = @_;
443 0 0         return 0 unless defined $arg;
444 0 0         return 1 if $arg =~ qr/^-?(?:\d+(?:\.\d*)?|\.\d+)$/;
445 0           return 0;
446             }
447              
448             =head2 checkExchangeId
449              
450             Checks the exchange id is either 1 (UK), 2 (Australian) or 3 (Global),
451              
452             =cut
453              
454             sub checkExchangeId {
455 0     0 1   my ($self, $arg) = @_;
456 0 0         return 0 unless defined $arg;
457 0 0         return 1 if grep { $_ == $arg } qw/1 2/;
  0            
458 0           return 0;
459             }
460              
461             =head2 checkCurrencyCode
462              
463             Checks the value submitted is a valid currency code accepted by betfair (e.g. 'EUR', 'GBP', 'CAD'). Accepts whole numbers with no decimal point and negative numbers with a leading minus ('-').
464              
465             =cut
466              
467             sub checkCurrencyCode {
468 0     0 1   my ($self, $arg) = @_;
469 0 0         return 0 unless defined $arg;
470 0 0         return 1 if grep {/^$arg$/} qw/GBP EUR HKD AUD CAD DKK NOK SGD SEK USD/;
  0            
471 0           return 0;
472             }
473              
474             =head2 checkInt
475              
476             Checks the value submitted is a whole number. Accepts negative numbers with a leading minus ('-').
477              
478             =cut
479              
480             sub checkInt {
481 0     0 1   my ($self, $arg) = @_;
482 0 0         return 0 unless defined $arg;
483 0 0         return 1 if $arg =~ /^$RE{num}{int}$/;
484 0           return 0;
485             }
486              
487             =head2 checkArrayInt
488              
489             Checks that the argument is a non-null arrayref containing only integers as defined by the L method.
490              
491             =cut
492              
493             sub checkArrayInt {
494 0     0 1   my ($self, $arg) = @_;
495 0 0         return 0 unless @$arg;
496 0 0         return 0 unless ref $arg eq 'ARRAY';
497 0           foreach (@{$arg}) {
  0            
498 0 0         return 0 unless $self->checkInt($_);
499             }
500 0           return 1;
501             }
502              
503             =head2 checkUsername
504              
505             Checks the username is between 8-20 characters and contains only letters and numbers.
506              
507             =cut
508              
509             sub checkUsername {
510 0     0 1   my ($self, $arg) = @_;
511 0 0         return 0 unless defined $arg;
512 0 0         return 1 if $arg =~ qr/^[a-zA-Z0-9]{8,20}$/;
513 0           return 0;
514             }
515              
516             =head2 checkPassword
517              
518             Checks password is between 8-20 characters. No further checking is done as the password is encrypted. The actual betfair rules are alphanumeric characters plus these valid symbols: $!?()*+,:;=@_./-[]{} with the total length between 8-20 characters.
519              
520             =cut
521              
522             sub checkPassword {
523 0     0 1   my ($self, $arg) = @_;
524 0 0         return 0 unless defined $arg;
525 0 0         return 1 if $arg =~ qr/^.{8,20}$/;
526 0           return 0;
527             }
528              
529             =head2 checkDate
530              
531             Checks date follows the XML datetime specification. Note that betfair will only accept datetimes not date values and it must be passed as a string. Some valid examples:
532              
533             # standard datetime
534             '2013-01-18T12:30:58'
535            
536             # datetime with UTC timezone
537             '2013-01-18T12:30:58Z'
538              
539             # datetime with -5hrs timezone
540             '2013-01-18T12:30:58-05:00'
541              
542             # datetime with +6hrs timezone
543             '2013-01-18T12:30:58+06:00'
544              
545             =cut
546              
547             sub checkDate {
548 0     0 1   my ($self, $arg) = @_;
549 0 0         return 0 unless defined $arg;
550 0 0         return 1 if $arg =~ qr/^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}/;
551 0           return 0;
552             }
553              
554             =head2 checkBoolean
555              
556             Checks that value is of a valid boolean type: a string value of either 'true' or 'false'.
557              
558             =cut
559              
560             sub checkBoolean {
561 0     0 1   my ($self, $arg) = @_;
562 0 0         return 0 unless defined $arg;
563 0 0         return 1 if grep {/^$arg$/} qw/true false/;
  0            
564 0           return 0;
565             }
566              
567             =head2 checkString
568              
569             Checks that the value is a string with a non-zero length.
570              
571             =cut
572              
573             =head2 checkHash
574              
575             Checks that the argument is a hash.
576              
577             =cut
578              
579             sub checkHash {
580 0     0 1   my ($self, $arg) = @_;
581 0 0         return 0 unless @$arg;
582 0 0         return 0 unless ref $arg eq 'HASH';
583 0           return 1;
584             }
585              
586              
587             sub checkString {
588 0     0 1   my ($self, $arg) = @_;
589 0 0         return 0 unless defined $arg;
590 0 0         return 1 if length($arg) > 0;
591 0           return 0;
592             }
593              
594             =head2 checkString9
595              
596             Checks that the value is a string with a non-zero length that is less than 10 characters.
597              
598             =cut
599              
600             sub checkString9 {
601 0     0 1   my ($self, $arg) = @_;
602 0 0         return 0 unless defined $arg;
603 0 0 0       return 1 if (length($arg) > 0 and length($arg) < 10);
604 0           return 0;
605             }
606              
607             =head2 checkCardDate
608              
609             Checks for a number containing exactly 4 digits. If the number begins with 0, it must be quoted (else Perl will remove the leading 0).
610              
611             =cut
612              
613             sub checkCardDate {
614 0     0 1   my ($self, $arg) = @_;
615 0 0         return 0 unless defined $arg;
616 0 0         return 1 if $arg =~ /^[0-9]{4}$/;
617 0           return 0;
618             }
619              
620             =head2 checkCv2
621              
622             Checks for a number containing exactly 3 digits. If the number begins with 0, it must be quoted (else Perl will remove the leading 0).
623              
624             =cut
625              
626             sub checkCv2 {
627 0     0 1   my ($self, $arg) = @_;
628 0 0         return 0 unless defined $arg;
629 0 0         return 1 if $arg =~ /^[0-9]{3}$/;
630 0           return 0;
631             }
632              
633             1;